• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "base/MemStream.h"
15 #include "base/PathUtils.h"
16 #include "base/System.h"
17 #include "host-common/address_space_device.h"
18 #include "host-common/address_space_device.hpp"
19 #include "host-common/address_space_graphics.h"
20 #include "host-common/address_space_graphics_types.h"
21 #include "host-common/AndroidPipe.h"
22 #include "host-common/android_pipe_device.h"
23 #include "host-common/vm_operations.h"
24 #include "host-common/window_agent.h"
25 #include "host-common/HostmemIdMapping.h"
26 #include "host-common/FeatureControl.h"
27 #include "host-common/feature_control.h"
28 #include "host-common/opengl/emugl_config.h"
29 #include "host-common/opengles-pipe.h"
30 #include "host-common/opengles.h"
31 #include "host-common/refcount-pipe.h"
32 #include "host-common/globals.h"
33 #include "snapshot/interface.h"
34 
35 #include <fstream>
36 #include <string>
37 
38 #include <stdio.h>
39 
40 #include "VulkanDispatch.h"
41 #include "GfxStreamAgents.h"
42 #include "render_api.h"
43 
44 #define GFXSTREAM_DEBUG_LEVEL 1
45 
46 #if GFXSTREAM_DEBUG_LEVEL >= 1
47 #define GFXS_LOG(fmt, ...)                                                     \
48     do {                                                                       \
49         fprintf(stdout, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \
50         fflush(stdout);                                                        \
51     } while (0)
52 
53 #else
54 #define GFXS_LOG(fmt,...)
55 #endif
56 
57 extern "C" {
58 #include "host-common/goldfish_pipe.h"
59 #include "virtio-gpu-gfxstream-renderer.h"
60 }  // extern "C"
61 
62 using android::AndroidPipe;
63 using android::base::pj;
64 
65 #ifdef _WIN32
66 #define VG_EXPORT __declspec(dllexport)
67 #else
68 #define VG_EXPORT __attribute__((visibility("default")))
69 #endif
70 
71 #define POST_CALLBACK_DISPLAY_TYPE_X 0
72 #define POST_CALLBACK_DISPLAY_TYPE_WAYLAND_SHARED_MEM 1
73 #define POST_CALLBACK_DISPLAY_TYPE_WINDOWS_HWND 2
74 
75 struct renderer_display_info;
76 typedef void (*get_pixels_t)(void*, uint32_t, uint32_t);
77 static get_pixels_t sGetPixelsFunc = 0;
78 typedef void (*post_callback_t)(void*, uint32_t, int, int, int, int, int, unsigned char*);
79 
80 
81 
82 extern "C" VG_EXPORT void gfxstream_backend_init(
83     uint32_t display_width,
84     uint32_t display_height,
85     uint32_t display_type,
86     void* renderer_cookie,
87     int renderer_flags,
88     struct virgl_renderer_callbacks* virglrenderer_callbacks);
89 
90 extern "C" VG_EXPORT void gfxstream_backend_setup_window(
91         void* native_window_handle,
92         int32_t window_x,
93         int32_t window_y,
94         int32_t window_width,
95         int32_t window_height,
96         int32_t fb_width,
97         int32_t fb_height);
98 
99 // For reading back rendered contents to display
100 extern "C" VG_EXPORT void get_pixels(void* pixels, uint32_t bytes);
101 
102 static const GoldfishPipeServiceOps goldfish_pipe_service_ops = {
103         // guest_open()
__anon7a2565260102() 104         [](GoldfishHwPipe* hwPipe) -> GoldfishHostPipe* {
105             return static_cast<GoldfishHostPipe*>(
106                     android_pipe_guest_open(hwPipe));
107         },
108         // guest_open_with_flags()
__anon7a2565260202() 109         [](GoldfishHwPipe* hwPipe, uint32_t flags) -> GoldfishHostPipe* {
110             return static_cast<GoldfishHostPipe*>(
111                     android_pipe_guest_open_with_flags(hwPipe, flags));
112         },
113         // guest_close()
__anon7a2565260302() 114         [](GoldfishHostPipe* hostPipe, GoldfishPipeCloseReason reason) {
115             static_assert((int)GOLDFISH_PIPE_CLOSE_GRACEFUL ==
116                                   (int)PIPE_CLOSE_GRACEFUL,
117                           "Invalid PIPE_CLOSE_GRACEFUL value");
118             static_assert(
119                     (int)GOLDFISH_PIPE_CLOSE_REBOOT == (int)PIPE_CLOSE_REBOOT,
120                     "Invalid PIPE_CLOSE_REBOOT value");
121             static_assert((int)GOLDFISH_PIPE_CLOSE_LOAD_SNAPSHOT ==
122                                   (int)PIPE_CLOSE_LOAD_SNAPSHOT,
123                           "Invalid PIPE_CLOSE_LOAD_SNAPSHOT value");
124             static_assert(
125                     (int)GOLDFISH_PIPE_CLOSE_ERROR == (int)PIPE_CLOSE_ERROR,
126                     "Invalid PIPE_CLOSE_ERROR value");
127 
128             android_pipe_guest_close(hostPipe,
129                                      static_cast<PipeCloseReason>(reason));
130         },
131         // guest_pre_load()
__anon7a2565260402() 132         [](QEMUFile* file) { (void)file; },
133         // guest_post_load()
__anon7a2565260502() 134         [](QEMUFile* file) { (void)file; },
135         // guest_pre_save()
__anon7a2565260602() 136         [](QEMUFile* file) { (void)file; },
137         // guest_post_save()
__anon7a2565260702() 138         [](QEMUFile* file) { (void)file; },
139         // guest_load()
140         [](QEMUFile* file,
141            GoldfishHwPipe* hwPipe,
__anon7a2565260802() 142            char* force_close) -> GoldfishHostPipe* {
143             (void)file;
144             (void)hwPipe;
145             (void)force_close;
146            return nullptr;
147         },
148         // guest_save()
__anon7a2565260902() 149         [](GoldfishHostPipe* hostPipe, QEMUFile* file) {
150             (void)hostPipe;
151             (void)file;
152         },
153         // guest_poll()
__anon7a2565260a02() 154         [](GoldfishHostPipe* hostPipe) {
155             static_assert((int)GOLDFISH_PIPE_POLL_IN == (int)PIPE_POLL_IN,
156                           "invalid POLL_IN values");
157             static_assert((int)GOLDFISH_PIPE_POLL_OUT == (int)PIPE_POLL_OUT,
158                           "invalid POLL_OUT values");
159             static_assert((int)GOLDFISH_PIPE_POLL_HUP == (int)PIPE_POLL_HUP,
160                           "invalid POLL_HUP values");
161 
162             return static_cast<GoldfishPipePollFlags>(
163                     android_pipe_guest_poll(hostPipe));
164         },
165         // guest_recv()
166         [](GoldfishHostPipe* hostPipe,
167            GoldfishPipeBuffer* buffers,
__anon7a2565260b02() 168            int numBuffers) -> int {
169             // NOTE: Assumes that AndroidPipeBuffer and GoldfishPipeBuffer
170             //       have exactly the same layout.
171             static_assert(
172                     sizeof(AndroidPipeBuffer) == sizeof(GoldfishPipeBuffer),
173                     "Invalid PipeBuffer sizes");
174         // We can't use a static_assert with offsetof() because in msvc, it uses
175         // reinterpret_cast.
176         // TODO: Add runtime assertion instead?
177         // https://developercommunity.visualstudio.com/content/problem/22196/static-assert-cannot-compile-constexprs-method-tha.html
178 #ifndef _MSC_VER
179             static_assert(offsetof(AndroidPipeBuffer, data) ==
180                                   offsetof(GoldfishPipeBuffer, data),
181                           "Invalid PipeBuffer::data offsets");
182             static_assert(offsetof(AndroidPipeBuffer, size) ==
183                                   offsetof(GoldfishPipeBuffer, size),
184                           "Invalid PipeBuffer::size offsets");
185 #endif
186             return android_pipe_guest_recv(
187                     hostPipe, reinterpret_cast<AndroidPipeBuffer*>(buffers),
188                     numBuffers);
189         },
190         // guest_send()
191         [](GoldfishHostPipe** hostPipe,
192            const GoldfishPipeBuffer* buffers,
__anon7a2565260c02() 193            int numBuffers) -> int {
194             return android_pipe_guest_send(
195                     reinterpret_cast<void**>(hostPipe),
196                     reinterpret_cast<const AndroidPipeBuffer*>(buffers),
197                     numBuffers);
198         },
199         // guest_wake_on()
__anon7a2565260d02() 200         [](GoldfishHostPipe* hostPipe, GoldfishPipeWakeFlags wakeFlags) {
201             android_pipe_guest_wake_on(hostPipe, static_cast<int>(wakeFlags));
202         },
203         // dma_add_buffer()
__anon7a2565260e02() 204         [](void* pipe, uint64_t paddr, uint64_t sz) {
205             // not considered for virtio
206         },
207         // dma_remove_buffer()
__anon7a2565260f02() 208         [](uint64_t paddr) {
209             // not considered for virtio
210         },
211         // dma_invalidate_host_mappings()
__anon7a2565261002() 212         []() {
213             // not considered for virtio
214         },
215         // dma_reset_host_mappings()
__anon7a2565261102() 216         []() {
217             // not considered for virtio
218         },
219         // dma_save_mappings()
__anon7a2565261202() 220         [](QEMUFile* file) {
221             (void)file;
222         },
223         // dma_load_mappings()
__anon7a2565261302() 224         [](QEMUFile* file) {
225             (void)file;
226         },
227 };
228 
229 extern const QAndroidVmOperations* const gQAndroidVmOperations;
230 
231 static void set_post_callback(struct renderer_display_info* r, post_callback_t func, uint32_t display_type);
232 
default_post_callback(void * context,uint32_t displayId,int width,int height,int ydir,int format,int frame_type,unsigned char * pixels)233 static void default_post_callback(
234     void* context, uint32_t displayId, int width, int height, int ydir, int format, int frame_type, unsigned char* pixels) {
235     (void)context;
236     (void)width;
237     (void)height;
238     (void)ydir;
239     (void)format;
240     (void)frame_type;
241     (void)pixels;
242     // no-op
243 }
244 
245 uint32_t sBackendFlags = 0;
246 
247 enum BackendFlags {
248     GFXSTREAM_BACKEND_FLAGS_NO_VK_BIT = 1 << 0,
249     GFXSTREAM_BACKEND_FLAGS_EGL2EGL_BIT = 1 << 1,
250 };
251 
252 // based on VIRGL_RENDERER_USE* and friends
253 enum RendererFlags {
254     GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT = 1 << 0,
255     GFXSTREAM_RENDERER_FLAGS_THREAD_SYNC = 1 << 1,
256     GFXSTREAM_RENDERER_FLAGS_USE_GLX_BIT = 1 << 2,
257     GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT = 1 << 3,
258     GFXSTREAM_RENDERER_FLAGS_USE_GLES_BIT = 1 << 4,
259     GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT = 1 << 5,  // for disabling vk
260     GFXSTREAM_RENDERER_FLAGS_IGNORE_HOST_GL_ERRORS_BIT =
261         1 << 6,  // control IgnoreHostOpenGLErrors flag
262     GFXSTREAM_RENDERER_FLAGS_NATIVE_TEXTURE_DECOMPRESSION_BIT =
263         1 << 7,  // Attempt GPU texture decompression
264     GFXSTREAM_RENDERER_FLAGS_ENABLE_BPTC_TEXTURES_BIT =
265         1 << 8,  // enable BPTC texture support if available
266     GFXSTREAM_RENDERER_FLAGS_ENABLE_GLES31_BIT =
267         1 << 9,  // disables the PlayStoreImage flag
268     GFXSTREAM_RENDERER_FLAGS_ENABLE_S3TC_TEXTURES_BIT =
269         1 << 10,  // enable S3TC texture support if available
270     GFXSTREAM_RENDERER_FLAGS_NO_SYNCFD_BIT = 1 << 20,  // for disabling syncfd
271     GFXSTREAM_RENDERER_FLAGS_GUEST_USES_ANGLE = 1 << 21,
272     GFXSTREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT = 1 << 22,
273 };
274 
275 // Sets backend flags for different kinds of initialization.
276 // Default (and default if not called): flags == 0
277 // Needs to be called before |gfxstream_backend_init|.
gfxstream_backend_set_flags(uint32_t flags)278 extern "C" VG_EXPORT void gfxstream_backend_set_flags(uint32_t flags) {
279     sBackendFlags = flags;
280 }
281 
gfxstream_backend_init(uint32_t display_width,uint32_t display_height,uint32_t display_type,void * renderer_cookie,int renderer_flags,struct virgl_renderer_callbacks * virglrenderer_callbacks)282 extern "C" VG_EXPORT void gfxstream_backend_init(
283     uint32_t display_width,
284     uint32_t display_height,
285     uint32_t display_type,
286     void* renderer_cookie,
287     int renderer_flags,
288     struct virgl_renderer_callbacks* virglrenderer_callbacks) {
289 
290 
291     // First we make some agents available.
292 
293 
294     GFXS_LOG("start. display dimensions: width %u height %u. backend flags: 0x%x renderer flags: 0x%x",
295              display_width, display_height, sBackendFlags, renderer_flags);
296 
297     AvdInfo** avdInfoPtr = aemu_get_android_avdInfoPtr();
298 
299     (*avdInfoPtr) = avdInfo_newCustom(
300         "goldfish_opengl_test",
301         28,
302         "x86_64",
303         "x86_64",
304         true /* is google APIs */,
305         AVD_PHONE);
306 
307     // Flags processing
308 
309     // TODO: hook up "gfxstream egl" to the renderer flags
310     // GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT in crosvm
311     // as it's specified from launch_cvd.
312     // At the moment, use ANDROID_GFXSTREAM_EGL=1
313     // For test on GCE
314     if (android::base::getEnvironmentVariable("ANDROID_GFXSTREAM_EGL") == "1") {
315         android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
316         android::base::setEnvironmentVariable("ANDROID_EMUGL_LOG_PRINT", "1");
317         android::base::setEnvironmentVariable("ANDROID_EMUGL_VERBOSE", "1");
318     }
319     // end for test on GCE
320 
321     android::base::setEnvironmentVariable("ANDROID_EMU_HEADLESS", "1");
322     android::base::setEnvironmentVariable("ANDROID_EMU_SANDBOX", "1");
323     android::base::setEnvironmentVariable("ANDROID_EMUGL_FIXED_BACKEND_LIST", "1");
324     bool vkDisabledByEnv = android::base::getEnvironmentVariable("ANDROID_EMU_DISABLE_VULKAN") == "1";
325     bool vkDisabledByFlag =
326         (sBackendFlags & GFXSTREAM_BACKEND_FLAGS_NO_VK_BIT) ||
327         (renderer_flags & GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT);
328     bool enableVk = !vkDisabledByEnv && !vkDisabledByFlag;
329 
330     bool egl2eglByEnv = android::base::getEnvironmentVariable("ANDROID_EGL_ON_EGL") == "1";
331     bool egl2eglByFlag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_USE_EGL_BIT;
332     bool enable_egl2egl = egl2eglByFlag || egl2eglByEnv;
333     if (enable_egl2egl) {
334         android::base::setEnvironmentVariable("ANDROID_GFXSTREAM_EGL", "1");
335         android::base::setEnvironmentVariable("ANDROID_EGL_ON_EGL", "1");
336     }
337 
338     bool ignoreHostGlErrorsFlag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_IGNORE_HOST_GL_ERRORS_BIT;
339     bool nativeTextureDecompression = renderer_flags & GFXSTREAM_RENDERER_FLAGS_NATIVE_TEXTURE_DECOMPRESSION_BIT;
340     bool bptcTextureSupport = renderer_flags & GFXSTREAM_RENDERER_FLAGS_ENABLE_BPTC_TEXTURES_BIT;
341     bool s3tcTextureSupport = renderer_flags & GFXSTREAM_RENDERER_FLAGS_ENABLE_S3TC_TEXTURES_BIT;
342     bool syncFdDisabledByFlag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_NO_SYNCFD_BIT;
343     bool surfaceless =
344             renderer_flags & GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT;
345     bool enableGlEs31Flag = renderer_flags & GFXSTREAM_RENDERER_FLAGS_ENABLE_GLES31_BIT;
346     bool guestUsesAngle = renderer_flags & GFXSTREAM_RENDERER_FLAGS_GUEST_USES_ANGLE;
347     bool useVulkanNativeSwapchain =
348         renderer_flags & GFXSTREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT;
349 
350     GFXS_LOG("Vulkan enabled? %d", enableVk);
351     GFXS_LOG("egl2egl enabled? %d", enable_egl2egl);
352     GFXS_LOG("ignore host gl errors enabled? %d", ignoreHostGlErrorsFlag);
353     GFXS_LOG("syncfd enabled? %d", !syncFdDisabledByFlag);
354     GFXS_LOG("use native texture decompression if available? %d", nativeTextureDecompression);
355     GFXS_LOG("enable BPTC support if available? %d", bptcTextureSupport);
356     GFXS_LOG("enable S3TC support if available? %d", s3tcTextureSupport);
357     GFXS_LOG("surfaceless? %d", surfaceless);
358     GFXS_LOG("OpenGL ES 3.1 enabled? %d", enableGlEs31Flag);
359     GFXS_LOG("guest using ANGLE? %d", guestUsesAngle);
360     GFXS_LOG("use Vulkan native swapchain on the host? %d",
361              useVulkanNativeSwapchain);
362 
363     // Need to manually set the GLES backend paths in gfxstream environment
364     // because the library search paths are not automatically set to include
365     // the directory in whioch the GLES backend resides.
366 #if defined(__linux__)
367 #define GFXSTREAM_LIB_SUFFIX ".so"
368 #elif defined(__APPLE__)
369 #define GFXSTREAM_LIB_SUFFIX ".dylib"
370 #else // Windows
371 #define GFXSTREAM_LIB_SUFFIX ".dll"
372 #endif
373 
374     feature_set_enabled_override(
375             kFeature_GLPipeChecksum, false);
376     feature_set_enabled_override(
377             kFeature_GLESDynamicVersion, true);
378     feature_set_enabled_override(
379             kFeature_PlayStoreImage, !enableGlEs31Flag);
380     feature_set_enabled_override(
381             kFeature_GLDMA, false);
382     feature_set_enabled_override(
383             kFeature_GLAsyncSwap, false);
384     feature_set_enabled_override(
385             kFeature_RefCountPipe, false);
386     feature_set_enabled_override(
387             kFeature_NoDelayCloseColorBuffer, true);
388     feature_set_enabled_override(
389             kFeature_IgnoreHostOpenGLErrors, ignoreHostGlErrorsFlag);
390     feature_set_enabled_override(
391             kFeature_NativeTextureDecompression, nativeTextureDecompression);
392     feature_set_enabled_override(
393             kFeature_BptcTextureSupport, bptcTextureSupport);
394     feature_set_enabled_override(
395             kFeature_S3tcTextureSupport, s3tcTextureSupport);
396     feature_set_enabled_override(
397             kFeature_GLDirectMem, false);
398     feature_set_enabled_override(
399             kFeature_Vulkan, enableVk);
400     feature_set_enabled_override(
401             kFeature_VulkanSnapshots, false);
402     feature_set_enabled_override(
403             kFeature_VulkanNullOptionalStrings, true);
404     feature_set_enabled_override(
405             kFeature_VulkanShaderFloat16Int8, true);
406     feature_set_enabled_override(
407             kFeature_HostComposition, true);
408     feature_set_enabled_override(
409             kFeature_VulkanIgnoredHandles, true);
410     feature_set_enabled_override(
411             kFeature_VirtioGpuNext, true);
412     feature_set_enabled_override(
413             kFeature_VirtioGpuNativeSync, !syncFdDisabledByFlag);
414     feature_set_enabled_override(
415             kFeature_GuestUsesAngle, guestUsesAngle);
416     feature_set_enabled_override(
417             kFeature_VulkanQueueSubmitWithCommands, true);
418     feature_set_enabled_override(kFeature_VulkanNativeSwapchain,
419                                  useVulkanNativeSwapchain);
420     feature_set_enabled_override(
421             kFeature_VulkanBatchedDescriptorSetUpdate, true);
422 
423     if (useVulkanNativeSwapchain && !enableVk) {
424         fprintf(stderr,
425                 "%s: can't enable vulkan native swapchain, Vulkan is disabled, "
426                 "fatal\n",
427                 __func__);
428         abort();
429     }
430 
431     emugl::vkDispatch(false /* don't use test ICD */);
432 
433     auto androidHw = aemu_get_android_hw();
434 
435     androidHw->hw_gltransport_asg_writeBufferSize = 1048576;
436     androidHw->hw_gltransport_asg_writeStepSize = 262144;
437     androidHw->hw_gltransport_asg_dataRingSize = 524288;
438     androidHw->hw_gltransport_drawFlushInterval = 10000;
439 
440     EmuglConfig config;
441 
442     // Make all the console agents available.
443     android::emulation::injectConsoleAgents(android::emulation::GfxStreamAndroidConsoleFactory());
444 
445     emuglConfig_init(&config, true /* gpu enabled */, "auto",
446                      enable_egl2egl ? "swiftshader_indirect" : "host",
447                      64,          /* bitness */
448                      surfaceless, /* no window */
449                      false,       /* blacklisted */
450                      false,       /* has guest renderer */
451                      WINSYS_GLESBACKEND_PREFERENCE_AUTO,
452                      true /* force host gpu vulkan */);
453 
454     emuglConfig_setupEnv(&config);
455 
456     android_prepareOpenglesEmulation();
457 
458     {
459         static emugl::RenderLibPtr renderLibPtr = initLibrary();
460         void* egldispatch = renderLibPtr->getEGLDispatch();
461         void* glesv2Dispatch = renderLibPtr->getGLESv2Dispatch();
462         android_setOpenglesEmulation(
463                 renderLibPtr.get(), egldispatch, glesv2Dispatch);
464     }
465 
466     int maj;
467     int min;
468     android_startOpenglesRenderer(
469         display_width, display_height, 1, 28,
470         getConsoleAgents()->vm,
471         getConsoleAgents()->emu,
472         getConsoleAgents()->multi_display,
473         &maj, &min);
474 
475     char* vendor = nullptr;
476     char* renderer = nullptr;
477     char* version = nullptr;
478 
479     android_getOpenglesHardwareStrings(
480         &vendor, &renderer, &version);
481 
482     GFXS_LOG("GL strings; [%s] [%s] [%s].\n",
483              vendor, renderer, version);
484 
485     auto openglesRenderer = android_getOpenglesRenderer();
486 
487     if (!openglesRenderer) {
488         fprintf(stderr, "%s: no renderer started, fatal\n", __func__);
489         abort();
490     }
491 
492     address_space_set_vm_operations(getConsoleAgents()->vm);
493     android_init_opengles_pipe();
494     android_opengles_pipe_set_recv_mode(2 /* virtio-gpu */);
495     android_init_refcount_pipe();
496 
497     sGetPixelsFunc = android_getReadPixelsFunc();
498 
499     pipe_virgl_renderer_init(renderer_cookie, renderer_flags, virglrenderer_callbacks);
500 
501     GFXS_LOG("Started renderer");
502 
503     if (surfaceless) {
504         set_post_callback(nullptr, default_post_callback, display_type);
505     }
506 }
507 
gfxstream_backend_setup_window(void * native_window_handle,int32_t window_x,int32_t window_y,int32_t window_width,int32_t window_height,int32_t fb_width,int32_t fb_height)508 extern "C" VG_EXPORT void gfxstream_backend_setup_window(
509         void* native_window_handle,
510         int32_t window_x,
511         int32_t window_y,
512         int32_t window_width,
513         int32_t window_height,
514         int32_t fb_width,
515         int32_t fb_height) {
516     android_showOpenglesWindow(native_window_handle, window_x, window_y,
517                                window_width, window_height, fb_width, fb_height,
518                                1.0f, 0, false, false);
519 }
520 
set_post_callback(struct renderer_display_info * r,post_callback_t func,uint32_t display_type)521 static void set_post_callback(struct renderer_display_info* r, post_callback_t func, uint32_t display_type) {
522 
523     // crosvm needs bgra readback depending on the display type
524     bool use_bgra_readback = false;
525     switch (display_type) {
526         case POST_CALLBACK_DISPLAY_TYPE_X:
527             GFXS_LOG("using display type: X11");
528             use_bgra_readback = true;
529             break;
530         case POST_CALLBACK_DISPLAY_TYPE_WAYLAND_SHARED_MEM:
531             GFXS_LOG("using display type: wayland shared mem");
532             break;
533         case POST_CALLBACK_DISPLAY_TYPE_WINDOWS_HWND:
534             GFXS_LOG("using display type: windows hwnd");
535             break;
536         default:
537             break;
538     }
539 
540     android_setPostCallback(func, r, false, 0);
541 }
542 
gfxstream_backend_teardown()543 extern "C" VG_EXPORT void gfxstream_backend_teardown() {
544     android_finishOpenglesRenderer();
545     android_hideOpenglesWindow();
546     android_stopOpenglesRenderer(true);
547 }
548 
gfxstream_backend_set_screen_mask(int width,int height,const unsigned char * rgbaData)549 extern "C" VG_EXPORT void gfxstream_backend_set_screen_mask(int width, int height, const unsigned char* rgbaData) {
550     android_setOpenglesScreenMask(width, height, rgbaData);
551 }
552 
get_pixels(void * pixels,uint32_t bytes)553 extern "C" VG_EXPORT void get_pixels(void* pixels, uint32_t bytes) {
554     //TODO: support display > 0
555     sGetPixelsFunc(pixels, bytes, 0);
556 }
557 
goldfish_pipe_get_service_ops()558 extern "C" const GoldfishPipeServiceOps* goldfish_pipe_get_service_ops() {
559     return &goldfish_pipe_service_ops;
560 }
561 
562