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