summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-11-06 16:14:50 +0100
committerLuboš Luňák <l.lunak@collabora.com>2019-11-27 09:55:16 +0100
commit54be644c092eebb8be57a251556fe3f0e5f99e57 (patch)
tree812d0e907d51ed41ba3441a4e9e427311eb29ed7
parent76ee0452b82f69f273526ba8a8c879ce17acb547 (diff)
make SkiaSalGraphicsImpl use GPU-backed SkSurface also for offscreen
Skia's sk_app::WindowContext can create GPU-backed SkSurface only for windows, but we also use virtual devices that are not windows. Fortunately, SkSurface can be created GPU-backed from GrContext* and sk_gpu_test::GrContextFactory seems to provide it easily. It is not completely clear to me what the rules are on mixing SkSurface's with different GrContext* (see the comment in SkiaSalGraphicsImpl::copyBits()), but it seems to work fine. Change-Id: I8110b67c41ab092e0c4b6a0973d6bed8a408c4c1
-rw-r--r--RepositoryExternal.mk1
-rw-r--r--external/skia/Library_skia.mk9
-rw-r--r--external/skia/make-api-visible.patch.126
-rw-r--r--vcl/Library_vcl.mk3
-rw-r--r--vcl/inc/skia/vulkan.hxx29
-rw-r--r--vcl/skia/gdiimpl.cxx14
-rw-r--r--vcl/skia/vulkan.cxx39
-rw-r--r--vcl/skia/win/gdiimpl.cxx19
-rw-r--r--vcl/skia/x11/gdiimpl.cxx20
9 files changed, 153 insertions, 7 deletions
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 91be30307dd7..6cf31f5c17ab 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -119,6 +119,7 @@ $(call gb_LinkTarget_set_include,$(1),\
-I$(call gb_UnpackedTarball_get_dir,skia)/include/gpu \
-I$(call gb_UnpackedTarball_get_dir,skia)/include/config \
-I$(call gb_UnpackedTarball_get_dir,skia)/include/third_party/vulkan \
+ -I$(call gb_UnpackedTarball_get_dir,skia)/tools/gpu \
-I$(call gb_UnpackedTarball_get_dir,skia) \
$$(INCLUDE) \
)
diff --git a/external/skia/Library_skia.mk b/external/skia/Library_skia.mk
index ed24d30fa93f..7d84762a621d 100644
--- a/external/skia/Library_skia.mk
+++ b/external/skia/Library_skia.mk
@@ -62,6 +62,7 @@ ifeq ($(OS),LINUX)
$(eval $(call gb_Library_add_libs,skia,\
-lm \
-ldl \
+ -lGLU \
-lGLX \
-lGL \
-lX11-xcb \
@@ -813,6 +814,12 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
))
$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/gpu/GrContextFactory \
+ UnpackedTarball/skia/tools/gpu/TestContext \
+ UnpackedTarball/skia/tools/gpu/gl/GLTestContext \
+ UnpackedTarball/skia/tools/gpu/gl/command_buffer/GLTestContext_command_buffer \
+ UnpackedTarball/skia/tools/gpu/mock/MockTestContext \
+ UnpackedTarball/skia/tools/gpu/vk/VkTestContext \
UnpackedTarball/skia/tools/gpu/vk/VkTestUtils \
UnpackedTarball/skia/tools/sk_app/GLWindowContext \
UnpackedTarball/skia/tools/sk_app/VulkanWindowContext \
@@ -841,6 +848,7 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
))
$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/gpu/gl/win/CreatePlatformGLTestContext_win \
UnpackedTarball/skia/tools/sk_app/win/GLWindowContext_win \
UnpackedTarball/skia/tools/sk_app/win/RasterWindowContext_win \
UnpackedTarball/skia/tools/sk_app/win/VulkanWindowContext_win \
@@ -863,6 +871,7 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
))
$(eval $(call gb_Library_add_generated_exception_objects,skia,\
+ UnpackedTarball/skia/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx \
UnpackedTarball/skia/tools/sk_app/unix/GLWindowContext_unix \
UnpackedTarball/skia/tools/sk_app/unix/RasterWindowContext_unix \
UnpackedTarball/skia/tools/sk_app/unix/VulkanWindowContext_unix \
diff --git a/external/skia/make-api-visible.patch.1 b/external/skia/make-api-visible.patch.1
index 2bf3a0f3d73a..3c2ff873eabb 100644
--- a/external/skia/make-api-visible.patch.1
+++ b/external/skia/make-api-visible.patch.1
@@ -1,3 +1,29 @@
+diff --git a/tools/gpu/GrContextFactory.h b/tools/gpu/GrContextFactory.h
+index d1b7fd5fa0..1b0bc249d2 100644
+--- a/tools/gpu/GrContextFactory.h
++++ b/tools/gpu/GrContextFactory.h
+@@ -26,7 +26,7 @@ class ContextInfo;
+ * factory is destroyed (though the caller can always grab a ref on the returned
+ * Gr and GL contexts to make them outlive the factory).
+ */
+-class GrContextFactory : SkNoncopyable {
++class SK_API GrContextFactory : SkNoncopyable {
+ public:
+ // The availability of context types is subject to platform and build configuration
+ // restrictions.
+diff --git a/tools/gpu/gl/GLTestContext.cpp b/tools/gpu/gl/GLTestContext.cpp
+index d4aa605188..5d246f9737 100644
+--- a/tools/gpu/gl/GLTestContext.cpp
++++ b/tools/gpu/gl/GLTestContext.cpp
+@@ -298,7 +298,7 @@ void GLTestContext::teardown() {
+ void GLTestContext::testAbandon() {
+ INHERITED::testAbandon();
+ if (fGL) {
+- fGL->abandon();
++// fGL->abandon();
+ }
+ }
+
diff --git a/tools/sk_app/unix/WindowContextFactory_unix.h b/tools/sk_app/unix/WindowContextFactory_unix.h
index 47310970d5..e02e6eb5b7 100644
--- a/tools/sk_app/unix/WindowContextFactory_unix.h
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index c054a2767a3c..1f05f7aa9dd2 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -586,7 +586,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/skia/SkiaHelper \
$(if $(filter SKIA,$(BUILD_TYPE)), \
vcl/skia/salbmp \
- vcl/skia/gdiimpl) \
+ vcl/skia/gdiimpl \
+ vcl/skia/vulkan) \
))
# runtime dependency
diff --git a/vcl/inc/skia/vulkan.hxx b/vcl/inc/skia/vulkan.hxx
new file mode 100644
index 000000000000..6c8e3c7bfa44
--- /dev/null
+++ b/vcl/inc/skia/vulkan.hxx
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_SKIA_VULKAN_HXX
+#define INCLUDED_VCL_INC_SKIA_VULKAN_HXX
+
+#include <GrContext.h>
+
+#include <vcl/dllapi.h>
+
+// Create and handle GrContext for Vulkan drawing to offscreen surfaces.
+// Skia already provides WindowContext class that does this for surfaces
+// used for drawing to windows, but it does not seem to provide a simple
+// way to get GrContext without a window.
+class VCL_PLUGIN_PUBLIC SkiaVulkanGrContext
+{
+public:
+ static GrContext* getGrContext();
+};
+
+#endif // INCLUDED_VCL_INC_SKIA_VULKAN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index f505e7778d64..612e097b6e12 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -407,6 +407,8 @@ void SkiaSalGraphicsImpl::drawPixel(long nX, long nY, Color nColor)
paint.setColor(toSkColor(nColor));
// Apparently drawPixel() is actually expected to set the pixel and not draw it.
paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
+ if (isGPU()) // TODO this may need caching?
+ ++nX; // https://bugs.chromium.org/p/skia/issues/detail?id=9611
canvas->drawPoint(nX, nY, paint);
postDraw();
}
@@ -677,7 +679,6 @@ void SkiaSalGraphicsImpl::copyArea(long nDestX, long nDestY, long nSrcX, long nS
<< Size(nSrcWidth, nSrcHeight));
sk_sp<SkImage> image
= mSurface->makeImageSnapshot(SkIRect::MakeXYWH(nSrcX, nSrcY, nSrcWidth, nSrcHeight));
- // TODO makeNonTextureImage() ?
mSurface->getCanvas()->drawImage(image, nDestX, nDestY);
postDraw();
}
@@ -690,14 +691,18 @@ void SkiaSalGraphicsImpl::copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcG
{
assert(dynamic_cast<SkiaSalGraphicsImpl*>(pSrcGraphics->GetImpl()));
src = static_cast<SkiaSalGraphicsImpl*>(pSrcGraphics->GetImpl());
+ src->checkSurface();
+ // TODO Without this flush() Skia asserts if both src and destination are
+ // GPU-backed SkSurface that come from different GrContext (e.g. when
+ // src comes from SkiaVulkanGrContext and target is a window). I don't
+ // know if it's a Skia bug or our GrContext usage is incorrect.
+ src->mSurface->flush();
}
else
src = this;
- src->checkSurface();
SAL_INFO("vcl.skia", "copybits(" << this << "): (" << src << "):" << rPosAry);
sk_sp<SkImage> image = src->mSurface->makeImageSnapshot(
SkIRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
- // TODO makeNonTextureImage() ?
mSurface->getCanvas()->drawImageRect(image,
SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY,
rPosAry.mnDestWidth,
@@ -1055,7 +1060,8 @@ bool SkiaSalGraphicsImpl::supportsOperation(OutDevSupportType eType) const
bool SkiaSalGraphicsImpl::isGPU() const
{
return mSurface.get()
- && mSurface->getBackendRenderTarget(SkSurface::kFlushRead_BackendHandleAccess).isValid();
+ && mSurface->getBackendRenderTarget(SkSurface::kFlushWrite_BackendHandleAccess)
+ .isValid();
}
#ifdef DBG_UTIL
diff --git a/vcl/skia/vulkan.cxx b/vcl/skia/vulkan.cxx
new file mode 100644
index 000000000000..c5c9093739fc
--- /dev/null
+++ b/vcl/skia/vulkan.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * Some of this code is based on Skia source code, covered by the following
+ * license notice (see readlicense_oo for the full license):
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ */
+
+#include <skia/vulkan.hxx>
+
+#include <GrContextFactory.h>
+
+#include <vcl/lazydelete.hxx>
+
+static GrContext* createGrContext()
+{
+ static vcl::DeleteOnDeinit<sk_gpu_test::GrContextFactory> factory(
+ new sk_gpu_test::GrContextFactory);
+ // The factory owns the context.
+ return factory.get()->get(sk_gpu_test::GrContextFactory::kVulkan_ContextType);
+}
+
+GrContext* SkiaVulkanGrContext::getGrContext()
+{
+ static GrContext* context = createGrContext();
+ return context;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index d54120d5ffce..f908ace261a3 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -12,6 +12,7 @@
#include <tools/sk_app/win/WindowContextFactory_win.h>
#include <tools/sk_app/WindowContext.h>
#include <win/saldata.hxx>
+#include <skia/vulkan.hxx>
#include <SkColorFilter.h>
#include <SkPixelRef.h>
@@ -44,14 +45,30 @@ void WinSkiaSalGraphicsImpl::Init()
void WinSkiaSalGraphicsImpl::createSurface()
{
+ destroySurface();
if (isOffscreen())
+ {
+ switch (renderMethodToUse())
+ {
+ case RenderVulkan:
+ mSurface = SkSurface::MakeRenderTarget(
+ SkiaVulkanGrContext::getGrContext(), SkBudgeted::kNo,
+ SkImageInfo::MakeN32Premul(GetWidth(), GetHeight()));
+ assert(mSurface.get());
+#ifdef DBG_UTIL
+ prefillSurface();
+#endif
+ return;
+ default:
+ break;
+ }
return SkiaSalGraphicsImpl::createSurface();
+ }
// When created, Init() gets called with size (0,0), which is invalid size
// for Skia. Creating the actual surface is delayed, so the size should be always
// valid here, but better check.
assert(GetWidth() != 0 && GetHeight() != 0);
sk_app::DisplayParams displayParams;
- destroySurface();
switch (renderMethodToUse())
{
case RenderRaster:
diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index fff94936a33d..af602d35bede 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -21,6 +21,8 @@
#include <tools/sk_app/unix/WindowContextFactory_unix.h>
#include <tools/sk_app/WindowContext.h>
+#include <skia/vulkan.hxx>
+
X11SkiaSalGraphicsImpl::X11SkiaSalGraphicsImpl(X11SalGraphics& rParent)
: SkiaSalGraphicsImpl(rParent, rParent.GetGeometryProvider())
, mX11Parent(rParent)
@@ -38,8 +40,25 @@ void X11SkiaSalGraphicsImpl::Init()
void X11SkiaSalGraphicsImpl::createSurface()
{
+ destroySurface();
if (isOffscreen())
+ {
+ switch (renderMethodToUse())
+ {
+ case RenderVulkan:
+ mSurface = SkSurface::MakeRenderTarget(
+ SkiaVulkanGrContext::getGrContext(), SkBudgeted::kNo,
+ SkImageInfo::MakeN32Premul(GetWidth(), GetHeight()));
+ assert(mSurface.get());
+#ifdef DBG_UTIL
+ prefillSurface();
+#endif
+ return;
+ default:
+ break;
+ }
return SkiaSalGraphicsImpl::createSurface();
+ }
sk_app::DisplayParams displayParams;
// TODO The Skia Xlib code actually requires the non-native color type to work properly.
// Use a macro to hide an unreachable code warning.
@@ -59,7 +78,6 @@ void X11SkiaSalGraphicsImpl::createSurface()
// Avoid this somehow.
winInfo.fWidth = GetWidth();
winInfo.fHeight = GetHeight();
- destroySurface();
switch (renderMethodToUse())
{
case RenderRaster: