diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 9b4a98af1d..e6291a3296 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -88,6 +88,7 @@ '<(skia_src_path)/gpu/GrClipMaskManager.cpp', '<(skia_src_path)/gpu/GrColorSpaceXform.cpp', '<(skia_src_path)/gpu/GrContext.cpp', + '<(skia_src_path)/gpu/GrContextPriv.h', '<(skia_src_path)/gpu/GrCoordTransform.cpp', '<(skia_src_path)/gpu/GrDefaultGeoProcFactory.cpp', '<(skia_src_path)/gpu/GrDefaultGeoProcFactory.h', diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 667301e61d..2a7c1383a0 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -24,6 +24,7 @@ struct GrBatchAtlasConfig; class GrBatchFontCache; struct GrContextOptions; +class GrContextPriv; class GrContextThreadSafeProxy; class GrDrawingManager; class GrDrawContext; @@ -179,19 +180,6 @@ public: */ int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; - /** - * Returns a helper object to orchestrate draws. - * Callers assume the creation ref of the drawContext - * NULL will be returned if the context has been abandoned. - * - * @param rt the render target receiving the draws - * @param surfaceProps the surface properties (mainly defines text drawing) - * - * @return a draw context - */ - sk_sp makeDrawContext(sk_sp rt, sk_sp colorSpace, - const SkSurfaceProps* = nullptr); - /** * Create both a GrRenderTarget and a matching GrDrawContext to wrap it. * We guarantee that "asTexture" will succeed for drawContexts created @@ -379,6 +367,10 @@ public: /** This is only useful for debug purposes */ SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } ) + // Provides access to functions that aren't part of the public API. + GrContextPriv contextPriv(); + const GrContextPriv contextPriv() const; + private: GrGpu* fGpu; const GrCaps* fCaps; @@ -434,6 +426,7 @@ private: // TODO: have the CMM use drawContexts and rm this friending friend class GrClipMaskManager; // the CMM is friended just so it can call 'drawingManager' friend class GrDrawingManager; // for access to drawingManager for ProgramUnitTest + friend class GrContextPriv; GrDrawingManager* drawingManager() { return fDrawingManager; } GrContext(); // init must be called after the constructor. diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 078cfbdb2c..94ad9644bc 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -6,6 +6,7 @@ */ #include "GrContext.h" +#include "GrContextPriv.h" #include "GrContextOptions.h" #include "GrDrawingManager.h" #include "GrDrawContext.h" @@ -25,6 +26,8 @@ #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) #define ASSERT_SINGLE_OWNER \ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);) +#define ASSERT_SINGLE_OWNER_PRIV \ + SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fContext->fSingleOwner);) #define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; } #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; } #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; } @@ -360,7 +363,9 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, // TODO: Need to decide the semantics of this function for color spaces. Do we support // conversion from a passed-in color space? For now, specifying nullptr means that this // path will do no conversion, so it will match the behavior of the non-draw path. - sk_sp drawContext(this->makeDrawContext(sk_ref_sp(renderTarget), nullptr)); + sk_sp drawContext(this->contextPriv().makeWrappedDrawContext( + sk_ref_sp(renderTarget), + nullptr)); if (!drawContext) { return false; } @@ -568,7 +573,9 @@ bool GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe src->flushWrites(); return fGpu->copySurface(dst, src, clippedSrcRect, clippedDstPoint); } - sk_sp drawContext(this->makeDrawContext(sk_ref_sp(dst->asRenderTarget()), nullptr)); + sk_sp drawContext(this->contextPriv().makeWrappedDrawContext( + sk_ref_sp(dst->asRenderTarget()), + nullptr)); if (!drawContext) { return false; } @@ -606,12 +613,59 @@ int GrContext::getRecommendedSampleCount(GrPixelConfig config, return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? chosenSampleCount : 0; } +sk_sp GrContextPriv::makeWrappedDrawContext(sk_sp rt, + sk_sp colorSpace, + const SkSurfaceProps* surfaceProps) { + ASSERT_SINGLE_OWNER_PRIV + return fContext->drawingManager()->drawContext(std::move(rt), std::move(colorSpace), + surfaceProps); +} -sk_sp GrContext::makeDrawContext(sk_sp rt, - sk_sp colorSpace, - const SkSurfaceProps* surfaceProps) { - ASSERT_SINGLE_OWNER - return fDrawingManager->drawContext(std::move(rt), std::move(colorSpace), surfaceProps); +sk_sp GrContextPriv::makeBackendTextureDrawContext(const GrBackendTextureDesc& desc, + sk_sp colorSpace, + const SkSurfaceProps* props, + GrWrapOwnership ownership) { + ASSERT_SINGLE_OWNER_PRIV + SkASSERT(desc.fFlags & kRenderTarget_GrBackendTextureFlag); + + sk_sp surface(fContext->textureProvider()->wrapBackendTexture(desc, ownership)); + if (!surface) { + return nullptr; + } + + return fContext->drawingManager()->drawContext(sk_ref_sp(surface->asRenderTarget()), + std::move(colorSpace), props); +} + +sk_sp GrContextPriv::makeBackendRenderTargetDrawContext( + const GrBackendRenderTargetDesc& desc, + sk_sp colorSpace, + const SkSurfaceProps* surfaceProps) { + ASSERT_SINGLE_OWNER_PRIV + + sk_sp rt(fContext->textureProvider()->wrapBackendRenderTarget(desc)); + if (!rt) { + return nullptr; + } + + return fContext->drawingManager()->drawContext(std::move(rt), std::move(colorSpace), + surfaceProps); +} + +sk_sp GrContextPriv::makeBackendTextureAsRenderTargetDrawContext( + const GrBackendTextureDesc& desc, + sk_sp colorSpace, + const SkSurfaceProps* surfaceProps) { + ASSERT_SINGLE_OWNER_PRIV + SkASSERT(desc.fFlags & kRenderTarget_GrBackendTextureFlag); + + sk_sp surface(fContext->resourceProvider()->wrapBackendTextureAsRenderTarget(desc)); + if (!surface) { + return nullptr; + } + + return fContext->drawingManager()->drawContext(sk_ref_sp(surface->asRenderTarget()), + std::move(colorSpace), surfaceProps); } sk_sp GrContext::makeDrawContext(SkBackingFit fit, @@ -640,7 +694,8 @@ sk_sp GrContext::makeDrawContext(SkBackingFit fit, return nullptr; } - sk_sp drawContext(this->makeDrawContext(sk_ref_sp(tex->asRenderTarget()), + sk_sp drawContext(this->contextPriv().makeWrappedDrawContext( + sk_ref_sp(tex->asRenderTarget()), std::move(colorSpace), surfaceProps)); if (!drawContext) { return nullptr; diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h new file mode 100644 index 0000000000..8646e25d49 --- /dev/null +++ b/src/gpu/GrContextPriv.h @@ -0,0 +1,57 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrContextPriv_DEFINED +#define GrContextPriv_DEFINED + +#include "GrContext.h" + +/** Class that adds methods to GrContext that are only intended for use internal to Skia. + This class is purely a privileged window into GrContext. It should never have additional + data members or virtual methods. */ +class GrContextPriv { +public: + // Create a drawContext that wraps an existing renderTarget + sk_sp makeWrappedDrawContext(sk_sp rt, + sk_sp colorSpace, + const SkSurfaceProps* = nullptr); + + sk_sp makeBackendTextureDrawContext(const GrBackendTextureDesc& desc, + sk_sp colorSpace, + const SkSurfaceProps* = nullptr, + GrWrapOwnership = kBorrow_GrWrapOwnership); + + sk_sp makeBackendRenderTargetDrawContext(const GrBackendRenderTargetDesc& desc, + sk_sp colorSpace, + const SkSurfaceProps* = nullptr); + + sk_sp makeBackendTextureAsRenderTargetDrawContext( + const GrBackendTextureDesc& desc, + sk_sp colorSpace, + const SkSurfaceProps* = nullptr); + +private: + explicit GrContextPriv(GrContext* context) : fContext(context) {} + GrContextPriv(const GrContextPriv&) {} // unimpl + GrContextPriv& operator=(const GrContextPriv&); // unimpl + + // No taking addresses of this type. + const GrContextPriv* operator&() const; + GrContextPriv* operator&(); + + GrContext* fContext; + + friend class GrContext; // to construct/copy this type. +}; + +inline GrContextPriv GrContext::contextPriv() { return GrContextPriv(this); } + +inline const GrContextPriv GrContext::contextPriv () const { + return GrContextPriv(const_cast(this)); +} + +#endif diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp index cccf9534f6..a0700a095f 100644 --- a/src/gpu/GrRenderTarget.cpp +++ b/src/gpu/GrRenderTarget.cpp @@ -9,6 +9,7 @@ #include "GrRenderTarget.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "GrDrawContext.h" #include "GrDrawTarget.h" #include "GrGpu.h" @@ -29,7 +30,8 @@ void GrRenderTarget::discard() { return; } - sk_sp drawContext(context->makeDrawContext(sk_ref_sp(this), nullptr)); + sk_sp drawContext(context->contextPriv().makeWrappedDrawContext(sk_ref_sp(this), + nullptr)); if (!drawContext) { return; } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 7271819269..82038f6232 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -9,6 +9,7 @@ #include "GrBlurUtils.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "SkDraw.h" #include "GrGpu.h" #include "GrGpuResourcePriv.h" @@ -104,8 +105,10 @@ sk_sp SkGpuDevice::Make(sk_sp rt, sk_spgetContext(); - sk_sp drawContext(context->makeDrawContext(std::move(rt), std::move(colorSpace), - props)); + sk_sp drawContext(context->contextPriv().makeWrappedDrawContext( + std::move(rt), + std::move(colorSpace), + props)); return sk_sp(new SkGpuDevice(std::move(drawContext), width, height, flags)); } diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp index 2dbb888425..a21b5a2f63 100644 --- a/tests/RectangleTextureTest.cpp +++ b/tests/RectangleTextureTest.cpp @@ -8,6 +8,7 @@ #include "Test.h" #if SK_SUPPORT_GPU #include "GrContext.h" +#include "GrContextPriv.h" #include "GrDrawContext.h" #include "gl/GrGLGpu.h" #include "gl/GrGLUtil.h" @@ -89,9 +90,9 @@ static void test_copy_surface_dst(skiatest::Reporter* reporter, GrContext* conte static void test_clear(skiatest::Reporter* reporter, GrContext* context, GrTexture* rectangleTexture) { if (rectangleTexture->asRenderTarget()) { - sk_sp dc( - context->makeDrawContext(sk_ref_sp(rectangleTexture->asRenderTarget()), - nullptr)); + sk_sp dc(context->contextPriv().makeWrappedDrawContext( + sk_ref_sp(rectangleTexture->asRenderTarget()), + nullptr)); if (!dc) { ERRORF(reporter, "Could not get GrDrawContext for rectangle texture."); return;