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