diff options
author | Michael Ludwig <michaelludwig@google.com> | 2019-01-23 11:14:29 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2019-01-23 16:45:01 +0000 |
commit | 7545190e32b2bee7472f7a91bd5d841298963f6d (patch) | |
tree | d04d3493d2fcbfdb6233b868ab054009fb6b90f8 /src | |
parent | 84e0064bc54399ccc7cd535af645bec67bea4185 (diff) | |
download | skqp-7545190e32b2bee7472f7a91bd5d841298963f6d.tar.gz |
Add new experimental API for rectangles with per-edge AA control
Also updates GM_draw_quad_set to use this API instead of the
bulk API on GrRenderTargetContext.
Bug: skia:8506
Change-Id: Ia342d83c509f9db69f06f01599c7041c98aabdb6
Reviewed-on: https://skia-review.googlesource.com/c/184488
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkCanvas.cpp | 22 | ||||
-rw-r--r-- | src/core/SkColorSpaceXformCanvas.cpp | 4 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 10 | ||||
-rw-r--r-- | src/core/SkDevice.h | 5 | ||||
-rw-r--r-- | src/core/SkLiteDL.cpp | 20 | ||||
-rw-r--r-- | src/core/SkLiteDL.h | 1 | ||||
-rw-r--r-- | src/core/SkLiteRecorder.cpp | 4 | ||||
-rw-r--r-- | src/core/SkLiteRecorder.h | 1 | ||||
-rw-r--r-- | src/core/SkOverdrawCanvas.cpp | 5 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 5 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 10 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 12 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 1 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 3 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 5 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 1 | ||||
-rw-r--r-- | src/core/SkRecords.h | 6 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 31 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.h | 7 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 20 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.h | 2 | ||||
-rw-r--r-- | src/gpu/ops/GrFillRectOp.h | 1 | ||||
-rw-r--r-- | src/utils/SkNWayCanvas.cpp | 8 | ||||
-rw-r--r-- | src/utils/SkPaintFilterCanvas.cpp | 11 |
24 files changed, 193 insertions, 2 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 5f342c4082..e14321dd11 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -1876,6 +1876,14 @@ void SkCanvas::experimental_DrawImageSetV1(const ImageSetEntry imageSet[], int c this->onDrawImageSet(imageSet, cnt, filterQuality, mode); } +void SkCanvas::experimental_DrawEdgeAARectV1(const SkRect& r, QuadAAFlags edgeAA, SkColor color, + SkBlendMode mode) { + TRACE_EVENT0("skia", TRACE_FUNC); + // To avoid redundant logic in our culling code and various backends, we always sort rects + // before passing them along. + this->onDrawEdgeAARect(r.makeSorted(), edgeAA, color, mode); +} + void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { TRACE_EVENT0("skia", TRACE_FUNC); if (bitmap.drawsNothing()) { @@ -2086,6 +2094,20 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { } } +void SkCanvas::onDrawEdgeAARect(const SkRect& r, QuadAAFlags edgeAA, SkColor color, + SkBlendMode mode) { + SkASSERT(r.isSorted()); + + SkPaint paint; + LOOPER_BEGIN(paint, nullptr) + + while (iter.next()) { + iter.fDevice->drawEdgeAARect(r, edgeAA, color, mode); + } + + LOOPER_END +} + void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { SkRect regionRect = SkRect::Make(region.getBounds()); if (paint.canComputeFastBounds()) { diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp index 63df9929fc..ceb014e7b5 100644 --- a/src/core/SkColorSpaceXformCanvas.cpp +++ b/src/core/SkColorSpaceXformCanvas.cpp @@ -57,6 +57,10 @@ public: void onDrawRect(const SkRect& rect, const SkPaint& paint) override { fTarget->drawRect(rect, fXformer->apply(paint)); } + void onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) override { + fTarget->experimental_DrawEdgeAARectV1(rect, aa, fXformer->apply(color), mode); + } void onDrawOval(const SkRect& oval, const SkPaint& paint) override { fTarget->drawOval(oval, fXformer->apply(paint)); } diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 35808887bf..d4cd75d321 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -129,6 +129,16 @@ void SkBaseDevice::drawDRRect(const SkRRect& outer, this->drawPath(path, paint, true); } +void SkBaseDevice::drawEdgeAARect(const SkRect& r, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + SkPaint paint; + paint.setColor(color); + paint.setBlendMode(mode); + paint.setAntiAlias(aa == SkCanvas::kAll_QuadAAFlags); + + this->drawRect(r, paint); +} + void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkBlendMode bmode, const SkPaint& paint) { SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &this->ctm()); diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h index d8621c499d..9f2d7fd08a 100644 --- a/src/core/SkDevice.h +++ b/src/core/SkDevice.h @@ -175,6 +175,11 @@ protected: virtual void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&); + // Default impl always calls drawRect() with a solid-color paint, setting it to anti-aliased + // only when all edge flags are set. + virtual void drawEdgeAARect(const SkRect& r, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode); + /** * If pathIsMutable, then the implementation is allowed to cast path to a * non-const pointer and modify it in place (as an optimization). Canvas diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp index 831544c2f2..d61f52c729 100644 --- a/src/core/SkLiteDL.cpp +++ b/src/core/SkLiteDL.cpp @@ -52,7 +52,8 @@ namespace { M(Flush) M(Save) M(Restore) M(SaveLayer) M(SaveBehind) \ M(Concat) M(SetMatrix) M(Translate) \ M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \ - M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawRegion) M(DrawOval) M(DrawArc) \ + M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawEdgeAARect) \ + M(DrawRegion) M(DrawOval) M(DrawArc) \ M(DrawRRect) M(DrawDRRect) M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) \ M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) M(DrawImageSet) \ M(DrawTextBlob) \ @@ -189,6 +190,19 @@ namespace { SkPaint paint; void draw(SkCanvas* c, const SkMatrix&) const { c->drawRect(rect, paint); } }; + struct DrawEdgeAARect final : Op { + static const auto kType = Type::DrawEdgeAARect; + DrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) + : rect(rect), aa(aa), color(color), mode(mode) {} + SkRect rect; + SkCanvas::QuadAAFlags aa; + SkColor color; + SkBlendMode mode; + void draw(SkCanvas* c, const SkMatrix&) const { + c->experimental_DrawEdgeAARectV1(rect, aa, color, mode); + } + }; struct DrawRegion final : Op { static const auto kType = Type::DrawRegion; DrawRegion(const SkRegion& region, const SkPaint& paint) : region(region), paint(paint) {} @@ -519,6 +533,10 @@ void SkLiteDL::drawPath(const SkPath& path, const SkPaint& paint) { void SkLiteDL::drawRect(const SkRect& rect, const SkPaint& paint) { this->push<DrawRect>(0, rect, paint); } +void SkLiteDL::drawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + this->push<DrawEdgeAARect>(0, rect, aa, color, mode); +} void SkLiteDL::drawRegion(const SkRegion& region, const SkPaint& paint) { this->push<DrawRegion>(0, region, paint); } diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h index 5c4c5199cc..a6041bc2d6 100644 --- a/src/core/SkLiteDL.h +++ b/src/core/SkLiteDL.h @@ -46,6 +46,7 @@ public: void drawPaint (const SkPaint&); void drawPath (const SkPath&, const SkPaint&); void drawRect (const SkRect&, const SkPaint&); + void drawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode); void drawRegion(const SkRegion&, const SkPaint&); void drawOval (const SkRect&, const SkPaint&); void drawArc (const SkRect&, SkScalar, SkScalar, bool, const SkPaint&); diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp index 50cece84c8..6dda8d6fa9 100644 --- a/src/core/SkLiteRecorder.cpp +++ b/src/core/SkLiteRecorder.cpp @@ -66,6 +66,10 @@ void SkLiteRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) { void SkLiteRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) { fDL->drawRect(rect, paint); } +void SkLiteRecorder::onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + fDL->drawEdgeAARect(rect, aa, color, mode); +} void SkLiteRecorder::onDrawRegion(const SkRegion& region, const SkPaint& paint) { fDL->drawRegion(region, paint); } diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h index 805b460df2..81eedb341c 100644 --- a/src/core/SkLiteRecorder.h +++ b/src/core/SkLiteRecorder.h @@ -39,6 +39,7 @@ public: void onDrawPaint (const SkPaint&) override; void onDrawPath (const SkPath&, const SkPaint&) override; void onDrawRect (const SkRect&, const SkPaint&) override; + void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override; void onDrawRegion(const SkRegion&, const SkPaint&) override; void onDrawOval (const SkRect&, const SkPaint&) override; void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; diff --git a/src/core/SkOverdrawCanvas.cpp b/src/core/SkOverdrawCanvas.cpp index d1f247e508..a7b39bbb66 100644 --- a/src/core/SkOverdrawCanvas.cpp +++ b/src/core/SkOverdrawCanvas.cpp @@ -117,6 +117,11 @@ void SkOverdrawCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { fList[0]->onDrawRect(rect, this->overdrawPaint(paint)); } +void SkOverdrawCanvas::onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + fList[0]->onDrawRect(rect, fPaint); +} + void SkOverdrawCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { fList[0]->onDrawRegion(region, this->overdrawPaint(paint)); } diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index 5231b6981f..e4bb6e4399 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -100,7 +100,10 @@ enum DrawType { DRAW_IMAGE_SET, SAVE_BEHIND, - LAST_DRAWTYPE_ENUM = SAVE_BEHIND, + + DRAW_EDGEAA_RECT, + + LAST_DRAWTYPE_ENUM = DRAW_EDGEAA_RECT, }; enum DrawVertexFlags { diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 0ee07ef5f1..499e2a576d 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -304,6 +304,16 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, canvas->drawDRRect(outer, inner, *paint); } } break; + case DRAW_EDGEAA_RECT: { + SkRect rect; + reader->readRect(&rect); + SkCanvas::QuadAAFlags aaFlags = static_cast<SkCanvas::QuadAAFlags>(reader->read32()); + SkColor color = reader->read32(); + SkBlendMode blend = static_cast<SkBlendMode>(reader->read32()); + BREAK_ON_READ_ERROR(reader); + + canvas->experimental_DrawEdgeAARectV1(rect, aaFlags, color, blend); + } break; case DRAW_IMAGE: { const SkPaint* paint = fPictureData->getPaint(reader); const SkImage* image = fPictureData->getImage(reader); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index d179b06438..01115bfdce 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -467,6 +467,18 @@ void SkPictureRecord::onDrawRect(const SkRect& rect, const SkPaint& paint) { this->validate(initialOffset, size); } +void SkPictureRecord::onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, + SkColor color, SkBlendMode mode) { + // op + rect + aa flags + color + mode + size_t size = 4 * kUInt32Size + sizeof(rect); + size_t initialOffset = this->addDraw(DRAW_EDGEAA_RECT, &size); + this->addRect(rect); + this->addInt((int) aa); + this->addInt((int) color); + this->addInt((int) mode); + this->validate(initialOffset, size); +} + void SkPictureRecord::onDrawRegion(const SkRegion& region, const SkPaint& paint) { // op + paint index + region size_t regionBytes = region.writeToMemory(nullptr); diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index 8ed9edfb7f..77137c4716 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -176,6 +176,7 @@ protected: void onDrawPaint(const SkPaint&) override; void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; + void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override; void onDrawRegion(const SkRegion&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index cb97336457..4dcc45502f 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -124,6 +124,7 @@ DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint)); DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint)); DRAW(DrawRRect, drawRRect(r.rrect, r.paint)); DRAW(DrawRect, drawRect(r.rect, r.paint)); +DRAW(DrawEdgeAARect, experimental_DrawEdgeAARectV1(r.rect, r.aa, r.color, r.mode)); DRAW(DrawRegion, drawRegion(r.region, r.paint)); DRAW(DrawTextBlob, drawTextBlob(r.blob.get(), r.x, r.y, r.paint)); DRAW(DrawAtlas, drawAtlas(r.atlas.get(), @@ -356,6 +357,8 @@ private: Bounds bounds(const NoOp&) const { return Bounds::MakeEmpty(); } // NoOps don't draw. Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); } + Bounds bounds(const DrawEdgeAARect& op) const { return this->adjustAndMap(op.rect, nullptr); } + Bounds bounds(const DrawRegion& op) const { SkRect rect = SkRect::Make(op.region.getBounds()); return this->adjustAndMap(rect, &op.paint); diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 5340bee41f..bfe1067bbd 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -151,6 +151,11 @@ void SkRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) { this->append<SkRecords::DrawRect>(paint, rect); } +void SkRecorder::onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + this->append<SkRecords::DrawEdgeAARect>(rect, aa, color, mode); +} + void SkRecorder::onDrawRegion(const SkRegion& region, const SkPaint& paint) { this->append<SkRecords::DrawRegion>(paint, region); } diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 1a68b1f2f9..6b4c7fe1cd 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -79,6 +79,7 @@ public: void onDrawPaint(const SkPaint&) override; void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; void onDrawRect(const SkRect&, const SkPaint&) override; + void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override; void onDrawRegion(const SkRegion&, const SkPaint&) override; void onDrawOval(const SkRect&, const SkPaint&) override; void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index 7500adcfc9..8f80924ab4 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -67,6 +67,7 @@ namespace SkRecords { M(DrawPoints) \ M(DrawRRect) \ M(DrawRect) \ + M(DrawEdgeAARect) \ M(DrawRegion) \ M(DrawTextBlob) \ M(DrawAtlas) \ @@ -286,6 +287,11 @@ RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag, RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag, SkPaint paint; SkRect rect); +RECORD(DrawEdgeAARect, kDraw_Tag, + SkRect rect; + SkCanvas::QuadAAFlags aa; + SkColor color; + SkBlendMode mode); RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag, SkPaint paint; SkRegion region); diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index ddfb13a630..31b8349766 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -909,6 +909,37 @@ void GrRenderTargetContext::fillRectToRect(const GrClip& clip, viewMatrix, croppedRect, croppedLocalRect)); } +void GrRenderTargetContext::fillRectWithEdgeAA(const GrClip& clip, GrPaint&& paint, + GrQuadAAFlags edgeAA, const SkMatrix& viewMatrix, + const SkRect& rect) { + ASSERT_SINGLE_OWNER + RETURN_IF_ABANDONED + SkDEBUGCODE(this->validate();) + GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "fillRectWithEdgeAA", fContext); + + // If aaType turns into MSAA, make sure to keep quads with no AA edges as MSAA. Sending those + // to drawFilledRect() would have it turn off MSAA in that case, which breaks seaming with + // any partial AA edges that kept MSAA. + GrAAType aaType = this->chooseAAType(GrAA::kYes, GrAllowMixedSamples::kNo); + if (aaType != GrAAType::kMSAA && + (edgeAA == GrQuadAAFlags::kNone || edgeAA == GrQuadAAFlags::kAll)) { + // This is equivalent to a regular filled rect draw, so route through there to take + // advantage of draw->clear optimizations + this->drawFilledRect(clip, std::move(paint), GrAA(edgeAA == GrQuadAAFlags::kAll), + viewMatrix, rect); + return; + } + + SkRect croppedRect = rect; + if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) { + return; + } + + AutoCheckFlush acf(this->drawingManager()); + this->addDrawOp(clip, GrFillRectOp::MakePerEdge(fContext, std::move(paint), aaType, edgeAA, + viewMatrix, croppedRect)); +} + void GrRenderTargetContext::drawTexture(const GrClip& clip, sk_sp<GrTextureProxy> proxy, GrSamplerState::Filter filter, const SkPMColor4f& color, const SkRect& srcRect, const SkRect& dstRect, diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 1dfe59a478..07b52f0b12 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -127,6 +127,12 @@ public: const SkRect& rect, const SkMatrix& localMatrix); + /** + * Creates an op that draws a fill rect with per-edge control over anti-aliasing. + */ + void fillRectWithEdgeAA(const GrClip& clip, GrPaint&& paint, GrQuadAAFlags edgeAA, + const SkMatrix& viewMatrix, const SkRect& rect); + /** Used with drawQuadSet */ struct QuadSetEntry { SkRect fRect; @@ -135,6 +141,7 @@ public: GrQuadAAFlags fAAFlags; }; + // TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer void drawQuadSet(const GrClip& clip, GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, const QuadSetEntry[], int cnt); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index c2fff53fd1..d7c2d5ef71 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -402,6 +402,26 @@ void SkGpuDevice::drawRect(const SkRect& rect, const SkPaint& paint) { this->ctm(), rect, &style); } +void SkGpuDevice::drawEdgeAARect(const SkRect& r, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + ASSERT_SINGLE_OWNER + GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawEdgeAARect", fContext.get()); + + SkPMColor4f dstColor = SkColor4fPrepForDst(SkColor4f::FromColor(color), + fRenderTargetContext->colorSpaceInfo(), + *fContext->contextPriv().caps()) + .premul(); + + GrPaint grPaint; + grPaint.setColor4f(dstColor); + if (mode != SkBlendMode::kSrcOver) { + grPaint.setXPFactory(SkBlendMode_AsXPFactory(mode)); + } + + fRenderTargetContext->fillRectWithEdgeAA(this->clip(), std::move(grPaint), + SkToGrQuadAAFlags(aa), this->ctm(), r); +} + /////////////////////////////////////////////////////////////////////////////// void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) { diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h index d14572a877..fdd8cbcdd6 100644 --- a/src/gpu/SkGpuDevice.h +++ b/src/gpu/SkGpuDevice.h @@ -72,6 +72,8 @@ public: void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint& paint) override; void drawRect(const SkRect& r, const SkPaint& paint) override; + void drawEdgeAARect(const SkRect& r, SkCanvas::QuadAAFlags edgeAA, SkColor color, + SkBlendMode mode) override; void drawRRect(const SkRRect& r, const SkPaint& paint) override; void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) override; void drawRegion(const SkRegion& r, const SkPaint& paint) override; diff --git a/src/gpu/ops/GrFillRectOp.h b/src/gpu/ops/GrFillRectOp.h index 175c9f3a6c..27c6f9edd1 100644 --- a/src/gpu/ops/GrFillRectOp.h +++ b/src/gpu/ops/GrFillRectOp.h @@ -53,6 +53,7 @@ std::unique_ptr<GrDrawOp> MakePerEdgeWithLocalRect(GrContext* context, const GrUserStencilSettings* stencil = nullptr); // Bulk API for drawing quads with a single op +// TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer std::unique_ptr<GrDrawOp> MakeSet(GrContext* context, GrPaint&& paint, GrAAType aaType, diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp index 5e3745136d..1e6cd89083 100644 --- a/src/utils/SkNWayCanvas.cpp +++ b/src/utils/SkNWayCanvas.cpp @@ -162,6 +162,14 @@ void SkNWayCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { } } +void SkNWayCanvas::onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, SkColor color, + SkBlendMode mode) { + Iter iter(fList); + while (iter.next()) { + iter->experimental_DrawEdgeAARectV1(rect, aa, color, mode); + } +} + void SkNWayCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { Iter iter(fList); while (iter.next()) { diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp index 8f48b44426..ded7fc2fba 100644 --- a/src/utils/SkPaintFilterCanvas.cpp +++ b/src/utils/SkPaintFilterCanvas.cpp @@ -64,6 +64,17 @@ void SkPaintFilterCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { } } +void SkPaintFilterCanvas::onDrawEdgeAARect(const SkRect& rect, SkCanvas::QuadAAFlags aa, + SkColor color, SkBlendMode mode) { + SkPaint paint; + paint.setColor(color); + paint.setBlendMode(mode); + AutoPaintFilter apf(this, kRect_Type, paint); + if (apf.shouldDraw()) { + this->SkNWayCanvas::onDrawEdgeAARect(rect, aa, paint.getColor(), paint.getBlendMode()); + } +} + void SkPaintFilterCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { AutoPaintFilter apf(this, kRRect_Type, paint); if (apf.shouldDraw()) { |