Refactor HWUI readback code to be backend independent
Implement readback from Surface, TextureView and HW Bitmap
for Vulkan pipeline by wrapping the graphics buffer in an SkImage.
Refactor both Vulkan and GL readback to use common code.
TextureView readback is moved from IRenderPipeline interface to
Readback class. Refactor all 3 readback flows to use common
implementation.
Test: Passed all view, uirendering and graphics CTS tests with GL
Test: Passed many CTS test with Vulkan, that require readback
Bug: 113673613
Change-Id: Ifbfd8170a5401f87a709b4b1b9fa058e8e11768d
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index b6cd4b0..3ca0f81 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -28,12 +28,13 @@
void LayerDrawable::onDraw(SkCanvas* canvas) {
Layer* layer = mLayerUpdater->backingLayer();
if (layer) {
- DrawLayer(canvas->getGrContext(), canvas, layer);
+ DrawLayer(canvas->getGrContext(), canvas, layer, nullptr, nullptr, true);
}
}
bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer,
- const SkRect* dstRect) {
+ const SkRect* srcRect, const SkRect* dstRect,
+ bool useLayerTransform) {
if (context == nullptr) {
SkDEBUGF(("Attempting to draw LayerDrawable into an unsupported surface"));
return false;
@@ -60,12 +61,10 @@
}
SkMatrix matrix;
- if (dstRect) {
- // Destination rectangle is set only when we are trying to read back the content
- // of the layer. In this case we don't want to apply layer transform.
- matrix = textureMatrix;
- } else {
+ if (useLayerTransform) {
matrix = SkMatrix::Concat(layerTransform, textureMatrix);
+ } else {
+ matrix = textureMatrix;
}
SkPaint paint;
@@ -81,16 +80,26 @@
canvas->save();
canvas->concat(matrix);
}
- if (dstRect) {
+ if (dstRect || srcRect) {
SkMatrix matrixInv;
if (!matrix.invert(&matrixInv)) {
matrixInv = matrix;
}
- SkRect srcRect = SkRect::MakeIWH(layerWidth, layerHeight);
- matrixInv.mapRect(&srcRect);
- SkRect skiaDestRect = *dstRect;
+ SkRect skiaSrcRect;
+ if (srcRect) {
+ skiaSrcRect = *srcRect;
+ } else {
+ skiaSrcRect = SkRect::MakeIWH(layerWidth, layerHeight);
+ }
+ matrixInv.mapRect(&skiaSrcRect);
+ SkRect skiaDestRect;
+ if (dstRect) {
+ skiaDestRect = *dstRect;
+ } else {
+ skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight);
+ }
matrixInv.mapRect(&skiaDestRect);
- canvas->drawImageRect(layerImage.get(), srcRect, skiaDestRect, &paint,
+ canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, &paint,
SkCanvas::kFast_SrcRectConstraint);
} else {
canvas->drawImage(layerImage.get(), 0, 0, &paint);