SkCanvas is no longer reference-counted
Change-Id: Ie821efe7c0a7d1301715e303aaf4d7ec86ac35e7
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 5e21dfc..6786a69 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -52,16 +52,20 @@
SkiaCanvas::SkiaCanvas() {}
SkiaCanvas::SkiaCanvas(SkCanvas* canvas)
- : mCanvas(SkRef(canvas)) {}
+ : mCanvas(canvas) {}
SkiaCanvas::SkiaCanvas(const SkBitmap& bitmap) {
- mCanvas.reset(new SkCanvas(bitmap));
+ mCanvasOwned = std::unique_ptr<SkCanvas>(new SkCanvas(bitmap));
+ mCanvas = mCanvasOwned.get();
}
SkiaCanvas::~SkiaCanvas() {}
void SkiaCanvas::reset(SkCanvas* skiaCanvas) {
- mCanvas.reset(SkRef(skiaCanvas));
+ if (mCanvas != skiaCanvas) {
+ mCanvas = skiaCanvas;
+ mCanvasOwned.reset();
+ }
mSaveStack.reset(nullptr);
mHighContrastText = false;
}
@@ -99,8 +103,9 @@
mCanvas->replayClips(&copier);
}
- // unrefs the existing canvas
- mCanvas.reset(newCanvas);
+ // deletes the previously owned canvas (if any)
+ mCanvasOwned = std::unique_ptr<SkCanvas>(newCanvas);
+ mCanvas = newCanvas;
// clean up the old save stack
mSaveStack.reset(nullptr);
@@ -307,7 +312,7 @@
const SkMatrix saveMatrix = mCanvas->getTotalMatrix();
for (auto clip = begin; clip != end; ++clip) {
- clip->apply(mCanvas.get());
+ clip->apply(mCanvas);
}
mCanvas->setMatrix(saveMatrix);
@@ -562,7 +567,7 @@
void SkiaCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix, const SkPaint* paint) {
SkBitmap bitmap;
hwuiBitmap.getSkBitmap(&bitmap);
- SkAutoCanvasRestore acr(mCanvas.get(), true);
+ SkAutoCanvasRestore acr(mCanvas, true);
mCanvas->concat(matrix);
mCanvas->drawBitmap(bitmap, 0, 0, paint);
}
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index a0cdfcb..4f1d857 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -35,15 +35,15 @@
* Create a new SkiaCanvas.
*
* @param canvas SkCanvas to handle calls made to this SkiaCanvas. Must
- * not be NULL. This constructor will ref() the SkCanvas, and unref()
- * it in its destructor.
+ * not be NULL. This constructor does not take ownership, so the caller
+ * must guarantee that it remains valid while the SkiaCanvas is valid.
*/
explicit SkiaCanvas(SkCanvas* canvas);
virtual ~SkiaCanvas();
virtual SkCanvas* asSkCanvas() override {
- return mCanvas.get();
+ return mCanvas;
}
virtual void resetRecording(int width, int height,
@@ -182,7 +182,9 @@
class Clip;
- sk_sp<SkCanvas> mCanvas;
+ std::unique_ptr<SkCanvas> mCanvasOwned; // might own a canvas we allocated
+ SkCanvas* mCanvas; // we do NOT own this canvas, it must survive us
+ // unless it is the same as mCanvasOwned.get()
std::unique_ptr<SkDeque> mSaveStack; // lazily allocated, tracks partial saves.
std::vector<Clip> mClipStack; // tracks persistent clips.
};
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index ae4f0f4..dd97dec 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -303,40 +303,42 @@
static const int LAYER_HEIGHT = 200;
class ProjectionTestCanvas : public SkCanvas {
public:
- ProjectionTestCanvas() : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT) {}
+ ProjectionTestCanvas(int* drawCounter)
+ : SkCanvas(CANVAS_WIDTH, CANVAS_HEIGHT)
+ , mDrawCounter(drawCounter)
+ {}
void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
const SkPaint&) override {
- EXPECT_EQ(0, mIndex++); //part of painting the layer
+ EXPECT_EQ(0, (*mDrawCounter)++); //part of painting the layer
EXPECT_EQ(SkRect::MakeLTRB(0, 0, LAYER_WIDTH, LAYER_HEIGHT), getBounds(this));
}
void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
- EXPECT_EQ(1, mIndex++);
+ EXPECT_EQ(1, (*mDrawCounter)++);
EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), getBounds(this));
}
void onDrawOval(const SkRect&, const SkPaint&) override {
- EXPECT_EQ(2, mIndex++);
+ EXPECT_EQ(2, (*mDrawCounter)++);
SkMatrix expectedMatrix;
expectedMatrix.setTranslate(100 - SCROLL_X, 100 - SCROLL_Y);
EXPECT_EQ(expectedMatrix, getTotalMatrix());
EXPECT_EQ(SkRect::MakeLTRB(-85, -80, 295, 300), getLocalBounds(this));
}
- int mIndex = 0;
+ int* mDrawCounter;
};
class ProjectionLayer : public SkSurface_Base {
public:
- ProjectionLayer(ProjectionTestCanvas *canvas)
+ ProjectionLayer(int* drawCounter)
: SkSurface_Base(SkImageInfo::MakeN32Premul(LAYER_WIDTH, LAYER_HEIGHT), nullptr)
- , mCanvas(canvas) {
+ , mDrawCounter(drawCounter) {
}
void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override {
- EXPECT_EQ(3, mCanvas->mIndex++);
+ EXPECT_EQ(3, (*mDrawCounter)++);
EXPECT_EQ(SkRect::MakeLTRB(100 - SCROLL_X, 100 - SCROLL_Y, 300 - SCROLL_X,
- 300 - SCROLL_Y), getBounds(mCanvas));
+ 300 - SCROLL_Y), getBounds(this->getCanvas()));
}
SkCanvas* onNewCanvas() override {
- mCanvas->ref();
- return mCanvas;
+ return new ProjectionTestCanvas(mDrawCounter);
}
sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override {
return sk_sp<SkSurface>();
@@ -345,7 +347,7 @@
return sk_sp<SkImage>();
}
void onCopyOnWrite(ContentChangeMode) override {}
- ProjectionTestCanvas* mCanvas;
+ int* mDrawCounter;
};
auto receiverBackground = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
@@ -389,10 +391,10 @@
info.observer = nullptr;
parent->prepareTree(info);
- sk_sp<ProjectionTestCanvas> canvas(new ProjectionTestCanvas());
+ int drawCounter = 0;
//set a layer after prepareTree to avoid layer logic there
child->animatorProperties().mutateLayerProperties().setType(LayerType::RenderLayer);
- sk_sp<SkSurface> surfaceLayer1(new ProjectionLayer(canvas.get()));
+ sk_sp<SkSurface> surfaceLayer1(new ProjectionLayer(&drawCounter));
child->setLayerSurface(surfaceLayer1);
Matrix4 windowTransform;
windowTransform.loadTranslate(100, 100, 0);
@@ -402,11 +404,11 @@
layerUpdateQueue.enqueueLayerWithDamage(child.get(),
android::uirenderer::Rect(LAYER_WIDTH, LAYER_HEIGHT));
SkiaPipeline::renderLayersImpl(layerUpdateQueue, true);
- EXPECT_EQ(1, canvas->mIndex); //assert index 0 is drawn on the layer
+ EXPECT_EQ(1, drawCounter); //assert index 0 is drawn on the layer
- RenderNodeDrawable drawable(parent.get(), canvas.get(), true);
- canvas->drawDrawable(&drawable);
- EXPECT_EQ(4, canvas->mIndex);
+ RenderNodeDrawable drawable(parent.get(), surfaceLayer1->getCanvas(), true);
+ surfaceLayer1->getCanvas()->drawDrawable(&drawable);
+ EXPECT_EQ(4, drawCounter);
// clean up layer pointer, so we can safely destruct RenderNode
child->setLayerSurface(nullptr);
@@ -479,7 +481,7 @@
info.observer = nullptr;
parent->prepareTree(info);
- sk_sp<ProjectionChildScrollTestCanvas> canvas(new ProjectionChildScrollTestCanvas());
+ std::unique_ptr<ProjectionChildScrollTestCanvas> canvas(new ProjectionChildScrollTestCanvas());
RenderNodeDrawable drawable(parent.get(), canvas.get(), true);
canvas->drawDrawable(&drawable);
EXPECT_EQ(2, canvas->mIndex);