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