Revert "Change behavior of setBitmap to cleanly reset the canvas - identity matrix - no save stack - wide-open clip"
https://buganizer.corp.google.com/issues/36218535
This reverts commit 269f989fbf198b17994baf9141c4640aeaf34b4e.
Change-Id: Ib2473e4fce90c9abaa39eea2b77082ae26197b80
(cherry picked from commit 4f641d1e4586b027969052cc0ad6b65c1158e72e)
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 2a2e14b..7289429 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -157,12 +157,10 @@
/**
* Specify a bitmap for the canvas to draw into. All canvas state such as
- * layers, filters, and the save/restore stack are reset. Additionally,
+ * layers, filters, and the save/restore stack are reset with the exception
+ * of the current matrix and clip stack. Additionally, as a side-effect
* the canvas' target density is updated to match that of the bitmap.
*
- * Prior to API level {@value Build.VERSION_CODES#O} the current matrix and
- * clip stack were preserved.
- *
* @param bitmap Specifies a mutable bitmap for the canvas to draw into.
* @see #setDensity(int)
* @see #getDensity()
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 363aa83..812e4d8 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -73,9 +73,39 @@
// Canvas state operations: Replace Bitmap
// ----------------------------------------------------------------------------
+class ClipCopier : public SkCanvas::ClipVisitor {
+public:
+ explicit ClipCopier(SkCanvas* dstCanvas) : m_dstCanvas(dstCanvas) {}
+
+ virtual void clipRect(const SkRect& rect, SkClipOp op, bool antialias) {
+ m_dstCanvas->clipRect(rect, op, antialias);
+ }
+ virtual void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) {
+ m_dstCanvas->clipRRect(rrect, op, antialias);
+ }
+ virtual void clipPath(const SkPath& path, SkClipOp op, bool antialias) {
+ m_dstCanvas->clipPath(path, op, antialias);
+ }
+
+private:
+ SkCanvas* m_dstCanvas;
+};
+
void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
- mCanvasOwned.reset(new SkCanvas(bitmap));
- mCanvas = mCanvasOwned.get();
+ SkCanvas* newCanvas = new SkCanvas(bitmap);
+
+ if (!bitmap.isNull()) {
+ // Copy the canvas matrix & clip state.
+ newCanvas->setMatrix(mCanvas->getTotalMatrix());
+
+ ClipCopier copier(newCanvas);
+ mCanvas->replayClips(&copier);
+ }
+
+ // deletes the previously owned canvas (if any)
+ mCanvasOwned = std::unique_ptr<SkCanvas>(newCanvas);
+ mCanvas = newCanvas;
+
// clean up the old save stack
mSaveStack.reset(nullptr);
}