From fe3b51636d4216c4ea6cb74ed0964c1d315ca487 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Thu, 2 Mar 2017 15:09:20 -0500 Subject: [PATCH] Use GrSemaphore rather than GrFence for external texture data BUG=skia: Change-Id: I0d23eb9dcf5c01c71d3571ef97690af68b900807 Reviewed-on: https://skia-review.googlesource.com/9141 Commit-Queue: Brian Osman Reviewed-by: Greg Daniel Reviewed-by: Brian Salomon --- gn/gpu.gni | 1 + include/gpu/GrContext.h | 6 ------ include/gpu/GrExternalTextureData.h | 10 ++++------ include/gpu/gl/GrGLTypes.h | 9 ++++++--- include/gpu/vk/GrVkTypes.h | 7 ++++--- src/gpu/GrContext.cpp | 7 ------- src/gpu/GrSemaphore.h | 4 +++- src/gpu/gl/GrGLExternalTextureData.cpp | 24 ++++++++++++++++++++++++ src/gpu/gl/GrGLTexture.cpp | 12 +++++++++--- src/image/SkImage_Gpu.cpp | 5 ++--- 10 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 src/gpu/gl/GrGLExternalTextureData.cpp diff --git a/gn/gpu.gni b/gn/gpu.gni index 100288f..e57a919 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -385,6 +385,7 @@ skia_gpu_sources = [ "$_src/gpu/gl/GrGLGpuCommandBuffer.h", "$_src/gpu/gl/GrGLGpuProgramCache.cpp", "$_src/gpu/gl/GrGLExtensions.cpp", + "$_src/gpu/gl/GrGLExternalTextureData.cpp", "$_src/gpu/gl/GrGLInterface.cpp", "$_src/gpu/gl/GrGLIRect.h", "$_src/gpu/gl/GrGLPath.cpp", diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 285525f..702fdb6 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -325,12 +325,6 @@ public: void prepareSurfaceForExternalIO(GrSurface*); /** - * As above, but additionally flushes the backend API (eg calls glFlush), and returns a fence - * that can be used to determine if the surface is safe to use on another context or thread. - */ - GrFence SK_WARN_UNUSED_RESULT prepareSurfaceForExternalIOAndFlush(GrSurface*); - - /** * An ID associated with this context, guaranteed to be unique. */ uint32_t uniqueID() { return fUniqueID; } diff --git a/include/gpu/GrExternalTextureData.h b/include/gpu/GrExternalTextureData.h index 9ab819c..5943fd8 100644 --- a/include/gpu/GrExternalTextureData.h +++ b/include/gpu/GrExternalTextureData.h @@ -10,21 +10,19 @@ #define GrExternalTextureData_DEFINED #include "GrTypes.h" -#include "GrTypesPriv.h" + +class GrContext; class SK_API GrExternalTextureData : SkNoncopyable { public: - GrExternalTextureData(GrFence fence) : fFence(fence) {} virtual ~GrExternalTextureData() {} virtual GrBackend getBackend() const = 0; - GrFence getFence() const { return fFence; } - protected: virtual GrBackendObject getBackendObject() const = 0; - - GrFence fFence; + virtual void attachToContext(GrContext*) = 0; friend class SkCrossContextImageData; + friend class SkImage; }; #endif diff --git a/include/gpu/gl/GrGLTypes.h b/include/gpu/gl/GrGLTypes.h index d03363c..baf87a4 100644 --- a/include/gpu/gl/GrGLTypes.h +++ b/include/gpu/gl/GrGLTypes.h @@ -11,6 +11,7 @@ #include "GrExternalTextureData.h" #include "GrGLConfig.h" +#include "SkRefCnt.h" /** * Classifies GL contexts by which standard they implement (currently as OpenGL vs. OpenGL ES). @@ -113,19 +114,21 @@ struct GrGLTextureInfo { GrGLuint fID; }; +class GrSemaphore; + class GrGLExternalTextureData : public GrExternalTextureData { public: - GrGLExternalTextureData(const GrGLTextureInfo& info, GrFence fence) - : INHERITED(fence) - , fInfo(info) {} + GrGLExternalTextureData(const GrGLTextureInfo& info, sk_sp semaphore); GrBackend getBackend() const override { return kOpenGL_GrBackend; } protected: GrBackendObject getBackendObject() const override { return reinterpret_cast(&fInfo); } + void attachToContext(GrContext*) override; GrGLTextureInfo fInfo; + sk_sp fSemaphore; typedef GrExternalTextureData INHERITED; }; diff --git a/include/gpu/vk/GrVkTypes.h b/include/gpu/vk/GrVkTypes.h index e9a3121..c98a94a 100644 --- a/include/gpu/vk/GrVkTypes.h +++ b/include/gpu/vk/GrVkTypes.h @@ -62,15 +62,16 @@ struct GrVkImageInfo { class GrVkExternalTextureData : public GrExternalTextureData { public: - GrVkExternalTextureData(const GrVkImageInfo& info, GrFence fence) - : INHERITED(fence) - , fInfo(info) {} + GrVkExternalTextureData(const GrVkImageInfo& info) : fInfo(info) {} GrBackend getBackend() const override { return kVulkan_GrBackend; } protected: GrBackendObject getBackendObject() const override { return reinterpret_cast(&fInfo); } + void attachToContext(GrContext*) override { + // TODO: Implement this + } GrVkImageInfo fInfo; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 97b525d..7dfee00 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -546,13 +546,6 @@ void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) { fDrawingManager->prepareSurfaceForExternalIO(surface); } -GrFence GrContext::prepareSurfaceForExternalIOAndFlush(GrSurface* surface) { - this->prepareSurfaceForExternalIO(surface); - GrFence fence = fGpu->insertFence(); - fGpu->flush(); - return fence; -} - void GrContext::flushSurfaceWrites(GrSurface* surface) { ASSERT_SINGLE_OWNER RETURN_IF_ABANDONED diff --git a/src/gpu/GrSemaphore.h b/src/gpu/GrSemaphore.h index bdeff09..717b4bb 100644 --- a/src/gpu/GrSemaphore.h +++ b/src/gpu/GrSemaphore.h @@ -13,7 +13,7 @@ class GrGpu; class GrSemaphore : public SkRefCnt { -public: +private: // This function should only be used in the case of exporting and importing a GrSemaphore object // from one GrContext to another. When exporting, the GrSemaphore should be set to a null GrGpu, // and when importing it should be set to the GrGpu of the current context. Once exported, a @@ -23,6 +23,8 @@ public: protected: explicit GrSemaphore(const GrGpu* gpu) : fGpu(gpu) {} + friend class GrGLExternalTextureData; // resetGpu + const GrGpu* fGpu; }; diff --git a/src/gpu/gl/GrGLExternalTextureData.cpp b/src/gpu/gl/GrGLExternalTextureData.cpp new file mode 100644 index 0000000..32c49b1 --- /dev/null +++ b/src/gpu/gl/GrGLExternalTextureData.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrContext.h" +#include "GrGpu.h" +#include "GrSemaphore.h" +#include "gl/GrGLTypes.h" + +GrGLExternalTextureData::GrGLExternalTextureData(const GrGLTextureInfo& info, + sk_sp semaphore) + : fInfo(info) + , fSemaphore(std::move(semaphore)) { + SkASSERT(fSemaphore->unique()); + fSemaphore->resetGpu(nullptr); +} + +void GrGLExternalTextureData::attachToContext(GrContext* context) { + fSemaphore->resetGpu(context->getGpu()); + context->getGpu()->waitSemaphore(fSemaphore); +} diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp index a560988..ee029bc 100644 --- a/src/gpu/gl/GrGLTexture.cpp +++ b/src/gpu/gl/GrGLTexture.cpp @@ -8,6 +8,7 @@ #include "GrContext.h" #include "GrGLTexture.h" #include "GrGLGpu.h" +#include "GrSemaphore.h" #include "GrShaderCaps.h" #include "SkMakeUnique.h" #include "SkTraceMemoryDump.h" @@ -114,11 +115,16 @@ GrBackendObject GrGLTexture::getTextureHandle() const { } std::unique_ptr GrGLTexture::detachBackendTexture() { - // Flush any pending writes to this texture, as well GL itself - GrFence fence = this->getContext()->prepareSurfaceForExternalIOAndFlush(this); + // Flush any pending writes to this texture + this->getContext()->prepareSurfaceForExternalIO(this); + + // Set up a semaphore to be signaled once the data is ready, and flush GL + sk_sp semaphore = this->getGpu()->makeSemaphore(); + this->getGpu()->insertSemaphore(semaphore); + this->getGpu()->flush(); // Make a copy of our GL-specific information - auto data = skstd::make_unique(fInfo, fence); + auto data = skstd::make_unique(fInfo, std::move(semaphore)); // Ensure the cache can't reach this texture anymore this->detachFromCache(); diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 88d1889..37a9193 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -17,6 +17,7 @@ #include "GrGpu.h" #include "GrImageTextureMaker.h" #include "GrRenderTargetContext.h" +#include "GrSemaphore.h" #include "GrTextureAdjuster.h" #include "GrTexturePriv.h" #include "GrTextureProvider.h" @@ -429,9 +430,7 @@ sk_sp SkImage::MakeFromCrossContextImageData( } if (ccid->fTextureData) { - GrFence fence = ccid->fTextureData->getFence(); - context->getGpu()->waitFence(fence); - context->getGpu()->deleteFence(fence); + ccid->fTextureData->attachToContext(context); } return MakeFromAdoptedTexture(context, ccid->fDesc, ccid->fAlphaType, -- 2.7.4