Store GrSurfaceProxyViews on SkSpecial*_Gpu.

To make this change cleaner, GrMakeCachedBitmapProxy now returns a view
and all its callers updated.

Additionally some effects were updated to fully use views in cases
where they had to be updated anyways to support SpecialImages and there
wasn't much additional work to pass them around everywhere.

Bug: skia:9556
Change-Id: Ie5a631cdec481391437e2f74275f958d15676780
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/267176
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Greg Daniel 2020-01-28 17:03:46 -05:00 committed by Skia Commit-Bot
parent ad9110026b
commit c52db71c9b
19 changed files with 201 additions and 154 deletions

View File

@ -592,7 +592,7 @@ sk_sp<SkSpecialImage> SkImageFilter_Base::DrawWithFP(GrRecordingContext* context
return SkSpecialImage::MakeDeferredFromGpu(
context, dstIRect, kNeedNewImageUniqueID_SpecialImage,
renderTargetContext->asTextureProxyRef(), renderTargetContext->colorInfo().colorType(),
renderTargetContext->readSurfaceView(), renderTargetContext->colorInfo().colorType(),
renderTargetContext->colorInfo().refColorSpace());
}

View File

@ -53,6 +53,8 @@ public:
#if SK_SUPPORT_GPU
virtual sk_sp<GrTextureProxy> onAsTextureProxyRef(GrRecordingContext* context) const = 0;
virtual GrSurfaceProxyView onAsSurfaceProxyViewRef(GrRecordingContext* context) const = 0;
#endif
// This subset is relative to the backing store's coordinate frame, it has already been mapped
@ -112,19 +114,19 @@ sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(GrRecordingContext* conte
// TODO: this is a tight copy of 'bmp' but it doesn't have to be (given SkSpecialImage's
// semantics). Since this is cached though we would have to bake the fit into the cache key.
sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(context, bmp);
if (!proxy) {
auto view = GrMakeCachedBitmapProxyView(context, bmp);
if (!view.proxy()) {
return nullptr;
}
const SkIRect rect = SkIRect::MakeSize(proxy->dimensions());
const SkIRect rect = SkIRect::MakeSize(view.proxy()->dimensions());
// GrMakeCachedBitmapProxy has uploaded only the specified subset of 'bmp' so we need not
// GrMakeCachedBitmapProxyView has uploaded only the specified subset of 'bmp' so we need not
// bother with SkBitmap::getSubset
return SkSpecialImage::MakeDeferredFromGpu(context,
rect,
this->uniqueID(),
std::move(proxy),
std::move(view),
SkColorTypeToGrColorType(bmp.colorType()),
sk_ref_sp(this->getColorSpace()),
&this->props(),
@ -158,6 +160,10 @@ SkColorSpace* SkSpecialImage::getColorSpace() const {
sk_sp<GrTextureProxy> SkSpecialImage::asTextureProxyRef(GrRecordingContext* context) const {
return as_SIB(this)->onAsTextureProxyRef(context);
}
GrSurfaceProxyView SkSpecialImage::asSurfaceProxyViewRef(GrRecordingContext* context) const {
return as_SIB(this)->onAsSurfaceProxyViewRef(context);
}
#endif
sk_sp<SkSpecialSurface> SkSpecialImage::makeSurface(
@ -207,12 +213,13 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(GrRecordingContext* context,
SkASSERT(rect_fits(subset, image->width(), image->height()));
#if SK_SUPPORT_GPU
if (sk_sp<GrTextureProxy> proxy = as_IB(image)->asTextureProxyRef(context)) {
GrSurfaceProxyView view = as_IB(image)->asSurfaceProxyViewRef(context);
if (view.proxy()) {
if (!as_IB(image)->context()->priv().matches(context)) {
return nullptr;
}
return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(view),
SkColorTypeToGrColorType(image->colorType()),
image->refColorSpace(), props);
} else
@ -263,10 +270,22 @@ public:
#if SK_SUPPORT_GPU
sk_sp<GrTextureProxy> onAsTextureProxyRef(GrRecordingContext* context) const override {
if (context) {
return GrMakeCachedBitmapProxy(context, fBitmap);
auto view = GrMakeCachedBitmapProxyView(context, fBitmap);
sk_sp<GrSurfaceProxy> proxy = view.detachProxy();
if (proxy->asTextureProxy()) {
GrSurfaceProxy* sProxy = proxy.release();
return sk_ref_sp<GrTextureProxy>(sProxy->asTextureProxy());
}
}
return nullptr;
}
GrSurfaceProxyView onAsSurfaceProxyViewRef(GrRecordingContext* context) const override {
if (context) {
return GrMakeCachedBitmapProxyView(context, fBitmap);
}
return nullptr;
return {};
}
#endif
@ -366,15 +385,10 @@ sk_sp<SkSpecialImage> SkSpecialImage::CopyFromRaster(const SkIRect& subset,
#if SK_SUPPORT_GPU
///////////////////////////////////////////////////////////////////////////////
static sk_sp<SkImage> wrap_proxy_in_image(GrRecordingContext* context, sk_sp<GrTextureProxy> proxy,
static sk_sp<SkImage> wrap_proxy_in_image(GrRecordingContext* context, GrSurfaceProxyView view,
SkColorType colorType, SkAlphaType alphaType,
sk_sp<SkColorSpace> colorSpace) {
// CONTEXT TODO: remove this use of 'backdoor' to create an SkImage
// TODO: Once SkSpecialImage stores a GrSurfaceProxyView instead of a proxy, use that to create
// the view here.
GrSurfaceOrigin origin = proxy->origin();
const GrSwizzle& swizzle = proxy->textureSwizzle();
GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context->priv().backdoor()),
kNeedNewImageUniqueID, std::move(view), colorType, alphaType,
std::move(colorSpace));
@ -383,11 +397,11 @@ static sk_sp<SkImage> wrap_proxy_in_image(GrRecordingContext* context, sk_sp<GrT
class SkSpecialImage_Gpu : public SkSpecialImage_Base {
public:
SkSpecialImage_Gpu(GrRecordingContext* context, const SkIRect& subset,
uint32_t uniqueID, sk_sp<GrTextureProxy> proxy, GrColorType ct,
uint32_t uniqueID, GrSurfaceProxyView view, GrColorType ct,
SkAlphaType at, sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props)
: INHERITED(subset, uniqueID, props)
, fContext(context)
, fTextureProxy(std::move(proxy))
, fView(std::move(view))
, fColorType(ct)
, fAlphaType(at)
, fColorSpace(std::move(colorSpace))
@ -405,16 +419,13 @@ public:
SkColorType colorType() const override { return GrColorTypeToSkColorType(fColorType); }
size_t getSize() const override {
return fTextureProxy->gpuMemorySize(*fContext->priv().caps());
return fView.proxy()->gpuMemorySize(*fContext->priv().caps());
}
void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override {
SkRect dst = SkRect::MakeXYWH(x, y,
this->subset().width(), this->subset().height());
GrSurfaceOrigin origin = fTextureProxy->origin();
const GrSwizzle& swizzle = fTextureProxy->textureSwizzle();
GrSurfaceProxyView view(fTextureProxy, origin, swizzle);
// TODO: In this instance we know we're going to draw a sub-portion of the backing
// texture into the canvas so it is okay to wrap it in an SkImage. This poses
// some problems for full deferral however in that when the deferred SkImage_Gpu
@ -423,8 +434,7 @@ public:
// to be tightened (if it is deferred).
sk_sp<SkImage> img =
sk_sp<SkImage>(new SkImage_Gpu(sk_ref_sp(canvas->getGrContext()), this->uniqueID(),
std::move(view), this->colorType(), fAlphaType,
fColorSpace));
fView, this->colorType(), fAlphaType, fColorSpace));
canvas->drawImageRect(img, this->subset(),
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
@ -433,7 +443,11 @@ public:
GrRecordingContext* onGetContext() const override { return fContext; }
sk_sp<GrTextureProxy> onAsTextureProxyRef(GrRecordingContext*) const override {
return fTextureProxy;
return fView.asTextureProxyRef();
}
GrSurfaceProxyView onAsSurfaceProxyViewRef(GrRecordingContext* context) const override {
return fView;
}
bool onGetROPixels(SkBitmap* dst) const override {
@ -452,11 +466,8 @@ public:
if (!rec) {
return false;
}
// TODO: Store a GrSurfaceProxyView on SkSpecialImage_Gpu instead of just a GrTextureProxy
GrSurfaceProxyView view(fTextureProxy, fTextureProxy->origin(),
fTextureProxy->textureSwizzle());
auto sContext = GrSurfaceContext::Make(fContext, std::move(view), fColorType,
this->alphaType(), fColorSpace);
auto sContext = GrSurfaceContext::Make(fContext, fView, fColorType, this->alphaType(),
fColorSpace);
if (!sContext) {
return false;
}
@ -491,7 +502,7 @@ public:
return SkSpecialImage::MakeDeferredFromGpu(fContext,
subset,
this->uniqueID(),
fTextureProxy,
fView,
fColorType,
fColorSpace,
&this->props(),
@ -500,19 +511,18 @@ public:
// TODO: move all the logic here into the subset-flavor GrSurfaceProxy::copy?
sk_sp<SkImage> onAsImage(const SkIRect* subset) const override {
GrSurfaceProxy* proxy = fView.proxy();
if (subset) {
if (fTextureProxy->isFunctionallyExact() &&
*subset == SkIRect::MakeSize(fTextureProxy->dimensions())) {
fTextureProxy->priv().exactify(false);
if (proxy->isFunctionallyExact() && *subset == SkIRect::MakeSize(proxy->dimensions())) {
proxy->priv().exactify(false);
// The existing GrTexture is already tight so reuse it in the SkImage
return wrap_proxy_in_image(fContext, fTextureProxy, this->colorType(), fAlphaType,
return wrap_proxy_in_image(fContext, fView, this->colorType(), fAlphaType,
fColorSpace);
}
sk_sp<GrTextureProxy> subsetProxy(
GrSurfaceProxy::Copy(fContext, fTextureProxy.get(), fColorType,
GrMipMapped::kNo, *subset, SkBackingFit::kExact,
SkBudgeted::kYes));
GrSurfaceProxy::Copy(fContext, proxy, fColorType, GrMipMapped::kNo, *subset,
SkBackingFit::kExact, SkBudgeted::kYes));
if (!subsetProxy) {
return nullptr;
}
@ -520,14 +530,14 @@ public:
SkASSERT(subsetProxy->priv().isExact());
// MDB: this is acceptable (wrapping subsetProxy in an SkImage) bc Copy will
// return a kExact-backed proxy
return wrap_proxy_in_image(fContext, std::move(subsetProxy), this->colorType(),
GrSurfaceProxyView subsetView(std::move(subsetProxy), fView.origin(), fView.swizzle());
return wrap_proxy_in_image(fContext, std::move(subsetView), this->colorType(),
fAlphaType, fColorSpace);
}
fTextureProxy->priv().exactify(true);
proxy->priv().exactify(true);
return wrap_proxy_in_image(fContext, fTextureProxy, this->colorType(), fAlphaType,
fColorSpace);
return wrap_proxy_in_image(fContext, fView, this->colorType(), fAlphaType, fColorSpace);
}
sk_sp<SkSurface> onMakeTightSurface(SkColorType colorType, const SkColorSpace* colorSpace,
@ -544,7 +554,7 @@ public:
private:
GrRecordingContext* fContext;
sk_sp<GrTextureProxy> fTextureProxy;
GrSurfaceProxyView fView;
const GrColorType fColorType;
const SkAlphaType fAlphaType;
sk_sp<SkColorSpace> fColorSpace;
@ -556,16 +566,16 @@ private:
sk_sp<SkSpecialImage> SkSpecialImage::MakeDeferredFromGpu(GrRecordingContext* context,
const SkIRect& subset,
uint32_t uniqueID,
sk_sp<GrTextureProxy> proxy,
GrSurfaceProxyView view,
GrColorType colorType,
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* props,
SkAlphaType at) {
if (!context || context->priv().abandoned() || !proxy) {
if (!context || context->priv().abandoned() || !view.asTextureProxy()) {
return nullptr;
}
SkASSERT_RELEASE(rect_fits(subset, proxy->width(), proxy->height()));
return sk_make_sp<SkSpecialImage_Gpu>(context, subset, uniqueID, std::move(proxy), colorType,
SkASSERT_RELEASE(rect_fits(subset, view.proxy()->width(), view.proxy()->height()));
return sk_make_sp<SkSpecialImage_Gpu>(context, subset, uniqueID, std::move(view), colorType,
at, std::move(colorSpace), props);
}
#endif

View File

@ -15,6 +15,7 @@
#if SK_SUPPORT_GPU
#include "include/private/GrTypesPriv.h"
#include "src/gpu/GrSurfaceProxyView.h"
#endif
class GrRecordingContext;
@ -86,7 +87,7 @@ public:
static sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrRecordingContext*,
const SkIRect& subset,
uint32_t uniqueID,
sk_sp<GrTextureProxy>,
GrSurfaceProxyView,
GrColorType,
sk_sp<SkColorSpace>,
const SkSurfaceProps* = nullptr,
@ -148,6 +149,14 @@ public:
* space (offset by subset().topLeft()).
*/
sk_sp<GrTextureProxy> asTextureProxyRef(GrRecordingContext*) const;
/**
* Regardless of how the underlying backing data is stored, returns the contents as a
* GrSurfaceProxyView. The returned view's proxy represents the entire backing image, so texture
* coordinates must be mapped from the content rect (e.g. relative to 'subset()') to the proxy's
* space (offset by subset().topLeft()).
*/
GrSurfaceProxyView asSurfaceProxyViewRef(GrRecordingContext*) const;
#endif
/**

View File

@ -127,7 +127,7 @@ public:
std::unique_ptr<GrRenderTargetContext> renderTargetContext,
int width, int height, const SkIRect& subset)
: INHERITED(subset, &renderTargetContext->surfaceProps())
, fProxy(renderTargetContext->asTextureProxyRef()) {
, fReadView(renderTargetContext->readSurfaceView()) {
// CONTEXT TODO: remove this use of 'backdoor' to create an SkGpuDevice
auto device = SkGpuDevice::Make(context->priv().backdoor(), std::move(renderTargetContext),
SkGpuDevice::kUninit_InitContents);
@ -143,21 +143,23 @@ public:
}
sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
if (!fProxy) {
if (!fReadView.asTextureProxy()) {
return nullptr;
}
GrColorType ct = SkColorTypeToGrColorType(fCanvas->imageInfo().colorType());
// Note: SkSpecialImages can only be snapShotted once, so this call is destructive and we
// move fReadMove.
return SkSpecialImage::MakeDeferredFromGpu(fCanvas->getGrContext(),
this->subset(),
kNeedNewImageUniqueID_SpecialImage,
std::move(fProxy), ct,
std::move(fReadView), ct,
fCanvas->imageInfo().refColorSpace(),
&this->props());
}
private:
sk_sp<GrTextureProxy> fProxy;
GrSurfaceProxyView fReadView;
typedef SkSpecialSurface_Base INHERITED;
};

View File

@ -341,12 +341,12 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::Make(GrRecordingContext*
SkASSERT(kPremul_SkAlphaType == bitmap.alphaType());
SkASSERT(bitmap.isImmutable());
sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(context, bitmap);
if (!proxy) {
auto view = GrMakeCachedBitmapProxyView(context, bitmap);
if (!view.proxy()) {
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(new ColorTableEffect(std::move(proxy)));
return std::unique_ptr<GrFragmentProcessor>(new ColorTableEffect(view.detachProxy()));
}
void ColorTableEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,

View File

@ -412,7 +412,7 @@ sk_sp<SkSpecialImage> ArithmeticImageFilterImpl::filterImageGPU(
return SkSpecialImage::MakeDeferredFromGpu(context,
SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
renderTargetContext->asTextureProxyRef(),
renderTargetContext->readSurfaceView(),
renderTargetContext->colorInfo().colorType(),
renderTargetContext->colorInfo().refColorSpace());
}

View File

@ -669,7 +669,7 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::gpuFilter(
return SkSpecialImage::MakeDeferredFromGpu(context,
SkIRect::MakeSize(dstBounds.size()),
kNeedNewImageUniqueID_SpecialImage,
renderTargetContext->asTextureProxyRef(),
renderTargetContext->readSurfaceView(),
renderTargetContext->colorInfo().colorType(),
sk_ref_sp(input->getColorSpace()),
ctx.surfaceProps());

View File

@ -379,7 +379,7 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffectImpl::onFilterImage(const Context&
context,
SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
renderTargetContext->asTextureProxyRef(),
renderTargetContext->readSurfaceView(),
renderTargetContext->colorInfo().colorType(),
renderTargetContext->colorInfo().refColorSpace());
}

View File

@ -537,7 +537,7 @@ sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(
context,
SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()),
kNeedNewImageUniqueID_SpecialImage,
renderTargetContext->asTextureProxyRef(),
renderTargetContext->readSurfaceView(),
renderTargetContext->colorInfo().colorType(),
renderTargetContext->colorInfo().refColorSpace());
}

View File

@ -209,19 +209,19 @@ SkIRect SkMorphologyImageFilterImpl::onFilterNodeBounds(
*/
class GrMorphologyEffect : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view,
SkAlphaType srcAlphaType, MorphDirection dir,
int radius, MorphType type) {
return std::unique_ptr<GrFragmentProcessor>(
new GrMorphologyEffect(std::move(proxy), srcAlphaType, dir, radius, type, nullptr));
new GrMorphologyEffect(std::move(view), srcAlphaType, dir, radius, type, nullptr));
}
static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view,
SkAlphaType srcAlphaType, MorphDirection dir,
int radius, MorphType type,
const float bounds[2]) {
return std::unique_ptr<GrFragmentProcessor>(
new GrMorphologyEffect(std::move(proxy), srcAlphaType, dir, radius, type, bounds));
new GrMorphologyEffect(std::move(view), srcAlphaType, dir, radius, type, bounds));
}
MorphType type() const { return fType; }
@ -254,7 +254,7 @@ private:
const TextureSampler& onTextureSampler(int i) const override { return fTextureSampler; }
GrMorphologyEffect(sk_sp<GrTextureProxy>, SkAlphaType srcAlphaType, MorphDirection, int radius,
GrMorphologyEffect(GrSurfaceProxyView, SkAlphaType srcAlphaType, MorphDirection, int radius,
MorphType, const float range[2]);
explicit GrMorphologyEffect(const GrMorphologyEffect&);
@ -393,15 +393,15 @@ void GrGLMorphologyEffect::onSetData(const GrGLSLProgramDataManager& pdman,
///////////////////////////////////////////////////////////////////////////////
GrMorphologyEffect::GrMorphologyEffect(sk_sp<GrTextureProxy> proxy,
GrMorphologyEffect::GrMorphologyEffect(GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
MorphDirection direction,
int radius,
MorphType type,
const float range[2])
: INHERITED(kGrMorphologyEffect_ClassID, ModulateForClampedSamplerOptFlags(srcAlphaType))
, fCoordTransform(proxy.get())
, fTextureSampler(std::move(proxy))
, fCoordTransform(view.proxy())
, fTextureSampler(std::move(view))
, fDirection(direction)
, fRadius(radius)
, fType(type)
@ -457,17 +457,21 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMorphologyEffect);
std::unique_ptr<GrFragmentProcessor> GrMorphologyEffect::TestCreate(GrProcessorTestData* d) {
auto [proxy, ct, at] = d->randomProxy();
GrSurfaceOrigin origin = proxy->origin();
GrSwizzle swizzle = proxy->textureSwizzle();
GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
MorphDirection dir = d->fRandom->nextBool() ? MorphDirection::kX : MorphDirection::kY;
static const int kMaxRadius = 10;
int radius = d->fRandom->nextRangeU(1, kMaxRadius);
MorphType type = d->fRandom->nextBool() ? MorphType::kErode : MorphType::kDilate;
return GrMorphologyEffect::Make(std::move(proxy), at, dir, radius, type);
return GrMorphologyEffect::Make(std::move(view), at, dir, radius, type);
}
#endif
static void apply_morphology_rect(GrRenderTargetContext* renderTargetContext,
const GrClip& clip,
sk_sp<GrTextureProxy> proxy,
GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
const SkIRect& srcRect,
const SkIRect& dstRect,
@ -476,7 +480,7 @@ static void apply_morphology_rect(GrRenderTargetContext* renderTargetContext,
const float bounds[2],
MorphDirection direction) {
GrPaint paint;
paint.addColorFragmentProcessor(GrMorphologyEffect::Make(std::move(proxy), srcAlphaType,
paint.addColorFragmentProcessor(GrMorphologyEffect::Make(std::move(view), srcAlphaType,
direction, radius, morphType, bounds));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
@ -485,7 +489,7 @@ static void apply_morphology_rect(GrRenderTargetContext* renderTargetContext,
static void apply_morphology_rect_no_bounds(GrRenderTargetContext* renderTargetContext,
const GrClip& clip,
sk_sp<GrTextureProxy> proxy,
GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
const SkIRect& srcRect,
const SkIRect& dstRect,
@ -494,7 +498,7 @@ static void apply_morphology_rect_no_bounds(GrRenderTargetContext* renderTargetC
MorphDirection direction) {
GrPaint paint;
paint.addColorFragmentProcessor(
GrMorphologyEffect::Make(std::move(proxy), srcAlphaType, direction, radius, morphType));
GrMorphologyEffect::Make(std::move(view), srcAlphaType, direction, radius, morphType));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
renderTargetContext->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(),
SkRect::Make(dstRect), SkRect::Make(srcRect));
@ -502,7 +506,7 @@ static void apply_morphology_rect_no_bounds(GrRenderTargetContext* renderTargetC
static void apply_morphology_pass(GrRenderTargetContext* renderTargetContext,
const GrClip& clip,
sk_sp<GrTextureProxy> textureProxy,
GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
const SkIRect& srcRect,
const SkIRect& dstRect,
@ -534,15 +538,15 @@ static void apply_morphology_pass(GrRenderTargetContext* renderTargetContext,
}
if (middleSrcRect.width() <= 0) {
// radius covers srcRect; use bounds over entire draw
apply_morphology_rect(renderTargetContext, clip, std::move(textureProxy), srcAlphaType,
srcRect, dstRect, radius, morphType, bounds, direction);
apply_morphology_rect(renderTargetContext, clip, std::move(view), srcAlphaType, srcRect,
dstRect, radius, morphType, bounds, direction);
} else {
// Draw upper and lower margins with bounds; middle without.
apply_morphology_rect(renderTargetContext, clip, textureProxy, srcAlphaType, lowerSrcRect,
apply_morphology_rect(renderTargetContext, clip, view, srcAlphaType, lowerSrcRect,
lowerDstRect, radius, morphType, bounds, direction);
apply_morphology_rect(renderTargetContext, clip, textureProxy, srcAlphaType, upperSrcRect,
apply_morphology_rect(renderTargetContext, clip, view, srcAlphaType, upperSrcRect,
upperDstRect, radius, morphType, bounds, direction);
apply_morphology_rect_no_bounds(renderTargetContext, clip, std::move(textureProxy),
apply_morphology_rect_no_bounds(renderTargetContext, clip, std::move(view),
srcAlphaType, middleSrcRect, middleDstRect, radius,
morphType, direction);
}
@ -551,14 +555,16 @@ static void apply_morphology_pass(GrRenderTargetContext* renderTargetContext,
static sk_sp<SkSpecialImage> apply_morphology(
GrRecordingContext* context, SkSpecialImage* input, const SkIRect& rect,
MorphType morphType, SkISize radius, const SkImageFilter_Base::Context& ctx) {
sk_sp<GrTextureProxy> srcTexture(input->asTextureProxyRef(context));
GrSurfaceProxyView srcView = input->asSurfaceProxyViewRef(context);
SkAlphaType srcAlphaType = input->alphaType();
SkASSERT(srcTexture);
SkASSERT(srcView.asTextureProxy());
sk_sp<SkColorSpace> colorSpace = ctx.refColorSpace();
GrColorType colorType = ctx.grColorType();
GrSurfaceProxy* proxy = srcView.proxy();
// setup new clip
const GrFixedClip clip(SkIRect::MakeSize(srcTexture->dimensions()));
const GrFixedClip clip(SkIRect::MakeSize(proxy->dimensions()));
const SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
SkIRect srcRect = rect;
@ -569,12 +575,12 @@ static sk_sp<SkSpecialImage> apply_morphology(
if (radius.fWidth > 0) {
auto dstRTContext = GrRenderTargetContext::Make(
context, colorType, colorSpace, SkBackingFit::kApprox, rect.size(), 1,
GrMipMapped::kNo, srcTexture->isProtected(), kBottomLeft_GrSurfaceOrigin);
GrMipMapped::kNo, proxy->isProtected(), kBottomLeft_GrSurfaceOrigin);
if (!dstRTContext) {
return nullptr;
}
apply_morphology_pass(dstRTContext.get(), clip, std::move(srcTexture), srcAlphaType,
apply_morphology_pass(dstRTContext.get(), clip, std::move(srcView), srcAlphaType,
srcRect, dstRect, radius.fWidth, morphType, MorphDirection::kX);
SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom,
dstRect.width(), radius.fHeight);
@ -582,28 +588,28 @@ static sk_sp<SkSpecialImage> apply_morphology(
? SK_PMColor4fWHITE : SK_PMColor4fTRANSPARENT;
dstRTContext->clear(&clearRect, clearColor, GrRenderTargetContext::CanClearFullscreen::kNo);
srcTexture = dstRTContext->asTextureProxyRef();
srcView = dstRTContext->readSurfaceView();
srcAlphaType = dstRTContext->colorInfo().alphaType();
srcRect = dstRect;
}
if (radius.fHeight > 0) {
auto dstRTContext = GrRenderTargetContext::Make(
context, colorType, colorSpace, SkBackingFit::kApprox, rect.size(), 1,
GrMipMapped::kNo, srcTexture->isProtected(), kBottomLeft_GrSurfaceOrigin);
GrMipMapped::kNo, srcView.proxy()->isProtected(), kBottomLeft_GrSurfaceOrigin);
if (!dstRTContext) {
return nullptr;
}
apply_morphology_pass(dstRTContext.get(), clip, std::move(srcTexture), srcAlphaType,
apply_morphology_pass(dstRTContext.get(), clip, std::move(srcView), srcAlphaType,
srcRect, dstRect, radius.fHeight, morphType, MorphDirection::kY);
srcTexture = dstRTContext->asTextureProxyRef();
srcView = dstRTContext->readSurfaceView();
}
return SkSpecialImage::MakeDeferredFromGpu(context,
SkIRect::MakeWH(rect.width(), rect.height()),
kNeedNewImageUniqueID_SpecialImage,
std::move(srcTexture), colorType,
std::move(srcView), colorType,
std::move(colorSpace), &input->props());
}
#endif

View File

@ -317,7 +317,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilterImpl::filterImageGPU(
return SkSpecialImage::MakeDeferredFromGpu(context,
SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
renderTargetContext->asTextureProxyRef(),
renderTargetContext->readSurfaceView(),
renderTargetContext->colorInfo().colorType(),
renderTargetContext->colorInfo().refColorSpace());
}

View File

@ -13,6 +13,7 @@
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/GrSurfaceProxy.h"
#include "src/gpu/GrSwizzle.h"
#include "src/gpu/GrTextureProxy.h"
class GrSurfaceProxyView {
public:
@ -68,7 +69,7 @@ public:
*this = {};
}
// This does not reset the origin or proxy, so the View can still be used to access those
// This does not reset the origin or swizzle, so the View can still be used to access those
// properties associated with the detached proxy.
sk_sp<GrSurfaceProxy> detachProxy() {
return std::move(fProxy);

View File

@ -1190,19 +1190,19 @@ void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap,
sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
// TODO: this makes a tight copy of 'bitmap' but it doesn't have to be (given SkSpecialImage's
// semantics). Since this is cached we would have to bake the fit into the cache key though.
sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(fContext.get(), bitmap);
if (!proxy) {
auto view = GrMakeCachedBitmapProxyView(fContext.get(), bitmap);
if (!view.proxy()) {
return nullptr;
}
const SkIRect rect = SkIRect::MakeSize(proxy->dimensions());
const SkIRect rect = SkIRect::MakeSize(view.proxy()->dimensions());
// GrMakeCachedBitmapProxy creates a tight copy of 'bitmap' so we don't have to subset
// GrMakeCachedBitmapProxyView creates a tight copy of 'bitmap' so we don't have to subset
// the special image
return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
rect,
bitmap.getGenerationID(),
std::move(proxy),
std::move(view),
SkColorTypeToGrColorType(bitmap.colorType()),
bitmap.refColorSpace(),
&this->surfaceProps());
@ -1211,12 +1211,12 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
SkPixmap pm;
if (image->isTextureBacked()) {
sk_sp<GrTextureProxy> proxy = as_IB(image)->asTextureProxyRef(this->context());
auto view = as_IB(image)->asSurfaceProxyViewRef(this->context());
return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
SkIRect::MakeWH(image->width(), image->height()),
image->uniqueID(),
std::move(proxy),
std::move(view),
SkColorTypeToGrColorType(image->colorType()),
image->refColorSpace(),
&this->surfaceProps());
@ -1244,24 +1244,25 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial(const SkIRect& subset, bool force
SkASSERT(rtc->asSurfaceProxy());
SkIRect finalSubset = subset;
sk_sp<GrTextureProxy> proxy(rtc->asTextureProxyRef());
if (forceCopy || !proxy) {
GrSurfaceProxyView view = rtc->readSurfaceView();
if (forceCopy || !view.asTextureProxy()) {
// When the device doesn't have a texture, or a copy is requested, we create a temporary
// texture that matches the device contents
proxy = GrSurfaceProxy::Copy(fContext.get(),
rtc->asSurfaceProxy(),
rtc->colorInfo().colorType(),
GrMipMapped::kNo, // Don't auto generate mips
subset,
SkBackingFit::kApprox,
SkBudgeted::kYes); // Always budgeted
auto proxy = GrSurfaceProxy::Copy(fContext.get(),
rtc->asSurfaceProxy(),
rtc->colorInfo().colorType(),
GrMipMapped::kNo, // Don't auto generate mips
subset,
SkBackingFit::kApprox,
SkBudgeted::kYes); // Always budgeted
if (!proxy) {
return nullptr;
}
view = GrSurfaceProxyView(std::move(proxy), view.origin(), view.swizzle());
// Since this copied only the requested subset, the special image wrapping the proxy no
// longer needs the original subset.
finalSubset = SkIRect::MakeSize(proxy->dimensions());
finalSubset = SkIRect::MakeSize(view.proxy()->dimensions());
}
GrColorType ct = SkColorTypeToGrColorType(this->imageInfo().colorType());
@ -1269,7 +1270,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial(const SkIRect& subset, bool force
return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
finalSubset,
kNeedNewImageUniqueID_SpecialImage,
std::move(proxy),
std::move(view),
ct,
this->imageInfo().refColorSpace(),
&this->surfaceProps());

View File

@ -144,16 +144,21 @@ sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrRecordingContext* ctx,
return maker.refTextureProxyForParams(params, scaleAdjust);
}
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrRecordingContext* context,
const SkBitmap& bitmap,
SkBackingFit fit) {
GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext* context, const SkBitmap& bitmap,
SkBackingFit fit) {
if (!bitmap.peekPixels(nullptr)) {
return nullptr;
return {};
}
GrBitmapTextureMaker maker(context, bitmap, GrBitmapTextureMaker::Cached::kYes, fit);
auto [proxy, ct] = maker.refTextureProxy(GrMipMapped::kNo);
return proxy;
if (!proxy) {
return {};
}
GrSurfaceOrigin origin = proxy->origin();
GrSwizzle swizzle = proxy->textureSwizzle();
return GrSurfaceProxyView(std::move(proxy), origin, swizzle);
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -188,8 +188,8 @@ sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrRecordingContext*,
* Create a texture proxy from the provided bitmap and add it to the texture cache
* using the key also extracted from 'bitmp'.
*/
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrRecordingContext*, const SkBitmap& bitmap,
SkBackingFit fit = SkBackingFit::kExact);
GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext*, const SkBitmap& bitmap,
SkBackingFit fit = SkBackingFit::kExact);
/**
* Our key includes the offset, width, and height so that bitmaps created by extractSubset()

View File

@ -59,13 +59,13 @@ static std::unique_ptr<GrFragmentProcessor> make_textured_colorizer(const SkPMCo
SkASSERT(1 == bitmap.height() && SkIsPow2(bitmap.width()));
SkASSERT(bitmap.isImmutable());
sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(args.fContext, bitmap);
if (proxy == nullptr) {
auto view = GrMakeCachedBitmapProxyView(args.fContext, bitmap);
if (!view.proxy()) {
SkDebugf("Gradient won't draw. Could not create texture.");
return nullptr;
}
return GrTextureGradientColorizer::Make(std::move(proxy));
return GrTextureGradientColorizer::Make(view.detachProxy());
}
// Analyze the shader's color stops and positions and chooses an appropriate colorizer to represent

View File

@ -718,11 +718,11 @@ public:
static std::unique_ptr<GrFragmentProcessor> Make(
SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles,
std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
sk_sp<GrTextureProxy> permutationsProxy, sk_sp<GrTextureProxy> noiseProxy,
GrSurfaceProxyView permutationsView, GrSurfaceProxyView noiseView,
const SkMatrix& matrix) {
return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect(
type, numOctaves, stitchTiles, std::move(paintingData),
std::move(permutationsProxy), std::move(noiseProxy), matrix));
std::move(permutationsView), std::move(noiseView), matrix));
}
const char* name() const override { return "PerlinNoise"; }
@ -760,15 +760,15 @@ private:
GrPerlinNoise2Effect(SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles,
std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
sk_sp<GrTextureProxy> permutationsProxy,
sk_sp<GrTextureProxy> noiseProxy,
GrSurfaceProxyView permutationsView,
GrSurfaceProxyView noiseView,
const SkMatrix& matrix)
: INHERITED(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags)
, fType(type)
, fNumOctaves(numOctaves)
, fStitchTiles(stitchTiles)
, fPermutationsSampler(std::move(permutationsProxy))
, fNoiseSampler(std::move(noiseProxy))
, fPermutationsSampler(std::move(permutationsView))
, fNoiseSampler(std::move(noiseView))
, fPaintingData(std::move(paintingData)) {
this->setTextureSamplerCnt(2);
fCoordTransform = GrCoordTransform(matrix);
@ -1143,11 +1143,11 @@ public:
static std::unique_ptr<GrFragmentProcessor> Make(
int octaves, SkScalar z,
std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
sk_sp<GrTextureProxy> permutationsProxy, sk_sp<GrTextureProxy> gradientProxy,
GrSurfaceProxyView permutationsView, GrSurfaceProxyView gradientView,
const SkMatrix& matrix) {
return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect(
octaves, z, std::move(paintingData), std::move(permutationsProxy),
std::move(gradientProxy), matrix));
octaves, z, std::move(paintingData), std::move(permutationsView),
std::move(gradientView), matrix));
}
const char* name() const override { return "ImprovedPerlinNoise"; }
@ -1178,14 +1178,14 @@ private:
GrImprovedPerlinNoiseEffect(int octaves, SkScalar z,
std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData,
sk_sp<GrTextureProxy> permutationsProxy,
sk_sp<GrTextureProxy> gradientProxy,
GrSurfaceProxyView permutationsView,
GrSurfaceProxyView gradientView,
const SkMatrix& matrix)
: INHERITED(kGrImprovedPerlinNoiseEffect_ClassID, kNone_OptimizationFlags)
, fOctaves(octaves)
, fZ(z)
, fPermutationsSampler(std::move(permutationsProxy))
, fGradientSampler(std::move(gradientProxy))
, fPermutationsSampler(std::move(permutationsView))
, fGradientSampler(std::move(gradientView))
, fPaintingData(std::move(paintingData)) {
this->setTextureSamplerCnt(2);
fCoordTransform = GrCoordTransform(matrix);
@ -1424,15 +1424,14 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
// go through GrBitmapTextureMaker to handle needed copies.
const SkBitmap& permutationsBitmap = paintingData->getImprovedPermutationsBitmap();
SkASSERT(SkIsPow2(permutationsBitmap.width()) && SkIsPow2(permutationsBitmap.height()));
sk_sp<GrTextureProxy> permutationsTexture(
GrMakeCachedBitmapProxy(context, permutationsBitmap));
auto permutationsView = GrMakeCachedBitmapProxyView(context, permutationsBitmap);
const SkBitmap& gradientBitmap = paintingData->getGradientBitmap();
SkASSERT(SkIsPow2(gradientBitmap.width()) && SkIsPow2(gradientBitmap.height()));
sk_sp<GrTextureProxy> gradientTexture(GrMakeCachedBitmapProxy(context, gradientBitmap));
auto gradientView = GrMakeCachedBitmapProxyView(context, gradientBitmap);
return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, fSeed, std::move(paintingData),
std::move(permutationsTexture),
std::move(gradientTexture), m);
std::move(permutationsView),
std::move(gradientView), m);
}
if (0 == fNumOctaves) {
@ -1456,19 +1455,19 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
// through GrBitmapTextureMaker to handle needed copies.
const SkBitmap& permutationsBitmap = paintingData->getPermutationsBitmap();
SkASSERT(SkIsPow2(permutationsBitmap.width()) && SkIsPow2(permutationsBitmap.height()));
sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedBitmapProxy(context, permutationsBitmap);
auto permutationsView = GrMakeCachedBitmapProxyView(context, permutationsBitmap);
const SkBitmap& noiseBitmap = paintingData->getNoiseBitmap();
SkASSERT(SkIsPow2(noiseBitmap.width()) && SkIsPow2(noiseBitmap.height()));
sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedBitmapProxy(context, noiseBitmap);
auto noiseView = GrMakeCachedBitmapProxyView(context, noiseBitmap);
if (permutationsProxy && noiseProxy) {
if (permutationsView.proxy() && noiseView.proxy()) {
auto inner = GrPerlinNoise2Effect::Make(fType,
fNumOctaves,
fStitchTiles,
std::move(paintingData),
std::move(permutationsProxy),
std::move(noiseProxy),
std::move(permutationsView),
std::move(noiseView),
m);
return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
}

View File

@ -207,25 +207,31 @@ DEF_TEST(ImageFilterCache_ImageBackedRaster, reporter) {
#include "src/gpu/GrSurfaceProxyPriv.h"
#include "src/gpu/GrTextureProxy.h"
static sk_sp<GrTextureProxy> create_proxy(GrRecordingContext* context) {
static GrSurfaceProxyView create_proxy_view(GrRecordingContext* context) {
SkBitmap srcBM = create_bm();
GrBitmapTextureMaker maker(context, srcBM);
auto [proxy, grCT] = maker.refTextureProxy(GrMipMapped::kNo);
return proxy;
if (!proxy) {
return {};
}
GrSurfaceOrigin origin = proxy->origin();
GrSwizzle swizzle = proxy->textureSwizzle();
return {std::move(proxy), origin, swizzle};
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrTextureProxy> srcProxy(create_proxy(context));
if (!srcProxy) {
GrSurfaceProxyView srcView = create_proxy_view(context);
if (!srcView.proxy()) {
return;
}
if (!srcProxy->instantiate(context->priv().resourceProvider())) {
if (!srcView.proxy()->instantiate(context->priv().resourceProvider())) {
return;
}
GrTexture* tex = srcProxy->peekTexture();
GrTexture* tex = srcView.proxy()->peekTexture();
GrBackendTexture backendTex = tex->getBackendTexture();
@ -258,8 +264,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ct
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_GPUBacked, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
sk_sp<GrTextureProxy> srcProxy(create_proxy(context));
if (!srcProxy) {
GrSurfaceProxyView srcView = create_proxy_view(context);
if (!srcView.proxy()) {
return;
}
@ -268,7 +274,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_GPUBacked, reporter, ctxInfo
sk_sp<SkSpecialImage> fullImg(SkSpecialImage::MakeDeferredFromGpu(
context, full,
kNeedNewImageUniqueID_SpecialImage,
srcProxy,
srcView,
GrColorType::kRGBA_8888, nullptr));
const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
@ -276,7 +282,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_GPUBacked, reporter, ctxInfo
sk_sp<SkSpecialImage> subsetImg(SkSpecialImage::MakeDeferredFromGpu(
context, subset,
kNeedNewImageUniqueID_SpecialImage,
srcProxy,
std::move(srcView),
GrColorType::kRGBA_8888, nullptr));
test_find_existing(reporter, fullImg, subsetImg);

View File

@ -229,11 +229,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_MakeTexture, reporter, ctxInfo)
return;
}
GrSurfaceOrigin origin = proxy->origin();
GrSwizzle swizzle = proxy->textureSwizzle();
GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
sk_sp<SkSpecialImage> gpuImage(SkSpecialImage::MakeDeferredFromGpu(
context,
SkIRect::MakeWH(kFullSize, kFullSize),
kNeedNewImageUniqueID_SpecialImage,
std::move(proxy),
std::move(view),
grCT,
nullptr));
@ -260,11 +264,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) {
return;
}
GrSurfaceOrigin origin = proxy->origin();
GrSwizzle swizzle = proxy->textureSwizzle();
GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
sk_sp<SkSpecialImage> fullSImg(SkSpecialImage::MakeDeferredFromGpu(
context,
SkIRect::MakeWH(kFullSize, kFullSize),
kNeedNewImageUniqueID_SpecialImage,
proxy,
view,
grCT,
nullptr));
@ -274,7 +282,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) {
sk_sp<SkSpecialImage> subSImg1(SkSpecialImage::MakeDeferredFromGpu(
context, subset,
kNeedNewImageUniqueID_SpecialImage,
std::move(proxy),
std::move(view),
grCT,
nullptr));
test_image(subSImg1, reporter, context, true);