generic Skia workaround for VCL sending empty size (tdf#140288)

There have already been commits to handle this, but the case
of getting the wrong size the first was still broken (or was
fixed in the past and got broken again). Try to be generic
by forcing these to be always considered to be offscreen
and force non-zero size there.

Change-Id: Ie366a296f7f6645333630fa31e9fe18d54c7fba8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111528
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 64707e3..2eb2ffd 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -241,7 +241,7 @@
    void checkSurface();
    void destroySurface();
    // Reimplemented for X11.
    virtual bool avoidRecreateByResize() const { return false; }
    virtual bool avoidRecreateByResize() const;
    void createWindowSurface(bool forceRaster = false);
    virtual void createWindowContext(bool forceRaster = false) = 0;
    void createOffscreenSurface();
@@ -251,7 +251,7 @@

    void setProvider(SalGeometryProvider* provider) { mProvider = provider; }

    bool isOffscreen() const { return mProvider == nullptr || mProvider->IsOffScreen(); }
    bool isOffscreen() const;
    bool isGPU() const { return mIsGPU; }

    void invert(basegfx::B2DPolygon const& rPoly, SalInvert eFlags);
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 9500101..d8ddf48 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -334,14 +334,24 @@
#endif
}

bool SkiaSalGraphicsImpl::isOffscreen() const
{
    if (mProvider == nullptr || mProvider->IsOffScreen())
        return true;
    // HACK: Sometimes (tdf#131939, tdf#138022, tdf#140288) VCL passes us a zero-sized window,
    // and zero size is invalid for Skia, so force offscreen surface, where we handle this.
    if (GetWidth() <= 0 || GetHeight() <= 0)
        return true;
    return false;
}

void SkiaSalGraphicsImpl::createOffscreenSurface()
{
    SkiaZone zone;
    assert(isOffscreen());
    assert(!mSurface);
    assert(!mWindowContext);
    // When created (especially on Windows), Init() gets called with size (0,0), which is invalid size
    // for Skia. May happen also in rare cases such as shutting down (tdf#131939).
    // HACK: See isOffscreen().
    int width = std::max(1, GetWidth());
    int height = std::max(1, GetHeight());
    switch (SkiaHelper::renderMethodToUse())
@@ -460,17 +470,7 @@
    }
    else if (GetWidth() != mSurface->width() || GetHeight() != mSurface->height())
    {
        if (avoidRecreateByResize())
            return;

        if (!GetWidth() || !GetHeight())
        {
            SAL_WARN("vcl.skia", "recreate(" << this << "): can't create empty surface "
                                             << Size(GetWidth(), GetHeight())
                                             << " => keeping old one!");
            return;
        }

        if (!avoidRecreateByResize())
        {
            Size oldSize(mSurface->width(), mSurface->height());
            // Recreating a surface means that the old SkSurface contents will be lost.
@@ -503,6 +503,14 @@
    }
}

bool SkiaSalGraphicsImpl::avoidRecreateByResize() const
{
    // Keep the old surface if VCL sends us a broken size (see isOffscreen()).
    if (GetWidth() == 0 || GetHeight() == 0)
        return true;
    return false;
}

void SkiaSalGraphicsImpl::flushDrawing()
{
    if (!mSurface)
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 054555c..8467b1d 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -38,6 +38,7 @@
{
    SkiaZone zone;
    sk_app::DisplayParams displayParams;
    assert(GetWidth() > 0 && GetHeight() > 0);
    displayParams.fSurfaceProps = *SkiaHelper::surfaceProps();
    switch (forceRaster ? SkiaHelper::RenderRaster : SkiaHelper::renderMethodToUse())
    {
diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index 29fb15d..2ef186a 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -108,6 +108,8 @@

bool X11SkiaSalGraphicsImpl::avoidRecreateByResize() const
{
    if (SkiaSalGraphicsImpl::avoidRecreateByResize())
        return true;
    if (!mSurface || isOffscreen())
        return false;
    // Skia's WindowContext uses actual dimensions of the X window, which due to X11 being