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