diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2019-12-03 11:39:01 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2019-12-06 14:25:30 +0100 |
commit | 5b667d771de65167e269bb145b888eabbc7fdedd (patch) | |
tree | e87eb59c423c19dbce1f3eddc6d0790b586811d0 /vcl/skia/win | |
parent | 8b94f29ee623a28c5225b904829e04c6b83a89a5 (diff) |
make Skia Windows text rendering use SkImage instead of SkBitmap
This will allow making it GPU-backed, as SkImage can be GPU-backed,
SkBitmap cannot.
Change-Id: I047eefe83741a036d372d39e5fc6a4fa400e6504
Reviewed-on: https://gerrit.libreoffice.org/84559
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl/skia/win')
-rw-r--r-- | vcl/skia/win/gdiimpl.cxx | 52 | ||||
-rw-r--r-- | vcl/skia/win/winlayout.cxx | 27 |
2 files changed, 27 insertions, 52 deletions
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index 53979f39aad4..5270a7c3af18 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -91,7 +91,7 @@ bool WinSkiaSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const& return false; preDraw(); - mSurface->getCanvas()->drawBitmap(iterator->second, nX, nY); + mSurface->getCanvas()->drawImage(iterator->second, nX, nY); postDraw(); return true; } @@ -103,16 +103,16 @@ bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, C assert(dynamic_cast<SkiaCompatibleDC*>(&rWhite)); assert(dynamic_cast<SkiaCompatibleDC*>(&rBlack)); - SkBitmap bitmap = static_cast<SkiaCompatibleDC&>(rWhite).getAsBitmap(); + sk_sp<SkImage> image = static_cast<SkiaCompatibleDC&>(rWhite).getAsImage(); preDraw(); - mSurface->getCanvas()->drawBitmap(bitmap, nX, nY); + mSurface->getCanvas()->drawImage(image, nX, nY); postDraw(); // TODO what is the point of the second texture? (void)rBlack; if (!aControlCacheKey.canCacheControl()) return true; - SkiaControlCachePair pair(aControlCacheKey, std::move(bitmap)); + SkiaControlCachePair pair(aControlCacheKey, std::move(image)); SkiaControlsCache::get().insert(std::move(pair)); return true; } @@ -137,8 +137,8 @@ void WinSkiaSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pText // SkiaCompatibleDC::wantsTextColorWhite() ensures the glyph is white. // TODO maybe other black/white in WinFontInstance::CacheGlyphToAtlas() should be swapped. paint.setColorFilter(SkColorFilters::Blend(toSkColor(aMaskColor), SkBlendMode::kModulate)); - mSurface->getCanvas()->drawBitmapRect( - static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap, + mSurface->getCanvas()->drawImageRect( + static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->image, SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight), SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight), @@ -150,7 +150,7 @@ void WinSkiaSalGraphicsImpl::DrawTextMask(CompatibleDC::Texture* pTexture, Color const SalTwoRect& rPosAry) { assert(dynamic_cast<SkiaCompatibleDC::Texture*>(pTexture)); - drawMask(rPosAry, static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap, nMaskColor); + drawMask(rPosAry, *static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->image, nMaskColor); } SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height) @@ -161,11 +161,11 @@ SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int wid std::unique_ptr<CompatibleDC::Texture> SkiaCompatibleDC::getAsMaskTexture() { auto ret = std::make_unique<SkiaCompatibleDC::Texture>(); - ret->bitmap = getAsMaskBitmap(); + ret->image = getAsMaskImage(); return ret; } -SkBitmap SkiaCompatibleDC::getAsMaskBitmap() +sk_sp<SkImage> SkiaCompatibleDC::getAsMaskImage() { // mpData is in the BGRA format, with A unused (and set to 0), and RGB are grey, // so convert it to Skia format, then to 8bit and finally use as alpha mask @@ -192,34 +192,11 @@ SkBitmap SkiaCompatibleDC::getAsMaskBitmap() alpha.setInfo(bitmap8.info().makeColorType(kAlpha_8_SkColorType), bitmap8.rowBytes()); alpha.setPixelRef(sk_ref_sp(bitmap8.pixelRef()), bitmap8.pixelRefOrigin().x(), bitmap8.pixelRefOrigin().y()); - return alpha; + // TODO GPU? + return SkImage::MakeFromBitmap(alpha); } -bool SkiaCompatibleDC::copyToTexture(CompatibleDC::Texture& aTexture) -{ - assert(mpImpl); - assert(dynamic_cast<SkiaCompatibleDC::Texture*>(&aTexture)); - SkBitmap tmpBitmap; - if (!tmpBitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight, - kBGRA_8888_SkColorType, kUnpremul_SkAlphaType), - mpData, maRects.mnSrcWidth * 4)) - abort(); - SkBitmap& bitmap = static_cast<SkiaCompatibleDC::Texture&>(aTexture).bitmap; - SkPaint paint; - paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha - SkCanvas canvas(bitmap); - // The data we got is upside-down. - SkMatrix matrix; - matrix.preTranslate(0, maRects.mnSrcHeight); - matrix.setConcat(matrix, SkMatrix::MakeScale(1, -1)); - canvas.concat(matrix); - canvas.drawBitmapRect(tmpBitmap, - SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight), - SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight), &paint); - return true; -} - -SkBitmap SkiaCompatibleDC::getAsBitmap() +sk_sp<SkImage> SkiaCompatibleDC::getAsImage() { SkBitmap tmpBitmap; if (!tmpBitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight, @@ -240,7 +217,8 @@ SkBitmap SkiaCompatibleDC::getAsBitmap() canvas.drawBitmapRect(tmpBitmap, SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight), SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight), &paint); - return bitmap; + // TODO GPU + return SkImage::MakeFromBitmap(bitmap); } SkiaControlsCache::SkiaControlsCache() @@ -252,9 +230,7 @@ SkiaControlCacheType& SkiaControlsCache::get() { SalData* data = GetSalData(); if (!data->m_pSkiaControlsCache) - { data->m_pSkiaControlsCache.reset(new SkiaControlsCache); - } return data->m_pSkiaControlsCache->cache; } diff --git a/vcl/skia/win/winlayout.cxx b/vcl/skia/win/winlayout.cxx index 5b38b0e63f81..e544943b0e3f 100644 --- a/vcl/skia/win/winlayout.cxx +++ b/vcl/skia/win/winlayout.cxx @@ -11,17 +11,16 @@ #include <skia/win/gdiimpl.hxx> -bool SkiaGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, - int nHeight) +bool SkiaGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, CompatibleDC* dc) { assert(rElement.maTexture.get() == nullptr); + assert(dynamic_cast<SkiaCompatibleDC*>(dc)); + SkiaCompatibleDC* sdc = static_cast<SkiaCompatibleDC*>(dc); 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; - mLRUOrder.push_back(texture->bitmap.getPixels()); + texture->image = sdc->getAsImage(); + mLRUOrder.push_back(texture->image->uniqueID()); return true; } @@ -31,10 +30,10 @@ void SkiaGlobalWinGlyphCache::Prune() if (mLRUOrder.size() > MAXSIZE) { size_t toRemove = mLRUOrder.size() - MAXSIZE; - std::vector<void*> pixelsToRemove(mLRUOrder.begin(), mLRUOrder.begin() + toRemove); + std::vector<uint32_t> idsToRemove(mLRUOrder.begin(), mLRUOrder.begin() + toRemove); mLRUOrder.erase(mLRUOrder.begin(), mLRUOrder.begin() + toRemove); for (auto& pWinGlyphCache : maWinGlyphCaches) - static_cast<SkiaWinGlyphCache*>(pWinGlyphCache)->RemoveTextures(pixelsToRemove); + static_cast<SkiaWinGlyphCache*>(pWinGlyphCache)->RemoveTextures(idsToRemove); } } @@ -43,21 +42,21 @@ 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()); + auto it = find(mLRUOrder.begin(), mLRUOrder.end(), texture->image->uniqueID()); if (it != mLRUOrder.end()) mLRUOrder.erase(it); - mLRUOrder.push_back(texture->bitmap.getPixels()); + mLRUOrder.push_back(texture->image->uniqueID()); } -void SkiaWinGlyphCache::RemoveTextures(const std::vector<void*>& pixelsToRemove) +void SkiaWinGlyphCache::RemoveTextures(const std::vector<uint32_t>& idsToRemove) { 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()) + uint32_t id = static_cast<SkiaCompatibleDC::Texture*>(it->second.maTexture.get()) + ->image->uniqueID(); + if (std::find(idsToRemove.begin(), idsToRemove.end(), id) != idsToRemove.end()) it = maWinTextureCache.erase(it); else ++it; |