aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoff Lang <geofflang@chromium.org>2023-11-27 14:44:07 -0500
committerAngle LUCI CQ <angle-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-12-08 17:26:07 +0000
commitc27a4a1d7d3794b92518735c2ba84871748c16f4 (patch)
tree3fc17b4144290dbf27b9d7f2c521067e41bd6b56
parent4732409f30383b45eb8824dea3e294b7a3de8e7d (diff)
downloadangle-c27a4a1d7d3794b92518735c2ba84871748c16f4.tar.gz
Re-use EGL sync object allocations.
Create a pool of EGL sync objects with their implementations that can be re-used. Update all backend implementations to support multiple calls to initialize/destroy. Pool size of 32 chosen through experimentation using Chrome. Bug: angleproject:8430 Change-Id: I86fea41aed35eddccc953efb3802bf5fdb7f3cb2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5063341 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
-rw-r--r--src/libANGLE/Display.cpp56
-rw-r--r--src/libANGLE/Display.h9
-rw-r--r--src/libANGLE/EGLSync.cpp8
-rw-r--r--src/libANGLE/EGLSync.h7
-rw-r--r--src/libANGLE/capture/FrameCapture.cpp4
-rw-r--r--src/libANGLE/renderer/metal/SyncMtl.mm6
-rw-r--r--src/libANGLE/renderer/vulkan/SyncVk.cpp9
-rw-r--r--src/libANGLE/renderer/vulkan/SyncVk.h2
8 files changed, 62 insertions, 39 deletions
diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp
index 9a4a73b63a..b2dc054476 100644
--- a/src/libANGLE/Display.cpp
+++ b/src/libANGLE/Display.cpp
@@ -1166,7 +1166,7 @@ Error Display::destroyInvalidEglObjects()
while (!mInvalidSyncMap.empty())
{
- destroySyncImpl(mInvalidSyncMap.begin()->second, &mInvalidSyncMap);
+ destroySyncImpl(mInvalidSyncMap.begin()->second->id(), &mInvalidSyncMap);
}
return NoError();
@@ -1206,7 +1206,8 @@ Error Display::terminate(Thread *thread, TerminateReason terminateReason)
mInvalidSurfaceMap.insert(mState.surfaceMap.begin(), mState.surfaceMap.end());
mState.surfaceMap.clear();
- mInvalidSyncMap.insert(mSyncMap.begin(), mSyncMap.end());
+ mInvalidSyncMap.insert(std::make_move_iterator(mSyncMap.begin()),
+ std::make_move_iterator(mSyncMap.end()));
mSyncMap.clear();
// Cache total number of contexts before invalidation. This is used as a check to verify that
@@ -1261,6 +1262,8 @@ Error Display::terminate(Thread *thread, TerminateReason terminateReason)
// Clean up all invalid objects
ANGLE_TRY(destroyInvalidEglObjects());
+ mSyncPools.clear();
+
mConfigSet.clear();
if (mDevice != nullptr && mDevice->getOwningDisplay() != nullptr)
@@ -1641,17 +1644,29 @@ Error Display::createSync(const gl::Context *currentContext,
ANGLE_TRY(restoreLostDevice());
}
- angle::UniqueObjectPointer<egl::Sync, Display> syncPtr(new Sync(mImplementation, id, type),
- this);
+ std::unique_ptr<Sync> sync;
- ANGLE_TRY(syncPtr->initialize(this, currentContext, attribs));
+ SyncPool &pool = mSyncPools[type];
+ if (!pool.empty())
+ {
+ sync = std::move(pool.back());
+ pool.pop_back();
+ }
+ else
+ {
+ sync.reset(new Sync(mImplementation, type));
+ }
- Sync *sync = syncPtr.release();
+ Error err = sync->initialize(this, currentContext, id, attribs);
+ if (err.isError())
+ {
+ sync->onDestroy(this);
+ return err;
+ }
- sync->addRef();
- mSyncMap.insert(std::pair(sync->id().value, sync));
+ *outSync = sync.get();
+ mSyncMap.insert(std::pair(id.value, std::move(sync)));
- *outSync = sync;
return NoError();
}
@@ -1890,12 +1905,21 @@ Error Display::destroyContext(Thread *thread, gl::Context *context)
return NoError();
}
-void Display::destroySyncImpl(Sync *sync, SyncMap *syncs)
+void Display::destroySyncImpl(SyncID syncId, SyncMap *syncs)
{
- auto iter = syncs->find(sync->id().value);
+ auto iter = syncs->find(syncId.value);
ASSERT(iter != syncs->end());
- mSyncHandleAllocator.release(sync->id().value);
- iter->second->release(this);
+ mSyncHandleAllocator.release(syncId.value);
+
+ auto &sync = iter->second;
+ sync->onDestroy(this);
+
+ SyncPool &pool = mSyncPools[sync->getType()];
+ if (pool.size() < kMaxSyncPoolSizePerType)
+ {
+ pool.push_back(std::move(sync));
+ }
+
syncs->erase(iter);
}
@@ -1916,7 +1940,7 @@ Error Display::destroySurface(Surface *surface)
void Display::destroySync(Sync *sync)
{
- return destroySyncImpl(sync, &mSyncMap);
+ return destroySyncImpl(sync->id(), &mSyncMap);
}
bool Display::isDeviceLost() const
@@ -2628,7 +2652,7 @@ const egl::Image *Display::getImage(egl::ImageID imageID) const
const egl::Sync *Display::getSync(egl::SyncID syncID) const
{
auto iter = mSyncMap.find(syncID.value);
- return iter != mSyncMap.end() ? iter->second : nullptr;
+ return iter != mSyncMap.end() ? iter->second.get() : nullptr;
}
gl::Context *Display::getContext(gl::ContextID contextID)
@@ -2652,7 +2676,7 @@ egl::Image *Display::getImage(egl::ImageID imageID)
egl::Sync *Display::getSync(egl::SyncID syncID)
{
auto iter = mSyncMap.find(syncID.value);
- return iter != mSyncMap.end() ? iter->second : nullptr;
+ return iter != mSyncMap.end() ? iter->second.get() : nullptr;
}
// static
diff --git a/src/libANGLE/Display.h b/src/libANGLE/Display.h
index 4079be8834..536347df54 100644
--- a/src/libANGLE/Display.h
+++ b/src/libANGLE/Display.h
@@ -80,7 +80,7 @@ constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
using ImageMap = angle::HashMap<GLuint, Image *>;
using StreamSet = angle::HashSet<Stream *>;
-using SyncMap = angle::HashMap<GLuint, Sync *>;
+using SyncMap = angle::HashMap<GLuint, std::unique_ptr<Sync>>;
class Display final : public LabeledObject,
public angle::ObserverInterface,
@@ -353,12 +353,17 @@ class Display final : public LabeledObject,
ImageMap mImageMap;
StreamSet mStreamSet;
+
SyncMap mSyncMap;
+ static constexpr size_t kMaxSyncPoolSizePerType = 32;
+ using SyncPool = angle::FixedVector<std::unique_ptr<Sync>, kMaxSyncPoolSizePerType>;
+ std::map<EGLenum, SyncPool> mSyncPools;
+
void destroyImageImpl(Image *image, ImageMap *images);
void destroyStreamImpl(Stream *stream, StreamSet *streams);
Error destroySurfaceImpl(Surface *surface, SurfaceMap *surfaces);
- void destroySyncImpl(Sync *sync, SyncMap *syncs);
+ void destroySyncImpl(SyncID syncId, SyncMap *syncs);
ContextMap mInvalidContextMap;
ImageMap mInvalidImageMap;
diff --git a/src/libANGLE/EGLSync.cpp b/src/libANGLE/EGLSync.cpp
index 1800b33131..b7480c94b8 100644
--- a/src/libANGLE/EGLSync.cpp
+++ b/src/libANGLE/EGLSync.cpp
@@ -18,8 +18,8 @@
namespace egl
{
-Sync::Sync(rx::EGLImplFactory *factory, const egl::SyncID &id, EGLenum type)
- : mLabel(nullptr), mId(id), mType(type), mCondition(0), mNativeFenceFD(0)
+Sync::Sync(rx::EGLImplFactory *factory, EGLenum type)
+ : mLabel(nullptr), mId(0), mType(type), mCondition(0), mNativeFenceFD(0)
{
switch (mType)
{
@@ -42,17 +42,17 @@ void Sync::onDestroy(const Display *display)
{
ASSERT(mFence);
mFence->onDestroy(display);
- mFence.reset();
}
Sync::~Sync() {}
Error Sync::initialize(const Display *display,
const gl::Context *context,
+ const SyncID &id,
const AttributeMap &attribs)
{
+ mId = id;
mAttributeMap = attribs;
-
mNativeFenceFD =
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID);
mCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
diff --git a/src/libANGLE/EGLSync.h b/src/libANGLE/EGLSync.h
index 7fa32c9837..3082c702ab 100644
--- a/src/libANGLE/EGLSync.h
+++ b/src/libANGLE/EGLSync.h
@@ -29,10 +29,10 @@ class Context;
namespace egl
{
-class Sync final : public angle::RefCountObject<Display, angle::Result>, public LabeledObject
+class Sync final : public LabeledObject
{
public:
- Sync(rx::EGLImplFactory *factory, const SyncID &id, EGLenum type);
+ Sync(rx::EGLImplFactory *factory, EGLenum type);
~Sync() override;
void setLabel(EGLLabelKHR label) override;
@@ -40,10 +40,11 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public
const SyncID &id() const { return mId; }
- void onDestroy(const Display *display) override;
+ void onDestroy(const Display *display);
Error initialize(const Display *display,
const gl::Context *context,
+ const SyncID &id,
const AttributeMap &attribs);
Error clientWait(const Display *display,
const gl::Context *context,
diff --git a/src/libANGLE/capture/FrameCapture.cpp b/src/libANGLE/capture/FrameCapture.cpp
index 0026393ce1..5238f755c8 100644
--- a/src/libANGLE/capture/FrameCapture.cpp
+++ b/src/libANGLE/capture/FrameCapture.cpp
@@ -4633,11 +4633,11 @@ void CaptureShareGroupMidExecutionSetup(
}
// Capture EGL Sync Objects
- const egl::SyncMap eglSyncMap = context->getDisplay()->getSyncsForCapture();
+ const egl::SyncMap &eglSyncMap = context->getDisplay()->getSyncsForCapture();
for (const auto &eglSyncIter : eglSyncMap)
{
egl::SyncID eglSyncID = {eglSyncIter.first};
- const egl::Sync *eglSync = eglSyncIter.second;
+ const egl::Sync *eglSync = eglSyncIter.second.get();
EGLSync eglSyncObject = gl::unsafe_int_to_pointer_cast<EGLSync>(eglSyncID.value);
if (!eglSync)
diff --git a/src/libANGLE/renderer/metal/SyncMtl.mm b/src/libANGLE/renderer/metal/SyncMtl.mm
index 24961a80be..ccd3734c11 100644
--- a/src/libANGLE/renderer/metal/SyncMtl.mm
+++ b/src/libANGLE/renderer/metal/SyncMtl.mm
@@ -30,14 +30,12 @@ static uint64_t makeSignalValue(EGLAttrib highPart, EGLAttrib lowPart)
// SharedEvent is only available on iOS 12.0+ or mac 10.14+
#if ANGLE_MTL_EVENT_AVAILABLE
-Sync::Sync() {}
+Sync::Sync() : mCv(new std::condition_variable()), mLock(new std::mutex()) {}
Sync::~Sync() {}
void Sync::onDestroy()
{
mMetalSharedEvent = nil;
- mCv = nullptr;
- mLock = nullptr;
}
angle::Result Sync::initialize(ContextMtl *contextMtl,
@@ -59,8 +57,6 @@ angle::Result Sync::initialize(ContextMtl *contextMtl,
auto signaledValue = mMetalSharedEvent.get().signaledValue;
mSignalValue = signalValue.valid() ? signalValue.value() : signaledValue + 1;
- mCv.reset(new std::condition_variable());
- mLock.reset(new std::mutex());
return angle::Result::Continue;
}
diff --git a/src/libANGLE/renderer/vulkan/SyncVk.cpp b/src/libANGLE/renderer/vulkan/SyncVk.cpp
index 243a0d67f8..286e61e153 100644
--- a/src/libANGLE/renderer/vulkan/SyncVk.cpp
+++ b/src/libANGLE/renderer/vulkan/SyncVk.cpp
@@ -613,10 +613,7 @@ angle::Result SyncVk::getStatus(const gl::Context *context, GLint *outResult)
EGLSyncVk::EGLSyncVk() : EGLSyncImpl(), mSyncHelper(nullptr) {}
-EGLSyncVk::~EGLSyncVk()
-{
- SafeDelete(mSyncHelper);
-}
+EGLSyncVk::~EGLSyncVk() {}
void EGLSyncVk::onDestroy(const egl::Display *display)
{
@@ -635,7 +632,7 @@ egl::Error EGLSyncVk::initialize(const egl::Display *display,
case EGL_SYNC_FENCE_KHR:
{
vk::SyncHelper *syncHelper = new vk::SyncHelper();
- mSyncHelper = syncHelper;
+ mSyncHelper.reset(syncHelper);
if (syncHelper->initialize(vk::GetImpl(context), true) == angle::Result::Stop)
{
return egl::Error(EGL_BAD_ALLOC, "eglCreateSyncKHR failed to create sync object");
@@ -645,7 +642,7 @@ egl::Error EGLSyncVk::initialize(const egl::Display *display,
case EGL_SYNC_NATIVE_FENCE_ANDROID:
{
vk::SyncHelperNativeFence *syncHelper = new vk::SyncHelperNativeFence();
- mSyncHelper = syncHelper;
+ mSyncHelper.reset(syncHelper);
EGLint nativeFenceFd =
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID);
return angle::ToEGL(syncHelper->initializeWithFd(vk::GetImpl(context), nativeFenceFd),
diff --git a/src/libANGLE/renderer/vulkan/SyncVk.h b/src/libANGLE/renderer/vulkan/SyncVk.h
index a9c37bf871..0c71a61c5f 100644
--- a/src/libANGLE/renderer/vulkan/SyncVk.h
+++ b/src/libANGLE/renderer/vulkan/SyncVk.h
@@ -198,7 +198,7 @@ class EGLSyncVk final : public EGLSyncImpl
private:
// SyncHelper or SyncHelperNativeFence decided at run-time.
- vk::SyncHelperInterface *mSyncHelper;
+ std::unique_ptr<vk::SyncHelperInterface> mSyncHelper;
};
} // namespace rx