Merge "Add media.codec process to native stack dump list" into oc-dev
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d5498ed..6f430a3 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -399,6 +399,10 @@
Transform t = getTransform();
win = t.transform(win);
+ if (!s.finalCrop.isEmpty()) {
+ win.intersect(s.finalCrop, &win);
+ }
+
const sp<Layer>& p = getParent();
// Now we need to calculate the parent bounds, so we can clip ourselves to those.
// When calculating the parent bounds for purposes of clipping,
@@ -2543,7 +2547,25 @@
}
for (const sp<Layer>& child : mCurrentChildren) {
- newParent->addChild(child);
+ // We don't call addChild as we need to delay updating the child's parent pointer until
+ // a transaction occurs. Remember a refresh could occur in between now and the next
+ // transaction, in which case the Layer's parent pointer would be updated, but changes
+ // made to the parent in the same transaction would not have applied.
+ // This means that the following kind of scenario wont work:
+ //
+ // 1. Existing and visible child and parent surface exist
+ // 2. Create new surface hidden
+ // 3. Open transaction
+ // 4. Show the new surface, and reparent the old surface's children to it.
+ // 5. Close transaction.
+ //
+ // If we were to update the parent pointer immediately, then the child surface
+ // could disappear for one frame as it pointed at the new parent which
+ // hasn't yet become visible as the transaction hasn't yet occurred.
+ //
+ // Instead we defer the reparenting to commitChildList which happens as part
+ // of the global transaction.
+ newParent->mCurrentChildren.add(child);
sp<Client> client(child->mClientRef.promote());
if (client != nullptr) {
@@ -2713,6 +2735,8 @@
void Layer::commitChildList() {
for (size_t i = 0; i < mCurrentChildren.size(); i++) {
const auto& child = mCurrentChildren[i];
+ child->setParent(this);
+
child->commitChildList();
}
mDrawingChildren = mCurrentChildren;
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 68519a1..b7792c7 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -834,6 +834,38 @@
}
}
+TEST_F(ChildLayerTest, ChildLayerCropping) {
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->show();
+ mChild->setPosition(0, 0);
+ mFGSurfaceControl->setPosition(0, 0);
+ mFGSurfaceControl->setCrop(Rect(0, 0, 5, 5));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ mCapture->expectChildColor(0, 0);
+ mCapture->expectChildColor(4, 4);
+ mCapture->expectBGColor(5, 5);
+ }
+}
+
+TEST_F(ChildLayerTest, ChildLayerFinalCropping) {
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->show();
+ mChild->setPosition(0, 0);
+ mFGSurfaceControl->setPosition(0, 0);
+ mFGSurfaceControl->setFinalCrop(Rect(0, 0, 5, 5));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ mCapture->expectChildColor(0, 0);
+ mCapture->expectChildColor(4, 4);
+ mCapture->expectBGColor(5, 5);
+ }
+}
+
TEST_F(ChildLayerTest, ChildLayerConstraints) {
SurfaceComposerClient::openGlobalTransaction();
mChild->show();