vcl/inc/opengl/PackedTextureAtlas.hxx | 6 +++ vcl/opengl/PackedTextureAtlas.cxx | 38 ++++++++++++++++++---- vcl/opengl/gdiimpl.cxx | 13 +++++++ vcl/win/source/gdi/winlayout.cxx | 57 +++++++++++++++++++++++++++++++--- 4 files changed, 103 insertions(+), 11 deletions(-)
New commits: commit 49e703679c61f0e9ef75163d671ba890e8768884 Author: Tomaž Vajngerl <[email protected]> Date: Fri Apr 8 17:03:48 2016 +0900 tdf#99244 opengl: miter limit for poly lines (cherry picked from commit ea6196f0a51d1bf4cd722468406dcc8c64c7435c) Change-Id: I1c363a8f1d21bbacab0c5785544aa8becfe39363 diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index d3d6392..0c107da 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -682,6 +682,8 @@ inline glm::vec2 normalize(const glm::vec2& vector) return vector; } +SAL_CONSTEXPR float constMiterMinimumAngle = 15.0f; + } // end anonymous namespace void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth) @@ -864,6 +866,17 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl if (eLineJoin == basegfx::B2DLineJoin::Miter) { + float angle = std::atan2(previousLineVector.x * nextLineVector.y - previousLineVector.y * nextLineVector.x, + previousLineVector.x * nextLineVector.x + previousLineVector.y * nextLineVector.y); + + angle = (F_PI - std::fabs(angle)) / F_PI180; + + if (angle < constMiterMinimumAngle) + eLineJoin = basegfx::B2DLineJoin::Bevel; + } + + if (eLineJoin == basegfx::B2DLineJoin::Miter) + { // With miter join we calculate the extrusion vector by adding normals of // previous and next line segment. The vector shows the way but we also // need the length (otherwise the line will be deformed). Length factor is commit f971fe65a52b6a4fbf9bad48778f7be924964a30 Author: Tomaž Vajngerl <[email protected]> Date: Mon Apr 11 18:23:18 2016 +0900 opengl: limit the number of textures for the glyph texture atlas Change-Id: I7790e8dddb4586167f860e0ecc81bda1f4dae21a diff --git a/vcl/inc/opengl/PackedTextureAtlas.hxx b/vcl/inc/opengl/PackedTextureAtlas.hxx index 17501f3..4d9015f 100644 --- a/vcl/inc/opengl/PackedTextureAtlas.hxx +++ b/vcl/inc/opengl/PackedTextureAtlas.hxx @@ -35,10 +35,16 @@ class VCL_PLUGIN_PUBLIC PackedTextureAtlasManager void CreateNewTexture(); public: + + /** + * nTextureWidth and nTextureHeight are the dimensions of the common texture(s) + * nTextureLimit is the maximum limit of that a texture atlas can have (0 or less - unlimited) + */ 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); + std::vector<GLuint> ReduceTextureNumber(int nMaxNumberOfTextures); }; #endif // INCLUDED_VCL_INC_OPENGL_PACKEDTEXTUREATLAS_HXX diff --git a/vcl/opengl/PackedTextureAtlas.cxx b/vcl/opengl/PackedTextureAtlas.cxx index 60fa1e9..f7f681d 100644 --- a/vcl/opengl/PackedTextureAtlas.cxx +++ b/vcl/opengl/PackedTextureAtlas.cxx @@ -24,12 +24,21 @@ struct Node std::unique_ptr<Node> mRightNode; bool mOccupied; + Node(int nWidth, int nHeight); + Node(Rectangle& aRectangle); bool isLeaf(); Node* insert(int nWidth, int nHeight, int nPadding); }; +Node::Node(int nWidth, int nHeight) + : mRectangle(Rectangle(Point(), Size(nWidth, nHeight))) + , mLeftNode() + , mRightNode() + , mOccupied(false) +{} + Node::Node(Rectangle& aRectangle) : mRectangle(aRectangle) , mLeftNode() @@ -101,8 +110,15 @@ Node* Node::insert(int nWidth, int nHeight, int nPadding) struct PackedTexture { - std::unique_ptr<Node> mpRootNode; ImplOpenGLTexture* mpTexture; + std::unique_ptr<Node> mpRootNode; + int mnDeallocatedArea; + + PackedTexture(int nWidth, int nHeight) + : mpTexture(new ImplOpenGLTexture(nWidth, nHeight, true)) + , mpRootNode(new Node(nWidth, nHeight)) + , mnDeallocatedArea(0) + {} }; PackedTextureAtlasManager::PackedTextureAtlasManager(int nTextureWidth, int nTextureHeight) @@ -116,17 +132,13 @@ PackedTextureAtlasManager::~PackedTextureAtlasManager() for (std::unique_ptr<PackedTexture>& pPackedTexture : maPackedTextures) { // Free texture early in VCL shutdown while we have a context. - pPackedTexture->mpTexture->Dispose(); - pPackedTexture->mpTexture->DecreaseRefCount(0); + delete pPackedTexture->mpTexture; } } void PackedTextureAtlasManager::CreateNewTexture() { - std::unique_ptr<PackedTexture> pPackedTexture(new PackedTexture); - pPackedTexture->mpTexture = new ImplOpenGLTexture(mnTextureWidth, mnTextureHeight, true); - Rectangle aInitialRect(Point(0, 0), Size(mnTextureWidth, mnTextureHeight)); - pPackedTexture->mpRootNode.reset(new Node(aInitialRect)); + std::unique_ptr<PackedTexture> pPackedTexture(new PackedTexture(mnTextureWidth, mnTextureHeight)); maPackedTextures.push_back(std::move(pPackedTexture)); } @@ -161,4 +173,16 @@ OpenGLTexture PackedTextureAtlasManager::InsertBuffer(int nWidth, int nHeight, i return aTexture; } +std::vector<GLuint> PackedTextureAtlasManager::ReduceTextureNumber(int nMaxNumberOfTextures) +{ + std::vector<GLuint> aTextureIDs; + while (int(maPackedTextures.size()) > nMaxNumberOfTextures) + { + // Remove oldest created texture + aTextureIDs.push_back(maPackedTextures[0]->mpTexture->mnTexture); + maPackedTextures.erase(maPackedTextures.begin()); + } + return aTextureIDs; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 49aa0c4..f5b3a6b 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -48,6 +48,7 @@ #include <winver.h> #include <unordered_map> +#include <unordered_set> typedef std::unordered_map<int,int> IntMap; @@ -97,19 +98,66 @@ struct OpenGLGlyphDrawElement } }; +class GlyphCache; + +struct GlobalGlyphCache +{ + GlobalGlyphCache() + : maPackedTextureAtlas(2048, 2048) + {} + + PackedTextureAtlasManager maPackedTextureAtlas; + std::unordered_set<GlyphCache*> maGlyphCaches; +}; + class GlyphCache { private: - static PackedTextureAtlasManager sPackedTextureAtlas; + static std::unique_ptr<GlobalGlyphCache> gGlobalGlyphCache; std::unordered_map<int, OpenGLGlyphDrawElement> maOpenGLTextureCache; public: GlyphCache() - {} + { + gGlobalGlyphCache.get()->maGlyphCaches.insert(this); + } + + ~GlyphCache() + { + gGlobalGlyphCache.get()->maGlyphCaches.erase(this); + } void ReserveTextureSpace(OpenGLGlyphDrawElement& rElement, int nWidth, int nHeight) { - rElement.maTexture = sPackedTextureAtlas.Reserve(nWidth, nHeight); + GlobalGlyphCache* pGlobalGlyphCache = gGlobalGlyphCache.get(); + rElement.maTexture = pGlobalGlyphCache->maPackedTextureAtlas.Reserve(nWidth, nHeight); + std::vector<GLuint> aTextureIDs = pGlobalGlyphCache->maPackedTextureAtlas.ReduceTextureNumber(8); + if (!aTextureIDs.empty()) + { + for (auto& pGlyphCache: pGlobalGlyphCache->maGlyphCaches) + { + pGlyphCache->RemoveTextures(aTextureIDs); + } + } + } + + void RemoveTextures(std::vector<GLuint>& rTextureIDs) + { + auto it = maOpenGLTextureCache.begin(); + + while (it != maOpenGLTextureCache.end()) + { + GLuint nTextureID = it->second.maTexture.Id(); + + if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end()) + { + it = maOpenGLTextureCache.erase(it); + } + else + { + it++; + } + } } void PutDrawElementInCache(const OpenGLGlyphDrawElement& rElement, int nGlyphIndex) @@ -130,7 +178,8 @@ public: } }; -PackedTextureAtlasManager GlyphCache::sPackedTextureAtlas(2048, 2048); +// static initialization +std::unique_ptr<GlobalGlyphCache> GlyphCache::gGlobalGlyphCache(new GlobalGlyphCache); // win32 specific physical font instance class ImplWinFontEntry : public ImplFontEntry
_______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
