Add SkiaCanvas::captureCanvasState()
Test: Verified bug is fixed. Wrote unit test. Bug: 37268771 Change-Id: I9deb7db353cd2129ad245e7f65419670463bb717
This commit is contained in:
@@ -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>
|
||||
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user