diff --git a/gn/gpu.gni b/gn/gpu.gni index 0e805b34f3..47106aa8f5 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -15,6 +15,7 @@ skia_gpu_sources = [ "$_include/gpu/GrConfig.h", "$_include/gpu/GrContextOptions.h", "$_include/gpu/GrContext.h", + "$_include/gpu/GrContextThreadSafeProxy.h", "$_include/gpu/GrDriverBugWorkarounds.h", "$_include/gpu/GrGpuResource.h", "$_include/gpu/GrRenderTarget.h", @@ -71,6 +72,7 @@ skia_gpu_sources = [ "$_src/gpu/GrColorSpaceXform.h", "$_src/gpu/GrContext.cpp", "$_src/gpu/GrContextPriv.h", + "$_src/gpu/GrContextThreadSafeProxy.cpp", "$_src/gpu/GrContextThreadSafeProxyPriv.h", "$_src/gpu/GrCoordTransform.h", "$_src/gpu/GrDDLContext.cpp", diff --git a/include/core/SkSurfaceCharacterization.h b/include/core/SkSurfaceCharacterization.h index 8f4c0a3270..9955cd1884 100644 --- a/include/core/SkSurfaceCharacterization.h +++ b/include/core/SkSurfaceCharacterization.h @@ -17,7 +17,7 @@ class SkColorSpace; #if SK_SUPPORT_GPU -#include "GrContext.h" +#include "GrContextThreadSafeProxy.h" /** \class SkSurfaceCharacterization A surface characterization contains all the information Ganesh requires to makes its internal diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 3b83873eb5..54564ae2e3 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -13,7 +13,6 @@ #include "SkTypes.h" #include "../private/GrAuditTrail.h" #include "../private/GrSingleOwner.h" -#include "../private/GrSkSLFPFactoryCache.h" #include "GrContextOptions.h" // We shouldn't need this but currently Android is relying on this being include transitively. @@ -25,7 +24,6 @@ class GrBackendSemaphore; class GrCaps; class GrContextPriv; class GrContextThreadSafeProxy; -class GrContextThreadSafeProxyPriv; class GrDrawingManager; class GrFragmentProcessor; struct GrGLInterface; @@ -39,6 +37,7 @@ class GrRenderTargetContext; class GrResourceCache; class GrResourceProvider; class GrSamplerState; +class GrSkSLFPFactoryCache; class GrSurfaceProxy; class GrSwizzle; class GrTextBlobCache; @@ -47,7 +46,6 @@ class GrTextureProxy; struct GrVkBackendContext; class SkImage; -class SkSurfaceCharacterization; class SkSurfaceProps; class SkTaskGroup; class SkTraceMemoryDump; @@ -359,83 +357,4 @@ private: typedef SkRefCnt INHERITED; }; -/** - * Can be used to perform actions related to the generating GrContext in a thread safe manner. The - * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext. - */ -class SK_API GrContextThreadSafeProxy : public SkRefCnt { -public: - ~GrContextThreadSafeProxy(); - - bool matches(GrContext* context) const { return context->uniqueID() == fContextUniqueID; } - - /** - * Create a surface characterization for a DDL that will be replayed into the GrContext - * that created this proxy. On failure the resulting characterization will be invalid (i.e., - * "!c.isValid()"). - * - * @param cacheMaxResourceBytes The max resource bytes limit that will be in effect when the - * DDL created with this characterization is replayed. - * Note: the contract here is that the DDL will be created as - * if it had a full 'cacheMaxResourceBytes' to use. If replayed - * into a GrContext that already has locked GPU memory, the - * replay can exceed the budget. To rephrase, all resource - * allocation decisions are made at record time and at playback - * time the budget limits will be ignored. - * @param ii The image info specifying properties of the SkSurface that - * the DDL created with this characterization will be replayed - * into. - * Note: Ganesh doesn't make use of the SkImageInfo's alphaType - * @param backendFormat Information about the format of the GPU surface that will - * back the SkSurface upon replay - * @param sampleCount The sample count of the SkSurface that the DDL created with - * this characterization will be replayed into - * @param origin The origin of the SkSurface that the DDL created with this - * characterization will be replayed into - * @param surfaceProps The surface properties of the SkSurface that the DDL created - * with this characterization will be replayed into - * @param isMipMapped Will the surface the DDL will be replayed into have space - * allocated for mipmaps? - * @param willUseGLFBO0 Will the surface the DDL will be replayed into be backed by GL - * FBO 0. This flag is only valid if using an GL backend. - */ - SkSurfaceCharacterization createCharacterization( - size_t cacheMaxResourceBytes, - const SkImageInfo& ii, const GrBackendFormat& backendFormat, - int sampleCount, GrSurfaceOrigin origin, - const SkSurfaceProps& surfaceProps, - bool isMipMapped, bool willUseGLFBO0 = false); - - bool operator==(const GrContextThreadSafeProxy& that) const { - // Each GrContext should only ever have a single thread-safe proxy. - SkASSERT((this == &that) == (fContextUniqueID == that.fContextUniqueID)); - return this == &that; - } - - bool operator!=(const GrContextThreadSafeProxy& that) const { return !(*this == that); } - - // Provides access to functions that aren't part of the public API. - GrContextThreadSafeProxyPriv priv(); - const GrContextThreadSafeProxyPriv priv() const; - -private: - // DDL TODO: need to add unit tests for backend & maybe options - GrContextThreadSafeProxy(sk_sp caps, - uint32_t uniqueID, - GrBackendApi backend, - const GrContextOptions& options, - sk_sp cache); - - sk_sp fCaps; - const uint32_t fContextUniqueID; - const GrBackendApi fBackend; - const GrContextOptions fOptions; - sk_sp fFPFactoryCache; - - friend class GrDirectContext; // To construct this object - friend class GrContextThreadSafeProxyPriv; - - typedef SkRefCnt INHERITED; -}; - #endif diff --git a/include/gpu/GrContextThreadSafeProxy.h b/include/gpu/GrContextThreadSafeProxy.h new file mode 100644 index 0000000000..7a67843bb0 --- /dev/null +++ b/include/gpu/GrContextThreadSafeProxy.h @@ -0,0 +1,101 @@ +/* + * Copyright 2019 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrContextThreadSafeProxy_DEFINED +#define GrContextThreadSafeProxy_DEFINED + +#include "GrContextOptions.h" +#include "SkRefCnt.h" + +class GrBackendFormat; +class GrCaps; +class GrContext; +class GrContextThreadSafeProxyPriv; +class GrSkSLFPFactoryCache; +struct SkImageInfo; +class SkSurfaceCharacterization; + +/** + * Can be used to perform actions related to the generating GrContext in a thread safe manner. The + * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext. + */ +class SK_API GrContextThreadSafeProxy : public SkRefCnt { +public: + ~GrContextThreadSafeProxy() override; + + bool matches(GrContext* context) const; + + /** + * Create a surface characterization for a DDL that will be replayed into the GrContext + * that created this proxy. On failure the resulting characterization will be invalid (i.e., + * "!c.isValid()"). + * + * @param cacheMaxResourceBytes The max resource bytes limit that will be in effect when the + * DDL created with this characterization is replayed. + * Note: the contract here is that the DDL will be created as + * if it had a full 'cacheMaxResourceBytes' to use. If replayed + * into a GrContext that already has locked GPU memory, the + * replay can exceed the budget. To rephrase, all resource + * allocation decisions are made at record time and at playback + * time the budget limits will be ignored. + * @param ii The image info specifying properties of the SkSurface that + * the DDL created with this characterization will be replayed + * into. + * Note: Ganesh doesn't make use of the SkImageInfo's alphaType + * @param backendFormat Information about the format of the GPU surface that will + * back the SkSurface upon replay + * @param sampleCount The sample count of the SkSurface that the DDL created with + * this characterization will be replayed into + * @param origin The origin of the SkSurface that the DDL created with this + * characterization will be replayed into + * @param surfaceProps The surface properties of the SkSurface that the DDL created + * with this characterization will be replayed into + * @param isMipMapped Will the surface the DDL will be replayed into have space + * allocated for mipmaps? + * @param willUseGLFBO0 Will the surface the DDL will be replayed into be backed by GL + * FBO 0. This flag is only valid if using an GL backend. + */ + SkSurfaceCharacterization createCharacterization( + size_t cacheMaxResourceBytes, + const SkImageInfo& ii, const GrBackendFormat& backendFormat, + int sampleCount, GrSurfaceOrigin origin, + const SkSurfaceProps& surfaceProps, + bool isMipMapped, bool willUseGLFBO0 = false); + + bool operator==(const GrContextThreadSafeProxy& that) const { + // Each GrContext should only ever have a single thread-safe proxy. + SkASSERT((this == &that) == (fContextUniqueID == that.fContextUniqueID)); + return this == &that; + } + + bool operator!=(const GrContextThreadSafeProxy& that) const { return !(*this == that); } + + // Provides access to functions that aren't part of the public API. + GrContextThreadSafeProxyPriv priv(); + const GrContextThreadSafeProxyPriv priv() const; + +private: + // DDL TODO: need to add unit tests for backend & maybe options + GrContextThreadSafeProxy(sk_sp caps, + uint32_t uniqueID, + GrBackendApi backend, + const GrContextOptions& options, + sk_sp cache); + + sk_sp fCaps; + const uint32_t fContextUniqueID; + const GrBackendApi fBackend; + const GrContextOptions fOptions; + sk_sp fFPFactoryCache; + + friend class GrDirectContext; // To construct this object + friend class GrContextThreadSafeProxyPriv; + + typedef SkRefCnt INHERITED; +}; + +#endif diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index d122a4d891..657b7dac70 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -169,76 +169,6 @@ GrContext::~GrContext() { ////////////////////////////////////////////////////////////////////////////// -GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp caps, uint32_t uniqueID, - GrBackendApi backend, - const GrContextOptions& options, - sk_sp cache) - : fCaps(std::move(caps)) - , fContextUniqueID(uniqueID) - , fBackend(backend) - , fOptions(options) - , fFPFactoryCache(std::move(cache)) {} - -GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default; - -sk_sp GrContext::threadSafeProxy() { - return fThreadSafeProxy; -} - -SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( - size_t cacheMaxResourceBytes, - const SkImageInfo& ii, const GrBackendFormat& backendFormat, - int sampleCnt, GrSurfaceOrigin origin, - const SkSurfaceProps& surfaceProps, - bool isMipMapped, bool willUseGLFBO0) { - if (!backendFormat.isValid()) { - return SkSurfaceCharacterization(); // return an invalid characterization - } - - if (GrBackendApi::kOpenGL != backendFormat.backend() && willUseGLFBO0) { - // The willUseGLFBO0 flags can only be used for a GL backend. - return SkSurfaceCharacterization(); // return an invalid characterization - } - - if (!fCaps->mipMapSupport()) { - isMipMapped = false; - } - - GrPixelConfig config = fCaps->getConfigFromBackendFormat(backendFormat, ii.colorType()); - if (config == kUnknown_GrPixelConfig) { - return SkSurfaceCharacterization(); // return an invalid characterization - } - - if (!SkSurface_Gpu::Valid(fCaps.get(), config, ii.colorSpace())) { - return SkSurfaceCharacterization(); // return an invalid characterization - } - - sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, config); - if (!sampleCnt) { - return SkSurfaceCharacterization(); // return an invalid characterization - } - - GrFSAAType FSAAType = GrFSAAType::kNone; - if (sampleCnt > 1) { - FSAAType = fCaps->usesMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA; - } - - // This surface characterization factory assumes that the resulting characterization is - // textureable. - if (!fCaps->isConfigTexturable(config)) { - return SkSurfaceCharacterization(); // return an invalid characterization - } - - return SkSurfaceCharacterization(sk_ref_sp(this), - cacheMaxResourceBytes, ii, - origin, config, FSAAType, sampleCnt, - SkSurfaceCharacterization::Textureable(true), - SkSurfaceCharacterization::MipMapped(isMipMapped), - SkSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0), - SkSurfaceCharacterization::VulkanSecondaryCBCompatible(false), - surfaceProps); -} - void GrContext::abandonContext() { ASSERT_SINGLE_OWNER @@ -1140,6 +1070,8 @@ sk_sp GrContextPriv::makeDeferredRenderTargetContext( return renderTargetContext; } +sk_sp GrContextPriv::getFPFactoryCache() { return fContext->fFPFactoryCache; } + std::unique_ptr GrContext::createPMToUPMEffect( std::unique_ptr fp) { ASSERT_SINGLE_OWNER diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 468a599b8b..24309ec99b 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -279,9 +279,7 @@ public: GrContextOptions::PersistentCache* getPersistentCache() { return fContext->fPersistentCache; } - sk_sp getFPFactoryCache() { - return fContext->fFPFactoryCache; - } + sk_sp getFPFactoryCache(); /** This is only useful for debug purposes */ SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fContext->fSingleOwner; } ) diff --git a/src/gpu/GrContextThreadSafeProxy.cpp b/src/gpu/GrContextThreadSafeProxy.cpp new file mode 100644 index 0000000000..cfa4b33f9f --- /dev/null +++ b/src/gpu/GrContextThreadSafeProxy.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2019 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrContextThreadSafeProxy.h" +#include "GrContextThreadSafeProxyPriv.h" + +#include "GrCaps.h" +#include "GrContext.h" +#include "GrSkSLFPFactoryCache.h" +#include "SkSurface_Gpu.h" +#include "SkSurfaceCharacterization.h" + +GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp caps, uint32_t uniqueID, + GrBackendApi backend, + const GrContextOptions& options, + sk_sp cache) + : fCaps(std::move(caps)) + , fContextUniqueID(uniqueID) + , fBackend(backend) + , fOptions(options) + , fFPFactoryCache(std::move(cache)) {} + +GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default; + +sk_sp GrContext::threadSafeProxy() { + return fThreadSafeProxy; +} + +bool GrContextThreadSafeProxy::matches(GrContext* context) const { + return context->uniqueID() == fContextUniqueID; +} + +SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization( + size_t cacheMaxResourceBytes, + const SkImageInfo& ii, const GrBackendFormat& backendFormat, + int sampleCnt, GrSurfaceOrigin origin, + const SkSurfaceProps& surfaceProps, + bool isMipMapped, bool willUseGLFBO0) { + if (!backendFormat.isValid()) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + if (GrBackendApi::kOpenGL != backendFormat.backend() && willUseGLFBO0) { + // The willUseGLFBO0 flags can only be used for a GL backend. + return SkSurfaceCharacterization(); // return an invalid characterization + } + + if (!fCaps->mipMapSupport()) { + isMipMapped = false; + } + + GrPixelConfig config = fCaps->getConfigFromBackendFormat(backendFormat, ii.colorType()); + if (config == kUnknown_GrPixelConfig) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + if (!SkSurface_Gpu::Valid(fCaps.get(), config, ii.colorSpace())) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, config); + if (!sampleCnt) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + GrFSAAType FSAAType = GrFSAAType::kNone; + if (sampleCnt > 1) { + FSAAType = fCaps->usesMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA; + } + + // This surface characterization factory assumes that the resulting characterization is + // textureable. + if (!fCaps->isConfigTexturable(config)) { + return SkSurfaceCharacterization(); // return an invalid characterization + } + + return SkSurfaceCharacterization(sk_ref_sp(this), + cacheMaxResourceBytes, ii, + origin, config, FSAAType, sampleCnt, + SkSurfaceCharacterization::Textureable(true), + SkSurfaceCharacterization::MipMapped(isMipMapped), + SkSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0), + SkSurfaceCharacterization::VulkanSecondaryCBCompatible(false), + surfaceProps); +} + +//////////////////////////////////////////////////////////////////////////////// +sk_sp GrContextThreadSafeProxyPriv::fpFactoryCache() const { + return fProxy->fFPFactoryCache; +} diff --git a/src/gpu/GrContextThreadSafeProxyPriv.h b/src/gpu/GrContextThreadSafeProxyPriv.h index 1d251e46c3..298ad783cf 100644 --- a/src/gpu/GrContextThreadSafeProxyPriv.h +++ b/src/gpu/GrContextThreadSafeProxyPriv.h @@ -8,7 +8,7 @@ #ifndef GrContextThreadSafeProxyPriv_DEFINED #define GrContextThreadSafeProxyPriv_DEFINED -#include "GrContext.h" +#include "GrContextThreadSafeProxy.h" /** * Class that adds methods to GrContextThreadSafeProxy that are only intended for use internal to @@ -23,7 +23,7 @@ public: sk_sp refCaps() const { return fProxy->fCaps; } uint32_t contextUniqueID() const { return fProxy->fContextUniqueID; } GrBackendApi backend() const { return fProxy->fBackend; } - sk_sp fpFactoryCache() const { return fProxy->fFPFactoryCache; } + sk_sp fpFactoryCache() const; private: explicit GrContextThreadSafeProxyPriv(GrContextThreadSafeProxy* proxy) : fProxy(proxy) {} diff --git a/src/gpu/GrDDLContext.cpp b/src/gpu/GrDDLContext.cpp index eb5ed29e6b..5461bd98f1 100644 --- a/src/gpu/GrDDLContext.cpp +++ b/src/gpu/GrDDLContext.cpp @@ -9,6 +9,7 @@ #include "GrCaps.h" #include "GrContextPriv.h" #include "GrContextThreadSafeProxyPriv.h" +#include "GrSkSLFPFactoryCache.h" /** * The DDL Context is the one in effect during DDL Recording. It isn't backed by a GrGPU and diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp index c46d84e909..9e6075c436 100644 --- a/src/gpu/GrDirectContext.cpp +++ b/src/gpu/GrDirectContext.cpp @@ -9,6 +9,7 @@ #include "GrContext.h" #include "GrContextPriv.h" +#include "GrContextThreadSafeProxy.h" #include "GrGpu.h" #include "effects/GrSkSLFP.h" diff --git a/src/image/SkImage_GpuBase.h b/src/image/SkImage_GpuBase.h index 37d3b22024..cd7b906845 100644 --- a/src/image/SkImage_GpuBase.h +++ b/src/image/SkImage_GpuBase.h @@ -9,12 +9,12 @@ #define SkImage_GpuBase_DEFINED #include "GrBackendSurface.h" +#include "GrContext.h" #include "GrTypesPriv.h" #include "SkDeferredDisplayListRecorder.h" #include "SkImage_Base.h" #include "SkYUVAIndex.h" -class GrContext; class SkColorSpace; class SkImage_GpuBase : public SkImage_Base { diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index 907adfa499..01975004b1 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -33,6 +33,7 @@ #include "sk_tool_utils.h" #include "GrContextPriv.h" +#include "GrContextThreadSafeProxy.h" #include "GrGpu.h" #include "GrResourceCache.h" #include "GrTexture.h"