Loading libs/hwui/SkiaCanvas.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -410,6 +411,30 @@ void SkiaCanvas::setDrawFilter(SkDrawFilter* drawFilter) { mCanvas->setDrawFilter(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 // ---------------------------------------------------------------------------- Loading libs/hwui/SkiaCanvas.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading libs/hwui/hwui/Canvas.h +5 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include <SkCanvas.h> #include <SkMatrix.h> class SkCanvasState; namespace minikin { class Layout; } Loading Loading @@ -200,6 +202,9 @@ public: virtual SkDrawFilter* getDrawFilter() = 0; virtual void setDrawFilter(SkDrawFilter* drawFilter) = 0; // WebView only virtual SkCanvasState* captureCanvasState() const { return nullptr; } // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- Loading libs/hwui/tests/unit/SkiaCanvasTests.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <gtest/gtest.h> #include <RecordingCanvas.h> #include <SkBlurDrawLooper.h> #include <SkCanvasStateUtils.h> #include <SkPicture.h> #include <SkPictureRecorder.h> Loading Loading @@ -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); } Loading
libs/hwui/SkiaCanvas.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -410,6 +411,30 @@ void SkiaCanvas::setDrawFilter(SkDrawFilter* drawFilter) { mCanvas->setDrawFilter(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 // ---------------------------------------------------------------------------- Loading
libs/hwui/SkiaCanvas.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
libs/hwui/hwui/Canvas.h +5 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include <SkCanvas.h> #include <SkMatrix.h> class SkCanvasState; namespace minikin { class Layout; } Loading Loading @@ -200,6 +202,9 @@ public: virtual SkDrawFilter* getDrawFilter() = 0; virtual void setDrawFilter(SkDrawFilter* drawFilter) = 0; // WebView only virtual SkCanvasState* captureCanvasState() const { return nullptr; } // ---------------------------------------------------------------------------- // Canvas draw operations // ---------------------------------------------------------------------------- Loading
libs/hwui/tests/unit/SkiaCanvasTests.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <gtest/gtest.h> #include <RecordingCanvas.h> #include <SkBlurDrawLooper.h> #include <SkCanvasStateUtils.h> #include <SkPicture.h> #include <SkPictureRecorder.h> Loading Loading @@ -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); }