[Libreoffice-commits] core.git: vcl/inc vcl/skia
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jan 20 15:03:16 UTC 2020
vcl/inc/skia/gdiimpl.hxx | 1 +
vcl/skia/gdiimpl.cxx | 16 ++++++++++++++++
vcl/skia/win/gdiimpl.cxx | 1 +
vcl/skia/x11/gdiimpl.cxx | 1 +
4 files changed, 19 insertions(+)
New commits:
commit ad3580df085b3a3d66eb73cae997ea5ca178ccc1
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Jan 20 12:10:00 2020 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Jan 20 16:02:46 2020 +0100
workaround for Skia+Cairo text drawing exhausting GPU memory
See the description in SkiaSalGraphicsImpl::postDraw().
Change-Id: Ia6b38741fcfe3f6b5f0a21051886c55ed5324c61
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87062
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index f1ddc20bdf01..10b6371b4dcd 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -277,6 +277,7 @@ protected:
std::unique_ptr<SkCanvas> mXorCanvas;
SkRect mXorExtents; // the area that needs updating for the xor operation (or empty for all)
std::unique_ptr<SkiaFlushIdle> mFlush;
+ int mPendingPixelsToFlush;
};
#endif
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index a88f78823382..66086c9af82b 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -177,6 +177,7 @@ SkiaSalGraphicsImpl::SkiaSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvid
, mFillColor(SALCOLOR_NONE)
, mXorMode(false)
, mFlush(new SkiaFlushIdle(this))
+ , mPendingPixelsToFlush(0)
{
}
@@ -375,6 +376,20 @@ void SkiaSalGraphicsImpl::postDraw()
else if (!mFlush->IsActive())
mFlush->Start();
}
+ // Skia (at least when using Vulkan) queues drawing commands and executes them only later.
+ // But some operations may queue way too much data to draw, leading to Vulkan getting out of memory,
+ // which at least on Linux leads to driver problems affecting even the whole X11 session.
+ // One such problematic operation may be drawBitmap(SkBitmap), which is used by SkiaX11CairoTextRender
+ // to draw text, which is internally done by creating the SkBitmap from cairo surface data. Apparently
+ // the cairo surface's size matches the size of the destination (window), which may be large,
+ // and each text drawing allocates a new surface (and thus SkBitmap). So we may end up queueing up
+ // millions of pixels of bitmap data. So force a flush if such a possibly problematic operation
+ // has queued up too much data.
+ if (mPendingPixelsToFlush > 10 * 1024 * 1024)
+ {
+ mSurface->flush();
+ mPendingPixelsToFlush = 0;
+ }
}
// VCL can sometimes resize us without telling us, update the surface if needed.
@@ -1125,6 +1140,7 @@ void SkiaSalGraphicsImpl::drawBitmap(const SalTwoRect& rPosAry, const SkBitmap&
getDrawCanvas()->drawBitmapRect(aBitmap, aSourceRect, aDestinationRect, &aPaint);
if (mXorMode) // limit xor area update
mXorExtents = aDestinationRect;
+ mPendingPixelsToFlush += aBitmap.width() * aBitmap.height();
postDraw();
}
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index deace0072630..e9889415cc5e 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -57,6 +57,7 @@ void WinSkiaSalGraphicsImpl::freeResources() {}
void WinSkiaSalGraphicsImpl::performFlush()
{
+ mPendingPixelsToFlush = 0;
if (mWindowContext)
mWindowContext->swapBuffers();
}
diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index 04e2586e7f7a..a139a336c7b7 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -107,6 +107,7 @@ void X11SkiaSalGraphicsImpl::freeResources() {}
void X11SkiaSalGraphicsImpl::performFlush()
{
+ mPendingPixelsToFlush = 0;
// TODO XPutImage() is somewhat inefficient, XShmPutImage() should be preferred.
mWindowContext->swapBuffers();
}
More information about the Libreoffice-commits
mailing list