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 /gm/lattice.cpp | |
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>
Diffstat (limited to 'gm/lattice.cpp')
-rw-r--r-- | gm/lattice.cpp | 180 |
1 files changed, 172 insertions, 8 deletions
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; ) + + + |