Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / vcl / opengl / FixedTextureAtlas.cxx
blob7a980c9251e4cbf00d5b4645582894007e21a4ce
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
11 #include <sal/config.h>
12 #include <vcl/opengl/OpenGLContext.hxx>
13 #include <vcl/opengl/OpenGLHelper.hxx>
15 #include "opengl/framebuffer.hxx"
16 #include "opengl/texture.hxx"
18 #include "opengl/FixedTextureAtlas.hxx"
20 #include <o3tl/make_unique.hxx>
22 struct FixedTexture
24 ImplOpenGLTexture* mpTexture;
25 int mnFreeSlots;
26 std::vector<bool> maAllocatedSlots;
28 FixedTexture(int nTextureWidth, int nTextureHeight, int nNumberOfSlots)
29 : mpTexture(new ImplOpenGLTexture(nTextureWidth, nTextureHeight, true))
30 , mnFreeSlots(nNumberOfSlots)
31 , maAllocatedSlots(nNumberOfSlots, false)
33 auto aDeallocateFunction = [this] (int nSlotNumber)
35 deallocateSlot(nSlotNumber);
38 mpTexture->SetSlotDeallocateCallback(aDeallocateFunction);
39 mpTexture->InitializeSlotMechanism(nNumberOfSlots);
42 ~FixedTexture()
44 mpTexture->ResetSlotDeallocateCallback();
45 mpTexture->DecreaseRefCount(-1);
48 void allocateSlot(int nSlot)
50 maAllocatedSlots[nSlot] = true;
51 mnFreeSlots--;
54 void deallocateSlot(int nSlot)
56 maAllocatedSlots[nSlot] = false;
57 mnFreeSlots++;
60 int findAndAllocateFreeSlot()
62 for (size_t i = 0; i < maAllocatedSlots.size(); ++i)
64 if (!maAllocatedSlots[i])
66 allocateSlot(i);
67 return i;
70 return -1;
74 FixedTextureAtlasManager::FixedTextureAtlasManager(int nWidthFactor, int nHeightFactor, int nSubTextureSize)
75 : mWidthFactor(nWidthFactor)
76 , mHeightFactor(nHeightFactor)
77 , mSubTextureSize(nSubTextureSize)
81 FixedTextureAtlasManager::~FixedTextureAtlasManager()
85 void FixedTextureAtlasManager::CreateNewTexture()
87 int nTextureWidth = mWidthFactor * mSubTextureSize;
88 int nTextureHeight = mHeightFactor * mSubTextureSize;
89 maFixedTextures.push_back(o3tl::make_unique<FixedTexture>(nTextureWidth, nTextureHeight, mWidthFactor * mHeightFactor));
92 OpenGLTexture FixedTextureAtlasManager::Reserve(int nWidth, int nHeight)
94 FixedTexture* pFixedTexture = nullptr;
96 auto funFreeSlot = [] (std::unique_ptr<FixedTexture>& inFixedTexture)
98 return inFixedTexture->mnFreeSlots > 0;
101 auto it = std::find_if(maFixedTextures.begin(), maFixedTextures.end(), funFreeSlot);
103 if (it != maFixedTextures.end())
105 pFixedTexture = (*it).get();
107 else
109 CreateNewTexture();
110 pFixedTexture = maFixedTextures.back().get();
113 int nSlot = pFixedTexture->findAndAllocateFreeSlot();
115 // Calculate coordinates in texture
116 int nX = (nSlot % mWidthFactor) * mSubTextureSize;
117 int nY = (nSlot / mWidthFactor) * mSubTextureSize;
119 Rectangle aRectangle(Point(nX, nY), Size(nWidth, nHeight));
121 return OpenGLTexture(pFixedTexture->mpTexture, aRectangle, nSlot);
124 OpenGLTexture FixedTextureAtlasManager::InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData)
126 OpenGLTexture aTexture = Reserve(nWidth, nHeight);
127 if (pData == nullptr)
128 return aTexture;
130 aTexture.CopyData(nWidth, nHeight, nFormat, nType, pData);
132 return aTexture;
135 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */