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
This commit is contained in:
@@ -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/gpu \
|
||||||
-I$(call gb_UnpackedTarball_get_dir,skia)/include/config \
|
-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)/include/third_party/vulkan \
|
||||||
|
-I$(call gb_UnpackedTarball_get_dir,skia)/tools/gpu \
|
||||||
-I$(call gb_UnpackedTarball_get_dir,skia) \
|
-I$(call gb_UnpackedTarball_get_dir,skia) \
|
||||||
$$(INCLUDE) \
|
$$(INCLUDE) \
|
||||||
)
|
)
|
||||||
|
9
external/skia/Library_skia.mk
vendored
9
external/skia/Library_skia.mk
vendored
@@ -62,6 +62,7 @@ ifeq ($(OS),LINUX)
|
|||||||
$(eval $(call gb_Library_add_libs,skia,\
|
$(eval $(call gb_Library_add_libs,skia,\
|
||||||
-lm \
|
-lm \
|
||||||
-ldl \
|
-ldl \
|
||||||
|
-lGLU \
|
||||||
-lGLX \
|
-lGLX \
|
||||||
-lGL \
|
-lGL \
|
||||||
-lX11-xcb \
|
-lX11-xcb \
|
||||||
@@ -813,6 +814,12 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
|
|||||||
))
|
))
|
||||||
|
|
||||||
$(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/gpu/vk/VkTestUtils \
|
||||||
UnpackedTarball/skia/tools/sk_app/GLWindowContext \
|
UnpackedTarball/skia/tools/sk_app/GLWindowContext \
|
||||||
UnpackedTarball/skia/tools/sk_app/VulkanWindowContext \
|
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,\
|
$(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/GLWindowContext_win \
|
||||||
UnpackedTarball/skia/tools/sk_app/win/RasterWindowContext_win \
|
UnpackedTarball/skia/tools/sk_app/win/RasterWindowContext_win \
|
||||||
UnpackedTarball/skia/tools/sk_app/win/VulkanWindowContext_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,\
|
$(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/GLWindowContext_unix \
|
||||||
UnpackedTarball/skia/tools/sk_app/unix/RasterWindowContext_unix \
|
UnpackedTarball/skia/tools/sk_app/unix/RasterWindowContext_unix \
|
||||||
UnpackedTarball/skia/tools/sk_app/unix/VulkanWindowContext_unix \
|
UnpackedTarball/skia/tools/sk_app/unix/VulkanWindowContext_unix \
|
||||||
|
26
external/skia/make-api-visible.patch.1
vendored
26
external/skia/make-api-visible.patch.1
vendored
@@ -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
|
diff --git a/tools/sk_app/unix/WindowContextFactory_unix.h b/tools/sk_app/unix/WindowContextFactory_unix.h
|
||||||
index 47310970d5..e02e6eb5b7 100644
|
index 47310970d5..e02e6eb5b7 100644
|
||||||
--- a/tools/sk_app/unix/WindowContextFactory_unix.h
|
--- a/tools/sk_app/unix/WindowContextFactory_unix.h
|
||||||
|
@@ -586,7 +586,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
|
|||||||
vcl/skia/SkiaHelper \
|
vcl/skia/SkiaHelper \
|
||||||
$(if $(filter SKIA,$(BUILD_TYPE)), \
|
$(if $(filter SKIA,$(BUILD_TYPE)), \
|
||||||
vcl/skia/salbmp \
|
vcl/skia/salbmp \
|
||||||
vcl/skia/gdiimpl) \
|
vcl/skia/gdiimpl \
|
||||||
|
vcl/skia/vulkan) \
|
||||||
))
|
))
|
||||||
|
|
||||||
# runtime dependency
|
# runtime dependency
|
||||||
|
29
vcl/inc/skia/vulkan.hxx
Normal file
29
vcl/inc/skia/vulkan.hxx
Normal file
@@ -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: */
|
@@ -407,6 +407,8 @@ void SkiaSalGraphicsImpl::drawPixel(long nX, long nY, Color nColor)
|
|||||||
paint.setColor(toSkColor(nColor));
|
paint.setColor(toSkColor(nColor));
|
||||||
// Apparently drawPixel() is actually expected to set the pixel and not draw it.
|
// Apparently drawPixel() is actually expected to set the pixel and not draw it.
|
||||||
paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
|
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);
|
canvas->drawPoint(nX, nY, paint);
|
||||||
postDraw();
|
postDraw();
|
||||||
}
|
}
|
||||||
@@ -677,7 +679,6 @@ void SkiaSalGraphicsImpl::copyArea(long nDestX, long nDestY, long nSrcX, long nS
|
|||||||
<< Size(nSrcWidth, nSrcHeight));
|
<< Size(nSrcWidth, nSrcHeight));
|
||||||
sk_sp<SkImage> image
|
sk_sp<SkImage> image
|
||||||
= mSurface->makeImageSnapshot(SkIRect::MakeXYWH(nSrcX, nSrcY, nSrcWidth, nSrcHeight));
|
= mSurface->makeImageSnapshot(SkIRect::MakeXYWH(nSrcX, nSrcY, nSrcWidth, nSrcHeight));
|
||||||
// TODO makeNonTextureImage() ?
|
|
||||||
mSurface->getCanvas()->drawImage(image, nDestX, nDestY);
|
mSurface->getCanvas()->drawImage(image, nDestX, nDestY);
|
||||||
postDraw();
|
postDraw();
|
||||||
}
|
}
|
||||||
@@ -690,14 +691,18 @@ void SkiaSalGraphicsImpl::copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcG
|
|||||||
{
|
{
|
||||||
assert(dynamic_cast<SkiaSalGraphicsImpl*>(pSrcGraphics->GetImpl()));
|
assert(dynamic_cast<SkiaSalGraphicsImpl*>(pSrcGraphics->GetImpl()));
|
||||||
src = static_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
|
else
|
||||||
src = this;
|
src = this;
|
||||||
src->checkSurface();
|
|
||||||
SAL_INFO("vcl.skia", "copybits(" << this << "): (" << src << "):" << rPosAry);
|
SAL_INFO("vcl.skia", "copybits(" << this << "): (" << src << "):" << rPosAry);
|
||||||
sk_sp<SkImage> image = src->mSurface->makeImageSnapshot(
|
sk_sp<SkImage> image = src->mSurface->makeImageSnapshot(
|
||||||
SkIRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
|
SkIRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight));
|
||||||
// TODO makeNonTextureImage() ?
|
|
||||||
mSurface->getCanvas()->drawImageRect(image,
|
mSurface->getCanvas()->drawImageRect(image,
|
||||||
SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY,
|
SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY,
|
||||||
rPosAry.mnDestWidth,
|
rPosAry.mnDestWidth,
|
||||||
@@ -1055,7 +1060,8 @@ bool SkiaSalGraphicsImpl::supportsOperation(OutDevSupportType eType) const
|
|||||||
bool SkiaSalGraphicsImpl::isGPU() const
|
bool SkiaSalGraphicsImpl::isGPU() const
|
||||||
{
|
{
|
||||||
return mSurface.get()
|
return mSurface.get()
|
||||||
&& mSurface->getBackendRenderTarget(SkSurface::kFlushRead_BackendHandleAccess).isValid();
|
&& mSurface->getBackendRenderTarget(SkSurface::kFlushWrite_BackendHandleAccess)
|
||||||
|
.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DBG_UTIL
|
#ifdef DBG_UTIL
|
||||||
|
39
vcl/skia/vulkan.cxx
Normal file
39
vcl/skia/vulkan.cxx
Normal file
@@ -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: */
|
@@ -12,6 +12,7 @@
|
|||||||
#include <tools/sk_app/win/WindowContextFactory_win.h>
|
#include <tools/sk_app/win/WindowContextFactory_win.h>
|
||||||
#include <tools/sk_app/WindowContext.h>
|
#include <tools/sk_app/WindowContext.h>
|
||||||
#include <win/saldata.hxx>
|
#include <win/saldata.hxx>
|
||||||
|
#include <skia/vulkan.hxx>
|
||||||
|
|
||||||
#include <SkColorFilter.h>
|
#include <SkColorFilter.h>
|
||||||
#include <SkPixelRef.h>
|
#include <SkPixelRef.h>
|
||||||
@@ -44,14 +45,30 @@ void WinSkiaSalGraphicsImpl::Init()
|
|||||||
|
|
||||||
void WinSkiaSalGraphicsImpl::createSurface()
|
void WinSkiaSalGraphicsImpl::createSurface()
|
||||||
{
|
{
|
||||||
|
destroySurface();
|
||||||
if (isOffscreen())
|
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();
|
return SkiaSalGraphicsImpl::createSurface();
|
||||||
|
}
|
||||||
// When created, Init() gets called with size (0,0), which is invalid size
|
// 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
|
// for Skia. Creating the actual surface is delayed, so the size should be always
|
||||||
// valid here, but better check.
|
// valid here, but better check.
|
||||||
assert(GetWidth() != 0 && GetHeight() != 0);
|
assert(GetWidth() != 0 && GetHeight() != 0);
|
||||||
sk_app::DisplayParams displayParams;
|
sk_app::DisplayParams displayParams;
|
||||||
destroySurface();
|
|
||||||
switch (renderMethodToUse())
|
switch (renderMethodToUse())
|
||||||
{
|
{
|
||||||
case RenderRaster:
|
case RenderRaster:
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
#include <tools/sk_app/unix/WindowContextFactory_unix.h>
|
#include <tools/sk_app/unix/WindowContextFactory_unix.h>
|
||||||
#include <tools/sk_app/WindowContext.h>
|
#include <tools/sk_app/WindowContext.h>
|
||||||
|
|
||||||
|
#include <skia/vulkan.hxx>
|
||||||
|
|
||||||
X11SkiaSalGraphicsImpl::X11SkiaSalGraphicsImpl(X11SalGraphics& rParent)
|
X11SkiaSalGraphicsImpl::X11SkiaSalGraphicsImpl(X11SalGraphics& rParent)
|
||||||
: SkiaSalGraphicsImpl(rParent, rParent.GetGeometryProvider())
|
: SkiaSalGraphicsImpl(rParent, rParent.GetGeometryProvider())
|
||||||
, mX11Parent(rParent)
|
, mX11Parent(rParent)
|
||||||
@@ -38,8 +40,25 @@ void X11SkiaSalGraphicsImpl::Init()
|
|||||||
|
|
||||||
void X11SkiaSalGraphicsImpl::createSurface()
|
void X11SkiaSalGraphicsImpl::createSurface()
|
||||||
{
|
{
|
||||||
|
destroySurface();
|
||||||
if (isOffscreen())
|
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();
|
return SkiaSalGraphicsImpl::createSurface();
|
||||||
|
}
|
||||||
sk_app::DisplayParams displayParams;
|
sk_app::DisplayParams displayParams;
|
||||||
// TODO The Skia Xlib code actually requires the non-native color type to work properly.
|
// TODO The Skia Xlib code actually requires the non-native color type to work properly.
|
||||||
// Use a macro to hide an unreachable code warning.
|
// Use a macro to hide an unreachable code warning.
|
||||||
@@ -59,7 +78,6 @@ void X11SkiaSalGraphicsImpl::createSurface()
|
|||||||
// Avoid this somehow.
|
// Avoid this somehow.
|
||||||
winInfo.fWidth = GetWidth();
|
winInfo.fWidth = GetWidth();
|
||||||
winInfo.fHeight = GetHeight();
|
winInfo.fHeight = GetHeight();
|
||||||
destroySurface();
|
|
||||||
switch (renderMethodToUse())
|
switch (renderMethodToUse())
|
||||||
{
|
{
|
||||||
case RenderRaster:
|
case RenderRaster:
|
||||||
|
Reference in New Issue
Block a user