Merge "Move Buffer to the new "gl" subdirectory"
diff --git a/stream-servers/Android.bp b/stream-servers/Android.bp
index 1b6a8e4..2a90b3a 100644
--- a/stream-servers/Android.bp
+++ b/stream-servers/Android.bp
@@ -57,7 +57,6 @@
"Debug.cpp",
"DisplaySurface.cpp",
"DisplaySurfaceUser.cpp",
- "FenceSync.cpp",
"Hwc2.cpp",
"PostWorker.cpp",
"ReadbackWorker.cpp",
diff --git a/stream-servers/CMakeLists.txt b/stream-servers/CMakeLists.txt
index 05ab846..aa65183 100644
--- a/stream-servers/CMakeLists.txt
+++ b/stream-servers/CMakeLists.txt
@@ -19,7 +19,6 @@
Debug.cpp
DisplaySurface.cpp
DisplaySurfaceUser.cpp
- FenceSync.cpp
Hwc2.cpp
PostWorker.cpp
ReadbackWorker.cpp
diff --git a/stream-servers/FenceSync.cpp b/stream-servers/FenceSync.cpp
deleted file mode 100644
index 678d432..0000000
--- a/stream-servers/FenceSync.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-* Copyright (C) 2016 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-#include "FenceSync.h"
-
-#include <unordered_set>
-
-#include "FrameBuffer.h"
-#include "OpenGLESDispatch/DispatchTables.h"
-#include "OpenGLESDispatch/EGLDispatch.h"
-#include "RenderThreadInfo.h"
-#include "StalePtrRegistry.h"
-
-#include "aemu/base/containers/Lookup.h"
-#include "aemu/base/containers/StaticMap.h"
-#include "aemu/base/files/StreamSerializing.h"
-#include "aemu/base/synchronization/Lock.h"
-
-using android::base::AutoLock;
-using android::base::Lock;
-using android::base::StaticMap;
-
-// Timeline class is meant to delete native fences after the
-// sync device has incremented the timeline. We assume a
-// maximum number of outstanding timelines in the guest (16) in
-// order to derive when a native fence is definitely safe to
-// delete. After at least that many timeline increments have
-// happened, we sweep away the remaining native fences.
-// The function that performs the deleting,
-// incrementTimelineAndDeleteOldFences(), happens on the SyncThread.
-
-class Timeline {
-public:
- Timeline() = default;
-
- static constexpr int kMaxGuestTimelines = 16;
- void addFence(FenceSync* fence) {
- mFences.set(fence, mTime.load() + kMaxGuestTimelines);
- }
-
- void incrementTimelineAndDeleteOldFences() {
- ++mTime;
- sweep();
- }
-
- void sweep() {
- mFences.eraseIf([time = mTime.load()](FenceSync* fence, int fenceTime) {
- FenceSync* actual = FenceSync::getFromHandle((uint64_t)(uintptr_t)fence);
- if (!actual) return true;
-
- bool shouldErase = fenceTime <= time;
- if (shouldErase) {
- if (!actual->decRef() &&
- actual->shouldDestroyWhenSignaled()) {
- actual->decRef();
- }
- }
- return shouldErase;
- });
- }
-
-private:
- std::atomic<int> mTime {0};
- StaticMap<FenceSync*, int> mFences;
-};
-
-static Timeline* sTimeline() {
- static Timeline* t = new Timeline;
- return t;
-}
-
-// static
-void FenceSync::incrementTimelineAndDeleteOldFences() {
- sTimeline()->incrementTimelineAndDeleteOldFences();
-}
-
-FenceSync::FenceSync(bool hasNativeFence,
- bool destroyWhenSignaled) :
- mDestroyWhenSignaled(destroyWhenSignaled) {
-
- addToRegistry();
-
- assert(mCount == 1);
- if (hasNativeFence) {
- incRef();
- sTimeline()->addFence(this);
- }
-
- // assumes that there is a valid + current OpenGL context
- assert(RenderThreadInfo::get());
-
- mDisplay = FrameBuffer::getFB()->getDisplay();
- mSync = s_egl.eglCreateSyncKHR(mDisplay,
- EGL_SYNC_FENCE_KHR,
- NULL);
-}
-
-FenceSync::~FenceSync() {
- removeFromRegistry();
-}
-
-EGLint FenceSync::wait(uint64_t timeout) {
- incRef();
- EGLint wait_res =
- s_egl.eglClientWaitSyncKHR(mDisplay, mSync,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
- timeout);
- decRef();
- return wait_res;
-}
-
-void FenceSync::waitAsync() {
- s_egl.eglWaitSyncKHR(mDisplay, mSync, 0);
-}
-
-bool FenceSync::isSignaled() {
- EGLint val;
- if (EGL_TRUE ==
- s_egl.eglGetSyncAttribKHR(
- mDisplay, mSync, EGL_SYNC_STATUS_KHR, &val))
- return val == EGL_SIGNALED_KHR;
-
- return true; // if invalid, treat as signaled
-}
-
-void FenceSync::destroy() {
- s_egl.eglDestroySyncKHR(mDisplay, mSync);
-}
-
-// Snapshots for FenceSync//////////////////////////////////////////////////////
-// It's possible, though it does not happen often, that a fence
-// can be created but not yet waited on by the guest, which
-// needs careful handling:
-//
-// 1. Avoid manipulating garbage memory on snapshot restore;
-// rcCreateSyncKHR *creates new fence in valid memory*
-// --snapshot--
-// rcClientWaitSyncKHR *refers to uninitialized memory*
-// rcDestroySyncKHR *refers to uninitialized memory*
-// 2. Make rcCreateSyncKHR/rcDestroySyncKHR implementations return
-// the "signaled" status if referring to previous snapshot fences. It's
-// assumed that the GPU is long done with them.
-// 3. Avoid name collisions where a new FenceSync object is created
-// that has the same uint64_t casting as a FenceSync object from a previous
-// snapshot.
-
-// Maintain a StalePtrRegistry<FenceSync>:
-static StalePtrRegistry<FenceSync>* sFenceRegistry() {
- static StalePtrRegistry<FenceSync>* s = new StalePtrRegistry<FenceSync>;
- return s;
-}
-
-// static
-void FenceSync::addToRegistry() {
- sFenceRegistry()->addPtr(this);
-}
-
-// static
-void FenceSync::removeFromRegistry() {
- sFenceRegistry()->removePtr(this);
-}
-
-// static
-void FenceSync::onSave(android::base::Stream* stream) {
- sFenceRegistry()->makeCurrentPtrsStale();
- sFenceRegistry()->onSave(stream);
-}
-
-// static
-void FenceSync::onLoad(android::base::Stream* stream) {
- sFenceRegistry()->onLoad(stream);
-}
-
-// static
-FenceSync* FenceSync::getFromHandle(uint64_t handle) {
- return sFenceRegistry()->getPtr(handle);
-}
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index d56d3f7..004bb53 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -64,6 +64,7 @@
using gfxstream::EmulatedEglContext;
using gfxstream::EmulatedEglContextMap;
using gfxstream::EmulatedEglContextPtr;
+using gfxstream::EmulatedEglFenceSync;
using gfxstream::EmulatedEglWindowSurface;
using gfxstream::EmulatedEglWindowSurfaceMap;
using gfxstream::EmulatedEglWindowSurfacePtr;
@@ -1467,6 +1468,47 @@
return colorBuffersToCleanUp;
}
+void FrameBuffer::createEmulatedEglFenceSync(EGLenum type,
+ int destroyWhenSignaled,
+ uint64_t* outSync,
+ uint64_t* outSyncThread) {
+ if (!m_emulationGl) {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+ << "GL/EGL emulation not available.";
+ }
+
+ // TODO(b/233939967): move RenderThreadInfoGl usage to EmulationGl.
+ RenderThreadInfoGl* const info = RenderThreadInfoGl::get();
+ if (!info) {
+ GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+ << "RenderThreadInfoGl not available.";
+ }
+ if (!info->currContext) {
+ auto fb = FrameBuffer::getFB();
+ uint32_t syncContext;
+ uint32_t syncSurface;
+ createTrivialContext(0, // There is no context to share.
+ &syncContext,
+ &syncSurface);
+ bindContext(syncContext,
+ syncSurface,
+ syncSurface);
+ // This context is then cleaned up when the render thread exits.
+ }
+
+ auto sync = m_emulationGl->createEmulatedEglFenceSync(type, destroyWhenSignaled);
+ if (!sync) {
+ return;
+ }
+
+ if (outSync) {
+ *outSync = (uint64_t)(uintptr_t)sync.release();
+ }
+ if (outSyncThread) {
+ *outSyncThread = reinterpret_cast<uint64_t>(SyncThread::get());
+ }
+}
+
void FrameBuffer::drainGlRenderThreadResources() {
// If we're already exiting then snapshot should not contain
// this thread information at all.
@@ -2982,6 +3024,7 @@
}
}
+ EmulatedEglFenceSync::onSave(stream);
}
bool FrameBuffer::onLoad(Stream* stream,
@@ -3189,6 +3232,9 @@
}
repost(false);
+
+ EmulatedEglFenceSync::onLoad(stream);
+
return true;
// TODO: restore memory management
}
@@ -3335,7 +3381,7 @@
}
void FrameBuffer::waitForGpu(uint64_t eglsync) {
- FenceSync* fenceSync = FenceSync::getFromHandle(eglsync);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(eglsync);
if (!fenceSync) {
ERR("err: fence sync 0x%llx not found", (unsigned long long)eglsync);
@@ -3348,20 +3394,20 @@
void FrameBuffer::waitForGpuVulkan(uint64_t deviceHandle, uint64_t fenceHandle) {
(void)deviceHandle;
if (!m_emulationGl) {
- // Guest ANGLE should always use the asyncWaitForGpuVulkanWithCb call. FenceSync is a
+ // Guest ANGLE should always use the asyncWaitForGpuVulkanWithCb call. EmulatedEglFenceSync is a
// wrapper over EGLSyncKHR and should not be used for pure Vulkan environment.
return;
}
// Note: this will always be nullptr.
- FenceSync* fenceSync = FenceSync::getFromHandle(fenceHandle);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(fenceHandle);
// Note: This will always signal right away.
SyncThread::get()->triggerBlockedWaitNoTimeline(fenceSync);
}
void FrameBuffer::asyncWaitForGpuWithCb(uint64_t eglsync, FenceCompletionCallback cb) {
- FenceSync* fenceSync = FenceSync::getFromHandle(eglsync);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(eglsync);
if (!fenceSync) {
ERR("err: fence sync 0x%llx not found", (unsigned long long)eglsync);
diff --git a/stream-servers/FrameBuffer.h b/stream-servers/FrameBuffer.h
index da3575d..ce08e03 100644
--- a/stream-servers/FrameBuffer.h
+++ b/stream-servers/FrameBuffer.h
@@ -216,6 +216,11 @@
// Returns the set of ColorBuffers destroyed (for further cleanup)
std::vector<HandleType> destroyEmulatedEglWindowSurfaceLocked(HandleType p_surface);
+ void createEmulatedEglFenceSync(EGLenum type,
+ int destroyWhenSignaled,
+ uint64_t* outSync = nullptr,
+ uint64_t* outSyncThread = nullptr);
+
// Create a new ColorBuffer instance from this display instance.
// |p_width| and |p_height| are its dimensions in pixels.
// |p_internalFormat| is the OpenGL format of this color buffer.
diff --git a/stream-servers/RenderControl.cpp b/stream-servers/RenderControl.cpp
index 2d44259..20803e2 100644
--- a/stream-servers/RenderControl.cpp
+++ b/stream-servers/RenderControl.cpp
@@ -23,7 +23,6 @@
#include <memory>
#include "ChecksumCalculatorThreadInfo.h"
-#include "FenceSync.h"
#include "FrameBuffer.h"
#include "GLESVersionDetector.h"
#include "OpenGLESDispatch/DispatchTables.h"
@@ -46,6 +45,7 @@
using emugl::emugl_sync_register_trigger_wait;
using gfxstream::GLESApi;
using gfxstream::GLESApi_CM;
+using gfxstream::EmulatedEglFenceSync;
#define DEBUG_GRALLOC_SYNC 0
#define DEBUG_EGL_SYNC 0
@@ -1111,7 +1111,7 @@
SyncThread::get()->triggerWaitVk(reinterpret_cast<VkFence>(eglsync_ptr),
timeline);
} else {
- FenceSync* fenceSync = reinterpret_cast<FenceSync*>(eglsync_ptr);
+ EmulatedEglFenceSync* fenceSync = reinterpret_cast<EmulatedEglFenceSync*>(eglsync_ptr);
EGLSYNC_DPRINT(
"eglsync=0x%llx fenceSync=%p thread_ptr=0x%llx "
"timeline=0x%llx",
@@ -1127,15 +1127,9 @@
static void rcCreateSyncKHR(EGLenum type,
EGLint* attribs,
uint32_t num_attribs,
- int destroy_when_signaled,
- uint64_t* eglsync_out,
- uint64_t* syncthread_out) {
- EGLSYNC_DPRINT("type=0x%x num_attribs=%d",
- type, num_attribs);
-
- bool hasNativeFence =
- type == EGL_SYNC_NATIVE_FENCE_ANDROID;
-
+ int destroyWhenSignaled,
+ uint64_t* outSync,
+ uint64_t* outSyncThread) {
// Usually we expect rcTriggerWait to be registered
// at the beginning in rcGetRendererVersion, called
// on init for all contexts.
@@ -1144,44 +1138,16 @@
// rcTriggerWait is registered.
emugl_sync_register_trigger_wait(rcTriggerWait);
- RenderThreadInfoGl* const tInfo = RenderThreadInfoGl::get();
- if (!tInfo) {
- GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
- << "Render thread GL not available.";
- }
-
- if (!tInfo->currContext) {
- auto fb = FrameBuffer::getFB();
- uint32_t create_sync_cxt, create_sync_surf;
- fb->createTrivialContext(0, // There is no context to share.
- &create_sync_cxt,
- &create_sync_surf);
- fb->bindContext(create_sync_cxt,
- create_sync_surf,
- create_sync_surf);
- // This context is then cleaned up when the render thread exits.
- }
-
- FenceSync* fenceSync = new FenceSync(hasNativeFence,
- destroy_when_signaled);
-
- // This MUST be present, or we get a deadlock effect.
- s_gles2.glFlush();
-
- if (syncthread_out) *syncthread_out =
- reinterpret_cast<uint64_t>(SyncThread::get());
-
- if (eglsync_out) {
- uint64_t res = (uint64_t)(uintptr_t)fenceSync;
- *eglsync_out = res;
- EGLSYNC_DPRINT("send out eglsync 0x%llx", res);
- }
+ FrameBuffer::getFB()->createEmulatedEglFenceSync(type,
+ destroyWhenSignaled,
+ outSync,
+ outSyncThread);
}
// |rcClientWaitSyncKHR| implements |eglClientWaitSyncKHR|
// on the guest through using the host's existing
// |eglClientWaitSyncKHR| implementation, which is done
-// through the FenceSync object.
+// through the EmulatedEglFenceSync object.
static EGLint rcClientWaitSyncKHR(uint64_t handle,
EGLint flags,
uint64_t timeout) {
@@ -1196,7 +1162,7 @@
EGLSYNC_DPRINT("handle=0x%lx flags=0x%x timeout=%" PRIu64,
handle, flags, timeout);
- FenceSync* fenceSync = FenceSync::getFromHandle(handle);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
if (!fenceSync) {
EGLSYNC_DPRINT("fenceSync null, return condition satisfied");
@@ -1232,7 +1198,7 @@
EGLSYNC_DPRINT("handle=0x%lx flags=0x%x", handle, flags);
- FenceSync* fenceSync = FenceSync::getFromHandle(handle);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
if (!fenceSync) { return; }
@@ -1254,7 +1220,7 @@
}
static int rcDestroySyncKHR(uint64_t handle) {
- FenceSync* fenceSync = FenceSync::getFromHandle(handle);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
if (!fenceSync) return 0;
fenceSync->decRef();
return 0;
@@ -1391,7 +1357,7 @@
}
static int rcIsSyncSignaled(uint64_t handle) {
- FenceSync* fenceSync = FenceSync::getFromHandle(handle);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
if (!fenceSync) return 1; // assume destroyed => signaled
return fenceSync->isSignaled() ? 1 : 0;
}
@@ -1529,7 +1495,7 @@
}
static void rcDestroySyncKHRAsync(uint64_t handle) {
- FenceSync* fenceSync = FenceSync::getFromHandle(handle);
+ EmulatedEglFenceSync* fenceSync = EmulatedEglFenceSync::getFromHandle(handle);
if (!fenceSync) return;
fenceSync->decRef();
}
diff --git a/stream-servers/RendererImpl.cpp b/stream-servers/RendererImpl.cpp
index d56f28b..3309cd7 100644
--- a/stream-servers/RendererImpl.cpp
+++ b/stream-servers/RendererImpl.cpp
@@ -19,7 +19,6 @@
#include <utility>
#include <variant>
-#include "FenceSync.h"
#include "FrameBuffer.h"
#include "RenderChannelImpl.h"
#include "RenderThread.h"
@@ -337,8 +336,6 @@
auto fb = FrameBuffer::getFB();
assert(fb);
fb->onSave(stream, textureSaver);
-
- FenceSync::onSave(stream);
}
bool RendererImpl::load(android::base::Stream* stream,
@@ -366,9 +363,6 @@
bool res = true;
- res = fb->onLoad(stream, textureLoader);
- FenceSync::onLoad(stream);
-
return res;
}
diff --git a/stream-servers/SyncThread.cpp b/stream-servers/SyncThread.cpp
index 0042973..e348ff5 100644
--- a/stream-servers/SyncThread.cpp
+++ b/stream-servers/SyncThread.cpp
@@ -33,6 +33,7 @@
using android::base::EventHangMetadata;
using emugl::ABORT_REASON_OTHER;
using emugl::FatalError;
+using gfxstream::EmulatedEglFenceSync;
#define DEBUG 0
@@ -117,7 +118,7 @@
cleanup();
}
-void SyncThread::triggerWait(FenceSync* fenceSync,
+void SyncThread::triggerWait(EmulatedEglFenceSync* fenceSync,
uint64_t timeline) {
std::stringstream ss;
ss << "triggerWait fenceSyncInfo=0x" << std::hex << reinterpret_cast<uintptr_t>(fenceSync)
@@ -146,7 +147,7 @@
ss.str());
}
-void SyncThread::triggerBlockedWaitNoTimeline(FenceSync* fenceSync) {
+void SyncThread::triggerBlockedWaitNoTimeline(EmulatedEglFenceSync* fenceSync) {
std::stringstream ss;
ss << "triggerBlockedWaitNoTimeline fenceSyncInfo=0x" << std::hex
<< reinterpret_cast<uintptr_t>(fenceSync);
@@ -158,7 +159,7 @@
ss.str());
}
-void SyncThread::triggerWaitWithCompletionCallback(FenceSync* fenceSync, FenceCompletionCallback cb) {
+void SyncThread::triggerWaitWithCompletionCallback(EmulatedEglFenceSync* fenceSync, FenceCompletionCallback cb) {
std::stringstream ss;
ss << "triggerWaitWithCompletionCallback fenceSyncInfo=0x" << std::hex
<< reinterpret_cast<uintptr_t>(fenceSync);
@@ -333,17 +334,17 @@
mWorkerThreadPool.waitAllItems();
}
-void SyncThread::doSyncWait(FenceSync* fenceSync, std::function<void()> onComplete) {
+void SyncThread::doSyncWait(EmulatedEglFenceSync* fenceSync, std::function<void()> onComplete) {
DPRINT("enter");
- if (!FenceSync::getFromHandle((uint64_t)(uintptr_t)fenceSync)) {
+ if (!EmulatedEglFenceSync::getFromHandle((uint64_t)(uintptr_t)fenceSync)) {
if (onComplete) {
onComplete();
}
return;
}
- // We shouldn't use FenceSync to wait, when SyncThread is initialized
- // without GL enabled, because FenceSync uses EGL/GLES.
+ // We shouldn't use EmulatedEglFenceSync to wait, when SyncThread is initialized
+ // without GL enabled, because EmulatedEglFenceSync uses EGL/GLES.
SYNC_THREAD_CHECK(!mNoGL);
EGLint wait_result = 0x0;
@@ -391,7 +392,7 @@
if (onComplete) {
onComplete();
}
- FenceSync::incrementTimelineAndDeleteOldFences();
+ EmulatedEglFenceSync::incrementTimelineAndDeleteOldFences();
DPRINT("done timeline increment");
diff --git a/stream-servers/SyncThread.h b/stream-servers/SyncThread.h
index 59be896..dd3aa11 100644
--- a/stream-servers/SyncThread.h
+++ b/stream-servers/SyncThread.h
@@ -25,7 +25,6 @@
#include <string>
#include <type_traits>
-#include "FenceSync.h"
#include "aemu/base/synchronization/ConditionVariable.h"
#include "aemu/base/HealthMonitor.h"
#include "aemu/base/synchronization/Lock.h"
@@ -33,6 +32,7 @@
#include "aemu/base/Optional.h"
#include "aemu/base/threads/Thread.h"
#include "aemu/base/threads/ThreadPool.h"
+#include "gl/EmulatedEglFenceSync.h"
#include "render-utils/virtio_gpu_ops.h"
#include "vulkan/VkDecoderGlobalState.h"
@@ -52,13 +52,13 @@
SyncThread(bool noGL, HealthMonitor<>& healthMonitor);
~SyncThread();
- // |triggerWait|: async wait with a given FenceSync object.
+ // |triggerWait|: async wait with a given EmulatedEglFenceSync object.
// We use the wait() method to do a eglClientWaitSyncKHR.
// After wait is over, the timeline will be incremented,
// which should signal the guest-side fence FD.
// This method is how the goldfish sync virtual device
// knows when to increment timelines / signal native fence FD's.
- void triggerWait(FenceSync* fenceSync, uint64_t timeline);
+ void triggerWait(gfxstream::EmulatedEglFenceSync* fenceSync, uint64_t timeline);
// |triggerWaitVk|: async wait with a given VkFence object.
// The |vkFence| argument is a *boxed* host Vulkan handle of the fence.
@@ -72,11 +72,12 @@
// for use with the virtio-gpu path; is meant to have a current context
// while waiting.
- void triggerBlockedWaitNoTimeline(FenceSync* fenceSync);
+ void triggerBlockedWaitNoTimeline(gfxstream::EmulatedEglFenceSync* fenceSync);
// For use with virtio-gpu and async fence completion callback. This is async like triggerWait,
// but takes a fence completion callback instead of incrementing some timeline directly.
- void triggerWaitWithCompletionCallback(FenceSync* fenceSync, FenceCompletionCallback);
+ void triggerWaitWithCompletionCallback(gfxstream::EmulatedEglFenceSync* fenceSync,
+ FenceCompletionCallback);
void triggerWaitVkWithCompletionCallback(VkFence fenceHandle, FenceCompletionCallback);
void triggerWaitVkQsriWithCompletionCallback(VkImage image, FenceCompletionCallback);
void triggerGeneral(FenceCompletionCallback, std::string description);
@@ -126,7 +127,8 @@
// |doSyncThreadCmd| execute the actual task. These run on the sync thread.
void doSyncThreadCmd(Command&& command, ThreadPool::WorkerId);
- void doSyncWait(FenceSync* fenceSync, std::function<void()> onComplete);
+ void doSyncWait(gfxstream::EmulatedEglFenceSync* fenceSync,
+ std::function<void()> onComplete);
static int doSyncWaitVk(VkFence, std::function<void()> onComplete);
// EGL objects / object handles specific to
diff --git a/stream-servers/gl/Android.bp b/stream-servers/gl/Android.bp
index bc76f78..0ddae14 100644
--- a/stream-servers/gl/Android.bp
+++ b/stream-servers/gl/Android.bp
@@ -19,6 +19,7 @@
"DisplaySurfaceGl.cpp",
"EmulatedEglConfig.cpp",
"EmulatedEglContext.cpp",
+ "EmulatedEglFenceSync.cpp",
"EmulatedEglImage.cpp",
"EmulatedEglWindowSurface.cpp",
"EmulationGl.cpp",
diff --git a/stream-servers/gl/CMakeLists.txt b/stream-servers/gl/CMakeLists.txt
index 76eb44c..711f768 100644
--- a/stream-servers/gl/CMakeLists.txt
+++ b/stream-servers/gl/CMakeLists.txt
@@ -17,6 +17,7 @@
DisplaySurfaceGl.cpp
EmulatedEglConfig.cpp
EmulatedEglContext.cpp
+ EmulatedEglFenceSync.cpp
EmulatedEglImage.cpp
EmulatedEglWindowSurface.cpp
EmulationGl.cpp
diff --git a/stream-servers/gl/EmulatedEglFenceSync.cpp b/stream-servers/gl/EmulatedEglFenceSync.cpp
new file mode 100644
index 0000000..8ac94da
--- /dev/null
+++ b/stream-servers/gl/EmulatedEglFenceSync.cpp
@@ -0,0 +1,215 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "EmulatedEglFenceSync.h"
+
+#include <unordered_set>
+
+#include "OpenGLESDispatch/DispatchTables.h"
+#include "OpenGLESDispatch/EGLDispatch.h"
+#include "RenderThreadInfoGl.h"
+#include "StalePtrRegistry.h"
+#include "aemu/base/containers/Lookup.h"
+#include "aemu/base/containers/StaticMap.h"
+#include "aemu/base/files/StreamSerializing.h"
+#include "aemu/base/synchronization/Lock.h"
+
+namespace gfxstream {
+namespace {
+
+using android::base::AutoLock;
+using android::base::Lock;
+using android::base::StaticMap;
+
+// Timeline class is meant to delete native fences after the
+// sync device has incremented the timeline. We assume a
+// maximum number of outstanding timelines in the guest (16) in
+// order to derive when a native fence is definitely safe to
+// delete. After at least that many timeline increments have
+// happened, we sweep away the remaining native fences.
+// The function that performs the deleting,
+// incrementTimelineAndDeleteOldFences(), happens on the SyncThread.
+
+class Timeline {
+ public:
+ Timeline() = default;
+
+ static constexpr int kMaxGuestTimelines = 16;
+ void addFence(EmulatedEglFenceSync* fence) {
+ mFences.set(fence, mTime.load() + kMaxGuestTimelines);
+ }
+
+ void incrementTimelineAndDeleteOldFences() {
+ ++mTime;
+ sweep();
+ }
+
+ void sweep() {
+ mFences.eraseIf([time = mTime.load()](EmulatedEglFenceSync* fence, int fenceTime) {
+ EmulatedEglFenceSync* actual = EmulatedEglFenceSync::getFromHandle((uint64_t)(uintptr_t)fence);
+ if (!actual) return true;
+
+ bool shouldErase = fenceTime <= time;
+ if (shouldErase) {
+ if (!actual->decRef() &&
+ actual->shouldDestroyWhenSignaled()) {
+ actual->decRef();
+ }
+ }
+ return shouldErase;
+ });
+ }
+
+ private:
+ std::atomic<int> mTime {0};
+ StaticMap<EmulatedEglFenceSync*, int> mFences;
+};
+
+static Timeline* sTimeline() {
+ static Timeline* t = new Timeline;
+ return t;
+}
+
+} // namespace
+
+// static
+void EmulatedEglFenceSync::incrementTimelineAndDeleteOldFences() {
+ sTimeline()->incrementTimelineAndDeleteOldFences();
+}
+
+// static
+std::unique_ptr<EmulatedEglFenceSync> EmulatedEglFenceSync::create(
+ EGLDisplay display,
+ bool hasNativeFence,
+ bool destroyWhenSignaled) {
+ auto sync = s_egl.eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
+ if (sync == EGL_NO_SYNC_KHR) {
+ ERR("Failed to create EGL fence sync: %d", s_egl.eglGetError());
+ return nullptr;
+ }
+
+ // This MUST be present, or we get a deadlock effect.
+ s_gles2.glFlush();
+
+ return std::unique_ptr<EmulatedEglFenceSync>(
+ new EmulatedEglFenceSync(display,
+ sync,
+ hasNativeFence,
+ destroyWhenSignaled));
+}
+
+EmulatedEglFenceSync::EmulatedEglFenceSync(EGLDisplay display,
+ EGLSyncKHR sync,
+ bool hasNativeFence,
+ bool destroyWhenSignaled)
+ : mDestroyWhenSignaled(destroyWhenSignaled),
+ mDisplay(display),
+ mSync(sync) {
+
+ addToRegistry();
+
+ assert(mCount == 1);
+ if (hasNativeFence) {
+ incRef();
+ sTimeline()->addFence(this);
+ }
+
+ // Assumes that there is a valid + current OpenGL context
+ assert(RenderThreadInfoGl::get());
+}
+
+EmulatedEglFenceSync::~EmulatedEglFenceSync() {
+ removeFromRegistry();
+}
+
+EGLint EmulatedEglFenceSync::wait(uint64_t timeout) {
+ incRef();
+ EGLint wait_res =
+ s_egl.eglClientWaitSyncKHR(mDisplay, mSync,
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
+ timeout);
+ decRef();
+ return wait_res;
+}
+
+void EmulatedEglFenceSync::waitAsync() {
+ s_egl.eglWaitSyncKHR(mDisplay, mSync, 0);
+}
+
+bool EmulatedEglFenceSync::isSignaled() {
+ EGLint val;
+ if (EGL_TRUE ==
+ s_egl.eglGetSyncAttribKHR(
+ mDisplay, mSync, EGL_SYNC_STATUS_KHR, &val))
+ return val == EGL_SIGNALED_KHR;
+
+ return true; // if invalid, treat as signaled
+}
+
+void EmulatedEglFenceSync::destroy() {
+ s_egl.eglDestroySyncKHR(mDisplay, mSync);
+}
+
+// Snapshots for EmulatedEglFenceSync//////////////////////////////////////////////////////
+// It's possible, though it does not happen often, that a fence
+// can be created but not yet waited on by the guest, which
+// needs careful handling:
+//
+// 1. Avoid manipulating garbage memory on snapshot restore;
+// rcCreateSyncKHR *creates new fence in valid memory*
+// --snapshot--
+// rcClientWaitSyncKHR *refers to uninitialized memory*
+// rcDestroySyncKHR *refers to uninitialized memory*
+// 2. Make rcCreateSyncKHR/rcDestroySyncKHR implementations return
+// the "signaled" status if referring to previous snapshot fences. It's
+// assumed that the GPU is long done with them.
+// 3. Avoid name collisions where a new EmulatedEglFenceSync object is created
+// that has the same uint64_t casting as a EmulatedEglFenceSync object from a previous
+// snapshot.
+
+// Maintain a StalePtrRegistry<EmulatedEglFenceSync>:
+static StalePtrRegistry<EmulatedEglFenceSync>* sFenceRegistry() {
+ static StalePtrRegistry<EmulatedEglFenceSync>* s = new StalePtrRegistry<EmulatedEglFenceSync>;
+ return s;
+}
+
+// static
+void EmulatedEglFenceSync::addToRegistry() {
+ sFenceRegistry()->addPtr(this);
+}
+
+// static
+void EmulatedEglFenceSync::removeFromRegistry() {
+ sFenceRegistry()->removePtr(this);
+}
+
+// static
+void EmulatedEglFenceSync::onSave(android::base::Stream* stream) {
+ sFenceRegistry()->makeCurrentPtrsStale();
+ sFenceRegistry()->onSave(stream);
+}
+
+// static
+void EmulatedEglFenceSync::onLoad(android::base::Stream* stream) {
+ sFenceRegistry()->onLoad(stream);
+}
+
+// static
+EmulatedEglFenceSync* EmulatedEglFenceSync::getFromHandle(uint64_t handle) {
+ return sFenceRegistry()->getPtr(handle);
+}
+
+} // namespace gfxstream
diff --git a/stream-servers/FenceSync.h b/stream-servers/gl/EmulatedEglFenceSync.h
similarity index 87%
rename from stream-servers/FenceSync.h
rename to stream-servers/gl/EmulatedEglFenceSync.h
index e301f7c..f53374a 100644
--- a/stream-servers/FenceSync.h
+++ b/stream-servers/gl/EmulatedEglFenceSync.h
@@ -16,16 +16,19 @@
#pragma once
-#include "aemu/base/Compiler.h"
-#include "aemu/base/files/Stream.h"
-#include "aemu/base/synchronization/Lock.h"
+#include <atomic>
+#include <memory>
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <atomic>
+#include "aemu/base/Compiler.h"
+#include "aemu/base/files/Stream.h"
+#include "aemu/base/synchronization/Lock.h"
-// The FenceSync class wraps actual EGLSyncKHR objects
+namespace gfxstream {
+
+// The EmulatedEglFenceSync class wraps actual EGLSyncKHR objects
// and issues calls to eglCreateSyncKHR, eglClientWaitSyncKHR,
// and eglDestroySyncKHR.
//
@@ -53,16 +56,19 @@
// those on the guest, as that would require starting up another guest
// thread and OpenGL context (complete with host connection)
// to destroy it.
-class FenceSync {
-public:
+class EmulatedEglFenceSync {
+ public:
// The constructor wraps eglCreateSyncKHR on the host OpenGL driver.
// |hasNativeFence| specifies whether this sync object
// is of EGL_SYNC_NATIVE_FENCE_ANDROID nature (2), and
// |destroyWhenSignaled| specifies whether or not to destroy
// the sync object when the native fence FD becomes signaled (3).
- FenceSync(bool hasNativeFence,
- bool destroyWhenSignaled);
- ~FenceSync();
+ static std::unique_ptr<EmulatedEglFenceSync> create(
+ EGLSyncKHR sync,
+ bool hasNativeFence,
+ bool destroyWhenSignaled);
+
+ ~EmulatedEglFenceSync();
// wait() wraps eglClientWaitSyncKHR. During such a wait, we need
// to increment the reference count while the wait is active,
@@ -80,7 +86,7 @@
}
// When a native fence gets signaled, this function is called to update the
- // timeline counter in the FenceSync internal timeline and delete old
+ // timeline counter in the EmulatedEglFenceSync internal timeline and delete old
// fences.
static void incrementTimelineAndDeleteOldFences();
@@ -118,12 +124,18 @@
void addToRegistry();
void removeFromRegistry();
- static FenceSync* getFromHandle(uint64_t handle);
+ static EmulatedEglFenceSync* getFromHandle(uint64_t handle);
// Functions for snapshotting all fence state at once
static void onSave(android::base::Stream* stream);
static void onLoad(android::base::Stream* stream);
-private:
+
+ private:
+ EmulatedEglFenceSync(EGLDisplay display,
+ EGLSyncKHR sync,
+ bool hasNativeFence,
+ bool destroyWhenSignaled);
+
bool mDestroyWhenSignaled;
std::atomic<int> mCount {1};
@@ -135,5 +147,7 @@
// careful control of when eglDestroySyncKHR is actually called.
void destroy();
- DISALLOW_COPY_AND_ASSIGN(FenceSync);
+ DISALLOW_COPY_AND_ASSIGN(EmulatedEglFenceSync);
};
+
+} // namespace gfxstream
diff --git a/stream-servers/gl/EmulationGl.cpp b/stream-servers/gl/EmulationGl.cpp
index 0c0f5ec..351dc52 100644
--- a/stream-servers/gl/EmulationGl.cpp
+++ b/stream-servers/gl/EmulationGl.cpp
@@ -591,6 +591,16 @@
return EmulatedEglContext::onLoad(stream, mEglDisplay);
}
+std::unique_ptr<EmulatedEglFenceSync> EmulationGl::createEmulatedEglFenceSync(
+ EGLenum type,
+ int destroyWhenSignaled) {
+ const bool hasNativeFence = type == EGL_SYNC_NATIVE_FENCE_ANDROID;
+ return EmulatedEglFenceSync::create(mEglDisplay,
+ hasNativeFence,
+ destroyWhenSignaled);
+
+}
+
std::unique_ptr<EmulatedEglImage> EmulationGl::createEmulatedEglImage(
EmulatedEglContext* context,
EGLenum target,
diff --git a/stream-servers/gl/EmulationGl.h b/stream-servers/gl/EmulationGl.h
index 91ee41a..f3b750b 100644
--- a/stream-servers/gl/EmulationGl.h
+++ b/stream-servers/gl/EmulationGl.h
@@ -34,6 +34,7 @@
#include "EmulatedEglContext.h"
#include "EmulatedEglConfig.h"
#include "EmulatedEglContext.h"
+#include "EmulatedEglFenceSync.h"
#include "EmulatedEglImage.h"
#include "EmulatedEglWindowSurface.h"
#include "OpenGLESDispatch/GLESv2Dispatch.h"
@@ -98,6 +99,10 @@
std::unique_ptr<EmulatedEglContext> loadEmulatedEglContext(
android::base::Stream* stream);
+ std::unique_ptr<EmulatedEglFenceSync> createEmulatedEglFenceSync(
+ EGLenum type,
+ int destroyWhenSignaled);
+
std::unique_ptr<EmulatedEglImage> createEmulatedEglImage(
EmulatedEglContext* context,
EGLenum target,
diff --git a/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.cpp b/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.cpp
index b2c7cb1..5a0cd78 100644
--- a/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.cpp
+++ b/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.cpp
@@ -17,7 +17,9 @@
#include "ANGLEShaderParser.h"
#include "ShaderTranslator.h"
+#include "aemu/base/SharedLibrary.h"
#include "aemu/base/synchronization/Lock.h"
+#include "host-common/logging.h"
#include <map>
#include <string>
@@ -32,6 +34,80 @@
bool kInitialized = false;
bool sIsGles2Gles = false;
+class LazyLoadedSTDispatch {
+public:
+ LazyLoadedSTDispatch() {
+ memset(&mDispatch, 0, sizeof(STDispatch));
+
+#ifdef __APPLE__
+ const char kLibName[] = "libshadertranslator.dylib";
+#elif defined(_WIN32)
+ const char kLibName[] = "libshadertranslator.dll";
+#else
+ const char kLibName[] = "libshadertranslator.so";
+#endif
+ char error[256];
+ mLib = android::base::SharedLibrary::open(kLibName, error, sizeof(error));
+ if (!mLib) {
+ ERR("%s: Could not open shader translator library %s [%s]\n",
+ __func__, kLibName, error);
+ return;
+ }
+
+ mDispatch.initialize =
+ (STInitialize_t)mLib->findSymbol("STInitialize");
+ mDispatch.finalize =
+ (STFinalize_t)mLib->findSymbol("STFinalize");
+ mDispatch.generateResources =
+ (STGenerateResources_t)mLib->findSymbol("STGenerateResources");
+ mDispatch.compileAndResolve =
+ (STCompileAndResolve_t)mLib->findSymbol("STCompileAndResolve");
+ mDispatch.freeShaderResolveState =
+ (STFreeShaderResolveState_t)mLib->findSymbol("STFreeShaderResolveState");
+ mDispatch.copyVariable =
+ (STCopyVariable_t)mLib->findSymbol("STCopyVariable");
+ mDispatch.copyInterfaceBlock =
+ (STCopyInterfaceBlock_t)mLib->findSymbol("STCopyInterfaceBlock");
+ mDispatch.destroyVariable =
+ (STDestroyVariable_t)mLib->findSymbol("STDestroyVariable");
+ mDispatch.destroyInterfaceBlock =
+ (STDestroyInterfaceBlock_t)mLib->findSymbol("STDestroyInterfaceBlock");
+
+ mValid = dispatchValid();
+
+ if (!mValid) {
+ ERR("%s: error, shader translator dispatch not valid\n", __func__);
+ }
+ }
+
+ STDispatch* getDispatch() {
+ if (!mValid) return nullptr;
+ return &mDispatch;
+ }
+
+private:
+ bool dispatchValid() {
+ return (nullptr != mDispatch.initialize) &&
+ (nullptr != mDispatch.finalize) &&
+ (nullptr != mDispatch.generateResources) &&
+ (nullptr != mDispatch.compileAndResolve) &&
+ (nullptr != mDispatch.copyVariable) &&
+ (nullptr != mDispatch.copyInterfaceBlock) &&
+ (nullptr != mDispatch.destroyVariable) &&
+ (nullptr != mDispatch.destroyInterfaceBlock);
+ }
+
+ android::base::SharedLibrary* mLib = nullptr;
+ bool mValid = false;
+ STDispatch mDispatch;
+};
+
+
+static STDispatch* getSTDispatch() {
+ static LazyLoadedSTDispatch* dispatch = new LazyLoadedSTDispatch;
+ return dispatch->getDispatch();
+}
+
ShaderLinkInfo::ShaderLinkInfo() = default;
ShaderLinkInfo::ShaderLinkInfo(const ShaderLinkInfo& other) {
clear();
@@ -70,11 +146,12 @@
esslVersion = other.esslVersion;
if (!sIsGles2Gles) {
- for (const auto& var: other.uniforms) { uniforms.push_back(STCopyVariable(&var)); }
- for (const auto& var: other.varyings) { varyings.push_back(STCopyVariable(&var)); }
- for (const auto& var: other.attributes) { attributes.push_back(STCopyVariable(&var)); }
- for (const auto& var: other.outputVars) { outputVars.push_back(STCopyVariable(&var)); }
- for (const auto& var: other.interfaceBlocks) { interfaceBlocks.push_back(STCopyInterfaceBlock(&var)); }
+ auto dispatch = getSTDispatch();
+ for (const auto& var: other.uniforms) { uniforms.push_back(dispatch->copyVariable(&var)); }
+ for (const auto& var: other.varyings) { varyings.push_back(dispatch->copyVariable(&var)); }
+ for (const auto& var: other.attributes) { attributes.push_back(dispatch->copyVariable(&var)); }
+ for (const auto& var: other.outputVars) { outputVars.push_back(dispatch->copyVariable(&var)); }
+ for (const auto& var: other.interfaceBlocks) { interfaceBlocks.push_back(dispatch->copyInterfaceBlock(&var)); }
}
nameMap = other.nameMap;
@@ -84,11 +161,12 @@
void ShaderLinkInfo::clear() {
if (!sIsGles2Gles) {
- for (auto& var: uniforms) { STDestroyVariable(&var); }
- for (auto& var: varyings) { STDestroyVariable(&var); }
- for (auto& var: attributes) { STDestroyVariable(&var); }
- for (auto& var: outputVars) { STDestroyVariable(&var); }
- for (auto& var: interfaceBlocks) { STDestroyInterfaceBlock(&var); }
+ auto dispatch = getSTDispatch();
+ for (auto& var: uniforms) { dispatch->destroyVariable(&var); }
+ for (auto& var: varyings) { dispatch->destroyVariable(&var); }
+ for (auto& var: attributes) { dispatch->destroyVariable(&var); }
+ for (auto& var: outputVars) { dispatch->destroyVariable(&var); }
+ for (auto& var: interfaceBlocks) { dispatch->destroyInterfaceBlock(&var); }
}
uniforms.clear();
@@ -166,7 +244,7 @@
BuiltinResourcesEditCallback callback) {
if (!sIsGles2Gles) {
- STGenerateResources(&kResources);
+ getSTDispatch()->generateResources(&kResources);
}
callback(kResources);
@@ -179,7 +257,7 @@
sIsGles2Gles = isGles2Gles;
if (!sIsGles2Gles) {
- STInitialize();
+ getSTDispatch()->initialize();
}
initializeResources(editCallback);
@@ -217,19 +295,23 @@
linkInfo->nameMapReverse[elt.second] = elt.first;
}
+ auto st = getSTDispatch();
+ auto stCopyVariable = st->copyVariable;
+ auto stCopyInterfaceBlock = st->copyInterfaceBlock;
+
linkInfo->uniforms = convertArrayToVecWithCopy(
compileResult->uniformsCount,
compileResult->pUniforms,
- STCopyVariable);
+ stCopyVariable);
std::vector<ST_ShaderVariable> inputVaryings =
convertArrayToVecWithCopy(
compileResult->inputVaryingsCount, compileResult->pInputVaryings,
- STCopyVariable);
+ stCopyVariable);
std::vector<ST_ShaderVariable> outputVaryings =
convertArrayToVecWithCopy(
compileResult->outputVaryingsCount, compileResult->pOutputVaryings,
- STCopyVariable);
+ stCopyVariable);
linkInfo->varyings.clear();
linkInfo->varyings.insert(
@@ -245,19 +327,19 @@
convertArrayToVecWithCopy(
compileResult->allAttributesCount,
compileResult->pAllAttributes,
- STCopyVariable);
+ stCopyVariable);
linkInfo->outputVars =
convertArrayToVecWithCopy(
compileResult->activeOutputVariablesCount,
compileResult->pActiveOutputVariables,
- STCopyVariable);
+ stCopyVariable);
linkInfo->interfaceBlocks =
convertArrayToVecWithCopy(
compileResult->uniformBlocksCount,
compileResult->pUniformBlocks,
- STCopyInterfaceBlock);
+ stCopyInterfaceBlock);
// todo: split to uniform and ssbo
}
@@ -338,7 +420,8 @@
ST_ShaderCompileResult* res = nullptr;
- STCompileAndResolve(&ci, &res);
+ auto st = getSTDispatch();
+ st->compileAndResolve(&ci, &res);
sCompilerMap()->emplace(key, res->outputHandle);
*outInfolog = std::string(res->infoLog);
@@ -348,7 +431,7 @@
bool ret = res->compileStatus == 1;
- STFreeShaderResolveState(res);
+ st->freeShaderResolveState(res);
return ret;
}
diff --git a/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.h b/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.h
index 187764f..9d9f742 100644
--- a/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.h
+++ b/stream-servers/gl/glestranslator/GLES_V2/ANGLEShaderParser.h
@@ -30,8 +30,6 @@
// Convenient to query those
extern ST_BuiltInResources kResources;
-STDispatch* getSTDispatch();
-
// For performing link-time validation of shader programs.
struct ShaderLinkInfo {
int esslVersion;
diff --git a/stream-servers/gl/glestranslator/GLES_V2/CMakeLists.txt b/stream-servers/gl/glestranslator/GLES_V2/CMakeLists.txt
index 550ed00..5aee5c5 100644
--- a/stream-servers/gl/glestranslator/GLES_V2/CMakeLists.txt
+++ b/stream-servers/gl/glestranslator/GLES_V2/CMakeLists.txt
@@ -19,9 +19,3 @@
apigen-codec-common
aemu-base.headers
aemu-host-common.headers)
-
-if(USE_ANGLE_SHADER_PARSER)
- target_link_libraries(
- GLES_V2_translator_static PRIVATE
- angle_shader_translator)
-endif ()
diff --git a/stream-servers/tests/SampleApplication.cpp b/stream-servers/tests/SampleApplication.cpp
index 0067d03..cbb1e74 100644
--- a/stream-servers/tests/SampleApplication.cpp
+++ b/stream-servers/tests/SampleApplication.cpp
@@ -35,6 +35,7 @@
using android::base::Lock;
using android::base::MessageChannel;
using android::base::TestSystem;
+using gfxstream::EmulatedEglFenceSync;
using gfxstream::GLESApi;
using gfxstream::GLESApi_3_0;
using gfxstream::GLESApi_CM;
@@ -166,13 +167,14 @@
class ColorBufferQueue { // Note: we could have called this BufferQueue but there is another
// class of name BufferQueue that does something totally different
-public:
+ public:
static constexpr int kCapacity = 3;
class Item {
- public:
- Item(unsigned int cb = 0, FenceSync* s = nullptr) : colorBuffer(cb), sync(s) { }
+ public:
+ Item(unsigned int cb = 0, EmulatedEglFenceSync* s = nullptr)
+ : colorBuffer(cb), sync(s) { }
unsigned int colorBuffer = 0;
- FenceSync* sync = nullptr;
+ EmulatedEglFenceSync* sync = nullptr;
};
ColorBufferQueue() = default;
@@ -185,7 +187,7 @@
mQueue.receive(outItem);
}
-private:
+ private:
MessageChannel<Item, kCapacity> mQueue;
};
@@ -316,11 +318,10 @@
}
}
-FenceSync* SampleApplication::getFenceSync() {
- auto gl = getGlDispatch();
- FenceSync* sync = new FenceSync(false, false);
- gl->glFlush();
- return sync;
+EmulatedEglFenceSync* SampleApplication::getFenceSync() {
+ uint64_t sync;
+ mFb->createEmulatedEglFenceSync(EGL_SYNC_FENCE_KHR, false, &sync);
+ return EmulatedEglFenceSync::getFromHandle(sync);
}
void SampleApplication::drawWorkerWithCompose(ColorBufferQueue& app2sfQueue,
diff --git a/stream-servers/tests/SampleApplication.h b/stream-servers/tests/SampleApplication.h
index b7c8e81..73cb716 100644
--- a/stream-servers/tests/SampleApplication.h
+++ b/stream-servers/tests/SampleApplication.h
@@ -18,11 +18,11 @@
#include <functional>
#include <memory>
-#include "FenceSync.h"
#include "Hwc2.h"
#include "OpenGLESDispatch/GLESv2Dispatch.h"
#include "aemu/base/Compiler.h"
#include "gl/EmulatedEglContext.h"
+#include "gl/EmulatedEglFenceSync.h"
class FrameBuffer;
class OSWindow;
@@ -84,7 +84,7 @@
void drawWorkerWithCompose(ColorBufferQueue& app2sfQueue, ColorBufferQueue& sf2appQueue);
void drawWorker(ColorBufferQueue& app2sfQueue, ColorBufferQueue& sf2appQueue,
ColorBufferQueue& sf2hwcQueue, ColorBufferQueue& hwc2sfQueue);
- FenceSync* getFenceSync();
+ gfxstream::EmulatedEglFenceSync* getFenceSync();
protected:
virtual void initialize() = 0;
diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt
index f4fb8e0..c0824fd 100644
--- a/third-party/CMakeLists.txt
+++ b/third-party/CMakeLists.txt
@@ -209,6 +209,3 @@
if(NOT TARGET flatbuffers)
message(FATAL_ERROR "The dependency flatbuffers not found.")
endif()
-if(USE_ANGLE_SHADER_PARSER AND NOT TARGET angle_shader_translator)
- message(FATAL_ERROR "The dependency angle_shader_translator not found.")
-endif()
\ No newline at end of file