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>
diff --git a/src/core/SkLatticeIter.cpp b/src/core/SkLatticeIter.cpp
index 9b2a279..551982e 100644
--- a/src/core/SkLatticeIter.cpp
+++ b/src/core/SkLatticeIter.cpp
@@ -166,16 +166,19 @@
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 @@
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 @@
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 @@
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;
}