auto* surfaceInterface = reinterpret_cast<Dali::Integration::RenderSurfaceInterface*>(rt->GetCreateInfo().surface);
surfaceInterface->MakeContextCurrent();
surfaceInterface->PostRender();
+
+ // Delete discarded surface context sync objects.
+ // NOTE : We can assume that surface context is become current now.
+ // And also can asusme that ResolvePresentRenderTarget() will be called at most 1 times per each frame.
+ mSyncPool.ProcessDiscardSyncObjects(GetSurfaceContext(surfaceInterface));
}
}
{
mTextureDependencyChecker.Reset();
mSyncPool.AgeSyncObjects();
+
+ // Delete discarded resource context sync objects.
+ // NOTE : We can assume that current context is resource context now.
+ mSyncPool.ProcessDiscardSyncObjects(mCurrentContext);
}
Integration::GlAbstraction& EglGraphicsController::GetGlAbstraction()
void EglGraphicsController::DeleteSurfaceContext(Dali::Integration::RenderSurfaceInterface* surface)
{
- mSurfaceContexts.erase(std::remove_if(
- mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) { return surface == iter.first; }),
- mSurfaceContexts.end());
+ auto iter = mSurfaceContexts.begin();
+ auto newEndIter = mSurfaceContexts.begin();
+ const auto endIter = mSurfaceContexts.end();
+ for(; iter != endIter; ++iter)
+ {
+ if(iter->first != surface)
+ {
+ if(newEndIter != iter)
+ {
+ *newEndIter = std::move(*iter);
+ }
+ newEndIter++;
+ continue;
+ }
+ else
+ {
+ // Mark as given context will be deleted soon.
+ // It will make sync object id that created by given context
+ // become invalidated.
+ mSyncPool.InvalidateContext(iter->second.get());
+ }
+ }
+
+ mSurfaceContexts.erase(newEndIter, endIter);
}
void EglGraphicsController::ActivateResourceContext()
{
if(surface && mGraphics->IsResourceContextSupported())
{
- auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) { return (iter.first == surface); });
+ auto* context = GetSurfaceContext(surface);
- if(iter != mSurfaceContexts.end())
+ if(context)
{
- mCurrentContext = iter->second.get();
+ mCurrentContext = context;
mCurrentContext->GlContextCreated();
}
}
}
+GLES::Context* EglGraphicsController::GetSurfaceContext(Dali::Integration::RenderSurfaceInterface* surface) const
+{
+ if(DALI_LIKELY(surface))
+ {
+ auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](const SurfaceContextPair& iter) { return (iter.first == surface); });
+
+ if(iter != mSurfaceContexts.end())
+ {
+ return iter->second.get();
+ }
+ }
+ return nullptr;
+}
+
void EglGraphicsController::AddTexture(GLES::Texture& texture)
{
// Assuming we are on the correct context
// EXTERNAL INCLUDES
#include <dali/devel-api/common/map-wrapper.h>
#include <dali/graphics-api/graphics-controller.h>
+#include <memory>
#include <queue>
#include <unordered_map>
#include <unordered_set>
uint32_t GetDeviceLimitation(Dali::Graphics::DeviceCapability capability) override;
+private:
+ /**
+ * Get the surface context
+ *
+ * @param[in] surface The surface whose context to want get context.
+ * @return valid context or null if not found.
+ */
+ GLES::Context* GetSurfaceContext(Dali::Integration::RenderSurfaceInterface* surface) const;
+
private:
Integration::GlAbstraction* mGlAbstraction{nullptr};
Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
void* mSharedContext{nullptr}; ///< Shared EGL context
GLES::TextureDependencyChecker mTextureDependencyChecker; // Checks if FBO textures need syncing
- GLES::SyncPool mSyncPool;
- std::size_t mCapacity{0u}; ///< Memory Usage (of command buffers)
+
+ GLES::SyncPool mSyncPool;
+ std::size_t mCapacity{0u}; ///< Memory Usage (of command buffers)
};
} // namespace Graphics
std::unordered_map<const GLES::ProgramImpl*, std::map<std::size_t, uint32_t>> mProgramVAOMap; ///< GL program-VAO map
uint32_t mProgramVAOCurrentState{0u}; ///< Currently bound VAO
GLStateCache mGlStateCache{}; ///< GL status cache
- std::vector<Dali::GLuint> mDiscardedVAOList{};
+
+ std::vector<Dali::GLuint> mDiscardedVAOList{};
bool mGlContextCreated{false}; ///< True if the OpenGL context has been created
bool mVertexBuffersChanged{true}; ///< True if BindVertexBuffers changed any buffer bindings
}
}
-
void Context::ClearState()
{
mImpl->mCurrentTextureBindings.clear();
void SetDepthWriteEnable(bool depthWriteEnable);
void ResetGLESState();
+
private:
/**
* @brief Clear current state
namespace Dali::Graphics::GLES
{
-AgingSyncObject::AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool _egl)
+SyncPool::AgingSyncObject::AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool _egl)
: controller(controller),
writeContext(writeContext),
egl(_egl)
}
}
-AgingSyncObject::~AgingSyncObject()
+SyncPool::AgingSyncObject::~AgingSyncObject()
{
if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
{
}
}
-bool AgingSyncObject::IsSynced()
+bool SyncPool::AgingSyncObject::IsSynced()
{
bool synced = false;
if(egl)
return synced;
}
-bool AgingSyncObject::ClientWait()
+bool SyncPool::AgingSyncObject::ClientWait()
{
bool synced = false;
if(egl)
return synced;
}
-void AgingSyncObject::Wait()
+void SyncPool::AgingSyncObject::Wait()
{
if(egl)
{
SyncPool::~SyncPool() = default;
-AgingSyncObject* SyncPool::AllocateSyncObject(const Context* writeContext, SyncPool::SyncContext syncContext)
+SyncPool::SyncObjectId SyncPool::AllocateSyncObject(const Context* writeContext, SyncPool::SyncContext syncContext)
{
- AgingSyncObject* agingSyncObject = new AgingSyncObject(mController, writeContext, (syncContext == SyncContext::EGL));
+ auto agingSyncObject = std::make_unique<AgingSyncObject>(mController, writeContext, (syncContext == SyncContext::EGL));
+
+ auto syncPoolObjectId = mSyncObjectId++;
// Take ownership of sync object
- mSyncObjects.PushBack(agingSyncObject);
- return agingSyncObject;
+ mSyncObjects.insert(std::make_pair(syncPoolObjectId, std::move(agingSyncObject)));
+ return syncPoolObjectId;
}
-bool SyncPool::IsSynced(AgingSyncObject* agingSyncObject)
+bool SyncPool::IsSynced(SyncPool::SyncObjectId syncPoolObjectId)
{
+ AgingSyncObject* agingSyncObject = GetAgingSyncObject(syncPoolObjectId);
+
if(DALI_LIKELY(agingSyncObject != nullptr))
{
return agingSyncObject->IsSynced();
return false;
}
-void SyncPool::Wait(AgingSyncObject* agingSyncObject)
+void SyncPool::Wait(SyncPool::SyncObjectId syncPoolObjectId)
{
+ AgingSyncObject* agingSyncObject = GetAgingSyncObject(syncPoolObjectId);
+
if(DALI_LIKELY(agingSyncObject != nullptr))
{
agingSyncObject->syncing = true;
}
}
-bool SyncPool::ClientWait(AgingSyncObject* agingSyncObject)
+bool SyncPool::ClientWait(SyncPool::SyncObjectId syncPoolObjectId)
{
+ AgingSyncObject* agingSyncObject = GetAgingSyncObject(syncPoolObjectId);
+
if(DALI_LIKELY(agingSyncObject != nullptr))
{
return agingSyncObject->ClientWait();
return false;
}
-void SyncPool::FreeSyncObject(AgingSyncObject* agingSyncObject)
+void SyncPool::FreeSyncObject(SyncPool::SyncObjectId syncPoolObjectId)
{
- if(DALI_LIKELY(agingSyncObject != nullptr))
+ auto iter = mSyncObjects.find(syncPoolObjectId);
+ if(iter != mSyncObjects.end())
{
- // Release memory of sync object
- mSyncObjects.EraseObject(agingSyncObject);
+ // Move memory of sync object to discard queue
+ DiscardAgingSyncObject(std::move(iter->second));
+
+ mSyncObjects.erase(iter);
}
}
*/
void SyncPool::AgeSyncObjects()
{
- DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count: %d\n", mSyncObjects.Count());
-
- if(!mSyncObjects.IsEmpty())
+ if(!mSyncObjects.empty())
{
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count: %d\n", mSyncObjects.size());
+
// Age the remaining sync objects.
- for(auto iter = mSyncObjects.Begin(); iter != mSyncObjects.End();)
+ for(auto iter = mSyncObjects.begin(); iter != mSyncObjects.end();)
{
- auto* agingSyncObject = (*iter);
- if(agingSyncObject != nullptr && (agingSyncObject->glSyncObject != 0 || agingSyncObject->eglSyncObject != nullptr) && agingSyncObject->age > 0)
+ auto* agingSyncObject = (iter->second).get();
+ if(agingSyncObject != nullptr &&
+ (agingSyncObject->glSyncObject != 0 ||
+ agingSyncObject->eglSyncObject != nullptr) &&
+ agingSyncObject->age > 0)
{
--agingSyncObject->age;
++iter;
}
else
+ {
+ // Move memory of sync object to discard queue
+ DiscardAgingSyncObject(std::move(iter->second));
+
+ iter = mSyncObjects.erase(iter);
+ }
+ }
+
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count after erase: %d\n", mSyncObjects.size());
+ }
+}
+
+void SyncPool::ProcessDiscardSyncObjects(const Context* currentContext)
+{
+ auto iter = mDiscardSyncObjects.find(currentContext);
+ if(iter != mDiscardSyncObjects.end())
+ {
+#ifdef DEBUG_ENABLED
+ auto& agingSyncObjectsList = iter->second;
+
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "ProcessDiscardSyncObjects: context[%p], count: %zu\n", currentContext, agingSyncObjectsList.size());
+#endif
+
+ mDiscardSyncObjects.erase(iter);
+ }
+}
+
+void SyncPool::InvalidateContext(const Context* invalidatedContext)
+{
+ if(!mSyncObjects.empty())
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "InvalidateContext: context[%p], count: %d\n", invalidatedContext, mSyncObjects.size());
+
+ // Age the remaining sync objects.
+ for(auto iter = mSyncObjects.begin(); iter != mSyncObjects.end();)
+ {
+ auto* agingSyncObject = (iter->second).get();
+ if(agingSyncObject == nullptr ||
+ agingSyncObject->writeContext == invalidatedContext)
{
// Release memory of sync object
- iter = mSyncObjects.Erase(iter);
+ // Note : We don't need to call DiscardAgingSyncObject here.
+ // Even if current context is not given context, we should call it
+ // since some DALI objects should be destroyed.
+ // Don't worry about EGLSync leak, since it will be destroyed by eglDestroyContext.
+ iter = mSyncObjects.erase(iter);
+ }
+ else
+ {
+ ++iter;
}
}
+
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "InvalidateContext: context[%p], count after erase: %d\n", mSyncObjects.size());
}
- DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count after erase: %d\n", mSyncObjects.Count());
+ // Release discarded sync objects.
+ ProcessDiscardSyncObjects(invalidatedContext);
+}
+
+void SyncPool::DiscardAgingSyncObject(std::unique_ptr<AgingSyncObject>&& agingSyncObject)
+{
+ const Context* currentContext = agingSyncObject->writeContext;
+ mDiscardSyncObjects[currentContext].emplace_back(std::move(agingSyncObject));
+}
+
+SyncPool::AgingSyncObject* SyncPool::GetAgingSyncObject(SyncPool::SyncObjectId syncPoolObjectId) const
+{
+ auto iter = mSyncObjects.find(syncPoolObjectId);
+ if(iter != mSyncObjects.end())
+ {
+ return iter->second.get();
+ }
+ return nullptr;
}
} // namespace Dali::Graphics::GLES
#include <dali/integration-api/ordered-set.h>
#include <dali/public-api/common/vector-wrapper.h>
+#include <cstdint>
+#include <memory>
+
namespace Dali
{
namespace Internal::Adaptor
{
class Context;
-struct AgingSyncObject
-{
- AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool egl = false);
- ~AgingSyncObject();
-
- EglGraphicsController& controller;
- const Context* writeContext;
- union
- {
- GLsync glSyncObject;
- Internal::Adaptor::EglSyncObject* eglSyncObject;
- };
- uint8_t age{2};
- bool syncing{false};
- bool egl{false};
-
- bool IsSynced();
- void Wait();
- bool ClientWait();
-};
-using AgingSyncPtrRef = std::unique_ptr<AgingSyncObject>&;
-
/**
* A vector of current fence syncs. They only age if glWaitSync is called on them in the
* same frame they are created, otherwise they are deleted.
* They must be created in the writeContext, but can be synced from a readContext.
- * (Pool per context? - probably only ever used in resource context!)
+ *
+ * To match the created context and destroy context, we use discarded sync objects queue per each context.
+ * After when we can assume that eglMakeCurrent called, we can safely discard the sync objects.
+ *
+ * @note Before destroy the context, we should call InvalidateContext(), to ensure release memories.
*/
class SyncPool
{
public:
+ using SyncObjectId = uint32_t;
+
enum class SyncContext
{
EGL, ///< Use EGL sync when syncing between multiple contexts
/**
* Allocate a sync object in the writeContext
* @param writeContext
- * @return An owned ptr to a sync object
+ * @return An unique id to a sync object
*/
- AgingSyncObject* AllocateSyncObject(const Context* writeContext, SyncContext syncContext);
+ SyncObjectId AllocateSyncObject(const Context* writeContext, SyncContext syncContext);
/**
* Check whether given object is synced in the CPU
- * @param syncPoolObject The object to check synced.
+ * @param syncPoolObjectId The id of object to check synced.
* @return true if the sync object was signaled, false if it timed out
*/
- bool IsSynced(AgingSyncObject* syncPoolObject);
+ bool IsSynced(SyncObjectId syncPoolObjectId);
/**
* Wait on a sync object in any context in the GPU
- * @param syncPoolObject The object to wait on.
+ * @param syncPoolObjectId The id of object to wait on.
*/
- void Wait(AgingSyncObject* syncPoolObject);
+ void Wait(SyncObjectId syncPoolObjectId);
/**
* Wait on a sync object in any context in the CPU
- * @param syncPoolObject The object to wait on.
+ * @param syncPoolObjectId The id of object to wait on.
* @return true if the sync object was signaled, false if it timed out
*/
- bool ClientWait(AgingSyncObject* syncPoolObject);
+ bool ClientWait(SyncObjectId syncPoolObjectId);
/**
* Delete the sync object if it's not needed.
- * @param syncPoolObject The object to delete.
+ * @param syncPoolObjectId The id of object to delete.
*/
- void FreeSyncObject(AgingSyncObject* syncPoolObject);
+ void FreeSyncObject(SyncObjectId syncPoolObjectId);
/**
* Age outstanding sync objects. Call at the end of each frame.
*/
void AgeSyncObjects();
+public: /// Contexts relative API
+ /**
+ * Delete all sync objects that were created by given context.
+ *
+ * @param[in] currentContext The current context which will delete its sync objects.
+ */
+ void ProcessDiscardSyncObjects(const Context* currentContext);
+
+ /**
+ * Notify that given context will be destroyed soon.
+ * Let we remove all sync objects created by given context.
+ * @param invalidatedContext The context which will be called eglDestroyContext soon.
+ */
+ void InvalidateContext(const Context* invalidatedContext);
+
+private:
+ struct AgingSyncObject
+ {
+ AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool egl = false);
+ ~AgingSyncObject();
+
+ EglGraphicsController& controller;
+ const Context* writeContext;
+ union
+ {
+ GLsync glSyncObject;
+ Internal::Adaptor::EglSyncObject* eglSyncObject;
+ };
+ uint8_t age{2};
+ bool syncing{false};
+ bool egl{false};
+
+ bool IsSynced();
+ void Wait();
+ bool ClientWait();
+ };
+
private:
- Dali::Integration::OrderedSet<AgingSyncObject> mSyncObjects; ///< The list of sync objects in this pool (owned)
- EglGraphicsController& mController;
+ /**
+ * Discard a sync object that was created by given context.
+ * @param currentContext The current context which will delete its sync object.
+ * @param agingSyncObject The sync object to delete.
+ */
+ void DiscardAgingSyncObject(std::unique_ptr<AgingSyncObject>&& agingSyncObject);
+
+ /**
+ * Get aging sync object from the container
+ * @param syncPoolObjectId The id of object to get.
+ * @return pointer to the aging sync object
+ */
+ AgingSyncObject* GetAgingSyncObject(SyncObjectId syncPoolObjectId) const;
+
+private:
+ using SyncObjectContainer = std::unordered_map<SyncObjectId, std::unique_ptr<AgingSyncObject>>;
+ SyncObjectContainer mSyncObjects; ///< The list of sync objects in this pool (owned)
+
+ using DiscardedSyncObjectContainer = std::unordered_map<const Context*, std::vector<std::unique_ptr<AgingSyncObject>>>;
+ DiscardedSyncObjectContainer mDiscardSyncObjects; ///< The list of discarded sync objects per each context
+
+ EglGraphicsController& mController;
+
+ SyncObjectId mSyncObjectId{0u};
};
} // namespace GLES
{
texture->SetDependencyIndex(0xffffffff);
}
- mController.GetSyncPool().FreeSyncObject(textureDependency.agingSyncObject);
+ mController.GetSyncPool().FreeSyncObject(textureDependency.agingSyncObjectId);
}
mFramebufferTextureDependencies.clear();
{
for(auto& nativeTextureDependency : mNativeTextureDependencies[nativeIndex])
{
- if(nativeTextureDependency.agingSyncObject != nullptr)
- {
- mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObject);
- }
+ mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObjectId);
}
mNativeTextureDependencies[nativeIndex].clear();
}
}
if(!textureDependency.syncing)
{
- mController.GetSyncPool().FreeSyncObject(textureDependency.agingSyncObject);
+ mController.GetSyncPool().FreeSyncObject(textureDependency.agingSyncObjectId);
}
}
mFramebufferTextureDependencies.clear();
- if(mNativeTextureDependencies[0].size() > 0 || mNativeTextureDependencies[1].size())
+ if(!mNativeTextureDependencies[0].empty() || !mNativeTextureDependencies[1].empty())
{
DALI_ASSERT_ALWAYS(mIsFirstPreparedNativeTextureDependency && "CreateNativeTextureSync should be called before PostRender!");
// Remove all infomations about previous native textures
for(auto& nativeTextureDependency : mNativeTextureDependencies[mPreviousNativeTextureDependencyIndex])
{
- if(nativeTextureDependency.agingSyncObject != nullptr)
- {
- mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObject);
- }
+ mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObjectId);
}
mNativeTextureDependencies[mPreviousNativeTextureDependencyIndex].clear();
// We have to check on different EGL contexts: The shared resource context is used to write to fbos,
// but they are usually drawn onto separate scene context.
DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::AddTextures() Allocating sync object\n");
- textureDependency.agingSyncObject = mController.GetSyncPool().AllocateSyncObject(writeContext, SyncPool::SyncContext::EGL);
+ textureDependency.agingSyncObjectId = mController.GetSyncPool().AllocateSyncObject(writeContext, SyncPool::SyncContext::EGL);
}
void TextureDependencyChecker::CheckNeedsSync(const GLES::Context* readContext, const GLES::Texture* texture, bool cpu)
if(cpu)
{
DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync Insert CPU WAIT");
- mController.GetSyncPool().ClientWait(textureDependency.agingSyncObject);
+ mController.GetSyncPool().ClientWait(textureDependency.agingSyncObjectId);
}
else
{
// to the sync point.
// However, this may instead timeout, and we can't tell the difference (at least, for glFenceSync)
DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync Insert GPU WAIT");
- mController.GetSyncPool().Wait(textureDependency.agingSyncObject);
+ mController.GetSyncPool().Wait(textureDependency.agingSyncObjectId);
}
}
}
auto iter = nativeTextureDependency.textures.find(texture);
if(iter != nativeTextureDependency.textures.end())
{
- if(nativeTextureDependency.agingSyncObject != nullptr)
+ if(cpu)
{
- if(cpu)
- {
- DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync (for native) Insert CPU WAIT");
- nativeTextureDependency.synced = mController.GetSyncPool().ClientWait(nativeTextureDependency.agingSyncObject);
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync (for native) Insert CPU WAIT");
+ nativeTextureDependency.synced = mController.GetSyncPool().ClientWait(nativeTextureDependency.agingSyncObjectId);
- if(DALI_LIKELY(nativeTextureDependency.synced) && readContext == nativeTextureDependency.agingSyncObject->writeContext)
- {
- // We can free sync object immediatly if we are using same context.
- mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObject);
- nativeTextureDependency.agingSyncObject = nullptr;
- }
- }
- else
+ if(DALI_LIKELY(nativeTextureDependency.synced) && readContext == nativeTextureDependency.writeContext)
{
- // Wait on the sync object in GPU. This will ensure that the writeContext completes its tasks prior
- // to the sync point.
- // However, this may instead timeout, and we can't tell the difference (at least, for glFenceSync)
- DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync (for native) Insert GPU WAIT");
- mController.GetSyncPool().Wait(nativeTextureDependency.agingSyncObject);
+ // We can free sync object immediatly if we are using same context.
+ mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObjectId);
}
}
+ else
+ {
+ // Wait on the sync object in GPU. This will ensure that the writeContext completes its tasks prior
+ // to the sync point.
+ // However, this may instead timeout, and we can't tell the difference (at least, for glFenceSync)
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync (for native) Insert GPU WAIT");
+ mController.GetSyncPool().Wait(nativeTextureDependency.agingSyncObjectId);
+ }
nativeTextureDependency.textures.erase(iter);
}
nativeTextureDependency.textures.erase(jter);
if(nativeTextureDependency.textures.empty())
{
- mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObject);
+ mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObjectId);
iter = mNativeTextureDependencies[nativeIndex].erase(iter);
isErased = true;
if(DALI_LIKELY(!mNativeTextureDependencies[mCurrentNativeTextureDependencyIndex].empty()))
{
- auto& nativeTextureDependency = mNativeTextureDependencies[mCurrentNativeTextureDependencyIndex].back();
+ auto& nativeTextureDependency = mNativeTextureDependencies[mCurrentNativeTextureDependencyIndex].back();
+ nativeTextureDependency.writeContext = writeContext; // Store write context
DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CreateNativeTextureSync() Allocating sync object\n");
- nativeTextureDependency.agingSyncObject = mController.GetSyncPool().AllocateSyncObject(writeContext, SyncPool::SyncContext::EGL);
+ nativeTextureDependency.agingSyncObjectId = mController.GetSyncPool().AllocateSyncObject(writeContext, SyncPool::SyncContext::EGL);
}
}
class Context;
class Framebuffer;
class Texture;
-class AgingSyncObject;
/**
* Class to handle dependency checks between textures on different
void CreateNativeTextureSync(const Context* writeContext);
private:
+ using SyncObjectId = uint32_t; ///< Note : It should be matched with Dali::Graphics::GLES::SyncPool:SyncObjectId.
+
struct FramebufferTextureDependency
{
std::vector<Texture*> textures;
Context* writeContext{nullptr};
Framebuffer* framebuffer{nullptr};
- AgingSyncObject* agingSyncObject{nullptr};
+ SyncObjectId agingSyncObjectId{0u};
bool syncing{false};
};
std::vector<FramebufferTextureDependency> mFramebufferTextureDependencies;
struct NativeTextureDependency
{
std::unordered_set<const Texture*> textures;
- AgingSyncObject* agingSyncObject{nullptr};
+ const Context* writeContext{nullptr};
+ SyncObjectId agingSyncObjectId{0u};
bool synced{false};
};
std::vector<NativeTextureDependency> mNativeTextureDependencies[2];