1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "RenderControl.h"
18
19 #include <inttypes.h>
20 #include <string.h>
21
22 #include <atomic>
23 #include <memory>
24
25 #include "ChecksumCalculatorThreadInfo.h"
26 #include "FrameBuffer.h"
27 #include "GLESVersionDetector.h"
28 #include "OpenGLESDispatch/DispatchTables.h"
29 #include "OpenGLESDispatch/EGLDispatch.h"
30 #include "RenderThreadInfo.h"
31 #include "RenderThreadInfoGl.h"
32 #include "SyncThread.h"
33 #include "aemu/base/Tracing.h"
34 #include "host-common/feature_control.h"
35 #include "host-common/logging.h"
36 #include "host-common/misc.h"
37 #include "host-common/opengl/misc.h"
38 #include "host-common/sync_device.h"
39 #include "stream-servers/compressedTextureFormats/AstcCpuDecompressor.h"
40 #include "vulkan/VkCommonOperations.h"
41 #include "vulkan/VkDecoderGlobalState.h"
42
43 namespace gfxstream {
44
45 using android::base::AutoLock;
46 using android::base::Lock;
47 using emugl::emugl_sync_device_exists;
48 using emugl::emugl_sync_register_trigger_wait;
49 using gl::EmulatedEglFenceSync;
50 using gl::GLES_DISPATCH_MAX_VERSION_2;
51 using gl::GLES_DISPATCH_MAX_VERSION_3_0;
52 using gl::GLES_DISPATCH_MAX_VERSION_3_1;
53 using gl::GLESApi;
54 using gl::GLESApi_CM;
55 using gl::GLESDispatchMaxVersion;
56 using gl::RenderThreadInfoGl;
57
58 #define DEBUG 0
59 #define DEBUG_GRALLOC_SYNC 0
60 #define DEBUG_EGL_SYNC 0
61
62 #define RENDERCONTROL_DPRINT(...) \
63 do { \
64 if (DEBUG) { \
65 fprintf(stderr, __VA_ARGS__); \
66 } \
67 } while (0)
68
69 #if DEBUG_GRALLOC_SYNC
70 #define GRSYNC_DPRINT RENDERCONTROL_DPRINT
71 #else
72 #define GRSYNC_DPRINT(...)
73 #endif
74
75 #if DEBUG_EGL_SYNC
76 #define EGLSYNC_DPRINT RENDERCONTROL_DPRINT
77 #else
78 #define EGLSYNC_DPRINT(...)
79 #endif
80
81 // GrallocSync is a class that helps to reflect the behavior of
82 // gralloc_lock/gralloc_unlock on the guest.
83 // If we don't use this, apps that use gralloc buffers (such as webcam)
84 // will have out-of-order frames,
85 // as GL calls from different threads in the guest
86 // are allowed to arrive at the host in any ordering.
87 class GrallocSync {
88 public:
GrallocSync()89 GrallocSync() {
90 // Having in-order webcam frames is nice, but not at the cost
91 // of potential deadlocks;
92 // we need to be careful of what situations in which
93 // we actually lock/unlock the gralloc color buffer.
94 //
95 // To avoid deadlock:
96 // we require rcColorBufferCacheFlush to be called
97 // whenever gralloc_lock is called on the guest,
98 // and we require rcUpdateWindowColorBuffer to be called
99 // whenever gralloc_unlock is called on the guest.
100 //
101 // Some versions of the system image optimize out
102 // the call to rcUpdateWindowColorBuffer in the case of zero
103 // width/height, but since we're using that as synchronization,
104 // that lack of calling can lead to a deadlock on the host
105 // in many situations
106 // (switching camera sides, exiting benchmark apps, etc).
107 // So, we put GrallocSync under the feature control.
108 mEnabled = feature_is_enabled(kFeature_GrallocSync);
109
110 // There are two potential tricky situations to handle:
111 // a. Multiple users of gralloc buffers that all want to
112 // call gralloc_lock. This is obeserved to happen on older APIs
113 // (<= 19).
114 // b. The pipe doesn't have to preserve ordering of the
115 // gralloc_lock and gralloc_unlock commands themselves.
116 //
117 // To handle a), notice the situation is one of one type of user
118 // needing multiple locks that needs to exclude concurrent use
119 // by another type of user. This maps well to a read/write lock,
120 // where gralloc_lock and gralloc_unlock users are readers
121 // and rcFlushWindowColorBuffer is the writer.
122 // From the perspective of the host preparing and posting
123 // buffers, these are indeed read/write operations.
124 //
125 // To handle b), we give up on locking when the state is observed
126 // to be bad. lockState tracks how many color buffer locks there are.
127 // If lockState < 0, it means we definitely have an unlock before lock
128 // sort of situation, and should give up.
129 lockState = 0;
130 }
131
132 // lockColorBufferPrepare is designed to handle
133 // gralloc_lock/unlock requests, and uses the read lock.
134 // When rcFlushWindowColorBuffer is called (when frames are posted),
135 // we use the write lock (see GrallocSyncPostLock).
lockColorBufferPrepare()136 void lockColorBufferPrepare() {
137 int newLockState = ++lockState;
138 if (mEnabled && newLockState == 1) {
139 mGrallocColorBufferLock.lockRead();
140 } else if (mEnabled) {
141 GRSYNC_DPRINT("warning: recursive/multiple locks from guest!");
142 }
143 }
unlockColorBufferPrepare()144 void unlockColorBufferPrepare() {
145 int newLockState = --lockState;
146 if (mEnabled && newLockState == 0) mGrallocColorBufferLock.unlockRead();
147 }
148 android::base::ReadWriteLock mGrallocColorBufferLock;
149 private:
150 bool mEnabled;
151 std::atomic<int> lockState;
152 DISALLOW_COPY_ASSIGN_AND_MOVE(GrallocSync);
153 };
154
155 class GrallocSyncPostLock : public android::base::AutoWriteLock {
156 public:
GrallocSyncPostLock(GrallocSync & grallocsync)157 GrallocSyncPostLock(GrallocSync& grallocsync) :
158 android::base::AutoWriteLock(grallocsync.mGrallocColorBufferLock) { }
159 };
160
sGrallocSync()161 static GrallocSync* sGrallocSync() {
162 static GrallocSync* g = new GrallocSync;
163 return g;
164 }
165
166 static const GLint rendererVersion = 1;
167
168 // GLAsyncSwap version history:
169 // "ANDROID_EMU_NATIVE_SYNC": original version
170 // "ANDROIDEMU_native_sync_v2": +cleanup of sync objects
171 // "ANDROIDEMU_native_sync_v3": EGL_KHR_wait_sync
172 // "ANDROIDEMU_native_sync_v4": Correct eglGetSyncAttrib via rcIsSyncSignaled
173 // (We need all the different strings to not be prefixes of any other
174 // due to how they are checked for in the GL extensions on the guest)
175 static const char* kAsyncSwapStrV2 = "ANDROID_EMU_native_sync_v2";
176 static const char* kAsyncSwapStrV3 = "ANDROID_EMU_native_sync_v3";
177 static const char* kAsyncSwapStrV4 = "ANDROID_EMU_native_sync_v4";
178
179 // DMA version history:
180 // "ANDROID_EMU_dma_v1": add dma device and rcUpdateColorBufferDMA and do
181 // yv12 conversion on the GPU
182 // "ANDROID_EMU_dma_v2": adds DMA support glMapBufferRange (and unmap)
183 static const char* kDma1Str = "ANDROID_EMU_dma_v1";
184 static const char* kDma2Str = "ANDROID_EMU_dma_v2";
185 static const char* kDirectMemStr = "ANDROID_EMU_direct_mem";
186
187 // GLESDynamicVersion: up to 3.1 so far
188 static const char* kGLESDynamicVersion_2 = "ANDROID_EMU_gles_max_version_2";
189 static const char* kGLESDynamicVersion_3_0 = "ANDROID_EMU_gles_max_version_3_0";
190 static const char* kGLESDynamicVersion_3_1 = "ANDROID_EMU_gles_max_version_3_1";
191
192 // HWComposer Host Composition
193 static const char* kHostCompositionV1 = "ANDROID_EMU_host_composition_v1";
194 static const char* kHostCompositionV2 = "ANDROID_EMU_host_composition_v2";
195
196 // Vulkan
197 static const char* kVulkanFeatureStr = "ANDROID_EMU_vulkan";
198 static const char* kDeferredVulkanCommands = "ANDROID_EMU_deferred_vulkan_commands";
199 static const char* kVulkanNullOptionalStrings = "ANDROID_EMU_vulkan_null_optional_strings";
200 static const char* kVulkanCreateResourcesWithRequirements = "ANDROID_EMU_vulkan_create_resources_with_requirements";
201
202 // treat YUV420_888 as NV21
203 static const char* kYUV420888toNV21 = "ANDROID_EMU_YUV420_888_to_NV21";
204
205 // Cache YUV frame
206 static const char* kYUVCache = "ANDROID_EMU_YUV_Cache";
207
208 // GL protocol v2
209 static const char* kAsyncUnmapBuffer = "ANDROID_EMU_async_unmap_buffer";
210 // Vulkan: Correct marshaling for ignored handles
211 static const char* kVulkanIgnoredHandles = "ANDROID_EMU_vulkan_ignored_handles";
212
213 // virtio-gpu-next
214 static const char* kVirtioGpuNext = "ANDROID_EMU_virtio_gpu_next";
215
216 // address space subdevices
217 static const char* kHasSharedSlotsHostMemoryAllocator = "ANDROID_EMU_has_shared_slots_host_memory_allocator";
218
219 // vulkan free memory sync
220 static const char* kVulkanFreeMemorySync = "ANDROID_EMU_vulkan_free_memory_sync";
221
222 // virtio-gpu native sync
223 static const char* kVirtioGpuNativeSync = "ANDROID_EMU_virtio_gpu_native_sync";
224
225 // Struct defs for VK_KHR_shader_float16_int8
226 static const char* kVulkanShaderFloat16Int8 = "ANDROID_EMU_vulkan_shader_float16_int8";
227
228 // Async queue submit
229 static const char* kVulkanAsyncQueueSubmit = "ANDROID_EMU_vulkan_async_queue_submit";
230
231 // Host side tracing
232 static const char* kHostSideTracing = "ANDROID_EMU_host_side_tracing";
233
234 // Some frame commands we can easily make async
235 // rcMakeCurrent
236 // rcCompose
237 // rcDestroySyncKHR
238 static const char* kAsyncFrameCommands = "ANDROID_EMU_async_frame_commands";
239
240 // Queue submit with commands
241 static const char* kVulkanQueueSubmitWithCommands = "ANDROID_EMU_vulkan_queue_submit_with_commands";
242
243 // Batched descriptor set update
244 static const char* kVulkanBatchedDescriptorSetUpdate = "ANDROID_EMU_vulkan_batched_descriptor_set_update";
245
246 // Synchronized glBufferData call
247 static const char* kSyncBufferData = "ANDROID_EMU_sync_buffer_data";
248
249 // Async vkQSRI
250 static const char* kVulkanAsyncQsri = "ANDROID_EMU_vulkan_async_qsri";
251
252 // Read color buffer DMA
253 static const char* kReadColorBufferDma = "ANDROID_EMU_read_color_buffer_dma";
254
255 // Multiple display configs
256 static const char* kHWCMultiConfigs= "ANDROID_EMU_hwc_multi_configs";
257
258 static void rcTriggerWait(uint64_t glsync_ptr,
259 uint64_t thread_ptr,
260 uint64_t timeline);
261
registerTriggerWait()262 void registerTriggerWait() {
263 emugl_sync_register_trigger_wait(rcTriggerWait);
264 }
265
rcGetRendererVersion()266 static GLint rcGetRendererVersion()
267 {
268 registerTriggerWait();
269
270 sGrallocSync();
271 return rendererVersion;
272 }
273
rcGetEGLVersion(EGLint * major,EGLint * minor)274 static EGLint rcGetEGLVersion(EGLint* major, EGLint* minor)
275 {
276 FrameBuffer *fb = FrameBuffer::getFB();
277 if (!fb) {
278 return EGL_FALSE;
279 }
280 fb->getEmulationGl().getEglVersion(major, minor);
281
282 return EGL_TRUE;
283 }
284
rcQueryEGLString(EGLenum name,void * buffer,EGLint bufferSize)285 static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize)
286 {
287 FrameBuffer *fb = FrameBuffer::getFB();
288 if (!fb) {
289 return 0;
290 }
291
292 const char* str = gl::s_egl.eglQueryString(fb->getDisplay(), name);
293 if (!str) {
294 return 0;
295 }
296
297 std::string eglStr(str);
298 if ((fb->getMaxGLESVersion() >= GLES_DISPATCH_MAX_VERSION_3_0) &&
299 feature_is_enabled(kFeature_GLESDynamicVersion) &&
300 eglStr.find("EGL_KHR_create_context") == std::string::npos) {
301 eglStr += "EGL_KHR_create_context ";
302 }
303
304 int len = eglStr.size() + 1;
305 if (!buffer || len > bufferSize) {
306 return -len;
307 }
308
309 strcpy((char *)buffer, eglStr.c_str());
310 return len;
311 }
312
shouldEnableAsyncSwap()313 static bool shouldEnableAsyncSwap() {
314 bool isPhone = true;
315 bool playStoreImage = feature_is_enabled(
316 kFeature_PlayStoreImage);
317 return feature_is_enabled(kFeature_GLAsyncSwap) &&
318 emugl_sync_device_exists() && (isPhone || playStoreImage) &&
319 sizeof(void*) == 8;
320 }
321
shouldEnableVirtioGpuNativeSync()322 static bool shouldEnableVirtioGpuNativeSync() {
323 return feature_is_enabled(kFeature_VirtioGpuNativeSync);
324 }
325
shouldEnableHostComposition()326 static bool shouldEnableHostComposition() {
327 return feature_is_enabled(kFeature_HostComposition);
328 }
329
shouldEnableVulkan()330 static bool shouldEnableVulkan() {
331 // TODO: Restrict further to devices supporting external memory.
332 return feature_is_enabled(kFeature_Vulkan) && vk::getGlobalVkEmulation() &&
333 vk::VkDecoderGlobalState::get()->getHostFeatureSupport().supportsVulkan;
334 }
335
shouldEnableDeferredVulkanCommands()336 static bool shouldEnableDeferredVulkanCommands() {
337 auto supportInfo = vk::VkDecoderGlobalState::get()->getHostFeatureSupport();
338 return supportInfo.supportsVulkan &&
339 supportInfo.useDeferredCommands;
340 }
341
shouldEnableCreateResourcesWithRequirements()342 static bool shouldEnableCreateResourcesWithRequirements() {
343 auto supportInfo = vk::VkDecoderGlobalState::get()->getHostFeatureSupport();
344 return supportInfo.supportsVulkan &&
345 supportInfo.useCreateResourcesWithRequirements;
346 }
347
shouldEnableVulkanShaderFloat16Int8()348 static bool shouldEnableVulkanShaderFloat16Int8() {
349 return shouldEnableVulkan() &&
350 feature_is_enabled(kFeature_VulkanShaderFloat16Int8);
351 }
352
shouldEnableAsyncQueueSubmit()353 static bool shouldEnableAsyncQueueSubmit() {
354 return shouldEnableVulkan();
355 }
356
shouldEnableVulkanAsyncQsri()357 static bool shouldEnableVulkanAsyncQsri() {
358 return shouldEnableVulkan() &&
359 (feature_is_enabled(kFeature_GLAsyncSwap) ||
360 (feature_is_enabled(kFeature_VirtioGpuNativeSync) &&
361 feature_is_enabled(kFeature_VirtioGpuFenceContexts)));
362 }
363
shouldEnableVsyncGatedSyncFences()364 static bool shouldEnableVsyncGatedSyncFences() {
365 return shouldEnableAsyncSwap();
366 }
367
maxVersionToFeatureString(GLESDispatchMaxVersion version)368 const char* maxVersionToFeatureString(GLESDispatchMaxVersion version) {
369 switch (version) {
370 case GLES_DISPATCH_MAX_VERSION_2:
371 return kGLESDynamicVersion_2;
372 case GLES_DISPATCH_MAX_VERSION_3_0:
373 return kGLESDynamicVersion_3_0;
374 case GLES_DISPATCH_MAX_VERSION_3_1:
375 return kGLESDynamicVersion_3_1;
376 default:
377 return kGLESDynamicVersion_2;
378 }
379 }
380
shouldEnableQueueSubmitWithCommands()381 static bool shouldEnableQueueSubmitWithCommands() {
382 return shouldEnableVulkan() &&
383 feature_is_enabled(kFeature_VulkanQueueSubmitWithCommands);
384 }
385
shouldEnableBatchedDescriptorSetUpdate()386 static bool shouldEnableBatchedDescriptorSetUpdate() {
387 return shouldEnableVulkan() &&
388 shouldEnableQueueSubmitWithCommands() &&
389 feature_is_enabled(kFeature_VulkanBatchedDescriptorSetUpdate);
390 }
391
392 // OpenGL ES 3.x support involves changing the GL_VERSION string, which is
393 // assumed to be formatted in the following way:
394 // "OpenGL ES-CM 1.m <vendor-info>" or
395 // "OpenGL ES M.m <vendor-info>"
396 // where M is the major version number and m is minor version number. If the
397 // GL_VERSION string doesn't reflect the maximum available version of OpenGL
398 // ES, many apps will not be able to detect support. We need to mess with the
399 // version string in the first place since the underlying backend (whether it
400 // is Translator, SwiftShader, ANGLE, et al) may not advertise a GL_VERSION
401 // string reflecting their maximum capabilities.
replaceESVersionString(const std::string & prev,const std::string & newver)402 std::string replaceESVersionString(const std::string& prev,
403 const std::string& newver) {
404
405 // There is no need to fiddle with the string
406 // if we are in a ES 1.x context.
407 // Such contexts are considered as a special case that must
408 // be untouched.
409 if (prev.find("ES-CM") != std::string::npos) {
410 return prev;
411 }
412
413 size_t esStart = prev.find("ES ");
414 size_t esEnd = prev.find(" ", esStart + 3);
415
416 if (esStart == std::string::npos ||
417 esEnd == std::string::npos) {
418 // Account for out-of-spec version strings.
419 fprintf(stderr, "%s: Error: invalid OpenGL ES version string %s\n",
420 __func__, prev.c_str());
421 return prev;
422 }
423
424 std::string res = prev.substr(0, esStart + 3);
425 res += newver;
426 res += prev.substr(esEnd);
427
428 return res;
429 }
430
431 // If the GLES3 feature is disabled, we also want to splice out
432 // OpenGL extensions that should not appear in a GLES2 system.
removeExtension(std::string & currExts,const std::string & toRemove)433 void removeExtension(std::string& currExts, const std::string& toRemove) {
434 size_t pos = currExts.find(toRemove);
435
436 if (pos != std::string::npos)
437 currExts.erase(pos, toRemove.length());
438 }
439
rcGetGLString(EGLenum name,void * buffer,EGLint bufferSize)440 static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) {
441 RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
442
443 // whatever we end up returning,
444 // it will have a terminating \0,
445 // so account for it here.
446 std::string glStr;
447
448 if (tInfo && tInfo->currContext.get()) {
449 const char *str = nullptr;
450 if (tInfo->currContext->clientVersion() > GLESApi_CM) {
451 str = (const char*)gl::s_gles2.glGetString(name);
452 }
453 else {
454 str = (const char*)gl::s_gles1.glGetString(name);
455 }
456 if (str) {
457 glStr += str;
458 }
459 }
460
461 // We add the maximum supported GL protocol number into GL_EXTENSIONS
462
463 // filter extensions by name to match guest-side support
464 GLESDispatchMaxVersion maxVersion = FrameBuffer::getFB()->getMaxGLESVersion();
465 if (name == GL_EXTENSIONS) {
466 glStr = gl::filterExtensionsBasedOnMaxVersion(maxVersion, glStr);
467 }
468
469 bool isChecksumEnabled =
470 feature_is_enabled(kFeature_GLPipeChecksum);
471 bool asyncSwapEnabled = shouldEnableAsyncSwap();
472 bool virtioGpuNativeSyncEnabled = shouldEnableVirtioGpuNativeSync();
473 bool dma1Enabled =
474 feature_is_enabled(kFeature_GLDMA);
475 bool dma2Enabled =
476 feature_is_enabled(kFeature_GLDMA2);
477 bool directMemEnabled =
478 feature_is_enabled(kFeature_GLDirectMem);
479 bool hostCompositionEnabled = shouldEnableHostComposition();
480 bool vulkanEnabled = shouldEnableVulkan();
481 bool deferredVulkanCommandsEnabled =
482 shouldEnableVulkan() && shouldEnableDeferredVulkanCommands();
483 bool vulkanNullOptionalStringsEnabled =
484 shouldEnableVulkan() && feature_is_enabled(kFeature_VulkanNullOptionalStrings);
485 bool vulkanCreateResourceWithRequirementsEnabled =
486 shouldEnableVulkan() && shouldEnableCreateResourcesWithRequirements();
487 bool YUV420888toNV21Enabled =
488 feature_is_enabled(kFeature_YUV420888toNV21);
489 bool YUVCacheEnabled =
490 feature_is_enabled(kFeature_YUVCache);
491 bool AsyncUnmapBufferEnabled = feature_is_enabled(kFeature_AsyncComposeSupport);
492 bool vulkanIgnoredHandlesEnabled =
493 shouldEnableVulkan() && feature_is_enabled(kFeature_VulkanIgnoredHandles);
494 bool virtioGpuNextEnabled =
495 feature_is_enabled(kFeature_VirtioGpuNext);
496 bool hasSharedSlotsHostMemoryAllocatorEnabled =
497 feature_is_enabled(kFeature_HasSharedSlotsHostMemoryAllocator);
498 bool vulkanFreeMemorySyncEnabled =
499 shouldEnableVulkan();
500 bool vulkanShaderFloat16Int8Enabled = shouldEnableVulkanShaderFloat16Int8();
501 bool vulkanAsyncQueueSubmitEnabled = shouldEnableAsyncQueueSubmit();
502 bool vulkanQueueSubmitWithCommands = shouldEnableQueueSubmitWithCommands();
503 bool vulkanBatchedDescriptorSetUpdate = shouldEnableBatchedDescriptorSetUpdate();
504 bool syncBufferDataEnabled = true;
505 bool vulkanAsyncQsri = shouldEnableVulkanAsyncQsri();
506 bool readColorBufferDma = directMemEnabled && hasSharedSlotsHostMemoryAllocatorEnabled;
507 bool hwcMultiConfigs = feature_is_enabled(kFeature_HWCMultiConfigs);
508
509 if (isChecksumEnabled && name == GL_EXTENSIONS) {
510 glStr += ChecksumCalculatorThreadInfo::getMaxVersionString();
511 glStr += " ";
512 }
513
514 if (asyncSwapEnabled && name == GL_EXTENSIONS) {
515 glStr += kAsyncSwapStrV2;
516 glStr += " "; // for compatibility with older system images
517 // Only enable EGL_KHR_wait_sync (and above) for host gpu.
518 if (emugl::getRenderer() == SELECTED_RENDERER_HOST) {
519 glStr += kAsyncSwapStrV3;
520 glStr += " ";
521 glStr += kAsyncSwapStrV4;
522 glStr += " ";
523 }
524 }
525
526 if (dma1Enabled && name == GL_EXTENSIONS) {
527 glStr += kDma1Str;
528 glStr += " ";
529 }
530
531 if (dma2Enabled && name == GL_EXTENSIONS) {
532 glStr += kDma2Str;
533 glStr += " ";
534 }
535
536 if (directMemEnabled && name == GL_EXTENSIONS) {
537 glStr += kDirectMemStr;
538 glStr += " ";
539 }
540
541 if (hostCompositionEnabled && name == GL_EXTENSIONS) {
542 glStr += kHostCompositionV1;
543 glStr += " ";
544 }
545
546 if (hostCompositionEnabled && name == GL_EXTENSIONS) {
547 glStr += kHostCompositionV2;
548 glStr += " ";
549 }
550
551 if (vulkanEnabled && name == GL_EXTENSIONS) {
552 glStr += kVulkanFeatureStr;
553 glStr += " ";
554 }
555
556 if (deferredVulkanCommandsEnabled && name == GL_EXTENSIONS) {
557 glStr += kDeferredVulkanCommands;
558 glStr += " ";
559 }
560
561 if (vulkanNullOptionalStringsEnabled && name == GL_EXTENSIONS) {
562 glStr += kVulkanNullOptionalStrings;
563 glStr += " ";
564 }
565
566 if (vulkanCreateResourceWithRequirementsEnabled && name == GL_EXTENSIONS) {
567 glStr += kVulkanCreateResourcesWithRequirements;
568 glStr += " ";
569 }
570
571 if (YUV420888toNV21Enabled && name == GL_EXTENSIONS) {
572 glStr += kYUV420888toNV21;
573 glStr += " ";
574 }
575
576 if (YUVCacheEnabled && name == GL_EXTENSIONS) {
577 glStr += kYUVCache;
578 glStr += " ";
579 }
580
581 if (AsyncUnmapBufferEnabled && name == GL_EXTENSIONS) {
582 glStr += kAsyncUnmapBuffer;
583 glStr += " ";
584 }
585
586 if (vulkanIgnoredHandlesEnabled && name == GL_EXTENSIONS) {
587 glStr += kVulkanIgnoredHandles;
588 glStr += " ";
589 }
590
591 if (virtioGpuNextEnabled && name == GL_EXTENSIONS) {
592 glStr += kVirtioGpuNext;
593 glStr += " ";
594 }
595
596 if (hasSharedSlotsHostMemoryAllocatorEnabled && name == GL_EXTENSIONS) {
597 glStr += kHasSharedSlotsHostMemoryAllocator;
598 glStr += " ";
599 }
600
601 if (vulkanFreeMemorySyncEnabled && name == GL_EXTENSIONS) {
602 glStr += kVulkanFreeMemorySync;
603 glStr += " ";
604 }
605
606 if (vulkanShaderFloat16Int8Enabled && name == GL_EXTENSIONS) {
607 glStr += kVulkanShaderFloat16Int8;
608 glStr += " ";
609 }
610
611 if (vulkanAsyncQueueSubmitEnabled && name == GL_EXTENSIONS) {
612 glStr += kVulkanAsyncQueueSubmit;
613 glStr += " ";
614 }
615
616 if (vulkanQueueSubmitWithCommands && name == GL_EXTENSIONS) {
617 glStr += kVulkanQueueSubmitWithCommands;
618 glStr += " ";
619 }
620
621 if (vulkanBatchedDescriptorSetUpdate && name == GL_EXTENSIONS) {
622 glStr += kVulkanBatchedDescriptorSetUpdate;
623 glStr += " ";
624 }
625
626 if (virtioGpuNativeSyncEnabled && name == GL_EXTENSIONS) {
627 glStr += kVirtioGpuNativeSync;
628 glStr += " ";
629 }
630
631 if (syncBufferDataEnabled && name == GL_EXTENSIONS) {
632 glStr += kSyncBufferData;
633 glStr += " ";
634 }
635
636 if (vulkanAsyncQsri && name == GL_EXTENSIONS) {
637 glStr += kVulkanAsyncQsri;
638 glStr += " ";
639 }
640
641 if (readColorBufferDma && name == GL_EXTENSIONS) {
642 glStr += kReadColorBufferDma;
643 glStr += " ";
644 }
645
646 if (hwcMultiConfigs && name == GL_EXTENSIONS) {
647 glStr += kHWCMultiConfigs;
648 glStr += " ";
649 }
650
651 if (name == GL_EXTENSIONS) {
652
653 GLESDispatchMaxVersion guestExtVer = GLES_DISPATCH_MAX_VERSION_2;
654 if (feature_is_enabled(kFeature_GLESDynamicVersion)) {
655 // If the image is in ES 3 mode, add GL_OES_EGL_image_external_essl3 for better Skia support.
656 glStr += "GL_OES_EGL_image_external_essl3 ";
657 guestExtVer = maxVersion;
658 }
659
660 // If we have a GLES3 implementation, add the corresponding
661 // GLESv2 extensions as well.
662 if (maxVersion > GLES_DISPATCH_MAX_VERSION_2) {
663 glStr += "GL_OES_vertex_array_object ";
664 }
665
666
667
668 // ASTC LDR compressed texture support.
669 const std::string& glExtensions =
670 FrameBuffer::getFB()->hasEmulationGl()
671 ? FrameBuffer::getFB()->getEmulationGl().getGlesExtensionsString()
672 : "<no GL emulation>";
673 const bool hasNativeAstc =
674 glExtensions.find("GL_KHR_texture_compression_astc_ldr") != std::string::npos;
675 const bool hasAstcDecompressor = vk::AstcCpuDecompressor::get().available();
676 if (hasNativeAstc || hasAstcDecompressor) {
677 glStr += "GL_KHR_texture_compression_astc_ldr ";
678 } else {
679 RENDERCONTROL_DPRINT(
680 "rcGetGLString: ASTC not supported. CPU decompressor? %d. GL extensions: %s",
681 hasAstcDecompressor, glExtensions.c_str());
682 }
683
684 // Host side tracing support.
685 glStr += kHostSideTracing;
686 glStr += " ";
687
688 if (feature_is_enabled(kFeature_AsyncComposeSupport)) {
689 // Async makecurrent support.
690 glStr += kAsyncFrameCommands;
691 glStr += " ";
692 }
693
694 glStr += maxVersionToFeatureString(guestExtVer);
695 glStr += " ";
696 }
697
698 if (name == GL_VERSION) {
699 if (feature_is_enabled(kFeature_GLESDynamicVersion)) {
700 switch (maxVersion) {
701 // Underlying GLES implmentation's max version string
702 // is allowed to be higher than the version of the request
703 // for the context---it can create a higher version context,
704 // and return simply the max possible version overall.
705 case GLES_DISPATCH_MAX_VERSION_2:
706 glStr = replaceESVersionString(glStr, "2.0");
707 break;
708 case GLES_DISPATCH_MAX_VERSION_3_0:
709 glStr = replaceESVersionString(glStr, "3.0");
710 break;
711 case GLES_DISPATCH_MAX_VERSION_3_1:
712 glStr = replaceESVersionString(glStr, "3.1");
713 break;
714 default:
715 break;
716 }
717 } else {
718 glStr = replaceESVersionString(glStr, "2.0");
719 }
720 }
721
722 int nextBufferSize = glStr.size() + 1;
723
724 if (!buffer || nextBufferSize > bufferSize) {
725 return -nextBufferSize;
726 }
727
728 snprintf((char *)buffer, nextBufferSize, "%s", glStr.c_str());
729 return nextBufferSize;
730 }
731
rcGetNumConfigs(uint32_t * p_numAttribs)732 static EGLint rcGetNumConfigs(uint32_t* p_numAttribs)
733 {
734 int numConfigs = 0, numAttribs = 0;
735
736 FrameBuffer::getFB()->getConfigs()->getPackInfo(&numConfigs, &numAttribs);
737 if (p_numAttribs) {
738 *p_numAttribs = static_cast<uint32_t>(numAttribs);
739 }
740 return numConfigs;
741 }
742
rcGetConfigs(uint32_t bufSize,GLuint * buffer)743 static EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer)
744 {
745 GLuint bufferSize = (GLuint)bufSize;
746 return FrameBuffer::getFB()->getConfigs()->packConfigs(bufferSize, buffer);
747 }
748
rcChooseConfig(EGLint * attribs,uint32_t attribs_size,uint32_t * configs,uint32_t configs_size)749 static EGLint rcChooseConfig(EGLint *attribs,
750 uint32_t attribs_size,
751 uint32_t *configs,
752 uint32_t configs_size)
753 {
754 FrameBuffer *fb = FrameBuffer::getFB();
755 if (!fb) {
756 return 0;
757 }
758
759 if (attribs_size == 0) {
760 if (configs && configs_size > 0) {
761 // Pick the first config
762 *configs = 0;
763 if (attribs) *attribs = EGL_NONE;
764 }
765 }
766
767 return fb->getConfigs()->chooseConfig(
768 attribs, (EGLint*)configs, (EGLint)configs_size);
769 }
770
rcGetFBParam(EGLint param)771 static EGLint rcGetFBParam(EGLint param)
772 {
773 FrameBuffer *fb = FrameBuffer::getFB();
774 if (!fb) {
775 return 0;
776 }
777 return fb->getDisplayConfigsParam(0, param);
778 }
779
rcCreateContext(uint32_t config,uint32_t share,uint32_t glVersion)780 static uint32_t rcCreateContext(uint32_t config,
781 uint32_t share, uint32_t glVersion)
782 {
783 FrameBuffer *fb = FrameBuffer::getFB();
784 if (!fb) {
785 return 0;
786 }
787
788 HandleType ret = fb->createEmulatedEglContext(config, share, (GLESApi)glVersion);
789 return ret;
790 }
791
rcDestroyContext(uint32_t context)792 static void rcDestroyContext(uint32_t context)
793 {
794 FrameBuffer *fb = FrameBuffer::getFB();
795 if (!fb) {
796 return;
797 }
798
799 fb->destroyEmulatedEglContext(context);
800 }
801
rcCreateWindowSurface(uint32_t config,uint32_t width,uint32_t height)802 static uint32_t rcCreateWindowSurface(uint32_t config,
803 uint32_t width, uint32_t height)
804 {
805 FrameBuffer *fb = FrameBuffer::getFB();
806 if (!fb) {
807 return 0;
808 }
809
810 return fb->createEmulatedEglWindowSurface(config, width, height);
811 }
812
rcDestroyWindowSurface(uint32_t windowSurface)813 static void rcDestroyWindowSurface(uint32_t windowSurface)
814 {
815 FrameBuffer *fb = FrameBuffer::getFB();
816 if (!fb) {
817 return;
818 }
819
820 fb->destroyEmulatedEglWindowSurface(windowSurface);
821 }
822
rcCreateColorBuffer(uint32_t width,uint32_t height,GLenum internalFormat)823 static uint32_t rcCreateColorBuffer(uint32_t width,
824 uint32_t height, GLenum internalFormat)
825 {
826 FrameBuffer *fb = FrameBuffer::getFB();
827 if (!fb) {
828 return 0;
829 }
830
831 return fb->createColorBuffer(width, height, internalFormat,
832 FRAMEWORK_FORMAT_GL_COMPATIBLE);
833 }
834
rcCreateColorBufferDMA(uint32_t width,uint32_t height,GLenum internalFormat,int frameworkFormat)835 static uint32_t rcCreateColorBufferDMA(uint32_t width,
836 uint32_t height, GLenum internalFormat,
837 int frameworkFormat)
838 {
839 FrameBuffer *fb = FrameBuffer::getFB();
840 if (!fb) {
841 return 0;
842 }
843
844 return fb->createColorBuffer(width, height, internalFormat,
845 (FrameworkFormat)frameworkFormat);
846 }
847
rcOpenColorBuffer2(uint32_t colorbuffer)848 static int rcOpenColorBuffer2(uint32_t colorbuffer)
849 {
850 FrameBuffer *fb = FrameBuffer::getFB();
851 if (!fb) {
852 return -1;
853 }
854 return fb->openColorBuffer( colorbuffer );
855 }
856
rcOpenColorBuffer(uint32_t colorbuffer)857 static void rcOpenColorBuffer(uint32_t colorbuffer)
858 {
859 (void) rcOpenColorBuffer2(colorbuffer);
860 }
861
rcCloseColorBuffer(uint32_t colorbuffer)862 static void rcCloseColorBuffer(uint32_t colorbuffer)
863 {
864 FrameBuffer *fb = FrameBuffer::getFB();
865 if (!fb) {
866 return;
867 }
868 fb->closeColorBuffer( colorbuffer );
869 }
870
rcFlushWindowColorBuffer(uint32_t windowSurface)871 static int rcFlushWindowColorBuffer(uint32_t windowSurface)
872 {
873 GRSYNC_DPRINT("waiting for gralloc cb lock");
874 GrallocSyncPostLock lock(*sGrallocSync());
875 GRSYNC_DPRINT("lock gralloc cb lock {");
876
877 FrameBuffer *fb = FrameBuffer::getFB();
878 if (!fb) {
879 GRSYNC_DPRINT("unlock gralloc cb lock");
880 return -1;
881 }
882
883 HandleType colorBufferHandle = fb->getEmulatedEglWindowSurfaceColorBufferHandle(windowSurface);
884
885 if (!fb->flushEmulatedEglWindowSurfaceColorBuffer(windowSurface)) {
886 GRSYNC_DPRINT("unlock gralloc cb lock }");
887 return -1;
888 }
889
890 // Make the GL updates visible to other backings if necessary.
891 fb->flushColorBufferFromGl(colorBufferHandle);
892
893 GRSYNC_DPRINT("unlock gralloc cb lock }");
894
895 return 0;
896 }
897
898 // Note that even though this calls rcFlushWindowColorBuffer,
899 // the "Async" part is in the return type, which is void
900 // versus return type int for rcFlushWindowColorBuffer.
901 //
902 // The different return type, even while calling the same
903 // functions internally, will end up making the encoder
904 // and decoder use a different protocol. This is because
905 // the encoder generally obeys the following conventions:
906 //
907 // - The encoder will immediately send and wait for a command
908 // result if the return type is not void.
909 // - The encoder will cache the command in a buffer and send
910 // at a convenient time if the return type is void.
911 //
912 // It can also be expensive performance-wise to trigger
913 // sending traffic back to the guest. Generally, the more we avoid
914 // encoding commands that perform two-way traffic, the better.
915 //
916 // Hence, |rcFlushWindowColorBufferAsync| will avoid extra traffic;
917 // with return type void,
918 // the guest will not wait until this function returns,
919 // nor will it immediately send the command,
920 // resulting in more asynchronous behavior.
rcFlushWindowColorBufferAsync(uint32_t windowSurface)921 static void rcFlushWindowColorBufferAsync(uint32_t windowSurface)
922 {
923 rcFlushWindowColorBuffer(windowSurface);
924 }
925
rcSetWindowColorBuffer(uint32_t windowSurface,uint32_t colorBuffer)926 static void rcSetWindowColorBuffer(uint32_t windowSurface,
927 uint32_t colorBuffer)
928 {
929 FrameBuffer *fb = FrameBuffer::getFB();
930 if (!fb) {
931 return;
932 }
933 fb->setEmulatedEglWindowSurfaceColorBuffer(windowSurface, colorBuffer);
934 }
935
rcMakeCurrent(uint32_t context,uint32_t drawSurf,uint32_t readSurf)936 static EGLint rcMakeCurrent(uint32_t context,
937 uint32_t drawSurf, uint32_t readSurf)
938 {
939 FrameBuffer *fb = FrameBuffer::getFB();
940 if (!fb) {
941 return EGL_FALSE;
942 }
943
944 bool ret = fb->bindContext(context, drawSurf, readSurf);
945
946 return (ret ? EGL_TRUE : EGL_FALSE);
947 }
948
rcFBPost(uint32_t colorBuffer)949 static void rcFBPost(uint32_t colorBuffer)
950 {
951 FrameBuffer *fb = FrameBuffer::getFB();
952 if (!fb) {
953 return;
954 }
955
956 fb->post(colorBuffer);
957 }
958
rcFBSetSwapInterval(EGLint interval)959 static void rcFBSetSwapInterval(EGLint interval)
960 {
961 // XXX: TBD - should be implemented
962 }
963
rcBindTexture(uint32_t colorBuffer)964 static void rcBindTexture(uint32_t colorBuffer)
965 {
966 FrameBuffer *fb = FrameBuffer::getFB();
967 if (!fb) {
968 return;
969 }
970
971 // Update for GL use if necessary.
972 fb->invalidateColorBufferForGl(colorBuffer);
973
974 fb->bindColorBufferToTexture(colorBuffer);
975 }
976
rcBindRenderbuffer(uint32_t colorBuffer)977 static void rcBindRenderbuffer(uint32_t colorBuffer)
978 {
979 FrameBuffer *fb = FrameBuffer::getFB();
980 if (!fb) {
981 return;
982 }
983
984 // Update for GL use if necessary.
985 fb->invalidateColorBufferForGl(colorBuffer);
986
987 fb->bindColorBufferToRenderbuffer(colorBuffer);
988 }
989
rcColorBufferCacheFlush(uint32_t colorBuffer,EGLint postCount,int forRead)990 static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer,
991 EGLint postCount, int forRead)
992 {
993 // gralloc_lock() on the guest calls rcColorBufferCacheFlush
994 GRSYNC_DPRINT("waiting for gralloc cb lock");
995 sGrallocSync()->lockColorBufferPrepare();
996 GRSYNC_DPRINT("lock gralloc cb lock {");
997 return 0;
998 }
999
rcReadColorBuffer(uint32_t colorBuffer,GLint x,GLint y,GLint width,GLint height,GLenum format,GLenum type,void * pixels)1000 static void rcReadColorBuffer(uint32_t colorBuffer,
1001 GLint x, GLint y,
1002 GLint width, GLint height,
1003 GLenum format, GLenum type, void* pixels)
1004 {
1005 FrameBuffer *fb = FrameBuffer::getFB();
1006 if (!fb) {
1007 return;
1008 }
1009
1010 fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
1011 }
1012
rcUpdateColorBuffer(uint32_t colorBuffer,GLint x,GLint y,GLint width,GLint height,GLenum format,GLenum type,void * pixels)1013 static int rcUpdateColorBuffer(uint32_t colorBuffer,
1014 GLint x, GLint y,
1015 GLint width, GLint height,
1016 GLenum format, GLenum type, void* pixels)
1017 {
1018 FrameBuffer *fb = FrameBuffer::getFB();
1019
1020 if (!fb) {
1021 GRSYNC_DPRINT("unlock gralloc cb lock");
1022 sGrallocSync()->unlockColorBufferPrepare();
1023 return -1;
1024 }
1025
1026 fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
1027
1028 GRSYNC_DPRINT("unlock gralloc cb lock");
1029 sGrallocSync()->unlockColorBufferPrepare();
1030
1031 return 0;
1032 }
1033
rcUpdateColorBufferDMA(uint32_t colorBuffer,GLint x,GLint y,GLint width,GLint height,GLenum format,GLenum type,void * pixels,uint32_t pixels_size)1034 static int rcUpdateColorBufferDMA(uint32_t colorBuffer,
1035 GLint x, GLint y,
1036 GLint width, GLint height,
1037 GLenum format, GLenum type,
1038 void* pixels, uint32_t pixels_size)
1039 {
1040 FrameBuffer *fb = FrameBuffer::getFB();
1041
1042 if (!fb) {
1043 GRSYNC_DPRINT("unlock gralloc cb lock");
1044 sGrallocSync()->unlockColorBufferPrepare();
1045 return -1;
1046 }
1047
1048 fb->updateColorBuffer(colorBuffer, x, y, width, height,
1049 format, type, pixels);
1050
1051 GRSYNC_DPRINT("unlock gralloc cb lock");
1052 sGrallocSync()->unlockColorBufferPrepare();
1053
1054 return 0;
1055 }
1056
rcCreateClientImage(uint32_t context,EGLenum target,GLuint buffer)1057 static uint32_t rcCreateClientImage(uint32_t context, EGLenum target, GLuint buffer)
1058 {
1059 FrameBuffer *fb = FrameBuffer::getFB();
1060 if (!fb) {
1061 return 0;
1062 }
1063
1064 return fb->createEmulatedEglImage(context, target, buffer);
1065 }
1066
rcDestroyClientImage(uint32_t image)1067 static int rcDestroyClientImage(uint32_t image)
1068 {
1069 FrameBuffer *fb = FrameBuffer::getFB();
1070 if (!fb) {
1071 return 0;
1072 }
1073
1074 return fb->destroyEmulatedEglImage(image);
1075 }
1076
rcSelectChecksumHelper(uint32_t protocol,uint32_t reserved)1077 static void rcSelectChecksumHelper(uint32_t protocol, uint32_t reserved) {
1078 ChecksumCalculatorThreadInfo::setVersion(protocol);
1079 }
1080
1081 // |rcTriggerWait| is called from the goldfish sync
1082 // kernel driver whenever a native fence fd is created.
1083 // We will then need to use the host to find out
1084 // when to signal that native fence fd. We use
1085 // SyncThread for that.
rcTriggerWait(uint64_t eglsync_ptr,uint64_t thread_ptr,uint64_t timeline)1086 static void rcTriggerWait(uint64_t eglsync_ptr,
1087 uint64_t thread_ptr,
1088 uint64_t timeline) {
1089 if (thread_ptr == 1) {
1090 // Is vulkan sync fd;
1091 // just signal right away for now
1092 EGLSYNC_DPRINT("vkFence=0x%llx timeline=0x%llx", eglsync_ptr,
1093 thread_ptr, timeline);
1094 SyncThread::get()->triggerWaitVk(reinterpret_cast<VkFence>(eglsync_ptr),
1095 timeline);
1096 } else {
1097 EmulatedEglFenceSync* fenceSync = reinterpret_cast<EmulatedEglFenceSync*>(eglsync_ptr);
1098 FrameBuffer *fb = FrameBuffer::getFB();
1099 if (fb && fenceSync->isCompositionFence()) {
1100 fb->scheduleVsyncTask([eglsync_ptr, fenceSync, timeline](uint64_t) {
1101 EGLSYNC_DPRINT(
1102 "vsync: eglsync=0x%llx fenceSync=%p thread_ptr=0x%llx "
1103 "timeline=0x%llx",
1104 eglsync_ptr, fenceSync, thread_ptr, timeline);
1105 SyncThread::get()->triggerWait(fenceSync, timeline);
1106 });
1107 } else {
1108 EGLSYNC_DPRINT(
1109 "eglsync=0x%llx fenceSync=%p thread_ptr=0x%llx "
1110 "timeline=0x%llx",
1111 eglsync_ptr, fenceSync, thread_ptr, timeline);
1112 SyncThread::get()->triggerWait(fenceSync, timeline);
1113 }
1114 }
1115 }
1116
1117 // |rcCreateSyncKHR| implements the guest's |eglCreateSyncKHR| by calling the
1118 // host's implementation of |eglCreateSyncKHR|. A SyncThread is also notified
1119 // for purposes of signaling any native fence fd's that get created in the
1120 // guest off the sync object created here.
rcCreateSyncKHR(EGLenum type,EGLint * attribs,uint32_t num_attribs,int destroyWhenSignaled,uint64_t * outSync,uint64_t * outSyncThread)1121 static void rcCreateSyncKHR(EGLenum type,
1122 EGLint* attribs,
1123 uint32_t num_attribs,
1124 int destroyWhenSignaled,
1125 uint64_t* outSync,
1126 uint64_t* outSyncThread) {
1127 // Usually we expect rcTriggerWait to be registered
1128 // at the beginning in rcGetRendererVersion, called
1129 // on init for all contexts.
1130 // But if we are loading from snapshot, that's not
1131 // guaranteed, and we need to make sure
1132 // rcTriggerWait is registered.
1133 emugl_sync_register_trigger_wait(rcTriggerWait);
1134
1135 FrameBuffer::getFB()->createEmulatedEglFenceSync(type,
1136 destroyWhenSignaled,
1137 outSync,
1138 outSyncThread);
1139
1140 RenderThreadInfo* tInfo = RenderThreadInfo::get();
1141 if (tInfo && outSync && shouldEnableVsyncGatedSyncFences()) {
1142 auto fenceSync = reinterpret_cast<EmulatedEglFenceSync*>(outSync);
1143 fenceSync->setIsCompositionFence(tInfo->m_isCompositionThread);
1144 }
1145 }
1146
1147 // |rcClientWaitSyncKHR| implements |eglClientWaitSyncKHR|
1148 // on the guest through using the host's existing
1149 // |eglClientWaitSyncKHR| implementation, which is done
1150 // through the EmulatedEglFenceSync object.
rcClientWaitSyncKHR(uint64_t handle,EGLint flags,uint64_t timeout)1151 static EGLint rcClientWaitSyncKHR(uint64_t handle,
1152 EGLint flags,
1153 uint64_t timeout) {
1154 RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
1155 if (!tInfo) {
1156 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
1157 << "Render thread GL not available.";
1158 }
1159
1160 FrameBuffer *fb = FrameBuffer::getFB();
1161
1162 EGLSYNC_DPRINT("handle=0x%lx flags=0x%x timeout=%" PRIu64,
1163 handle, flags, timeout);
1164
1165 EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
1166
1167 if (!fenceSync) {
1168 EGLSYNC_DPRINT("fenceSync null, return condition satisfied");
1169 return EGL_CONDITION_SATISFIED_KHR;
1170 }
1171
1172 // Sometimes a gralloc-buffer-only thread is doing stuff with sync.
1173 // This happens all the time with YouTube videos in the browser.
1174 // In this case, create a context on the host just for syncing.
1175 if (!tInfo->currContext) {
1176 uint32_t gralloc_sync_cxt, gralloc_sync_surf;
1177 fb->createTrivialContext(0, // There is no context to share.
1178 &gralloc_sync_cxt,
1179 &gralloc_sync_surf);
1180 fb->bindContext(gralloc_sync_cxt,
1181 gralloc_sync_surf,
1182 gralloc_sync_surf);
1183 // This context is then cleaned up when the render thread exits.
1184 }
1185
1186 return fenceSync->wait(timeout);
1187 }
1188
rcWaitSyncKHR(uint64_t handle,EGLint flags)1189 static void rcWaitSyncKHR(uint64_t handle,
1190 EGLint flags) {
1191 RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
1192 if (!tInfo) {
1193 GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
1194 << "Render thread GL not available.";
1195 }
1196
1197 FrameBuffer *fb = FrameBuffer::getFB();
1198
1199 EGLSYNC_DPRINT("handle=0x%lx flags=0x%x", handle, flags);
1200
1201 EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
1202
1203 if (!fenceSync) { return; }
1204
1205 // Sometimes a gralloc-buffer-only thread is doing stuff with sync.
1206 // This happens all the time with YouTube videos in the browser.
1207 // In this case, create a context on the host just for syncing.
1208 if (!tInfo->currContext) {
1209 uint32_t gralloc_sync_cxt, gralloc_sync_surf;
1210 fb->createTrivialContext(0, // There is no context to share.
1211 &gralloc_sync_cxt,
1212 &gralloc_sync_surf);
1213 fb->bindContext(gralloc_sync_cxt,
1214 gralloc_sync_surf,
1215 gralloc_sync_surf);
1216 // This context is then cleaned up when the render thread exits.
1217 }
1218
1219 fenceSync->waitAsync();
1220 }
1221
rcDestroySyncKHR(uint64_t handle)1222 static int rcDestroySyncKHR(uint64_t handle) {
1223 EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
1224 if (!fenceSync) return 0;
1225 fenceSync->decRef();
1226 return 0;
1227 }
1228
rcSetPuid(uint64_t puid)1229 static void rcSetPuid(uint64_t puid) {
1230 RenderThreadInfo *tInfo = RenderThreadInfo::get();
1231 tInfo->m_puid = puid;
1232 }
1233
rcCompose(uint32_t bufferSize,void * buffer)1234 static int rcCompose(uint32_t bufferSize, void* buffer) {
1235 RenderThreadInfo *tInfo = RenderThreadInfo::get();
1236 if (tInfo) tInfo->m_isCompositionThread = true;
1237
1238 FrameBuffer *fb = FrameBuffer::getFB();
1239 if (!fb) {
1240 return -1;
1241 }
1242 return fb->compose(bufferSize, buffer, true);
1243 }
1244
rcComposeWithoutPost(uint32_t bufferSize,void * buffer)1245 static int rcComposeWithoutPost(uint32_t bufferSize, void* buffer) {
1246 RenderThreadInfo *tInfo = RenderThreadInfo::get();
1247 if (tInfo) tInfo->m_isCompositionThread = true;
1248
1249 FrameBuffer *fb = FrameBuffer::getFB();
1250 if (!fb) {
1251 return -1;
1252 }
1253 return fb->compose(bufferSize, buffer, false);
1254 }
1255
rcCreateDisplay(uint32_t * displayId)1256 static int rcCreateDisplay(uint32_t* displayId) {
1257 FrameBuffer *fb = FrameBuffer::getFB();
1258 if (!fb) {
1259 return -1;
1260 }
1261
1262 // Assume this API call always allocates a new displayId
1263 *displayId = FrameBuffer::s_invalidIdMultiDisplay;
1264 return fb->createDisplay(displayId);
1265 }
1266
rcCreateDisplayById(uint32_t displayId)1267 static int rcCreateDisplayById(uint32_t displayId) {
1268 FrameBuffer *fb = FrameBuffer::getFB();
1269 if (!fb) {
1270 return -1;
1271 }
1272
1273 return fb->createDisplay(displayId);
1274 }
1275
rcDestroyDisplay(uint32_t displayId)1276 static int rcDestroyDisplay(uint32_t displayId) {
1277 FrameBuffer *fb = FrameBuffer::getFB();
1278 if (!fb) {
1279 return -1;
1280 }
1281
1282 return fb->destroyDisplay(displayId);
1283 }
1284
rcSetDisplayColorBuffer(uint32_t displayId,uint32_t colorBuffer)1285 static int rcSetDisplayColorBuffer(uint32_t displayId, uint32_t colorBuffer) {
1286 FrameBuffer *fb = FrameBuffer::getFB();
1287 if (!fb) {
1288 return -1;
1289 }
1290
1291 return fb->setDisplayColorBuffer(displayId, colorBuffer);
1292 }
1293
rcGetDisplayColorBuffer(uint32_t displayId,uint32_t * colorBuffer)1294 static int rcGetDisplayColorBuffer(uint32_t displayId, uint32_t* colorBuffer) {
1295 FrameBuffer *fb = FrameBuffer::getFB();
1296 if (!fb) {
1297 return -1;
1298 }
1299
1300 return fb->getDisplayColorBuffer(displayId, colorBuffer);
1301 }
1302
rcGetColorBufferDisplay(uint32_t colorBuffer,uint32_t * displayId)1303 static int rcGetColorBufferDisplay(uint32_t colorBuffer, uint32_t* displayId) {
1304 FrameBuffer *fb = FrameBuffer::getFB();
1305 if (!fb) {
1306 return -1;
1307 }
1308
1309 return fb->getColorBufferDisplay(colorBuffer, displayId);
1310 }
1311
rcGetDisplayPose(uint32_t displayId,int32_t * x,int32_t * y,uint32_t * w,uint32_t * h)1312 static int rcGetDisplayPose(uint32_t displayId,
1313 int32_t* x,
1314 int32_t* y,
1315 uint32_t* w,
1316 uint32_t* h) {
1317 FrameBuffer *fb = FrameBuffer::getFB();
1318 if (!fb) {
1319 return -1;
1320 }
1321
1322 return fb->getDisplayPose(displayId, x, y, w, h);
1323 }
1324
rcSetDisplayPose(uint32_t displayId,int32_t x,int32_t y,uint32_t w,uint32_t h)1325 static int rcSetDisplayPose(uint32_t displayId,
1326 int32_t x,
1327 int32_t y,
1328 uint32_t w,
1329 uint32_t h) {
1330 FrameBuffer *fb = FrameBuffer::getFB();
1331 if (!fb) {
1332 return -1;
1333 }
1334
1335 return fb->setDisplayPose(displayId, x, y, w, h);
1336 }
1337
rcSetDisplayPoseDpi(uint32_t displayId,int32_t x,int32_t y,uint32_t w,uint32_t h,uint32_t dpi)1338 static int rcSetDisplayPoseDpi(uint32_t displayId,
1339 int32_t x,
1340 int32_t y,
1341 uint32_t w,
1342 uint32_t h,
1343 uint32_t dpi) {
1344 FrameBuffer *fb = FrameBuffer::getFB();
1345 if (!fb) {
1346 return -1;
1347 }
1348
1349 return fb->setDisplayPose(displayId, x, y, w, h, dpi);
1350 }
1351
rcReadColorBufferYUV(uint32_t colorBuffer,GLint x,GLint y,GLint width,GLint height,void * pixels,uint32_t pixels_size)1352 static void rcReadColorBufferYUV(uint32_t colorBuffer,
1353 GLint x, GLint y,
1354 GLint width, GLint height,
1355 void* pixels, uint32_t pixels_size)
1356 {
1357 FrameBuffer *fb = FrameBuffer::getFB();
1358 if (!fb) {
1359 return;
1360 }
1361
1362 fb->readColorBufferYUV(colorBuffer, x, y, width, height, pixels, pixels_size);
1363 }
1364
rcIsSyncSignaled(uint64_t handle)1365 static int rcIsSyncSignaled(uint64_t handle) {
1366 EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
1367 if (!fenceSync) return 1; // assume destroyed => signaled
1368 return fenceSync->isSignaled() ? 1 : 0;
1369 }
1370
rcCreateColorBufferWithHandle(uint32_t width,uint32_t height,GLenum internalFormat,uint32_t handle)1371 static void rcCreateColorBufferWithHandle(
1372 uint32_t width, uint32_t height, GLenum internalFormat, uint32_t handle)
1373 {
1374 FrameBuffer *fb = FrameBuffer::getFB();
1375
1376 if (!fb) {
1377 return;
1378 }
1379
1380 fb->createColorBufferWithHandle(
1381 width, height, internalFormat,
1382 FRAMEWORK_FORMAT_GL_COMPATIBLE, handle);
1383 }
1384
rcCreateBuffer2(uint64_t size,uint32_t memoryProperty)1385 static uint32_t rcCreateBuffer2(uint64_t size, uint32_t memoryProperty) {
1386 FrameBuffer* fb = FrameBuffer::getFB();
1387 if (!fb) {
1388 return 0;
1389 }
1390
1391 return fb->createBuffer(size, memoryProperty);
1392 }
1393
rcCreateBuffer(uint32_t size)1394 static uint32_t rcCreateBuffer(uint32_t size) {
1395 return rcCreateBuffer2(size, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1396 }
1397
rcCloseBuffer(uint32_t buffer)1398 static void rcCloseBuffer(uint32_t buffer) {
1399 FrameBuffer* fb = FrameBuffer::getFB();
1400 if (!fb) {
1401 return;
1402 }
1403 fb->closeBuffer(buffer);
1404 }
1405
rcSetColorBufferVulkanMode2(uint32_t colorBuffer,uint32_t mode,uint32_t memoryProperty)1406 static int rcSetColorBufferVulkanMode2(uint32_t colorBuffer, uint32_t mode,
1407 uint32_t memoryProperty) {
1408 #define VULKAN_MODE_VULKAN_ONLY 1
1409
1410 bool modeIsVulkanOnly = mode == VULKAN_MODE_VULKAN_ONLY;
1411
1412 if (!vk::setColorBufferVulkanMode(colorBuffer, mode)) {
1413 fprintf(stderr,
1414 "%s: error: failed to set Vulkan mode for colorBuffer 0x%x\n",
1415 __func__, colorBuffer);
1416 return -1;
1417 }
1418
1419 return 0;
1420 }
1421
rcSetColorBufferVulkanMode(uint32_t colorBuffer,uint32_t mode)1422 static int rcSetColorBufferVulkanMode(uint32_t colorBuffer, uint32_t mode) {
1423 return rcSetColorBufferVulkanMode2(colorBuffer, mode,
1424 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1425 }
1426
rcMapGpaToBufferHandle(uint32_t bufferHandle,uint64_t gpa)1427 static int32_t rcMapGpaToBufferHandle(uint32_t bufferHandle, uint64_t gpa) {
1428 int32_t result = vk::mapGpaToBufferHandle(bufferHandle, gpa);
1429 if (result < 0) {
1430 fprintf(stderr,
1431 "%s: error: failed to map gpa %" PRIx64 " to buffer handle 0x%x: %d\n",
1432 __func__, gpa, bufferHandle, result);
1433 }
1434 return result;
1435 }
1436
rcMapGpaToBufferHandle2(uint32_t bufferHandle,uint64_t gpa,uint64_t size)1437 static int32_t rcMapGpaToBufferHandle2(uint32_t bufferHandle,
1438 uint64_t gpa,
1439 uint64_t size) {
1440 int32_t result = vk::mapGpaToBufferHandle(bufferHandle, gpa, size);
1441 if (result < 0) {
1442 fprintf(stderr,
1443 "%s: error: failed to map gpa %" PRIx64 " to buffer handle 0x%x: %d\n",
1444 __func__, gpa, bufferHandle, result);
1445 }
1446 return result;
1447 }
1448
rcFlushWindowColorBufferAsyncWithFrameNumber(uint32_t windowSurface,uint32_t frameNumber)1449 static void rcFlushWindowColorBufferAsyncWithFrameNumber(uint32_t windowSurface, uint32_t frameNumber) {
1450 android::base::traceCounter("gfxstreamFrameNumber", (int64_t)frameNumber);
1451 rcFlushWindowColorBufferAsync(windowSurface);
1452 }
1453
rcSetTracingForPuid(uint64_t puid,uint32_t enable,uint64_t time)1454 static void rcSetTracingForPuid(uint64_t puid, uint32_t enable, uint64_t time) {
1455 if (enable) {
1456 android::base::setGuestTime(time);
1457 android::base::enableTracing();
1458 } else {
1459 android::base::disableTracing();
1460 }
1461 }
1462
rcMakeCurrentAsync(uint32_t context,uint32_t drawSurf,uint32_t readSurf)1463 static void rcMakeCurrentAsync(uint32_t context, uint32_t drawSurf, uint32_t readSurf) {
1464 AEMU_SCOPED_THRESHOLD_TRACE_CALL();
1465 FrameBuffer* fb = FrameBuffer::getFB();
1466 if (!fb) { return; }
1467
1468 fb->bindContext(context, drawSurf, readSurf);
1469 }
1470
rcComposeAsync(uint32_t bufferSize,void * buffer)1471 static void rcComposeAsync(uint32_t bufferSize, void* buffer) {
1472 RenderThreadInfo *tInfo = RenderThreadInfo::get();
1473 if (tInfo) tInfo->m_isCompositionThread = true;
1474
1475 FrameBuffer* fb = FrameBuffer::getFB();
1476 if (!fb) {
1477 return;
1478 }
1479 fb->compose(bufferSize, buffer, true);
1480 }
1481
rcComposeAsyncWithoutPost(uint32_t bufferSize,void * buffer)1482 static void rcComposeAsyncWithoutPost(uint32_t bufferSize, void* buffer) {
1483 RenderThreadInfo *tInfo = RenderThreadInfo::get();
1484 if (tInfo) tInfo->m_isCompositionThread = true;
1485
1486 FrameBuffer *fb = FrameBuffer::getFB();
1487 if (!fb) {
1488 return;
1489 }
1490 fb->compose(bufferSize, buffer, false);
1491 }
1492
rcDestroySyncKHRAsync(uint64_t handle)1493 static void rcDestroySyncKHRAsync(uint64_t handle) {
1494 EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
1495 if (!fenceSync) return;
1496 fenceSync->decRef();
1497 }
1498
rcReadColorBufferDMA(uint32_t colorBuffer,GLint x,GLint y,GLint width,GLint height,GLenum format,GLenum type,void * pixels,uint32_t pixels_size)1499 static int rcReadColorBufferDMA(uint32_t colorBuffer,
1500 GLint x, GLint y,
1501 GLint width, GLint height,
1502 GLenum format, GLenum type, void* pixels, uint32_t pixels_size)
1503 {
1504 FrameBuffer *fb = FrameBuffer::getFB();
1505 if (!fb) {
1506 return -1;
1507 }
1508
1509 fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels);
1510 return 0;
1511 }
1512
rcGetFBDisplayConfigsCount()1513 static int rcGetFBDisplayConfigsCount() {
1514 FrameBuffer *fb = FrameBuffer::getFB();
1515 if (!fb) {
1516 return -1;
1517 }
1518 return fb->getDisplayConfigsCount();
1519 }
1520
rcGetFBDisplayConfigsParam(int configId,GLint param)1521 static int rcGetFBDisplayConfigsParam(int configId, GLint param) {
1522 FrameBuffer *fb = FrameBuffer::getFB();
1523 if (!fb) {
1524 return -1;
1525 }
1526 return fb->getDisplayConfigsParam(configId, param);
1527 }
1528
rcGetFBDisplayActiveConfig()1529 static int rcGetFBDisplayActiveConfig() {
1530 FrameBuffer *fb = FrameBuffer::getFB();
1531 if (!fb) {
1532 return -1;
1533 }
1534 return fb->getDisplayActiveConfig();
1535 }
1536
rcSetProcessMetadata(char * key,RenderControlByte * valuePtr,uint32_t valueSize)1537 static void rcSetProcessMetadata(char* key, RenderControlByte* valuePtr, uint32_t valueSize) {
1538 RenderThreadInfo* tInfo = RenderThreadInfo::get();
1539 if (strcmp(key, "process_name") == 0) {
1540 // We know this is a c formatted string
1541 tInfo->m_processName = std::string((char*) valuePtr);
1542 }
1543 }
1544
rcGetHostExtensionsString(uint32_t bufferSize,void * buffer)1545 static int rcGetHostExtensionsString(uint32_t bufferSize, void* buffer) {
1546 // TODO(b/233939967): split off host extensions from GL extensions.
1547 return rcGetGLString(GL_EXTENSIONS, buffer, bufferSize);
1548 }
1549
initRenderControlContext(renderControl_decoder_context_t * dec)1550 void initRenderControlContext(renderControl_decoder_context_t *dec)
1551 {
1552 dec->rcGetRendererVersion = rcGetRendererVersion;
1553 dec->rcGetEGLVersion = rcGetEGLVersion;
1554 dec->rcQueryEGLString = rcQueryEGLString;
1555 dec->rcGetGLString = rcGetGLString;
1556 dec->rcGetNumConfigs = rcGetNumConfigs;
1557 dec->rcGetConfigs = rcGetConfigs;
1558 dec->rcChooseConfig = rcChooseConfig;
1559 dec->rcGetFBParam = rcGetFBParam;
1560 dec->rcCreateContext = rcCreateContext;
1561 dec->rcDestroyContext = rcDestroyContext;
1562 dec->rcCreateWindowSurface = rcCreateWindowSurface;
1563 dec->rcDestroyWindowSurface = rcDestroyWindowSurface;
1564 dec->rcCreateColorBuffer = rcCreateColorBuffer;
1565 dec->rcOpenColorBuffer = rcOpenColorBuffer;
1566 dec->rcCloseColorBuffer = rcCloseColorBuffer;
1567 dec->rcSetWindowColorBuffer = rcSetWindowColorBuffer;
1568 dec->rcFlushWindowColorBuffer = rcFlushWindowColorBuffer;
1569 dec->rcMakeCurrent = rcMakeCurrent;
1570 dec->rcFBPost = rcFBPost;
1571 dec->rcFBSetSwapInterval = rcFBSetSwapInterval;
1572 dec->rcBindTexture = rcBindTexture;
1573 dec->rcBindRenderbuffer = rcBindRenderbuffer;
1574 dec->rcColorBufferCacheFlush = rcColorBufferCacheFlush;
1575 dec->rcReadColorBuffer = rcReadColorBuffer;
1576 dec->rcUpdateColorBuffer = rcUpdateColorBuffer;
1577 dec->rcOpenColorBuffer2 = rcOpenColorBuffer2;
1578 dec->rcCreateClientImage = rcCreateClientImage;
1579 dec->rcDestroyClientImage = rcDestroyClientImage;
1580 dec->rcSelectChecksumHelper = rcSelectChecksumHelper;
1581 dec->rcCreateSyncKHR = rcCreateSyncKHR;
1582 dec->rcClientWaitSyncKHR = rcClientWaitSyncKHR;
1583 dec->rcFlushWindowColorBufferAsync = rcFlushWindowColorBufferAsync;
1584 dec->rcDestroySyncKHR = rcDestroySyncKHR;
1585 dec->rcSetPuid = rcSetPuid;
1586 dec->rcUpdateColorBufferDMA = rcUpdateColorBufferDMA;
1587 dec->rcCreateColorBufferDMA = rcCreateColorBufferDMA;
1588 dec->rcWaitSyncKHR = rcWaitSyncKHR;
1589 dec->rcCompose = rcCompose;
1590 dec->rcCreateDisplay = rcCreateDisplay;
1591 dec->rcDestroyDisplay = rcDestroyDisplay;
1592 dec->rcSetDisplayColorBuffer = rcSetDisplayColorBuffer;
1593 dec->rcGetDisplayColorBuffer = rcGetDisplayColorBuffer;
1594 dec->rcGetColorBufferDisplay = rcGetColorBufferDisplay;
1595 dec->rcGetDisplayPose = rcGetDisplayPose;
1596 dec->rcSetDisplayPose = rcSetDisplayPose;
1597 dec->rcSetColorBufferVulkanMode = rcSetColorBufferVulkanMode;
1598 dec->rcReadColorBufferYUV = rcReadColorBufferYUV;
1599 dec->rcIsSyncSignaled = rcIsSyncSignaled;
1600 dec->rcCreateColorBufferWithHandle = rcCreateColorBufferWithHandle;
1601 dec->rcCreateBuffer = rcCreateBuffer;
1602 dec->rcCreateBuffer2 = rcCreateBuffer2;
1603 dec->rcCloseBuffer = rcCloseBuffer;
1604 dec->rcSetColorBufferVulkanMode2 = rcSetColorBufferVulkanMode2;
1605 dec->rcMapGpaToBufferHandle = rcMapGpaToBufferHandle;
1606 dec->rcMapGpaToBufferHandle2 = rcMapGpaToBufferHandle2;
1607 dec->rcFlushWindowColorBufferAsyncWithFrameNumber = rcFlushWindowColorBufferAsyncWithFrameNumber;
1608 dec->rcSetTracingForPuid = rcSetTracingForPuid;
1609 dec->rcMakeCurrentAsync = rcMakeCurrentAsync;
1610 dec->rcComposeAsync = rcComposeAsync;
1611 dec->rcDestroySyncKHRAsync = rcDestroySyncKHRAsync;
1612 dec->rcComposeWithoutPost = rcComposeWithoutPost;
1613 dec->rcComposeAsyncWithoutPost = rcComposeAsyncWithoutPost;
1614 dec->rcCreateDisplayById = rcCreateDisplayById;
1615 dec->rcSetDisplayPoseDpi = rcSetDisplayPoseDpi;
1616 dec->rcReadColorBufferDMA = rcReadColorBufferDMA;
1617 dec->rcGetFBDisplayConfigsCount = rcGetFBDisplayConfigsCount;
1618 dec->rcGetFBDisplayConfigsParam = rcGetFBDisplayConfigsParam;
1619 dec->rcGetFBDisplayActiveConfig = rcGetFBDisplayActiveConfig;
1620 dec->rcSetProcessMetadata = rcSetProcessMetadata;
1621 dec->rcGetHostExtensionsString = rcGetHostExtensionsString;
1622 }
1623
1624 } // namespace gfxstream