[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