diff options
author | 2017-04-13 09:33:18 -0400 | |
---|---|---|
committer | 2017-04-13 14:23:38 -0400 | |
commit | d0814db633dbd76ecdec08806199d49654562d48 (patch) | |
tree | 1f6cce0103507b2c88ce8861ef0e8fd4f092f72f | |
parent | 43791354c72dec37f9e93ab9cb1b494bb99926db (diff) |
Add SkiaCanvas::captureCanvasState()
Test: Verified bug is fixed. Wrote unit test.
Bug: 37268771
Change-Id: I9deb7db353cd2129ad245e7f65419670463bb717
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 25 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.h | 2 | ||||
-rw-r--r-- | libs/hwui/hwui/Canvas.h | 4 | ||||
-rw-r--r-- | libs/hwui/tests/unit/SkiaCanvasTests.cpp | 30 |
4 files changed, 61 insertions, 0 deletions
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index c902a7333f2f..ece0b472c6bf 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -23,6 +23,7 @@ #include "hwui/MinikinUtils.h" #include "pipeline/skia/AnimatedDrawables.h" +#include <SkCanvasStateUtils.h> #include <SkColorSpaceXformCanvas.h> #include <SkDrawable.h> #include <SkDeque.h> @@ -411,6 +412,30 @@ void SkiaCanvas::setDrawFilter(SkDrawFilter* drawFilter) { } // ---------------------------------------------------------------------------- +// Canvas state operations: Capture +// ---------------------------------------------------------------------------- + +SkCanvasState* SkiaCanvas::captureCanvasState() const { + SkCanvas* canvas = mCanvas; + if (mCanvasOwned) { + // Important to use the underlying SkCanvas, not the wrapper. + canvas = mCanvasOwned.get(); + } + + // Workarounds for http://crbug.com/271096: SW draw only supports + // translate & scale transforms, and a simple rectangular clip. + // (This also avoids significant wasted time in calling + // SkCanvasStateUtils::CaptureCanvasState when the clip is complex). + if (!canvas->isClipRect() || + (canvas->getTotalMatrix().getType() & + ~(SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask))) { + return nullptr; + } + + return SkCanvasStateUtils::CaptureCanvasState(canvas); +} + +// ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index 45924f62f6fc..af2c23e4a2b7 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -102,6 +102,8 @@ public: virtual SkDrawFilter* getDrawFilter() override; virtual void setDrawFilter(SkDrawFilter* drawFilter) override; + virtual SkCanvasState* captureCanvasState() const override; + virtual void drawColor(int color, SkBlendMode mode) override; virtual void drawPaint(const SkPaint& paint) override; diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h index 22679456cba1..ac8a08169997 100644 --- a/libs/hwui/hwui/Canvas.h +++ b/libs/hwui/hwui/Canvas.h @@ -27,6 +27,7 @@ #include <SkCanvas.h> #include <SkMatrix.h> +class SkCanvasState; class SkVertices; namespace minikin { @@ -204,6 +205,9 @@ public: virtual SkDrawFilter* getDrawFilter() = 0; virtual void setDrawFilter(SkDrawFilter* drawFilter) = 0; + // WebView only + virtual SkCanvasState* captureCanvasState() const { return nullptr; } + // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp index 44476af742f1..0d1eba4af2f9 100644 --- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp +++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp @@ -19,6 +19,7 @@ #include <gtest/gtest.h> #include <RecordingCanvas.h> #include <SkBlurDrawLooper.h> +#include <SkCanvasStateUtils.h> #include <SkPicture.h> #include <SkPictureRecorder.h> @@ -128,3 +129,32 @@ TEST(SkiaCanvas, colorSpaceXform) { canvas.asSkCanvas()->drawPicture(picture); ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0)); } + +TEST(SkiaCanvas, captureCanvasState) { + // Create a software canvas. + SkImageInfo info = SkImageInfo::Make(1, 1, kN32_SkColorType, kOpaque_SkAlphaType); + sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info); + SkBitmap skBitmap; + bitmap->getSkBitmap(&skBitmap); + skBitmap.eraseColor(0); + SkiaCanvas canvas(skBitmap); + + // Translate, then capture and verify the CanvasState. + canvas.translate(1.0f, 1.0f); + SkCanvasState* state = canvas.captureCanvasState(); + ASSERT_NE(state, nullptr); + std::unique_ptr<SkCanvas> newCanvas = SkCanvasStateUtils::MakeFromCanvasState(state); + ASSERT_NE(newCanvas.get(), nullptr); + newCanvas->translate(-1.0f, -1.0f); + ASSERT_TRUE(newCanvas->getTotalMatrix().isIdentity()); + SkCanvasStateUtils::ReleaseCanvasState(state); + + // Create a picture canvas. + SkPictureRecorder recorder; + SkCanvas* skPicCanvas = recorder.beginRecording(1, 1, NULL, 0); + SkiaCanvas picCanvas(skPicCanvas, Canvas::XformToSRGB::kDefer); + state = picCanvas.captureCanvasState(); + + // Verify that we cannot get the CanvasState. + ASSERT_EQ(state, nullptr); +} |