summaryrefslogtreecommitdiff
path: root/vcl/headless
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-01-11 19:08:50 +0100
committerCaolán McNamara <caolanm@redhat.com>2022-01-26 12:59:39 +0100
commit7c29b13ac67e3796b5998789371fa68acb01a260 (patch)
treec563254986e85a2c5433aed59a3be45ea8999077 /vcl/headless
parentd243e9dbfb8497bed03601a04f168bc1832ce263 (diff)
avoid Xlib cairo surfaces for small virtual devices (bsc#1183308)
The (private :( ) document contains a large number of small shapes for which VclProcessor2D::RenderTransparencePrimitive2D() gets called, which results in GetBitmapEx() on the VirtualDevice. And Cairo normally needs to do a roundtrip to the XServer to fetch the content, which makes the rendering pretty slow. Forcing image-based surface for small sizes of VirtualDevice actually has better performance for the document, and the lack of possible HW acceleration generally shouldn't matter for a surface this small. Additionally drawinglayer's VirtualDevice reusing tries to reuse even a large one when a small one is needed, so a hack is needed to avoid that in this case, I couldn't find a better way. Change-Id: I0f58659ab88165a6bd915f100fc3b1d4802a0fa9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128309 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com> (cherry picked from commit cf9be3417bc2be5f772c03180b7cbd248b82cad5) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128815 Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/headless')
-rw-r--r--vcl/headless/svpvd.cxx39
1 files changed, 26 insertions, 13 deletions
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
index f8e9cb5e6874..21d231b229e9 100644
--- a/vcl/headless/svpvd.cxx
+++ b/vcl/headless/svpvd.cxx
@@ -76,29 +76,42 @@ void SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long nNewDY,
cairo_surface_destroy(m_pSurface);
}
+ double fXScale, fYScale;
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // Force scaling of the painting
+ fXScale = fYScale = comphelper::LibreOfficeKit::getDPIScale();
+ }
+ else
+ {
+ dl_cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
+ }
+
if (pBuffer)
{
- double fXScale, fYScale;
- if (comphelper::LibreOfficeKit::isActive())
- {
- // Force scaling of the painting
- fXScale = fYScale = comphelper::LibreOfficeKit::getDPIScale();
- }
- else
- {
- dl_cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
- nNewDX *= fXScale;
- nNewDY *= fYScale;
- }
+ nNewDX *= fXScale;
+ nNewDY *= fYScale;
m_pSurface = cairo_image_surface_create_for_data(pBuffer, CAIRO_FORMAT_ARGB32,
nNewDX, nNewDY, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nNewDX));
-
+ dl_cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
+ }
+ else if(nNewDX <= 32 && nNewDY <= 32)
+ {
+ nNewDX *= fXScale;
+ nNewDY *= fYScale;
+
+ // Force image-based surface if small. Small VirtualDevice instances are often used for small
+ // temporary bitmaps that will eventually have GetBitmap() called on them, which would cause
+ // X Server roundtrip with Xlib-based surface, which may be way more costly than doing the drawing
+ // in software (which should be fairly cheap for small surfaces anyway).
+ m_pSurface = cairo_surface_create_similar_image(m_pRefSurface, CAIRO_FORMAT_ARGB32, nNewDX, nNewDY);
dl_cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
}
else
{
m_pSurface = cairo_surface_create_similar(m_pRefSurface, CAIRO_CONTENT_COLOR_ALPHA, nNewDX, nNewDY);
+ // Device scale is inherited in this case.
}
}