Update hole punch logic in HWUI
--Updated HWUI holepunch logic for SurfaceView to
also apply the stretch to the hole punch
--Updated RenderNode callbacks to also include
an offset from the ancestor RenderNode that also
has a stretch configured on it
--Added new test activity to verify hole punch
logic
Bug: 179047472
Test: manual
Change-Id: Ibbaf8248a31839ba9dc352ecb9fef54e1276918e
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 0bf9480..94fe243 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -197,6 +197,27 @@
}
}
+static void computeTransformImpl(const DirtyStack* frame, const DirtyStack* end,
+ Matrix4* outMatrix) {
+ while (frame != end) {
+ switch (frame->type) {
+ case TransformRenderNode:
+ frame->renderNode->applyViewPropertyTransforms(*outMatrix);
+ break;
+ case TransformMatrix4:
+ outMatrix->multiply(*frame->matrix4);
+ break;
+ case TransformNone:
+ // nothing to be done
+ break;
+ default:
+ LOG_ALWAYS_FATAL("Tried to compute transform with an invalid type: %d",
+ frame->type);
+ }
+ frame = frame->prev;
+ }
+}
+
void DamageAccumulator::applyRenderNodeTransform(DirtyStack* frame) {
if (frame->pendingDirty.isEmpty()) {
return;
@@ -249,19 +270,38 @@
mHead->pendingDirty.setEmpty();
}
-const StretchEffect* DamageAccumulator::findNearestStretchEffect() const {
+DamageAccumulator::StretchResult DamageAccumulator::findNearestStretchEffect() const {
DirtyStack* frame = mHead;
while (frame->prev != frame) {
- frame = frame->prev;
if (frame->type == TransformRenderNode) {
+ const auto& renderNode = frame->renderNode;
+ const auto& frameRenderNodeProperties = renderNode->properties();
const auto& effect =
- frame->renderNode->properties().layerProperties().getStretchEffect();
+ frameRenderNodeProperties.layerProperties().getStretchEffect();
+ const float width = (float) renderNode->getWidth();
+ const float height = (float) renderNode->getHeight();
if (!effect.isEmpty()) {
- return &effect;
+ Matrix4 stretchMatrix;
+ computeTransformImpl(mHead, frame, &stretchMatrix);
+ Rect stretchRect = Rect(0.f, 0.f, width, height);
+ stretchMatrix.mapRect(stretchRect);
+
+ return StretchResult{
+ .stretchEffect = &effect,
+ .childRelativeBounds = SkRect::MakeLTRB(
+ stretchRect.left,
+ stretchRect.top,
+ stretchRect.right,
+ stretchRect.bottom
+ ),
+ .width = width,
+ .height = height
+ };
}
}
+ frame = frame->prev;
}
- return nullptr;
+ return StretchResult{};
}
} /* namespace uirenderer */