[Libreoffice-commits] core.git: Branch 'feature/fixes20' - 2 commits - vcl/inc vcl/opengl vcl/win

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Thu Apr 14 08:53:10 UTC 2016


 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 <tomaz.vajngerl at collabora.co.uk>
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 <tomaz.vajngerl at collabora.co.uk>
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


More information about the Libreoffice-commits mailing list