Revert "Add GrSurfaceFillContext"
This reverts commit b339bbe9dcbfea25b08539ebe3d8c5ec9a868e42.
Revert "Make backend allocation tests avoid alphatype conversions"
This reverts commit 177af6f4102c431e17999ec90afa3e18bacdd8b1.
Bug: skia:11019
Change-Id: Id80aa7df4a15c8530a609c49ca6264bce7831852
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344569
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrSurfaceDrawContext.cpp b/src/gpu/GrSurfaceDrawContext.cpp
index 2a07d0d..31c5d34 100644
--- a/src/gpu/GrSurfaceDrawContext.cpp
+++ b/src/gpu/GrSurfaceDrawContext.cpp
@@ -73,6 +73,7 @@
#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; }
//////////////////////////////////////////////////////////////////////////////
@@ -201,6 +202,43 @@
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,
@@ -288,16 +326,28 @@
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* surfaceProps,
bool flushTimeOpsTask)
- : GrSurfaceFillContext(context,
- std::move(readView),
- std::move(writeView),
- {colorType, kPremul_SkAlphaType, std::move(colorSpace)},
- flushTimeOpsTask)
+ : GrSurfaceContext(context,
+ std::move(readView),
+ {colorType, kPremul_SkAlphaType, std::move(colorSpace)})
+ , fWriteView(std::move(writeView))
, 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
}
@@ -321,6 +371,27 @@
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) {
@@ -445,6 +516,99 @@
}
}
+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) {
@@ -595,7 +759,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;
- ClearToGrPaint(constColor->array(), &paint);
+ clear_to_grpaint(*constColor, &paint);
this->drawRRect(nullptr, std::move(paint), result.fAA, SkMatrix::I(), result.fRRect,
GrStyle::SimpleFill());
return QuadOptimization::kSubmitted;
@@ -762,8 +926,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);
@@ -1820,6 +1984,12 @@
}
}
+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) {
@@ -1847,12 +2017,9 @@
bool skipDraw = false;
if (clip) {
// Have a complex clip, so defer to its early clip culling
- GrAAType aaType;
- if (usesHWAA) {
- aaType = GrAAType::kMSAA;
- } else {
- aaType = op->hasAABloat() ? GrAAType::kCoverage : GrAAType::kNone;
- }
+ GrAAType aaType = usesHWAA ? GrAAType::kMSAA :
+ (op->hasAABloat() ? GrAAType::kCoverage :
+ GrAAType::kNone);
skipDraw = clip->apply(fContext, this, aaType, usesUserStencilBits,
&appliedClip, &bounds) == GrClip::Effect::kClippedOut;
} else {
@@ -1958,3 +2125,31 @@
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;
+}