1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
12 #include <sal/config.h>
13 #include <vcl/opengl/OpenGLContext.hxx>
14 #include <vcl/opengl/OpenGLHelper.hxx>
16 #include <opengl/framebuffer.hxx>
17 #include <opengl/texture.hxx>
19 #include <opengl/FixedTextureAtlas.hxx>
21 #include <o3tl/make_unique.hxx>
25 std::shared_ptr
<ImplOpenGLTexture
> mpTexture
;
27 std::vector
<bool> maAllocatedSlots
;
29 FixedTexture(int nTextureWidth
, int nTextureHeight
, int nNumberOfSlots
)
30 : mpTexture(new ImplOpenGLTexture(nTextureWidth
, nTextureHeight
, true))
31 , mnFreeSlots(nNumberOfSlots
)
32 , maAllocatedSlots(nNumberOfSlots
, false)
34 auto aDeallocateFunction
= [this] (int nSlotNumber
)
36 deallocateSlot(nSlotNumber
);
39 mpTexture
->SetSlotDeallocateCallback(aDeallocateFunction
);
40 mpTexture
->InitializeSlotMechanism(nNumberOfSlots
);
45 mpTexture
->ResetSlotDeallocateCallback();
48 void allocateSlot(int nSlot
)
50 maAllocatedSlots
[nSlot
] = true;
54 void deallocateSlot(int nSlot
)
56 maAllocatedSlots
[nSlot
] = false;
60 int findAndAllocateFreeSlot()
62 for (size_t i
= 0; i
< maAllocatedSlots
.size(); ++i
)
64 if (!maAllocatedSlots
[i
])
74 FixedTexture(const FixedTexture
&) = delete;
75 FixedTexture
& operator=(const FixedTexture
&) = delete;
78 FixedTextureAtlasManager::FixedTextureAtlasManager(int nWidthFactor
, int nHeightFactor
, int nSubTextureSize
)
79 : mWidthFactor(nWidthFactor
)
80 , mHeightFactor(nHeightFactor
)
81 , mSubTextureSize(nSubTextureSize
)
85 FixedTextureAtlasManager::~FixedTextureAtlasManager()
89 void FixedTextureAtlasManager::CreateNewTexture()
91 int nTextureWidth
= mWidthFactor
* mSubTextureSize
;
92 int nTextureHeight
= mHeightFactor
* mSubTextureSize
;
93 maFixedTextures
.push_back(o3tl::make_unique
<FixedTexture
>(nTextureWidth
, nTextureHeight
, mWidthFactor
* mHeightFactor
));
96 OpenGLTexture
FixedTextureAtlasManager::Reserve(int nWidth
, int nHeight
)
98 FixedTexture
* pFixedTexture
= nullptr;
100 auto funFreeSlot
= [] (std::unique_ptr
<FixedTexture
>& inFixedTexture
)
102 return inFixedTexture
->mnFreeSlots
> 0;
105 auto it
= std::find_if(maFixedTextures
.begin(), maFixedTextures
.end(), funFreeSlot
);
107 if (it
!= maFixedTextures
.end())
109 pFixedTexture
= (*it
).get();
114 pFixedTexture
= maFixedTextures
.back().get();
117 int nSlot
= pFixedTexture
->findAndAllocateFreeSlot();
119 // Calculate coordinates in texture
120 int nX
= (nSlot
% mWidthFactor
) * mSubTextureSize
;
121 int nY
= (nSlot
/ mWidthFactor
) * mSubTextureSize
;
123 tools::Rectangle
aRectangle(Point(nX
, nY
), Size(nWidth
, nHeight
));
125 return OpenGLTexture(pFixedTexture
->mpTexture
, aRectangle
, nSlot
);
128 OpenGLTexture
FixedTextureAtlasManager::InsertBuffer(int nWidth
, int nHeight
, int nFormat
, int nType
, sal_uInt8
const * pData
)
130 OpenGLTexture aTexture
= Reserve(nWidth
, nHeight
);
131 if (pData
== nullptr)
134 aTexture
.CopyData(nWidth
, nHeight
, nFormat
, nType
, pData
);
139 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */