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