summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author chaviw <chaviw@google.com> 2021-04-08 14:26:24 -0500
committer chaviw <chaviw@google.com> 2021-04-08 18:15:36 -0500
commit39d0147e73adc27461ef74eb3a833cc184a05a6f (patch)
tree9809a2bc7f266d64a4081306c7952eac9f772f6c
parentb16fa8e49508388184bbf1efff2092a036a54aa6 (diff)
Modify bounds and transform for BSL input.
We don't want to send the BufferStateLayer's transform to input, but rather the parent's transform. This is because the current layer's transform is information about how the buffer is placed on screen. The parent's transform makes more sense to send since this is information about how the layer is placed on screen. This transform is used by input to determine how to go from screen space back to window space. Also update the bounds for BufferStateLayer that's used for input. We need to include the transform here since input assumes the frame already includes the buffer transform. Test: EndToEndNativeInputTest Test: Rotate and scroll content Fixes: 184807094 Change-Id: I59c1f32a57dff4f007202b5998fff55f4e125438
-rw-r--r--libs/gui/tests/EndToEndNativeInputTest.cpp104
-rw-r--r--services/surfaceflinger/BufferStateLayer.cpp30
-rw-r--r--services/surfaceflinger/BufferStateLayer.h2
-rw-r--r--services/surfaceflinger/Layer.cpp14
-rw-r--r--services/surfaceflinger/Layer.h3
5 files changed, 120 insertions, 33 deletions
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 59e5c13b0b..49c44a78d1 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -47,6 +47,8 @@
using android::os::IInputFlinger;
+using android::hardware::graphics::common::V1_1::BufferUsage;
+
namespace android::test {
using Transaction = SurfaceComposerClient::Transaction;
@@ -95,15 +97,6 @@ public:
return std::make_unique<InputSurface>(surfaceControl, width, height);
}
- static std::unique_ptr<InputSurface> makeBlastInputSurface(const sp<SurfaceComposerClient> &scc,
- int width, int height) {
- sp<SurfaceControl> surfaceControl =
- scc->createSurface(String8("Test Buffer Surface"), width, height,
- PIXEL_FORMAT_RGBA_8888,
- ISurfaceComposerClient::eFXSurfaceBufferState);
- return std::make_unique<InputSurface>(surfaceControl, width, height);
- }
-
static std::unique_ptr<InputSurface> makeContainerInputSurface(
const sp<SurfaceComposerClient> &scc, int width, int height) {
sp<SurfaceControl> surfaceControl =
@@ -180,16 +173,19 @@ public:
EXPECT_EQ(flags, mev->getFlags() & flags);
}
- ~InputSurface() { mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken()); }
+ virtual ~InputSurface() {
+ mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
+ }
- void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
- const sp<SurfaceControl>&)> transactionBody) {
+ virtual void doTransaction(
+ std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
+ transactionBody) {
SurfaceComposerClient::Transaction t;
transactionBody(t, mSurfaceControl);
t.apply(true);
}
- void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
+ virtual void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
SurfaceComposerClient::Transaction t;
t.show(mSurfaceControl);
t.setInputWindowInfo(mSurfaceControl, mInputInfo);
@@ -259,6 +255,57 @@ public:
InputConsumer* mInputConsumer;
};
+class BlastInputSurface : public InputSurface {
+public:
+ BlastInputSurface(const sp<SurfaceControl> &sc, const sp<SurfaceControl> &parentSc, int width,
+ int height)
+ : InputSurface(sc, width, height) {
+ mParentSurfaceControl = parentSc;
+ }
+
+ ~BlastInputSurface() = default;
+
+ static std::unique_ptr<BlastInputSurface> makeBlastInputSurface(
+ const sp<SurfaceComposerClient> &scc, int width, int height) {
+ sp<SurfaceControl> parentSc =
+ scc->createSurface(String8("Test Parent Surface"), 0 /* bufHeight */,
+ 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceContainer);
+
+ sp<SurfaceControl> surfaceControl =
+ scc->createSurface(String8("Test Buffer Surface"), width, height,
+ PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceBufferState,
+ parentSc->getHandle());
+ return std::make_unique<BlastInputSurface>(surfaceControl, parentSc, width, height);
+ }
+
+ void doTransaction(
+ std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
+ transactionBody) override {
+ SurfaceComposerClient::Transaction t;
+ transactionBody(t, mParentSurfaceControl);
+ t.apply(true);
+ }
+
+ void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) override {
+ SurfaceComposerClient::Transaction t;
+ t.show(mParentSurfaceControl);
+ t.setLayer(mParentSurfaceControl, LAYER_BASE);
+ t.setPosition(mParentSurfaceControl, x, y);
+ t.setCrop(mParentSurfaceControl, crop);
+
+ t.show(mSurfaceControl);
+ t.setInputWindowInfo(mSurfaceControl, mInputInfo);
+ t.setCrop(mSurfaceControl, crop);
+ t.setAlpha(mSurfaceControl, 1);
+ t.apply(true);
+ }
+
+private:
+ sp<SurfaceControl> mParentSurfaceControl;
+};
+
class InputSurfacesTest : public ::testing::Test {
public:
InputSurfacesTest() {
@@ -289,15 +336,12 @@ public:
return InputSurface::makeColorInputSurface(mComposerClient, width, height);
}
- void postBuffer(const sp<SurfaceControl> &layer) {
- // wait for previous transactions (such as setSize) to complete
- Transaction().apply(true);
- ANativeWindow_Buffer buffer = {};
- EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
- ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
- // Request an empty transaction to get applied synchronously to ensure the buffer is
- // latched.
- Transaction().apply(true);
+ void postBuffer(const sp<SurfaceControl> &layer, int32_t w, int32_t h) {
+ int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+ BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE;
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test");
+ Transaction().setBuffer(layer, buffer).apply(true);
usleep(mBufferPostDelay);
}
@@ -474,8 +518,8 @@ TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
// Original bug ref: b/120839715
TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
- std::unique_ptr<InputSurface> bufferSurface =
- InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
+ std::unique_ptr<BlastInputSurface> bufferSurface =
+ BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
bgSurface->showAt(10, 10);
bufferSurface->showAt(10, 10);
@@ -483,16 +527,16 @@ TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
injectTap(11, 11);
bufferSurface->expectTap(1, 1);
- postBuffer(bufferSurface->mSurfaceControl);
+ postBuffer(bufferSurface->mSurfaceControl, 100, 100);
injectTap(11, 11);
bufferSurface->expectTap(1, 1);
}
TEST_F(InputSurfacesTest, input_ignores_buffer_layer_alpha) {
std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
- std::unique_ptr<InputSurface> bufferSurface =
- InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
- postBuffer(bufferSurface->mSurfaceControl);
+ std::unique_ptr<BlastInputSurface> bufferSurface =
+ BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
+ postBuffer(bufferSurface->mSurfaceControl, 100, 100);
bgSurface->showAt(10, 10);
bufferSurface->showAt(10, 10);
@@ -720,8 +764,8 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
- std::unique_ptr<InputSurface> bufferSurface =
- InputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
+ std::unique_ptr<BlastInputSurface> bufferSurface =
+ BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
bufferSurface->mInputInfo.ownerUid = 22222;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 09e3cd969c..ed826a0100 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -903,6 +903,36 @@ void BufferStateLayer::bufferMayChange(sp<GraphicBuffer>& newBuffer) {
}
}
+/*
+ * We don't want to send the layer's transform to input, but rather the
+ * parent's transform. This is because BufferStateLayer's transform is
+ * information about how the buffer is placed on screen. The parent's
+ * transform makes more sense to send since it's information about how the
+ * layer is placed on screen. This transform is used by input to determine
+ * how to go from screen space back to window space.
+ */
+ui::Transform BufferStateLayer::getInputTransform() const {
+ sp<Layer> parent = mDrawingParent.promote();
+ if (parent == nullptr) {
+ return ui::Transform();
+ }
+
+ return parent->getTransform();
+}
+
+/**
+ * Similar to getInputTransform, we need to update the bounds to include the transform.
+ * This is because bounds for BSL doesn't include buffer transform, where the input assumes
+ * that's already included.
+ */
+Rect BufferStateLayer::getInputBounds() const {
+ Rect bufferBounds = getCroppedBufferSize(getDrawingState());
+ if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) {
+ return bufferBounds;
+ }
+ return mDrawingState.transform.transform(bufferBounds);
+}
+
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index af2819eac7..8ce3e1f55b 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -118,6 +118,8 @@ protected:
void gatherBufferInfo() override;
uint64_t getHeadFrameNumber(nsecs_t expectedPresentTime) const;
void onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame);
+ ui::Transform getInputTransform() const override;
+ Rect getInputBounds() const override;
private:
friend class SlotGenerationTest;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2fcd8215eb..80d2ea849f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2535,14 +2535,22 @@ bool Layer::isRemovedFromCurrentState() const {
return mRemovedFromCurrentState;
}
+ui::Transform Layer::getInputTransform() const {
+ return getTransform();
+}
+
+Rect Layer::getInputBounds() const {
+ return getCroppedBufferSize(getDrawingState());
+}
+
void Layer::fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay) {
// Transform layer size to screen space and inset it by surface insets.
// If this is a portal window, set the touchableRegion to the layerBounds.
Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE
- ? getBufferSize(getDrawingState())
+ ? getInputBounds()
: info.touchableRegion.getBounds();
if (!layerBounds.isValid()) {
- layerBounds = getCroppedBufferSize(getDrawingState());
+ layerBounds = getInputBounds();
}
if (!layerBounds.isValid()) {
@@ -2555,7 +2563,7 @@ void Layer::fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhy
return;
}
- ui::Transform layerToDisplay = getTransform();
+ ui::Transform layerToDisplay = getInputTransform();
// Transform that takes window coordinates to unrotated display coordinates
ui::Transform t = toPhysicalDisplay * layerToDisplay;
int32_t xSurfaceInset = info.surfaceInset;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 4a105ebeda..f900968b3e 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1025,6 +1025,9 @@ protected:
compositionengine::OutputLayer* findOutputLayerForDisplay(const DisplayDevice*) const;
bool usingRelativeZ(LayerVector::StateSet) const;
+ virtual ui::Transform getInputTransform() const;
+ virtual Rect getInputBounds() const;
+
// SyncPoints which will be signaled when the correct frame is at the head
// of the queue and dropped after the frame has been latched. Protected by
// mLocalSyncPointMutex.