From 168820625c35a8c19f66c661efcbce7a5e334837 Mon Sep 17 00:00:00 2001 From: msarett Date: Tue, 16 Aug 2016 09:31:08 -0700 Subject: [PATCH] Add onDrawBitmapLattice(), avoid unnecessary bitmap->image copy out/Release/nanobench --match Lattice --config gpu --ms 3000 3.42ms -> 17.2us For reference, a loop over drawBitmapRects (which is what Android currently does) is about 13us. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2205273003 Review-Url: https://codereview.chromium.org/2205273003 --- include/core/SkCanvas.h | 6 ++- include/core/SkDevice.h | 2 + src/core/SkCanvas.cpp | 98 ++++++++++++++++++++++++++++---------------- src/core/SkDevice.cpp | 34 ++++++++++----- src/core/SkLiteDL.cpp | 9 ++++ src/core/SkLiteDL.h | 2 + src/core/SkLiteRecorder.cpp | 5 +++ src/core/SkLiteRecorder.h | 2 + src/core/SkPictureRecord.cpp | 36 ++++++++-------- src/core/SkPictureRecord.h | 9 +++- src/core/SkRecorder.cpp | 23 ++++++----- src/core/SkRecorder.h | 6 ++- src/pdf/SkPDFCanvas.cpp | 12 ++++++ src/pdf/SkPDFCanvas.h | 9 +++- 14 files changed, 171 insertions(+), 82 deletions(-) diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 73fcf43..0c70f00 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1439,14 +1439,16 @@ protected: SrcRectConstraint); virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, const SkPaint*); + virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, + const SkPaint*); virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*); virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, SrcRectConstraint); virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*); - virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, - const SkPaint*); + virtual void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst, + const SkPaint*); enum ClipEdgeStyle { kHard_ClipEdgeStyle, diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 99018df..4a08b75 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -198,6 +198,8 @@ protected: SkCanvas::SrcRectConstraint) = 0; virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint&); + virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&, + const SkRect& dst, const SkPaint&); virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&); virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst, diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 80ff34d..539fd36 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2057,6 +2057,19 @@ void SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const } } +void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, + const SkPaint* paint) { + RETURN_ON_NULL(image); + if (dst.isEmpty()) { + return; + } + if (SkLatticeIter::Valid(image->width(), image->height(), lattice)) { + this->onDrawImageLattice(image, lattice, dst, paint); + } else { + this->drawImageRect(image, dst, paint); + } +} + void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { if (bitmap.drawsNothing()) { return; @@ -2093,25 +2106,17 @@ void SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, con } else { this->drawBitmapRect(bitmap, dst, paint); } - } void SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, const SkPaint* paint) { - sk_sp image = SkImage::MakeFromBitmap(bitmap); - this->drawImageLattice(image.get(), lattice, dst, paint); -} - -void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, - const SkPaint* paint) { - RETURN_ON_NULL(image); - if (dst.isEmpty()) { + if (bitmap.drawsNothing() || dst.isEmpty()) { return; } - if (SkLatticeIter::Valid(image->width(), image->height(), lattice)) { - this->onDrawImageLattice(image, lattice, dst, paint); + if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), lattice)) { + this->onDrawBitmapLattice(bitmap, lattice, dst, paint); } else { - this->drawImageRect(image, dst, paint); + this->drawBitmapRect(bitmap, dst, paint); } } @@ -2419,29 +2424,6 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S LOOPER_END } -void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, - const SkPaint* paint) { - if (nullptr == paint || paint->canComputeFastBounds()) { - SkRect storage; - if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { - return; - } - } - - SkLazyPaint lazy; - if (nullptr == paint) { - paint = lazy.init(); - } - - LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) - - while (iter.next()) { - iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint()); - } - - LOOPER_END -} - void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); @@ -2612,6 +2594,52 @@ void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c LOOPER_END } +void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, + const SkPaint* paint) { + if (nullptr == paint || paint->canComputeFastBounds()) { + SkRect storage; + if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { + return; + } + } + + SkLazyPaint lazy; + if (nullptr == paint) { + paint = lazy.init(); + } + + LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) + + while (iter.next()) { + iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint()); + } + + LOOPER_END +} + +void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, + const SkRect& dst, const SkPaint* paint) { + if (nullptr == paint || paint->canComputeFastBounds()) { + SkRect storage; + if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { + return; + } + } + + SkLazyPaint lazy; + if (nullptr == paint) { + paint = lazy.init(); + } + + LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) + + while (iter.next()) { + iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint()); + } + + LOOPER_END +} + class SkDeviceFilteredPaint { public: SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 59408dc..74e86dc 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -12,6 +12,7 @@ #include "SkImage_Base.h" #include "SkImageFilter.h" #include "SkImageFilterCache.h" +#include "SkImagePriv.h" #include "SkLatticeIter.h" #include "SkMetaData.h" #include "SkPatchUtils.h" @@ -152,17 +153,6 @@ void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar } } -void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image, - const SkCanvas::Lattice& lattice, const SkRect& dst, - const SkPaint& paint) { - SkLatticeIter iter(image->width(), image->height(), lattice, dst); - - SkRect srcR, dstR; - while (iter.next(&srcR, &dstR)) { - this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); - } -} - void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) { @@ -193,6 +183,28 @@ void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, co } } +void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image, + const SkCanvas::Lattice& lattice, const SkRect& dst, + const SkPaint& paint) { + SkLatticeIter iter(image->width(), image->height(), lattice, dst); + + SkRect srcR, dstR; + while (iter.next(&srcR, &dstR)) { + this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); + } +} + +void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap, + const SkCanvas::Lattice& lattice, const SkRect& dst, + const SkPaint& paint) { + SkLatticeIter iter(bitmap.width(), bitmap.height(), lattice, dst); + + SkRect srcR, dstR; + while (iter.next(&srcR, &dstR)) { + this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); + } +} + void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], const SkColor colors[], int count, SkXfermode::Mode mode, const SkPaint& paint) { diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp index d649889..b8938ba 100644 --- a/src/core/SkLiteDL.cpp +++ b/src/core/SkLiteDL.cpp @@ -624,6 +624,15 @@ void SkLiteDL::drawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRec const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { this->push(0, SkImage::MakeFromBitmap(bm), src, dst, paint, constraint); } +void SkLiteDL::drawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice, + const SkRect& dst, const SkPaint* paint) { + int xs = lattice.fXCount, ys = lattice.fYCount; + size_t bytes = (xs + ys) * sizeof(int); + void* pod = this->push(bytes, SkImage::MakeFromBitmap(bm), xs, ys, dst, + paint); + copy_v(pod, lattice.fXDivs, xs, + lattice.fYDivs, ys); +} void SkLiteDL::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { this->push(0, sk_ref_sp(image), x,y, paint); diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h index 27e3479..aa4dea4 100644 --- a/src/core/SkLiteDL.h +++ b/src/core/SkLiteDL.h @@ -63,6 +63,8 @@ public: void drawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*); void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, SkCanvas::SrcRectConstraint); + void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&, const SkRect&, + const SkPaint*); void drawImage (const SkImage*, SkScalar,SkScalar, const SkPaint*); void drawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*); diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp index 6a8e130..b61dd8f 100644 --- a/src/core/SkLiteRecorder.cpp +++ b/src/core/SkLiteRecorder.cpp @@ -122,6 +122,11 @@ void SkLiteRecorder::onDrawBitmapRect(const SkBitmap& bm, const SkPaint* paint, SrcRectConstraint constraint) { fDL->drawBitmapRect(bm, src, dst, paint, constraint); } +void SkLiteRecorder::onDrawBitmapLattice(const SkBitmap& bm, + const SkCanvas::Lattice& lattice, const SkRect& dst, + const SkPaint* paint) { + fDL->drawBitmapLattice(bm, lattice, dst, paint); +} void SkLiteRecorder::onDrawImage(const SkImage* img, SkScalar x, SkScalar y, diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h index 1a38c02..a924378 100644 --- a/src/core/SkLiteRecorder.h +++ b/src/core/SkLiteRecorder.h @@ -52,6 +52,8 @@ public: void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override; void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override; + void onDrawBitmapLattice(const SkBitmap&, const Lattice&, const SkRect&, + const SkPaint*) override; void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*) override; void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, SrcRectConstraint) override; diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 4b31758..520451c 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -480,24 +480,6 @@ void SkPictureRecord::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, this->validate(initialOffset, size); } -void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& lattice, - const SkRect& dst, const SkPaint* paint) { - // xCount + xDivs + yCount+ yDivs - size_t latticeSize = (1 + lattice.fXCount + 1 + lattice.fYCount) * kUInt32Size; - - // op + paint index + image index + lattice + dst rect - size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst); - size_t initialOffset = this->addDraw(DRAW_IMAGE_LATTICE, &size); - this->addPaintPtr(paint); - this->addImage(image); - this->addInt(lattice.fXCount); - fWriter.writePad(lattice.fXDivs, lattice.fXCount * kUInt32Size); - this->addInt(lattice.fYCount); - fWriter.writePad(lattice.fYDivs, lattice.fYCount * kUInt32Size); - this->addRect(dst); - this->validate(initialOffset, size); -} - void SkPictureRecord::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { // id + paint_index + image_index + bool_for_src + constraint @@ -529,6 +511,24 @@ void SkPictureRecord::onDrawImageNine(const SkImage* img, const SkIRect& center, this->validate(initialOffset, size); } +void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& lattice, + const SkRect& dst, const SkPaint* paint) { + // xCount + xDivs + yCount+ yDivs + size_t latticeSize = (1 + lattice.fXCount + 1 + lattice.fYCount) * kUInt32Size; + + // op + paint index + image index + lattice + dst rect + size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst); + size_t initialOffset = this->addDraw(DRAW_IMAGE_LATTICE, &size); + this->addPaintPtr(paint); + this->addImage(image); + this->addInt(lattice.fXCount); + fWriter.writePad(lattice.fXDivs, lattice.fXCount * kUInt32Size); + this->addInt(lattice.fYCount); + fWriter.writePad(lattice.fYDivs, lattice.fYCount * kUInt32Size); + this->addRect(dst); + this->validate(initialOffset, size); +} + void SkPictureRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { // op + paint index + length + 'length' worth of chars + x + y diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index f071db1..ecdb368 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -190,12 +190,13 @@ protected: void onDrawRRect(const SkRRect&, const SkPaint&) override; void onDrawPath(const SkPath&, const SkPaint&) override; void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; - void onDrawImageLattice(const SkImage*, const SkCanvas::Lattice& lattice, const SkRect& dst, - const SkPaint*) override; void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, const SkPaint*, SrcRectConstraint) override; void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, const SkPaint*) override; + void onDrawImageLattice(const SkImage*, const SkCanvas::Lattice& lattice, const SkRect& dst, + const SkPaint*) override; + void onDrawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, @@ -250,6 +251,10 @@ protected: const SkPaint*) override { sk_throw(); } + void onDrawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice& lattice, const SkRect& dst, + const SkPaint*) override { + sk_throw(); + } private: SkPictureContentInfo fContentInfo; diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 7ffb1f4..b961c7d 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -206,21 +206,17 @@ void SkRecorder::onDrawBitmapNine(const SkBitmap& bitmap, } } +void SkRecorder::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, + const SkRect& dst, const SkPaint* paint) { + sk_sp image = SkImage::MakeFromBitmap(bitmap); + this->onDrawImageLattice(image.get(), lattice, dst, paint); +} + void SkRecorder::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint) { APPEND(DrawImage, this->copy(paint), sk_ref_sp(image), left, top); } -void SkRecorder::onDrawImageLattice(const SkImage* image, - const Lattice& lattice, - const SkRect& dst, - const SkPaint* paint) { - APPEND(DrawImageLattice, this->copy(paint), sk_ref_sp(image), - lattice.fXCount, this->copy(lattice.fXDivs, lattice.fXCount), - lattice.fYCount, this->copy(lattice.fYDivs, lattice.fYCount), dst); -} - - void SkRecorder::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { APPEND(DrawImageRect, this->copy(paint), sk_ref_sp(image), this->copy(src), dst, constraint); @@ -231,6 +227,13 @@ void SkRecorder::onDrawImageNine(const SkImage* image, const SkIRect& center, APPEND(DrawImageNine, this->copy(paint), sk_ref_sp(image), center, dst); } +void SkRecorder::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, + const SkPaint* paint) { + APPEND(DrawImageLattice, this->copy(paint), sk_ref_sp(image), + lattice.fXCount, this->copy(lattice.fXDivs, lattice.fXCount), + lattice.fYCount, this->copy(lattice.fYDivs, lattice.fYCount), dst); +} + void SkRecorder::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { APPEND(DrawText, diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 6da3824..ba171a1 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -111,14 +111,16 @@ public: void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, SrcRectConstraint) override; void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; - void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, - const SkPaint*) override; void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, const SkPaint*, SrcRectConstraint) override; void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, const SkPaint*) override; void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, const SkPaint*) override; + void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, + const SkPaint*) override; + void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst, + const SkPaint*) override; void onDrawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, diff --git a/src/pdf/SkPDFCanvas.cpp b/src/pdf/SkPDFCanvas.cpp index 1d31385..4ef1922 100644 --- a/src/pdf/SkPDFCanvas.cpp +++ b/src/pdf/SkPDFCanvas.cpp @@ -95,3 +95,15 @@ void SkPDFCanvas::onDrawImageLattice(const SkImage* image, this->drawImageRect(image, srcR, dstR, paint); } } + +void SkPDFCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, + const Lattice& lattice, + const SkRect& dst, + const SkPaint* paint) { + SkLatticeIter iter(bitmap.width(), bitmap.height(), lattice, dst); + SkRect srcR, dstR; + while (iter.next(&srcR, &dstR)) { + this->drawBitmapRect(bitmap, srcR, dstR, paint); + } +} + diff --git a/src/pdf/SkPDFCanvas.h b/src/pdf/SkPDFCanvas.h index 76bb7e1..5040e98 100644 --- a/src/pdf/SkPDFCanvas.h +++ b/src/pdf/SkPDFCanvas.h @@ -40,10 +40,15 @@ protected: SkCanvas::SrcRectConstraint) override; void onDrawImageLattice(const SkImage*, - const Lattice& lattice, - const SkRect& dst, + const Lattice&, + const SkRect&, const SkPaint*) override; + void onDrawBitmapLattice(const SkBitmap&, + const Lattice&, + const SkRect&, + const SkPaint*) override; + private: typedef SkCanvas INHERITED; }; -- 2.7.4