diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2019-10-23 11:29:22 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2019-11-27 09:55:10 +0100 |
commit | 619959827003814053a5e9ec81acfd07b3aa270a (patch) | |
tree | 29d77c1bc8a45f5102b62d04211bedd3d0ae41c7 /vcl/skia/win | |
parent | c6b50a85a2371c1f49f75d1a9fccc8548e03e02f (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.cxx | 43 |
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: */ |