summaryrefslogtreecommitdiff
path: root/vcl/skia/win
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-10-23 11:29:22 +0200
committerLuboš Luňák <l.lunak@collabora.com>2019-11-27 09:55:10 +0100
commit619959827003814053a5e9ec81acfd07b3aa270a (patch)
tree29d77c1bc8a45f5102b62d04211bedd3d0ae41c7 /vcl/skia/win
parentc6b50a85a2371c1f49f75d1a9fccc8548e03e02f (diff)
implement pruning in SkiaGlobalWinGlyphCache
Currently based on identifying the SkBitmap's by their getPixels(), but this may need changed later since it's probably going to be more performant to use SkSurface. Also move the cache pruning out of AllocateTexture(), as that may possibly remove elements that would be used by DrawCachedGlyphs(). Change-Id: Ide2de752f634593b97573667af49b7aa9ec1f47f
Diffstat (limited to 'vcl/skia/win')
-rw-r--r--vcl/skia/win/winlayout.cxx43
1 files changed, 42 insertions, 1 deletions
diff --git a/vcl/skia/win/winlayout.cxx b/vcl/skia/win/winlayout.cxx
index bd232c1d2bbf..5b38b0e63f81 100644
--- a/vcl/skia/win/winlayout.cxx
+++ b/vcl/skia/win/winlayout.cxx
@@ -17,10 +17,51 @@ bool SkiaGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, int
assert(rElement.maTexture.get() == nullptr);
SkiaCompatibleDC::Texture* texture = new SkiaCompatibleDC::Texture;
rElement.maTexture.reset(texture);
+ // TODO use something GPU-backed?
+ // TODO is it possible to have an atlas?
if (!texture->bitmap.tryAllocN32Pixels(nWidth, nHeight))
return false;
- // TODO prune cache
+ mLRUOrder.push_back(texture->bitmap.getPixels());
return true;
}
+void SkiaGlobalWinGlyphCache::Prune()
+{
+ const int MAXSIZE = 64; // TODO
+ if (mLRUOrder.size() > MAXSIZE)
+ {
+ size_t toRemove = mLRUOrder.size() - MAXSIZE;
+ std::vector<void*> pixelsToRemove(mLRUOrder.begin(), mLRUOrder.begin() + toRemove);
+ mLRUOrder.erase(mLRUOrder.begin(), mLRUOrder.begin() + toRemove);
+ for (auto& pWinGlyphCache : maWinGlyphCaches)
+ static_cast<SkiaWinGlyphCache*>(pWinGlyphCache)->RemoveTextures(pixelsToRemove);
+ }
+}
+
+void SkiaGlobalWinGlyphCache::NotifyElementUsed(WinGlyphDrawElement& rElement)
+{
+ SkiaCompatibleDC::Texture* texture
+ = static_cast<SkiaCompatibleDC::Texture*>(rElement.maTexture.get());
+ // make the most recently used
+ auto it = find(mLRUOrder.begin(), mLRUOrder.end(), texture->bitmap.getPixels());
+ if (it != mLRUOrder.end())
+ mLRUOrder.erase(it);
+ mLRUOrder.push_back(texture->bitmap.getPixels());
+}
+
+void SkiaWinGlyphCache::RemoveTextures(const std::vector<void*>& pixelsToRemove)
+{
+ auto it = maWinTextureCache.begin();
+ while (it != maWinTextureCache.end())
+ {
+ assert(dynamic_cast<SkiaCompatibleDC::Texture*>(it->second.maTexture.get()));
+ void* pixels = static_cast<SkiaCompatibleDC::Texture*>(it->second.maTexture.get())
+ ->bitmap.getPixels();
+ if (std::find(pixelsToRemove.begin(), pixelsToRemove.end(), pixels) != pixelsToRemove.end())
+ it = maWinTextureCache.erase(it);
+ else
+ ++it;
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */