ccpr: Set atlas proxy size to draw bounds rather than backing size

Bug: skia:
Change-Id: I6605754ecc5377b1c25847fdda478f8246979a2f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/209808
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Chris Dalton 2019-04-24 19:34:54 -04:00 committed by Skia Commit-Bot
parent f460eeec99
commit 46d0f9aad1
8 changed files with 45 additions and 21 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -189,6 +189,10 @@ sk_sp<GrRenderTargetContext> 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);

View File

@ -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,

View File

@ -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<const GrGpuBuffer> 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<GrCCPathProcessor>();
pdman.set2f(fAtlasAdjustUniform, 1.0f / proc.atlasSize().fWidth,
1.0f / proc.atlasSize().fHeight);
this->setTransformDataHelper(proc.localMatrix(), pdman, &transformIter);
const auto& proc = primProc.cast<GrCCPathProcessor>();
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.

View File

@ -61,14 +61,10 @@ public:
static sk_sp<const GrGpuBuffer> FindVertexBuffer(GrOnFlushResourceProvider*);
static sk_sp<const GrGpuBuffer> 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;

View File

@ -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());
}