Skip to content

Commit b3a2111

Browse files
IDeviceContextGL: added PurgeCaches parameter to UpdateCurrentGLContext method
1 parent 4f78d44 commit b3a2111

File tree

6 files changed

+40
-17
lines changed

6 files changed

+40
-17
lines changed

Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ class DeviceContextGLImpl final : public DeviceContextBase<EngineGLImplTraits>
293293
virtual void DILIGENT_CALL_TYPE BindSparseResourceMemory(const BindSparseResourceMemoryAttribs& Attribs) override final;
294294

295295
/// Implementation of IDeviceContextGL::UpdateCurrentGLContext().
296-
virtual bool DILIGENT_CALL_TYPE UpdateCurrentGLContext() override final;
296+
virtual bool DILIGENT_CALL_TYPE UpdateCurrentGLContext(bool PurgeCaches) override final;
297297

298298
GLContextState& GetContextState() { return m_ContextState; }
299299

Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ class RenderDeviceGLImpl : public RenderDeviceBase<EngineGLImplTraits>
197197
void OnDestroyPSO(PipelineStateGLImpl& PSO);
198198
void OnDestroyBuffer(BufferGLImpl& Buffer);
199199

200+
void PurgeContextCaches(GLContext::NativeGLContextType Context);
201+
200202
GLProgramCache& GetProgramCache() { return m_ProgramCache; }
201203

202204
size_t GetCommandQueueCount() const { return 1; }

Graphics/GraphicsEngineOpenGL/interface/DeviceContextGL.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2023 Diligent Graphics LLC
2+
* Copyright 2019-2024 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -56,10 +56,16 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContextGL, IDeviceContext)
5656

5757
/// If an application uses multiple GL contexts, this method must be called before any
5858
/// other command to let the engine update active context every time when control flow
59-
/// is passed over from the main application
59+
/// is passed over from the main application.
6060
///
61-
/// \return false if there is no active GL context, and true otherwise
62-
VIRTUAL bool METHOD(UpdateCurrentGLContext)(THIS) PURE;
61+
/// \param[in] PurgeCaches - Whether to purge context caches (e.g. VAO, FBO) before
62+
/// updating the active context. An application should set this
63+
/// flag to true if the last active context will not be used anymore
64+
/// (e.g. it was destroyed) to avoid memory leaks.
65+
///
66+
/// \return false if there is no active GL context, and true otherwise.
67+
VIRTUAL bool METHOD(UpdateCurrentGLContext)(THIS_
68+
bool PurgeCaches DEFAULT_INITIALIZER(false)) PURE;
6369

6470
/// Sets the swap in the device context. The swap chain is used by the device context
6571
/// to obtain the default FBO handle.
@@ -74,8 +80,8 @@ DILIGENT_END_INTERFACE
7480

7581
// clang-format off
7682

77-
# define IDeviceContextGL_UpdateCurrentGLContext(This) CALL_IFACE_METHOD(DeviceContextGL, UpdateCurrentGLContext, This)
78-
# define IDeviceContextGL_SetSwapChain(This, ...) CALL_IFACE_METHOD(DeviceContextGL, SetSwapChain, This, __VA_ARGS__)
83+
# define IDeviceContextGL_UpdateCurrentGLContext(This, ...) CALL_IFACE_METHOD(DeviceContextGL, UpdateCurrentGLContext, This, __VA_ARGS__)
84+
# define IDeviceContextGL_SetSwapChain(This, ...) CALL_IFACE_METHOD(DeviceContextGL, SetSwapChain, This, __VA_ARGS__)
7985

8086
// clang-format on
8187

Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -408,9 +408,8 @@ void DeviceContextGLImpl::CommitRenderTargets()
408408
"Depth buffer of the default framebuffer can only be bound with the default framebuffer's color buffer "
409409
"and cannot be combined with any other render target in OpenGL backend.");
410410

411-
auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext();
412-
auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext);
413-
const auto& FBO = FBOCache.GetFBO(NumRenderTargets, pBoundRTVs, m_pBoundDepthStencil, m_ContextState);
411+
auto& FBOCache = m_pDevice->GetFBOCache(m_ContextState.GetCurrentGLContext());
412+
const auto& FBO = FBOCache.GetFBO(NumRenderTargets, pBoundRTVs, m_pBoundDepthStencil, m_ContextState);
414413
// Even though the write mask only applies to writes to a framebuffer, the mask state is NOT
415414
// Framebuffer state. So it is NOT part of a Framebuffer Object or the Default Framebuffer.
416415
// Binding a new framebuffer will NOT affect the mask.
@@ -771,11 +770,10 @@ void DeviceContextGLImpl::PrepareForDraw(DRAW_FLAGS Flags, bool IsIndexed, GLenu
771770
DvpValidateCommittedShaderResources();
772771
#endif
773772

774-
const auto CurrNativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext();
775-
const auto& PipelineDesc = m_pPipelineState->GetGraphicsPipelineDesc();
773+
const auto& PipelineDesc = m_pPipelineState->GetGraphicsPipelineDesc();
776774
if (!m_ContextState.IsValidVAOBound())
777775
{
778-
auto& VaoCache = m_pDevice->GetVAOCache(CurrNativeGLContext);
776+
auto& VaoCache = m_pDevice->GetVAOCache(m_ContextState.GetCurrentGLContext());
779777
auto* pIndexBuffer = IsIndexed ? m_pIndexBuffer.RawPtr() : nullptr;
780778
if (PipelineDesc.InputLayout.NumElements > 0 || pIndexBuffer != nullptr)
781779
{
@@ -1655,8 +1653,13 @@ void DeviceContextGLImpl::EndQuery(IQuery* pQuery)
16551653
}
16561654
}
16571655

1658-
bool DeviceContextGLImpl::UpdateCurrentGLContext()
1656+
bool DeviceContextGLImpl::UpdateCurrentGLContext(bool PurgeCaches)
16591657
{
1658+
if (PurgeCaches)
1659+
{
1660+
m_pDevice->PurgeContextCaches(m_ContextState.GetCurrentGLContext());
1661+
}
1662+
16601663
auto NativeGLContext = m_pDevice->m_GLContext.GetCurrentNativeGLContext();
16611664
if (NativeGLContext == NULL)
16621665
return false;
@@ -1905,8 +1908,7 @@ void DeviceContextGLImpl::ResolveTextureSubresource(ITexture*
19051908
const auto& SrcTexDesc = pSrcTexGl->GetDesc();
19061909
//const auto& DstTexDesc = pDstTexGl->GetDesc();
19071910

1908-
auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext();
1909-
auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext);
1911+
auto& FBOCache = m_pDevice->GetFBOCache(m_ContextState.GetCurrentGLContext());
19101912

19111913
GLuint SrcFBOHandle = 0;
19121914
{

Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,19 @@ void RenderDeviceGLImpl::OnDestroyBuffer(BufferGLImpl& Buffer)
16821682
VAOCacheIt.second.OnDestroyBuffer(Buffer);
16831683
}
16841684

1685+
1686+
void RenderDeviceGLImpl::PurgeContextCaches(GLContext::NativeGLContextType Context)
1687+
{
1688+
{
1689+
Threading::SpinLockGuard FBOCacheGuard{m_FBOCacheLock};
1690+
m_FBOCache.erase(Context);
1691+
}
1692+
{
1693+
Threading::SpinLockGuard VAOCacheGuard{m_VAOCacheLock};
1694+
m_VAOCache.erase(Context);
1695+
}
1696+
}
1697+
16851698
void RenderDeviceGLImpl::IdleGPU()
16861699
{
16871700
glFinish();

Tests/IncludeTest/GraphicsEngineOpenGL/DeviceContextGLH_test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
void TestDeviceContextGL_CInterface(IDeviceContextGL* pCtxGL)
3131
{
32-
bool res = IDeviceContextGL_UpdateCurrentGLContext(pCtxGL);
32+
bool res = IDeviceContextGL_UpdateCurrentGLContext(pCtxGL, true);
3333
(void)res;
3434
IDeviceContextGL_SetSwapChain(pCtxGL, (struct ISwapChainGL*)NULL);
3535
}

0 commit comments

Comments
 (0)