Consolidate Proxy caching code in GrResourceProvider

This doesn't implement the GrSurfaceProxy-based caching but just carves out a space for it.

Split out of: https://skia-review.googlesource.com/c/8823/ (Remove GrFragmentProcessor-derived class' GrTexture-based ctors)

Change-Id: Iec87b45e3264b349d7804f63e361e970b925e335
Reviewed-on: https://skia-review.googlesource.com/9626
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2017-03-14 09:17:43 -04:00 committed by Skia Commit-Bot
parent 4a01ac9e41
commit d3749485db
19 changed files with 216 additions and 156 deletions

View File

@ -115,7 +115,7 @@ public:
* Try to directly render the mask filter into the target. Returns true if drawing was
* successful. If false is returned then paint is unmodified.
*/
virtual bool directFilterMaskGPU(GrResourceProvider* resourceProvider,
virtual bool directFilterMaskGPU(GrContext*,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,
const GrClip&,

View File

@ -180,9 +180,7 @@ public:
const GrSurfaceDesc&, SkBudgeted,
const void* srcData, size_t rowBytes);
static sk_sp<GrSurfaceProxy> MakeWrappedBackend(
GrContext*,
GrBackendTextureDesc&);
static sk_sp<GrSurfaceProxy> MakeWrappedBackend(GrContext*, GrBackendTextureDesc&);
const GrSurfaceDesc& desc() const { return fDesc; }

View File

@ -493,6 +493,15 @@ static GrTexture* set_key_and_return(GrResourceProvider* resourceProvider,
return tex;
}
#if 0
static void set_key_on_proxy(GrResourceProvider* resourceProvider,
GrTextureProxy* proxy, const GrUniqueKey& key) {
if (key.isValid()) {
resourceProvider->assignUniqueKeyToProxy(key, proxy);
}
}
#endif
sk_sp<SkColorSpace> SkImageCacherator::getColorSpace(GrContext* ctx, SkColorSpace* dstColorSpace) {
// TODO: This isn't always correct. Picture generator currently produces textures in N32,
// and will (soon) emit them in an arbitrary (destination) space. We will need to stash that

View File

@ -314,7 +314,7 @@ bool SkMaskFilter::canFilterMaskGPU(const SkRRect& devRRect,
return false;
}
bool SkMaskFilter::directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool SkMaskFilter::directFilterMaskGPU(GrContext*,
GrRenderTargetContext* renderTargetContext,
GrPaint&&,
const GrClip&,

View File

@ -260,7 +260,7 @@ static uint8_t* create_half_plane_profile(int profileWidth) {
return profile;
}
static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resourceProvider,
static sk_sp<GrTextureProxy> create_profile_texture(GrContext* context,
const SkRect& circle,
float sigma,
float* solidRadius, float* textureRadius) {
@ -299,8 +299,7 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resource
builder[0] = sigmaToCircleRRatioFixed;
builder.finish();
// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
sk_sp<GrTexture> blurProfile(resourceProvider->findAndRefTextureByUniqueKey(key));
sk_sp<GrTextureProxy> blurProfile = context->resourceProvider()->findProxyByUniqueKey(key);
if (!blurProfile) {
static constexpr int kProfileTextureWidth = 512;
GrSurfaceDesc texDesc;
@ -318,30 +317,30 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resource
kProfileTextureWidth));
}
blurProfile.reset(resourceProvider->createTexture(texDesc, SkBudgeted::kYes,
profile.get(), 0));
blurProfile = GrSurfaceProxy::MakeDeferred(*context->caps(), context->resourceProvider(),
texDesc, SkBudgeted::kYes, profile.get(), 0);
if (!blurProfile) {
return nullptr;
}
resourceProvider->assignUniqueKeyToTexture(key, blurProfile.get());
context->resourceProvider()->assignUniqueKeyToProxy(key, blurProfile.get());
}
return GrSurfaceProxy::MakeWrapped(std::move(blurProfile));
return blurProfile;
}
//////////////////////////////////////////////////////////////////////////////
sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrResourceProvider* resourceProvider,
sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(GrContext* context,
const SkRect& circle, float sigma) {
float solidRadius;
float textureRadius;
sk_sp<GrTextureProxy> profile(create_profile_texture(resourceProvider, circle, sigma,
sk_sp<GrTextureProxy> profile(create_profile_texture(context, circle, sigma,
&solidRadius, &textureRadius));
if (!profile) {
return nullptr;
}
return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(resourceProvider,
return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(context->resourceProvider(),
circle,
textureRadius, solidRadius,
std::move(profile)));
@ -356,7 +355,7 @@ sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate(GrProcessor
SkScalar wh = d->fRandom->nextRangeScalar(100.f, 1000.f);
SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f);
SkRect circle = SkRect::MakeWH(wh, wh);
return GrCircleBlurFragmentProcessor::Make(d->context()->resourceProvider(), circle, sigma);
return GrCircleBlurFragmentProcessor::Make(d->context(), circle, sigma);
}
#endif

View File

@ -34,7 +34,7 @@ public:
return str;
}
static sk_sp<GrFragmentProcessor> Make(GrResourceProvider*, const SkRect& circle, float sigma);
static sk_sp<GrFragmentProcessor> Make(GrContext*, const SkRect& circle, float sigma);
private:
// This nested GLSL processor implementation is defined in the cpp file.

View File

@ -51,7 +51,7 @@ public:
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const override;
bool directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool directFilterMaskGPU(GrContext*,
GrRenderTargetContext* renderTargetContext,
GrPaint&&,
const GrClip&,
@ -772,8 +772,7 @@ public:
const char* name() const override { return "RectBlur"; }
static sk_sp<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
const SkRect& rect, float sigma) {
static sk_sp<GrFragmentProcessor> Make(GrContext* context, const SkRect& rect, float sigma) {
int doubleProfileSize = SkScalarCeilToInt(12*sigma);
if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
@ -782,7 +781,7 @@ public:
return nullptr;
}
sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(context, sigma));
if (!blurProfile) {
return nullptr;
}
@ -806,7 +805,8 @@ public:
precision = kDefault_GrSLPrecision;
}
return sk_sp<GrFragmentProcessor>(new GrRectBlurEffect(resourceProvider, rect, sigma,
return sk_sp<GrFragmentProcessor>(new GrRectBlurEffect(context->resourceProvider(),
rect, sigma,
std::move(blurProfile), precision));
}
@ -824,7 +824,7 @@ private:
bool onIsEqual(const GrFragmentProcessor&) const override;
static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider*, float sigma);
static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrContext*, float sigma);
SkRect fRect;
float fSigma;
@ -942,9 +942,7 @@ void GrGLRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman,
pdman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma()));
}
// MDB TODO (caching): This side-steps the issue of texture proxies with unique IDs
sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(
GrResourceProvider* resourceProvider, float sigma) {
sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(GrContext* context, float sigma) {
GrSurfaceDesc texDesc;
unsigned int profileSize = SkScalarCeilToInt(6*sigma);
@ -960,20 +958,20 @@ sk_sp<GrTextureProxy> GrRectBlurEffect::CreateBlurProfileTexture(
builder[0] = profileSize;
builder.finish();
sk_sp<GrTexture> blurProfile(resourceProvider->findAndRefTextureByUniqueKey(key));
sk_sp<GrTextureProxy> blurProfile(context->resourceProvider()->findProxyByUniqueKey(key));
if (!blurProfile) {
std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
blurProfile.reset(resourceProvider->createTexture(texDesc, SkBudgeted::kYes,
profile.get(), 0));
blurProfile = GrSurfaceProxy::MakeDeferred(*context->caps(), context->resourceProvider(),
texDesc, SkBudgeted::kYes, profile.get(), 0);
if (!blurProfile) {
return nullptr;
}
resourceProvider->assignUniqueKeyToTexture(key, blurProfile.get());
context->resourceProvider()->assignUniqueKeyToProxy(key, blurProfile.get());
}
return GrSurfaceProxy::MakeWrapped(std::move(blurProfile));
return blurProfile;
}
GrRectBlurEffect::GrRectBlurEffect(GrResourceProvider* resourceProvider,
@ -1010,12 +1008,11 @@ sk_sp<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* d)
float sigma = d->fRandom->nextRangeF(3,8);
float width = d->fRandom->nextRangeF(200,300);
float height = d->fRandom->nextRangeF(200,300);
return GrRectBlurEffect::Make(d->context()->resourceProvider(), SkRect::MakeWH(width, height),
sigma);
return GrRectBlurEffect::Make(d->context(), SkRect::MakeWH(width, height), sigma);
}
#endif
bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,
const GrClip& clip,
@ -1042,9 +1039,9 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrResourceProvider* resourceProvi
SkScalar pad = 3.0f * xformedSigma;
rect.outset(pad, pad);
fp = GrRectBlurEffect::Make(resourceProvider, rect, xformedSigma);
fp = GrRectBlurEffect::Make(context, rect, xformedSigma);
} else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height())) {
fp = GrCircleBlurFragmentProcessor::Make(resourceProvider, rect, xformedSigma);
fp = GrCircleBlurFragmentProcessor::Make(context, rect, xformedSigma);
// expand the rect for the coverage geometry
int pad = SkScalarCeilToInt(6*xformedSigma)/2;
@ -1103,7 +1100,6 @@ private:
typedef GrFragmentProcessor INHERITED;
};
// MDB TODO (caching): This side-steps the issue of texture proxies with unique IDs
static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context,
const SkRRect& rrectToDraw,
const SkISize& size,
@ -1122,7 +1118,7 @@ static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context,
}
builder.finish();
sk_sp<GrTexture> mask(context->resourceProvider()->findAndRefTextureByUniqueKey(key));
sk_sp<GrTextureProxy> mask(context->resourceProvider()->findProxyByUniqueKey(key));
if (!mask) {
// TODO: this could be approx but the texture coords will need to be updated
sk_sp<GrRenderTargetContext> rtc(context->makeDeferredRenderTargetContextWithFallback(
@ -1154,14 +1150,14 @@ static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrContext* context,
return nullptr;
}
mask = rtc2->asTexture();
mask = rtc2->asTextureProxyRef();
if (!mask) {
return nullptr;
}
context->resourceProvider()->assignUniqueKeyToTexture(key, mask.get());
context->resourceProvider()->assignUniqueKeyToProxy(key, mask.get());
}
return GrSurfaceProxy::MakeWrapped(std::move(mask));
return mask;
}
sk_sp<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context,
@ -1370,11 +1366,9 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
SkScalar pad = 3.0f * xformedSigma;
const SkRect dstCoverageRect = devRRect.rect().makeOutset(pad, pad);
fp = GrRectBlurEffect::Make(context->resourceProvider(), dstCoverageRect, xformedSigma);
fp = GrRectBlurEffect::Make(context, dstCoverageRect, xformedSigma);
} else {
fp = GrCircleBlurFragmentProcessor::Make(context->resourceProvider(),
devRRect.rect(),
xformedSigma);
fp = GrCircleBlurFragmentProcessor::Make(context, devRRect.rect(), xformedSigma);
}
if (!fp) {

View File

@ -34,7 +34,7 @@ public:
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const override;
bool directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool directFilterMaskGPU(GrContext*,
GrRenderTargetContext* drawContext,
GrPaint&&,
const GrClip&,
@ -139,7 +139,7 @@ bool SkAmbientShadowMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
static const float kHeightFactor = 1.0f / 128.0f;
static const float kGeomFactor = 64.0f;
bool SkAmbientShadowMaskFilterImpl::directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool SkAmbientShadowMaskFilterImpl::directFilterMaskGPU(GrContext* context,
GrRenderTargetContext* rtContext,
GrPaint&& paint,
const GrClip& clip,
@ -167,11 +167,11 @@ bool SkAmbientShadowMaskFilterImpl::directFilterMaskGPU(GrResourceProvider* reso
// have our own GeometryProc.
if (path.isOval(nullptr) && path.getBounds().width() == path.getBounds().height()) {
SkRRect rrect = SkRRect::MakeOval(path.getBounds());
return this->directFilterRRectMaskGPU(nullptr, rtContext, std::move(paint), clip,
return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
SkMatrix::I(), strokeRec, rrect, rrect);
} else if (path.isRect(nullptr)) {
SkRRect rrect = SkRRect::MakeRect(path.getBounds());
return this->directFilterRRectMaskGPU(nullptr, rtContext, std::move(paint), clip,
return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
SkMatrix::I(), strokeRec, rrect, rrect);
}

View File

@ -35,7 +35,7 @@ public:
const SkIRect& clipBounds,
const SkMatrix& ctm,
SkRect* maskRect) const override;
bool directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool directFilterMaskGPU(GrContext*,
GrRenderTargetContext* drawContext,
GrPaint&&,
const GrClip&,
@ -156,7 +156,7 @@ bool SkSpotShadowMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect,
return true;
}
bool SkSpotShadowMaskFilterImpl::directFilterMaskGPU(GrResourceProvider* resourceProvider,
bool SkSpotShadowMaskFilterImpl::directFilterMaskGPU(GrContext* context,
GrRenderTargetContext* rtContext,
GrPaint&& paint,
const GrClip& clip,
@ -184,11 +184,11 @@ bool SkSpotShadowMaskFilterImpl::directFilterMaskGPU(GrResourceProvider* resourc
// have our own GeometryProc.
if (path.isOval(nullptr) && path.getBounds().width() == path.getBounds().height()) {
SkRRect rrect = SkRRect::MakeOval(path.getBounds());
return this->directFilterRRectMaskGPU(nullptr, rtContext, std::move(paint), clip,
return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
SkMatrix::I(), strokeRec, rrect, rrect);
} else if (path.isRect(nullptr)) {
SkRRect rrect = SkRRect::MakeRect(path.getBounds());
return this->directFilterRRectMaskGPU(nullptr, rtContext, std::move(paint), clip,
return this->directFilterRRectMaskGPU(context, rtContext, std::move(paint), clip,
SkMatrix::I(), strokeRec, rrect, rrect);
}

View File

@ -207,7 +207,7 @@ static void draw_path_with_mask_filter(GrContext* context,
return;
}
if (maskFilter->directFilterMaskGPU(context->resourceProvider(),
if (maskFilter->directFilterMaskGPU(context,
renderTargetContext,
std::move(paint),
clip,

View File

@ -380,16 +380,15 @@ static void add_invalidate_on_pop_message(const SkClipStack& stack, int32_t clip
SkDEBUGFAIL("Gen ID was not found in stack.");
}
// MDB TODO (caching): this side-steps the issue of texture proxies cached by unique ID
sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context,
const GrReducedClip& reducedClip) const {
GrResourceProvider* resourceProvider = context->resourceProvider();
GrUniqueKey key;
create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key);
sk_sp<GrTexture> texture(resourceProvider->findAndRefTextureByUniqueKey(key));
if (texture) {
return GrSurfaceProxy::MakeWrapped(std::move(texture));
sk_sp<GrTextureProxy> proxy(resourceProvider->findProxyByUniqueKey(key));
if (proxy) {
return proxy;
}
sk_sp<GrRenderTargetContext> rtc(context->makeRenderTargetContextWithFallback(
@ -411,27 +410,22 @@ sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context,
return nullptr;
}
GrTexture* tex = result->instantiate(context->resourceProvider());
if (!tex) {
return nullptr;
}
context->resourceProvider()->assignUniqueKeyToTexture(key, tex);
resourceProvider->assignUniqueKeyToProxy(key, result.get());
// MDB TODO (caching): this has to play nice with the GrSurfaceProxy's caching
add_invalidate_on_pop_message(*fStack, reducedClip.elementsGenID(), key);
return result;
}
// MDB TODO (caching): This side-steps the caching of texture proxies by unique ID
sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask(
GrContext* context,
const GrReducedClip& reducedClip) const {
GrUniqueKey key;
create_clip_mask_key(reducedClip.elementsGenID(), reducedClip.ibounds(), &key);
sk_sp<GrTexture> texture(context->resourceProvider()->findAndRefTextureByUniqueKey(key));
if (texture) {
return GrSurfaceProxy::MakeWrapped(std::move(texture));
sk_sp<GrTextureProxy> proxy(context->resourceProvider()->findProxyByUniqueKey(key));
if (proxy) {
return proxy;
}
// The mask texture may be larger than necessary. We round out the clip bounds and pin the top
@ -485,14 +479,10 @@ sk_sp<GrTextureProxy> GrClipStackClip::createSoftwareClipMask(
}
}
sk_sp<GrTextureProxy> result(helper.toTexture(context, SkBackingFit::kApprox));
sk_sp<GrTextureProxy> result(helper.toTextureProxy(context, SkBackingFit::kApprox));
GrTexture* tex = result->instantiate(context->resourceProvider());
if (!tex) {
return nullptr;
}
context->resourceProvider()->assignUniqueKeyToTexture(key, tex);
context->resourceProvider()->assignUniqueKeyToProxy(key, result.get());
// MDB TODO (caching): this has to play nice with the GrSurfaceProxy's caching
add_invalidate_on_pop_message(*fStack, reducedClip.elementsGenID(), key);
return result;
}

View File

@ -212,6 +212,34 @@ GrTexture* GrResourceProvider::findAndRefTextureByUniqueKey(const GrUniqueKey& k
return NULL;
}
// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
ASSERT_SINGLE_OWNER
SkASSERT(key.isValid());
if (this->isAbandoned() || !proxy) {
return;
}
GrTexture* texture = proxy->instantiate(this);
if (!texture) {
return;
}
this->assignUniqueKeyToResource(key, texture);
}
// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey& key) {
ASSERT_SINGLE_OWNER
sk_sp<GrTexture> texture(this->findAndRefTextureByUniqueKey(key));
if (!texture) {
return nullptr;
}
return GrSurfaceProxy::MakeWrapped(std::move(texture));
}
const GrBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern,
int patternSize,
int reps,

View File

@ -78,6 +78,10 @@ public:
/** Finds a texture by unique key. If the texture is found it is ref'ed and returned. */
GrTexture* findAndRefTextureByUniqueKey(const GrUniqueKey& key);
void assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy*);
sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey& key);
/**
* Finds a texture that approximately matches the descriptor. Will be at least as large in width
* and height as desc specifies. If desc specifies that the texture should be a render target

View File

@ -97,8 +97,9 @@ bool GrSWMaskHelper::init(const SkIRect& resultBounds, const SkMatrix* matrix) {
return true;
}
sk_sp<GrTextureProxy> GrSWMaskHelper::toTexture(GrContext* context, SkBackingFit fit) {
sk_sp<GrTextureProxy> GrSWMaskHelper::toTextureProxy(GrContext* context, SkBackingFit fit) {
GrSurfaceDesc desc;
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fWidth = fPixels.width();
desc.fHeight = fPixels.height();
desc.fConfig = kAlpha_8_GrPixelConfig;
@ -132,12 +133,12 @@ void GrSWMaskHelper::toSDF(unsigned char* sdf) {
* Software rasterizes shape to A8 mask and uploads the result to a scratch texture. Returns the
* resulting texture on success; nullptr on failure.
*/
sk_sp<GrTexture> GrSWMaskHelper::DrawShapeMaskToTexture(GrContext* context,
const GrShape& shape,
const SkIRect& resultBounds,
GrAA aa,
SkBackingFit fit,
const SkMatrix* matrix) {
sk_sp<GrTextureProxy> GrSWMaskHelper::DrawShapeMaskToTexture(GrContext* context,
const GrShape& shape,
const SkIRect& resultBounds,
GrAA aa,
SkBackingFit fit,
const SkMatrix* matrix) {
GrSWMaskHelper helper;
if (!helper.init(resultBounds, matrix)) {
@ -146,15 +147,11 @@ sk_sp<GrTexture> GrSWMaskHelper::DrawShapeMaskToTexture(GrContext* context,
helper.drawShape(shape, SkRegion::kReplace_Op, aa, 0xFF);
sk_sp<GrTextureProxy> tProxy = helper.toTexture(context, fit);
if (!tProxy) {
return nullptr;
}
return sk_ref_sp(tProxy->instantiate(context->resourceProvider()));
return helper.toTextureProxy(context, fit);
}
void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
void GrSWMaskHelper::DrawToTargetWithShapeMask(GrContext* context,
sk_sp<GrTextureProxy> proxy,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,
const GrUserStencilSettings& userStencilSettings,
@ -178,7 +175,7 @@ void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
std::unique_ptr<GrMeshDrawOp> op = GrRectOpFactory::MakeNonAAFill(
paint.getColor(), SkMatrix::I(), dstRect, nullptr, &invert);
paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(
texture, nullptr, maskMatrix, GrSamplerParams::kNone_FilterMode));
context, std::move(proxy), nullptr, maskMatrix, GrSamplerParams::kNone_FilterMode));
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
pipelineBuilder.setUserStencil(&userStencilSettings);
renderTargetContext->addMeshDrawOp(pipelineBuilder, clip, std::move(op));

View File

@ -55,7 +55,7 @@ public:
// Draw a single path into the accumuation bitmap using the specified op
void drawShape(const GrShape&, SkRegion::Op op, GrAA, uint8_t alpha);
sk_sp<GrTextureProxy> toTexture(GrContext*, SkBackingFit fit);
sk_sp<GrTextureProxy> toTextureProxy(GrContext*, SkBackingFit fit);
// Convert mask generation results to a signed distance field
void toSDF(unsigned char* sdf);
@ -67,17 +67,18 @@ public:
// Canonical usage utility that draws a single path and uploads it
// to the GPU. The result is returned.
static sk_sp<GrTexture> DrawShapeMaskToTexture(GrContext*,
const GrShape&,
const SkIRect& resultBounds,
GrAA,
SkBackingFit,
const SkMatrix* matrix);
static sk_sp<GrTextureProxy> DrawShapeMaskToTexture(GrContext*,
const GrShape&,
const SkIRect& resultBounds,
GrAA,
SkBackingFit,
const SkMatrix* matrix);
// This utility draws a path mask generated by DrawShapeMaskToTexture using a provided paint.
// The rectangle is drawn in device space. The 'viewMatrix' will be used to ensure the correct
// local coords are provided to any fragment processors in the paint.
static void DrawToTargetWithShapeMask(GrTexture* texture,
static void DrawToTargetWithShapeMask(GrContext*,
sk_sp<GrTextureProxy>,
GrRenderTargetContext*,
GrPaint&& paint,
const GrUserStencilSettings& userStencilSettings,

View File

@ -204,22 +204,22 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
// should always be true, though.
}
sk_sp<GrTexture> texture;
sk_sp<GrTextureProxy> proxy;
if (useCache) {
texture.reset(fResourceProvider->findAndRefTextureByUniqueKey(maskKey));
proxy = fResourceProvider->findProxyByUniqueKey(maskKey);
}
if (!texture) {
GrContext* context = args.fRenderTargetContext->surfPriv().getContext();
if (!proxy) {
SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox;
GrAA aa = GrAAType::kCoverage == args.fAAType ? GrAA::kYes : GrAA::kNo;
GrContext* context = args.fRenderTargetContext->surfPriv().getContext();
texture = GrSWMaskHelper::DrawShapeMaskToTexture(context, *args.fShape,
*boundsForMask, aa,
fit, args.fViewMatrix);
if (!texture) {
proxy = GrSWMaskHelper::DrawShapeMaskToTexture(context, *args.fShape,
*boundsForMask, aa,
fit, args.fViewMatrix);
if (!proxy) {
return false;
}
if (useCache) {
fResourceProvider->assignUniqueKeyToTexture(maskKey, texture.get());
fResourceProvider->assignUniqueKeyToProxy(maskKey, proxy.get());
}
}
if (inverseFilled) {
@ -228,7 +228,7 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
unclippedDevShapeBounds);
}
GrSWMaskHelper::DrawToTargetWithShapeMask(
texture.get(), args.fRenderTargetContext, std::move(args.fPaint),
context, std::move(proxy), args.fRenderTargetContext, std::move(args.fPaint),
*args.fUserStencilSettings, *args.fClip, *args.fViewMatrix,
SkIPoint{boundsForMask->fLeft, boundsForMask->fTop}, *boundsForMask);

View File

@ -105,25 +105,33 @@ GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bitmap) {
return GrUploadPixmapToTexture(ctx, pixmap, SkBudgeted::kYes);
}
GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBudgeted budgeted) {
const SkPixmap* pmap = &pixmap;
SkPixmap tmpPixmap;
SkBitmap tmpBitmap;
if (!SkImageInfoIsValid(pixmap.info())) {
sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrContext* ctx, const SkBitmap& bitmap) {
SkAutoLockPixels alp(bitmap);
if (!bitmap.readyToDraw()) {
return nullptr;
}
SkPixmap pixmap;
if (!bitmap.peekPixels(&pixmap)) {
return nullptr;
}
return GrUploadPixmapToTextureProxy(ctx, pixmap, SkBudgeted::kYes);
}
const GrCaps* caps = ctx->caps();
GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *caps);
static const SkPixmap* compute_desc(const GrCaps& caps, const SkPixmap& pixmap,
GrSurfaceDesc* desc,
SkBitmap* tmpBitmap, SkPixmap* tmpPixmap) {
const SkPixmap* pmap = &pixmap;
*desc = GrImageInfoToSurfaceDesc(pixmap.info(), caps);
// TODO: We're checking for srgbSupport, but we can then end up picking sBGRA as our pixel
// config (which may not be supported). We need better fallback management here.
SkColorSpace* colorSpace = pixmap.colorSpace();
if (caps->srgbSupport() &&
if (caps.srgbSupport() &&
colorSpace && colorSpace->gammaCloseToSRGB() && !as_CSB(colorSpace)->nonLinearBlending() &&
!GrPixelConfigIsSRGB(desc.fConfig)) {
!GrPixelConfigIsSRGB(desc->fConfig)) {
// We were supplied an sRGB-like color space, but we don't have a suitable pixel config.
// Convert to 8888 sRGB so we can handle the data correctly. The raster backend doesn't
// handle sRGB Index8 -> sRGB 8888 correctly (yet), so lie about both the source and
@ -136,36 +144,70 @@ GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBud
kN32_SkColorType, kPremul_SkAlphaType,
pixmap.info().refColorSpace());
tmpBitmap.allocPixels(dstInfo);
tmpBitmap->allocPixels(dstInfo);
SkImageInfo linDstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap.getPixels(), tmpBitmap.rowBytes())) {
if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap->getPixels(), tmpBitmap->rowBytes())) {
return nullptr;
}
if (!tmpBitmap.peekPixels(&tmpPixmap)) {
if (!tmpBitmap->peekPixels(tmpPixmap)) {
return nullptr;
}
pmap = &tmpPixmap;
pmap = tmpPixmap;
// must rebuild desc, since we've forced the info to be N32
desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
*desc = GrImageInfoToSurfaceDesc(pmap->info(), caps);
} else if (kIndex_8_SkColorType == pixmap.colorType()) {
SkImageInfo info = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
tmpBitmap.allocPixels(info);
if (!pixmap.readPixels(info, tmpBitmap.getPixels(), tmpBitmap.rowBytes())) {
tmpBitmap->allocPixels(info);
if (!pixmap.readPixels(info, tmpBitmap->getPixels(), tmpBitmap->rowBytes())) {
return nullptr;
}
if (!tmpBitmap.peekPixels(&tmpPixmap)) {
if (!tmpBitmap->peekPixels(tmpPixmap)) {
return nullptr;
}
pmap = &tmpPixmap;
pmap = tmpPixmap;
// must rebuild desc, since we've forced the info to be N32
desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
*desc = GrImageInfoToSurfaceDesc(pmap->info(), caps);
}
return ctx->resourceProvider()->createTexture(desc, budgeted, pmap->addr(),
pmap->rowBytes());
return pmap;
}
GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBudgeted budgeted) {
if (!SkImageInfoIsValid(pixmap.info())) {
return nullptr;
}
SkBitmap tmpBitmap;
SkPixmap tmpPixmap;
GrSurfaceDesc desc;
if (const SkPixmap* pmap = compute_desc(*ctx->caps(), pixmap, &desc, &tmpBitmap, &tmpPixmap)) {
return ctx->resourceProvider()->createTexture(desc, budgeted, pmap->addr(),
pmap->rowBytes());
}
return nullptr;
}
sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrContext* ctx,
const SkPixmap& pixmap,
SkBudgeted budgeted) {
if (!SkImageInfoIsValid(pixmap.info())) {
return nullptr;
}
SkBitmap tmpBitmap;
SkPixmap tmpPixmap;
GrSurfaceDesc desc;
if (const SkPixmap* pmap = compute_desc(*ctx->caps(), pixmap, &desc, &tmpBitmap, &tmpPixmap)) {
return GrSurfaceProxy::MakeDeferred(*ctx->caps(), ctx->resourceProvider(), desc,
budgeted, pmap->addr(), pmap->rowBytes());
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
@ -270,8 +312,6 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
nullptr, scaleAdjust);
}
// MDB TODO (caching): For better or for worse, this method currently side-steps the issue of
// caching an uninstantiated proxy via a key.
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrContext* context, const SkBitmap& bitmap) {
GrUniqueKey originalKey;
@ -281,29 +321,25 @@ sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrContext* context, const SkBitmap
GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
}
sk_sp<GrTexture> tex;
sk_sp<GrTextureProxy> proxy;
if (originalKey.isValid()) {
tex.reset(context->resourceProvider()->findAndRefTextureByUniqueKey(originalKey));
proxy = context->resourceProvider()->findProxyByUniqueKey(originalKey);
}
if (!tex) {
tex.reset(GrUploadBitmapToTexture(context, bitmap));
if (tex && originalKey.isValid()) {
context->resourceProvider()->assignUniqueKeyToTexture(originalKey, tex.get());
if (!proxy) {
proxy = GrUploadBitmapToTextureProxy(context, bitmap);
if (proxy && originalKey.isValid()) {
context->resourceProvider()->assignUniqueKeyToProxy(originalKey, proxy.get());
// MDB TODO (caching): this has to play nice with the GrSurfaceProxy's caching
GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
}
}
if (!tex) {
return nullptr;
}
sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex));
if (!proxy) {
return nullptr;
}
return sk_ref_sp(proxy->asTextureProxy());
return proxy;
}
sk_sp<GrTexture> GrMakeCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,

View File

@ -213,13 +213,17 @@ GrTexture* GrRefCachedBitmapTexture(GrContext*, const SkBitmap&,
*/
GrTexture* GrUploadBitmapToTexture(GrContext*, const SkBitmap&);
sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrContext*, const SkBitmap&);
GrTexture* GrGenerateMipMapsAndUploadToTexture(GrContext*, const SkBitmap&,
SkColorSpace* dstColorSpace);
/**
* Creates a new texture for the pixmap.
*/
GrTexture* GrUploadPixmapToTexture(GrContext*, const SkPixmap&, SkBudgeted budgeted);
GrTexture* GrUploadPixmapToTexture(GrContext*, const SkPixmap&, SkBudgeted);
sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrContext*, const SkPixmap&, SkBudgeted);
/**
* Creates a new texture populated with the mipmap levels.

View File

@ -196,10 +196,10 @@ GrTextureStripAtlas::AtlasRow* GrTextureStripAtlas::getLRU() {
void GrTextureStripAtlas::lockTexture() {
GrSurfaceDesc texDesc;
texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
texDesc.fWidth = fDesc.fWidth;
texDesc.fHeight = fDesc.fHeight;
texDesc.fConfig = fDesc.fConfig;
texDesc.fIsMipMapped = false;
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey key;
@ -207,24 +207,24 @@ void GrTextureStripAtlas::lockTexture() {
builder[0] = static_cast<uint32_t>(fCacheKey);
builder.finish();
// MDB TODO (caching): this side-steps the issue of proxies with unique IDs
sk_sp<GrTexture> texture(fDesc.fContext->resourceProvider()->findAndRefTextureByUniqueKey(key));
if (!texture) {
texture.reset(fDesc.fContext->resourceProvider()->createTexture(
texDesc, SkBudgeted::kYes,
nullptr, 0,
GrResourceProvider::kNoPendingIO_Flag));
if (!texture) {
sk_sp<GrTextureProxy> proxy = fDesc.fContext->resourceProvider()->findProxyByUniqueKey(key);
if (!proxy) {
proxy = GrSurfaceProxy::MakeDeferred(fDesc.fContext->resourceProvider(),
*fDesc.fContext->caps(), texDesc, SkBackingFit::kExact,
SkBudgeted::kYes,
GrResourceProvider::kNoPendingIO_Flag);
if (!proxy) {
return;
}
fDesc.fContext->resourceProvider()->assignUniqueKeyToTexture(key, texture.get());
fDesc.fContext->resourceProvider()->assignUniqueKeyToProxy(key, proxy.get());
// This is a new texture, so all of our cache info is now invalid
this->initLRU();
fKeyTable.rewind();
}
SkASSERT(texture);
fTexContext = fDesc.fContext->contextPriv().makeWrappedSurfaceContext(std::move(texture));
SkASSERT(proxy);
fTexContext = fDesc.fContext->contextPriv().makeWrappedSurfaceContext(std::move(proxy),
nullptr);
}
void GrTextureStripAtlas::unlockTexture() {