// Fill an RGBA_8888 formatted surface with a single color.
static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc,
- uint8_t r, uint8_t g, uint8_t b) {
+ uint8_t r, uint8_t g, uint8_t b, bool unlock=true) {
ANativeWindow_Buffer outBuffer;
sp<Surface> s = sc->getSurface();
ASSERT_TRUE(s != NULL);
pixel[3] = 255;
}
}
- ASSERT_EQ(NO_ERROR, s->unlockAndPost());
+ if (unlock) {
+ ASSERT_EQ(NO_ERROR, s->unlockAndPost());
+ }
}
// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check
sc->expectFGColor(127, 127);
sc->expectBGColor(128, 128);
}
+
+ void lockAndFillFGBuffer() {
+ fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
+ }
+
+ void unlockFGBuffer() {
+ sp<Surface> s = mFGSurfaceControl->getSurface();
+ ASSERT_EQ(NO_ERROR, s->unlockAndPost());
+ waitForPostedBuffers();
+ }
+
void completeFGResize() {
fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
waitForPostedBuffers();
EXPECT_CROPPED_STATE("after the resize finishes");
}
+// In this test we ensure that setGeometryAppliesWithResize actually demands
+// a buffer of the new size, and not just any size.
+TEST_F(CropLatchingTest, FinalCropLatchingBufferOldSize) {
+ EXPECT_INITIAL_STATE("before anything");
+ // Normally the crop applies immediately even while a resize is pending.
+ SurfaceComposerClient::openGlobalTransaction();
+ mFGSurfaceControl->setSize(128, 128);
+ mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ EXPECT_CROPPED_STATE("after setting crop (without geometryAppliesWithResize)");
+
+ restoreInitialState();
+
+ // In order to prepare to submit a buffer at the wrong size, we acquire it prior to
+ // initiating the resize.
+ lockAndFillFGBuffer();
+
+ SurfaceComposerClient::openGlobalTransaction();
+ mFGSurfaceControl->setSize(128, 128);
+ mFGSurfaceControl->setGeometryAppliesWithResize();
+ mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ EXPECT_INITIAL_STATE("after setting crop (with geometryAppliesWithResize)");
+
+ // We now submit our old buffer, at the old size, and ensure it doesn't
+ // trigger geometry latching.
+ unlockFGBuffer();
+
+ EXPECT_INITIAL_STATE("after unlocking FG buffer (with geometryAppliesWithResize)");
+
+ completeFGResize();
+
+ EXPECT_CROPPED_STATE("after the resize finishes");
+}
+
+TEST_F(CropLatchingTest, FinalCropLatchingRegressionForb37531386) {
+ EXPECT_INITIAL_STATE("before anything");
+ // In this scenario, we attempt to set the final crop a second time while the resize
+ // is still pending, and ensure we are successful. Success meaning the second crop
+ // is the one which eventually latches and not the first.
+ SurfaceComposerClient::openGlobalTransaction();
+ mFGSurfaceControl->setSize(128, 128);
+ mFGSurfaceControl->setGeometryAppliesWithResize();
+ mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ SurfaceComposerClient::openGlobalTransaction();
+ mFGSurfaceControl->setFinalCrop(Rect(0, 0, -1, -1));
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ EXPECT_INITIAL_STATE("after setting crops with geometryAppliesWithResize");
+
+ completeFGResize();
+
+ EXPECT_INITIAL_STATE("after the resize finishes");
+}
+
TEST_F(LayerUpdateTest, DeferredTransactionTest) {
sp<ScreenCapture> sc;
{