Add captureLayers function to capture a layer and its children.
The captureLayers function gets a root layer as its argument.
It will capture the content for that layer and its descendants. The
capture will set the root layer's transform back to (0, 0).
Test: Transaction_test ScreenCaptureTest
Change-Id: I84fb66a65cd91434cddc99506b1924cf9f950935
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 27739ce..56328c9 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1063,17 +1063,16 @@
// drawing...
// ---------------------------------------------------------------------------
-void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
- onDraw(hw, clip, false);
+void Layer::draw(const RenderArea& renderArea, const Region& clip) const {
+ onDraw(renderArea, clip, false);
}
-void Layer::draw(const sp<const DisplayDevice>& hw,
- bool useIdentityTransform) const {
- onDraw(hw, Region(hw->bounds()), useIdentityTransform);
+void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) const {
+ onDraw(renderArea, Region(renderArea.getBounds()), useIdentityTransform);
}
-void Layer::draw(const sp<const DisplayDevice>& hw) const {
- onDraw(hw, Region(hw->bounds()), false);
+void Layer::draw(const RenderArea& renderArea) const {
+ onDraw(renderArea, Region(renderArea.getBounds()), false);
}
static constexpr mat4 inverseOrientation(uint32_t transform) {
@@ -1097,7 +1096,7 @@
/*
* onDraw will draw the current layer onto the presentable buffer
*/
-void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
+void Layer::onDraw(const RenderArea& renderArea, const Region& clip,
bool useIdentityTransform) const
{
ATRACE_CALL();
@@ -1119,12 +1118,12 @@
finished = true;
return;
}
- under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
+ under.orSelf(renderArea.getTransform().transform(layer->visibleRegion));
});
// if not everything below us is covered, we plug the holes!
Region holes(clip.subtract(under));
if (!holes.isEmpty()) {
- clearWithOpenGL(hw, 0, 0, 0, 1);
+ clearWithOpenGL(renderArea, 0, 0, 0, 1);
}
return;
}
@@ -1138,13 +1137,13 @@
// is probably going to have something visibly wrong.
}
- bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
+ bool blackOutLayer = isProtected() || (isSecure() && !renderArea.isSecure());
RenderEngine& engine(mFlinger->getRenderEngine());
if (!blackOutLayer) {
// TODO: we could be more subtle with isFixedSize()
- const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
+ const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize();
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
@@ -1190,31 +1189,29 @@
} else {
engine.setupLayerBlackedOut();
}
- drawWithOpenGL(hw, useIdentityTransform);
+ drawWithOpenGL(renderArea, useIdentityTransform);
engine.disableTexturing();
}
-void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
+void Layer::clearWithOpenGL(const RenderArea& renderArea,
float red, float green, float blue,
float alpha) const
{
RenderEngine& engine(mFlinger->getRenderEngine());
- computeGeometry(hw, mMesh, false);
+ computeGeometry(renderArea, mMesh, false);
engine.setupFillWithColor(red, green, blue, alpha);
engine.drawMesh(mMesh);
}
-void Layer::clearWithOpenGL(
- const sp<const DisplayDevice>& hw) const {
- clearWithOpenGL(hw, 0,0,0,0);
+void Layer::clearWithOpenGL(const RenderArea& renderArea) const {
+ clearWithOpenGL(renderArea, 0,0,0,0);
}
-void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
- bool useIdentityTransform) const {
+void Layer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
const State& s(getDrawingState());
- computeGeometry(hw, mMesh, useIdentityTransform);
+ computeGeometry(renderArea, mMesh, useIdentityTransform);
/*
* NOTE: the way we compute the texture coordinates here produces
@@ -1440,12 +1437,11 @@
}
}
-void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
- bool useIdentityTransform) const
-{
+void Layer::computeGeometry(const RenderArea& renderArea, Mesh& mesh,
+ bool useIdentityTransform) const {
const Layer::State& s(getDrawingState());
- const Transform hwTransform(hw->getTransform());
- const uint32_t hw_h = hw->getHeight();
+ const Transform renderAreaTransform(renderArea.getTransform());
+ const uint32_t height = renderArea.getHeight();
Rect win = computeBounds();
vec2 lt = vec2(win.left, win.top);
@@ -1469,12 +1465,12 @@
}
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
- position[0] = hwTransform.transform(lt);
- position[1] = hwTransform.transform(lb);
- position[2] = hwTransform.transform(rb);
- position[3] = hwTransform.transform(rt);
+ position[0] = renderAreaTransform.transform(lt);
+ position[1] = renderAreaTransform.transform(lb);
+ position[2] = renderAreaTransform.transform(rb);
+ position[3] = renderAreaTransform.transform(rt);
for (size_t i=0 ; i<4 ; i++) {
- position[i].y = hw_h - position[i].y;
+ position[i].y = height - position[i].y;
}
}
@@ -1512,8 +1508,8 @@
return !mCurrentCrop.isEmpty();
}
-bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
- return mNeedsFiltering || hw->needsFiltering();
+bool Layer::needsFiltering(const RenderArea& renderArea) const {
+ return mNeedsFiltering || renderArea.needsFiltering();
}
void Layer::setVisibleRegion(const Region& visibleRegion) {
@@ -2773,6 +2769,29 @@
}
}
+/**
+ * Traverse only children in z order, ignoring relative layers.
+ */
+void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet,
+ const LayerVector::Visitor& visitor) {
+ const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
+ const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
+
+ size_t i = 0;
+ for (; i < children.size(); i++) {
+ const auto& relative = children[i];
+ if (relative->getZ() >= 0) {
+ break;
+ }
+ relative->traverseChildrenInZOrder(stateSet, visitor);
+ }
+ visitor(this);
+ for (; i < children.size(); i++) {
+ const auto& relative = children[i];
+ relative->traverseChildrenInZOrder(stateSet, visitor);
+ }
+}
+
Transform Layer::getTransform() const {
Transform t;
const auto& p = mDrawingParent.promote();