diff options
author | Geoff Lang <geofflang@chromium.org> | 2023-11-27 14:44:07 -0500 |
---|---|---|
committer | Angle LUCI CQ <angle-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-12-08 17:26:07 +0000 |
commit | c27a4a1d7d3794b92518735c2ba84871748c16f4 (patch) | |
tree | 3fc17b4144290dbf27b9d7f2c521067e41bd6b56 | |
parent | 4732409f30383b45eb8824dea3e294b7a3de8e7d (diff) | |
download | angle-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.cpp | 56 | ||||
-rw-r--r-- | src/libANGLE/Display.h | 9 | ||||
-rw-r--r-- | src/libANGLE/EGLSync.cpp | 8 | ||||
-rw-r--r-- | src/libANGLE/EGLSync.h | 7 | ||||
-rw-r--r-- | src/libANGLE/capture/FrameCapture.cpp | 4 | ||||
-rw-r--r-- | src/libANGLE/renderer/metal/SyncMtl.mm | 6 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/SyncVk.cpp | 9 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/SyncVk.h | 2 |
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 |