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