summaryrefslogtreecommitdiff
path: root/vcl/inc
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-04-08 19:17:41 +0900
committerMichael Meeks <michael.meeks@collabora.com>2016-04-08 14:47:02 +0000
commitbd1bfeff238705fa89b4912865aa7cc6c4c1857f (patch)
tree09bcaa03f2873964541d59bad39e9ff182b7dc54 /vcl/inc
parent674fc004a5c5adcce4bb2c2841298431a79c01f2 (diff)
tdf#94682 optimize texture drawing on Win. (squashed multi commits)
Includes commits from master: opengl: deferred and optimized (text) texture drawing 96a098c0e8a009b77a26061dac3318da71d34ee4 opengl: texture atlas impl. to efficiently packs textures 40e9ed91bd8bbfecfc3832d73a81741d0aa97d3a opengl: use packed texture atlas for glyph cache in win. backend 80d0b2916db81a7f47bb1d368677016bbb870df6 opengl: fix wrong clipping when drawing text 094faaae6982472375420e57d6b9e34eefdbced8 opengl: cleanup texture, const internal format f65e77c965bb47d53c994d90b7fd0bf5009b343b Change-Id: I31ecd891d1d69e94973673930b0606e1ac884aab Reviewed-on: https://gerrit.libreoffice.org/23914 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'vcl/inc')
-rw-r--r--vcl/inc/opengl/AccumulatedTextures.hxx113
-rw-r--r--vcl/inc/opengl/FixedTextureAtlas.hxx1
-rw-r--r--vcl/inc/opengl/PackedTextureAtlas.hxx46
-rw-r--r--vcl/inc/opengl/texture.hxx36
-rw-r--r--vcl/inc/openglgdiimpl.hxx8
-rw-r--r--vcl/inc/win/salgdi.h5
6 files changed, 183 insertions, 26 deletions
diff --git a/vcl/inc/opengl/AccumulatedTextures.hxx b/vcl/inc/opengl/AccumulatedTextures.hxx
new file mode 100644
index 000000000000..e74c06535f69
--- /dev/null
+++ b/vcl/inc/opengl/AccumulatedTextures.hxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_ACCUMULATEDTEXTURES_H
+#define INCLUDED_VCL_INC_OPENGL_ACCUMULATEDTEXTURES_H
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include <o3tl/make_unique.hxx>
+#include "opengl/texture.hxx"
+#include <memory>
+
+struct TextureDrawParameters
+{
+ std::vector<GLfloat> maVertices;
+ std::vector<GLfloat> maTextureCoords;
+ GLint getNumberOfVertices()
+ {
+ return maVertices.size() / 2;
+ }
+};
+
+struct AccumulatedTexturesEntry
+{
+ OpenGLTexture maTexture;
+ std::unordered_map<SalColor, TextureDrawParameters> maColorTextureDrawParametersMap;
+
+ AccumulatedTexturesEntry(const OpenGLTexture& rTexture)
+ : maTexture(rTexture)
+ {}
+
+ void insert(const OpenGLTexture& rTexture, const SalColor& aColor, const SalTwoRect& r2Rect)
+ {
+ TextureDrawParameters& aDrawParameters = maColorTextureDrawParametersMap[aColor];
+ rTexture.FillCoords<GL_TRIANGLES>(aDrawParameters.maTextureCoords, r2Rect, false);
+
+ GLfloat nX1 = r2Rect.mnDestX;
+ GLfloat nY1 = r2Rect.mnDestY;
+ GLfloat nX2 = r2Rect.mnDestX + r2Rect.mnDestWidth;
+ GLfloat nY2 = r2Rect.mnDestY + r2Rect.mnDestHeight;
+
+ auto& rVertices = aDrawParameters.maVertices;
+ rVertices.push_back(nX1);
+ rVertices.push_back(nY1);
+
+ rVertices.push_back(nX2);
+ rVertices.push_back(nY1);
+
+ rVertices.push_back(nX1);
+ rVertices.push_back(nY2);
+
+ rVertices.push_back(nX1);
+ rVertices.push_back(nY2);
+
+ rVertices.push_back(nX2);
+ rVertices.push_back(nY1);
+
+ rVertices.push_back(nX2);
+ rVertices.push_back(nY2);
+ }
+};
+
+class AccumulatedTextures
+{
+private:
+ typedef std::unordered_map<GLuint, std::unique_ptr<AccumulatedTexturesEntry>> AccumulatedTexturesMap;
+
+ AccumulatedTexturesMap maEntries;
+
+public:
+ AccumulatedTextures()
+ {}
+
+ bool empty()
+ {
+ return maEntries.empty();
+ }
+
+ void clear()
+ {
+ maEntries.clear();
+ }
+
+ void insert(OpenGLTexture& rTexture, const SalColor& aColor, const SalTwoRect& r2Rect)
+ {
+ GLuint nTextureId = rTexture.Id();
+
+ if (maEntries.find(nTextureId) == maEntries.end())
+ {
+ OpenGLTexture aWholeTexture(rTexture.GetWholeTexture());
+ maEntries[nTextureId] = o3tl::make_unique<AccumulatedTexturesEntry>(aWholeTexture);
+ }
+
+ std::unique_ptr<AccumulatedTexturesEntry>& rEntry = maEntries[nTextureId];
+ rEntry->insert(rTexture, aColor, r2Rect);
+ }
+
+ AccumulatedTexturesMap& getAccumulatedTexturesMap()
+ {
+ return maEntries;
+ }
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/FixedTextureAtlas.hxx b/vcl/inc/opengl/FixedTextureAtlas.hxx
index 5b22b619d945..8d104a788c83 100644
--- a/vcl/inc/opengl/FixedTextureAtlas.hxx
+++ b/vcl/inc/opengl/FixedTextureAtlas.hxx
@@ -28,6 +28,7 @@ public:
FixedTextureAtlasManager(int nWidthFactor, int nHeightFactor, int nTextureSize);
~FixedTextureAtlasManager();
OpenGLTexture InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData);
+ OpenGLTexture Reserve(int nWidth, int nHeight);
int GetSubtextureSize()
{
diff --git a/vcl/inc/opengl/PackedTextureAtlas.hxx b/vcl/inc/opengl/PackedTextureAtlas.hxx
new file mode 100644
index 000000000000..17501f368208
--- /dev/null
+++ b/vcl/inc/opengl/PackedTextureAtlas.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX
+#define INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX
+
+#include "opengl/texture.hxx"
+
+struct PackedTexture;
+
+/**
+ * Pack texutres into one texutre atlas.
+ *
+ * This is based on algorithm described in [1] and is an
+ * addaptation of "texture atlas generator" from [2].
+ *
+ * [1]: http://www.blackpawn.com/texts/lightmaps/
+ * [2]: https://github.com/lukaszdk/texture-atlas-generator
+ *
+ */
+class VCL_PLUGIN_PUBLIC PackedTextureAtlasManager
+{
+ std::vector<std::unique_ptr<PackedTexture>> maPackedTextures;
+
+ int mnTextureWidth;
+ int mnTextureHeight;
+
+ void CreateNewTexture();
+
+public:
+ PackedTextureAtlasManager(int nTextureWidth, int nTextureHeight);
+ ~PackedTextureAtlasManager();
+ OpenGLTexture InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData);
+ OpenGLTexture Reserve(int nWidth, int nHeight);
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index 938891848ab7..6afc17630431 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -51,30 +51,8 @@ public:
bool InsertBuffer(int nX, int nY, int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData);
- void IncreaseRefCount(int nSlotNumber)
- {
- mnRefCount++;
- if (mpSlotReferences && nSlotNumber >= 0)
- {
- if (mpSlotReferences->at(nSlotNumber) == 0)
- mnFreeSlots--;
- mpSlotReferences->at(nSlotNumber)++;
- }
- }
-
- void DecreaseRefCount(int nSlotNumber)
- {
- mnRefCount--;
- if (mpSlotReferences && nSlotNumber >= 0)
- {
- mpSlotReferences->at(nSlotNumber)--;
- if (mpSlotReferences->at(nSlotNumber) == 0)
- mnFreeSlots++;
- }
-
- if (mnRefCount <= 0)
- delete this;
- }
+ void IncreaseRefCount(int nSlotNumber);
+ void DecreaseRefCount(int nSlotNumber);
bool IsUnique()
{
@@ -97,7 +75,7 @@ private:
public:
OpenGLTexture();
- OpenGLTexture(ImplOpenGLTexture* pImpl, Rectangle aRectangle, int nSlotNumber = 0);
+ OpenGLTexture(ImplOpenGLTexture* pImpl, Rectangle aRectangle, int nSlotNumber);
OpenGLTexture( int nWidth, int nHeight, bool bAllocate = true );
OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, void const * pData );
@@ -111,9 +89,10 @@ public:
GLuint Id() const;
int GetWidth() const;
int GetHeight() const;
+
void GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted=false ) const;
void GetWholeCoord( GLfloat* pCoord ) const;
-
+ OpenGLTexture GetWholeTexture();
void Bind();
void Unbind();
void Read( GLenum nFormat, GLenum nType, sal_uInt8* pData );
@@ -121,6 +100,8 @@ public:
bool HasStencil() const;
GLuint StencilId() const;
+ bool CopyData(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData);
+
void SaveToFile(const OUString& rFileName);
GLenum GetFilter() const;
@@ -130,6 +111,9 @@ public:
OpenGLTexture& operator=( const OpenGLTexture& rTexture );
bool operator==( const OpenGLTexture& rTexture ) const;
bool operator!=( const OpenGLTexture& rTexture ) const;
+
+ template<GLenum type>
+ void FillCoords(std::vector<GLfloat>& aCoordVector, const SalTwoRect& rPosAry, bool bInverted) const;
};
#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index ca8232ae2c45..6dfa73c7b742 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -28,6 +28,7 @@
#include "opengl/program.hxx"
#include "opengl/texture.hxx"
#include "regionband.hxx"
+#include "opengl/AccumulatedTextures.hxx"
#include <vcl/opengl/OpenGLContext.hxx>
@@ -99,6 +100,8 @@ protected:
SalColor mProgramSolidColor;
double mProgramSolidTransparency;
+ std::unique_ptr<AccumulatedTextures> mpAccumulatedTextures;
+
void ImplInitClipRegion();
void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
void ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge = false );
@@ -144,6 +147,8 @@ public:
void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
void DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect );
void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect );
+ void DeferredTextDraw(OpenGLTexture& rTexture, const SalColor nMaskColor, const SalTwoRect& rPosAry);
+ void FlushDeferredDrawing();
public:
// get the width of the device
@@ -164,6 +169,9 @@ public:
// operations to do before painting
void PreDraw(XOROption eOpt = IGNORE_XOR);
+ // initialize pre-draw state
+ void InitializePreDrawState(XOROption eOpt = IGNORE_XOR);
+
// operations to do after painting
void PostDraw();
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 085f77eed706..30b143814043 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -173,11 +173,16 @@ public:
SalTwoRect getTwoRect() { return maRects; }
+ Size getBitmapSize() { return Size(maRects.mnSrcWidth, maRects.mnSrcHeight); }
+
/// Reset the DC with the defined color.
void fill(sal_uInt32 color);
/// Obtain the texture; the caller must delete it after use.
OpenGLTexture* getTexture();
+
+ /// Copy bitmap data to the texture. Texutre must be initialized and the correct size to hold the bitmap.
+ bool copyToTexture(OpenGLTexture& aTexture);
};
class WinSalGraphics : public SalGraphics