Use stack based cleanup for canvas save/restore calls.
Using this approach enables future CLs to add quick reject logic
to drawing layers in future CLs and more cleanly manages the
save/restore lifetimes.
Test: librendererengine_test
Bug: 181028875
Change-Id: I061a6986d0a2d3735d35b1c065a1bd41c147a41b
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 327b04c..769951f 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -556,6 +556,26 @@
canvas->translate(-display.clip.left, -display.clip.top);
}
+class AutoSaveRestore {
+public:
+ AutoSaveRestore(SkCanvas* canvas) : mCanvas(canvas) { mSaveCount = canvas->save(); }
+ ~AutoSaveRestore() { restore(); }
+ void replace(SkCanvas* canvas) {
+ mCanvas = canvas;
+ mSaveCount = canvas->save();
+ }
+ void restore() {
+ if (mCanvas) {
+ mCanvas->restoreToCount(mSaveCount);
+ mCanvas = nullptr;
+ }
+ }
+
+private:
+ SkCanvas* mCanvas;
+ int mSaveCount;
+};
+
status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
const sp<GraphicBuffer>& buffer,
@@ -650,7 +670,7 @@
}
}
- canvas->save();
+ AutoSaveRestore surfaceAutoSaveRestore(canvas);
// Clear the entire canvas with a transparent black to prevent ghost images.
canvas->clear(SK_ColorTRANSPARENT);
initCanvas(canvas, display);
@@ -705,7 +725,7 @@
// assign dstCanvas to canvas and ensure that the canvas state is up to date
canvas = dstCanvas;
- canvas->save();
+ surfaceAutoSaveRestore.replace(canvas);
initCanvas(canvas, display);
LOG_ALWAYS_FATAL_IF(activeSurface->getCanvas()->getSaveCount() !=
@@ -717,7 +737,7 @@
activeSurface = dstSurface;
}
- canvas->save();
+ SkAutoCanvasRestore layerAutoSaveRestore(canvas, true);
if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
// Record the name of the layer if the capture is running.
std::stringstream layerSettings;
@@ -888,9 +908,8 @@
}
canvas->drawRect(bounds, paint);
}
- canvas->restore();
}
- canvas->restore();
+ surfaceAutoSaveRestore.restore();
mCapture->endCapture();
{
ATRACE_NAME("flush surface");