SkCanvas is no longer reference-counted

Change-Id: Ie821efe7c0a7d1301715e303aaf4d7ec86ac35e7
This commit is contained in:
Mike Reed
2016-11-18 17:21:09 -05:00
parent d0835e45f7
commit 6acfe16b56
3 changed files with 39 additions and 30 deletions

View File

@@ -52,16 +52,20 @@ Canvas* Canvas::create_canvas(SkCanvas* skiaCanvas) {
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 @@ void SkiaCanvas::setBitmap(const SkBitmap& bitmap) {
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 @@ void SkiaCanvas::applyPersistentClips(size_t clipStartIndex) {
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& bitmap, float left, float top, const SkPaint
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);
}

View File

@@ -35,15 +35,15 @@ public:
* 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 @@ private:
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.
};

View File

@@ -303,40 +303,42 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) {
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 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) {
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 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) {
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 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) {
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 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionChildScroll) {
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);