Add GrSurfaceFillContext
This is a new base class for GrSurfaceDrawContext. It allows any
alpha-type but is restricted to non-blending fills of irects using FPs,
clears,and discards.
Bug: skia:11019
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341680
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Change-Id: I696df3617719fcd8303faa73fb44b32b3fb4f71c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344896
diff --git a/gm/clear_swizzle.cpp b/gm/clear_swizzle.cpp
index 268a53a4..aeec946 100644
--- a/gm/clear_swizzle.cpp
+++ b/gm/clear_swizzle.cpp
@@ -23,10 +23,11 @@
auto make_offscreen = [&](const SkISize dimensions) {
GrSwizzle readSwizzle = GrSwizzle::Concat(rtCtx->readSwizzle(), GrSwizzle{"bgra"});
GrSwizzle writeSwizzle = GrSwizzle::Concat(rtCtx->readSwizzle(), GrSwizzle{"bgra"});
- return GrSurfaceDrawContext::Make(ctx,
+ return GrSurfaceFillContext::Make(ctx,
+ kPremul_SkAlphaType,
rtCtx->colorInfo().refColorSpace(),
- SkBackingFit::kExact,
dimensions,
+ SkBackingFit::kExact,
rtCtx->asSurfaceProxy()->backendFormat(),
/* sample count*/ 1,
GrMipmapped::kNo,
@@ -34,8 +35,7 @@
readSwizzle,
writeSwizzle,
kTopLeft_GrSurfaceOrigin,
- SkBudgeted::kYes,
- /* surface props */ nullptr);
+ SkBudgeted::kYes);
};
struct {
diff --git a/gm/samplelocations.cpp b/gm/samplelocations.cpp
index 9ff6454..11e2b7a 100644
--- a/gm/samplelocations.cpp
+++ b/gm/samplelocations.cpp
@@ -358,7 +358,7 @@
0xffff>()
);
- offscreenRTC->clear({0,1,0,1});
+ offscreenRTC->clear(SkPMColor4f{0, 1, 0, 1});
// Stencil.
offscreenRTC->addDrawOp(SampleLocationsTestOp::Make(ctx, canvas->getTotalMatrix(), fGradType));
diff --git a/gn/gpu.gni b/gn/gpu.gni
index d8f87a6..fcda974 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -224,6 +224,8 @@
"$_src/gpu/GrSurfaceContext.h",
"$_src/gpu/GrSurfaceDrawContext.cpp",
"$_src/gpu/GrSurfaceDrawContext.h",
+ "$_src/gpu/GrSurfaceFillContext.cpp",
+ "$_src/gpu/GrSurfaceFillContext.h",
"$_src/gpu/GrSurfaceProxy.cpp",
"$_src/gpu/GrSurfaceProxy.h",
"$_src/gpu/GrSurfaceProxyPriv.h",
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 1ecd385..794688b 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -63,6 +63,18 @@
return SkIRect{0, 0, size.fWidth, size.fHeight};
}
+ /** Returns constructed SkIRect set to (pt.x(), pt.y(), pt.x() + size.width(),
+ pt.y() + size.height()). Does not validate input; size.width() or size.height() may be
+ negative.
+
+ @param pt values for SkIRect fLeft and fTop
+ @param size values for SkIRect width and height
+ @return bounds at pt with width and height of size
+ */
+ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakePtSize(SkIPoint pt, SkISize size) {
+ return MakeXYWH(pt.x(), pt.y(), size.width(), size.height());
+ }
+
/** Returns constructed SkIRect set to (l, t, r, b). Does not sort input; SkIRect may
result in fLeft greater than fRight, or fTop greater than fBottom.
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 143fbdb..08da5a0 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -591,28 +591,32 @@
SkColorType colorType,
const SkColorSpace* colorSpace,
GrProtected isProtected) {
- GrPaint paint;
- paint.setColorFragmentProcessor(std::move(fp));
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ GrImageInfo info(SkColorTypeToGrColorType(colorType),
+ kPremul_SkAlphaType,
+ sk_ref_sp(colorSpace),
+ bounds.size());
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- context, SkColorTypeToGrColorType(colorType), sk_ref_sp(colorSpace),
- SkBackingFit::kApprox, bounds.size(), 1, GrMipmapped::kNo, isProtected,
- kBottomLeft_GrSurfaceOrigin);
- if (!surfaceDrawContext) {
+ auto surfaceFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kApprox,
+ 1,
+ GrMipmapped::kNo,
+ isProtected,
+ kBottomLeft_GrSurfaceOrigin);
+ if (!surfaceFillContext) {
return nullptr;
}
SkIRect dstIRect = SkIRect::MakeWH(bounds.width(), bounds.height());
SkRect srcRect = SkRect::Make(bounds);
- SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
- surfaceDrawContext->fillRectToRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- dstRect, srcRect);
+ surfaceFillContext->fillRectToRectWithFP(srcRect, dstIRect, std::move(fp));
- return SkSpecialImage::MakeDeferredFromGpu(
- context, dstIRect, kNeedNewImageUniqueID_SpecialImage,
- surfaceDrawContext->readSurfaceView(), surfaceDrawContext->colorInfo().colorType(),
- surfaceDrawContext->colorInfo().refColorSpace());
+ return SkSpecialImage::MakeDeferredFromGpu(context,
+ dstIRect,
+ kNeedNewImageUniqueID_SpecialImage,
+ surfaceFillContext->readSurfaceView(),
+ surfaceFillContext->colorInfo().colorType(),
+ surfaceFillContext->colorInfo().refColorSpace());
}
sk_sp<SkSpecialImage> SkImageFilter_Base::ImageToColorSpace(SkSpecialImage* src,
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index 0ad8b0c..1a954e6 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -331,8 +331,7 @@
isProtected = foregroundView.proxy()->isProtected();
}
- GrPaint paint;
- std::unique_ptr<GrFragmentProcessor> bgFP;
+ std::unique_ptr<GrFragmentProcessor> fp;
const auto& caps = *ctx.getContext()->priv().caps();
GrSamplerState sampler(GrSamplerState::WrapMode::kClampToBorder,
GrSamplerState::Filter::kNearest);
@@ -342,13 +341,19 @@
SkMatrix backgroundMatrix = SkMatrix::Translate(
SkIntToScalar(bgSubset.left() - backgroundOffset.fX),
SkIntToScalar(bgSubset.top() - backgroundOffset.fY));
- bgFP = GrTextureEffect::MakeSubset(std::move(backgroundView), background->alphaType(),
- backgroundMatrix, sampler, bgSubset, caps);
- bgFP = GrColorSpaceXformEffect::Make(std::move(bgFP),
- background->getColorSpace(), background->alphaType(),
- ctx.colorSpace(), kPremul_SkAlphaType);
+ fp = GrTextureEffect::MakeSubset(std::move(backgroundView),
+ background->alphaType(),
+ backgroundMatrix,
+ sampler,
+ bgSubset,
+ caps);
+ fp = GrColorSpaceXformEffect::Make(std::move(fp),
+ background->getColorSpace(),
+ background->alphaType(),
+ ctx.colorSpace(),
+ kPremul_SkAlphaType);
} else {
- bgFP = GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT);
+ fp = GrConstColorProcessor::Make(SK_PMColor4fTRANSPARENT);
}
if (foreground) {
@@ -356,37 +361,41 @@
SkMatrix foregroundMatrix = SkMatrix::Translate(
SkIntToScalar(fgSubset.left() - foregroundOffset.fX),
SkIntToScalar(fgSubset.top() - foregroundOffset.fY));
- auto fgFP = GrTextureEffect::MakeSubset(std::move(foregroundView), foreground->alphaType(),
- foregroundMatrix, sampler, fgSubset, caps);
+ auto fgFP = GrTextureEffect::MakeSubset(std::move(foregroundView),
+ foreground->alphaType(),
+ foregroundMatrix,
+ sampler,
+ fgSubset,
+ caps);
fgFP = GrColorSpaceXformEffect::Make(std::move(fgFP),
- foreground->getColorSpace(), foreground->alphaType(),
- ctx.colorSpace(), kPremul_SkAlphaType);
- paint.setColorFragmentProcessor(
- GrArithmeticProcessor::Make(std::move(fgFP), std::move(bgFP), fInputs));
- } else {
- paint.setColorFragmentProcessor(std::move(bgFP));
+ foreground->getColorSpace(),
+ foreground->alphaType(),
+ ctx.colorSpace(),
+ kPremul_SkAlphaType);
+ fp = GrArithmeticProcessor::Make(std::move(fgFP), std::move(fp), fInputs);
}
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- context, ctx.grColorType(), ctx.refColorSpace(), SkBackingFit::kApprox, bounds.size(),
- 1, GrMipmapped::kNo, isProtected, kBottomLeft_GrSurfaceOrigin);
- if (!surfaceDrawContext) {
+ GrImageInfo info(ctx.grColorType(), kPremul_SkAlphaType, ctx.refColorSpace(), bounds.size());
+ auto surfaceFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kApprox,
+ 1,
+ GrMipmapped::kNo,
+ isProtected,
+ kBottomLeft_GrSurfaceOrigin);
+ if (!surfaceFillContext) {
return nullptr;
}
- SkMatrix matrix;
- matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
- surfaceDrawContext->drawRect(nullptr, std::move(paint), GrAA::kNo, matrix,
- SkRect::Make(bounds));
+ surfaceFillContext->fillRectToRectWithFP(bounds, SkIRect::MakeSize(bounds.size()),
+ std::move(fp));
return SkSpecialImage::MakeDeferredFromGpu(context,
SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
- surfaceDrawContext->readSurfaceView(),
- surfaceDrawContext->colorInfo().colorType(),
- surfaceDrawContext->colorInfo().refColorSpace());
+ surfaceFillContext->readSurfaceView(),
+ surfaceFillContext->colorInfo().colorType(),
+ surfaceFillContext->colorInfo().refColorSpace());
}
#endif
diff --git a/src/effects/imagefilters/SkDisplacementMapEffect.cpp b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
index 81ffb15..64057da 100644
--- a/src/effects/imagefilters/SkDisplacementMapEffect.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapEffect.cpp
@@ -340,32 +340,33 @@
fp = GrColorSpaceXformEffect::Make(std::move(fp),
color->getColorSpace(), color->alphaType(),
ctx.colorSpace(), kPremul_SkAlphaType);
-
- GrPaint paint;
- paint.setColorFragmentProcessor(std::move(fp));
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- SkMatrix matrix;
- matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
-
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- context, ctx.grColorType(), ctx.refColorSpace(), SkBackingFit::kApprox,
- bounds.size(), 1, GrMipmapped::kNo, isProtected, kBottomLeft_GrSurfaceOrigin);
- if (!surfaceDrawContext) {
+ GrImageInfo info(ctx.grColorType(),
+ kPremul_SkAlphaType,
+ ctx.refColorSpace(),
+ bounds.size());
+ auto surfaceFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kApprox,
+ 1,
+ GrMipmapped::kNo,
+ isProtected,
+ kBottomLeft_GrSurfaceOrigin);
+ if (!surfaceFillContext) {
return nullptr;
}
- surfaceDrawContext->drawRect(nullptr, std::move(paint), GrAA::kNo, matrix,
- SkRect::Make(colorBounds));
+ surfaceFillContext->fillRectToRectWithFP(colorBounds,
+ SkIRect::MakeSize(colorBounds.size()),
+ std::move(fp));
offset->fX = bounds.left();
offset->fY = bounds.top();
- return SkSpecialImage::MakeDeferredFromGpu(
- context,
- SkIRect::MakeWH(bounds.width(), bounds.height()),
- kNeedNewImageUniqueID_SpecialImage,
- surfaceDrawContext->readSurfaceView(),
- surfaceDrawContext->colorInfo().colorType(),
- surfaceDrawContext->colorInfo().refColorSpace());
+ return SkSpecialImage::MakeDeferredFromGpu(context,
+ SkIRect::MakeWH(bounds.width(), bounds.height()),
+ kNeedNewImageUniqueID_SpecialImage,
+ surfaceFillContext->readSurfaceView(),
+ surfaceFillContext->colorInfo().colorType(),
+ surfaceFillContext->colorInfo().refColorSpace());
}
#endif
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index 42ca4ba..0e04952 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -441,10 +441,10 @@
private:
#if SK_SUPPORT_GPU
- void drawRect(GrSurfaceDrawContext*,
+ void drawRect(GrSurfaceFillContext*,
GrSurfaceProxyView srcView,
const SkMatrix& matrix,
- const SkRect& dstRect,
+ const SkIRect& dstRect,
BoundaryMode boundaryMode,
const SkIRect* srcBounds,
const SkIRect& bounds) const;
@@ -457,21 +457,17 @@
};
#if SK_SUPPORT_GPU
-void SkLightingImageFilterInternal::drawRect(GrSurfaceDrawContext* surfaceDrawContext,
+void SkLightingImageFilterInternal::drawRect(GrSurfaceFillContext* surfaceFillContext,
GrSurfaceProxyView srcView,
const SkMatrix& matrix,
- const SkRect& dstRect,
+ const SkIRect& dstRect,
BoundaryMode boundaryMode,
const SkIRect* srcBounds,
const SkIRect& bounds) const {
- SkRect srcRect = dstRect.makeOffset(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()));
- GrPaint paint;
+ SkIRect srcRect = dstRect.makeOffset(bounds.topLeft());
auto fp = this->makeFragmentProcessor(std::move(srcView), matrix, srcBounds, boundaryMode,
- *surfaceDrawContext->caps());
- paint.setColorFragmentProcessor(std::move(fp));
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- surfaceDrawContext->fillRectToRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- dstRect, srcRect);
+ *surfaceFillContext->caps());
+ surfaceFillContext->fillRectToRectWithFP(srcRect, dstRect, std::move(fp));
}
sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(
@@ -486,55 +482,61 @@
GrSurfaceProxyView inputView = input->view(context);
SkASSERT(inputView.asTextureProxy());
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- context, ctx.grColorType(), ctx.refColorSpace(), SkBackingFit::kApprox,
- offsetBounds.size(), 1, GrMipmapped::kNo, inputView.proxy()->isProtected(),
- kBottomLeft_GrSurfaceOrigin);
- if (!surfaceDrawContext) {
+ GrImageInfo info(ctx.grColorType(),
+ kPremul_SkAlphaType,
+ ctx.refColorSpace(),
+ offsetBounds.size());
+ auto surfaceFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kApprox,
+ 1,
+ GrMipmapped::kNo,
+ inputView.proxy()->isProtected(),
+ kBottomLeft_GrSurfaceOrigin);
+ if (!surfaceFillContext) {
return nullptr;
}
- SkIRect dstIRect = SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height());
- SkRect dstRect = SkRect::Make(dstIRect);
+ SkIRect dstRect = SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height());
const SkIRect inputBounds = SkIRect::MakeWH(input->width(), input->height());
- SkRect topLeft = SkRect::MakeXYWH(0, 0, 1, 1);
- SkRect top = SkRect::MakeXYWH(1, 0, dstRect.width() - 2, 1);
- SkRect topRight = SkRect::MakeXYWH(dstRect.width() - 1, 0, 1, 1);
- SkRect left = SkRect::MakeXYWH(0, 1, 1, dstRect.height() - 2);
- SkRect interior = dstRect.makeInset(1, 1);
- SkRect right = SkRect::MakeXYWH(dstRect.width() - 1, 1, 1, dstRect.height() - 2);
- SkRect bottomLeft = SkRect::MakeXYWH(0, dstRect.height() - 1, 1, 1);
- SkRect bottom = SkRect::MakeXYWH(1, dstRect.height() - 1, dstRect.width() - 2, 1);
- SkRect bottomRight = SkRect::MakeXYWH(dstRect.width() - 1, dstRect.height() - 1, 1, 1);
+ SkIRect topLeft = SkIRect::MakeXYWH(0, 0, 1, 1);
+ SkIRect top = SkIRect::MakeXYWH(1, 0, dstRect.width() - 2, 1);
+ SkIRect topRight = SkIRect::MakeXYWH(dstRect.width() - 1, 0, 1, 1);
+ SkIRect left = SkIRect::MakeXYWH(0, 1, 1, dstRect.height() - 2);
+ SkIRect interior = dstRect.makeInset(1, 1);
+ SkIRect right = SkIRect::MakeXYWH(dstRect.width() - 1, 1, 1, dstRect.height() - 2);
+ SkIRect bottomLeft = SkIRect::MakeXYWH(0, dstRect.height() - 1, 1, 1);
+ SkIRect bottom = SkIRect::MakeXYWH(1, dstRect.height() - 1, dstRect.width() - 2, 1);
+ SkIRect bottomRight = SkIRect::MakeXYWH(dstRect.width() - 1, dstRect.height() - 1, 1, 1);
const SkIRect* pSrcBounds = inputBounds.contains(offsetBounds) ? nullptr : &inputBounds;
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, topLeft,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, topLeft,
kTopLeft_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, top,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, top,
kTop_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, topRight,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, topRight,
kTopRight_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, left,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, left,
kLeft_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, interior,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, interior,
kInterior_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, right,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, right,
kRight_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, bottomLeft,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, bottomLeft,
kBottomLeft_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), inputView, matrix, bottom,
+ this->drawRect(surfaceFillContext.get(), inputView, matrix, bottom,
kBottom_BoundaryMode, pSrcBounds, offsetBounds);
- this->drawRect(surfaceDrawContext.get(), std::move(inputView), matrix, bottomRight,
+ this->drawRect(surfaceFillContext.get(), std::move(inputView), matrix, bottomRight,
kBottomRight_BoundaryMode, pSrcBounds, offsetBounds);
return SkSpecialImage::MakeDeferredFromGpu(
context,
SkIRect::MakeWH(offsetBounds.width(), offsetBounds.height()),
kNeedNewImageUniqueID_SpecialImage,
- surfaceDrawContext->readSurfaceView(),
- surfaceDrawContext->colorInfo().colorType(),
- surfaceDrawContext->colorInfo().refColorSpace());
+ surfaceFillContext->readSurfaceView(),
+ surfaceFillContext->colorInfo().colorType(),
+ surfaceFillContext->colorInfo().refColorSpace());
}
#endif
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index 57e943d..fb4c723 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -361,7 +361,7 @@
}
#endif
-static void apply_morphology_rect(GrSurfaceDrawContext* surfaceDrawContext,
+static void apply_morphology_rect(GrSurfaceFillContext* surfaceFillContext,
GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
const SkIRect& srcRect,
@@ -370,17 +370,17 @@
MorphType morphType,
const float range[2],
MorphDirection direction) {
- GrPaint paint;
- paint.setColorFragmentProcessor(GrMorphologyEffect::Make(/*inputFP=*/nullptr, std::move(view),
- srcAlphaType, direction, radius,
- morphType, range));
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- surfaceDrawContext->fillRectToRect(/*clip=*/nullptr, std::move(paint), GrAA::kNo,
- SkMatrix::I(), SkRect::Make(dstRect),
- SkRect::Make(srcRect));
+ auto fp = GrMorphologyEffect::Make(/*inputFP=*/nullptr,
+ std::move(view),
+ srcAlphaType,
+ direction,
+ radius,
+ morphType,
+ range);
+ surfaceFillContext->fillRectToRectWithFP(srcRect, dstRect, std::move(fp));
}
-static void apply_morphology_rect_no_bounds(GrSurfaceDrawContext* surfaceDrawContext,
+static void apply_morphology_rect_no_bounds(GrSurfaceFillContext* surfaceFillContext,
GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
const SkIRect& srcRect,
@@ -388,16 +388,12 @@
int radius,
MorphType morphType,
MorphDirection direction) {
- GrPaint paint;
- paint.setColorFragmentProcessor(GrMorphologyEffect::Make(
- /*inputFP=*/nullptr, std::move(view), srcAlphaType, direction, radius, morphType));
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- surfaceDrawContext->fillRectToRect(/*clip=*/nullptr, std::move(paint), GrAA::kNo,
- SkMatrix::I(), SkRect::Make(dstRect),
- SkRect::Make(srcRect));
+ auto fp = GrMorphologyEffect::Make(
+ /*inputFP=*/nullptr, std::move(view), srcAlphaType, direction, radius, morphType);
+ surfaceFillContext->fillRectToRectWithFP(srcRect, dstRect, std::move(fp));
}
-static void apply_morphology_pass(GrSurfaceDrawContext* surfaceDrawContext,
+static void apply_morphology_pass(GrSurfaceFillContext* surfaceFillContext,
GrSurfaceProxyView view,
SkAlphaType srcAlphaType,
const SkIRect& srcRect,
@@ -430,15 +426,15 @@
}
if (middleSrcRect.width() <= 0) {
// radius covers srcRect; use bounds over entire draw
- apply_morphology_rect(surfaceDrawContext, std::move(view), srcAlphaType, srcRect,
+ apply_morphology_rect(surfaceFillContext, std::move(view), srcAlphaType, srcRect,
dstRect, radius, morphType, bounds, direction);
} else {
// Draw upper and lower margins with bounds; middle without.
- apply_morphology_rect(surfaceDrawContext, view, srcAlphaType, lowerSrcRect,
+ apply_morphology_rect(surfaceFillContext, view, srcAlphaType, lowerSrcRect,
lowerDstRect, radius, morphType, bounds, direction);
- apply_morphology_rect(surfaceDrawContext, view, srcAlphaType, upperSrcRect,
+ apply_morphology_rect(surfaceFillContext, view, srcAlphaType, upperSrcRect,
upperDstRect, radius, morphType, bounds, direction);
- apply_morphology_rect_no_bounds(surfaceDrawContext, std::move(view), srcAlphaType,
+ apply_morphology_rect_no_bounds(surfaceFillContext, std::move(view), srcAlphaType,
middleSrcRect, middleDstRect, radius, morphType, direction);
}
}
@@ -461,37 +457,47 @@
SkASSERT(radius.width() > 0 || radius.height() > 0);
if (radius.fWidth > 0) {
- auto dstRTContext = GrSurfaceDrawContext::Make(
- context, colorType, colorSpace, SkBackingFit::kApprox, rect.size(), 1,
- GrMipmapped::kNo, proxy->isProtected(), kBottomLeft_GrSurfaceOrigin);
- if (!dstRTContext) {
+ GrImageInfo info(colorType, kPremul_SkAlphaType, colorSpace, rect.size());
+ auto dstFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kApprox,
+ 1,
+ GrMipmapped::kNo,
+ proxy->isProtected(),
+ kBottomLeft_GrSurfaceOrigin);
+ if (!dstFillContext) {
return nullptr;
}
- apply_morphology_pass(dstRTContext.get(), std::move(srcView), srcAlphaType,
+ apply_morphology_pass(dstFillContext.get(), std::move(srcView), srcAlphaType,
srcRect, dstRect, radius.fWidth, morphType, MorphDirection::kX);
SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom,
dstRect.width(), radius.fHeight);
SkPMColor4f clearColor = MorphType::kErode == morphType
? SK_PMColor4fWHITE : SK_PMColor4fTRANSPARENT;
- dstRTContext->clear(clearRect, clearColor);
+ dstFillContext->clear(clearRect, clearColor);
- srcView = dstRTContext->readSurfaceView();
- srcAlphaType = dstRTContext->colorInfo().alphaType();
+ srcView = dstFillContext->readSurfaceView();
+ srcAlphaType = dstFillContext->colorInfo().alphaType();
srcRect = dstRect;
}
if (radius.fHeight > 0) {
- auto dstRTContext = GrSurfaceDrawContext::Make(
- context, colorType, colorSpace, SkBackingFit::kApprox, rect.size(), 1,
- GrMipmapped::kNo, srcView.proxy()->isProtected(), kBottomLeft_GrSurfaceOrigin);
- if (!dstRTContext) {
+ GrImageInfo info(colorType, kPremul_SkAlphaType, colorSpace, rect.size());
+ auto dstFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kApprox,
+ 1,
+ GrMipmapped::kNo,
+ srcView.proxy()->isProtected(),
+ kBottomLeft_GrSurfaceOrigin);
+ if (!dstFillContext) {
return nullptr;
}
- apply_morphology_pass(dstRTContext.get(), std::move(srcView), srcAlphaType,
+ apply_morphology_pass(dstFillContext.get(), std::move(srcView), srcAlphaType,
srcRect, dstRect, radius.fHeight, morphType, MorphDirection::kY);
- srcView = dstRTContext->readSurfaceView();
+ srcView = dstFillContext->readSurfaceView();
}
return SkSpecialImage::MakeDeferredFromGpu(context,
diff --git a/src/effects/imagefilters/SkXfermodeImageFilter.cpp b/src/effects/imagefilters/SkXfermodeImageFilter.cpp
index e2d8c45..2ce8f21 100644
--- a/src/effects/imagefilters/SkXfermodeImageFilter.cpp
+++ b/src/effects/imagefilters/SkXfermodeImageFilter.cpp
@@ -251,7 +251,6 @@
foregroundView = foreground->view(context);
}
- GrPaint paint;
std::unique_ptr<GrFragmentProcessor> fp;
const auto& caps = *ctx.getContext()->priv().caps();
GrSamplerState sampler(GrSamplerState::WrapMode::kClampToBorder,
@@ -284,26 +283,22 @@
fp = GrBlendFragmentProcessor::Make(std::move(fgFP), std::move(fp), fMode);
}
- paint.setColorFragmentProcessor(std::move(fp));
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- context, ctx.grColorType(), ctx.refColorSpace(), SkBackingFit::kApprox, bounds.size());
- if (!surfaceDrawContext) {
+ GrImageInfo info(ctx.grColorType(), kPremul_SkAlphaType, ctx.refColorSpace(), bounds.size());
+ auto surfaceFillContext = GrSurfaceFillContext::Make(context, info, SkBackingFit::kApprox);
+ if (!surfaceFillContext) {
return nullptr;
}
- SkMatrix matrix;
- matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
- surfaceDrawContext->drawRect(nullptr, std::move(paint), GrAA::kNo, matrix,
- SkRect::Make(bounds));
+ surfaceFillContext->fillRectToRectWithFP(bounds,
+ SkIRect::MakeSize(bounds.size()),
+ std::move(fp));
return SkSpecialImage::MakeDeferredFromGpu(context,
SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
- surfaceDrawContext->readSurfaceView(),
- surfaceDrawContext->colorInfo().colorType(),
- surfaceDrawContext->colorInfo().refColorSpace());
+ surfaceFillContext->readSurfaceView(),
+ surfaceFillContext->colorInfo().colorType(),
+ surfaceFillContext->colorInfo().refColorSpace());
}
#endif
diff --git a/src/gpu/GrOpsTask.h b/src/gpu/GrOpsTask.h
index 9a9dbf7..c0448f4 100644
--- a/src/gpu/GrOpsTask.h
+++ b/src/gpu/GrOpsTask.h
@@ -76,6 +76,19 @@
void discard();
+ enum class CanDiscardPreviousOps : bool {
+ kYes = true,
+ kNo = false
+ };
+
+ // Perform book-keeping for a fullscreen clear, regardless of how the clear is implemented later
+ // (i.e. setColorLoadOp(), adding a ClearOp, or adding a GrFillRectOp that covers the device).
+ // Returns true if the clear can be converted into a load op (barring device caps).
+ bool resetForFullscreenClear(CanDiscardPreviousOps);
+
+ // Must only be called if native color buffer clearing is enabled.
+ void setColorLoadOp(GrLoadOp op, std::array<float, 4> color = {0, 0, 0, 0});
+
#ifdef SK_DEBUG
int numClips() const override { return fNumClips; }
void visitProxies_debugOnly(const GrOp::VisitProxyFunc&) const override;
@@ -124,19 +137,6 @@
// get preserved across its split tasks.
void setMustPreserveStencil() { fMustPreserveStencil = true; }
- // Must only be called if native color buffer clearing is enabled.
- void setColorLoadOp(GrLoadOp op, std::array<float, 4> color = {0, 0, 0, 0});
-
- enum class CanDiscardPreviousOps : bool {
- kYes = true,
- kNo = false
- };
-
- // Perform book-keeping for a fullscreen clear, regardless of how the clear is implemented later
- // (i.e. setColorLoadOp(), adding a ClearOp, or adding a GrFillRectOp that covers the device).
- // Returns true if the clear can be converted into a load op (barring device caps).
- bool resetForFullscreenClear(CanDiscardPreviousOps);
-
class OpChain {
public:
OpChain(GrOp::Owner, GrProcessorSet::Analysis, GrAppliedClip*, const DstProxyView*);
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index d1a57ce..8ec7265 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -246,7 +246,7 @@
if (proxy->asRenderTargetProxy()) {
GrBackendFormat expectedFormat;
std::tie(ct, expectedFormat) =
- GrSurfaceDrawContext::GetFallbackColorTypeAndFormat(fImageContext, ct, sampleCnt);
+ GrSurfaceFillContext::GetFallbackColorTypeAndFormat(fImageContext, ct, sampleCnt);
SkASSERT(expectedFormat == proxy->backendFormat());
}
GrSwizzle swizzle = fImageContext->priv().caps()->getReadSwizzle(proxy->backendFormat(), ct);
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index ab40c07..b9c9444 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -45,8 +45,6 @@
std::unique_ptr<GrSurfaceContext> surfaceContext;
if (proxy->asRenderTargetProxy()) {
- SkASSERT(info.alphaType() == kPremul_SkAlphaType ||
- info.alphaType() == kOpaque_SkAlphaType);
// Will we ever want a swizzle that is not the default write swizzle for the format and
// colorType here? If so we will need to manually pass that in.
GrSwizzle writeSwizzle;
@@ -55,12 +53,19 @@
info.colorType());
}
GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle);
- surfaceContext = std::make_unique<GrSurfaceDrawContext>(context,
- std::move(readView),
- std::move(writeView),
- info.colorType(),
- info.refColorSpace(),
- /*surface props*/ nullptr);
+ if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
+ surfaceContext = std::make_unique<GrSurfaceDrawContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ info.colorType(),
+ info.refColorSpace(),
+ /*surface props*/ nullptr);
+ } else {
+ surfaceContext = std::make_unique<GrSurfaceFillContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ info);
+ }
} else {
surfaceContext = std::make_unique<GrSurfaceContext>(context, std::move(readView), info);
}
@@ -237,11 +242,14 @@
GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
? GrColorType::kRGBA_8888
: this->colorInfo().colorType();
- tempCtx = GrSurfaceDrawContext::Make(
- dContext, colorType, this->colorInfo().refColorSpace(), SkBackingFit::kApprox,
- dstInfo.dimensions(), 1, GrMipMapped::kNo, GrProtected::kNo,
- kTopLeft_GrSurfaceOrigin);
- if (!tempCtx) {
+ SkAlphaType alphaType = canvas2DFastPath ? dstInfo.alphaType()
+ : this->colorInfo().alphaType();
+ GrImageInfo tempInfo(colorType,
+ alphaType,
+ this->colorInfo().refColorSpace(),
+ dstInfo.dimensions());
+ auto sfc = GrSurfaceFillContext::Make(dContext, tempInfo, SkBackingFit::kApprox);
+ if (!sfc) {
return false;
}
@@ -253,25 +261,17 @@
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
dstInfo = dstInfo.makeColorType(GrColorType::kRGBA_8888);
}
- // The render target context is incorrectly tagged as kPremul even though we're
- // writing unpremul data thanks to the PMToUPM effect. Fake out the dst alpha type
- // so we don't double unpremul.
- dstInfo = dstInfo.makeAlphaType(kPremul_SkAlphaType);
} else {
fp = GrTextureEffect::Make(this->readSurfaceView(), this->colorInfo().alphaType());
}
if (!fp) {
return false;
}
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.setColorFragmentProcessor(std::move(fp));
-
- tempCtx->asRenderTargetContext()->fillRectToRect(
- nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::MakeWH(dstInfo.width(), dstInfo.height()),
- SkRect::MakeXYWH(pt.fX, pt.fY, dstInfo.width(), dstInfo.height()));
+ sfc->fillRectToRectWithFP(SkIRect::MakePtSize(pt, dstInfo.dimensions()),
+ SkIRect::MakeSize(dstInfo.dimensions()),
+ std::move(fp));
pt = {0, 0};
+ tempCtx = std::move(sfc);
} else {
auto restrictions = this->caps()->getDstCopyRestrictions(this->asRenderTargetProxy(),
this->colorInfo().colorType());
@@ -404,7 +404,7 @@
bool canvas2DFastPath = !caps->avoidWritePixelsFastPath() && premul && !needColorConversion &&
(srcInfo.colorType() == GrColorType::kRGBA_8888 ||
srcInfo.colorType() == GrColorType::kBGRA_8888) &&
- SkToBool(this->asRenderTargetContext()) &&
+ this->asFillContext() &&
(dstColorType == GrColorType::kRGBA_8888 ||
dstColorType == GrColorType::kBGRA_8888) &&
rgbaDefaultFormat.isValid() &&
@@ -434,7 +434,7 @@
// we can use a draw instead which doesn't have this origin restriction. Thus for render
// targets we will use top left and otherwise we will make the origins match.
GrSurfaceOrigin tempOrigin =
- this->asRenderTargetContext() ? kTopLeft_GrSurfaceOrigin : this->origin();
+ this->asFillContext() ? kTopLeft_GrSurfaceOrigin : this->origin();
auto tempProxy = dContext->priv().proxyProvider()->createProxy(
format, srcInfo.dimensions(), GrRenderable::kNo, 1, GrMipmapped::kNo,
SkBackingFit::kApprox, SkBudgeted::kYes, GrProtected::kNo);
@@ -455,7 +455,7 @@
return false;
}
- if (this->asRenderTargetContext()) {
+ if (this->asFillContext()) {
std::unique_ptr<GrFragmentProcessor> fp;
if (canvas2DFastPath) {
fp = dContext->priv().createUPMToPMEffect(
@@ -470,13 +470,10 @@
if (!fp) {
return false;
}
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.setColorFragmentProcessor(std::move(fp));
- this->asRenderTargetContext()->fillRectToRect(
- nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::MakeXYWH(pt.fX, pt.fY, srcInfo.width(), srcInfo.height()),
- SkRect::MakeWH(srcInfo.width(), srcInfo.height()));
+ this->asFillContext()->fillRectToRectWithFP(
+ SkIRect::MakeSize(srcInfo.dimensions()),
+ SkIRect::MakePtSize(pt, srcInfo.dimensions()),
+ std::move(fp));
} else {
SkIRect srcRect = SkIRect::MakeWH(srcInfo.width(), srcInfo.height());
SkIPoint dstPoint = SkIPoint::Make(pt.fX, pt.fY);
diff --git a/src/gpu/GrSurfaceContext.h b/src/gpu/GrSurfaceContext.h
index 9e1b3c6..60fc978 100644
--- a/src/gpu/GrSurfaceContext.h
+++ b/src/gpu/GrSurfaceContext.h
@@ -23,10 +23,11 @@
class GrAuditTrail;
class GrDrawingManager;
class GrRecordingContext;
-class GrSurfaceDrawContext;
class GrRenderTargetProxy;
class GrSingleOwner;
class GrSurface;
+class GrSurfaceDrawContext;
+class GrSurfaceFillContext;
class GrSurfaceProxy;
class GrTextureProxy;
struct SkIPoint;
@@ -43,7 +44,8 @@
GrSurfaceProxyView readView,
const GrColorInfo&);
- // Makes either a GrSurfaceContext or a GrSurfaceDrawContext, depending on GrRenderable.
+ // Makes either a GrSurfaceContext, GrFillDrawContext, or a GrSurfaceDrawContext, depending on
+ // GrRenderable and the GrImageInfo.
static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*,
const GrImageInfo&,
const GrBackendFormat&,
@@ -55,6 +57,7 @@
GrProtected = GrProtected::kNo,
SkBudgeted = SkBudgeted::kYes);
+ // Same as the above but chooses the texture format using the default format for the color type.
static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*,
const GrImageInfo&,
SkBackingFit = SkBackingFit::kExact,
@@ -159,6 +162,7 @@
}
virtual GrSurfaceDrawContext* asRenderTargetContext() { return nullptr; }
+ virtual GrSurfaceFillContext* asFillContext() { return nullptr; }
/**
* Rescales the contents of srcRect. The gamma in which the rescaling occurs is controlled by
diff --git a/src/gpu/GrSurfaceDrawContext.cpp b/src/gpu/GrSurfaceDrawContext.cpp
index efe7671..3721f2a 100644
--- a/src/gpu/GrSurfaceDrawContext.cpp
+++ b/src/gpu/GrSurfaceDrawContext.cpp
@@ -73,7 +73,6 @@
#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
#define RETURN_IF_ABANDONED if (fContext->abandoned()) { return; }
#define RETURN_FALSE_IF_ABANDONED if (fContext->abandoned()) { return false; }
-#define RETURN_NULL_IF_ABANDONED if (fContext->abandoned()) { return nullptr; }
//////////////////////////////////////////////////////////////////////////////
@@ -202,43 +201,6 @@
surfaceProps);
}
-static inline GrColorType color_type_fallback(GrColorType ct) {
- switch (ct) {
- // kRGBA_8888 is our default fallback for many color types that may not have renderable
- // backend formats.
- case GrColorType::kAlpha_8:
- case GrColorType::kBGR_565:
- case GrColorType::kABGR_4444:
- case GrColorType::kBGRA_8888:
- case GrColorType::kRGBA_1010102:
- case GrColorType::kBGRA_1010102:
- case GrColorType::kRGBA_F16:
- case GrColorType::kRGBA_F16_Clamped:
- return GrColorType::kRGBA_8888;
- case GrColorType::kAlpha_F16:
- return GrColorType::kRGBA_F16;
- case GrColorType::kGray_8:
- return GrColorType::kRGB_888x;
- default:
- return GrColorType::kUnknown;
- }
-}
-
-std::tuple<GrColorType, GrBackendFormat> GrSurfaceDrawContext::GetFallbackColorTypeAndFormat(
- GrImageContext* context, GrColorType colorType, int sampleCnt) {
- auto caps = context->priv().caps();
- do {
- auto format = caps->getDefaultBackendFormat(colorType, GrRenderable::kYes);
- // We continue to the fallback color type if there no default renderable format or we
- // requested msaa and the format doesn't support msaa.
- if (format.isValid() && caps->isFormatRenderable(format, sampleCnt)) {
- return {colorType, format};
- }
- colorType = color_type_fallback(colorType);
- } while (colorType != GrColorType::kUnknown);
- return {GrColorType::kUnknown, {}};
-}
-
std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::MakeWithFallback(
GrRecordingContext* context,
GrColorType colorType,
@@ -326,28 +288,16 @@
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* surfaceProps,
bool flushTimeOpsTask)
- : GrSurfaceContext(context,
- std::move(readView),
- {colorType, kPremul_SkAlphaType, std::move(colorSpace)})
- , fWriteView(std::move(writeView))
+ : GrSurfaceFillContext(context,
+ std::move(readView),
+ std::move(writeView),
+ {colorType, kPremul_SkAlphaType, std::move(colorSpace)},
+ flushTimeOpsTask)
, fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
- , fFlushTimeOpsTask(flushTimeOpsTask)
, fGlyphPainter(*this) {
- fOpsTask = sk_ref_sp(context->priv().drawingManager()->getLastOpsTask(this->asSurfaceProxy()));
- SkASSERT(this->asSurfaceProxy() == fWriteView.proxy());
- SkASSERT(this->origin() == fWriteView.origin());
-
SkDEBUGCODE(this->validate();)
}
-#ifdef SK_DEBUG
-void GrSurfaceDrawContext::onValidate() const {
- if (fOpsTask && !fOpsTask->isClosed()) {
- SkASSERT(this->drawingManager()->getLastRenderTask(fWriteView.proxy()) == fOpsTask.get());
- }
-}
-#endif
-
GrSurfaceDrawContext::~GrSurfaceDrawContext() {
ASSERT_SINGLE_OWNER
}
@@ -371,27 +321,6 @@
return GrMipmapped::kNo;
}
-GrOpsTask* GrSurfaceDrawContext::getOpsTask() {
- ASSERT_SINGLE_OWNER
- SkDEBUGCODE(this->validate();)
-
- if (!fOpsTask || fOpsTask->isClosed()) {
- sk_sp<GrOpsTask> newOpsTask = this->drawingManager()->newOpsTask(this->writeSurfaceView(),
- fFlushTimeOpsTask);
- if (fOpsTask && fNumStencilSamples > 0) {
- // Store the stencil values in memory upon completion of fOpsTask.
- fOpsTask->setMustPreserveStencil();
- // Reload the stencil buffer content at the beginning of newOpsTask.
- // FIXME: Could the topo sort insert a task between these two that modifies the stencil
- // values?
- newOpsTask->setInitialStencilContent(GrOpsTask::StencilContent::kPreserved);
- }
- fOpsTask = std::move(newOpsTask);
- }
- SkASSERT(!fOpsTask->isClosed());
- return fOpsTask.get();
-}
-
static SkColor compute_canonical_color(const SkPaint& paint, bool lcd) {
SkColor canonicalColor = SkPaintPriv::ComputeLuminanceColor(paint);
if (lcd) {
@@ -516,99 +445,6 @@
}
}
-void GrSurfaceDrawContext::discard() {
- ASSERT_SINGLE_OWNER
- RETURN_IF_ABANDONED
- SkDEBUGCODE(this->validate();)
- GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "discard", fContext);
-
- AutoCheckFlush acf(this->drawingManager());
-
- this->getOpsTask()->discard();
-}
-
-static void clear_to_grpaint(const SkPMColor4f& color, GrPaint* paint) {
- paint->setColor4f(color);
- if (color.isOpaque()) {
- // Can just rely on the src-over blend mode to do the right thing
- paint->setPorterDuffXPFactory(SkBlendMode::kSrcOver);
- } else {
- // A clear overwrites the prior color, so even if it's transparent, it behaves as if it
- // were src blended
- paint->setPorterDuffXPFactory(SkBlendMode::kSrc);
- }
-}
-
-// NOTE: We currently pass the premul color unmodified to the gpu, since we assume the GrRTC has a
-// premul alpha type. If we ever support different alpha type render targets, this function should
-// transform the color as appropriate.
-void GrSurfaceDrawContext::internalClear(const SkIRect* scissor,
- const SkPMColor4f& color,
- bool upgradePartialToFull) {
- ASSERT_SINGLE_OWNER
- RETURN_IF_ABANDONED
- SkDEBUGCODE(this->validate();)
- GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "clear", fContext);
-
- // There are three ways clears are handled: load ops, native clears, and draws. Load ops are
- // only for fullscreen clears; native clears can be fullscreen or with scissors if the backend
- // supports then. Drawing an axis-aligned rect is the fallback path.
- GrScissorState scissorState(this->asSurfaceProxy()->backingStoreDimensions());
- if (scissor && !scissorState.set(*scissor)) {
- // The clear is offscreen, so skip it (normally this would be handled by addDrawOp,
- // except clear ops are not draw ops).
- return;
- }
-
- // If we have a scissor but it's okay to clear beyond it for performance reasons, then disable
- // the test. We only do this when the clear would be handled by a load op or natively.
- if (scissorState.enabled() && !this->caps()->performColorClearsAsDraws()) {
- if (upgradePartialToFull && (this->caps()->preferFullscreenClears() ||
- this->caps()->shouldInitializeTextures())) {
- // TODO: wrt the shouldInitializeTextures path, it would be more performant to
- // only clear the entire target if we knew it had not been cleared before. As
- // is this could end up doing a lot of redundant clears.
- scissorState.setDisabled();
- } else {
- // Unlike with stencil clears, we also allow clears up to the logical dimensions of the
- // render target to overflow into any approx-fit padding of the backing store dimensions
- scissorState.relaxTest(this->dimensions());
- }
- }
-
- if (!scissorState.enabled()) {
- // This is a fullscreen clear, so could be handled as a load op. Regardless, we can also
- // discard all prior ops in the current task since the color buffer will be overwritten.
- GrOpsTask* opsTask = this->getOpsTask();
- if (opsTask->resetForFullscreenClear(this->canDiscardPreviousOpsOnFullClear()) &&
- !this->caps()->performColorClearsAsDraws()) {
- SkPMColor4f clearColor = this->writeSurfaceView().swizzle().applyTo(color);
- // The op list was emptied and native clears are allowed, so just use the load op
- opsTask->setColorLoadOp(GrLoadOp::kClear, clearColor.array());
- return;
- } else {
- // Will use an op for the clear, reset the load op to discard since the op will
- // blow away the color buffer contents
- opsTask->setColorLoadOp(GrLoadOp::kDiscard);
- }
- }
-
- // At this point we are either a partial clear or a fullscreen clear that couldn't be applied
- // as a load op.
- bool clearAsDraw = this->caps()->performColorClearsAsDraws() ||
- (scissorState.enabled() && this->caps()->performPartialClearsAsDraws());
- if (clearAsDraw) {
- GrPaint paint;
- clear_to_grpaint(color, &paint);
- this->addDrawOp(nullptr,
- GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
- SkRect::Make(scissorState.rect())));
- } else {
- SkPMColor4f clearColor = this->writeSurfaceView().swizzle().applyTo(color);
- this->addOp(GrClearOp::MakeColor(fContext, scissorState, clearColor.array()));
- }
-}
-
void GrSurfaceDrawContext::drawPaint(const GrClip* clip,
GrPaint&& paint,
const SkMatrix& viewMatrix) {
@@ -759,7 +595,7 @@
// Since the cropped quad became a rectangle which covered the bounds of the rrect,
// we can draw the rrect directly and ignore the edge flags
GrPaint paint;
- clear_to_grpaint(*constColor, &paint);
+ ClearToGrPaint(constColor->array(), &paint);
this->drawRRect(nullptr, std::move(paint), result.fAA, SkMatrix::I(), result.fRRect,
GrStyle::SimpleFill());
return QuadOptimization::kSubmitted;
@@ -926,8 +762,8 @@
int numRequiredSamples = this->numSamples();
if (useMixedSamplesIfNotMSAA && 1 == numRequiredSamples) {
SkASSERT(this->asRenderTargetProxy()->canUseMixedSamples(*this->caps()));
- numRequiredSamples = this->caps()->internalMultisampleCount(
- this->asSurfaceProxy()->backendFormat());
+ numRequiredSamples =
+ this->caps()->internalMultisampleCount(this->asSurfaceProxy()->backendFormat());
}
SkASSERT(numRequiredSamples > 0);
@@ -1990,12 +1826,6 @@
}
}
-void GrSurfaceDrawContext::addOp(GrOp::Owner op) {
- GrDrawingManager* drawingMgr = this->drawingManager();
- this->getOpsTask()->addOp(drawingMgr,
- std::move(op), GrTextureResolveManager(drawingMgr), *this->caps());
-}
-
void GrSurfaceDrawContext::addDrawOp(const GrClip* clip,
GrOp::Owner op,
const std::function<WillAddOpFn>& willAddFn) {
@@ -2023,9 +1853,12 @@
bool skipDraw = false;
if (clip) {
// Have a complex clip, so defer to its early clip culling
- GrAAType aaType = usesHWAA ? GrAAType::kMSAA :
- (op->hasAABloat() ? GrAAType::kCoverage :
- GrAAType::kNone);
+ GrAAType aaType;
+ if (usesHWAA) {
+ aaType = GrAAType::kMSAA;
+ } else {
+ aaType = op->hasAABloat() ? GrAAType::kCoverage : GrAAType::kNone;
+ }
skipDraw = clip->apply(fContext, this, aaType, usesUserStencilBits,
&appliedClip, &bounds) == GrClip::Effect::kClippedOut;
} else {
@@ -2131,31 +1964,3 @@
dstProxyView->setDstSampleType(fDstSampleType);
return true;
}
-
-bool GrSurfaceDrawContext::blitTexture(GrSurfaceProxyView view,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint) {
- SkASSERT(view.asTextureProxy());
- SkIRect clippedSrcRect;
- SkIPoint clippedDstPoint;
- if (!GrClipSrcRectAndDstPoint(this->asSurfaceProxy()->dimensions(), view.proxy()->dimensions(),
- srcRect, dstPoint, &clippedSrcRect, &clippedDstPoint)) {
- return false;
- }
-
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- auto fp = GrTextureEffect::Make(std::move(view), kUnknown_SkAlphaType);
- if (!fp) {
- return false;
- }
- paint.setColorFragmentProcessor(std::move(fp));
-
- this->fillRectToRect(
- nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::MakeXYWH(clippedDstPoint.fX, clippedDstPoint.fY, clippedSrcRect.width(),
- clippedSrcRect.height()),
- SkRect::Make(clippedSrcRect));
- return true;
-}
diff --git a/src/gpu/GrSurfaceDrawContext.h b/src/gpu/GrSurfaceDrawContext.h
index 36498dc..6d85a09 100644
--- a/src/gpu/GrSurfaceDrawContext.h
+++ b/src/gpu/GrSurfaceDrawContext.h
@@ -18,14 +18,12 @@
#include "src/gpu/GrOpsTask.h"
#include "src/gpu/GrPaint.h"
#include "src/gpu/GrRenderTargetProxy.h"
-#include "src/gpu/GrSurfaceContext.h"
+#include "src/gpu/GrSurfaceFillContext.h"
#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/text/GrTextBlob.h"
-#include <tuple>
-
class GrBackendSemaphore;
class GrClip;
class GrColorSpaceXform;
@@ -58,7 +56,7 @@
/**
* A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
*/
-class GrSurfaceDrawContext : public GrSurfaceContext {
+class GrSurfaceDrawContext : public GrSurfaceFillContext {
public:
static std::unique_ptr<GrSurfaceDrawContext> Make(GrRecordingContext*,
GrColorType,
@@ -99,10 +97,6 @@
SkBudgeted,
const SkSurfaceProps*);
- static std::tuple<GrColorType, GrBackendFormat> GetFallbackColorTypeAndFormat(GrImageContext*,
- GrColorType,
- int sampleCnt);
-
// Same as previous factory but will try to use fallback GrColorTypes if the one passed in
// fails. The fallback GrColorType will have at least the number of channels and precision per
// channel as the passed in GrColorType. It may also swizzle the changes (e.g., BGRA -> RGBA).
@@ -154,25 +148,6 @@
~GrSurfaceDrawContext() override;
/**
- * Provides a perfomance hint that the render target's contents are allowed
- * to become undefined.
- */
- void discard();
-
- /**
- * Clear the rect of the render target to the given color.
- * @param rect the rect to clear to
- * @param color the color to clear to.
- */
- void clear(const SkIRect& rect, const SkPMColor4f& color) {
- this->internalClear(&rect, color);
- }
- // Clears the entire render target to the color.
- void clear(const SkPMColor4f& color) {
- this->internalClear(nullptr, color);
- }
-
- /**
* Draw everywhere (respecting the clip) with the paint.
*/
void drawPaint(const GrClip*, GrPaint&&, const SkMatrix& viewMatrix);
@@ -559,20 +534,11 @@
const SkGlyphRunList& glyphRunList);
/**
- * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
- * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
- * respectively.
- */
- bool blitTexture(GrSurfaceProxyView view, const SkIRect& srcRect, const SkIPoint& dstPoint);
-
- /**
* Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the
* command stream.
*/
void drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>, const SkRect& bounds);
- GrOpsTask* getOpsTask();
-
// called to note the last clip drawn to the stencil buffer.
// TODO: remove after clipping overhaul.
void setLastClip(uint32_t clipStackGenID,
@@ -595,12 +561,6 @@
opsTask->fLastClipNumAnalyticElements != numClipAnalyticElements;
}
- // Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target
- // if that is the more performant option.
- void clearAtLeast(const SkIRect& scissor, const SkPMColor4f& color) {
- this->internalClear(&scissor, color, /* upgrade to full */ true);
- }
-
void clearStencilClip(const SkIRect& scissor, bool insideStencilMask) {
this->internalStencilClear(&scissor, insideStencilMask);
}
@@ -652,8 +612,6 @@
*/
GrSurfaceProxy::UniqueID uniqueID() const { return this->asSurfaceProxy()->uniqueID(); }
- void addOp(GrOp::Owner);
-
// Allows caller of addDrawOp to know which op list an op will be added to.
using WillAddOpFn = void(GrOp*, uint32_t opsTaskID);
// These perform processing specific to GrDrawOp-derived ops before recording them into an
@@ -681,10 +639,6 @@
bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
GrMipmapped mipmapped() const;
- // TODO: See if it makes sense for this to return a const& instead and require the callers to
- // make a copy (which refs the proxy) if needed.
- GrSurfaceProxyView writeSurfaceView() { return fWriteView; }
-
// This entry point should only be called if the backing GPU object is known to be
// instantiated.
GrRenderTarget* accessRenderTarget() { return this->asSurfaceProxy()->peekRenderTarget(); }
@@ -693,7 +647,6 @@
#if GR_TEST_UTILS
void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; }
- GrOpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }
#endif
private:
@@ -701,13 +654,9 @@
GrAAType chooseAAType(GrAA);
- SkDEBUGCODE(void onValidate() const override;)
-
- GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const;
+ GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const override;
void setNeedsStencil(bool useMixedSamplesIfNotMSAA);
- void internalClear(const SkIRect* scissor, const SkPMColor4f&,
- bool upgradePartialToFull = false);
void internalStencilClear(const SkIRect* scissor, bool insideStencilMask);
// Only consumes the GrPaint if successful.
@@ -772,14 +721,7 @@
SkGlyphRunListPainter* glyphPainter() { return &fGlyphPainter; }
- GrSurfaceProxyView fWriteView;
-
- // In MDB-mode the GrOpsTask can be closed by some other surfaceDrawContext that has picked
- // it up. For this reason, the GrOpsTask should only ever be accessed via 'getOpsTask'.
- sk_sp<GrOpsTask> fOpsTask;
-
SkSurfaceProps fSurfaceProps;
- bool fFlushTimeOpsTask;
int fNumStencilSamples = 0;
@@ -789,7 +731,7 @@
bool fPreserveOpsOnFullClear_TestingOnly = false;
#endif
SkGlyphRunListPainter fGlyphPainter;
- using INHERITED = GrSurfaceContext;
+ using INHERITED = GrSurfaceFillContext;
};
#endif
diff --git a/src/gpu/GrSurfaceFillContext.cpp b/src/gpu/GrSurfaceFillContext.cpp
new file mode 100644
index 0000000..49bf84d
--- /dev/null
+++ b/src/gpu/GrSurfaceFillContext.cpp
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/GrSurfaceFillContext.h"
+
+#include "include/private/GrImageContext.h"
+#include "src/gpu/GrImageContextPriv.h"
+#include "src/gpu/GrProxyProvider.h"
+#include "src/gpu/GrSurfaceDrawContext.h"
+#include "src/gpu/ops/GrClearOp.h"
+#include "src/gpu/ops/GrFillRectOp.h"
+
+#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
+#define RETURN_IF_ABANDONED if (fContext->abandoned()) { return; }
+
+class AutoCheckFlush {
+public:
+ AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
+ SkASSERT(fDrawingManager);
+ }
+ ~AutoCheckFlush() { fDrawingManager->flushIfNecessary(); }
+
+private:
+ GrDrawingManager* fDrawingManager;
+};
+
+static inline GrColorType color_type_fallback(GrColorType ct) {
+ switch (ct) {
+ // kRGBA_8888 is our default fallback for many color types that may not have renderable
+ // backend formats.
+ case GrColorType::kAlpha_8:
+ case GrColorType::kBGR_565:
+ case GrColorType::kABGR_4444:
+ case GrColorType::kBGRA_8888:
+ case GrColorType::kRGBA_1010102:
+ case GrColorType::kBGRA_1010102:
+ case GrColorType::kRGBA_F16:
+ case GrColorType::kRGBA_F16_Clamped:
+ return GrColorType::kRGBA_8888;
+ case GrColorType::kAlpha_F16:
+ return GrColorType::kRGBA_F16;
+ case GrColorType::kGray_8:
+ return GrColorType::kRGB_888x;
+ default:
+ return GrColorType::kUnknown;
+ }
+}
+
+std::tuple<GrColorType, GrBackendFormat> GrSurfaceFillContext::GetFallbackColorTypeAndFormat(
+ GrImageContext* context, GrColorType colorType, int sampleCnt) {
+ auto caps = context->priv().caps();
+ do {
+ auto format = caps->getDefaultBackendFormat(colorType, GrRenderable::kYes);
+ // We continue to the fallback color type if there no default renderable format or we
+ // requested msaa and the format doesn't support msaa.
+ if (format.isValid() && caps->isFormatRenderable(format, sampleCnt)) {
+ return {colorType, format};
+ }
+ colorType = color_type_fallback(colorType);
+ } while (colorType != GrColorType::kUnknown);
+ return {GrColorType::kUnknown, {}};
+}
+
+std::unique_ptr<GrSurfaceFillContext> GrSurfaceFillContext::Make(GrRecordingContext* context,
+ SkAlphaType alphaType,
+ sk_sp<SkColorSpace> colorSpace,
+ SkISize dimensions,
+ SkBackingFit fit,
+ const GrBackendFormat& format,
+ int sampleCount,
+ GrMipmapped mipmapped,
+ GrProtected isProtected,
+ GrSwizzle readSwizzle,
+ GrSwizzle writeSwizzle,
+ GrSurfaceOrigin origin,
+ SkBudgeted budgeted) {
+ SkASSERT(context);
+ SkASSERT(!dimensions.isEmpty());
+ SkASSERT(sampleCount >= 1);
+ SkASSERT(format.isValid() && format.backend() == context->backend());
+ if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) {
+ return GrSurfaceDrawContext::Make(context,
+ std::move(colorSpace),
+ fit,
+ dimensions,
+ format,
+ sampleCount,
+ mipmapped,
+ isProtected,
+ readSwizzle,
+ writeSwizzle,
+ origin,
+ budgeted,
+ /* surface props*/ nullptr);
+ }
+
+ sk_sp<GrTextureProxy> proxy = context->priv().proxyProvider()->createProxy(format,
+ dimensions,
+ GrRenderable::kYes,
+ sampleCount,
+ mipmapped,
+ fit,
+ budgeted,
+ isProtected);
+ if (!proxy) {
+ return nullptr;
+ }
+ GrImageInfo info(GrColorType::kUnknown, alphaType, std::move(colorSpace), dimensions);
+ GrSurfaceProxyView readView( proxy, origin, readSwizzle);
+ GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
+ auto fillContext = std::make_unique<GrSurfaceFillContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ info.colorInfo());
+ fillContext->discard();
+ return fillContext;
+}
+
+std::unique_ptr<GrSurfaceFillContext> GrSurfaceFillContext::Make(GrRecordingContext* context,
+ GrImageInfo info,
+ SkBackingFit fit,
+ int sampleCount,
+ GrMipmapped mipmapped,
+ GrProtected isProtected,
+ GrSurfaceOrigin origin,
+ SkBudgeted budgeted) {
+ if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
+ return GrSurfaceDrawContext::Make(context,
+ info.colorType(),
+ info.refColorSpace(),
+ fit,
+ info.dimensions(),
+ sampleCount,
+ mipmapped,
+ isProtected,
+ origin,
+ budgeted,
+ nullptr);
+ }
+ GrBackendFormat format = context->priv().caps()->getDefaultBackendFormat(info.colorType(),
+ GrRenderable::kYes);
+ sk_sp<GrTextureProxy> proxy = context->priv().proxyProvider()->createProxy(format,
+ info.dimensions(),
+ GrRenderable::kYes,
+ sampleCount,
+ mipmapped,
+ fit,
+ budgeted,
+ isProtected);
+ if (!proxy) {
+ return nullptr;
+ }
+ GrSwizzle readSwizzle = context->priv().caps()->getReadSwizzle (format, info.colorType());
+ GrSwizzle writeSwizzle = context->priv().caps()->getWriteSwizzle(format, info.colorType());
+
+ GrSurfaceProxyView readView( proxy, origin, readSwizzle);
+ GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
+ auto fillContext = std::make_unique<GrSurfaceFillContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ info.colorInfo());
+ fillContext->discard();
+ return fillContext;
+}
+
+std::unique_ptr<GrSurfaceFillContext> GrSurfaceFillContext::MakeWithFallback(
+ GrRecordingContext* context,
+ GrImageInfo info,
+ SkBackingFit fit,
+ int sampleCount,
+ GrMipmapped mipmapped,
+ GrProtected isProtected,
+ GrSurfaceOrigin origin,
+ SkBudgeted budgeted) {
+ if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
+ return GrSurfaceDrawContext::MakeWithFallback(context,
+ info.colorType(),
+ info.refColorSpace(),
+ fit,
+ info.dimensions(),
+ sampleCount,
+ mipmapped,
+ isProtected,
+ origin,
+ budgeted,
+ nullptr);
+ }
+ auto [ct, _] = GetFallbackColorTypeAndFormat(context, info.colorType(), sampleCount);
+ if (ct == GrColorType::kUnknown) {
+ return nullptr;
+ }
+ info = info.makeColorType(ct);
+ return GrSurfaceFillContext::Make(context,
+ info,
+ fit,
+ sampleCount,
+ mipmapped,
+ isProtected,
+ origin,
+ budgeted);
+}
+
+std::unique_ptr<GrSurfaceFillContext> GrSurfaceFillContext::MakeFromBackendTexture(
+ GrRecordingContext* context,
+ GrColorInfo info,
+ const GrBackendTexture& tex,
+ int sampleCount,
+ GrSurfaceOrigin origin,
+ sk_sp<GrRefCntedCallback> releaseHelper) {
+ SkASSERT(sampleCount > 0);
+
+ if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
+ return GrSurfaceDrawContext::MakeFromBackendTexture(context,
+ info.colorType(),
+ info.refColorSpace(),
+ tex,
+ sampleCount,
+ origin,
+ nullptr,
+ std::move(releaseHelper));
+ }
+ const GrBackendFormat& format = tex.getBackendFormat();
+ GrSwizzle readSwizzle, writeSwizzle;
+ if (info.colorType() != GrColorType::kUnknown) {
+ if (!context->priv().caps()->areColorTypeAndFormatCompatible(info.colorType(), format)) {
+ return nullptr;
+ }
+ readSwizzle = context->priv().caps()->getReadSwizzle (format, info.colorType());
+ writeSwizzle = context->priv().caps()->getWriteSwizzle(format, info.colorType());
+ }
+
+ sk_sp<GrTextureProxy> proxy(context->priv().proxyProvider()->wrapRenderableBackendTexture(
+ tex, sampleCount, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
+ std::move(releaseHelper)));
+ if (!proxy) {
+ return nullptr;
+ }
+
+ GrSurfaceProxyView readView( proxy, origin, readSwizzle);
+ GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
+
+ return std::make_unique<GrSurfaceFillContext>(context,
+ std::move(readView),
+ std::move(writeView),
+ std::move(info));
+
+}
+
+// In MDB mode the reffing of the 'getLastOpsTask' call's result allows in-progress
+// GrOpsTask to be picked up and added to by GrSurfaceFillContext lower in the call
+// stack. When this occurs with a closed GrOpsTask, a new one will be allocated
+// when the GrSurfaceFillContext attempts to use it (via getOpsTask).
+GrSurfaceFillContext::GrSurfaceFillContext(GrRecordingContext* context,
+ GrSurfaceProxyView readView,
+ GrSurfaceProxyView writeView,
+ const GrColorInfo& colorInfo,
+ bool flushTimeOpsTask)
+ : GrSurfaceContext(context, std::move(readView), std::move(colorInfo))
+ , fWriteView(std::move(writeView))
+ , fFlushTimeOpsTask(flushTimeOpsTask) {
+ fOpsTask = sk_ref_sp(context->priv().drawingManager()->getLastOpsTask(this->asSurfaceProxy()));
+ SkASSERT(this->asSurfaceProxy() == fWriteView.proxy());
+ SkASSERT(this->origin() == fWriteView.origin());
+
+ SkDEBUGCODE(this->validate();)
+}
+
+void GrSurfaceFillContext::fillRectWithFP(const SkIRect& dstRect,
+ std::unique_ptr<GrFragmentProcessor> fp) {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceFillContext", "fillRectWithFP", fContext);
+
+ AutoCheckFlush acf(this->drawingManager());
+
+ GrPaint paint;
+ paint.setColorFragmentProcessor(std::move(fp));
+ paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ auto op = GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
+ SkRect::Make(dstRect));
+ this->addDrawOp(std::move(op));
+}
+
+void GrSurfaceFillContext::addDrawOp(GrOp::Owner owner) {
+ GrDrawOp* op = static_cast<GrDrawOp*>(owner.get());
+ GrClampType clampType = GrColorTypeClampType(this->colorInfo().colorType());
+ auto clip = GrAppliedClip::Disabled();
+ const GrCaps& caps = *this->caps();
+ GrProcessorSet::Analysis analysis = op->finalize(caps,
+ &clip,
+ /*mixed sample coverage*/ false,
+ clampType);
+ SkASSERT(!(op->fixedFunctionFlags() & GrDrawOp::FixedFunctionFlags::kUsesStencil));
+ SkASSERT(!analysis.requiresDstTexture());
+ SkRect bounds = owner->bounds();
+ // We shouldn't have coverage AA or hairline draws in fill contexts.
+ SkASSERT(!op->hasAABloat() && !op->hasZeroArea());
+ if (!bounds.intersect(this->asSurfaceProxy()->getBoundsRect())) {
+ return;
+ }
+ op->setClippedBounds(op->bounds());
+ SkDEBUGCODE(op->fAddDrawOpCalled = true;)
+
+ GrXferProcessor::DstProxyView dstProxyView;
+ this->getOpsTask()->addDrawOp(fContext->priv().drawingManager(),
+ std::move(owner),
+ analysis,
+ std::move(clip),
+ dstProxyView,
+ GrTextureResolveManager(this->drawingManager()),
+ caps);
+}
+
+void GrSurfaceFillContext::ClearToGrPaint(std::array<float, 4> color, GrPaint* paint) {
+ paint->setColor4f({color[0], color[1], color[2], color[3]});
+ if (color[3] == 1.f) {
+ // Can just rely on the src-over blend mode to do the right thing.
+ // This may improve batching.
+ paint->setPorterDuffXPFactory(SkBlendMode::kSrcOver);
+ } else {
+ // A clear overwrites the prior color, so even if it's transparent, it behaves as if it
+ // were src blended
+ paint->setPorterDuffXPFactory(SkBlendMode::kSrc);
+ }
+}
+
+void GrSurfaceFillContext::addOp(GrOp::Owner op) {
+ GrDrawingManager* drawingMgr = this->drawingManager();
+ this->getOpsTask()->addOp(drawingMgr,
+ std::move(op),
+ GrTextureResolveManager(drawingMgr),
+ *this->caps());
+}
+
+GrOpsTask* GrSurfaceFillContext::getOpsTask() {
+ ASSERT_SINGLE_OWNER
+ SkDEBUGCODE(this->validate();)
+
+ if (!fOpsTask || fOpsTask->isClosed()) {
+ sk_sp<GrOpsTask> newOpsTask = this->drawingManager()->newOpsTask(this->writeSurfaceView(),
+ fFlushTimeOpsTask);
+ if (fOpsTask) {
+ this->willReplaceOpsTask(fOpsTask.get(), newOpsTask.get());
+ }
+ fOpsTask = std::move(newOpsTask);
+ }
+ SkASSERT(!fOpsTask->isClosed());
+ return fOpsTask.get();
+}
+
+#ifdef SK_DEBUG
+void GrSurfaceFillContext::onValidate() const {
+ if (fOpsTask && !fOpsTask->isClosed()) {
+ SkASSERT(this->drawingManager()->getLastRenderTask(fWriteView.proxy()) == fOpsTask.get());
+ }
+}
+#endif
+
+void GrSurfaceFillContext::discard() {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "discard", fContext);
+
+ AutoCheckFlush acf(this->drawingManager());
+
+ this->getOpsTask()->discard();
+}
+
+void GrSurfaceFillContext::internalClear(const SkIRect* scissor,
+ std::array<float, 4> color,
+ bool upgradePartialToFull) {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_CREATE_TRACE_MARKER_CONTEXT("GrSurfaceDrawContext", "clear", fContext);
+
+ // There are three ways clears are handled: load ops, native clears, and draws. Load ops are
+ // only for fullscreen clears; native clears can be fullscreen or with scissors if the backend
+ // supports then. Drawing an axis-aligned rect is the fallback path.
+ GrScissorState scissorState(this->asSurfaceProxy()->backingStoreDimensions());
+ if (scissor && !scissorState.set(*scissor)) {
+ // The clear is offscreen, so skip it (normally this would be handled by addDrawOp,
+ // except clear ops are not draw ops).
+ return;
+ }
+
+ // If we have a scissor but it's okay to clear beyond it for performance reasons, then disable
+ // the test. We only do this when the clear would be handled by a load op or natively.
+ if (scissorState.enabled() && !this->caps()->performColorClearsAsDraws()) {
+ if (upgradePartialToFull && (this->caps()->preferFullscreenClears() ||
+ this->caps()->shouldInitializeTextures())) {
+ // TODO: wrt the shouldInitializeTextures path, it would be more performant to
+ // only clear the entire target if we knew it had not been cleared before. As
+ // is this could end up doing a lot of redundant clears.
+ scissorState.setDisabled();
+ } else {
+ // Unlike with stencil clears, we also allow clears up to the logical dimensions of the
+ // render target to overflow into any approx-fit padding of the backing store dimensions
+ scissorState.relaxTest(this->dimensions());
+ }
+ }
+
+ if (!scissorState.enabled()) {
+ // This is a fullscreen clear, so could be handled as a load op. Regardless, we can also
+ // discard all prior ops in the current task since the color buffer will be overwritten.
+ GrOpsTask* opsTask = this->getOpsTask();
+ if (opsTask->resetForFullscreenClear(this->canDiscardPreviousOpsOnFullClear()) &&
+ !this->caps()->performColorClearsAsDraws()) {
+ color = this->writeSurfaceView().swizzle().applyTo(color);
+ // The op list was emptied and native clears are allowed, so just use the load op
+ opsTask->setColorLoadOp(GrLoadOp::kClear, color);
+ return;
+ } else {
+ // Will use an op for the clear, reset the load op to discard since the op will
+ // blow away the color buffer contents
+ opsTask->setColorLoadOp(GrLoadOp::kDiscard);
+ }
+ }
+
+ // At this point we are either a partial clear or a fullscreen clear that couldn't be applied
+ // as a load op.
+ bool clearAsDraw = this->caps()->performColorClearsAsDraws() ||
+ (scissorState.enabled() && this->caps()->performPartialClearsAsDraws());
+ if (clearAsDraw) {
+ GrPaint paint;
+ ClearToGrPaint(color, &paint);
+ auto op = GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
+ SkRect::Make(scissorState.rect()));
+ this->addDrawOp(std::move(op));
+ } else {
+ color = this->writeSurfaceView().swizzle().applyTo(color);
+ this->addOp(GrClearOp::MakeColor(fContext, scissorState, color));
+ }
+}
+
+bool GrSurfaceFillContext::blitTexture(GrSurfaceProxyView view,
+ const SkIRect& srcRect,
+ const SkIPoint& dstPoint) {
+ SkASSERT(view.asTextureProxy());
+ SkIRect clippedSrcRect;
+ SkIPoint clippedDstPoint;
+ if (!GrClipSrcRectAndDstPoint(this->dimensions(),
+ view.dimensions(),
+ srcRect,
+ dstPoint,
+ &clippedSrcRect,
+ &clippedDstPoint)) {
+ return false;
+ }
+
+ auto fp = GrTextureEffect::Make(std::move(view), kUnknown_SkAlphaType);
+ auto dstRect = SkIRect::MakePtSize(clippedDstPoint, clippedSrcRect.size());
+ auto srcRectF = SkRect::Make(clippedSrcRect);
+ this->fillRectToRectWithFP(srcRectF, dstRect, std::move(fp));
+ return true;
+}
diff --git a/src/gpu/GrSurfaceFillContext.h b/src/gpu/GrSurfaceFillContext.h
new file mode 100644
index 0000000..88f192e
--- /dev/null
+++ b/src/gpu/GrSurfaceFillContext.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSurfaceFillContext_DEFINED
+#define GrSurfaceFillContext_DEFINED
+
+#include "include/core/SkSize.h"
+#include "include/private/GrTypesPriv.h"
+#include "src/gpu/GrImageInfo.h"
+#include "src/gpu/GrOpsTask.h"
+#include "src/gpu/GrSurfaceContext.h"
+#include "src/gpu/GrSwizzle.h"
+#include "src/gpu/effects/GrMatrixEffect.h"
+
+#include <array>
+#include <tuple>
+
+class GrFragmentProcessor;
+class GrImageContext;
+class GrOp;
+class GrBackendFormat;
+class GrRecordingContext;
+class GrSurfaceProxyView;
+class SkColorSpace;
+
+class GrSurfaceFillContext : public GrSurfaceContext {
+public:
+ /**
+ * Checks whether the passed color type is renderable with the passed context. If so, the
+ * same color type is passed back along with the default format used for the color type. If
+ * not, provides an alternative (perhaps lower bit depth and/or unorm instead of float) color
+ * type that is supported along with it's default format or kUnknown if there no renderable
+ * fallback format.
+ */
+ static std::tuple<GrColorType, GrBackendFormat> GetFallbackColorTypeAndFormat(GrImageContext*,
+ GrColorType,
+ int sampleCount);
+
+ GrSurfaceFillContext(GrRecordingContext*,
+ GrSurfaceProxyView readView,
+ GrSurfaceProxyView writeView,
+ const GrColorInfo&,
+ bool flushTimeOpsTask = false);
+
+ /**
+ * Uses GrImageInfo's color type to pick the default texture format. Will return a
+ * GrSurfaceDrawContext if possible.
+ */
+ static std::unique_ptr<GrSurfaceFillContext> Make(GrRecordingContext*,
+ GrImageInfo,
+ SkBackingFit = SkBackingFit::kExact,
+ int sampleCount = 1,
+ GrMipmapped = GrMipmapped::kNo,
+ GrProtected = GrProtected::kNo,
+ GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
+ SkBudgeted = SkBudgeted::kYes);
+
+ /**
+ * Like the above but uses GetFallbackColorTypeAndFormat to find a fallback color type (and
+ * compatible format) if the passed GrImageInfo's color type is not renderable.
+ */
+ static std::unique_ptr<GrSurfaceFillContext> MakeWithFallback(
+ GrRecordingContext*,
+ GrImageInfo,
+ SkBackingFit = SkBackingFit::kExact,
+ int sampleCount = 1,
+ GrMipmapped = GrMipmapped::kNo,
+ GrProtected = GrProtected::kNo,
+ GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
+ SkBudgeted = SkBudgeted::kYes);
+
+ /**
+ * Makes a custom configured GrSurfaceFillContext where the caller specifies the specific
+ * texture format and swizzles. The color type will be kUnknown. Returns a GrSurfaceDrawContext
+ * if possible.
+ */
+ static std::unique_ptr<GrSurfaceFillContext> Make(GrRecordingContext*,
+ SkAlphaType,
+ sk_sp<SkColorSpace>,
+ SkISize dimensions,
+ SkBackingFit,
+ const GrBackendFormat&,
+ int sampleCount,
+ GrMipmapped,
+ GrProtected,
+ GrSwizzle readSwizzle,
+ GrSwizzle writeSwizzle,
+ GrSurfaceOrigin,
+ SkBudgeted);
+
+ /**
+ * Creates a GrSurfaceFillContext from an existing GrBackendTexture. The GrColorInfo's color
+ * type must be compatible with backend texture's format or this will fail. All formats are
+ * considered compatible with kUnknown. Returns a GrSurfaceDrawContext if possible.
+ */
+ static std::unique_ptr<GrSurfaceFillContext> MakeFromBackendTexture(
+ GrRecordingContext*,
+ GrColorInfo,
+ const GrBackendTexture&,
+ int sampleCount,
+ GrSurfaceOrigin,
+ sk_sp<GrRefCntedCallback> releaseHelper);
+
+ GrSurfaceFillContext* asFillContext() override { return this; }
+
+ /**
+ * Provides a performance hint that the render target's contents are allowed
+ * to become undefined.
+ */
+ void discard();
+
+ /**
+ * Clear the rect of the render target to the given color.
+ * @param rect the rect to clear to
+ * @param color the color to clear to.
+ */
+ template <SkAlphaType AlphaType>
+ void clear(const SkIRect& rect, const SkRGBA4f<AlphaType>& color) {
+ this->internalClear(&rect, this->adjustColorAlphaType(color));
+ }
+
+ /** Clears the entire render target to the color. */
+ template <SkAlphaType AlphaType> void clear(const SkRGBA4f<AlphaType>& color) {
+ this->internalClear(nullptr, this->adjustColorAlphaType(color));
+ }
+
+ /**
+ * Clear at minimum the pixels within 'scissor', but is allowed to clear the full render target
+ * if that is the more performant option.
+ */
+ template <SkAlphaType AlphaType>
+ void clearAtLeast(const SkIRect& scissor, const SkRGBA4f<AlphaType>& color) {
+ this->internalClear(&scissor,
+ this->adjustColorAlphaType(color),
+ /* upgrade to full */ true);
+ }
+
+ /** Fills 'dstRect' with 'fp' */
+ void fillRectWithFP(const SkIRect& dstRect, std::unique_ptr<GrFragmentProcessor> fp);
+
+ /**
+ * A convenience version of fillRectWithFP that applies a coordinate transformation via
+ * GrMatrixEffect.
+ */
+ void fillRectWithFP(const SkIRect& dstRect,
+ const SkMatrix& localMatrix,
+ std::unique_ptr<GrFragmentProcessor> fp) {
+ fp = GrMatrixEffect::Make(localMatrix, std::move(fp));
+ this->fillRectWithFP(dstRect, std::move(fp));
+ }
+
+ /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */
+ void fillRectToRectWithFP(const SkRect& srcRect,
+ const SkIRect& dstRect,
+ std::unique_ptr<GrFragmentProcessor> fp) {
+ SkMatrix lm;
+ lm.setRectToRect(SkRect::Make(dstRect), srcRect, SkMatrix::kFill_ScaleToFit);
+ this->fillRectWithFP(dstRect, lm, std::move(fp));
+ }
+
+ /** Fills 'dstRect' with 'fp' using a local matrix that maps 'srcRect' to 'dstRect' */
+ void fillRectToRectWithFP(const SkIRect& srcRect,
+ const SkIRect& dstRect,
+ std::unique_ptr<GrFragmentProcessor> fp) {
+ this->fillRectToRectWithFP(SkRect::Make(srcRect), dstRect, std::move(fp));
+ }
+
+ /** Fills the entire render target with the passed FP. */
+ void fillWithFP(std::unique_ptr<GrFragmentProcessor> fp) {
+ this->fillRectWithFP(SkIRect::MakeSize(fWriteView.proxy()->dimensions()), std::move(fp));
+ }
+
+ /**
+ * A convenience version of fillWithFP that applies a coordinate transformation via
+ * GrMatrixEffect and fills the entire render target.
+ */
+ void fillWithFP(const SkMatrix& localMatrix, std::unique_ptr<GrFragmentProcessor> fp) {
+ this->fillRectWithFP(
+ SkIRect::MakeSize(fWriteView.proxy()->dimensions()), localMatrix, std::move(fp));
+ }
+
+ /**
+ * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
+ * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
+ * respectively.
+ */
+ bool blitTexture(GrSurfaceProxyView view, const SkIRect& srcRect, const SkIPoint& dstPoint);
+
+ GrOpsTask* getOpsTask();
+
+ int numSamples() const { return this->asRenderTargetProxy()->numSamples(); }
+ bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
+ GrMipmapped mipmapped() const;
+
+#if GR_TEST_UTILS
+ GrOpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }
+#endif
+
+ const GrSurfaceProxyView& writeSurfaceView() const { return fWriteView; }
+
+protected:
+ /**
+ * Creates a constant color paint for a clear, using src-over if possible to improve batching.
+ */
+ static void ClearToGrPaint(std::array<float, 4> color, GrPaint* paint);
+
+ void addOp(GrOp::Owner);
+
+private:
+ template <SkAlphaType AlphaType>
+ static std::array<float, 4> ConvertColor(SkRGBA4f<AlphaType> color);
+
+ template <SkAlphaType AlphaType>
+ std::array<float, 4> adjustColorAlphaType(SkRGBA4f<AlphaType> color) const;
+
+ /** Override to be notified in subclass before the current ops task is replaced. */
+ virtual void willReplaceOpsTask(GrOpsTask* prevTask, GrOpsTask* nextTask) {}
+
+ /**
+ * Override to be called to participate in the decision to discard all previous ops if a
+ * fullscreen clear occurs.
+ */
+ virtual GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const {
+ return GrOpsTask::CanDiscardPreviousOps::kYes;
+ }
+
+ void internalClear(const SkIRect* scissor,
+ std::array<float, 4> color,
+ bool upgradePartialToFull = false);
+
+ void addDrawOp(GrOp::Owner);
+
+ SkDEBUGCODE(void onValidate() const override;)
+
+ GrSurfaceProxyView fWriteView;
+
+ // The GrOpsTask can be closed by some other surface context that has picked it up. For this
+ // reason, the GrOpsTask should only ever be accessed via 'getOpsTask'.
+ sk_sp<GrOpsTask> fOpsTask;
+
+ bool fFlushTimeOpsTask;
+
+ using INHERITED = GrSurfaceContext;
+};
+
+template<>
+inline std::array<float, 4> GrSurfaceFillContext::ConvertColor<kPremul_SkAlphaType>(
+ SkPMColor4f color) {
+ return color.unpremul().array();
+}
+
+template<>
+inline std::array<float, 4> GrSurfaceFillContext::ConvertColor<kUnpremul_SkAlphaType>(
+ SkColor4f color) {
+ return color.premul().array();
+}
+
+template <SkAlphaType AlphaType>
+std::array<float, 4> GrSurfaceFillContext::adjustColorAlphaType(SkRGBA4f<AlphaType> color) const {
+ if (AlphaType == kUnknown_SkAlphaType ||
+ this->colorInfo().alphaType() == kUnknown_SkAlphaType) {
+ return color.array();
+ }
+ return (AlphaType == this->colorInfo().alphaType()) ? color.array() : ConvertColor(color);
+}
+
+#endif
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index a588da3..7719dc9 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -291,19 +291,19 @@
}
}
if (src->asTextureProxy()) {
- auto dstContext = GrSurfaceDrawContext::Make(context,
+ auto dstContext = GrSurfaceFillContext::Make(context,
+ kUnknown_SkAlphaType,
nullptr,
- fit,
{width, height},
+ fit,
format,
- /* sample count*/ 1,
+ 1,
mipMapped,
src->isProtected(),
GrSwizzle::RGBA(),
GrSwizzle::RGBA(),
origin,
- budgeted,
- /*surface props*/ nullptr);
+ budgeted);
GrSurfaceProxyView view(sk_ref_sp(src), origin, GrSwizzle::RGBA());
if (dstContext && dstContext->blitTexture(std::move(view), srcRect, dstPoint)) {
return dstContext->asSurfaceProxyRef();
diff --git a/src/gpu/GrSwizzle.h b/src/gpu/GrSwizzle.h
index a250842..dad7597 100644
--- a/src/gpu/GrSwizzle.h
+++ b/src/gpu/GrSwizzle.h
@@ -41,8 +41,14 @@
}
/** Applies this swizzle to the input color and returns the swizzled color. */
+ constexpr std::array<float, 4> applyTo(std::array<float, 4> color) const;
+
+ /** Convenience version for SkRGBA colors. */
template <SkAlphaType AlphaType>
- constexpr SkRGBA4f<AlphaType> applyTo(const SkRGBA4f<AlphaType>& color) const;
+ constexpr SkRGBA4f<AlphaType> applyTo(SkRGBA4f<AlphaType> color) const {
+ std::array<float, 4> result = this->applyTo(color.array());
+ return {result[0], result[1], result[2], result[3]};
+ }
void apply(SkRasterPipeline*) const;
@@ -56,8 +62,7 @@
private:
explicit constexpr GrSwizzle(uint16_t key) : fKey(key) {}
- template <SkAlphaType AlphaType>
- static constexpr float ComponentIndexToFloat(const SkRGBA4f<AlphaType>& color, int idx);
+ static constexpr float ComponentIndexToFloat(std::array<float, 4>, int idx);
static constexpr int CToI(char c);
static constexpr char IToC(int idx);
@@ -75,8 +80,7 @@
return *this;
}
-template <SkAlphaType AlphaType>
-constexpr SkRGBA4f<AlphaType> GrSwizzle::applyTo(const SkRGBA4f<AlphaType>& color) const {
+constexpr std::array<float, 4> GrSwizzle::applyTo(std::array<float, 4> color) const {
uint32_t key = fKey;
// Index of the input color that should be mapped to output r.
int idx = (key & 15);
@@ -93,8 +97,7 @@
return { outR, outG, outB, outA };
}
-template <SkAlphaType AlphaType>
-constexpr float GrSwizzle::ComponentIndexToFloat(const SkRGBA4f<AlphaType>& color, int idx) {
+constexpr float GrSwizzle::ComponentIndexToFloat(std::array<float, 4> color, int idx) {
if (idx <= 3) {
return color[idx];
}
diff --git a/src/gpu/GrThreadSafeCache.cpp b/src/gpu/GrThreadSafeCache.cpp
index 61749a5..d76db3e 100644
--- a/src/gpu/GrThreadSafeCache.cpp
+++ b/src/gpu/GrThreadSafeCache.cpp
@@ -326,8 +326,7 @@
constexpr int kSampleCnt = 1;
auto [newCT, format] =
- GrSurfaceDrawContext::GetFallbackColorTypeAndFormat(
- dContext, origCT, kSampleCnt);
+ GrSurfaceFillContext::GetFallbackColorTypeAndFormat(dContext, origCT, kSampleCnt);
if (newCT == GrColorType::kUnknown) {
return {GrSurfaceProxyView(nullptr), nullptr};
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index a9c8154..09c51ae 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -22,7 +22,6 @@
@cppEnd {
bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* dContext) {
static constexpr int kSize = 256;
- static constexpr GrColorType kColorType = GrColorType::kRGBA_8888;
SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
uint32_t* srcData = data.get();
uint32_t* firstRead = data.get() + kSize * kSize;
@@ -40,28 +39,24 @@
color[0] = std::min(x, y);
}
}
- memset(firstRead, 0, kSize * kSize * sizeof(uint32_t));
- memset(secondRead, 0, kSize * kSize * sizeof(uint32_t));
+ std::fill_n( firstRead, kSize * kSize, 0);
+ std::fill_n(secondRead, kSize * kSize, 0);
- const SkImageInfo ii = SkImageInfo::Make(kSize, kSize,
- kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ const SkImageInfo pmII =
+ SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ const SkImageInfo upmII = pmII.makeAlphaType(kUnpremul_SkAlphaType);
- auto readRTC = GrSurfaceDrawContext::Make(
- dContext, kColorType, nullptr, SkBackingFit::kExact, {kSize, kSize});
- auto tempRTC = GrSurfaceDrawContext::Make(
- dContext, kColorType, nullptr, SkBackingFit::kExact, {kSize, kSize});
- if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
+ auto readSFC = GrSurfaceFillContext::Make(dContext, upmII, SkBackingFit::kExact);
+ auto tempSFC = GrSurfaceFillContext::Make(dContext, pmII, SkBackingFit::kExact);
+ if (!readSFC || !tempSFC) {
return false;
}
- // Adding discard to appease vulkan validation warning about loading uninitialized data on
- // draw
- readRTC->discard();
// This function is only ever called if we are in a GrDirectContext since we are
// calling read pixels here. Thus the pixel data will be uploaded immediately and we don't
// need to keep the pixel data alive in the proxy. Therefore the ReleaseProc is nullptr.
SkBitmap bitmap;
- bitmap.installPixels(ii, srcData, 4 * kSize);
+ bitmap.installPixels(pmII, srcData, 4 * kSize);
bitmap.setImmutable();
GrBitmapTextureMaker maker(dContext, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
@@ -70,50 +65,37 @@
return false;
}
- static const SkRect kRect = SkRect::MakeIWH(kSize, kSize);
-
// We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
// from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
// We then verify that two reads produced the same values.
- GrPaint paint1;
- paint1.setColorFragmentProcessor(GrConfigConversionEffect::Make(
- GrTextureEffect::Make(std::move(dataView), kPremul_SkAlphaType),
- PMConversion::kToUnpremul));
- paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- readRTC->fillRectToRect(nullptr, std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect, kRect);
- if (!readRTC->readPixels(dContext, ii, firstRead, 0, {0, 0})) {
+ auto fp1 = GrConfigConversionEffect::Make(GrTextureEffect::Make(std::move(dataView),
+ bitmap.alphaType()),
+ PMConversion::kToUnpremul);
+ readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp1));
+ if (!readSFC->readPixels(dContext, upmII, firstRead, 0, {0, 0})) {
return false;
}
- // Adding discard to appease vulkan validation warning about loading uninitialized data on
- // draw
- tempRTC->discard();
+ auto fp2 = GrConfigConversionEffect::Make(
+ GrTextureEffect::Make(readSFC->readSurfaceView(),
+ readSFC->colorInfo().alphaType()),
+ PMConversion::kToPremul);
+ tempSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp2));
- GrPaint paint2;
- paint2.setColorFragmentProcessor(GrConfigConversionEffect::Make(
- GrTextureEffect::Make(readRTC->readSurfaceView(), kUnpremul_SkAlphaType),
- PMConversion::kToPremul));
- paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ auto fp3 = GrConfigConversionEffect::Make(
+ GrTextureEffect::Make(tempSFC->readSurfaceView(),
+ tempSFC->colorInfo().alphaType()),
+ PMConversion::kToUnpremul);
+ readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp3));
- tempRTC->fillRectToRect(nullptr, std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect, kRect);
-
- GrPaint paint3;
- paint3.setColorFragmentProcessor(GrConfigConversionEffect::Make(
- GrTextureEffect::Make(tempRTC->readSurfaceView(), kPremul_SkAlphaType),
- PMConversion::kToUnpremul));
- paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- readRTC->fillRectToRect(nullptr, std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect, kRect);
-
- if (!readRTC->readPixels(dContext, ii, secondRead, 0, {0, 0})) {
+ if (!readSFC->readPixels(dContext, upmII, secondRead, 0, {0, 0})) {
return false;
}
for (int y = 0; y < kSize; ++y) {
for (int x = 0; x <= y; ++x) {
- if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) {
+ if (firstRead[kSize*y + x] != secondRead[kSize*y + x]) {
return false;
}
}
diff --git a/src/gpu/effects/generated/GrConfigConversionEffect.cpp b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
index 6c4ec43..1f165cc 100644
--- a/src/gpu/effects/generated/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
@@ -87,7 +87,6 @@
bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* dContext) {
static constexpr int kSize = 256;
- static constexpr GrColorType kColorType = GrColorType::kRGBA_8888;
SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
uint32_t* srcData = data.get();
uint32_t* firstRead = data.get() + kSize * kSize;
@@ -105,28 +104,24 @@
color[0] = std::min(x, y);
}
}
- memset(firstRead, 0, kSize * kSize * sizeof(uint32_t));
- memset(secondRead, 0, kSize * kSize * sizeof(uint32_t));
+ std::fill_n(firstRead, kSize * kSize, 0);
+ std::fill_n(secondRead, kSize * kSize, 0);
- const SkImageInfo ii =
+ const SkImageInfo pmII =
SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ const SkImageInfo upmII = pmII.makeAlphaType(kUnpremul_SkAlphaType);
- auto readRTC = GrSurfaceDrawContext::Make(dContext, kColorType, nullptr, SkBackingFit::kExact,
- {kSize, kSize});
- auto tempRTC = GrSurfaceDrawContext::Make(dContext, kColorType, nullptr, SkBackingFit::kExact,
- {kSize, kSize});
- if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
+ auto readSFC = GrSurfaceFillContext::Make(dContext, upmII, SkBackingFit::kExact);
+ auto tempSFC = GrSurfaceFillContext::Make(dContext, pmII, SkBackingFit::kExact);
+ if (!readSFC || !tempSFC) {
return false;
}
- // Adding discard to appease vulkan validation warning about loading uninitialized data on
- // draw
- readRTC->discard();
// This function is only ever called if we are in a GrDirectContext since we are
// calling read pixels here. Thus the pixel data will be uploaded immediately and we don't
// need to keep the pixel data alive in the proxy. Therefore the ReleaseProc is nullptr.
SkBitmap bitmap;
- bitmap.installPixels(ii, srcData, 4 * kSize);
+ bitmap.installPixels(pmII, srcData, 4 * kSize);
bitmap.setImmutable();
GrBitmapTextureMaker maker(dContext, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
@@ -135,44 +130,29 @@
return false;
}
- static const SkRect kRect = SkRect::MakeIWH(kSize, kSize);
-
// We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
// from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
// We then verify that two reads produced the same values.
- GrPaint paint1;
- paint1.setColorFragmentProcessor(GrConfigConversionEffect::Make(
- GrTextureEffect::Make(std::move(dataView), kPremul_SkAlphaType),
- PMConversion::kToUnpremul));
- paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- readRTC->fillRectToRect(nullptr, std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect, kRect);
- if (!readRTC->readPixels(dContext, ii, firstRead, 0, {0, 0})) {
+ auto fp1 = GrConfigConversionEffect::Make(
+ GrTextureEffect::Make(std::move(dataView), bitmap.alphaType()),
+ PMConversion::kToUnpremul);
+ readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp1));
+ if (!readSFC->readPixels(dContext, upmII, firstRead, 0, {0, 0})) {
return false;
}
- // Adding discard to appease vulkan validation warning about loading uninitialized data on
- // draw
- tempRTC->discard();
+ auto fp2 = GrConfigConversionEffect::Make(
+ GrTextureEffect::Make(readSFC->readSurfaceView(), readSFC->colorInfo().alphaType()),
+ PMConversion::kToPremul);
+ tempSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp2));
- GrPaint paint2;
- paint2.setColorFragmentProcessor(GrConfigConversionEffect::Make(
- GrTextureEffect::Make(readRTC->readSurfaceView(), kUnpremul_SkAlphaType),
- PMConversion::kToPremul));
- paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ auto fp3 = GrConfigConversionEffect::Make(
+ GrTextureEffect::Make(tempSFC->readSurfaceView(), tempSFC->colorInfo().alphaType()),
+ PMConversion::kToUnpremul);
+ readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp3));
- tempRTC->fillRectToRect(nullptr, std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect, kRect);
-
- GrPaint paint3;
- paint3.setColorFragmentProcessor(GrConfigConversionEffect::Make(
- GrTextureEffect::Make(tempRTC->readSurfaceView(), kPremul_SkAlphaType),
- PMConversion::kToUnpremul));
- paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
- readRTC->fillRectToRect(nullptr, std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect, kRect);
-
- if (!readRTC->readPixels(dContext, ii, secondRead, 0, {0, 0})) {
+ if (!readSFC->readPixels(dContext, upmII, secondRead, 0, {0, 0})) {
return false;
}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index aefe227..2f6c1e7 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -88,10 +88,11 @@
return nullptr;
}
- auto surfaceDrawContext = GrSurfaceDrawContext::MakeWithFallback(
- direct, SkColorTypeToGrColorType(targetCT), nullptr, SkBackingFit::kExact,
- this->dimensions());
- if (!surfaceDrawContext) {
+ auto info = this->imageInfo().makeColorType(targetCT).makeColorSpace(targetCS);
+ auto surfaceFillContext = GrSurfaceFillContext::MakeWithFallback(direct,
+ std::move(info),
+ SkBackingFit::kExact);
+ if (!surfaceFillContext) {
return nullptr;
}
@@ -101,20 +102,12 @@
targetCS.get(), this->alphaType());
SkASSERT(colorFP);
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.setColorFragmentProcessor(std::move(colorFP));
+ surfaceFillContext->fillWithFP(std::move(colorFP));
+ SkASSERT(surfaceFillContext->asTextureProxy());
- surfaceDrawContext->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
- SkRect::MakeIWH(this->width(), this->height()));
- if (!surfaceDrawContext->asTextureProxy()) {
- return nullptr;
- }
-
- targetCT = GrColorTypeToSkColorType(surfaceDrawContext->colorInfo().colorType());
- // MDB: this call is okay bc we know 'surfaceDrawContext' was exact
+ targetCT = GrColorTypeToSkColorType(surfaceFillContext->colorInfo().colorType());
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct), kNeedNewImageUniqueID,
- surfaceDrawContext->readSurfaceView(), targetCT,
+ surfaceFillContext->readSurfaceView(), targetCT,
this->alphaType(), std::move(targetCS));
}
diff --git a/src/image/SkImage_GpuBase.h b/src/image/SkImage_GpuBase.h
index 63d34f2..f4f763e 100644
--- a/src/image/SkImage_GpuBase.h
+++ b/src/image/SkImage_GpuBase.h
@@ -17,7 +17,7 @@
class GrColorSpaceXform;
class GrDirectContext;
class GrImageContext;
-class GrSurfaceDrawContext;
+class GrSurfaceFillContext;
class SkColorSpace;
class SkImage_GpuBase : public SkImage_Base {
diff --git a/src/image/SkImage_GpuYUVA.cpp b/src/image/SkImage_GpuYUVA.cpp
index b203827..18be7eb 100644
--- a/src/image/SkImage_GpuYUVA.cpp
+++ b/src/image/SkImage_GpuYUVA.cpp
@@ -205,19 +205,22 @@
}
// Needs to create a render target in order to draw to it for the yuv->rgb conversion.
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- context, GrColorType::kRGBA_8888, this->refColorSpace(), SkBackingFit::kExact,
- this->dimensions(), 1, GrMipmapped::kNo, GrProtected::kNo);
- if (!surfaceDrawContext) {
+ GrImageInfo info(GrColorType::kRGBA_8888,
+ kPremul_SkAlphaType,
+ this->refColorSpace(),
+ this->dimensions());
+ auto surfaceFillContext = GrSurfaceFillContext::Make(context,
+ info,
+ SkBackingFit::kExact,
+ /*sample count*/ 1,
+ GrMipmapped::kNo,
+ GrProtected::kNo);
+ if (!surfaceFillContext) {
return;
}
- const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
const GrCaps& caps = *context->priv().caps();
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-
auto fp = GrYUVtoRGBEffect::Make(fViews,
fYUVAIndices,
fYUVColorSpace,
@@ -230,11 +233,10 @@
this->alphaType());
fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(colorSpaceXform));
}
- paint.setColorFragmentProcessor(std::move(fp));
- surfaceDrawContext->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
+ surfaceFillContext->fillWithFP(std::move(fp));
- fRGBView = surfaceDrawContext->readSurfaceView();
+ fRGBView = surfaceFillContext->readSurfaceView();
SkASSERT(fRGBView.swizzle() == GrSwizzle());
for (auto& v : fViews) {
v.reset();
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index 3edcbcc..9cca6a3 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -305,17 +305,24 @@
}
// TODO: investigate preallocating mip maps here
- GrColorType ct = SkColorTypeToGrColorType(this->colorType());
- auto surfaceDrawContext = GrSurfaceDrawContext::Make(
- ctx, ct, nullptr, SkBackingFit::kExact, this->dimensions(), 1, GrMipmapped::kNo,
- GrProtected::kNo, kTopLeft_GrSurfaceOrigin, budgeted);
- if (!surfaceDrawContext) {
+ GrImageInfo info(SkColorTypeToGrColorType(this->colorType()),
+ kPremul_SkAlphaType,
+ /*color space*/ nullptr,
+ this->dimensions());
+ auto surfaceFillContext = GrSurfaceFillContext::Make(ctx,
+ info,
+ SkBackingFit::kExact,
+ 1,
+ GrMipmapped::kNo,
+ GrProtected::kNo,
+ kTopLeft_GrSurfaceOrigin,
+ budgeted);
+ if (!surfaceFillContext) {
return {};
}
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
SkAssertResult(yuvaPixmaps.toYUVAIndices(yuvaIndices));
- GrPaint paint;
std::unique_ptr<GrFragmentProcessor> yuvToRgbProcessor =
GrYUVtoRGBEffect::Make(yuvViews,
yuvaIndices,
@@ -340,18 +347,15 @@
GrColorSpaceXformEffect::Make(std::move(yuvToRgbProcessor),
srcColorSpace, kOpaque_SkAlphaType,
dstColorSpace, kOpaque_SkAlphaType);
- paint.setColorFragmentProcessor(std::move(colorConversionProcessor));
-
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- const SkRect r = SkRect::Make(this->dimensions());
-
SkMatrix m = SkEncodedOriginToMatrix(yuvaPixmaps.yuvaInfo().origin(),
this->width(),
this->height());
- surfaceDrawContext->drawRect(nullptr, std::move(paint), GrAA::kNo, m, r);
+ // The returned matrix is a view matrix but we need a local matrix.
+ SkAssertResult(m.invert(&m));
+ surfaceFillContext->fillWithFP(m, std::move(colorConversionProcessor));
- SkASSERT(surfaceDrawContext->asTextureProxy());
- return surfaceDrawContext->readSurfaceView();
+ SkASSERT(surfaceFillContext->asTextureProxy());
+ return surfaceFillContext->readSurfaceView();
}
sk_sp<SkCachedData> SkImage_Lazy::getPlanes(
diff --git a/tests/CopySurfaceTest.cpp b/tests/CopySurfaceTest.cpp
index f05dc86..19dadfc 100644
--- a/tests/CopySurfaceTest.cpp
+++ b/tests/CopySurfaceTest.cpp
@@ -115,8 +115,8 @@
srcRect,
dstPoint);
} else if (dRenderable == GrRenderable::kYes) {
- SkASSERT(dstContext->asRenderTargetContext());
- result = dstContext->asRenderTargetContext()->blitTexture(
+ SkASSERT(dstContext->asFillContext());
+ result = dstContext->asFillContext()->blitTexture(
std::move(srcView), srcRect, dstPoint);
}
diff --git a/tests/EGLImageTest.cpp b/tests/EGLImageTest.cpp
index b7e8c90..8ad24b6 100644
--- a/tests/EGLImageTest.cpp
+++ b/tests/EGLImageTest.cpp
@@ -184,13 +184,11 @@
// Should not be able to wrap as a RT
{
- auto temp = GrSurfaceDrawContext::MakeFromBackendTexture(context0,
- colorInfo.colorType(),
- /*color space*/ nullptr,
+ auto temp = GrSurfaceFillContext::MakeFromBackendTexture(context0,
+ colorInfo,
backendTex,
1,
origin,
- /*surface props*/ nullptr,
/*release helper*/ nullptr);
if (temp) {
ERRORF(reporter, "Should not be able to wrap an EXTERNAL texture as a RT.");
diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp
index 96ef0ae..a075907 100644
--- a/tests/GrMipMappedTest.cpp
+++ b/tests/GrMipMappedTest.cpp
@@ -429,7 +429,7 @@
auto mipmapRTC = GrSurfaceDrawContext::Make(
dContext.get(), colorType, nullptr, mipmapProxy, kTopLeft_GrSurfaceOrigin, nullptr);
- mipmapRTC->clear({.1f,.2f,.3f,.4f});
+ mipmapRTC->clear(SkPMColor4f{.1f, .2f, .3f, .4f});
REPORTER_ASSERT(reporter, drawingManager->getLastRenderTask(mipmapProxy.get()));
// mipmapProxy's last render task should now just be the opsTask containing the clear.
REPORTER_ASSERT(reporter,
@@ -475,7 +475,7 @@
REPORTER_ASSERT(reporter, rtc2Task->dependsOn(initialMipmapRegenTask));
// Render something to dirty the mips.
- mipmapRTC->clear({.1f,.2f,.3f,.4f});
+ mipmapRTC->clear(SkPMColor4f{.1f, .2f, .3f, .4f});
auto mipmapRTCTask = sk_ref_sp(mipmapRTC->testingOnly_PeekLastOpsTask());
REPORTER_ASSERT(reporter, mipmapRTCTask);
diff --git a/tests/GrThreadSafeCacheTest.cpp b/tests/GrThreadSafeCacheTest.cpp
index 6db901b..16d267e 100644
--- a/tests/GrThreadSafeCacheTest.cpp
+++ b/tests/GrThreadSafeCacheTest.cpp
@@ -645,7 +645,7 @@
GrPaint paint;
paint.setColor4f({0.0f, 0.0f, 1.0f, 1.0f});
- rtc->clear({1.0f, 1.0f, 1.0f, 1.0f});
+ rtc->clear(SkPMColor4f{1.0f, 1.0f, 1.0f, 1.0f});
rtc->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
{ 10, 10, wh-10.0f, wh-10.0f }, &GrStyle::SimpleFill());
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index 16a493d..dffa40a 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -471,7 +471,7 @@
rContext, GrColorType::kRGBA_8888, nullptr,
SkBackingFit::kApprox, {3 * kDrawnTileSize, kDrawnTileSize});
- rtc->clear({ 1, 0, 0, 1 });
+ rtc->clear(SkPMColor4f{1, 0, 0, 1});
for (int i = 0; i < 3; ++i) {
SkRect r = SkRect::MakeXYWH(i*kDrawnTileSize, 0, kDrawnTileSize, kDrawnTileSize);
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index 5befdc3..f0aa7b4 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -962,14 +962,11 @@
if (src.colorType() == kRGB_888x_SkColorType) {
return Surface();
}
- std::unique_ptr<GrSurfaceContext> surfContext;
- // Renderable + unpremul/unknown is not allowed (yet!), skbug.com/11019
- if (renderable == GrRenderable::kNo ||
- src.alphaType() == kPremul_SkAlphaType ||
- src.alphaType() == kOpaque_SkAlphaType) {
- surfContext = GrSurfaceContext::Make(direct, src.info(), SkBackingFit::kExact,
- origin, renderable);
- }
+ auto surfContext = GrSurfaceContext::Make(direct,
+ src.info(),
+ SkBackingFit::kExact,
+ origin,
+ renderable);
if (surfContext) {
surfContext->writePixels(direct,
src.info(),
diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp
index 9d106de..1c49e0f 100644
--- a/tests/RectangleTextureTest.cpp
+++ b/tests/RectangleTextureTest.cpp
@@ -24,17 +24,14 @@
static void test_basic_draw_as_src(skiatest::Reporter* reporter, GrDirectContext* dContext,
GrSurfaceProxyView rectView, GrColorType colorType,
SkAlphaType alphaType, uint32_t expectedPixelValues[]) {
- auto rtContext = GrSurfaceDrawContext::Make(
- dContext, colorType, nullptr, SkBackingFit::kExact, rectView.proxy()->dimensions());
+ auto fillContext = GrSurfaceFillContext::Make(
+ dContext, {colorType, kPremul_SkAlphaType, nullptr, rectView.dimensions()});
for (auto filter : {GrSamplerState::Filter::kNearest, GrSamplerState::Filter::kLinear}) {
for (auto mm : {GrSamplerState::MipmapMode::kNone, GrSamplerState::MipmapMode::kLinear}) {
- rtContext->clear(SkPMColor4f::FromBytes_RGBA(0xDDCCBBAA));
+ fillContext->clear(SkPMColor4f::FromBytes_RGBA(0xDDCCBBAA));
auto fp = GrTextureEffect::Make(rectView, alphaType, SkMatrix::I(), filter, mm);
- GrPaint paint;
- paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
- paint.setColorFragmentProcessor(std::move(fp));
- rtContext->drawPaint(nullptr, std::move(paint), SkMatrix::I());
- TestReadPixels(reporter, dContext, rtContext.get(), expectedPixelValues,
+ fillContext->fillWithFP(std::move(fp));
+ TestReadPixels(reporter, dContext, fillContext.get(), expectedPixelValues,
"RectangleTexture-basic-draw");
}
}
@@ -42,13 +39,13 @@
static void test_clear(skiatest::Reporter* reporter, GrDirectContext* dContext,
GrSurfaceContext* rectContext) {
- if (GrSurfaceDrawContext* rtc = rectContext->asRenderTargetContext()) {
+ if (GrSurfaceFillContext* sfc = rectContext->asFillContext()) {
// Clear the whole thing.
GrColor color0 = GrColorPackRGBA(0xA, 0xB, 0xC, 0xD);
- rtc->clear(SkPMColor4f::FromBytes_RGBA(color0));
+ sfc->clear(SkPMColor4f::FromBytes_RGBA(color0));
- int w = rtc->width();
- int h = rtc->height();
+ int w = sfc->width();
+ int h = sfc->height();
int pixelCnt = w * h;
SkAutoTMalloc<uint32_t> expectedPixels(pixelCnt);
@@ -59,14 +56,14 @@
expectedBytes0[1] = GrColorUnpackG(color0);
expectedBytes0[2] = GrColorUnpackB(color0);
expectedBytes0[3] = GrColorUnpackA(color0);
- for (int i = 0; i < rtc->width() * rtc->height(); ++i) {
+ for (int i = 0; i < sfc->width() * sfc->height(); ++i) {
expectedPixels.get()[i] = expectedColor0;
}
// Clear the the top to a different color.
GrColor color1 = GrColorPackRGBA(0x1, 0x2, 0x3, 0x4);
SkIRect rect = SkIRect::MakeWH(w, h/2);
- rtc->clear(rect, SkPMColor4f::FromBytes_RGBA(color1));
+ sfc->clear(rect, SkPMColor4f::FromBytes_RGBA(color1));
uint32_t expectedColor1 = 0;
uint8_t* expectedBytes1 = reinterpret_cast<uint8_t*>(&expectedColor1);
@@ -81,7 +78,7 @@
}
}
- TestReadPixels(reporter, dContext, rtc, expectedPixels.get(), "RectangleTexture-clear");
+ TestReadPixels(reporter, dContext, sfc, expectedPixels.get(), "RectangleTexture-clear");
}
}