summaryrefslogtreecommitdiff
path: root/vcl/opengl
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-04-08 17:08:04 +0900
committerTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-04-08 19:10:14 +0900
commitcd089979607566bc26259ff9edb079842aabdd4e (patch)
treebe8955067072c88769b865cc1b4441e81aee4c03 /vcl/opengl
parentf65e77c965bb47d53c994d90b7fd0bf5009b343b (diff)
opengl: refactor GL texture slot mechanism to be more general
Slot mechanism in ImplOpenGLTexture was written to support needs for FixedTextureAtlas. This commit makes the slot mechanism more general so it can be used in other kinds of texture atlases like PackedTextureAtlas. The ImplOpenGLTexture still tracks slots, but it is not needed to define beforehand how many slots there are. The deallocation has been factored out, ImplOpenGLTexture instead calls a callback function that a slot with a specific "slot id" has been deallocated. Change-Id: I23950d325b803969f958d03ebf34805687c4e620
Diffstat (limited to 'vcl/opengl')
-rw-r--r--vcl/opengl/FixedTextureAtlas.cxx76
-rw-r--r--vcl/opengl/texture.cxx47
2 files changed, 79 insertions, 44 deletions
diff --git a/vcl/opengl/FixedTextureAtlas.cxx b/vcl/opengl/FixedTextureAtlas.cxx
index 1ed83111d293..87c5bb1ff2ac 100644
--- a/vcl/opengl/FixedTextureAtlas.cxx
+++ b/vcl/opengl/FixedTextureAtlas.cxx
@@ -17,6 +17,52 @@
#include "opengl/FixedTextureAtlas.hxx"
+struct FixedTexture
+{
+ ImplOpenGLTexture* mpTexture;
+ int mnFreeSlots;
+ std::vector<bool> maAllocatedSlots;
+
+ FixedTexture(ImplOpenGLTexture* pTexture, int nNumberOfSlots)
+ : mpTexture(pTexture)
+ , mnFreeSlots(nNumberOfSlots)
+ , maAllocatedSlots(nNumberOfSlots, false)
+ {
+ auto aDeallocateFunction = [this] (int nSlotNumber)
+ {
+ deallocateSlot(nSlotNumber);
+ };
+
+ mpTexture->SetSlotDeallocateCallback(aDeallocateFunction);
+ mpTexture->InitializeSlotMechanism(nNumberOfSlots);
+ }
+
+ void allocateSlot(int nSlot)
+ {
+ maAllocatedSlots[nSlot] = true;
+ mnFreeSlots--;
+ }
+
+ void deallocateSlot(int nSlot)
+ {
+ maAllocatedSlots[nSlot] = false;
+ mnFreeSlots++;
+ }
+
+ int findAndAllocateFreeSlot()
+ {
+ for (size_t i = 0; i < maAllocatedSlots.size(); ++i)
+ {
+ if (!maAllocatedSlots[i])
+ {
+ allocateSlot(i);
+ return i;
+ }
+ }
+ return -1;
+ }
+};
+
FixedTextureAtlasManager::FixedTextureAtlasManager(int nWidthFactor, int nHeightFactor, int nSubTextureSize)
: mWidthFactor(nWidthFactor)
, mHeightFactor(nHeightFactor)
@@ -26,11 +72,10 @@ FixedTextureAtlasManager::FixedTextureAtlasManager(int nWidthFactor, int nHeight
FixedTextureAtlasManager::~FixedTextureAtlasManager()
{
- for (auto i = mpTextures.begin(); i != mpTextures.end(); ++i)
+ for (std::unique_ptr<FixedTexture>& pFixedTexture : maFixedTextures)
{
// Free texture early in VCL shutdown while we have a context.
- (*i)->Dispose();
- (*i)->DecreaseRefCount(0);
+ delete pFixedTexture->mpTexture;
}
}
@@ -38,32 +83,35 @@ void FixedTextureAtlasManager::CreateNewTexture()
{
int nTextureWidth = mWidthFactor * mSubTextureSize;
int nTextureHeight = mHeightFactor * mSubTextureSize;
- mpTextures.push_back(new ImplOpenGLTexture(nTextureWidth, nTextureHeight, true));
- mpTextures.back()->InitializeSlots(mWidthFactor * mHeightFactor);
+ std::unique_ptr<FixedTexture> pFixedTexture(
+ new FixedTexture(new ImplOpenGLTexture(nTextureWidth, nTextureHeight, true),
+ mWidthFactor * mHeightFactor));
+
+ maFixedTextures.push_back(std::move(pFixedTexture));
}
OpenGLTexture FixedTextureAtlasManager::Reserve(int nWidth, int nHeight)
{
- ImplOpenGLTexture* pTexture = nullptr;
+ FixedTexture* pFixedTexture = nullptr;
- auto funFreeSlot = [] (ImplOpenGLTexture *mpTexture)
+ auto funFreeSlot = [] (std::unique_ptr<FixedTexture>& inFixedTexture)
{
- return mpTexture->mnFreeSlots > 0;
+ return inFixedTexture->mnFreeSlots > 0;
};
- auto it = std::find_if(mpTextures.begin(), mpTextures.end(), funFreeSlot);
+ auto it = std::find_if(maFixedTextures.begin(), maFixedTextures.end(), funFreeSlot);
- if (it != mpTextures.end())
+ if (it != maFixedTextures.end())
{
- pTexture = *it;
+ pFixedTexture = (*it).get();
}
else
{
CreateNewTexture();
- pTexture = mpTextures.back();
+ pFixedTexture = maFixedTextures.back().get();
}
- int nSlot = pTexture->FindFreeSlot();
+ int nSlot = pFixedTexture->findAndAllocateFreeSlot();
// Calculate coordinates in texture
int nX = (nSlot % mWidthFactor) * mSubTextureSize;
@@ -71,7 +119,7 @@ OpenGLTexture FixedTextureAtlasManager::Reserve(int nWidth, int nHeight)
Rectangle aRectangle(Point(nX, nY), Size(nWidth, nHeight));
- return OpenGLTexture(pTexture, aRectangle, nSlot);
+ return OpenGLTexture(pFixedTexture->mpTexture, aRectangle, nSlot);
}
OpenGLTexture FixedTextureAtlasManager::InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData)
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 6388a92809cf..b3a36263271b 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -43,8 +43,7 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate )
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
- mnOptStencil( 0 ),
- mnFreeSlots(-1)
+ mnOptStencil( 0 )
{
OpenGLVCLContextZone aContextZone;
@@ -78,8 +77,7 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight )
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
- mnOptStencil( 0 ),
- mnFreeSlots(-1)
+ mnOptStencil( 0 )
{
OpenGLVCLContextZone aContextZone;
@@ -113,8 +111,7 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
- mnOptStencil( 0 ),
- mnFreeSlots(-1)
+ mnOptStencil( 0 )
{
OpenGLVCLContextZone aContextZone;
@@ -221,53 +218,43 @@ bool ImplOpenGLTexture::InsertBuffer(int nX, int nY, int nWidth, int nHeight, in
return true;
}
-bool ImplOpenGLTexture::InitializeSlots(int nSlotSize)
+bool ImplOpenGLTexture::InitializeSlotMechanism(int nInitialSlotSize)
{
if (mpSlotReferences)
return false;
- mpSlotReferences.reset(new std::vector<int>(nSlotSize, 0));
- mnFreeSlots = nSlotSize;
-
+ mpSlotReferences.reset(new std::vector<int>(nInitialSlotSize, 0));
return true;
}
-int ImplOpenGLTexture::FindFreeSlot()
-{
- if (mnFreeSlots > 0 && mpSlotReferences)
- {
- for (size_t i = 0; i < mpSlotReferences->size(); i++)
- {
- if (mpSlotReferences->at(i) <= 0)
- {
- return i;
- }
- }
- }
- return -1;
-}
-
void ImplOpenGLTexture::IncreaseRefCount(int nSlotNumber)
{
mnRefCount++;
if (mpSlotReferences && nSlotNumber >= 0)
{
- if (mpSlotReferences->at(nSlotNumber) == 0)
- mnFreeSlots--;
+ if (nSlotNumber >= int(mpSlotReferences->size()))
+ mpSlotReferences->resize(nSlotNumber + 1, 0);
+
mpSlotReferences->at(nSlotNumber)++;
}
}
void ImplOpenGLTexture::DecreaseRefCount(int nSlotNumber)
{
- mnRefCount--;
if (mpSlotReferences && nSlotNumber >= 0)
{
+ if (nSlotNumber >= int(mpSlotReferences->size()))
+ mpSlotReferences->resize(nSlotNumber, 0);
+
mpSlotReferences->at(nSlotNumber)--;
- if (mpSlotReferences->at(nSlotNumber) == 0)
- mnFreeSlots++;
+
+ if (mpSlotReferences->at(nSlotNumber) == 0 && mFunctSlotDeallocateCallback)
+ {
+ mFunctSlotDeallocateCallback(nSlotNumber);
+ }
}
+ mnRefCount--;
if (mnRefCount <= 0)
delete this;
}