diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2016-04-08 19:17:41 +0900 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2016-04-08 14:47:02 +0000 |
commit | bd1bfeff238705fa89b4912865aa7cc6c4c1857f (patch) | |
tree | 09bcaa03f2873964541d59bad39e9ff182b7dc54 /vcl/inc | |
parent | 674fc004a5c5adcce4bb2c2841298431a79c01f2 (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.hxx | 113 | ||||
-rw-r--r-- | vcl/inc/opengl/FixedTextureAtlas.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/opengl/PackedTextureAtlas.hxx | 46 | ||||
-rw-r--r-- | vcl/inc/opengl/texture.hxx | 36 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 8 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 5 |
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 |