diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index a84f42a067..3fad4bc6cf 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -507,6 +507,17 @@ protected: GrSurfaceDescFlags, GrMipMapped, bool forceNoPendingIO) const; + // Once the size of a fully-lazy proxy is decided, and before it gets instantiated, the client + // can use this optional method to specify the proxy's size. (A proxy's size can be less than + // the GPU surface that backs it. e.g., SkBackingFit::kApprox.) Otherwise, the proxy's size will + // be set to match the underlying GPU surface upon instantiation. + void setLazySize(int width, int height) { + SkASSERT(GrSurfaceProxy::LazyState::kFully == this->lazyInstantiationState()); + SkASSERT(width > 0 && height > 0); + fWidth = width; + fHeight = height; + } + bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, bool needsStencil, GrSurfaceDescFlags descFlags, GrMipMapped, const GrUniqueKey*, bool dontForceNoPendingIO); diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index a3a0cd1f10..8a947977d6 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -462,6 +462,9 @@ bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvide fProxy->fHeight = surface->height(); } + SkASSERT(fProxy->fWidth <= surface->width()); + SkASSERT(fProxy->fHeight <= surface->height()); + bool needsStencil = fProxy->asRenderTargetProxy() ? fProxy->asRenderTargetProxy()->needsStencil() : false; diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h index 462e9e21c1..7307083f9f 100644 --- a/src/gpu/GrSurfaceProxyPriv.h +++ b/src/gpu/GrSurfaceProxyPriv.h @@ -46,6 +46,8 @@ public: // Don't. Just don't. void exactify(); + void setLazySize(int width, int height) { fProxy->setLazySize(width, height); } + bool doLazyInstantiation(GrResourceProvider*); GrSurfaceProxy::LazyInstantiationType lazyInstantiationType() const { diff --git a/src/gpu/ccpr/GrCCAtlas.cpp b/src/gpu/ccpr/GrCCAtlas.cpp index c3c8ed6add..3cfb5d0a4d 100644 --- a/src/gpu/ccpr/GrCCAtlas.cpp +++ b/src/gpu/ccpr/GrCCAtlas.cpp @@ -189,6 +189,10 @@ sk_sp GrCCAtlas::makeRenderTargetContext( SkASSERT(SkTMax(fHeight, fWidth) <= fMaxTextureSize); SkASSERT(fMaxTextureSize <= onFlushRP->caps()->maxRenderTargetSize()); + // Finalize the content size of our proxy. The GPU can potentially make optimizations if it + // knows we only intend to write out a smaller sub-rectangle of the backing texture. + fTextureProxy->priv().setLazySize(fDrawBounds.width(), fDrawBounds.height()); + if (backingTexture) { SkASSERT(backingTexture->config() == kAlpha_half_GrPixelConfig); SkASSERT(backingTexture->width() == fWidth); diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp index 0c5002ee9d..698ae4eb60 100644 --- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp +++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp @@ -415,7 +415,11 @@ void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState, const SkRect& chainB for (const InstanceRange& range : fInstanceRanges) { SkASSERT(range.fEndInstanceIdx > baseInstance); - GrCCPathProcessor pathProc(range.fAtlasProxy, fViewMatrixIfUsingLocalCoords); + const GrTextureProxy* atlas = range.fAtlasProxy; + SkASSERT(atlas->isInstantiated()); + + GrCCPathProcessor pathProc( + atlas->peekTexture(), atlas->origin(), fViewMatrixIfUsingLocalCoords); GrTextureProxy* atlasProxy = range.fAtlasProxy; fixedDynamicState.fPrimitiveProcessorTextures = &atlasProxy; pathProc.drawPaths(flushState, pipeline, &fixedDynamicState, *resources, baseInstance, diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp index 5ea975556c..96d88a7166 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPathProcessor.cpp @@ -10,6 +10,7 @@ #include "include/gpu/GrTexture.h" #include "src/gpu/GrGpuCommandBuffer.h" #include "src/gpu/GrOnFlushResourceProvider.h" +#include "src/gpu/GrTexturePriv.h" #include "src/gpu/ccpr/GrCCPerFlushResources.h" #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" #include "src/gpu/glsl/GrGLSLGeometryProcessor.h" @@ -78,13 +79,13 @@ sk_sp GrCCPathProcessor::FindIndexBuffer(GrOnFlushResourcePro } } -GrCCPathProcessor::GrCCPathProcessor(const GrTextureProxy* atlas, +GrCCPathProcessor::GrCCPathProcessor(const GrTexture* atlasTexture, GrSurfaceOrigin atlasOrigin, const SkMatrix& viewMatrixIfUsingLocalCoords) : INHERITED(kGrCCPathProcessor_ClassID) - , fAtlasAccess(atlas->textureType(), atlas->config(), GrSamplerState::Filter::kNearest, - GrSamplerState::WrapMode::kClamp) - , fAtlasSize(atlas->isize()) - , fAtlasOrigin(atlas->origin()) { + , fAtlasAccess(atlasTexture->texturePriv().textureType(), atlasTexture->config(), + GrSamplerState::Filter::kNearest, GrSamplerState::WrapMode::kClamp) + , fAtlasSize(SkISize::Make(atlasTexture->width(), atlasTexture->height())) + , fAtlasOrigin(atlasOrigin) { // TODO: Can we just assert that atlas has GrCCAtlas::kTextureOrigin and remove fAtlasOrigin? this->setInstanceAttributes(kInstanceAttribs, SK_ARRAY_COUNT(kInstanceAttribs)); SkASSERT(this->instanceStride() == sizeof(Instance)); @@ -104,10 +105,10 @@ public: private: void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, FPCoordTransformIter&& transformIter) override { - const GrCCPathProcessor& proc = primProc.cast(); - pdman.set2f(fAtlasAdjustUniform, 1.0f / proc.atlasSize().fWidth, - 1.0f / proc.atlasSize().fHeight); - this->setTransformDataHelper(proc.localMatrix(), pdman, &transformIter); + const auto& proc = primProc.cast(); + pdman.set2f( + fAtlasAdjustUniform, 1.0f / proc.fAtlasSize.fWidth, 1.0f / proc.fAtlasSize.fHeight); + this->setTransformDataHelper(proc.fLocalMatrix, pdman, &transformIter); } GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform; @@ -198,17 +199,17 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // Convert to atlas coordinates in order to do our texture lookup. v->codeAppendf("float2 atlascoord = octocoord + float2(dev_to_atlas_offset);"); - if (kTopLeft_GrSurfaceOrigin == proc.atlasOrigin()) { + if (kTopLeft_GrSurfaceOrigin == proc.fAtlasOrigin) { v->codeAppendf("%s.xy = atlascoord * %s;", texcoord.vsOut(), atlasAdjust); } else { - SkASSERT(kBottomLeft_GrSurfaceOrigin == proc.atlasOrigin()); + SkASSERT(kBottomLeft_GrSurfaceOrigin == proc.fAtlasOrigin); v->codeAppendf("%s.xy = float2(atlascoord.x * %s.x, 1 - atlascoord.y * %s.y);", texcoord.vsOut(), atlasAdjust, atlasAdjust); } v->codeAppendf("%s.z = wind * .5;", texcoord.vsOut()); gpArgs->fPositionVar.set(kFloat2_GrSLType, "octocoord"); - this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, proc.localMatrix(), + this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, proc.fLocalMatrix, args.fFPCoordTransformHandler); // Fragment shader. diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h index 0e2a22d159..642cbdc9f1 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.h +++ b/src/gpu/ccpr/GrCCPathProcessor.h @@ -61,14 +61,10 @@ public: static sk_sp FindVertexBuffer(GrOnFlushResourceProvider*); static sk_sp FindIndexBuffer(GrOnFlushResourceProvider*); - GrCCPathProcessor(const GrTextureProxy* atlas, + GrCCPathProcessor(const GrTexture* atlasTexture, GrSurfaceOrigin atlasOrigin, const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I()); const char* name() const override { return "GrCCPathProcessor"; } - const SkISize& atlasSize() const { return fAtlasSize; } - GrSurfaceOrigin atlasOrigin() const { return fAtlasOrigin; } - const SkMatrix& localMatrix() const { return fLocalMatrix; } - void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp index ffec7fb886..567a77835f 100644 --- a/src/gpu/ccpr/GrCCPerFlushResources.cpp +++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp @@ -76,12 +76,15 @@ public: void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { SkASSERT(fSrcProxy); - GrPipeline::FixedDynamicState dynamicState; auto srcProxy = fSrcProxy.get(); - dynamicState.fPrimitiveProcessorTextures = &srcProxy; + SkASSERT(srcProxy->isInstantiated()); + + GrCCPathProcessor pathProc(srcProxy->peekTexture(), srcProxy->origin()); GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrc); - GrCCPathProcessor pathProc(srcProxy); + GrPipeline::FixedDynamicState dynamicState; + dynamicState.fPrimitiveProcessorTextures = &srcProxy; + pathProc.drawPaths(flushState, pipeline, &dynamicState, *fResources, fBaseInstance, fEndInstance, this->bounds()); }