Reland "Reland "Update SkCanvas' experimental SkiaRenderer API""
This reverts commit 138a06d1b1cd035daf6b6a970c75126e94777822.
Reason for revert: add explicit constructors to ImageSetEntry to account for the new arguments,
matching SkiaRenderer's current initializer list. Also hardens SkPictureDrawback's deserialization
code for drawEdgeAAImageSet and drawEdgeAAQuad from a fuzz that was found during the CL's brief
lifespan.
Original change's description:
> Revert "Reland "Update SkCanvas' experimental SkiaRenderer API""
>
> This reverts commit bd9d88a6e4d9730f3aa67227e5a1618180513a87.
>
> Reason for revert: Breaks SkiaRenderer on Android. Rendering is all corrupted, bisected to this change.
>
> Original change's description:
> > Reland "Update SkCanvas' experimental SkiaRenderer API"
> >
> > This reverts commit 90791c202dd2d943565237bf511d929e8bd19951.
> >
> > Reason for revert: Jumped the gun, just need to update blacklist
> >
> > Original change's description:
> > > Revert "Update SkCanvas' experimental SkiaRenderer API"
> > >
> > > This reverts commit 4bf964602ab8758f6e580aaaa69add4fb260c1a6.
> > >
> > > Reason for revert: vulkan dm crashes
> > >
> > > Original change's description:
> > > > Update SkCanvas' experimental SkiaRenderer API
> > > >
> > > > This lifts the temporary functions in SkGpuDevice into SkCanvas and
> > > > deprecates the older experimental_DrawImageSetV1 and
> > > > experimental_DrawEdgeAARect. The new functions can handle paints and
> > > > transform batching. Internally, SkCanvas routes the old functions to the
> > > > new entry points and all device-level code is updated to handle the new
> > > > API features.
> > > >
> > > > While touching all of the canvas/device/recording areas, the
> > > > experimental functions are grouped in an "EdgeAA" cluster instead of being
> > > > separated into the image category and the rectangle category.
> > > >
> > > > Bug: skia:8739
> > > > Change-Id: I67c2a724873040ad5dc3307ab5b2823ba1eac54b
> > > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/190221
> > > > Commit-Queue: Michael Ludwig <michaelludwig@google.com>
> > > > Reviewed-by: Brian Salomon <bsalomon@google.com>
> > >
> > > TBR=bsalomon@google.com,robertphillips@google.com,michaelludwig@google.com
> > >
> > > Change-Id: I87a5a258c5a1bd15e16389cdf91743772d6fa98a
> > > No-Presubmit: true
> > > No-Tree-Checks: true
> > > No-Try: true
> > > Bug: skia:8739
> > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201226
> > > Reviewed-by: Michael Ludwig <michaelludwig@google.com>
> > > Commit-Queue: Michael Ludwig <michaelludwig@google.com>
> >
> > TBR=bsalomon@google.com,robertphillips@google.com,michaelludwig@google.com
> >
> > Change-Id: I75e9b6cbf079a7739b69a7e208730a930621abf9
> > No-Presubmit: true
> > No-Tree-Checks: true
> > No-Try: true
> > Bug: skia:8739
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201229
> > Reviewed-by: Michael Ludwig <michaelludwig@google.com>
> > Commit-Queue: Michael Ludwig <michaelludwig@google.com>
> > Auto-Submit: Michael Ludwig <michaelludwig@google.com>
>
> TBR=bsalomon@google.com,robertphillips@google.com,michaelludwig@google.com
>
> Change-Id: Ib87ef9b8b8598c16a8a6915920adf0b5dffc644b
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:8739
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201391
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
Bug: skia:8739, oss-fuzz:13794
Change-Id: Ibd7df4a398928c3170d16300bf3ade496125372c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201650
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 9e0b426..d84e91d 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1876,23 +1876,6 @@
}
}
-void SkCanvas::experimental_DrawImageSetV1(const ImageSetEntry imageSet[], int cnt,
- SkFilterQuality filterQuality, SkBlendMode mode) {
- TRACE_EVENT0("skia", TRACE_FUNC);
- RETURN_ON_NULL(imageSet);
- RETURN_ON_FALSE(cnt);
-
- 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()) {
@@ -2012,6 +1995,56 @@
LOOPER_END
}
+void SkCanvas::experimental_DrawImageSetV1(const ImageSetEntry imageSet[], int cnt,
+ SkFilterQuality filterQuality, SkBlendMode mode) {
+ TRACE_EVENT0("skia", TRACE_FUNC);
+ RETURN_ON_NULL(imageSet);
+ RETURN_ON_FALSE(cnt);
+
+ // DrawImageSetV1 is the same as DrawEdgeAAImageSet by making a paint from its filterQuality and
+ // blend mode, and not providing any clip region. To safely handle that, we make a copy of the
+ // entry set and set fHasClip to false and fMatrixIndex to -1 on each entry. Since this
+ // function will be going away, that performance hit is acceptable.
+ SkTArray<ImageSetEntry> safeImages(cnt);
+ for (int i = 0; i < cnt; ++i) {
+ ImageSetEntry& e = safeImages.push_back();
+ e = imageSet[i];
+ e.fHasClip = false;
+ e.fMatrixIndex = -1;
+ }
+
+ SkPaint paint;
+ paint.setFilterQuality(filterQuality);
+ paint.setBlendMode(mode);
+ this->onDrawEdgeAAImageSet(safeImages.begin(), cnt, nullptr, nullptr, &paint,
+ kFast_SrcRectConstraint);
+}
+
+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.
+ // DrawEdgeAARectV1 is the same as DrawEdgeAAQuad when no clip region is specified
+ this->onDrawEdgeAAQuad(r.makeSorted(), nullptr, edgeAA, color, mode);
+}
+
+void SkCanvas::experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
+ QuadAAFlags aaFlags, SkColor color, SkBlendMode mode) {
+ TRACE_EVENT0("skia", TRACE_FUNC);
+ // Make sure the rect is sorted before passing it along
+ this->onDrawEdgeAAQuad(rect.makeSorted(), clip, aaFlags, color, mode);
+}
+
+void SkCanvas::experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
+ const SkPoint dstClips[],
+ const SkMatrix preViewMatrices[],
+ const SkPaint* paint,
+ SrcRectConstraint constraint) {
+ TRACE_EVENT0("skia", TRACE_FUNC);
+ this->onDrawEdgeAAImageSet(imageSet, cnt, dstClips, preViewMatrices, paint, constraint);
+}
+
//////////////////////////////////////////////////////////////////////////////
// These are the virtual drawing methods
//////////////////////////////////////////////////////////////////////////////
@@ -2103,20 +2136,6 @@
}
}
-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()) {
@@ -2512,16 +2531,6 @@
LOOPER_END
}
-void SkCanvas::onDrawImageSet(const ImageSetEntry imageSet[], int count,
- SkFilterQuality filterQuality, SkBlendMode mode) {
- SkPaint paint;
- LOOPER_BEGIN(paint, nullptr)
- while (iter.next()) {
- iter.fDevice->drawImageSet(imageSet, count, filterQuality, mode);
- }
- LOOPER_END
-}
-
void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
const SkRect& dst, const SkPaint* paint) {
SkPaint realPaint;
@@ -2689,6 +2698,39 @@
LOOPER_END
}
+void SkCanvas::onDrawEdgeAAQuad(const SkRect& r, const SkPoint clip[4], QuadAAFlags edgeAA,
+ SkColor color, SkBlendMode mode) {
+ SkASSERT(r.isSorted());
+
+ // If this used a paint, it would be a filled color with blend mode, which does not
+ // need to use an autodraw loop, so use SkDrawIter directly.
+ if (this->quickReject(r)) {
+ return;
+ }
+
+ this->predrawNotify();
+ SkDrawIter iter(this);
+ while(iter.next()) {
+ iter.fDevice->drawEdgeAAQuad(r, clip, edgeAA, color, mode);
+ }
+}
+
+void SkCanvas::onDrawEdgeAAImageSet(const ImageSetEntry imageSet[], int count,
+ const SkPoint dstClips[], const SkMatrix preViewMatrices[],
+ const SkPaint* paint, SrcRectConstraint constraint) {
+ SkPaint realPaint;
+ init_image_paint(&realPaint, paint);
+
+ // Looper is used when there are image filters, which drawEdgeAAImageSet needs to support
+ // for Chromium's RenderPassDrawQuads' filters.
+ LOOPER_BEGIN(realPaint, nullptr)
+ while (iter.next()) {
+ iter.fDevice->drawEdgeAAImageSet(
+ imageSet, count, dstClips, preViewMatrices, looper.paint(), constraint);
+ }
+ LOOPER_END
+}
+
//////////////////////////////////////////////////////////////////////////////
// These methods are NOT virtual, and therefore must call back into virtual
// methods, rather than actually drawing themselves.
@@ -2841,6 +2883,27 @@
///////////////////////////////////////////////////////////////////////////////
+SkCanvas::ImageSetEntry::ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect,
+ const SkRect& dstRect, int matrixIndex, float alpha,
+ unsigned aaFlags, bool hasClip)
+ : fImage(std::move(image))
+ , fSrcRect(srcRect)
+ , fDstRect(dstRect)
+ , fMatrixIndex(matrixIndex)
+ , fAlpha(alpha)
+ , fAAFlags(aaFlags)
+ , fHasClip(hasClip) {}
+
+SkCanvas::ImageSetEntry::ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect,
+ const SkRect& dstRect, float alpha, unsigned aaFlags)
+ : fImage(std::move(image))
+ , fSrcRect(srcRect)
+ , fDstRect(dstRect)
+ , fAlpha(alpha)
+ , fAAFlags(aaFlags) {}
+
+///////////////////////////////////////////////////////////////////////////////
+
std::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels,
size_t rowBytes, const SkSurfaceProps* props) {
if (!SkSurfaceValidateRasterInfo(info, rowBytes)) {