blast: BufferStateLayer
Adds the initial foundation for supporting buffers on
transactions as well as the other metadata that had been passed
over BufferQueue.
Bug: 80477568
Test: Transaction_test.cpp
Change-Id: I61e44462c66c1a912adbabf62015e66bde44c216
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index eeee0ae..ee9ee78 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -114,6 +114,17 @@
mCurrentState.requested_legacy = mCurrentState.active_legacy;
mCurrentState.appId = 0;
mCurrentState.type = 0;
+ mCurrentState.active.w = 0;
+ mCurrentState.active.h = 0;
+ mCurrentState.active.transform.set(0, 0);
+ mCurrentState.transform = 0;
+ mCurrentState.transformToDisplayInverse = false;
+ mCurrentState.crop.makeInvalid();
+ mCurrentState.acquireFence = new Fence(-1);
+ mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
+ mCurrentState.hdrMetadata.validTypes = 0;
+ mCurrentState.surfaceDamageRegion.clear();
+ mCurrentState.api = -1;
// drawing state & current state are identical
mDrawingState = mCurrentState;
@@ -293,17 +304,19 @@
Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
const Layer::State& s(getDrawingState());
- Rect win(s.active_legacy.w, s.active_legacy.h);
+ Rect win(getActiveWidth(s), getActiveHeight(s));
- if (!s.crop_legacy.isEmpty()) {
- win.intersect(s.crop_legacy, &win);
+ Rect crop = getCrop(s);
+ if (!crop.isEmpty()) {
+ win.intersect(crop, &win);
}
Transform t = getTransform();
win = t.transform(win);
- if (!s.finalCrop_legacy.isEmpty()) {
- win.intersect(s.finalCrop_legacy, &win);
+ Rect finalCrop = getFinalCrop(s);
+ if (!finalCrop.isEmpty()) {
+ win.intersect(finalCrop, &win);
}
const sp<Layer>& p = mDrawingParent.promote();
@@ -322,7 +335,7 @@
}
if (reduceTransparentRegion) {
- auto const screenTransparentRegion = t.transform(s.activeTransparentRegion_legacy);
+ auto const screenTransparentRegion = t.transform(getActiveTransparentRegion(s));
win = reduce(win, screenTransparentRegion);
}
@@ -331,15 +344,16 @@
FloatRect Layer::computeBounds() const {
const Layer::State& s(getDrawingState());
- return computeBounds(s.activeTransparentRegion_legacy);
+ return computeBounds(getActiveTransparentRegion(s));
}
FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
const Layer::State& s(getDrawingState());
- Rect win(s.active_legacy.w, s.active_legacy.h);
+ Rect win(getActiveWidth(s), getActiveHeight(s));
- if (!s.crop_legacy.isEmpty()) {
- win.intersect(s.crop_legacy, &win);
+ Rect crop = getCrop(s);
+ if (!crop.isEmpty()) {
+ win.intersect(crop, &win);
}
const auto& p = mDrawingParent.promote();
@@ -379,9 +393,10 @@
// FIXME: the 3 lines below can produce slightly incorrect clipping when we have
// a viewport clipping and a window transform. we should use floating point to fix this.
- Rect activeCrop(s.active_legacy.w, s.active_legacy.h);
- if (!s.crop_legacy.isEmpty()) {
- activeCrop.intersect(s.crop_legacy, &activeCrop);
+ Rect activeCrop(getActiveWidth(s), getActiveHeight(s));
+ Rect crop = getCrop(s);
+ if (!crop.isEmpty()) {
+ activeCrop.intersect(crop, &activeCrop);
}
Transform t = getTransform();
@@ -389,8 +404,9 @@
if (!activeCrop.intersect(display->getViewport(), &activeCrop)) {
activeCrop.clear();
}
- if (!s.finalCrop_legacy.isEmpty()) {
- if (!activeCrop.intersect(s.finalCrop_legacy, &activeCrop)) {
+ Rect finalCrop = getFinalCrop(s);
+ if (!finalCrop.isEmpty()) {
+ if (!activeCrop.intersect(finalCrop, &activeCrop)) {
activeCrop.clear();
}
}
@@ -424,12 +440,12 @@
// transform.inverse().transform(transform.transform(Rect)) != Rect
// in which case we need to make sure the final rect is clipped to the
// display bounds.
- if (!activeCrop.intersect(Rect(s.active_legacy.w, s.active_legacy.h), &activeCrop)) {
+ if (!activeCrop.intersect(Rect(getActiveWidth(s), getActiveHeight(s)), &activeCrop)) {
activeCrop.clear();
}
// subtract the transparent region and snap to the bounds
- activeCrop = reduce(activeCrop, s.activeTransparentRegion_legacy);
+ activeCrop = reduce(activeCrop, getActiveTransparentRegion(s));
// Transform the window crop to match the buffer coordinate system,
// which means using the inverse of the current transform set on the
@@ -449,8 +465,8 @@
invTransform = (Transform(invTransformOrient) * Transform(invTransform)).getOrientation();
}
- int winWidth = s.active_legacy.w;
- int winHeight = s.active_legacy.h;
+ int winWidth = getActiveWidth(s);
+ int winHeight = getActiveHeight(s);
if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
// If the activeCrop has been rotate the ends are rotated but not
// the space itself so when transforming ends back we can't rely on
@@ -462,10 +478,10 @@
if (is_h_flipped == is_v_flipped) {
invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H;
}
- winWidth = s.active_legacy.h;
- winHeight = s.active_legacy.w;
+ winWidth = getActiveHeight(s);
+ winHeight = getActiveWidth(s);
}
- const Rect winCrop = activeCrop.transform(invTransform, s.active_legacy.w, s.active_legacy.h);
+ const Rect winCrop = activeCrop.transform(invTransform, getActiveWidth(s), getActiveHeight(s));
// below, crop is intersected with winCrop expressed in crop's coordinate space
float xScale = crop.getWidth() / float(winWidth);
@@ -518,10 +534,10 @@
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
- Region activeTransparentRegion(s.activeTransparentRegion_legacy);
+ Region activeTransparentRegion(getActiveTransparentRegion(s));
Transform t = getTransform();
- if (!s.crop_legacy.isEmpty()) {
- Rect activeCrop(s.crop_legacy);
+ Rect activeCrop = getCrop(s);
+ if (!activeCrop.isEmpty()) {
activeCrop = t.transform(activeCrop);
if (!activeCrop.intersect(display->getViewport(), &activeCrop)) {
activeCrop.clear();
@@ -533,23 +549,24 @@
// transform.inverse().transform(transform.transform(Rect)) != Rect
// in which case we need to make sure the final rect is clipped to the
// display bounds.
- if (!activeCrop.intersect(Rect(s.active_legacy.w, s.active_legacy.h), &activeCrop)) {
+ if (!activeCrop.intersect(Rect(getActiveWidth(s), getActiveHeight(s)), &activeCrop)) {
activeCrop.clear();
}
// mark regions outside the crop as transparent
- activeTransparentRegion.orSelf(Rect(0, 0, s.active_legacy.w, activeCrop.top));
+ activeTransparentRegion.orSelf(Rect(0, 0, getActiveWidth(s), activeCrop.top));
activeTransparentRegion.orSelf(
- Rect(0, activeCrop.bottom, s.active_legacy.w, s.active_legacy.h));
+ Rect(0, activeCrop.bottom, getActiveWidth(s), getActiveHeight(s)));
activeTransparentRegion.orSelf(Rect(0, activeCrop.top, activeCrop.left, activeCrop.bottom));
activeTransparentRegion.orSelf(
- Rect(activeCrop.right, activeCrop.top, s.active_legacy.w, activeCrop.bottom));
+ Rect(activeCrop.right, activeCrop.top, getActiveWidth(s), activeCrop.bottom));
}
// computeBounds returns a FloatRect to provide more accuracy during the
// transformation. We then round upon constructing 'frame'.
Rect frame{t.transform(computeBounds(activeTransparentRegion))};
- if (!s.finalCrop_legacy.isEmpty()) {
- if (!frame.intersect(s.finalCrop_legacy, &frame)) {
+ Rect finalCrop = getFinalCrop(s);
+ if (!finalCrop.isEmpty()) {
+ if (!frame.intersect(finalCrop, &frame)) {
frame.clear();
}
}
@@ -682,16 +699,18 @@
// Apply the layer's transform, followed by the display's global transform
// Here we're guaranteed that the layer's transform preserves rects
- Rect win(s.active_legacy.w, s.active_legacy.h);
- if (!s.crop_legacy.isEmpty()) {
- win.intersect(s.crop_legacy, &win);
+ Rect win(getActiveWidth(s), getActiveHeight(s));
+ Rect crop = getCrop(s);
+ if (!crop.isEmpty()) {
+ win.intersect(crop, &win);
}
// Subtract the transparent region and snap to the bounds
- Rect bounds = reduce(win, s.activeTransparentRegion_legacy);
+ Rect bounds = reduce(win, getActiveTransparentRegion(s));
Rect frame(getTransform().transform(bounds));
frame.intersect(display->getViewport(), &frame);
- if (!s.finalCrop_legacy.isEmpty()) {
- frame.intersect(s.finalCrop_legacy, &frame);
+ Rect finalCrop = getFinalCrop(s);
+ if (!finalCrop.isEmpty()) {
+ frame.intersect(finalCrop, &frame);
}
auto& displayTransform = display->getTransform();
auto position = displayTransform.transform(frame);
@@ -709,15 +728,15 @@
// drawing...
// ---------------------------------------------------------------------------
-void Layer::draw(const RenderArea& renderArea, const Region& clip) const {
+void Layer::draw(const RenderArea& renderArea, const Region& clip) {
onDraw(renderArea, clip, false);
}
-void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) const {
+void Layer::draw(const RenderArea& renderArea, bool useIdentityTransform) {
onDraw(renderArea, Region(renderArea.getBounds()), useIdentityTransform);
}
-void Layer::draw(const RenderArea& renderArea) const {
+void Layer::draw(const RenderArea& renderArea) {
onDraw(renderArea, Region(renderArea.getBounds()), false);
}
@@ -844,11 +863,12 @@
rt = layerTransform.transform(rt);
}
- if (!s.finalCrop_legacy.isEmpty()) {
- boundPoint(<, s.finalCrop_legacy);
- boundPoint(&lb, s.finalCrop_legacy);
- boundPoint(&rb, s.finalCrop_legacy);
- boundPoint(&rt, s.finalCrop_legacy);
+ Rect finalCrop = getFinalCrop(s);
+ if (!finalCrop.isEmpty()) {
+ boundPoint(<, finalCrop);
+ boundPoint(&lb, finalCrop);
+ boundPoint(&rb, finalCrop);
+ boundPoint(&rt, finalCrop);
}
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
@@ -984,19 +1004,11 @@
return stateUpdateAvailable;
}
-uint32_t Layer::doTransaction(uint32_t flags) {
- ATRACE_CALL();
-
- pushPendingState();
- Layer::State c = getCurrentState();
- if (!applyPendingStates(&c)) {
- return 0;
- }
-
+uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) {
const Layer::State& s(getDrawingState());
- const bool sizeChanged = (c.requested_legacy.w != s.requested_legacy.w) ||
- (c.requested_legacy.h != s.requested_legacy.h);
+ const bool sizeChanged = (stateToCommit->requested_legacy.w != s.requested_legacy.w) ||
+ (stateToCommit->requested_legacy.h != s.requested_legacy.h);
if (sizeChanged) {
// the size changed, we need to ask our client to request a new buffer
@@ -1007,16 +1019,18 @@
" drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
" requested={ wh={%4u,%4u} }}\n",
this, getName().string(), mCurrentTransform, getEffectiveScalingMode(),
- c.active_legacy.w, c.active_legacy.h, c.crop_legacy.left, c.crop_legacy.top,
- c.crop_legacy.right, c.crop_legacy.bottom, c.crop_legacy.getWidth(),
- c.crop_legacy.getHeight(), c.requested_legacy.w, c.requested_legacy.h,
+ stateToCommit->active_legacy.w, stateToCommit->active_legacy.h,
+ stateToCommit->crop_legacy.left, stateToCommit->crop_legacy.top,
+ stateToCommit->crop_legacy.right, stateToCommit->crop_legacy.bottom,
+ stateToCommit->crop_legacy.getWidth(), stateToCommit->crop_legacy.getHeight(),
+ stateToCommit->requested_legacy.w, stateToCommit->requested_legacy.h,
s.active_legacy.w, s.active_legacy.h, s.crop_legacy.left, s.crop_legacy.top,
s.crop_legacy.right, s.crop_legacy.bottom, s.crop_legacy.getWidth(),
s.crop_legacy.getHeight(), s.requested_legacy.w, s.requested_legacy.h);
// record the new size, form this point on, when the client request
// a buffer, it'll get the new size.
- setDefaultBufferSize(c.requested_legacy.w, c.requested_legacy.h);
+ setDefaultBufferSize(stateToCommit->requested_legacy.w, stateToCommit->requested_legacy.h);
}
// Don't let Layer::doTransaction update the drawing state
@@ -1037,8 +1051,9 @@
// resizePending state is to avoid applying the state of the new buffer
// to the old buffer. However in the state where we don't have an old buffer
// there is no such concern but we may still be being used as a parent layer.
- const bool resizePending = ((c.requested_legacy.w != c.active_legacy.w) ||
- (c.requested_legacy.h != c.active_legacy.h)) &&
+ const bool resizePending =
+ ((stateToCommit->requested_legacy.w != stateToCommit->active_legacy.w) ||
+ (stateToCommit->requested_legacy.h != stateToCommit->active_legacy.h)) &&
(getBE().compositionInfo.mBuffer != nullptr);
if (!isFixedSize()) {
if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) {
@@ -1062,21 +1077,37 @@
// being stored in the same data structure while having different latching rules.
// b/38182305
//
- // Careful that "c" and editCurrentState may not begin as equivalent due to
+ // Careful that "stateToCommit" and editCurrentState may not begin as equivalent due to
// applyPendingStates in the presence of deferred transactions.
if (mFreezeGeometryUpdates) {
- float tx = c.active_legacy.transform.tx();
- float ty = c.active_legacy.transform.ty();
- c.active_legacy = c.requested_legacy;
- c.active_legacy.transform.set(tx, ty);
- editCurrentState.active_legacy = c.active_legacy;
+ float tx = stateToCommit->active_legacy.transform.tx();
+ float ty = stateToCommit->active_legacy.transform.ty();
+ stateToCommit->active_legacy = stateToCommit->requested_legacy;
+ stateToCommit->active_legacy.transform.set(tx, ty);
+ editCurrentState.active_legacy = stateToCommit->active_legacy;
} else {
editCurrentState.active_legacy = editCurrentState.requested_legacy;
- c.active_legacy = c.requested_legacy;
+ stateToCommit->active_legacy = stateToCommit->requested_legacy;
}
}
- if (s.active_legacy != c.active_legacy) {
+ return flags;
+}
+
+uint32_t Layer::doTransaction(uint32_t flags) {
+ ATRACE_CALL();
+
+ pushPendingState();
+ Layer::State c = getCurrentState();
+ if (!applyPendingStates(&c)) {
+ return 0;
+ }
+
+ flags = doTransactionResize(flags, &c);
+
+ const Layer::State& s(getDrawingState());
+
+ if (getActiveGeometry(c) != getActiveGeometry(s)) {
// invalidate and recompute the visible regions if needed
flags |= Layer::eVisibleRegion;
}
@@ -1087,9 +1118,8 @@
this->contentDirty = true;
// we may use linear filtering, if the matrix scales us
- const uint8_t type = c.active_legacy.transform.getType();
- mNeedsFiltering =
- (!c.active_legacy.transform.preserveRects() || (type >= Transform::SCALE));
+ const uint8_t type = getActiveTransform(c).getType();
+ mNeedsFiltering = (!getActiveTransform(c).preserveRects() || (type >= Transform::SCALE));
}
// If the layer is hidden, signal and clear out all local sync points so
@@ -1278,6 +1308,7 @@
setTransactionFlags(eTransactionNeeded);
return true;
}
+
bool Layer::setTransparentRegionHint(const Region& transparent) {
mCurrentState.requestedTransparentRegion_legacy = transparent;
mCurrentState.modified = true;
@@ -1415,6 +1446,7 @@
// debugging
// ----------------------------------------------------------------------------
+// TODO(marissaw): add new layer state info to layer debugging
LayerDebugInfo Layer::getLayerDebugInfo() const {
LayerDebugInfo info;
const Layer::State& ds = getDrawingState();
@@ -1889,14 +1921,14 @@
bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth();
bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight();
}
- float sx = p->getDrawingState().active_legacy.w / static_cast<float>(bufferWidth);
- float sy = p->getDrawingState().active_legacy.h / static_cast<float>(bufferHeight);
+ float sx = p->getActiveWidth(p->getDrawingState()) / static_cast<float>(bufferWidth);
+ float sy = p->getActiveHeight(p->getDrawingState()) / static_cast<float>(bufferHeight);
Transform extraParentScaling;
extraParentScaling.set(sx, 0, 0, sy);
t = t * extraParentScaling;
}
}
- return t * getDrawingState().active_legacy.transform;
+ return t * getActiveTransform(getDrawingState());
}
half Layer::getAlpha() const {