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