diff options
| author | 2021-04-09 04:56:29 +0000 | |
|---|---|---|
| committer | 2021-04-09 04:56:29 +0000 | |
| commit | b759882ccd14a3fa0138f22004349c4e08ff6f2d (patch) | |
| tree | cc69342a308901dbfc90c945d4e3416284592424 | |
| parent | cb1d05d099fc0c991b2f2470e451ff1a3ccc7bd1 (diff) | |
| parent | 39d0147e73adc27461ef74eb3a833cc184a05a6f (diff) | |
Merge "Modify bounds and transform for BSL input." into sc-dev
| -rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 104 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 30 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 14 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 3 |
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. |