summaryrefslogtreecommitdiff
path: root/vcl/skia/win
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-12-03 11:39:01 +0100
committerLuboš Luňák <l.lunak@collabora.com>2019-12-06 14:25:30 +0100
commit5b667d771de65167e269bb145b888eabbc7fdedd (patch)
treee87eb59c423c19dbce1f3eddc6d0790b586811d0 /vcl/skia/win
parent8b94f29ee623a28c5225b904829e04c6b83a89a5 (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.cxx52
-rw-r--r--vcl/skia/win/winlayout.cxx27
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;