diff options
author | Stan Iliev <stani@google.com> | 2017-12-11 13:01:58 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-11 18:26:18 +0000 |
commit | ca8c0953e8da1def5e6c12dde6d4368b4bf16077 (patch) | |
tree | c7c0dabde70dbebfedba579f6f9d803652201943 | |
parent | 51493ee8488e29499a1a0a678a50aeca44ebf718 (diff) |
Implement a fast path for solid color lattice rectangle
Add a flag that hints, which lattice rectangles are solid colors.
Draw solid rectangles and 1x1 rectangles with drawRect.
Test: Measured performance of a ninepatch drawn by HWUI
Bug: b/69796044
Change-Id: Ib3b00ca608da42fa9f2d2038cc126a978421ec7c
Reviewed-on: https://skia-review.googlesource.com/79821
Commit-Queue: Stan Iliev <stani@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
-rw-r--r-- | bench/DrawLatticeBench.cpp | 3 | ||||
-rw-r--r-- | fuzz/FuzzCanvas.cpp | 4 | ||||
-rw-r--r-- | gm/lattice.cpp | 180 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 28 | ||||
-rw-r--r-- | src/core/SkDevice.cpp | 20 | ||||
-rw-r--r-- | src/core/SkLatticeIter.cpp | 32 | ||||
-rw-r--r-- | src/core/SkLatticeIter.h | 10 | ||||
-rw-r--r-- | src/core/SkLiteDL.cpp | 16 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 7 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 10 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 3 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 5 | ||||
-rw-r--r-- | src/core/SkRecords.h | 3 | ||||
-rw-r--r-- | src/gpu/ops/GrLatticeOp.cpp | 16 | ||||
-rw-r--r-- | src/pipe/SkPipeCanvas.cpp | 7 | ||||
-rw-r--r-- | src/pipe/SkPipeReader.cpp | 6 | ||||
-rw-r--r-- | tools/debugger/SkDrawCommand.cpp | 4 |
17 files changed, 296 insertions, 58 deletions
diff --git a/bench/DrawLatticeBench.cpp b/bench/DrawLatticeBench.cpp index 7a8cdf3b3a..fbab2f7adb 100644 --- a/bench/DrawLatticeBench.cpp +++ b/bench/DrawLatticeBench.cpp @@ -22,8 +22,9 @@ public: fLattice.fXCount = xCount; fLattice.fYDivs = yDivs; fLattice.fYCount = yCount; - fLattice.fFlags = nullptr; + fLattice.fRectTypes = nullptr; fLattice.fBounds = nullptr; + fLattice.fColors = nullptr; fName = SkStringPrintf("DrawLattice_%s", desc); } diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp index 618f7ac934..74b246757d 100644 --- a/fuzz/FuzzCanvas.cpp +++ b/fuzz/FuzzCanvas.cpp @@ -1548,7 +1548,7 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) { } constexpr int kMax = 6; int xDivs[kMax], yDivs[kMax]; - SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr}; + SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr, nullptr}; fuzz->nextRange(&lattice.fXCount, 2, kMax); fuzz->nextRange(&lattice.fYCount, 2, kMax); fuzz->nextN(xDivs, lattice.fXCount); @@ -1566,7 +1566,7 @@ static void fuzz_canvas(Fuzz* fuzz, SkCanvas* canvas, int depth = 9) { } constexpr int kMax = 6; int xDivs[kMax], yDivs[kMax]; - SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr}; + SkCanvas::Lattice lattice{xDivs, yDivs, nullptr, 0, 0, nullptr, nullptr}; fuzz->nextRange(&lattice.fXCount, 2, kMax); fuzz->nextRange(&lattice.fYCount, 2, kMax); fuzz->nextN(xDivs, lattice.fXCount); diff --git a/gm/lattice.cpp b/gm/lattice.cpp index 55759d0cd8..d5e2b45c6e 100644 --- a/gm/lattice.cpp +++ b/gm/lattice.cpp @@ -124,7 +124,8 @@ protected: lattice.fXDivs = xDivs + 1; lattice.fYCount = 4; lattice.fYDivs = yDivs + 1; - lattice.fFlags = nullptr; + lattice.fRectTypes = nullptr; + lattice.fColors = nullptr; SkIRect bounds = SkIRect::MakeLTRB(padLeft, padTop, image->width() - padRight, image->height() - padBottom); @@ -140,6 +141,19 @@ protected: } } + // Provide hints about 3 solid color rects. These colors match + // what was already in the bitmap. + int fixedColorX[3] = {2, 4, 1}; + int fixedColorY[3] = {1, 1, 2}; + SkColor fixedColor[3] = {SK_ColorBLACK, SK_ColorBLACK, SK_ColorBLACK}; + const SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, + kUnpremul_SkAlphaType); + for (int rectNum = 0; rectNum < 3; rectNum++) { + int srcX = xDivs[fixedColorX[rectNum]-1]; + int srcY = yDivs[fixedColorY[rectNum]-1]; + image->readPixels(info, &fixedColor[rectNum], 4, srcX, srcY); + } + // Include the degenerate first div. While normally the first patch is "scalable", // this will mean that the first non-degenerate patch is "fixed". lattice.fXCount = 5; @@ -148,13 +162,26 @@ protected: lattice.fYDivs = yDivs; // Let's skip a few rects. - SkCanvas::Lattice::Flags flags[36]; - sk_bzero(flags, 36 * sizeof(SkCanvas::Lattice::Flags)); - flags[4] = SkCanvas::Lattice::kTransparent_Flags; - flags[9] = SkCanvas::Lattice::kTransparent_Flags; - flags[12] = SkCanvas::Lattice::kTransparent_Flags; - flags[19] = SkCanvas::Lattice::kTransparent_Flags; - lattice.fFlags = flags; + SkCanvas::Lattice::RectType flags[36]; + sk_bzero(flags, 36 * sizeof(SkCanvas::Lattice::RectType)); + flags[4] = SkCanvas::Lattice::kTransparent; + flags[9] = SkCanvas::Lattice::kTransparent; + flags[12] = SkCanvas::Lattice::kTransparent; + flags[19] = SkCanvas::Lattice::kTransparent; + for (int rectNum = 0; rectNum < 3; rectNum++) { + flags[fixedColorY[rectNum]*6 + fixedColorX[rectNum]] + = SkCanvas::Lattice::kFixedColor; + } + lattice.fRectTypes = flags; + + SkColor colors[36]; + sk_bzero(colors, 36 * sizeof(SkColor)); + for (int rectNum = 0; rectNum < 3; rectNum++) { + colors[fixedColorY[rectNum]*6 + fixedColorX[rectNum]] + = fixedColor[rectNum]; + } + + lattice.fColors = colors; canvas->translate(400, 0); for (int iy = 0; iy < 2; ++iy) { @@ -179,3 +206,140 @@ private: typedef skiagm::GM INHERITED; }; DEF_GM( return new LatticeGM; ) + + +// LatticeGM2 exercises code paths that draw fixed color and 1x1 rectangles. +class LatticeGM2 : public skiagm::GM { +public: + LatticeGM2() {} + SkString onShortName() override { + return SkString("lattice2"); + } + + SkISize onISize() override { + return SkISize::Make(800, 800); + } + + sk_sp<SkImage> makeImage(SkCanvas* root, int padLeft, int padTop, int padRight, int padBottom) { + const int kSize = 80; + auto surface(make_surface(root, kSize, padLeft, padTop, padRight, padBottom)); + SkCanvas* canvas = surface->getCanvas();; + SkPaint paint; + paint.setAntiAlias(false); + SkRect r; + + //first line + r.setXYWH(0, 0, 4, 1); //4x1 green rect + paint.setColor(0xFF00FF00); + canvas->drawRect(r, paint); + + r.setXYWH(4, 0, 1, 1); //1x1 blue pixel -> draws as rectangle + paint.setColor(0xFF0000FF); + canvas->drawRect(r, paint); + + r.setXYWH(5, 0, kSize-5, 1); //the rest of the line is red + paint.setColor(0xFFFF0000); + canvas->drawRect(r, paint); + + + //second line -> draws as fixed color rectangles + r.setXYWH(0, 1, 4, 1); //4x1 red rect + paint.setColor(0xFFFF0000); + canvas->drawRect(r, paint); + + r.setXYWH(4, 1, 1, 1); //1x1 blue pixel with alpha + paint.setColor(0x880000FF); + canvas->drawRect(r, paint); + + r.setXYWH(5, 1, kSize-5, 1); //the rest of the line is green + paint.setColor(0xFF00FF00); + canvas->drawRect(r, paint); + + + //third line - does not draw, because it is transparent + r.setXYWH(0, 2, 4, kSize-2); //4x78 green rect + paint.setColor(0xFF00FF00); + canvas->drawRect(r, paint); + + r.setXYWH(4, 2, 1, kSize-2); //1x78 red pixel with alpha + paint.setColor(0x88FF0000); + canvas->drawRect(r, paint); + + r.setXYWH(5, 2, kSize-5, kSize-2); //the rest of the image is blue + paint.setColor(0xFF0000FF); + canvas->drawRect(r, paint); + + return surface->makeImageSnapshot(); + } + + void onDrawHelper(SkCanvas* canvas, int padLeft, int padTop, int padRight, int padBottom, + SkPaint& paint) { + int xDivs[2] = {4, 5}; + int yDivs[2] = {1, 2}; + + canvas->save(); + + sk_sp<SkImage> image = makeImage(canvas, padLeft, padTop, padRight, padBottom); + + canvas->drawImage(image, 10, 10, nullptr); + + SkCanvas::Lattice lattice; + lattice.fXCount = 2; + lattice.fXDivs = xDivs; + lattice.fYCount = 2; + lattice.fYDivs = yDivs; + lattice.fBounds = nullptr; + + SkCanvas::Lattice::RectType flags[9]; + sk_bzero(flags, 9 * sizeof(SkCanvas::Lattice::RectType)); + flags[3] = SkCanvas::Lattice::kFixedColor; + flags[4] = SkCanvas::Lattice::kFixedColor; + flags[5] = SkCanvas::Lattice::kFixedColor; + + flags[6] = SkCanvas::Lattice::kTransparent; + flags[7] = SkCanvas::Lattice::kTransparent; + flags[8] = SkCanvas::Lattice::kTransparent; + lattice.fRectTypes = flags; + + SkColor colors[9] = {SK_ColorBLACK, SK_ColorBLACK, SK_ColorBLACK, + 0xFFFF0000, 0x880000FF, 0xFF00FF00, + SK_ColorBLACK, SK_ColorBLACK, SK_ColorBLACK}; + lattice.fColors = colors; + paint.setColor(0xFFFFFFFF); + canvas->drawImageLattice(image.get(), lattice, + SkRect::MakeXYWH(100, 100, 200, 200), &paint); + + //draw the same content with alpha + canvas->translate(400, 0); + paint.setColor(0x80000FFF); + canvas->drawImageLattice(image.get(), lattice, + SkRect::MakeXYWH(100, 100, 200, 200), &paint); + + canvas->restore(); + } + + void onDraw(SkCanvas* canvas) override { + + //draw a rectangle in the background with transparent pixels + SkPaint paint; + paint.setColor(0x7F123456); + paint.setBlendMode(SkBlendMode::kSrc); + canvas->drawRect( SkRect::MakeXYWH(300, 0, 300, 800), paint); + + //draw image lattice with kSrcOver blending + paint.setBlendMode(SkBlendMode::kSrcOver); + this->onDrawHelper(canvas, 0, 0, 0, 0, paint); + + //draw image lattice with kSrcATop blending + canvas->translate(0.0f, 400.0f); + paint.setBlendMode(SkBlendMode::kSrcATop); + this->onDrawHelper(canvas, 0, 0, 0, 0, paint); + } + +private: + typedef skiagm::GM INHERITED; +}; +DEF_GM( return new LatticeGM2; ) + + + diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 15ee8721cd..f5f32f8267 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1760,12 +1760,19 @@ public: */ struct Lattice { - /** \enum SkCanvas::Lattice::Flags - Optional setting per rectangular grid entry to make it transparent. + /** \enum SkCanvas::Lattice::RectType + Optional setting per rectangular grid entry. */ - enum Flags : uint8_t { + enum RectType : uint8_t { + kDefault = 0, + /** Set to skip lattice rectangle by making it transparent. */ - kTransparent_Flags = 1 << 0, + kTransparent, + + /** The lattice rectangle is a fixed color. The color value is stored + in fColors. + */ + kFixedColor, }; /** Array of x-coordinates that divide the bitmap vertically. @@ -1784,13 +1791,13 @@ public: */ const int* fYDivs; - /** Optional array of flags, one per rectangular grid entry: + /** Optional array of rectangle types, one per rectangular grid entry: array length must be (fXCount + 1) * (fYCount + 1). Array entries correspond to the rectangular grid entries, ascending left to right and then top to bottom. */ - const Flags* fFlags; + const RectType* fRectTypes; /** Number of entries in fXDivs array; one less than the number of horizontal divisions. @@ -1807,6 +1814,15 @@ public: */ const SkIRect* fBounds; + + /** Optional array of colors, one per rectangular grid entry: + array length must be (fXCount + 1) * (fYCount + 1). + + Array entries correspond to the rectangular grid entries, ascending + left to right and then top to bottom. + */ + const SkColor* fColors; + }; /** Draw SkBitmap bitmap stretched proportionally to fit into SkRect dst. diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 5d5c9dae73..85136722b5 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -223,8 +223,24 @@ void SkBaseDevice::drawImageLattice(const SkImage* image, SkLatticeIter iter(lattice, dst); SkRect srcR, dstR; - while (iter.next(&srcR, &dstR)) { - this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); + SkColor c; + bool isFixedColor = false; + const SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); + + while (iter.next(&srcR, &dstR, &isFixedColor, &c)) { + if (isFixedColor || (srcR.width() <= 1.0f && srcR.height() <= 1.0f && + image->readPixels(info, &c, 4, srcR.fLeft, srcR.fTop))) { + // Fast draw with drawRect, if this is a patch containing a single color + // or if this is a patch containing a single pixel. + if (0 != c || !paint.isSrcOver()) { + SkPaint paintCopy(paint); + int alpha = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha())); + paintCopy.setColor(SkColorSetA(c, alpha)); + this->drawRect(dstR, paintCopy); + } + } else { + this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); + } } } diff --git a/src/core/SkLatticeIter.cpp b/src/core/SkLatticeIter.cpp index 9b2a279f2e..551982ec20 100644 --- a/src/core/SkLatticeIter.cpp +++ b/src/core/SkLatticeIter.cpp @@ -166,16 +166,19 @@ SkLatticeIter::SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst fNumRectsInLattice = (xCount + 1) * (yCount + 1); fNumRectsToDraw = fNumRectsInLattice; - if (lattice.fFlags) { - fFlags.push_back_n(fNumRectsInLattice); + if (lattice.fRectTypes) { + fRectTypes.push_back_n(fNumRectsInLattice); + fColors.push_back_n(fNumRectsInLattice); - const SkCanvas::Lattice::Flags* flags = lattice.fFlags; + const SkCanvas::Lattice::RectType* flags = lattice.fRectTypes; + const SkColor* colors = lattice.fColors; bool hasPadRow = (yCount != origYCount); bool hasPadCol = (xCount != origXCount); if (hasPadRow) { // The first row of rects are all empty, skip the first row of flags. flags += origXCount + 1; + colors += origXCount + 1; } int i = 0; @@ -184,17 +187,20 @@ SkLatticeIter::SkLatticeIter(const SkCanvas::Lattice& lattice, const SkRect& dst if (0 == x && hasPadCol) { // The first column of rects are all empty. Skip a rect. flags++; + colors++; continue; } - fFlags[i] = *flags; + fRectTypes[i] = *flags; + fColors[i] = *colors; flags++; + colors++; i++; } } - for (int j = 0; j < fFlags.count(); j++) { - if (SkCanvas::Lattice::kTransparent_Flags == fFlags[j]) { + for (int j = 0; j < fRectTypes.count(); j++) { + if (SkCanvas::Lattice::kTransparent == fRectTypes[j]) { fNumRectsToDraw--; } } @@ -248,7 +254,7 @@ SkLatticeIter::SkLatticeIter(int w, int h, const SkIRect& c, const SkRect& dst) fNumRectsToDraw = 9; } -bool SkLatticeIter::next(SkRect* src, SkRect* dst) { +bool SkLatticeIter::next(SkRect* src, SkRect* dst, bool* isFixedColor, SkColor* fixedColor) { int currRect = fCurrX + fCurrY * (fSrcX.count() - 1); if (currRect == fNumRectsInLattice) { return false; @@ -264,12 +270,20 @@ bool SkLatticeIter::next(SkRect* src, SkRect* dst) { fCurrY += 1; } - if (fFlags.count() > 0 && SkToBool(SkCanvas::Lattice::kTransparent_Flags & fFlags[currRect])) { - return this->next(src, dst); + if (fRectTypes.count() > 0 + && SkToBool(SkCanvas::Lattice::kTransparent == fRectTypes[currRect])) { + return this->next(src, dst, isFixedColor, fixedColor); } src->set(fSrcX[x], fSrcY[y], fSrcX[x + 1], fSrcY[y + 1]); dst->set(fDstX[x], fDstY[y], fDstX[x + 1], fDstY[y + 1]); + if (isFixedColor && fixedColor) { + *isFixedColor = fRectTypes.count() > 0 + && SkToBool(SkCanvas::Lattice::kFixedColor == fRectTypes[currRect]); + if (*isFixedColor) { + *fixedColor = fColors[currRect]; + } + } return true; } diff --git a/src/core/SkLatticeIter.h b/src/core/SkLatticeIter.h index aad39824d5..08cdd5a965 100644 --- a/src/core/SkLatticeIter.h +++ b/src/core/SkLatticeIter.h @@ -30,9 +30,12 @@ public: SkLatticeIter(int imageWidth, int imageHeight, const SkIRect& center, const SkRect& dst); /** - * While it returns true, use src/dst to draw the image/bitmap + * While it returns true, use src/dst to draw the image/bitmap. Optional parameters + * isFixedColor and fixedColor specify if the rectangle is filled with a fixed color. + * If (*isFixedColor) is true, then (*fixedColor) contains the rectangle color. */ - bool next(SkRect* src, SkRect* dst); + bool next(SkRect* src, SkRect* dst, bool* isFixedColor = nullptr, + SkColor* fixedColor = nullptr); /** * Apply a matrix to the dst points. @@ -51,7 +54,8 @@ private: SkTArray<SkScalar> fSrcY; SkTArray<SkScalar> fDstX; SkTArray<SkScalar> fDstY; - SkTArray<SkCanvas::Lattice::Flags> fFlags; + SkTArray<SkCanvas::Lattice::RectType> fRectTypes; + SkTArray<SkColor> fColors; int fCurrX; int fCurrY; diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp index ab5cce3e94..ed23acffe0 100644 --- a/src/core/SkLiteDL.cpp +++ b/src/core/SkLiteDL.cpp @@ -330,9 +330,13 @@ namespace { void draw(SkCanvas* c, const SkMatrix&) const { auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs*sizeof(int)); + auto colors = (0 == fs) ? nullptr : + pod<SkColor>(this, (xs+ys)*sizeof(int)); auto flags = (0 == fs) ? nullptr : - pod<SkCanvas::Lattice::Flags>(this, (xs+ys)*sizeof(int)); - c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src}, dst, &paint); + pod<SkCanvas::Lattice::RectType>(this, (xs+ys)*sizeof(int)+ + fs*sizeof(SkColor)); + c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst, + &paint); } }; @@ -619,14 +623,16 @@ void SkLiteDL::drawImageRect(sk_sp<const SkImage> image, const SkRect* src, cons void SkLiteDL::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint) { int xs = lattice.fXCount, ys = lattice.fYCount; - int fs = lattice.fFlags ? (xs + 1) * (ys + 1) : 0; - size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::Flags); + int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0; + size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) + + fs * sizeof(SkColor); SkASSERT(lattice.fBounds); void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds, dst, paint); copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, - lattice.fFlags, fs); + lattice.fColors, fs, + lattice.fRectTypes, fs); } void SkLiteDL::drawText(const void* text, size_t bytes, diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index f9f390ef5a..071e6b3650 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -351,8 +351,11 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader, lattice.fYCount = reader->readInt(); lattice.fYDivs = (const int*) reader->skip(lattice.fYCount * sizeof(int32_t)); int flagCount = reader->readInt(); - lattice.fFlags = (0 == flagCount) ? nullptr : (const SkCanvas::Lattice::Flags*) - reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags))); + lattice.fRectTypes = (0 == flagCount) ? nullptr : + (const SkCanvas::Lattice::RectType*) + reader->skip(SkAlign4(flagCount * sizeof(SkCanvas::Lattice::RectType))); + lattice.fColors = (0 == flagCount) ? nullptr : (const SkColor*) + reader->skip(SkAlign4(flagCount * sizeof(SkColor))); SkIRect src; reader->readIRect(&src); lattice.fBounds = &src; diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 3700e3b330..8a7b5cfa50 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -550,9 +550,12 @@ void SkPictureRecord::onDrawImageNine(const SkImage* img, const SkIRect& center, void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, const SkPaint* paint) { // xCount + xDivs + yCount+ yDivs - int flagCount = (nullptr == lattice.fFlags) ? 0 : (lattice.fXCount + 1) * (lattice.fYCount + 1); + int flagCount = (nullptr == lattice.fRectTypes) ? 0 : + (lattice.fXCount + 1) * (lattice.fYCount + 1); size_t latticeSize = (1 + lattice.fXCount + 1 + lattice.fYCount + 1) * kUInt32Size + - SkAlign4(flagCount * sizeof(SkCanvas::Lattice::Flags)) + sizeof(SkIRect); + SkAlign4(flagCount * sizeof(SkCanvas::Lattice::RectType)) + + SkAlign4(flagCount * sizeof(SkColor)) + + sizeof(SkIRect); // op + paint index + image index + lattice + dst rect size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst); @@ -564,7 +567,8 @@ void SkPictureRecord::onDrawImageLattice(const SkImage* image, const Lattice& la this->addInt(lattice.fYCount); fWriter.writePad(lattice.fYDivs, lattice.fYCount * kUInt32Size); this->addInt(flagCount); - fWriter.writePad(lattice.fFlags, flagCount * sizeof(SkCanvas::Lattice::Flags)); + fWriter.writePad(lattice.fRectTypes, flagCount * sizeof(SkCanvas::Lattice::RectType)); + fWriter.writePad(lattice.fColors, flagCount * sizeof(SkColor)); SkASSERT(lattice.fBounds); this->addIRect(*lattice.fBounds); this->addRect(dst); diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 56bde16726..89eb8a751a 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -101,7 +101,8 @@ template <> void Draw::draw(const DrawImageLattice& r) { lattice.fXDivs = r.xDivs; lattice.fYCount = r.yCount; lattice.fYDivs = r.yDivs; - lattice.fFlags = (0 == r.flagCount) ? nullptr : r.flags; + lattice.fRectTypes = (0 == r.flagCount) ? nullptr : r.flags; + lattice.fColors = (0 == r.flagCount) ? nullptr : r.colors; lattice.fBounds = &r.src; fCanvas->drawImageLattice(r.image.get(), lattice, r.dst, r.paint); } diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 3d53e9384e..9374b60264 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -238,12 +238,13 @@ void SkRecorder::onDrawImageNine(const SkImage* image, const SkIRect& center, void SkRecorder::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, const SkPaint* paint) { - int flagCount = lattice.fFlags ? (lattice.fXCount + 1) * (lattice.fYCount + 1) : 0; + int flagCount = lattice.fRectTypes ? (lattice.fXCount + 1) * (lattice.fYCount + 1) : 0; SkASSERT(lattice.fBounds); 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), - flagCount, this->copy(lattice.fFlags, flagCount), *lattice.fBounds, dst); + flagCount, this->copy(lattice.fRectTypes, flagCount), + this->copy(lattice.fColors, flagCount), *lattice.fBounds, dst); } void SkRecorder::onDrawText(const void* text, size_t byteLength, diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index bbac4452ca..f1e70b6c88 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -256,7 +256,8 @@ RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, int yCount; PODArray<int> yDivs; int flagCount; - PODArray<SkCanvas::Lattice::Flags> flags; + PODArray<SkCanvas::Lattice::RectType> flags; + PODArray<SkColor> colors; SkIRect src; SkRect dst); RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp index d91151c65e..7438eb2c0a 100644 --- a/src/gpu/ops/GrLatticeOp.cpp +++ b/src/gpu/ops/GrLatticeOp.cpp @@ -244,7 +244,8 @@ GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) { // edge of the image subset, respectively. std::unique_ptr<int[]> xdivs; std::unique_ptr<int[]> ydivs; - std::unique_ptr<SkCanvas::Lattice::Flags[]> flags; + std::unique_ptr<SkCanvas::Lattice::RectType[]> flags; + std::unique_ptr<SkColor[]> colors; SkIRect subset; do { imgW = random->nextRangeU(1, 1000); @@ -271,14 +272,17 @@ GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) { bool hasFlags = random->nextBool(); if (hasFlags) { int n = (lattice.fXCount + 1) * (lattice.fYCount + 1); - flags.reset(new SkCanvas::Lattice::Flags[n]); + flags.reset(new SkCanvas::Lattice::RectType[n]); + colors.reset(new SkColor[n]); for (int i = 0; i < n; ++i) { - flags[i] = random->nextBool() ? SkCanvas::Lattice::kTransparent_Flags - : (SkCanvas::Lattice::Flags)0; + flags[i] = random->nextBool() ? SkCanvas::Lattice::kTransparent + : SkCanvas::Lattice::kDefault; } - lattice.fFlags = flags.get(); + lattice.fRectTypes = flags.get(); + lattice.fColors = colors.get(); } else { - lattice.fFlags = nullptr; + lattice.fRectTypes = nullptr; + lattice.fColors = nullptr; } } while (!SkLatticeIter::Valid(imgW, imgH, lattice)); diff --git a/src/pipe/SkPipeCanvas.cpp b/src/pipe/SkPipeCanvas.cpp index b9fcd2d4b5..d53e40d83c 100644 --- a/src/pipe/SkPipeCanvas.cpp +++ b/src/pipe/SkPipeCanvas.cpp @@ -556,7 +556,7 @@ void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& latti if (paint) { extra |= kHasPaint_DrawImageLatticeMask; } - if (lattice.fFlags) { + if (lattice.fRectTypes) { extra |= kHasFlags_DrawImageLatticeMask; } if (lattice.fXCount >= kCount_DrawImageLatticeMask) { @@ -583,10 +583,11 @@ void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& latti // so we can store them smaller. writer.write(lattice.fXDivs, lattice.fXCount * sizeof(int32_t)); writer.write(lattice.fYDivs, lattice.fYCount * sizeof(int32_t)); - if (lattice.fFlags) { + if (lattice.fRectTypes) { int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1); SkASSERT(count > 0); - write_pad(&writer, lattice.fFlags, count); + write_pad(&writer, lattice.fRectTypes, count); + write_pad(&writer, lattice.fColors, count*sizeof(SkColor)); } SkASSERT(lattice.fBounds); writer.write(&lattice.fBounds, sizeof(*lattice.fBounds)); diff --git a/src/pipe/SkPipeReader.cpp b/src/pipe/SkPipeReader.cpp index 593c8b3ce9..3afb22e3bf 100644 --- a/src/pipe/SkPipeReader.cpp +++ b/src/pipe/SkPipeReader.cpp @@ -560,9 +560,11 @@ static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb, if (packedVerb & kHasFlags_DrawImageLatticeMask) { int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1); SkASSERT(count > 0); - lattice.fFlags = skip<SkCanvas::Lattice::Flags>(reader, SkAlign4(count)); + lattice.fRectTypes = skip<SkCanvas::Lattice::RectType>(reader, SkAlign4(count)); + lattice.fColors = skip<SkColor>(reader, SkAlign4(count)); } else { - lattice.fFlags = nullptr; + lattice.fRectTypes = nullptr; + lattice.fColors = nullptr; } lattice.fBounds = skip<SkIRect>(reader); const SkRect* dst = skip<SkRect>(reader); diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp index 5f4316f866..0c0d7ac0a0 100644 --- a/tools/debugger/SkDrawCommand.cpp +++ b/tools/debugger/SkDrawCommand.cpp @@ -1272,13 +1272,13 @@ Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) { YDivs.append(Json::Value(lattice.fYDivs[i])); } result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs; - if (nullptr != lattice.fFlags) { + if (nullptr != lattice.fRectTypes) { Json::Value flags(Json::arrayValue); int flagCount = 0; for (int row = 0; row < lattice.fYCount+1; row++) { Json::Value flagsRow(Json::arrayValue); for (int column = 0; column < lattice.fXCount+1; column++) { - flagsRow.append(Json::Value(lattice.fFlags[flagCount++])); + flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++])); } flags.append(flagsRow); } |