• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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