diff options
Diffstat (limited to 'vcl/skia')
-rw-r--r-- | vcl/skia/SkiaHelper.cxx | 37 | ||||
-rw-r--r-- | vcl/skia/win/gdiimpl.cxx | 2 | ||||
-rw-r--r-- | vcl/skia/x11/gdiimpl.cxx | 49 |
3 files changed, 71 insertions, 17 deletions
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx index 4b21e6740603..ff2a2a588741 100644 --- a/vcl/skia/SkiaHelper.cxx +++ b/vcl/skia/SkiaHelper.cxx @@ -69,6 +69,8 @@ static bool isVulkanBlacklisted(const VkPhysicalDeviceProperties& props) deviceIdStr); } +static sk_app::VulkanWindowContext::SharedGrContext getTemporaryGrContext(); + static void checkDeviceBlacklisted(bool blockDisable = false) { static bool done = false; @@ -80,9 +82,23 @@ static void checkDeviceBlacklisted(bool blockDisable = false) { case RenderVulkan: { - GrContext* grContext = SkiaHelper::getSharedGrContext(); + // First try if a GrContext already exists. + sk_app::VulkanWindowContext::SharedGrContext grContext + = sk_app::VulkanWindowContext::getSharedGrContext(); + if (!grContext.getGrContext()) + { + // This function is called from isVclSkiaEnabled(), which + // may be called when deciding which X11 visual to use, + // and that visual is normally needed when creating + // Skia's VulkanWindowContext, which is needed for the GrContext. + // Avoid the loop by creating a temporary GrContext + // that will use the default X11 visual (that shouldn't matter + // for just finding out information about Vulkan) and destroying + // the temporary context will clean up again. + grContext = getTemporaryGrContext(); + } bool blacklisted = true; // assume the worst - if (grContext) // Vulkan was initialized properly + if (grContext.getGrContext()) // Vulkan was initialized properly { blacklisted = isVulkanBlacklisted( sk_app::VulkanWindowContext::getPhysDeviceProperties()); @@ -230,8 +246,8 @@ void disableRenderMethod(RenderMethod method) static sk_app::VulkanWindowContext::SharedGrContext* sharedGrContext; -static std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContextFunction)() = nullptr; -static void setCreateVulkanWindowContext(std::unique_ptr<sk_app::WindowContext> (*function)()) +static std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContextFunction)(bool) = nullptr; +static void setCreateVulkanWindowContext(std::unique_ptr<sk_app::WindowContext> (*function)(bool)) { createVulkanWindowContextFunction = function; } @@ -259,7 +275,7 @@ GrContext* getSharedGrContext() done = true; if (createVulkanWindowContextFunction == nullptr) return nullptr; // not initialized properly (e.g. used from a VCL backend with no Skia support) - std::unique_ptr<sk_app::WindowContext> tmpContext = createVulkanWindowContextFunction(); + std::unique_ptr<sk_app::WindowContext> tmpContext = createVulkanWindowContextFunction(false); // Set up using the shared context created by the call above, if successful. context = sk_app::VulkanWindowContext::getSharedGrContext(); grContext = context.getGrContext(); @@ -272,6 +288,15 @@ GrContext* getSharedGrContext() return nullptr; } +static sk_app::VulkanWindowContext::SharedGrContext getTemporaryGrContext() +{ + if (createVulkanWindowContextFunction == nullptr) + return sk_app::VulkanWindowContext::SharedGrContext(); + std::unique_ptr<sk_app::WindowContext> tmpContext = createVulkanWindowContextFunction(true); + // Set up using the shared context created by the call above, if successful. + return sk_app::VulkanWindowContext::getSharedGrContext(); +} + sk_sp<SkSurface> createSkSurface(int width, int height, SkColorType type) { SkiaZone zone; @@ -315,7 +340,7 @@ void cleanup() // Skia should not be used from VCL backends that do not actually support it, as there will be setup missing. // The code here (that is in the vcl lib) needs a function for creating Vulkan context that is // usually available only in the backend libs. -void prepareSkia(std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContext)()) +void prepareSkia(std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContext)(bool)) { setCreateVulkanWindowContext(createVulkanWindowContext); skiaSupportedByBackend = true; diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index 0708c8ea633f..221819ca1c4f 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -349,7 +349,7 @@ SkiaControlCacheType& SkiaControlsCache::get() namespace { -std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext() +std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext(bool /*temporary*/) { SkiaZone zone; sk_app::DisplayParams displayParams; diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx index fe4553814758..0ed4b6a0ccbd 100644 --- a/vcl/skia/x11/gdiimpl.cxx +++ b/vcl/skia/x11/gdiimpl.cxx @@ -23,6 +23,8 @@ #include <skia/utils.hxx> #include <skia/zone.hxx> +#include <X11/Xutil.h> + X11SkiaSalGraphicsImpl::X11SkiaSalGraphicsImpl(X11SalGraphics& rParent) : SkiaSalGraphicsImpl(rParent, rParent.GetGeometryProvider()) , mX11Parent(rParent) @@ -43,7 +45,7 @@ void X11SkiaSalGraphicsImpl::createWindowContext() assert(mX11Parent.GetDrawable() != None); mWindowContext = createWindowContext(mX11Parent.GetXDisplay(), mX11Parent.GetDrawable(), &mX11Parent.GetVisual(), GetWidth(), GetHeight(), - SkiaHelper::renderMethodToUse()); + SkiaHelper::renderMethodToUse(), false); if (mWindowContext && SkiaHelper::renderMethodToUse() == SkiaHelper::RenderVulkan) mIsGPU = true; else @@ -52,8 +54,8 @@ void X11SkiaSalGraphicsImpl::createWindowContext() std::unique_ptr<sk_app::WindowContext> X11SkiaSalGraphicsImpl::createWindowContext(Display* display, Drawable drawable, - const SalVisual* visual, int width, int height, - SkiaHelper::RenderMethod renderMethod) + const XVisualInfo* visual, int width, int height, + SkiaHelper::RenderMethod renderMethod, bool temporary) { SkiaZone zone; sk_app::DisplayParams displayParams; @@ -63,15 +65,24 @@ X11SkiaSalGraphicsImpl::createWindowContext(Display* display, Drawable drawable, winInfo.fDisplay = display; winInfo.fWindow = drawable; winInfo.fFBConfig = nullptr; // not used - winInfo.fVisualInfo = const_cast<SalVisual*>(visual); + winInfo.fVisualInfo = const_cast<XVisualInfo*>(visual); + assert(winInfo.fVisualInfo->visual != nullptr); // make sure it's not an uninitialized SalVisual winInfo.fWidth = width; winInfo.fHeight = height; #ifdef DBG_UTIL // Our patched Skia has VulkanWindowContext that shares GrContext, which requires // that the X11 visual is always the same. Ensure it is so. static VisualID checkVisualID = -1U; - assert(checkVisualID == -1U || winInfo.fVisualInfo->visualid == checkVisualID); - checkVisualID = winInfo.fVisualInfo->visualid; + // Exception is for the temporary case during startup, when SkiaHelper's + // checkDeviceBlacklisted() needs a WindowContext and may be called before SalVisual + // is ready. + if (!temporary) + { + assert(checkVisualID == -1U || winInfo.fVisualInfo->visualid == checkVisualID); + checkVisualID = winInfo.fVisualInfo->visualid; + } +#else + (void)temporary; #endif switch (renderMethod) { @@ -122,12 +133,30 @@ void X11SkiaSalGraphicsImpl::performFlush() mWindowContext->swapBuffers(); } -std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext() +std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext(bool temporary) { SalDisplay* salDisplay = vcl_sal::getSalDisplay(GetGenericUnixSalData()); - return X11SkiaSalGraphicsImpl::createWindowContext( - salDisplay->GetDisplay(), None, &salDisplay->GetVisual(salDisplay->GetDefaultXScreen()), 1, - 1, SkiaHelper::RenderVulkan); + const XVisualInfo* visual; + XVisualInfo* visuals = nullptr; + if (!temporary) + visual = &salDisplay->GetVisual(salDisplay->GetDefaultXScreen()); + else + { + // SalVisual from salDisplay may not be setup yet at this point, get + // info for the default visual. + XVisualInfo search; + search.visualid = XVisualIDFromVisual( + DefaultVisual(salDisplay->GetDisplay(), salDisplay->GetDefaultXScreen().getXScreen())); + int count; + visuals = XGetVisualInfo(salDisplay->GetDisplay(), VisualIDMask, &search, &count); + assert(count == 1); + visual = visuals; + } + std::unique_ptr<sk_app::WindowContext> ret = X11SkiaSalGraphicsImpl::createWindowContext( + salDisplay->GetDisplay(), None, visual, 1, 1, SkiaHelper::RenderVulkan, temporary); + if (temporary) + XFree(visuals); + return ret; } void X11SkiaSalGraphicsImpl::prepareSkia() { SkiaHelper::prepareSkia(createVulkanWindowContext); } |