summaryrefslogtreecommitdiff
path: root/drawinglayer
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 /drawinglayer
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 'drawinglayer')
-rw-r--r--drawinglayer/source/processor2d/vclhelperbufferdevice.cxx34
1 files changed, 27 insertions, 7 deletions
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 9129271bcb6b..7f20d094b446 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -63,6 +63,8 @@ private:
// virtualdevice because that isn't safe to do at least for Gtk2
std::map<VclPtr<VirtualDevice>, VclPtr<OutputDevice>> maDeviceTemplates;
+ static bool isSizeSuitable(const VclPtr<VirtualDevice>& device, const Size& size);
+
public:
VDevBuffer();
virtual ~VDevBuffer() override;
@@ -98,6 +100,28 @@ VDevBuffer::~VDevBuffer()
}
}
+bool VDevBuffer::isSizeSuitable(const VclPtr<VirtualDevice>& device, const Size& rSizePixel)
+{
+ if (device->GetOutputWidthPixel() >= rSizePixel.getWidth()
+ && device->GetOutputHeightPixel() >= rSizePixel.getHeight())
+ {
+#if defined(UNX)
+ // HACK: See the small size handling in SvpSalVirtualDevice::CreateSurface().
+ // Make sure to not reuse a larger device when a small one should be preferred.
+ if (device->GetRenderBackendName() == "svp")
+ {
+ if (rSizePixel.getWidth() <= 32 && rSizePixel.getHeight() <= 32
+ && (device->GetOutputWidthPixel() > 32 || device->GetOutputHeightPixel() > 32))
+ {
+ return false;
+ }
+ }
+#endif
+ return true;
+ }
+ return false;
+}
+
VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel,
bool bTransparent)
{
@@ -124,9 +148,7 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
if (bOkay)
{
// found is valid
- const bool bCandidateOkay(
- a->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && a->buf->GetOutputHeightPixel() >= rSizePixel.getHeight());
+ const bool bCandidateOkay = isSizeSuitable(a->buf, rSizePixel);
if (bCandidateOkay)
{
@@ -151,16 +173,14 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
{
// found is invalid, use candidate
aFound = a;
- bOkay = aFound->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && aFound->buf->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ bOkay = isSizeSuitable(aFound->buf, rSizePixel);
}
}
else
{
// none yet, use candidate
aFound = a;
- bOkay = aFound->buf->GetOutputWidthPixel() >= rSizePixel.getWidth()
- && aFound->buf->GetOutputHeightPixel() >= rSizePixel.getHeight();
+ bOkay = isSizeSuitable(aFound->buf, rSizePixel);
}
}
}