From 0617894190ea0c3ee50889bee1d4df0f369b0761 Mon Sep 17 00:00:00 2001 From: chaviw Date: Thu, 27 Jul 2017 10:25:59 -0700 Subject: Add a re-parent function to re-parent a specific child. This is similar to reparentChildren, but the reparentChild will only re-parent a specific child to the new parent and not all children. Test: Added test in Transaction_test for reparentChild. Change-Id: I4275e0d5f1d5601b489956753c78a56d1a5d4c1c --- libs/gui/LayerState.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 9b06e63610..573f6856d6 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -45,6 +45,8 @@ status_t layer_state_t::write(Parcel& output) const output.writeInt32(overrideScalingMode); output.writeStrongBinder(IInterface::asBinder(barrierGbp)); output.writeStrongBinder(relativeLayerHandle); + output.writeStrongBinder(parentHandleForChild); + output.writeStrongBinder(childHandle); output.write(transparentRegion); return NO_ERROR; } @@ -77,6 +79,8 @@ status_t layer_state_t::read(const Parcel& input) barrierGbp = interface_cast(input.readStrongBinder()); relativeLayerHandle = input.readStrongBinder(); + parentHandleForChild = input.readStrongBinder(); + childHandle = input.readStrongBinder(); input.read(transparentRegion); return NO_ERROR; } -- cgit v1.2.3-59-g8ed1b From f1961f713de2b3f54c8ce7653964b969e1a02bc8 Mon Sep 17 00:00:00 2001 From: chaviw Date: Mon, 18 Sep 2017 16:41:07 -0700 Subject: Re-parent invoked on child instead of on parent. The function to re-parent an individual child is now invoked on the child instead of the parent. This ensures the child ends up with the last parent set if multiple reparent requests are made in the same transaction. This also allows adding a parent to a layer that didn't have one previously. Test: Transaction_test -> Reparent, ReparentToNoParent, ReparentFromNoParent Change-Id: Idab429eb2dca5a4ae1b020a5a7629d719dd4d995 --- libs/gui/LayerState.cpp | 2 - libs/gui/SurfaceComposerClient.cpp | 19 +++--- libs/gui/SurfaceControl.cpp | 5 +- libs/gui/include/gui/SurfaceComposerClient.h | 3 +- libs/gui/include/gui/SurfaceControl.h | 7 +-- libs/gui/include/private/gui/LayerState.h | 3 +- services/surfaceflinger/Layer.cpp | 28 +++------ services/surfaceflinger/Layer.h | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 6 +- services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 6 +- services/surfaceflinger/tests/Transaction_test.cpp | 67 +++++++++++++++++++++- 11 files changed, 94 insertions(+), 54 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 573f6856d6..3418a4983e 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -46,7 +46,6 @@ status_t layer_state_t::write(Parcel& output) const output.writeStrongBinder(IInterface::asBinder(barrierGbp)); output.writeStrongBinder(relativeLayerHandle); output.writeStrongBinder(parentHandleForChild); - output.writeStrongBinder(childHandle); output.write(transparentRegion); return NO_ERROR; } @@ -80,7 +79,6 @@ status_t layer_state_t::read(const Parcel& input) interface_cast(input.readStrongBinder()); relativeLayerHandle = input.readStrongBinder(); parentHandleForChild = input.readStrongBinder(); - childHandle = input.readStrongBinder(); input.read(transparentRegion); return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index b0ae7e0bdf..be7b1d2f6a 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -176,9 +176,8 @@ public: status_t reparentChildren(const sp& client, const sp& id, const sp& newParentHandle); - status_t reparentChild(const sp& client, - const sp& id, const sp& newParentHandle, - const sp& childHandle); + status_t reparent(const sp& client, + const sp& id, const sp& newParentHandle); status_t detachChildren(const sp& client, const sp& id); status_t setOverrideScalingMode(const sp& client, @@ -496,18 +495,16 @@ status_t Composer::reparentChildren( return NO_ERROR; } -status_t Composer::reparentChild(const sp& client, +status_t Composer::reparent(const sp& client, const sp& id, - const sp& newParentHandle, - const sp& childHandle) { + const sp& newParentHandle) { Mutex::Autolock lock(mLock); layer_state_t* s = getLayerStateLocked(client, id); if (!s) { return BAD_INDEX; } - s->what |= layer_state_t::eReparentChild; + s->what |= layer_state_t::eReparent; s->parentHandleForChild = newParentHandle; - s->childHandle = childHandle; return NO_ERROR; } @@ -849,9 +846,9 @@ status_t SurfaceComposerClient::reparentChildren(const sp& id, return getComposer().reparentChildren(this, id, newParentHandle); } -status_t SurfaceComposerClient::reparentChild(const sp& id, - const sp& newParentHandle, const sp& childHandle) { - return getComposer().reparentChild(this, id, newParentHandle, childHandle); +status_t SurfaceComposerClient::reparent(const sp& id, + const sp& newParentHandle) { + return getComposer().reparent(this, id, newParentHandle); } status_t SurfaceComposerClient::detachChildren(const sp& id) { diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index b9c5ef9580..d801d12738 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -191,11 +191,10 @@ status_t SurfaceControl::reparentChildren(const sp& newParentHandle) { return mClient->reparentChildren(mHandle, newParentHandle); } -status_t SurfaceControl::reparentChild(const sp& newParentHandle, - const sp& childHandle) { +status_t SurfaceControl::reparent(const sp& newParentHandle) { status_t err = validate(); if (err < 0) return err; - return mClient->reparentChild(mHandle, newParentHandle, childHandle); + return mClient->reparent(mHandle, newParentHandle); } status_t SurfaceControl::detachChildren() { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 6e2cb83544..cf2ff5b96e 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -161,8 +161,7 @@ public: const sp& handle, uint64_t frameNumber); status_t reparentChildren(const sp& id, const sp& newParentHandle); - status_t reparentChild(const sp& id, const sp& newParentHandle, - const sp& childHandle); + status_t reparent(const sp& id, const sp& newParentHandle); status_t detachChildren(const sp& id); status_t setOverrideScalingMode(const sp& id, int32_t overrideScalingMode); diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index d8b67ef96a..b506e00672 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -124,11 +124,10 @@ public: // Reparents all children of this layer to the new parent handle. status_t reparentChildren(const sp& newParentHandle); - // Reparents a specified child from this layer to the new parent handle. - // The child, parent, and new parent must all have the same client. + // Reparents the current layer to the new parent handle. The new parent must not be null. // This can be used instead of reparentChildren if the caller wants to - // only re-parent specific children. - status_t reparentChild(const sp& newParentHandle, const sp& childHandle); + // only re-parent a specific child. + status_t reparent(const sp& newParentHandle); // Detaches all child surfaces (and their children recursively) // from their SurfaceControl. diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h index 4f73e04e22..4ff2e5e0d6 100644 --- a/libs/gui/include/private/gui/LayerState.h +++ b/libs/gui/include/private/gui/LayerState.h @@ -60,7 +60,7 @@ struct layer_state_t { eReparentChildren = 0x00002000, eDetachChildren = 0x00004000, eRelativeLayerChanged = 0x00008000, - eReparentChild = 0x00010000 + eReparent = 0x00010000 }; layer_state_t() @@ -109,7 +109,6 @@ struct layer_state_t { sp relativeLayerHandle; sp parentHandleForChild; - sp childHandle; // non POD must be last. see write/read Region transparentRegion; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 9435a187d9..fd30e1614b 100755 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2625,8 +2625,8 @@ bool Layer::reparentChildren(const sp& newParentHandle) { return true; } -bool Layer::reparentChild(const sp& newParentHandle, const sp& childHandle) { - if (newParentHandle == nullptr || childHandle == nullptr) { +bool Layer::reparent(const sp& newParentHandle) { + if (newParentHandle == nullptr) { return false; } @@ -2637,29 +2637,19 @@ bool Layer::reparentChild(const sp& newParentHandle, const sp& return false; } - handle = static_cast(childHandle.get()); - sp child = handle->owner.promote(); - if (child == nullptr) { - ALOGE("Unable to promote child Layer handle"); - return false; - } - - if (mCurrentChildren.indexOf(child) < 0) { - ALOGE("Child layer is not child of current layer"); - return false; + sp parent = getParent(); + if (parent != nullptr) { + parent->removeChild(this); } + newParent->addChild(this); - sp parentClient(mClientRef.promote()); - sp childClient(child->mClientRef.promote()); + sp client(mClientRef.promote()); sp newParentClient(newParent->mClientRef.promote()); - if (parentClient != childClient || childClient != newParentClient) { - ALOGE("Current layer, child layer, and new parent layer must have the same client"); - return false; + if (client != newParentClient) { + client->setParentLayer(newParent); } - newParent->addChild(child); - mCurrentChildren.remove(child); return true; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index f94833b32f..e7ece4579e 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -241,7 +241,7 @@ public: bool setOverrideScalingMode(int32_t overrideScalingMode); void setInfo(uint32_t type, uint32_t appId); bool reparentChildren(const sp& layer); - bool reparentChild(const sp& newParentHandle, const sp& childHandle); + bool reparent(const sp& newParentHandle); bool detachChildren(); // If we have received a new buffer this frame, we will pass its surface diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index cae4deacb0..6ee14fe72a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3121,10 +3121,8 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } - // Always re-parent the children that explicitly requested to get - // re-parented before the general re-parent of all children. - if (what & layer_state_t::eReparentChild) { - if (layer->reparentChild(s.parentHandleForChild, s.childHandle)) { + if (what & layer_state_t::eReparent) { + if (layer->reparent(s.parentHandleForChild)) { flags |= eTransactionNeeded|eTraversalNeeded; } } diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index 71aa52dee6..1cf6ce33b7 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -2679,10 +2679,8 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } - // Always re-parent the children that explicitly requested to get - // re-parented before the general re-parent of all children. - if (what & layer_state_t::eReparentChild) { - if (layer->reparentChild(s.parentHandleForChild, s.childHandle)) { + if (what & layer_state_t::eReparent) { + if (layer->reparent(s.parentHandleForChild)) { flags |= eTransactionNeeded|eTraversalNeeded; } } diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index dea6503e4e..21194926da 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -1169,7 +1169,7 @@ TEST_F(ChildLayerTest, Bug36858924) { fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0); } -TEST_F(ChildLayerTest, ReparentChild) { +TEST_F(ChildLayerTest, Reparent) { SurfaceComposerClient::openGlobalTransaction(); mChild->show(); mChild->setPosition(10, 10); @@ -1185,7 +1185,7 @@ TEST_F(ChildLayerTest, ReparentChild) { // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } - mFGSurfaceControl->reparentChild(mBGSurfaceControl->getHandle(), mChild->getHandle()); + mChild->reparent(mBGSurfaceControl->getHandle()); { ScreenCapture::captureScreen(&mCapture); mCapture->expectFGColor(64, 64); @@ -1198,6 +1198,69 @@ TEST_F(ChildLayerTest, ReparentChild) { } } +TEST_F(ChildLayerTest, ReparentToNoParent) { + SurfaceComposerClient::openGlobalTransaction(); + mChild->show(); + mChild->setPosition(10, 10); + mFGSurfaceControl->setPosition(64, 64); + SurfaceComposerClient::closeGlobalTransaction(true); + + { + ScreenCapture::captureScreen(&mCapture); + // Top left of foreground must now be visible + mCapture->expectFGColor(64, 64); + // But 10 pixels in we should see the child surface + mCapture->expectChildColor(74, 74); + // And 10 more pixels we should be back to the foreground surface + mCapture->expectFGColor(84, 84); + } + mChild->reparent(nullptr); + { + ScreenCapture::captureScreen(&mCapture); + // Nothing should have changed. + mCapture->expectFGColor(64, 64); + mCapture->expectChildColor(74, 74); + mCapture->expectFGColor(84, 84); + } +} + +TEST_F(ChildLayerTest, ReparentFromNoParent) { + sp newSurface = mComposerClient->createSurface( + String8("New Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0); + ASSERT_TRUE(newSurface != NULL); + ASSERT_TRUE(newSurface->isValid()); + + fillSurfaceRGBA8(newSurface, 63, 195, 63); + SurfaceComposerClient::openGlobalTransaction(); + mChild->hide(); + newSurface->show(); + newSurface->setPosition(10, 10); + newSurface->setLayer(INT32_MAX-2); + mFGSurfaceControl->setPosition(64, 64); + SurfaceComposerClient::closeGlobalTransaction(true); + + { + ScreenCapture::captureScreen(&mCapture); + // Top left of foreground must now be visible + mCapture->expectFGColor(64, 64); + // At 10, 10 we should see the new surface + mCapture->checkPixel(10, 10, 63, 195, 63); + } + + SurfaceComposerClient::openGlobalTransaction(); + newSurface->reparent(mFGSurfaceControl->getHandle()); + SurfaceComposerClient::closeGlobalTransaction(true); + + { + ScreenCapture::captureScreen(&mCapture); + // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from + // mFGSurface, putting it at 74, 74. + mCapture->expectFGColor(64, 64); + mCapture->checkPixel(74, 74, 63, 195, 63); + mCapture->expectFGColor(84, 84); + } +} + TEST_F(ChildLayerTest, NestedChildren) { sp grandchild = mComposerClient->createSurface( String8("Grandchild surface"), -- cgit v1.2.3-59-g8ed1b From 13fdc49516d17f41e64e62e73c313b0928bf13cc Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 27 Jun 2017 12:40:18 -0700 Subject: Added native functionality to create a color layer. Added a new layer that can draw a specified color and specified alpha. This will replace creating a dim layer and allow any colors, not just black, to be set for this layer. Test: Added tests to Transaction_test.cpp to test with a color and a color layer with alpha. Change-Id: I00a38d1bbc01093026f088c3347454281bdc2b8c --- libs/gui/LayerDebugInfo.cpp | 20 ++++- libs/gui/LayerState.cpp | 6 ++ libs/gui/SurfaceComposerClient.cpp | 17 ++++ libs/gui/SurfaceControl.cpp | 5 ++ libs/gui/include/gui/ISurfaceComposerClient.h | 2 +- libs/gui/include/gui/LayerDebugInfo.h | 3 +- libs/gui/include/gui/SurfaceComposerClient.h | 2 + libs/gui/include/gui/SurfaceControl.h | 2 + libs/gui/include/private/gui/LayerState.h | 6 +- services/surfaceflinger/Android.mk | 2 +- services/surfaceflinger/ColorLayer.cpp | 66 +++++++++++++++ services/surfaceflinger/ColorLayer.h | 49 +++++++++++ services/surfaceflinger/Layer.cpp | 75 ++++++++--------- services/surfaceflinger/Layer.h | 24 ++---- services/surfaceflinger/LayerDim.cpp | 68 ---------------- services/surfaceflinger/LayerDim.h | 49 ----------- .../surfaceflinger/RenderEngine/Description.cpp | 14 +--- services/surfaceflinger/RenderEngine/Description.h | 9 +-- .../RenderEngine/GLES20RenderEngine.cpp | 50 ++---------- .../RenderEngine/GLES20RenderEngine.h | 9 +-- services/surfaceflinger/RenderEngine/Program.cpp | 8 +- services/surfaceflinger/RenderEngine/Program.h | 3 - .../surfaceflinger/RenderEngine/ProgramCache.cpp | 25 +++--- .../surfaceflinger/RenderEngine/ProgramCache.h | 10 +-- .../surfaceflinger/RenderEngine/RenderEngine.h | 8 +- services/surfaceflinger/SurfaceFlinger.cpp | 18 +++-- services/surfaceflinger/SurfaceFlinger.h | 4 +- services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 25 +++--- services/surfaceflinger/SurfaceInterceptor.cpp | 2 +- .../tests/SurfaceFlinger_test.filter | 2 +- services/surfaceflinger/tests/Transaction_test.cpp | 94 ++++++++++++++++++++++ 31 files changed, 381 insertions(+), 296 deletions(-) create mode 100644 services/surfaceflinger/ColorLayer.cpp create mode 100644 services/surfaceflinger/ColorLayer.h delete mode 100644 services/surfaceflinger/LayerDim.cpp delete mode 100644 services/surfaceflinger/LayerDim.h (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp index 57ddde075a..d3dc16d30e 100644 --- a/libs/gui/LayerDebugInfo.cpp +++ b/libs/gui/LayerDebugInfo.cpp @@ -43,7 +43,10 @@ status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const { RETURN_ON_ERROR(parcel->writeInt32(mHeight)); RETURN_ON_ERROR(parcel->write(mCrop)); RETURN_ON_ERROR(parcel->write(mFinalCrop)); - RETURN_ON_ERROR(parcel->writeFloat(mAlpha)); + RETURN_ON_ERROR(parcel->writeFloat(mColor.r)); + RETURN_ON_ERROR(parcel->writeFloat(mColor.g)); + RETURN_ON_ERROR(parcel->writeFloat(mColor.b)); + RETURN_ON_ERROR(parcel->writeFloat(mColor.a)); RETURN_ON_ERROR(parcel->writeUint32(mFlags)); RETURN_ON_ERROR(parcel->writeInt32(mPixelFormat)); RETURN_ON_ERROR(parcel->writeUint32(static_cast(mDataSpace))); @@ -79,7 +82,14 @@ status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) { RETURN_ON_ERROR(parcel->readInt32(&mHeight)); RETURN_ON_ERROR(parcel->read(mCrop)); RETURN_ON_ERROR(parcel->read(mFinalCrop)); - RETURN_ON_ERROR(parcel->readFloat(&mAlpha)); + mColor.r = parcel->readFloat(); + RETURN_ON_ERROR(parcel->errorCheck()); + mColor.g = parcel->readFloat(); + RETURN_ON_ERROR(parcel->errorCheck()); + mColor.b = parcel->readFloat(); + RETURN_ON_ERROR(parcel->errorCheck()); + mColor.a = parcel->readFloat(); + RETURN_ON_ERROR(parcel->errorCheck()); RETURN_ON_ERROR(parcel->readUint32(&mFlags)); RETURN_ON_ERROR(parcel->readInt32(&mPixelFormat)); // \todo [2017-07-25 kraita]: Static casting mDataSpace pointer to an uint32 does work. Better ways? @@ -116,8 +126,10 @@ std::string to_string(const LayerDebugInfo& info) { result.appendFormat("isOpaque=%1d, invalidate=%1d, ", info.mIsOpaque, info.mContentDirty); result.appendFormat("dataspace=%s, ", dataspaceDetails(info.mDataSpace).c_str()); result.appendFormat("pixelformat=%s, ", decodePixelFormat(info.mPixelFormat).c_str()); - result.appendFormat("alpha=%.3f, flags=0x%08x, ", - static_cast(info.mAlpha), info.mFlags); + result.appendFormat("color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ", + static_cast(info.mColor.r), static_cast(info.mColor.g), + static_cast(info.mColor.b), static_cast(info.mColor.a), + info.mFlags); result.appendFormat("tr=[%.2f, %.2f][%.2f, %.2f]", static_cast(info.mMatrix[0][0]), static_cast(info.mMatrix[0][1]), static_cast(info.mMatrix[1][0]), static_cast(info.mMatrix[1][1])); diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 3418a4983e..fcee73f445 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -46,6 +46,9 @@ status_t layer_state_t::write(Parcel& output) const output.writeStrongBinder(IInterface::asBinder(barrierGbp)); output.writeStrongBinder(relativeLayerHandle); output.writeStrongBinder(parentHandleForChild); + output.writeFloat(color.r); + output.writeFloat(color.g); + output.writeFloat(color.b); output.write(transparentRegion); return NO_ERROR; } @@ -79,6 +82,9 @@ status_t layer_state_t::read(const Parcel& input) interface_cast(input.readStrongBinder()); relativeLayerHandle = input.readStrongBinder(); parentHandleForChild = input.readStrongBinder(); + color.r = input.readFloat(); + color.g = input.readFloat(); + color.b = input.readFloat(); input.read(transparentRegion); return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index be7b1d2f6a..c5a4389ae8 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -158,6 +158,8 @@ public: const Region& transparentRegion); status_t setAlpha(const sp& client, const sp& id, float alpha); + status_t setColor(const sp& client, const sp& id, + const half3& color); status_t setMatrix(const sp& client, const sp& id, float dsdx, float dtdx, float dtdy, float dsdy); status_t setOrientation(int orientation); @@ -402,6 +404,17 @@ status_t Composer::setAlpha(const sp& client, return NO_ERROR; } +status_t Composer::setColor(const sp& client, + const sp& id, const half3& color) { + Mutex::Autolock _l(mLock); + layer_state_t* s = getLayerStateLocked(client, id); + if (!s) + return BAD_INDEX; + s->what |= layer_state_t::eColorChanged; + s->color = color; + return NO_ERROR; +} + status_t Composer::setLayerStack(const sp& client, const sp& id, uint32_t layerStack) { Mutex::Autolock _l(mLock); @@ -822,6 +835,10 @@ status_t SurfaceComposerClient::setAlpha(const sp& id, float alpha) { return getComposer().setAlpha(this, id, alpha); } +status_t SurfaceComposerClient::setColor(const sp& id, const half3& color) { + return getComposer().setColor(this, id, color); +} + status_t SurfaceComposerClient::setLayerStack(const sp& id, uint32_t layerStack) { return getComposer().setLayerStack(this, id, layerStack); } diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index d801d12738..9e1d7b6647 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -155,6 +155,11 @@ status_t SurfaceControl::setAlpha(float alpha) { if (err < 0) return err; return mClient->setAlpha(mHandle, alpha); } +status_t SurfaceControl::setColor(const half3& color) { + status_t err = validate(); + if (err < 0) return err; + return mClient->setColor(mHandle, color); +} status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) { status_t err = validate(); if (err < 0) return err; diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h index 2c613ea8c5..d5bbef25f8 100644 --- a/libs/gui/include/gui/ISurfaceComposerClient.h +++ b/libs/gui/include/gui/ISurfaceComposerClient.h @@ -41,7 +41,7 @@ public: eCursorWindow = 0x00002000, eFXSurfaceNormal = 0x00000000, - eFXSurfaceDim = 0x00020000, + eFXSurfaceColor = 0x00020000, eFXSurfaceMask = 0x000F0000, }; diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h index 8453e043ef..92bd8c5b28 100644 --- a/libs/gui/include/gui/LayerDebugInfo.h +++ b/libs/gui/include/gui/LayerDebugInfo.h @@ -22,6 +22,7 @@ #include #include +#include namespace android { @@ -52,7 +53,7 @@ public: int32_t mHeight = -1; Rect mCrop = Rect::INVALID_RECT; Rect mFinalCrop = Rect::INVALID_RECT; - float mAlpha = 0.f; + half4 mColor = half4(1.0_hf, 1.0_hf, 1.0_hf, 0.0_hf); uint32_t mFlags = 0; PixelFormat mPixelFormat = PIXEL_FORMAT_NONE; android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index cf2ff5b96e..17181430c7 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -32,6 +32,7 @@ #include #include +#include namespace android { @@ -149,6 +150,7 @@ public: status_t setRelativeLayer(const sp& id, const sp& relativeTo, int32_t layer); status_t setAlpha(const sp& id, float alpha=1.0f); + status_t setColor(const sp& id, const half3& color); status_t setMatrix(const sp& id, float dsdx, float dtdx, float dtdy, float dsdy); status_t setPosition(const sp& id, float x, float y); status_t setSize(const sp& id, uint32_t w, uint32_t h); diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index b506e00672..e98e26a391 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -29,6 +29,7 @@ #include #include +#include namespace android { @@ -90,6 +91,7 @@ public: status_t setFlags(uint32_t flags, uint32_t mask); status_t setTransparentRegionHint(const Region& transparent); status_t setAlpha(float alpha=1.0f); + status_t setColor(const half3& color); // Experimentarily it appears that the matrix transforms the // on-screen rectangle and it's contents before the position is diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h index 4ff2e5e0d6..bd42634730 100644 --- a/libs/gui/include/private/gui/LayerState.h +++ b/libs/gui/include/private/gui/LayerState.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace android { @@ -60,7 +61,8 @@ struct layer_state_t { eReparentChildren = 0x00002000, eDetachChildren = 0x00004000, eRelativeLayerChanged = 0x00008000, - eReparent = 0x00010000 + eReparent = 0x00010000, + eColorChanged = 0x00020000 }; layer_state_t() @@ -110,6 +112,8 @@ struct layer_state_t { sp parentHandleForChild; + half3 color; + // non POD must be last. see write/read Region transparentRegion; }; diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 38529b6d0a..1f4427a11a 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -14,7 +14,7 @@ LOCAL_SRC_FILES := \ FrameTracker.cpp \ GpuService.cpp \ Layer.cpp \ - LayerDim.cpp \ + ColorLayer.cpp \ LayerRejecter.cpp \ LayerVector.cpp \ MessageQueue.cpp \ diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp new file mode 100644 index 0000000000..6923782b27 --- /dev/null +++ b/services/surfaceflinger/ColorLayer.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// #define LOG_NDEBUG 0 +#undef LOG_TAG +#define LOG_TAG "ColorLayer" + +#include +#include +#include + +#include +#include + +#include + +#include "ColorLayer.h" +#include "SurfaceFlinger.h" +#include "DisplayDevice.h" +#include "RenderEngine/RenderEngine.h" + +namespace android { +// --------------------------------------------------------------------------- + +ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags) + : Layer(flinger, client, name, w, h, flags) { +} + +void ColorLayer::onDraw(const sp& hw, + const Region& /* clip */, bool useIdentityTransform) const +{ + const State& s(getDrawingState()); + if (s.color.a>0) { + Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2); + computeGeometry(hw, mesh, useIdentityTransform); + RenderEngine& engine(mFlinger->getRenderEngine()); + engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */, + true /* disableTexture */, s.color); + engine.drawMesh(mesh); + engine.disableBlending(); + } +} + +bool ColorLayer::isVisible() const { + const Layer::State& s(getDrawingState()); + return !isHiddenByPolicy() && s.color.a; +} + + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h new file mode 100644 index 0000000000..ac3e2a95dc --- /dev/null +++ b/services/surfaceflinger/ColorLayer.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_COLOR_LAYER_H +#define ANDROID_COLOR_LAYER_H + +#include +#include + +#include "Layer.h" + +// --------------------------------------------------------------------------- + +namespace android { + +class ColorLayer : public Layer +{ +public: + ColorLayer(SurfaceFlinger* flinger, const sp& client, + const String8& name, uint32_t w, uint32_t h, uint32_t flags); + virtual ~ColorLayer() = default; + + virtual const char* getTypeId() const { return "ColorLayer"; } + virtual void onDraw(const sp& hw, const Region& clip, + bool useIdentityTransform) const; + virtual bool isOpaque(const Layer::State&) const { return false; } + virtual bool isSecure() const { return false; } + virtual bool isFixedSize() const { return true; } + virtual bool isVisible() const; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_COLOR_LAYER_H diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index fd30e1614b..8734ee19fd 100755 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -137,11 +137,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, mCurrentState.requestedFinalCrop = mCurrentState.finalCrop; mCurrentState.requestedCrop = mCurrentState.crop; mCurrentState.z = 0; -#ifdef USE_HWC2 - mCurrentState.alpha = 1.0f; -#else - mCurrentState.alpha = 0xFF; -#endif + mCurrentState.color.a = 1.0f; mCurrentState.layerStack = 0; mCurrentState.flags = layerFlags; mCurrentState.sequence = 0; @@ -334,6 +330,10 @@ const String8& Layer::getName() const { return mName; } +bool Layer::getPremultipledAlpha() const { + return mPremultipliedAlpha; +} + status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { @@ -683,7 +683,7 @@ void Layer::setGeometry( " %s (%d)", mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(), static_cast(error)); #else - if (!isOpaque(s) || getAlpha() != 0xFF) { + if (!isOpaque(s) || getAlpha() != 1.0f) { layer.setBlending(mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE); @@ -757,7 +757,7 @@ void Layer::setGeometry( hwcInfo.sourceCrop = sourceCrop; } - float alpha = getAlpha(); + float alpha = static_cast(getAlpha()); error = hwcLayer->setPlaneAlpha(alpha); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: " "%s (%d)", mName.string(), alpha, to_string(error).c_str(), @@ -787,7 +787,7 @@ void Layer::setGeometry( const Transform& tr(hw->getTransform()); layer.setFrame(tr.transform(frame)); layer.setCrop(computeCrop(hw)); - layer.setPlaneAlpha(getAlpha()); + layer.setPlaneAlpha(static_cast(std::round(255.0f*getAlpha()))); #endif /* @@ -904,8 +904,11 @@ void Layer::setPerFrameData(const sp& displayDevice) { if (mActiveBuffer == nullptr) { setCompositionType(hwcId, HWC2::Composition::SolidColor); - // For now, we only support black for DimLayer - error = hwcLayer->setColor({0, 0, 0, 255}); + half4 color = getColor(); + error = hwcLayer->setColor({static_cast(std::round(255.0f*color.r)), + static_cast(std::round(255.0f * color.g)), + static_cast(std::round(255.0f * color.b)), + 255}); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), static_cast(error)); @@ -1254,7 +1257,8 @@ void Layer::drawWithOpenGL(const sp& hw, texCoords[3] = vec2(right, 1.0f - top); RenderEngine& engine(mFlinger->getRenderEngine()); - engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), getAlpha()); + engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), + false /* disableTexture */, getColor()); #ifdef USE_HWC2 engine.setSourceDataSpace(mCurrentState.dataSpace); #endif @@ -1877,19 +1881,30 @@ bool Layer::setSize(uint32_t w, uint32_t h) { setTransactionFlags(eTransactionNeeded); return true; } -#ifdef USE_HWC2 bool Layer::setAlpha(float alpha) { -#else -bool Layer::setAlpha(uint8_t alpha) { -#endif - if (mCurrentState.alpha == alpha) + if (mCurrentState.color.a == alpha) return false; mCurrentState.sequence++; - mCurrentState.alpha = alpha; + mCurrentState.color.a = alpha; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } + +bool Layer::setColor(const half3& color) { + if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g + && color.b == mCurrentState.color.b) + return false; + + mCurrentState.sequence++; + mCurrentState.color.r = color.r; + mCurrentState.color.g = color.g; + mCurrentState.color.b = color.b; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { mCurrentState.sequence++; mCurrentState.requested.transform.set( @@ -2141,13 +2156,8 @@ bool Layer::isHiddenByPolicy() const { } bool Layer::isVisible() const { -#ifdef USE_HWC2 return !(isHiddenByPolicy()) && getAlpha() > 0.0f && (mActiveBuffer != NULL || mSidebandStream != NULL); -#else - return !(isHiddenByPolicy()) && getAlpha() - && (mActiveBuffer != NULL || mSidebandStream != NULL); -#endif } bool Layer::allTransactionsSignaled() { @@ -2439,7 +2449,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mHeight = ds.active.h; info.mCrop = ds.crop; info.mFinalCrop = ds.finalCrop; - info.mAlpha = ds.alpha; + info.mColor = ds.color; info.mFlags = ds.flags; info.mPixelFormat = getPixelFormat(); info.mDataSpace = getDataSpace(); @@ -2467,7 +2477,6 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mContentDirty = contentDirty; return info; } - #ifdef USE_HWC2 void Layer::miniDumpHeader(String8& result) { result.append("----------------------------------------"); @@ -2791,23 +2800,17 @@ Transform Layer::getTransform() const { return t * getDrawingState().active.transform; } -#ifdef USE_HWC2 -float Layer::getAlpha() const { +half Layer::getAlpha() const { const auto& p = mDrawingParent.promote(); - float parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0; - return parentAlpha * getDrawingState().alpha; + half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf; + return parentAlpha * getDrawingState().color.a; } -#else -uint8_t Layer::getAlpha() const { - const auto& p = mDrawingParent.promote(); - float parentAlpha = (p != nullptr) ? (p->getAlpha() / 255.0f) : 1.0; - float drawingAlpha = getDrawingState().alpha / 255.0f; - drawingAlpha = drawingAlpha * parentAlpha; - return static_cast(std::round(drawingAlpha * 255)); +half4 Layer::getColor() const { + const half4 color(getDrawingState().color); + return half4(color.r, color.g, color.b, getAlpha()); } -#endif void Layer::commitChildList() { for (size_t i = 0; i < mCurrentChildren.size(); i++) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index e7ece4579e..921492b210 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -51,6 +51,8 @@ #include "RenderEngine/Mesh.h" #include "RenderEngine/Texture.h" +#include + namespace android { // --------------------------------------------------------------------------- @@ -119,11 +121,6 @@ public: // to achieve mirroring. uint32_t layerStack; -#ifdef USE_HWC2 - float alpha; -#else - uint8_t alpha; -#endif uint8_t flags; uint8_t mask; uint8_t reserved[2]; @@ -158,6 +155,8 @@ public: // A list of surfaces whose Z-order is interpreted relative to ours. SortedVector> zOrderRelatives; + + half4 color; }; // ----------------------------------------------------------------------- @@ -225,11 +224,8 @@ public: bool setLayer(int32_t z); bool setRelativeLayer(const sp& relativeToHandle, int32_t relativeZ); -#ifdef USE_HWC2 bool setAlpha(float alpha); -#else - bool setAlpha(uint8_t alpha); -#endif + bool setColor(const half3& color); bool setTransparentRegionHint(const Region& transparent); bool setFlags(uint8_t flags, uint8_t mask); bool setLayerStack(uint32_t layerStack); @@ -509,11 +505,8 @@ public: // Returns the Alpha of the Surface, accounting for the Alpha // of parent Surfaces in the hierarchy (alpha's will be multiplied // down the hierarchy). -#ifdef USE_HWC2 - float getAlpha() const; -#else - uint8_t getAlpha() const; -#endif + half getAlpha() const; + half4 getColor() const; void traverseInReverseZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor); @@ -683,9 +676,8 @@ public: sp getProducer() const; const String8& getName() const; void notifyAvailableFrames(); - PixelFormat getPixelFormat() const { return mFormat; } - + bool getPremultipledAlpha() const; private: // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp deleted file mode 100644 index daebf8abcd..0000000000 --- a/services/surfaceflinger/LayerDim.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// #define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "LayerDim" - -#include -#include -#include - -#include -#include - -#include - -#include "LayerDim.h" -#include "SurfaceFlinger.h" -#include "DisplayDevice.h" -#include "RenderEngine/RenderEngine.h" - -namespace android { -// --------------------------------------------------------------------------- - -LayerDim::LayerDim(SurfaceFlinger* flinger, const sp& client, - const String8& name, uint32_t w, uint32_t h, uint32_t flags) - : Layer(flinger, client, name, w, h, flags) { -} - -LayerDim::~LayerDim() { -} - -void LayerDim::onDraw(const sp& hw, - const Region& /* clip */, bool useIdentityTransform) const -{ - const State& s(getDrawingState()); - if (s.alpha>0) { - Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2); - computeGeometry(hw, mesh, useIdentityTransform); - RenderEngine& engine(mFlinger->getRenderEngine()); - engine.setupDimLayerBlending(s.alpha); - engine.drawMesh(mesh); - engine.disableBlending(); - } -} - -bool LayerDim::isVisible() const { - const Layer::State& s(getDrawingState()); - return !isHiddenByPolicy() && s.alpha; -} - - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h deleted file mode 100644 index a0cfca98cf..0000000000 --- a/services/surfaceflinger/LayerDim.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_LAYER_DIM_H -#define ANDROID_LAYER_DIM_H - -#include -#include - -#include "Layer.h" - -// --------------------------------------------------------------------------- - -namespace android { - -class LayerDim : public Layer -{ -public: - LayerDim(SurfaceFlinger* flinger, const sp& client, - const String8& name, uint32_t w, uint32_t h, uint32_t flags); - virtual ~LayerDim(); - - virtual const char* getTypeId() const { return "LayerDim"; } - virtual void onDraw(const sp& hw, const Region& clip, - bool useIdentityTransform) const; - virtual bool isOpaque(const Layer::State&) const { return false; } - virtual bool isSecure() const { return false; } - virtual bool isFixedSize() const { return true; } - virtual bool isVisible() const; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_DIM_H diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp index effd3191c8..706960cafe 100644 --- a/services/surfaceflinger/RenderEngine/Description.cpp +++ b/services/surfaceflinger/RenderEngine/Description.cpp @@ -27,22 +27,15 @@ namespace android { Description::Description() { - mPlaneAlpha = 1.0f; mPremultipliedAlpha = false; mOpaque = true; mTextureEnabled = false; mColorMatrixEnabled = false; - - memset(mColor, 0, sizeof(mColor)); } Description::~Description() { } -void Description::setPlaneAlpha(GLclampf planeAlpha) { - mPlaneAlpha = planeAlpha; -} - void Description::setPremultipliedAlpha(bool premultipliedAlpha) { mPremultipliedAlpha = premultipliedAlpha; } @@ -60,11 +53,8 @@ void Description::disableTexture() { mTextureEnabled = false; } -void Description::setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - mColor[0] = red; - mColor[1] = green; - mColor[2] = blue; - mColor[3] = alpha; +void Description::setColor(const half4& color) { + mColor = color; } void Description::setProjectionMatrix(const mat4& mtx) { diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h index 3beffdf9e1..cbac855ff3 100644 --- a/services/surfaceflinger/RenderEngine/Description.h +++ b/services/surfaceflinger/RenderEngine/Description.h @@ -35,8 +35,6 @@ class Description { friend class Program; friend class ProgramCache; - // value of the plane-alpha, between 0 and 1 - GLclampf mPlaneAlpha; // whether textures are premultiplied bool mPremultipliedAlpha; // whether this layer is marked as opaque @@ -46,8 +44,8 @@ class Description { Texture mTexture; bool mTextureEnabled; - // color used when texturing is disabled - GLclampf mColor[4]; + // color used when texturing is disabled or when setting alpha. + half4 mColor; // projection matrix mat4 mProjectionMatrix; @@ -60,12 +58,11 @@ public: Description(); ~Description(); - void setPlaneAlpha(GLclampf planeAlpha); void setPremultipliedAlpha(bool premultipliedAlpha); void setOpaque(bool opaque); void setTexture(const Texture& texture); void disableTexture(); - void setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void setColor(const half4& color); void setProjectionMatrix(const mat4& mtx); void setColorMatrix(const mat4& mtx); const mat4& getColorMatrix() const; diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 37a530b33a..daaa11e1d3 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -204,25 +204,17 @@ void GLES20RenderEngine::setViewportAndProjection( mVpHeight = vph; } -#ifdef USE_HWC2 void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha, - bool opaque, float alpha) { -#else -void GLES20RenderEngine::setupLayerBlending( - bool premultipliedAlpha, bool opaque, int alpha) { -#endif - + bool opaque, bool disableTexture, const half4& color) { mState.setPremultipliedAlpha(premultipliedAlpha); mState.setOpaque(opaque); -#ifdef USE_HWC2 - mState.setPlaneAlpha(alpha); + mState.setColor(color); - if (alpha < 1.0f || !opaque) { -#else - mState.setPlaneAlpha(alpha / 255.0f); + if (disableTexture) { + mState.disableTexture(); + } - if (alpha < 0xFF || !opaque) { -#endif + if (color.a < 1.0f || !opaque) { glEnable(GL_BLEND); glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { @@ -230,33 +222,6 @@ void GLES20RenderEngine::setupLayerBlending( } } -#ifdef USE_HWC2 -void GLES20RenderEngine::setupDimLayerBlending(float alpha) { -#else -void GLES20RenderEngine::setupDimLayerBlending(int alpha) { -#endif - mState.setPlaneAlpha(1.0f); - mState.setPremultipliedAlpha(true); - mState.setOpaque(false); -#ifdef USE_HWC2 - mState.setColor(0, 0, 0, alpha); -#else - mState.setColor(0, 0, 0, alpha/255.0f); -#endif - mState.disableTexture(); - -#ifdef USE_HWC2 - if (alpha == 1.0f) { -#else - if (alpha == 0xFF) { -#endif - glDisable(GL_BLEND); - } else { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } -} - #ifdef USE_HWC2 void GLES20RenderEngine::setColorMode(android_color_mode mode) { ALOGV("setColorMode: %s (0x%x)", decodeColorMode(mode).c_str(), mode); @@ -355,10 +320,9 @@ void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { } void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) { - mState.setPlaneAlpha(1.0f); mState.setPremultipliedAlpha(true); mState.setOpaque(false); - mState.setColor(r, g, b, a); + mState.setColor(half4(r, g, b, a)); mState.disableTexture(); glDisable(GL_BLEND); } diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index eaf94af54c..5ac12fc3d6 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -68,10 +68,9 @@ protected: virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation); -#ifdef USE_HWC2 virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, - float alpha) override; - virtual void setupDimLayerBlending(float alpha) override; + bool disableTexture, const half4& color) override; +#ifdef USE_HWC2 // Color management related functions and state void setColorMode(android_color_mode mode); @@ -92,10 +91,6 @@ protected: // Currently only supporting sRGB and DisplayP3 color spaces mat4 mSrgbToDisplayP3; -#else - virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, - int alpha); - virtual void setupDimLayerBlending(int alpha); #endif bool mPlatformHasWideColor = false; diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp index 48a8da5e8e..e95a6c573b 100644 --- a/services/surfaceflinger/RenderEngine/Program.cpp +++ b/services/surfaceflinger/RenderEngine/Program.cpp @@ -22,6 +22,7 @@ #include "Program.h" #include "ProgramCache.h" #include "Description.h" +#include namespace android { @@ -63,7 +64,6 @@ Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const c mTextureMatrixLoc = glGetUniformLocation(programId, "texture"); mSamplerLoc = glGetUniformLocation(programId, "sampler"); mColorLoc = glGetUniformLocation(programId, "color"); - mAlphaPlaneLoc = glGetUniformLocation(programId, "alphaPlane"); // set-up the default values for our uniforms glUseProgram(programId); @@ -132,11 +132,9 @@ void Program::setUniforms(const Description& desc) { glUniform1i(mSamplerLoc, 0); glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTexture.getMatrix().asArray()); } - if (mAlphaPlaneLoc >= 0) { - glUniform1f(mAlphaPlaneLoc, desc.mPlaneAlpha); - } if (mColorLoc >= 0) { - glUniform4fv(mColorLoc, 1, desc.mColor); + const float* color = &static_cast const &>(desc.mColor)[0]; + glUniform4fv(mColorLoc, 1, color); } if (mColorMatrixLoc >= 0) { glUniformMatrix4fv(mColorMatrixLoc, 1, GL_FALSE, desc.mColorMatrix.asArray()); diff --git a/services/surfaceflinger/RenderEngine/Program.h b/services/surfaceflinger/RenderEngine/Program.h index 36bd120e39..a2ae2ee007 100644 --- a/services/surfaceflinger/RenderEngine/Program.h +++ b/services/surfaceflinger/RenderEngine/Program.h @@ -79,9 +79,6 @@ private: /* location of the sampler uniform */ GLint mSamplerLoc; - /* location of the alpha plane uniform */ - GLint mAlphaPlaneLoc; - /* location of the color uniform */ GLint mColorLoc; }; diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp index 06b225299c..b4375454cc 100644 --- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp +++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp @@ -89,7 +89,7 @@ ProgramCache::~ProgramCache() { void ProgramCache::primeCache() { uint32_t shaderCount = 0; uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK | - Key::PLANE_ALPHA_MASK | Key::TEXTURE_MASK; + Key::ALPHA_MASK | Key::TEXTURE_MASK; // Prime the cache for all combinations of the above masks, // leaving off the experimental color matrix mask options. @@ -122,8 +122,8 @@ ProgramCache::Key ProgramCache::computeKey(const Description& description) { description.mTexture.getTextureTarget() == GL_TEXTURE_EXTERNAL_OES ? Key::TEXTURE_EXT : description.mTexture.getTextureTarget() == GL_TEXTURE_2D ? Key::TEXTURE_2D : Key::TEXTURE_OFF) - .set(Key::PLANE_ALPHA_MASK, - (description.mPlaneAlpha < 1) ? Key::PLANE_ALPHA_LT_ONE : Key::PLANE_ALPHA_EQ_ONE) + .set(Key::ALPHA_MASK, + (description.mColor.a < 1) ? Key::ALPHA_LT_ONE : Key::ALPHA_EQ_ONE) .set(Key::BLEND_MASK, description.mPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL) .set(Key::OPACITY_MASK, @@ -168,12 +168,12 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { } else if (needs.getTextureTarget() == Key::TEXTURE_2D) { fs << "uniform sampler2D sampler;" << "varying vec2 outTexCoords;"; - } else if (needs.getTextureTarget() == Key::TEXTURE_OFF) { - fs << "uniform vec4 color;"; } - if (needs.hasPlaneAlpha()) { - fs << "uniform float alphaPlane;"; + + if (needs.getTextureTarget() == Key::TEXTURE_OFF || needs.hasAlpha()) { + fs << "uniform vec4 color;"; } + if (needs.hasColorMatrix()) { fs << "uniform mat4 colorMatrix;"; } @@ -225,18 +225,19 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) { if (needs.isTexturing()) { fs << "gl_FragColor = texture2D(sampler, outTexCoords);"; } else { - fs << "gl_FragColor = color;"; + fs << "gl_FragColor.rgb = color.rgb;"; + fs << "gl_FragColor.a = 1.0;"; } if (needs.isOpaque()) { fs << "gl_FragColor.a = 1.0;"; } - if (needs.hasPlaneAlpha()) { - // modulate the alpha value with planeAlpha + if (needs.hasAlpha()) { + // modulate the current alpha value with alpha set if (needs.isPremultiplied()) { // ... and the color too if we're premultiplied - fs << "gl_FragColor *= alphaPlane;"; + fs << "gl_FragColor *= color.a;"; } else { - fs << "gl_FragColor.a *= alphaPlane;"; + fs << "gl_FragColor.a *= color.a;"; } } diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h index 5b0fbcd153..ff5cf0f21a 100644 --- a/services/surfaceflinger/RenderEngine/ProgramCache.h +++ b/services/surfaceflinger/RenderEngine/ProgramCache.h @@ -57,9 +57,9 @@ public: OPACITY_TRANSLUCENT = 0x00000000, OPACITY_MASK = 0x00000002, - PLANE_ALPHA_LT_ONE = 0x00000004, - PLANE_ALPHA_EQ_ONE = 0x00000000, - PLANE_ALPHA_MASK = 0x00000004, + ALPHA_LT_ONE = 0x00000004, + ALPHA_EQ_ONE = 0x00000000, + ALPHA_MASK = 0x00000004, TEXTURE_OFF = 0x00000000, TEXTURE_EXT = 0x00000008, @@ -95,8 +95,8 @@ public: inline bool isOpaque() const { return (mKey & OPACITY_MASK) == OPACITY_OPAQUE; } - inline bool hasPlaneAlpha() const { - return (mKey & PLANE_ALPHA_MASK) == PLANE_ALPHA_LT_ONE; + inline bool hasAlpha() const { + return (mKey & ALPHA_MASK) == ALPHA_LT_ONE; } inline bool hasColorMatrix() const { return (mKey & COLOR_MATRIX_MASK) == COLOR_MATRIX_ON; diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 954457946e..fa65979edd 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -25,6 +25,7 @@ #include #include #include +#include #define EGL_NO_CONFIG ((EGLConfig)0) @@ -98,16 +99,13 @@ public: virtual void checkErrors() const; virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0; + virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, + bool disableTexture, const half4& color) = 0; #ifdef USE_HWC2 - virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, float alpha) = 0; - virtual void setupDimLayerBlending(float alpha) = 0; virtual void setColorMode(android_color_mode mode) = 0; virtual void setSourceDataSpace(android_dataspace source) = 0; virtual void setWideColor(bool hasWideColor) = 0; virtual bool usesWideColor() = 0; -#else - virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0; - virtual void setupDimLayerBlending(int alpha) = 0; #endif virtual void setupLayerTexturing(const Texture& texture) = 0; virtual void setupLayerBlackedOut() = 0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e21379cd70..a7e7008b20 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -73,7 +73,7 @@ #include "EventThread.h" #include "Layer.h" #include "LayerVector.h" -#include "LayerDim.h" +#include "ColorLayer.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" @@ -2725,7 +2725,7 @@ bool SurfaceFlinger::doComposeSurfaces( case HWC2::Composition::SolidColor: { const Layer::State& state(layer->getDrawingState()); if (layer->getClearClientTarget(hwcId) && !firstLayer && - layer->isOpaque(state) && (state.alpha == 1.0f) + layer->isOpaque(state) && (state.color.a == 1.0f) && hasClientComposition) { // never clear the very first layer since we're // guaranteed the FB is already cleared @@ -3065,6 +3065,10 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (layer->setAlpha(s.alpha)) flags |= eTraversalNeeded; } + if (what & layer_state_t::eColorChanged) { + if (layer->setColor(s.color)) + flags |= eTraversalNeeded; + } if (what & layer_state_t::eMatrixChanged) { if (layer->setMatrix(s.matrix)) flags |= eTraversalNeeded; @@ -3168,8 +3172,8 @@ status_t SurfaceFlinger::createLayer( uniqueName, w, h, flags, format, handle, gbp, &layer); break; - case ISurfaceComposerClient::eFXSurfaceDim: - result = createDimLayer(client, + case ISurfaceComposerClient::eFXSurfaceColor: + result = createColorLayer(client, uniqueName, w, h, flags, handle, gbp, &layer); break; @@ -3251,11 +3255,11 @@ status_t SurfaceFlinger::createNormalLayer(const sp& client, return err; } -status_t SurfaceFlinger::createDimLayer(const sp& client, +status_t SurfaceFlinger::createColorLayer(const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, sp* handle, sp* gbp, sp* outLayer) { - *outLayer = new LayerDim(this, client, name, w, h, flags); + *outLayer = new ColorLayer(this, client, name, w, h, flags); *handle = (*outLayer)->getHandle(); *gbp = (*outLayer)->getProducer(); return NO_ERROR; @@ -4594,7 +4598,7 @@ void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* v ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", layer->isVisible() ? '+' : '-', i, layer->getName().string(), layer->getLayerStack(), state.z, - layer->isVisible(), state.flags, state.alpha); + layer->isVisible(), state.flags, static_cast(state.color.a)); i++; }); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 1b77aafc58..e87d35f912 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -84,7 +84,7 @@ class Client; class DisplayEventConnection; class EventThread; class Layer; -class LayerDim; +class ColorLayer; class Surface; class RenderEngine; class EventControlThread; @@ -410,7 +410,7 @@ private: sp* outHandle, sp* outGbp, sp* outLayer); - status_t createDimLayer(const sp& client, const String8& name, + status_t createColorLayer(const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, sp* outHandle, sp* outGbp, sp* outLayer); diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index b1c8c0ab69..b0021383ff 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -71,7 +71,7 @@ #include "EventThread.h" #include "Layer.h" #include "LayerVector.h" -#include "LayerDim.h" +#include "ColorLayer.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" @@ -2024,7 +2024,7 @@ void SurfaceFlinger::computeVisibleRegions(const sp& displa // compute the opaque region const int32_t layerOrientation = tr.getOrientation(); - if (s.alpha==255 && !translucent && + if (layer->getAlpha()==1.0f && !translucent && ((layerOrientation & Transform::ROT_INVALID) == false)) { // the opaque region is the layer's footprint opaqueRegion = visibleRegion; @@ -2297,7 +2297,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& hw, const const Layer::State& state(layer->getDrawingState()); if ((cur->getHints() & HWC_HINT_CLEAR_FB) && i - && layer->isOpaque(state) && (state.alpha == 0xFF) + && layer->isOpaque(state) && (state.color.a == 1.0f) && hasGlesComposition) { // never clear the very first layer since we're // guaranteed the FB is already cleared @@ -2622,9 +2622,14 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } if (what & layer_state_t::eAlphaChanged) { - if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) + if (layer->setAlpha(s.alpha)) flags |= eTraversalNeeded; } + if (what & layer_state_t::eColorChanged) { + if (layer->setColor(s.color)) { + flags |= eTraversalNeeded; + } + } if (what & layer_state_t::eMatrixChanged) { if (layer->setMatrix(s.matrix)) flags |= eTraversalNeeded; @@ -2728,8 +2733,8 @@ status_t SurfaceFlinger::createLayer( uniqueName, w, h, flags, format, handle, gbp, &layer); break; - case ISurfaceComposerClient::eFXSurfaceDim: - result = createDimLayer(client, + case ISurfaceComposerClient::eFXSurfaceColor: + result = createColorLayer(client, uniqueName, w, h, flags, handle, gbp, &layer); break; @@ -2804,11 +2809,11 @@ status_t SurfaceFlinger::createNormalLayer(const sp& client, return err; } -status_t SurfaceFlinger::createDimLayer(const sp& client, +status_t SurfaceFlinger::createColorLayer(const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, sp* handle, sp* gbp, sp* outLayer) { - *outLayer = new LayerDim(this, client, name, w, h, flags); + *outLayer = new ColorLayer(this, client, name, w, h, flags); *handle = (*outLayer)->getHandle(); *gbp = (*outLayer)->getProducer(); return NO_ERROR; @@ -4089,10 +4094,10 @@ void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* v if (layer->getLayerStack() == hw->getLayerStack() && state.z >= minLayerZ && state.z <= maxLayerZ) { layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { - ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%x", + ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f", layer->isVisible() ? '+' : '-', i, layer->getName().string(), layer->getLayerStack(), state.z, - layer->isVisible(), state.flags, state.alpha); + layer->isVisible(), state.flags, static_cast(state.color.a)); i++; }); } diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index db489b2456..eeb492978c 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -98,7 +98,7 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, addPositionLocked(transaction, layerId, layer->mCurrentState.active.transform.tx(), layer->mCurrentState.active.transform.ty()); addDepthLocked(transaction, layerId, layer->mCurrentState.z); - addAlphaLocked(transaction, layerId, layer->mCurrentState.alpha); + addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a); addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion); addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack); addCropLocked(transaction, layerId, layer->mCurrentState.crop); diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter index 6be708ad1c..5c188dc8a5 100644 --- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter +++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter @@ -1,5 +1,5 @@ { "presubmit": { - "filter": "LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*" + "filter": "LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:LayerColorTest.*" } } \ No newline at end of file diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 21194926da..8900a4d258 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -28,6 +28,7 @@ #include #include +#include namespace android { @@ -1276,4 +1277,97 @@ TEST_F(ChildLayerTest, NestedChildren) { } } +class LayerColorTest : public LayerUpdateTest { + protected: + void SetUp() override { + LayerUpdateTest::SetUp(); + + mLayerColorControl = mComposerClient->createSurface( + String8("Layer color surface"), + 128, 128, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceColor); + + ASSERT_TRUE(mLayerColorControl != NULL); + ASSERT_TRUE(mLayerColorControl->isValid()); + + SurfaceComposerClient::openGlobalTransaction(); + ASSERT_EQ(NO_ERROR, mLayerColorControl->setLayer(INT32_MAX-1)); + ASSERT_EQ(NO_ERROR, mLayerColorControl->setPosition(140, 140)); + ASSERT_EQ(NO_ERROR, mLayerColorControl->hide()); + ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide()); + SurfaceComposerClient::closeGlobalTransaction(true); + } + + void TearDown() override { + LayerUpdateTest::TearDown(); + mLayerColorControl = 0; + } + + sp mLayerColorControl; +}; + +TEST_F(LayerColorTest, ColorLayerNoAlpha) { + sp sc; + + { + SCOPED_TRACE("before setColor"); + ScreenCapture::captureScreen(&sc); + sc->expectBGColor(145, 145); + } + + + SurfaceComposerClient::openGlobalTransaction(); + half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f); + mLayerColorControl->setColor(color); + mLayerColorControl->show(); + SurfaceComposerClient::closeGlobalTransaction(true); + { + // There should now be a color + SCOPED_TRACE("after setColor"); + ScreenCapture::captureScreen(&sc); + sc->checkPixel(145, 145, 43, 207, 131); + } +} + +TEST_F(LayerColorTest, ColorLayerWithAlpha) { + sp sc; + { + SCOPED_TRACE("before setColor"); + ScreenCapture::captureScreen(&sc); + sc->expectBGColor(145, 145); + } + + SurfaceComposerClient::openGlobalTransaction(); + half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f); + mLayerColorControl->setColor(color); + mLayerColorControl->setAlpha(.75f); + mLayerColorControl->show(); + SurfaceComposerClient::closeGlobalTransaction(true); + { + // There should now be a color with .75 alpha + SCOPED_TRACE("after setColor"); + ScreenCapture::captureScreen(&sc); + sc->checkPixel(145, 145, 48, 171, 147); + } +} + +TEST_F(LayerColorTest, ColorLayerWithNoColor) { + sp sc; + { + SCOPED_TRACE("before setColor"); + ScreenCapture::captureScreen(&sc); + sc->expectBGColor(145, 145); + } + + SurfaceComposerClient::openGlobalTransaction(); + mLayerColorControl->show(); + SurfaceComposerClient::closeGlobalTransaction(true); + { + // There should now be set to 0,0,0 (black) as default. + SCOPED_TRACE("after setColor"); + ScreenCapture::captureScreen(&sc); + sc->checkPixel(145, 145, 0, 0, 0); + } +} + } -- cgit v1.2.3-59-g8ed1b From 4cdc58f6840d15b4952149d2b345ec1f97d505bc Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Wed, 23 Aug 2017 14:22:20 -0700 Subject: SurfaceFlinger Transactions as distinct objects. Essentially a process global singleton for transactions is not so useful once we make surface control public API as process isn't something an app developer is really thinking about. It's also nice that we get to delete two of the plumbing layers. Test: Boots Change-Id: I8864bd7e2f5865e3c0a425cf82f9928211911774 --- cmds/flatland/GLHelper.cpp | 22 +- cmds/surfacereplayer/replayer/Replayer.cpp | 154 +++-- cmds/surfacereplayer/replayer/Replayer.h | 64 +- libs/gui/ISurfaceComposer.cpp | 3 +- libs/gui/LayerState.cpp | 2 +- libs/gui/SurfaceComposerClient.cpp | 694 ++++++--------------- libs/gui/SurfaceControl.cpp | 122 +--- libs/gui/include/gui/LayerState.h | 177 ++++++ libs/gui/include/gui/SurfaceComposerClient.h | 189 ++++-- libs/gui/include/gui/SurfaceControl.h | 89 +-- libs/gui/include/private/gui/LayerState.h | 163 ----- libs/gui/tests/GLTest.cpp | 10 +- libs/gui/tests/Surface_test.cpp | 10 +- opengl/tests/lib/WindowSurface.cpp | 17 +- services/surfaceflinger/Layer.h | 3 +- services/surfaceflinger/SurfaceFlinger.h | 4 +- .../tests/SurfaceInterceptor_test.cpp | 144 +++-- services/surfaceflinger/tests/Transaction_test.cpp | 566 +++++++++-------- .../tests/fakehwc/FakeComposerUtils.h | 17 +- .../tests/fakehwc/SFFakeHwc_test.cpp | 352 ++++++----- 20 files changed, 1229 insertions(+), 1573 deletions(-) create mode 100644 libs/gui/include/gui/LayerState.h delete mode 100644 libs/gui/include/private/gui/LayerState.h (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp index dfc3e581fd..d5b3372f96 100644 --- a/cmds/flatland/GLHelper.cpp +++ b/cmds/flatland/GLHelper.cpp @@ -269,24 +269,10 @@ bool GLHelper::createWindowSurface(uint32_t w, uint32_t h, return false; } - SurfaceComposerClient::openGlobalTransaction(); - err = sc->setLayer(0x7FFFFFFF); - if (err != NO_ERROR) { - fprintf(stderr, "SurfaceComposer::setLayer error: %#x\n", err); - return false; - } - err = sc->setMatrix(scale, 0.0f, 0.0f, scale); - if (err != NO_ERROR) { - fprintf(stderr, "SurfaceComposer::setMatrix error: %#x\n", err); - return false; - } - - err = sc->show(); - if (err != NO_ERROR) { - fprintf(stderr, "SurfaceComposer::show error: %#x\n", err); - return false; - } - SurfaceComposerClient::closeGlobalTransaction(); + SurfaceComposerClient::Transaction{}.setLayer(sc, 0x7FFFFFFF) + .setMatrix(sc, scale, 0.0f, 0.0f, scale) + .show(sc) + .apply(); sp anw = sc->getSurface(); EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL); diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp index 2b5389b8dc..4140f40888 100644 --- a/cmds/surfacereplayer/replayer/Replayer.cpp +++ b/cmds/surfacereplayer/replayer/Replayer.cpp @@ -24,9 +24,9 @@ #include #include +#include #include #include -#include #include #include @@ -338,27 +338,29 @@ status_t Replayer::dispatchEvent(int index) { status_t Replayer::doTransaction(const Transaction& t, const std::shared_ptr& event) { ALOGV("Started Transaction"); - SurfaceComposerClient::openGlobalTransaction(); + SurfaceComposerClient::Transaction liveTransaction; status_t status = NO_ERROR; - status = doSurfaceTransaction(t.surface_change()); - doDisplayTransaction(t.display_change()); + status = doSurfaceTransaction(liveTransaction, t.surface_change()); + doDisplayTransaction(liveTransaction, t.display_change()); if (t.animation()) { - SurfaceComposerClient::setAnimationTransaction(); + liveTransaction.setAnimationTransaction(); } event->readyToExecute(); - SurfaceComposerClient::closeGlobalTransaction(t.synchronous()); + liveTransaction.apply(t.synchronous()); ALOGV("Ended Transaction"); return status; } -status_t Replayer::doSurfaceTransaction(const SurfaceChanges& surfaceChanges) { +status_t Replayer::doSurfaceTransaction( + SurfaceComposerClient::Transaction& transaction, + const SurfaceChanges& surfaceChanges) { status_t status = NO_ERROR; for (const SurfaceChange& change : surfaceChanges) { @@ -369,62 +371,66 @@ status_t Replayer::doSurfaceTransaction(const SurfaceChanges& surfaceChanges) { switch (change.SurfaceChange_case()) { case SurfaceChange::SurfaceChangeCase::kPosition: - status = setPosition(change.id(), change.position()); + setPosition(transaction, change.id(), change.position()); break; case SurfaceChange::SurfaceChangeCase::kSize: - status = setSize(change.id(), change.size()); + setSize(transaction, change.id(), change.size()); break; case SurfaceChange::SurfaceChangeCase::kAlpha: - status = setAlpha(change.id(), change.alpha()); + setAlpha(transaction, change.id(), change.alpha()); break; case SurfaceChange::SurfaceChangeCase::kLayer: - status = setLayer(change.id(), change.layer()); + setLayer(transaction, change.id(), change.layer()); break; case SurfaceChange::SurfaceChangeCase::kCrop: - status = setCrop(change.id(), change.crop()); + setCrop(transaction, change.id(), change.crop()); break; case SurfaceChange::SurfaceChangeCase::kMatrix: - status = setMatrix(change.id(), change.matrix()); + setMatrix(transaction, change.id(), change.matrix()); break; case SurfaceChange::SurfaceChangeCase::kFinalCrop: - status = setFinalCrop(change.id(), change.final_crop()); + setFinalCrop(transaction, change.id(), change.final_crop()); break; case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode: - status = setOverrideScalingMode(change.id(), change.override_scaling_mode()); + setOverrideScalingMode(transaction, change.id(), + change.override_scaling_mode()); break; case SurfaceChange::SurfaceChangeCase::kTransparentRegionHint: - status = setTransparentRegionHint(change.id(), change.transparent_region_hint()); + setTransparentRegionHint(transaction, change.id(), + change.transparent_region_hint()); break; case SurfaceChange::SurfaceChangeCase::kLayerStack: - status = setLayerStack(change.id(), change.layer_stack()); + setLayerStack(transaction, change.id(), change.layer_stack()); break; case SurfaceChange::SurfaceChangeCase::kHiddenFlag: - status = setHiddenFlag(change.id(), change.hidden_flag()); + setHiddenFlag(transaction, change.id(), change.hidden_flag()); break; case SurfaceChange::SurfaceChangeCase::kOpaqueFlag: - status = setOpaqueFlag(change.id(), change.opaque_flag()); + setOpaqueFlag(transaction, change.id(), change.opaque_flag()); break; case SurfaceChange::SurfaceChangeCase::kSecureFlag: - status = setSecureFlag(change.id(), change.secure_flag()); + setSecureFlag(transaction, change.id(), change.secure_flag()); break; case SurfaceChange::SurfaceChangeCase::kDeferredTransaction: waitUntilDeferredTransactionLayerExists(change.deferred_transaction(), lock); - status = setDeferredTransaction(change.id(), change.deferred_transaction()); + setDeferredTransaction(transaction, change.id(), + change.deferred_transaction()); break; default: - status = NO_ERROR; + status = 1; break; } if (status != NO_ERROR) { - ALOGE("SET TRANSACTION FAILED"); + ALOGE("Unknown Transaction Code"); return status; } } return status; } -void Replayer::doDisplayTransaction(const DisplayChanges& displayChanges) { +void Replayer::doDisplayTransaction(SurfaceComposerClient::Transaction& t, + const DisplayChanges& displayChanges) { for (const DisplayChange& change : displayChanges) { ALOGV("Doing display transaction"); std::unique_lock lock(mDisplayLock); @@ -434,16 +440,16 @@ void Replayer::doDisplayTransaction(const DisplayChanges& displayChanges) { switch (change.DisplayChange_case()) { case DisplayChange::DisplayChangeCase::kSurface: - setDisplaySurface(change.id(), change.surface()); + setDisplaySurface(t, change.id(), change.surface()); break; case DisplayChange::DisplayChangeCase::kLayerStack: - setDisplayLayerStack(change.id(), change.layer_stack()); + setDisplayLayerStack(t, change.id(), change.layer_stack()); break; case DisplayChange::DisplayChangeCase::kSize: - setDisplaySize(change.id(), change.size()); + setDisplaySize(t, change.id(), change.size()); break; case DisplayChange::DisplayChangeCase::kProjection: - setDisplayProjection(change.id(), change.projection()); + setDisplayProjection(t, change.id(), change.projection()); break; default: break; @@ -451,57 +457,66 @@ void Replayer::doDisplayTransaction(const DisplayChanges& displayChanges) { } } -status_t Replayer::setPosition(layer_id id, const PositionChange& pc) { +void Replayer::setPosition(SurfaceComposerClient::Transaction& t, + layer_id id, const PositionChange& pc) { ALOGV("Layer %d: Setting Position -- x=%f, y=%f", id, pc.x(), pc.y()); - return mLayers[id]->setPosition(pc.x(), pc.y()); + t.setPosition(mLayers[id], pc.x(), pc.y()); } -status_t Replayer::setSize(layer_id id, const SizeChange& sc) { +void Replayer::setSize(SurfaceComposerClient::Transaction& t, + layer_id id, const SizeChange& sc) { ALOGV("Layer %d: Setting Size -- w=%u, h=%u", id, sc.w(), sc.h()); - return mLayers[id]->setSize(sc.w(), sc.h()); + t.setSize(mLayers[id], sc.w(), sc.h()); } -status_t Replayer::setLayer(layer_id id, const LayerChange& lc) { +void Replayer::setLayer(SurfaceComposerClient::Transaction& t, + layer_id id, const LayerChange& lc) { ALOGV("Layer %d: Setting Layer -- layer=%d", id, lc.layer()); - return mLayers[id]->setLayer(lc.layer()); + t.setLayer(mLayers[id], lc.layer()); } -status_t Replayer::setAlpha(layer_id id, const AlphaChange& ac) { +void Replayer::setAlpha(SurfaceComposerClient::Transaction& t, + layer_id id, const AlphaChange& ac) { ALOGV("Layer %d: Setting Alpha -- alpha=%f", id, ac.alpha()); - return mLayers[id]->setAlpha(ac.alpha()); + t.setAlpha(mLayers[id], ac.alpha()); } -status_t Replayer::setCrop(layer_id id, const CropChange& cc) { +void Replayer::setCrop(SurfaceComposerClient::Transaction& t, + layer_id id, const CropChange& cc) { ALOGV("Layer %d: Setting Crop -- left=%d, top=%d, right=%d, bottom=%d", id, cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), cc.rectangle().bottom()); Rect r = Rect(cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), cc.rectangle().bottom()); - return mLayers[id]->setCrop(r); + t.setCrop(mLayers[id], r); } -status_t Replayer::setFinalCrop(layer_id id, const FinalCropChange& fcc) { +void Replayer::setFinalCrop(SurfaceComposerClient::Transaction& t, + layer_id id, const FinalCropChange& fcc) { ALOGV("Layer %d: Setting Final Crop -- left=%d, top=%d, right=%d, bottom=%d", id, fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), fcc.rectangle().bottom()); Rect r = Rect(fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), fcc.rectangle().bottom()); - return mLayers[id]->setFinalCrop(r); + t.setFinalCrop(mLayers[id], r); } -status_t Replayer::setMatrix(layer_id id, const MatrixChange& mc) { +void Replayer::setMatrix(SurfaceComposerClient::Transaction& t, + layer_id id, const MatrixChange& mc) { ALOGV("Layer %d: Setting Matrix -- dsdx=%f, dtdx=%f, dsdy=%f, dtdy=%f", id, mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy()); - return mLayers[id]->setMatrix(mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy()); + t.setMatrix(mLayers[id], mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy()); } -status_t Replayer::setOverrideScalingMode(layer_id id, const OverrideScalingModeChange& osmc) { +void Replayer::setOverrideScalingMode(SurfaceComposerClient::Transaction& t, + layer_id id, const OverrideScalingModeChange& osmc) { ALOGV("Layer %d: Setting Override Scaling Mode -- mode=%d", id, osmc.override_scaling_mode()); - return mLayers[id]->setOverrideScalingMode(osmc.override_scaling_mode()); + t.setOverrideScalingMode(mLayers[id], osmc.override_scaling_mode()); } -status_t Replayer::setTransparentRegionHint(layer_id id, const TransparentRegionHintChange& trhc) { +void Replayer::setTransparentRegionHint(SurfaceComposerClient::Transaction& t, + layer_id id, const TransparentRegionHintChange& trhc) { ALOGV("Setting Transparent Region Hint"); Region re = Region(); @@ -510,71 +525,80 @@ status_t Replayer::setTransparentRegionHint(layer_id id, const TransparentRegion re.merge(rect); } - return mLayers[id]->setTransparentRegionHint(re); + t.setTransparentRegionHint(mLayers[id], re); } -status_t Replayer::setLayerStack(layer_id id, const LayerStackChange& lsc) { +void Replayer::setLayerStack(SurfaceComposerClient::Transaction& t, + layer_id id, const LayerStackChange& lsc) { ALOGV("Layer %d: Setting LayerStack -- layer_stack=%d", id, lsc.layer_stack()); - return mLayers[id]->setLayerStack(lsc.layer_stack()); + t.setLayerStack(mLayers[id], lsc.layer_stack()); } -status_t Replayer::setHiddenFlag(layer_id id, const HiddenFlagChange& hfc) { +void Replayer::setHiddenFlag(SurfaceComposerClient::Transaction& t, + layer_id id, const HiddenFlagChange& hfc) { ALOGV("Layer %d: Setting Hidden Flag -- hidden_flag=%d", id, hfc.hidden_flag()); layer_id flag = hfc.hidden_flag() ? layer_state_t::eLayerHidden : 0; - return mLayers[id]->setFlags(flag, layer_state_t::eLayerHidden); + t.setFlags(mLayers[id], flag, layer_state_t::eLayerHidden); } -status_t Replayer::setOpaqueFlag(layer_id id, const OpaqueFlagChange& ofc) { +void Replayer::setOpaqueFlag(SurfaceComposerClient::Transaction& t, + layer_id id, const OpaqueFlagChange& ofc) { ALOGV("Layer %d: Setting Opaque Flag -- opaque_flag=%d", id, ofc.opaque_flag()); layer_id flag = ofc.opaque_flag() ? layer_state_t::eLayerOpaque : 0; - return mLayers[id]->setFlags(flag, layer_state_t::eLayerOpaque); + t.setFlags(mLayers[id], flag, layer_state_t::eLayerOpaque); } -status_t Replayer::setSecureFlag(layer_id id, const SecureFlagChange& sfc) { +void Replayer::setSecureFlag(SurfaceComposerClient::Transaction& t, + layer_id id, const SecureFlagChange& sfc) { ALOGV("Layer %d: Setting Secure Flag -- secure_flag=%d", id, sfc.secure_flag()); layer_id flag = sfc.secure_flag() ? layer_state_t::eLayerSecure : 0; - return mLayers[id]->setFlags(flag, layer_state_t::eLayerSecure); + t.setFlags(mLayers[id], flag, layer_state_t::eLayerSecure); } -status_t Replayer::setDeferredTransaction(layer_id id, const DeferredTransactionChange& dtc) { +void Replayer::setDeferredTransaction(SurfaceComposerClient::Transaction& t, + layer_id id, const DeferredTransactionChange& dtc) { ALOGV("Layer %d: Setting Deferred Transaction -- layer_id=%d, " "frame_number=%llu", id, dtc.layer_id(), dtc.frame_number()); if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { ALOGE("Layer %d not found in Deferred Transaction", dtc.layer_id()); - return BAD_VALUE; + return; } auto handle = mLayers[dtc.layer_id()]->getHandle(); - return mLayers[id]->deferTransactionUntil(handle, dtc.frame_number()); + t.deferTransactionUntil(mLayers[id], handle, dtc.frame_number()); } -void Replayer::setDisplaySurface(display_id id, const DispSurfaceChange& /*dsc*/) { +void Replayer::setDisplaySurface(SurfaceComposerClient::Transaction& t, + display_id id, const DispSurfaceChange& /*dsc*/) { sp outProducer; sp outConsumer; BufferQueue::createBufferQueue(&outProducer, &outConsumer); - SurfaceComposerClient::setDisplaySurface(mDisplays[id], outProducer); + t.setDisplaySurface(mDisplays[id], outProducer); } -void Replayer::setDisplayLayerStack(display_id id, const LayerStackChange& lsc) { - SurfaceComposerClient::setDisplayLayerStack(mDisplays[id], lsc.layer_stack()); +void Replayer::setDisplayLayerStack(SurfaceComposerClient::Transaction& t, + display_id id, const LayerStackChange& lsc) { + t.setDisplayLayerStack(mDisplays[id], lsc.layer_stack()); } -void Replayer::setDisplaySize(display_id id, const SizeChange& sc) { - SurfaceComposerClient::setDisplaySize(mDisplays[id], sc.w(), sc.h()); +void Replayer::setDisplaySize(SurfaceComposerClient::Transaction& t, + display_id id, const SizeChange& sc) { + t.setDisplaySize(mDisplays[id], sc.w(), sc.h()); } -void Replayer::setDisplayProjection(display_id id, const ProjectionChange& pc) { +void Replayer::setDisplayProjection(SurfaceComposerClient::Transaction& t, + display_id id, const ProjectionChange& pc) { Rect viewport = Rect(pc.viewport().left(), pc.viewport().top(), pc.viewport().right(), pc.viewport().bottom()); Rect frame = Rect(pc.frame().left(), pc.frame().top(), pc.frame().right(), pc.frame().bottom()); - SurfaceComposerClient::setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame); + t.setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame); } status_t Replayer::createSurfaceControl( diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h index f36c9fd4a4..295403eace 100644 --- a/cmds/surfacereplayer/replayer/Replayer.h +++ b/cmds/surfacereplayer/replayer/Replayer.h @@ -77,28 +77,48 @@ class Replayer { void deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr& event); void updatePowerMode(const PowerModeUpdate& update, const std::shared_ptr& event); - status_t doSurfaceTransaction(const SurfaceChanges& surfaceChange); - void doDisplayTransaction(const DisplayChanges& displayChange); - - status_t setPosition(layer_id id, const PositionChange& pc); - status_t setSize(layer_id id, const SizeChange& sc); - status_t setAlpha(layer_id id, const AlphaChange& ac); - status_t setLayer(layer_id id, const LayerChange& lc); - status_t setCrop(layer_id id, const CropChange& cc); - status_t setFinalCrop(layer_id id, const FinalCropChange& fcc); - status_t setMatrix(layer_id id, const MatrixChange& mc); - status_t setOverrideScalingMode(layer_id id, const OverrideScalingModeChange& osmc); - status_t setTransparentRegionHint(layer_id id, const TransparentRegionHintChange& trgc); - status_t setLayerStack(layer_id id, const LayerStackChange& lsc); - status_t setHiddenFlag(layer_id id, const HiddenFlagChange& hfc); - status_t setOpaqueFlag(layer_id id, const OpaqueFlagChange& ofc); - status_t setSecureFlag(layer_id id, const SecureFlagChange& sfc); - status_t setDeferredTransaction(layer_id id, const DeferredTransactionChange& dtc); - - void setDisplaySurface(display_id id, const DispSurfaceChange& dsc); - void setDisplayLayerStack(display_id id, const LayerStackChange& lsc); - void setDisplaySize(display_id id, const SizeChange& sc); - void setDisplayProjection(display_id id, const ProjectionChange& pc); + status_t doSurfaceTransaction(SurfaceComposerClient::Transaction& transaction, + const SurfaceChanges& surfaceChange); + void doDisplayTransaction(SurfaceComposerClient::Transaction& transaction, + const DisplayChanges& displayChange); + + void setPosition(SurfaceComposerClient::Transaction& t, + layer_id id, const PositionChange& pc); + void setSize(SurfaceComposerClient::Transaction& t, + layer_id id, const SizeChange& sc); + void setAlpha(SurfaceComposerClient::Transaction& t, + layer_id id, const AlphaChange& ac); + void setLayer(SurfaceComposerClient::Transaction& t, + layer_id id, const LayerChange& lc); + void setCrop(SurfaceComposerClient::Transaction& t, + layer_id id, const CropChange& cc); + void setFinalCrop(SurfaceComposerClient::Transaction& t, + layer_id id, const FinalCropChange& fcc); + void setMatrix(SurfaceComposerClient::Transaction& t, + layer_id id, const MatrixChange& mc); + void setOverrideScalingMode(SurfaceComposerClient::Transaction& t, + layer_id id, const OverrideScalingModeChange& osmc); + void setTransparentRegionHint(SurfaceComposerClient::Transaction& t, + layer_id id, const TransparentRegionHintChange& trgc); + void setLayerStack(SurfaceComposerClient::Transaction& t, + layer_id id, const LayerStackChange& lsc); + void setHiddenFlag(SurfaceComposerClient::Transaction& t, + layer_id id, const HiddenFlagChange& hfc); + void setOpaqueFlag(SurfaceComposerClient::Transaction& t, + layer_id id, const OpaqueFlagChange& ofc); + void setSecureFlag(SurfaceComposerClient::Transaction& t, + layer_id id, const SecureFlagChange& sfc); + void setDeferredTransaction(SurfaceComposerClient::Transaction& t, + layer_id id, const DeferredTransactionChange& dtc); + + void setDisplaySurface(SurfaceComposerClient::Transaction& t, + display_id id, const DispSurfaceChange& dsc); + void setDisplayLayerStack(SurfaceComposerClient::Transaction& t, + display_id id, const LayerStackChange& lsc); + void setDisplaySize(SurfaceComposerClient::Transaction& t, + display_id id, const SizeChange& sc); + void setDisplayProjection(SurfaceComposerClient::Transaction& t, + display_id id, const ProjectionChange& pc); void doDeleteSurfaceControls(); void waitUntilTimestamp(int64_t timestamp); diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 8e7f814313..96771257c1 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -29,8 +29,7 @@ #include #include #include - -#include +#include #include diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index fcee73f445..bfc6f28704 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include namespace android { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c5a4389ae8..40e319e28a 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -37,11 +36,11 @@ #include #include #include +#include #include #include #include -#include namespace android { // --------------------------------------------------------------------------- @@ -97,208 +96,71 @@ void ComposerService::composerServiceDied() // --------------------------------------------------------------------------- -static inline -int compare_type(const ComposerState& lhs, const ComposerState& rhs) { - if (lhs.client < rhs.client) return -1; - if (lhs.client > rhs.client) return 1; - if (lhs.state.surface < rhs.state.surface) return -1; - if (lhs.state.surface > rhs.state.surface) return 1; - return 0; +SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : + mForceSynchronous(other.mForceSynchronous), + mTransactionNestCount(other.mTransactionNestCount), + mAnimation(other.mAnimation) { + mDisplayStates = other.mDisplayStates; + mComposerStates = other.mComposerStates; } -static inline -int compare_type(const DisplayState& lhs, const DisplayState& rhs) { - return compare_type(lhs.token, rhs.token); -} - -class Composer : public Singleton -{ - friend class Singleton; - - mutable Mutex mLock; - SortedVector mComposerStates; - SortedVector mDisplayStates; - uint32_t mForceSynchronous; - uint32_t mTransactionNestCount; - bool mAnimation; - - Composer() : Singleton(), - mForceSynchronous(0), mTransactionNestCount(0), - mAnimation(false) - { } - - void openGlobalTransactionImpl(); - void closeGlobalTransactionImpl(bool synchronous); - void setAnimationTransactionImpl(); - status_t enableVSyncInjectionsImpl(bool enable); - status_t injectVSyncImpl(nsecs_t when); - - layer_state_t* getLayerStateLocked( - const sp& client, const sp& id); - - DisplayState& getDisplayStateLocked(const sp& token); - -public: - sp createDisplay(const String8& displayName, bool secure); - void destroyDisplay(const sp& display); - sp getBuiltInDisplay(int32_t id); - - status_t setPosition(const sp& client, const sp& id, - float x, float y); - status_t setSize(const sp& client, const sp& id, - uint32_t w, uint32_t h); - status_t setLayer(const sp& client, const sp& id, - int32_t z); - status_t setRelativeLayer(const sp& client, const sp& id, - const sp& relativeTo, int32_t z); - status_t setFlags(const sp& client, const sp& id, - uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint( - const sp& client, const sp& id, - const Region& transparentRegion); - status_t setAlpha(const sp& client, const sp& id, - float alpha); - status_t setColor(const sp& client, const sp& id, - const half3& color); - status_t setMatrix(const sp& client, const sp& id, - float dsdx, float dtdx, float dtdy, float dsdy); - status_t setOrientation(int orientation); - status_t setCrop(const sp& client, const sp& id, - const Rect& crop); - status_t setFinalCrop(const sp& client, - const sp& id, const Rect& crop); - status_t setLayerStack(const sp& client, - const sp& id, uint32_t layerStack); - status_t deferTransactionUntil(const sp& client, - const sp& id, const sp& handle, - uint64_t frameNumber); - status_t deferTransactionUntil(const sp& client, - const sp& id, const sp& barrierSurface, - uint64_t frameNumber); - status_t reparentChildren(const sp& client, - const sp& id, - const sp& newParentHandle); - status_t reparent(const sp& client, - const sp& id, const sp& newParentHandle); - status_t detachChildren(const sp& client, - const sp& id); - status_t setOverrideScalingMode(const sp& client, - const sp& id, int32_t overrideScalingMode); - status_t setGeometryAppliesWithResize(const sp& client, - const sp& id); - - status_t setDisplaySurface(const sp& token, - sp bufferProducer); - void setDisplayLayerStack(const sp& token, uint32_t layerStack); - void setDisplayProjection(const sp& token, - uint32_t orientation, - const Rect& layerStackRect, - const Rect& displayRect); - void setDisplaySize(const sp& token, uint32_t width, uint32_t height); - - static void setAnimationTransaction() { - Composer::getInstance().setAnimationTransactionImpl(); +status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { + if (mStatus != NO_ERROR) { + return mStatus; } - static void openGlobalTransaction() { - Composer::getInstance().openGlobalTransactionImpl(); - } + sp sf(ComposerService::getComposerService()); - static void closeGlobalTransaction(bool synchronous) { - Composer::getInstance().closeGlobalTransactionImpl(synchronous); - } + Vector composerStates; + Vector displayStates; + uint32_t flags = 0; - static status_t enableVSyncInjections(bool enable) { - return Composer::getInstance().enableVSyncInjectionsImpl(enable); - } + mForceSynchronous |= synchronous; - static status_t injectVSync(nsecs_t when) { - return Composer::getInstance().injectVSyncImpl(when); + composerStates = mComposerStates; + mComposerStates.clear(); + + displayStates = mDisplayStates; + mDisplayStates.clear(); + + if (mForceSynchronous) { + flags |= ISurfaceComposer::eSynchronous; + } + if (mAnimation) { + flags |= ISurfaceComposer::eAnimation; } -}; -ANDROID_SINGLETON_STATIC_INSTANCE(Composer); + mForceSynchronous = false; + mAnimation = false; + + sf->setTransactionState(composerStates, displayStates, flags); + mStatus = NO_ERROR; + return NO_ERROR; +} // --------------------------------------------------------------------------- -sp Composer::createDisplay(const String8& displayName, bool secure) { +sp SurfaceComposerClient::createDisplay(const String8& displayName, bool secure) { return ComposerService::getComposerService()->createDisplay(displayName, secure); } -void Composer::destroyDisplay(const sp& display) { +void SurfaceComposerClient::destroyDisplay(const sp& display) { return ComposerService::getComposerService()->destroyDisplay(display); } -sp Composer::getBuiltInDisplay(int32_t id) { +sp SurfaceComposerClient::getBuiltInDisplay(int32_t id) { return ComposerService::getComposerService()->getBuiltInDisplay(id); } -void Composer::openGlobalTransactionImpl() { - { // scope for the lock - Mutex::Autolock _l(mLock); - mTransactionNestCount += 1; - } -} - -void Composer::closeGlobalTransactionImpl(bool synchronous) { - sp sm(ComposerService::getComposerService()); - - Vector transaction; - Vector displayTransaction; - uint32_t flags = 0; - - { // scope for the lock - Mutex::Autolock _l(mLock); - mForceSynchronous |= synchronous; - if (!mTransactionNestCount) { - ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior " - "call to openGlobalTransaction()."); - } else if (--mTransactionNestCount) { - return; - } - - transaction = mComposerStates; - mComposerStates.clear(); - - displayTransaction = mDisplayStates; - mDisplayStates.clear(); - - if (mForceSynchronous) { - flags |= ISurfaceComposer::eSynchronous; - } - if (mAnimation) { - flags |= ISurfaceComposer::eAnimation; - } - - mForceSynchronous = false; - mAnimation = false; - } - - sm->setTransactionState(transaction, displayTransaction, flags); -} - -status_t Composer::enableVSyncInjectionsImpl(bool enable) { - sp sm(ComposerService::getComposerService()); - return sm->enableVSyncInjections(enable); -} - -status_t Composer::injectVSyncImpl(nsecs_t when) { - sp sm(ComposerService::getComposerService()); - return sm->injectVSync(when); -} - -void Composer::setAnimationTransactionImpl() { - Mutex::Autolock _l(mLock); +void SurfaceComposerClient::Transaction::setAnimationTransaction() { mAnimation = true; } -layer_state_t* Composer::getLayerStateLocked( - const sp& client, const sp& id) { - +layer_state_t* SurfaceComposerClient::Transaction::getLayerStateLocked(const sp& sc) { ComposerState s; - s.client = client->mClient; - s.state.surface = id; + s.client = sc->getClient()->mClient; + s.state.surface = sc->getHandle(); ssize_t index = mComposerStates.indexOf(s); if (index < 0) { @@ -310,24 +172,36 @@ layer_state_t* Composer::getLayerStateLocked( return &(out[index].state); } -status_t Composer::setPosition(const sp& client, - const sp& id, float x, float y) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( + const sp& sc, float x, float y) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::ePositionChanged; s->x = x; s->y = y; - return NO_ERROR; + return *this; } -status_t Composer::setSize(const sp& client, - const sp& id, uint32_t w, uint32_t h) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show( + const sp& sc) { + return setFlags(sc, 0, layer_state_t::eLayerHidden); +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::hide( + const sp& sc) { + return setFlags(sc, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden); +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSize( + const sp& sc, uint32_t w, uint32_t h) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eSizeChanged; s->w = w; s->h = h; @@ -335,41 +209,41 @@ status_t Composer::setSize(const sp& client, // Resizing a surface makes the transaction synchronous. mForceSynchronous = true; - return NO_ERROR; + return *this; } -status_t Composer::setLayer(const sp& client, - const sp& id, int32_t z) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer( + const sp& sc, int32_t z) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eLayerChanged; s->z = z; - return NO_ERROR; + return *this; } -status_t Composer::setRelativeLayer(const sp& client, - const sp& id, const sp& relativeTo, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelativeLayer(const sp& sc, const sp& relativeTo, int32_t z) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; } s->what |= layer_state_t::eRelativeLayerChanged; s->relativeLayerHandle = relativeTo; s->z = z; - return NO_ERROR; + return *this; } -status_t Composer::setFlags(const sp& client, - const sp& id, uint32_t flags, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags( + const sp& sc, uint32_t flags, uint32_t mask) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) || (mask & layer_state_t::eLayerSecure)) { @@ -378,61 +252,54 @@ status_t Composer::setFlags(const sp& client, s->flags &= ~mask; s->flags |= (flags & mask); s->mask |= mask; - return NO_ERROR; + return *this; } -status_t Composer::setTransparentRegionHint( - const sp& client, const sp& id, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTransparentRegionHint( + const sp& sc, const Region& transparentRegion) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eTransparentRegionChanged; s->transparentRegion = transparentRegion; - return NO_ERROR; + return *this; } -status_t Composer::setAlpha(const sp& client, - const sp& id, float alpha) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha( + const sp& sc, float alpha) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eAlphaChanged; s->alpha = alpha; - return NO_ERROR; + return *this; } -status_t Composer::setColor(const sp& client, - const sp& id, const half3& color) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; - s->what |= layer_state_t::eColorChanged; - s->color = color; - return NO_ERROR; -} - -status_t Composer::setLayerStack(const sp& client, - const sp& id, uint32_t layerStack) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayerStack( + const sp& sc, uint32_t layerStack) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eLayerStackChanged; s->layerStack = layerStack; - return NO_ERROR; + return *this; } -status_t Composer::setMatrix(const sp& client, - const sp& id, float dsdx, float dtdx, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMatrix( + const sp& sc, float dsdx, float dtdx, float dtdy, float dsdy) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eMatrixChanged; layer_state_t::matrix22_t matrix; matrix.dsdx = dsdx; @@ -440,106 +307,115 @@ status_t Composer::setMatrix(const sp& client, matrix.dsdy = dsdy; matrix.dtdy = dtdy; s->matrix = matrix; - return NO_ERROR; + return *this; } -status_t Composer::setCrop(const sp& client, - const sp& id, const Rect& crop) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); - if (!s) - return BAD_INDEX; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( + const sp& sc, const Rect& crop) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } s->what |= layer_state_t::eCropChanged; s->crop = crop; - return NO_ERROR; + return *this; } -status_t Composer::setFinalCrop(const sp& client, - const sp& id, const Rect& crop) { - Mutex::Autolock _l(mLock); - layer_state_t* s = getLayerStateLocked(client, id); +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFinalCrop(const sp& sc, const Rect& crop) { + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eFinalCropChanged; s->finalCrop = crop; - return NO_ERROR; + return *this; } -status_t Composer::deferTransactionUntil( - const sp& client, const sp& id, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::deferTransactionUntil( + const sp& sc, const sp& handle, uint64_t frameNumber) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eDeferTransaction; s->barrierHandle = handle; s->frameNumber = frameNumber; - return NO_ERROR; + return *this; } -status_t Composer::deferTransactionUntil( - const sp& client, const sp& id, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::deferTransactionUntil( + const sp& sc, const sp& barrierSurface, uint64_t frameNumber) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eDeferTransaction; s->barrierGbp = barrierSurface->getIGraphicBufferProducer(); s->frameNumber = frameNumber; - return NO_ERROR; + return *this; } -status_t Composer::reparentChildren( - const sp& client, - const sp& id, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparentChildren( + const sp& sc, const sp& newParentHandle) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eReparentChildren; s->reparentHandle = newParentHandle; - return NO_ERROR; + return *this; } -status_t Composer::reparent(const sp& client, - const sp& id, +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent( + const sp& sc, const sp& newParentHandle) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eReparent; s->parentHandleForChild = newParentHandle; - return NO_ERROR; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor( + const sp& sc, + const half3& color) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eColorChanged; + s->color = color; + return *this; } -status_t Composer::detachChildren( - const sp& client, - const sp& id) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachChildren( + const sp& sc) { + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; } s->what |= layer_state_t::eDetachChildren; - return NO_ERROR; + return *this; } -status_t Composer::setOverrideScalingMode( - const sp& client, - const sp& id, int32_t overrideScalingMode) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setOverrideScalingMode( + const sp& sc, int32_t overrideScalingMode) { + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } switch (overrideScalingMode) { @@ -552,29 +428,29 @@ status_t Composer::setOverrideScalingMode( default: ALOGE("unknown scaling mode: %d", overrideScalingMode); - return BAD_VALUE; + mStatus = BAD_VALUE; + return *this; } s->what |= layer_state_t::eOverrideScalingModeChanged; s->overrideScalingMode = overrideScalingMode; - return NO_ERROR; + return *this; } -status_t Composer::setGeometryAppliesWithResize( - const sp& client, - const sp& id) { - Mutex::Autolock lock(mLock); - layer_state_t* s = getLayerStateLocked(client, id); +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeometryAppliesWithResize( + const sp& sc) { + layer_state_t* s = getLayerStateLocked(sc); if (!s) { - return BAD_INDEX; + mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eGeometryAppliesWithResize; - return NO_ERROR; + return *this; } // --------------------------------------------------------------------------- -DisplayState& Composer::getDisplayStateLocked(const sp& token) { +DisplayState& SurfaceComposerClient::Transaction::getDisplayStateLocked(const sp& token) { DisplayState s; s.token = token; ssize_t index = mDisplayStates.indexOf(s); @@ -586,8 +462,8 @@ DisplayState& Composer::getDisplayStateLocked(const sp& token) { return mDisplayStates.editItemAt(static_cast(index)); } -status_t Composer::setDisplaySurface(const sp& token, - sp bufferProducer) { +status_t SurfaceComposerClient::Transaction::setDisplaySurface(const sp& token, + const sp& bufferProducer) { if (bufferProducer.get() != nullptr) { // Make sure that composition can never be stalled by a virtual display // consumer that isn't processing buffers fast enough. @@ -599,26 +475,23 @@ status_t Composer::setDisplaySurface(const sp& token, return err; } } - Mutex::Autolock _l(mLock); DisplayState& s(getDisplayStateLocked(token)); s.surface = bufferProducer; s.what |= DisplayState::eSurfaceChanged; return NO_ERROR; } -void Composer::setDisplayLayerStack(const sp& token, +void SurfaceComposerClient::Transaction::setDisplayLayerStack(const sp& token, uint32_t layerStack) { - Mutex::Autolock _l(mLock); DisplayState& s(getDisplayStateLocked(token)); s.layerStack = layerStack; s.what |= DisplayState::eLayerStackChanged; } -void Composer::setDisplayProjection(const sp& token, +void SurfaceComposerClient::Transaction::setDisplayProjection(const sp& token, uint32_t orientation, const Rect& layerStackRect, const Rect& displayRect) { - Mutex::Autolock _l(mLock); DisplayState& s(getDisplayStateLocked(token)); s.orientation = orientation; s.viewport = layerStackRect; @@ -627,8 +500,7 @@ void Composer::setDisplayProjection(const sp& token, mForceSynchronous = true; // TODO: do we actually still need this? } -void Composer::setDisplaySize(const sp& token, uint32_t width, uint32_t height) { - Mutex::Autolock _l(mLock); +void SurfaceComposerClient::Transaction::setDisplaySize(const sp& token, uint32_t width, uint32_t height) { DisplayState& s(getDisplayStateLocked(token)); s.width = width; s.height = height; @@ -638,22 +510,22 @@ void Composer::setDisplaySize(const sp& token, uint32_t width, uint32_t // --------------------------------------------------------------------------- SurfaceComposerClient::SurfaceComposerClient() - : mStatus(NO_INIT), mComposer(Composer::getInstance()) + : mStatus(NO_INIT) { } SurfaceComposerClient::SurfaceComposerClient(const sp& root) - : mStatus(NO_INIT), mComposer(Composer::getInstance()), mParent(root) + : mStatus(NO_INIT), mParent(root) { } void SurfaceComposerClient::onFirstRef() { - sp sm(ComposerService::getComposerService()); - if (sm != 0) { + sp sf(ComposerService::getComposerService()); + if (sf != 0) { auto rootProducer = mParent.promote(); sp conn; - conn = (rootProducer != nullptr) ? sm->createScopedConnection(rootProducer) : - sm->createConnection(); + conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : + sf->createConnection(); if (conn != 0) { mClient = conn; mStatus = NO_ERROR; @@ -676,8 +548,8 @@ sp SurfaceComposerClient::connection() const { status_t SurfaceComposerClient::linkToComposerDeath( const sp& recipient, void* cookie, uint32_t flags) { - sp sm(ComposerService::getComposerService()); - return IInterface::asBinder(sm)->linkToDeath(recipient, cookie, flags); + sp sf(ComposerService::getComposerService()); + return IInterface::asBinder(sf)->linkToDeath(recipient, cookie, flags); } void SurfaceComposerClient::dispose() { @@ -720,19 +592,6 @@ sp SurfaceComposerClient::createSurface( return sur; } -sp SurfaceComposerClient::createDisplay(const String8& displayName, - bool secure) { - return Composer::getInstance().createDisplay(displayName, secure); -} - -void SurfaceComposerClient::destroyDisplay(const sp& display) { - Composer::getInstance().destroyDisplay(display); -} - -sp SurfaceComposerClient::getBuiltInDisplay(int32_t id) { - return Composer::getInstance().getBuiltInDisplay(id); -} - status_t SurfaceComposerClient::destroySurface(const sp& sid) { if (mStatus != NO_ERROR) return mStatus; @@ -755,161 +614,18 @@ status_t SurfaceComposerClient::getLayerFrameStats(const sp& token, return mClient->getLayerFrameStats(token, outStats); } -inline Composer& SurfaceComposerClient::getComposer() { - return mComposer; -} - // ---------------------------------------------------------------------------- -void SurfaceComposerClient::openGlobalTransaction() { - Composer::openGlobalTransaction(); -} - -void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { - Composer::closeGlobalTransaction(synchronous); -} - -void SurfaceComposerClient::setAnimationTransaction() { - Composer::setAnimationTransaction(); -} - status_t SurfaceComposerClient::enableVSyncInjections(bool enable) { - return Composer::enableVSyncInjections(enable); + sp sf(ComposerService::getComposerService()); + return sf->enableVSyncInjections(enable); } status_t SurfaceComposerClient::injectVSync(nsecs_t when) { - return Composer::injectVSync(when); -} - -// ---------------------------------------------------------------------------- - -status_t SurfaceComposerClient::setCrop(const sp& id, const Rect& crop) { - return getComposer().setCrop(this, id, crop); -} - -status_t SurfaceComposerClient::setFinalCrop(const sp& id, - const Rect& crop) { - return getComposer().setFinalCrop(this, id, crop); -} - -status_t SurfaceComposerClient::setPosition(const sp& id, float x, float y) { - return getComposer().setPosition(this, id, x, y); + sp sf(ComposerService::getComposerService()); + return sf->injectVSync(when); } -status_t SurfaceComposerClient::setSize(const sp& id, uint32_t w, uint32_t h) { - return getComposer().setSize(this, id, w, h); -} - -status_t SurfaceComposerClient::setLayer(const sp& id, int32_t z) { - return getComposer().setLayer(this, id, z); -} - -status_t SurfaceComposerClient::setRelativeLayer(const sp& id, - const sp& relativeTo, int32_t z) { - return getComposer().setRelativeLayer(this, id, relativeTo, z); -} - -status_t SurfaceComposerClient::hide(const sp& id) { - return getComposer().setFlags(this, id, - layer_state_t::eLayerHidden, - layer_state_t::eLayerHidden); -} - -status_t SurfaceComposerClient::show(const sp& id) { - return getComposer().setFlags(this, id, - 0, - layer_state_t::eLayerHidden); -} - -status_t SurfaceComposerClient::setFlags(const sp& id, uint32_t flags, - uint32_t mask) { - return getComposer().setFlags(this, id, flags, mask); -} - -status_t SurfaceComposerClient::setTransparentRegionHint(const sp& id, - const Region& transparentRegion) { - return getComposer().setTransparentRegionHint(this, id, transparentRegion); -} - -status_t SurfaceComposerClient::setAlpha(const sp& id, float alpha) { - return getComposer().setAlpha(this, id, alpha); -} - -status_t SurfaceComposerClient::setColor(const sp& id, const half3& color) { - return getComposer().setColor(this, id, color); -} - -status_t SurfaceComposerClient::setLayerStack(const sp& id, uint32_t layerStack) { - return getComposer().setLayerStack(this, id, layerStack); -} - -status_t SurfaceComposerClient::setMatrix(const sp& id, float dsdx, float dtdx, - float dtdy, float dsdy) { - return getComposer().setMatrix(this, id, dsdx, dtdx, dtdy, dsdy); -} - -status_t SurfaceComposerClient::deferTransactionUntil(const sp& id, - const sp& handle, uint64_t frameNumber) { - return getComposer().deferTransactionUntil(this, id, handle, frameNumber); -} - -status_t SurfaceComposerClient::deferTransactionUntil(const sp& id, - const sp& barrierSurface, uint64_t frameNumber) { - return getComposer().deferTransactionUntil(this, id, barrierSurface, frameNumber); -} - -status_t SurfaceComposerClient::reparentChildren(const sp& id, - const sp& newParentHandle) { - return getComposer().reparentChildren(this, id, newParentHandle); -} - -status_t SurfaceComposerClient::reparent(const sp& id, - const sp& newParentHandle) { - return getComposer().reparent(this, id, newParentHandle); -} - -status_t SurfaceComposerClient::detachChildren(const sp& id) { - return getComposer().detachChildren(this, id); -} - -status_t SurfaceComposerClient::setOverrideScalingMode( - const sp& id, int32_t overrideScalingMode) { - return getComposer().setOverrideScalingMode( - this, id, overrideScalingMode); -} - -status_t SurfaceComposerClient::setGeometryAppliesWithResize( - const sp& id) { - return getComposer().setGeometryAppliesWithResize(this, id); -} - -// ---------------------------------------------------------------------------- - -status_t SurfaceComposerClient::setDisplaySurface(const sp& token, - sp bufferProducer) { - return Composer::getInstance().setDisplaySurface(token, bufferProducer); -} - -void SurfaceComposerClient::setDisplayLayerStack(const sp& token, - uint32_t layerStack) { - Composer::getInstance().setDisplayLayerStack(token, layerStack); -} - -void SurfaceComposerClient::setDisplayProjection(const sp& token, - uint32_t orientation, - const Rect& layerStackRect, - const Rect& displayRect) { - Composer::getInstance().setDisplayProjection(token, orientation, - layerStackRect, displayRect); -} - -void SurfaceComposerClient::setDisplaySize(const sp& token, - uint32_t width, uint32_t height) { - Composer::getInstance().setDisplaySize(token, width, height); -} - -// ---------------------------------------------------------------------------- - status_t SurfaceComposerClient::getDisplayConfigs( const sp& display, Vector* configs) { diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 9e1d7b6647..f6a2b8fed6 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -97,123 +97,6 @@ bool SurfaceControl::isSameSurface( return lhs->mHandle == rhs->mHandle; } -status_t SurfaceControl::setLayerStack(uint32_t layerStack) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setLayerStack(mHandle, layerStack); -} - -status_t SurfaceControl::setLayer(int32_t layer) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setLayer(mHandle, layer); -} - -status_t SurfaceControl::setRelativeLayer(const sp& relativeTo, int32_t layer) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setRelativeLayer(mHandle, relativeTo, layer); -} - -status_t SurfaceControl::setPosition(float x, float y) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setPosition(mHandle, x, y); -} -status_t SurfaceControl::setGeometryAppliesWithResize() { - status_t err = validate(); - if (err < 0) return err; - return mClient->setGeometryAppliesWithResize(mHandle); -} -status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setSize(mHandle, w, h); -} -status_t SurfaceControl::hide() { - status_t err = validate(); - if (err < 0) return err; - return mClient->hide(mHandle); -} -status_t SurfaceControl::show() { - status_t err = validate(); - if (err < 0) return err; - return mClient->show(mHandle); -} -status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setFlags(mHandle, flags, mask); -} -status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setTransparentRegionHint(mHandle, transparent); -} -status_t SurfaceControl::setAlpha(float alpha) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setAlpha(mHandle, alpha); -} -status_t SurfaceControl::setColor(const half3& color) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setColor(mHandle, color); -} -status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setMatrix(mHandle, dsdx, dtdx, dtdy, dsdy); -} -status_t SurfaceControl::setCrop(const Rect& crop) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setCrop(mHandle, crop); -} -status_t SurfaceControl::setFinalCrop(const Rect& crop) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setFinalCrop(mHandle, crop); -} - -status_t SurfaceControl::deferTransactionUntil(const sp& handle, - uint64_t frameNumber) { - status_t err = validate(); - if (err < 0) return err; - return mClient->deferTransactionUntil(mHandle, handle, frameNumber); -} - -status_t SurfaceControl::deferTransactionUntil(const sp& handle, - uint64_t frameNumber) { - status_t err = validate(); - if (err < 0) return err; - return mClient->deferTransactionUntil(mHandle, handle, frameNumber); -} - -status_t SurfaceControl::reparentChildren(const sp& newParentHandle) { - status_t err = validate(); - if (err < 0) return err; - return mClient->reparentChildren(mHandle, newParentHandle); -} - -status_t SurfaceControl::reparent(const sp& newParentHandle) { - status_t err = validate(); - if (err < 0) return err; - return mClient->reparent(mHandle, newParentHandle); -} - -status_t SurfaceControl::detachChildren() { - status_t err = validate(); - if (err < 0) return err; - return mClient->detachChildren(mHandle); -} - -status_t SurfaceControl::setOverrideScalingMode(int32_t overrideScalingMode) { - status_t err = validate(); - if (err < 0) return err; - return mClient->setOverrideScalingMode(mHandle, overrideScalingMode); -} - status_t SurfaceControl::clearLayerFrameStats() const { status_t err = validate(); if (err < 0) return err; @@ -278,5 +161,10 @@ sp SurfaceControl::getHandle() const return mHandle; } +sp SurfaceControl::getClient() const +{ + return mClient; +} + // ---------------------------------------------------------------------------- }; // namespace android diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h new file mode 100644 index 0000000000..ae6965a0fc --- /dev/null +++ b/libs/gui/include/gui/LayerState.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SF_LAYER_STATE_H +#define ANDROID_SF_LAYER_STATE_H + +#include +#include + +#include + +#include +#include +#include +#include + +namespace android { + +class Parcel; +class ISurfaceComposerClient; + +/* + * Used to communicate layer information between SurfaceFlinger and its clients. + */ +struct layer_state_t { + + + enum { + eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java + eLayerOpaque = 0x02, // SURFACE_OPAQUE + eLayerSecure = 0x80, // SECURE + }; + + enum { + ePositionChanged = 0x00000001, + eLayerChanged = 0x00000002, + eSizeChanged = 0x00000004, + eAlphaChanged = 0x00000008, + eMatrixChanged = 0x00000010, + eTransparentRegionChanged = 0x00000020, + eFlagsChanged = 0x00000040, + eLayerStackChanged = 0x00000080, + eCropChanged = 0x00000100, + eDeferTransaction = 0x00000200, + eFinalCropChanged = 0x00000400, + eOverrideScalingModeChanged = 0x00000800, + eGeometryAppliesWithResize = 0x00001000, + eReparentChildren = 0x00002000, + eDetachChildren = 0x00004000, + eRelativeLayerChanged = 0x00008000, + eReparent = 0x00010000, + eColorChanged = 0x00020000 + }; + + layer_state_t() + : what(0), + x(0), y(0), z(0), w(0), h(0), layerStack(0), + alpha(0), flags(0), mask(0), + reserved(0), crop(Rect::INVALID_RECT), + finalCrop(Rect::INVALID_RECT), frameNumber(0), + overrideScalingMode(-1) + { + matrix.dsdx = matrix.dtdy = 1.0f; + matrix.dsdy = matrix.dtdx = 0.0f; + } + + status_t write(Parcel& output) const; + status_t read(const Parcel& input); + + struct matrix22_t { + float dsdx{0}; + float dtdx{0}; + float dtdy{0}; + float dsdy{0}; + }; + sp surface; + uint32_t what; + float x; + float y; + int32_t z; + uint32_t w; + uint32_t h; + uint32_t layerStack; + float alpha; + uint8_t flags; + uint8_t mask; + uint8_t reserved; + matrix22_t matrix; + Rect crop; + Rect finalCrop; + sp barrierHandle; + sp reparentHandle; + uint64_t frameNumber; + int32_t overrideScalingMode; + + sp barrierGbp; + + sp relativeLayerHandle; + + sp parentHandleForChild; + + half3 color; + + // non POD must be last. see write/read + Region transparentRegion; +}; + +struct ComposerState { + sp client; + layer_state_t state; + status_t write(Parcel& output) const; + status_t read(const Parcel& input); +}; + +struct DisplayState { + + enum { + eOrientationDefault = 0, + eOrientation90 = 1, + eOrientation180 = 2, + eOrientation270 = 3, + eOrientationUnchanged = 4, + eOrientationSwapMask = 0x01 + }; + + enum { + eSurfaceChanged = 0x01, + eLayerStackChanged = 0x02, + eDisplayProjectionChanged = 0x04, + eDisplaySizeChanged = 0x08 + }; + + DisplayState(); + + uint32_t what; + sp token; + sp surface; + uint32_t layerStack; + uint32_t orientation; + Rect viewport; + Rect frame; + uint32_t width, height; + status_t write(Parcel& output) const; + status_t read(const Parcel& input); +}; + +static inline +int compare_type(const ComposerState& lhs, const ComposerState& rhs) { + if (lhs.client < rhs.client) return -1; + if (lhs.client > rhs.client) return 1; + if (lhs.state.surface < rhs.state.surface) return -1; + if (lhs.state.surface > rhs.state.surface) return 1; + return 0; +} + +static inline +int compare_type(const DisplayState& lhs, const DisplayState& rhs) { + return compare_type(lhs.token, rhs.token); +} + +}; // namespace android + +#endif // ANDROID_SF_LAYER_STATE_H + diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 17181430c7..00d593638d 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -33,13 +33,13 @@ #include #include #include +#include namespace android { // --------------------------------------------------------------------------- struct DisplayInfo; -class Composer; class HdrCapabilities; class ISurfaceComposerClient; class IGraphicBufferProducer; @@ -122,93 +122,158 @@ public: //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. static sp getBuiltInDisplay(int32_t id); - // ------------------------------------------------------------------------ - // Composer parameters - // All composer parameters must be changed within a transaction - // several surfaces can be updated in one transaction, all changes are - // committed at once when the transaction is closed. - // closeGlobalTransaction() requires an IPC with the server. - - //! Open a composer transaction on all active SurfaceComposerClients. - static void openGlobalTransaction(); - - //! Close a composer transaction on all active SurfaceComposerClients. - static void closeGlobalTransaction(bool synchronous = false); - static status_t enableVSyncInjections(bool enable); static status_t injectVSync(nsecs_t when); - //! Flag the currently open transaction as an animation transaction. - static void setAnimationTransaction(); - - status_t hide(const sp& id); - status_t show(const sp& id); - status_t setFlags(const sp& id, uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(const sp& id, const Region& transparent); - status_t setLayer(const sp& id, int32_t layer); - status_t setRelativeLayer(const sp& id, - const sp& relativeTo, int32_t layer); - status_t setAlpha(const sp& id, float alpha=1.0f); - status_t setColor(const sp& id, const half3& color); - status_t setMatrix(const sp& id, float dsdx, float dtdx, float dtdy, float dsdy); - status_t setPosition(const sp& id, float x, float y); - status_t setSize(const sp& id, uint32_t w, uint32_t h); - status_t setCrop(const sp& id, const Rect& crop); - status_t setFinalCrop(const sp& id, const Rect& crop); - status_t setLayerStack(const sp& id, uint32_t layerStack); - status_t deferTransactionUntil(const sp& id, - const sp& handle, uint64_t frameNumber); - status_t deferTransactionUntil(const sp& id, - const sp& handle, uint64_t frameNumber); - status_t reparentChildren(const sp& id, - const sp& newParentHandle); - status_t reparent(const sp& id, const sp& newParentHandle); - status_t detachChildren(const sp& id); - status_t setOverrideScalingMode(const sp& id, - int32_t overrideScalingMode); - status_t setGeometryAppliesWithResize(const sp& id); + class Transaction { + SortedVector mComposerStates; + SortedVector mDisplayStates; + uint32_t mForceSynchronous = 0; + uint32_t mTransactionNestCount = 0; + bool mAnimation = false; + + int mStatus = NO_ERROR; + + layer_state_t* getLayerStateLocked(const sp& sc); + DisplayState& getDisplayStateLocked(const sp& token); + + public: + Transaction() = default; + virtual ~Transaction() = default; + Transaction(Transaction const& other); + + status_t apply(bool synchronous = false); + + Transaction& show(const sp& sc); + Transaction& hide(const sp& sc); + Transaction& setPosition(const sp& sc, + float x, float y); + Transaction& setSize(const sp& sc, + uint32_t w, uint32_t h); + Transaction& setLayer(const sp& sc, + int32_t z); + + // Sets a Z order relative to the Surface specified by "relativeTo" but + // without becoming a full child of the relative. Z-ordering works exactly + // as if it were a child however. + // + // As a nod to sanity, only non-child surfaces may have a relative Z-order. + // + // This overrides any previous call and is overriden by any future calls + // to setLayer. + // + // If the relative is removed, the Surface will have no layer and be + // invisible, until the next time set(Relative)Layer is called. + Transaction& setRelativeLayer(const sp& sc, + const sp& relativeTo, int32_t z); + Transaction& setFlags(const sp& sc, + uint32_t flags, uint32_t mask); + Transaction& setTransparentRegionHint(const sp& sc, + const Region& transparentRegion); + Transaction& setAlpha(const sp& sc, + float alpha); + Transaction& setMatrix(const sp& sc, + float dsdx, float dtdx, float dtdy, float dsdy); + Transaction& setOrientation(const sp& sc, + const Rect& crop); + Transaction& setCrop(const sp& sc, const Rect& crop); + Transaction& setFinalCrop(const sp& sc, const Rect& crop); + Transaction& setLayerStack(const sp& sc, uint32_t layerStack); + // Defers applying any changes made in this transaction until the Layer + // identified by handle reaches the given frameNumber. If the Layer identified + // by handle is removed, then we will apply this transaction regardless of + // what frame number has been reached. + Transaction& deferTransactionUntil(const sp& sc, + const sp& handle, + uint64_t frameNumber); + // A variant of deferTransactionUntil which identifies the Layer we wait for by + // Surface instead of Handle. Useful for clients which may not have the + // SurfaceControl for some of their Surfaces. Otherwise behaves identically. + Transaction& deferTransactionUntil(const sp& sc, + const sp& barrierSurface, + uint64_t frameNumber); + // Reparents all children of this layer to the new parent handle. + Transaction& reparentChildren(const sp& sc, + const sp& newParentHandle); + + /// Reparents the current layer to the new parent handle. The new parent must not be null. + // This can be used instead of reparentChildren if the caller wants to + // only re-parent a specific child. + Transaction& reparent(const sp& sc, + const sp& newParentHandle); + + Transaction& setColor(const sp& sc, const half3& color); + + // Detaches all child surfaces (and their children recursively) + // from their SurfaceControl. + // The child SurfaceControls will not throw exceptions or return errors, + // but transactions will have no effect. + // The child surfaces will continue to follow their parent surfaces, + // and remain eligible for rendering, but their relative state will be + // frozen. We use this in the WindowManager, in app shutdown/relaunch + // scenarios, where the app would otherwise clean up its child Surfaces. + // Sometimes the WindowManager needs to extend their lifetime slightly + // in order to perform an exit animation or prevent flicker. + Transaction& detachChildren(const sp& sc); + // Set an override scaling mode as documented in + // the override scaling mode will take precedence over any client + // specified scaling mode. -1 will clear the override scaling mode. + Transaction& setOverrideScalingMode(const sp& sc, + int32_t overrideScalingMode); + + // If the size changes in this transaction, all geometry updates specified + // in this transaction will not complete until a buffer of the new size + // arrives. As some elements normally apply immediately, this enables + // freezing the total geometry of a surface until a resize is completed. + Transaction& setGeometryAppliesWithResize(const sp& sc); + + status_t setDisplaySurface(const sp& token, + const sp& bufferProducer); + + void setDisplayLayerStack(const sp& token, uint32_t layerStack); + + /* setDisplayProjection() defines the projection of layer stacks + * to a given display. + * + * - orientation defines the display's orientation. + * - layerStackRect defines which area of the window manager coordinate + * space will be used. + * - displayRect defines where on the display will layerStackRect be + * mapped to. displayRect is specified post-orientation, that is + * it uses the orientation seen by the end-user. + */ + void setDisplayProjection(const sp& token, + uint32_t orientation, + const Rect& layerStackRect, + const Rect& displayRect); + void setDisplaySize(const sp& token, uint32_t width, uint32_t height); + void setAnimationTransaction(); + }; status_t destroySurface(const sp& id); status_t clearLayerFrameStats(const sp& token) const; status_t getLayerFrameStats(const sp& token, FrameStats* outStats) const; - static status_t clearAnimationFrameStats(); static status_t getAnimationFrameStats(FrameStats* outStats); static status_t getHdrCapabilities(const sp& display, HdrCapabilities* outCapabilities); - static status_t setDisplaySurface(const sp& token, - sp bufferProducer); - static void setDisplayLayerStack(const sp& token, - uint32_t layerStack); - static void setDisplaySize(const sp& token, uint32_t width, uint32_t height); - - /* setDisplayProjection() defines the projection of layer stacks - * to a given display. - * - * - orientation defines the display's orientation. - * - layerStackRect defines which area of the window manager coordinate - * space will be used. - * - displayRect defines where on the display will layerStackRect be - * mapped to. displayRect is specified post-orientation, that is - * it uses the orientation seen by the end-user. - */ static void setDisplayProjection(const sp& token, uint32_t orientation, const Rect& layerStackRect, const Rect& displayRect); + inline sp getClient() { return mClient; } + private: virtual void onFirstRef(); - Composer& getComposer(); mutable Mutex mLock; status_t mStatus; sp mClient; - Composer& mComposer; wp mParent; }; diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index e98e26a391..384815dad8 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -61,93 +61,6 @@ public: // disconnect any api that's connected void disconnect(); - status_t setLayerStack(uint32_t layerStack); - status_t setLayer(int32_t layer); - - // Sets a Z order relative to the Surface specified by "relativeTo" but - // without becoming a full child of the relative. Z-ordering works exactly - // as if it were a child however. - // - // As a nod to sanity, only non-child surfaces may have a relative Z-order. - // - // This overrides any previous and is overriden by any future calls - // to setLayer. - // - // If the relative dissapears, the Surface will have no layer and be - // invisible, until the next time set(Relative)Layer is called. - // - // TODO: This is probably a hack. Currently it exists only to work around - // some framework usage of the hidden APPLICATION_MEDIA_OVERLAY window type - // which allows inserting a window between a SurfaceView and it's main application - // window. However, since we are using child windows for the SurfaceView, but not using - // child windows elsewhere in O, the WindowManager can't set the layer appropriately. - // This is only used by the "TvInputService" and following the port of ViewRootImpl - // to child surfaces, we can then port this and remove this method. - status_t setRelativeLayer(const sp& relativeTo, int32_t layer); - status_t setPosition(float x, float y); - status_t setSize(uint32_t w, uint32_t h); - status_t hide(); - status_t show(); - status_t setFlags(uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(const Region& transparent); - status_t setAlpha(float alpha=1.0f); - status_t setColor(const half3& color); - - // Experimentarily it appears that the matrix transforms the - // on-screen rectangle and it's contents before the position is - // applied. - // - // TODO: Test with other combinations to find approximate transformation rules. - // - // For example: - // Layer sized (W,H) set to position (x,y) with matrix M=[-1, 0, 0, 1] (Horizontal flip) gives - // [((0, 0), (W, H)) x M] + (x,y) = ((-W, 0), (0, H)) + (x,y) = ((-W + x, y), (x, H+y)) - status_t setMatrix(float dsdx, float dtdx, float dtdy, float dsdy); - status_t setCrop(const Rect& crop); - status_t setFinalCrop(const Rect& crop); - - // If the size changes in this transaction, all geometry updates specified - // in this transaction will not complete until a buffer of the new size - // arrives. As some elements normally apply immediately, this enables - // freezing the total geometry of a surface until a resize is completed. - status_t setGeometryAppliesWithResize(); - - // Defers applying any changes made in this transaction until the Layer - // identified by handle reaches the given frameNumber. If the Layer identified - // by handle is removed, then we will apply this transaction regardless of - // what frame number has been reached. - status_t deferTransactionUntil(const sp& handle, uint64_t frameNumber); - - // A variant of deferTransactionUntil which identifies the Layer we wait for by - // Surface instead of Handle. Useful for clients which may not have the - // SurfaceControl for some of their Surfaces. Otherwise behaves identically. - status_t deferTransactionUntil(const sp& barrier, uint64_t frameNumber); - - // Reparents all children of this layer to the new parent handle. - status_t reparentChildren(const sp& newParentHandle); - - // Reparents the current layer to the new parent handle. The new parent must not be null. - // This can be used instead of reparentChildren if the caller wants to - // only re-parent a specific child. - status_t reparent(const sp& newParentHandle); - - // Detaches all child surfaces (and their children recursively) - // from their SurfaceControl. - // The child SurfaceControl's will not throw exceptions or return errors, - // but transactions will have no effect. - // The child surfaces will continue to follow their parent surfaces, - // and remain eligible for rendering, but their relative state will be - // frozen. We use this in the WindowManager, in app shutdown/relaunch - // scenarios, where the app would otherwise clean up its child Surfaces. - // Sometimes the WindowManager needs to extend their lifetime slightly - // in order to perform an exit animation or prevent flicker. - status_t detachChildren(); - - // Set an override scaling mode as documented in - // the override scaling mode will take precedence over any client - // specified scaling mode. -1 will clear the override scaling mode. - status_t setOverrideScalingMode(int32_t overrideScalingMode); - static status_t writeSurfaceToParcel( const sp& control, Parcel* parcel); @@ -158,6 +71,8 @@ public: status_t clearLayerFrameStats() const; status_t getLayerFrameStats(FrameStats* outStats) const; + sp getClient() const; + private: // can't be copied SurfaceControl& operator = (SurfaceControl& rhs); diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h deleted file mode 100644 index bd42634730..0000000000 --- a/libs/gui/include/private/gui/LayerState.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_SF_LAYER_STATE_H -#define ANDROID_SF_LAYER_STATE_H - -#include -#include - -#include - -#include -#include -#include -#include - -namespace android { - -class Parcel; -class ISurfaceComposerClient; - -/* - * Used to communicate layer information between SurfaceFlinger and its clients. - */ -struct layer_state_t { - - - enum { - eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java - eLayerOpaque = 0x02, // SURFACE_OPAQUE - eLayerSecure = 0x80, // SECURE - }; - - enum { - ePositionChanged = 0x00000001, - eLayerChanged = 0x00000002, - eSizeChanged = 0x00000004, - eAlphaChanged = 0x00000008, - eMatrixChanged = 0x00000010, - eTransparentRegionChanged = 0x00000020, - eFlagsChanged = 0x00000040, - eLayerStackChanged = 0x00000080, - eCropChanged = 0x00000100, - eDeferTransaction = 0x00000200, - eFinalCropChanged = 0x00000400, - eOverrideScalingModeChanged = 0x00000800, - eGeometryAppliesWithResize = 0x00001000, - eReparentChildren = 0x00002000, - eDetachChildren = 0x00004000, - eRelativeLayerChanged = 0x00008000, - eReparent = 0x00010000, - eColorChanged = 0x00020000 - }; - - layer_state_t() - : what(0), - x(0), y(0), z(0), w(0), h(0), layerStack(0), - alpha(0), flags(0), mask(0), - reserved(0), crop(Rect::INVALID_RECT), - finalCrop(Rect::INVALID_RECT), frameNumber(0), - overrideScalingMode(-1) - { - matrix.dsdx = matrix.dtdy = 1.0f; - matrix.dsdy = matrix.dtdx = 0.0f; - } - - status_t write(Parcel& output) const; - status_t read(const Parcel& input); - - struct matrix22_t { - float dsdx{0}; - float dtdx{0}; - float dtdy{0}; - float dsdy{0}; - }; - sp surface; - uint32_t what; - float x; - float y; - int32_t z; - uint32_t w; - uint32_t h; - uint32_t layerStack; - float alpha; - uint8_t flags; - uint8_t mask; - uint8_t reserved; - matrix22_t matrix; - Rect crop; - Rect finalCrop; - sp barrierHandle; - sp reparentHandle; - uint64_t frameNumber; - int32_t overrideScalingMode; - - sp barrierGbp; - - sp relativeLayerHandle; - - sp parentHandleForChild; - - half3 color; - - // non POD must be last. see write/read - Region transparentRegion; -}; - -struct ComposerState { - sp client; - layer_state_t state; - status_t write(Parcel& output) const; - status_t read(const Parcel& input); -}; - -struct DisplayState { - - enum { - eOrientationDefault = 0, - eOrientation90 = 1, - eOrientation180 = 2, - eOrientation270 = 3, - eOrientationUnchanged = 4, - eOrientationSwapMask = 0x01 - }; - - enum { - eSurfaceChanged = 0x01, - eLayerStackChanged = 0x02, - eDisplayProjectionChanged = 0x04, - eDisplaySizeChanged = 0x08 - }; - - DisplayState(); - - uint32_t what; - sp token; - sp surface; - uint32_t layerStack; - uint32_t orientation; - Rect viewport; - Rect frame; - uint32_t width, height; - status_t write(Parcel& output) const; - status_t read(const Parcel& input); -}; - -}; // namespace android - -#endif // ANDROID_SF_LAYER_STATE_H - diff --git a/libs/gui/tests/GLTest.cpp b/libs/gui/tests/GLTest.cpp index 1739d9c7ca..a91552f7fe 100644 --- a/libs/gui/tests/GLTest.cpp +++ b/libs/gui/tests/GLTest.cpp @@ -22,6 +22,8 @@ namespace android { +using Transaction = SurfaceComposerClient::Transaction; + static int abs(int value) { return value > 0 ? value : -value; } @@ -68,10 +70,10 @@ void GLTest::SetUp() { ASSERT_TRUE(mSurfaceControl != NULL); ASSERT_TRUE(mSurfaceControl->isValid()); - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF)); - ASSERT_EQ(NO_ERROR, mSurfaceControl->show()); - SurfaceComposerClient::closeGlobalTransaction(); + Transaction t; + ASSERT_EQ(NO_ERROR, t.setLayer(mSurfaceControl, 0x7FFFFFFF) + .show(mSurfaceControl) + .apply()); sp window = mSurfaceControl->getSurface(); mEglSurface = createWindowSurface(mEglDisplay, mGlConfig, window); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 45e95a593b..bfcd75f26c 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -42,6 +42,8 @@ using namespace std::chrono_literals; using namespace android::hardware::configstore; using namespace android::hardware::configstore::V1_0; +using Transaction = SurfaceComposerClient::Transaction; + static bool hasWideColorDisplay = getBool(false); @@ -69,10 +71,10 @@ protected: ASSERT_TRUE(mSurfaceControl != NULL); ASSERT_TRUE(mSurfaceControl->isValid()); - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7fffffff)); - ASSERT_EQ(NO_ERROR, mSurfaceControl->show()); - SurfaceComposerClient::closeGlobalTransaction(); + Transaction t; + ASSERT_EQ(NO_ERROR, t.setLayer(mSurfaceControl, 0x7fffffff) + .show(mSurfaceControl) + .apply()); mSurface = mSurfaceControl->getSurface(); ASSERT_TRUE(mSurface != NULL); diff --git a/opengl/tests/lib/WindowSurface.cpp b/opengl/tests/lib/WindowSurface.cpp index 142894524d..2b76279801 100644 --- a/opengl/tests/lib/WindowSurface.cpp +++ b/opengl/tests/lib/WindowSurface.cpp @@ -62,19 +62,10 @@ WindowSurface::WindowSurface() { return; } - SurfaceComposerClient::openGlobalTransaction(); - err = sc->setLayer(0x7FFFFFFF); // always on top - if (err != NO_ERROR) { - fprintf(stderr, "SurfaceComposer::setLayer error: %#x\n", err); - return; - } - - err = sc->show(); - if (err != NO_ERROR) { - fprintf(stderr, "SurfaceComposer::show error: %#x\n", err); - return; - } - SurfaceComposerClient::closeGlobalTransaction(); + SurfaceComposerClient::Transaction{} + .setLayer(sc, 0x7FFFFFFF) + .show(sc) + .apply(); mSurfaceControl = sc; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 921492b210..47924ae877 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -33,8 +33,7 @@ #include #include - -#include +#include #include diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index e87d35f912..32e4067ece 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -43,14 +43,14 @@ #include #include #include +#include + #include #include #include -#include - #include "Barrier.h" #include "DisplayDevice.h" #include "DispSync.h" diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index 0cc763c740..ed806b87f5 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -22,10 +22,11 @@ #include #include +#include #include #include + #include -#include #include #include @@ -34,6 +35,8 @@ namespace android { +using Transaction = SurfaceComposerClient::Transaction; + constexpr int32_t SCALING_UPDATE = 1; constexpr uint32_t BUFFER_UPDATES = 18; constexpr uint32_t LAYER_UPDATE = INT_MAX - 2; @@ -149,11 +152,11 @@ protected: ASSERT_TRUE(mBGSurfaceControl->isValid()); mBGLayerId = getSurfaceId("BG Interceptor Test Surface"); - SurfaceComposerClient::openGlobalTransaction(); - mComposerClient->setDisplayLayerStack(display, 0); - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT_MAX-3)); - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show()); - SurfaceComposerClient::closeGlobalTransaction(true); + Transaction t; + t.setDisplayLayerStack(display, 0); + ASSERT_EQ(NO_ERROR, t.setLayer(mBGSurfaceControl, INT_MAX-3) + .show(mBGSurfaceControl) + .apply()); } virtual void TearDown() { @@ -169,13 +172,14 @@ protected: int32_t mTargetId; public: - void captureTest(void (SurfaceInterceptorTest::* action)(void), + void captureTest(void (SurfaceInterceptorTest::* action)(Transaction&), bool (SurfaceInterceptorTest::* verification)(Trace *)); - void captureTest(void (SurfaceInterceptorTest::* action)(void), + void captureTest(void (SurfaceInterceptorTest::* action)(Transaction&), SurfaceChange::SurfaceChangeCase changeCase); - void captureTest(void (SurfaceInterceptorTest::* action)(void), + void captureTest(void (SurfaceInterceptorTest::* action)(Transaction&), Increment::IncrementCase incrementCase); - void runInTransaction(void (SurfaceInterceptorTest::* action)(void), bool intercepted = false); + void runInTransaction(void (SurfaceInterceptorTest::* action)(Transaction&), + bool intercepted = false); // Verification of changes to a surface bool positionUpdateFound(const SurfaceChange& change, bool foundPosition); @@ -206,28 +210,29 @@ public: bool bufferUpdatesFound(Trace* trace); // Perform each of the possible changes to a surface - void positionUpdate(); - void sizeUpdate(); - void alphaUpdate(); - void layerUpdate(); - void cropUpdate(); - void finalCropUpdate(); - void matrixUpdate(); - void overrideScalingModeUpdate(); - void transparentRegionHintUpdate(); - void layerStackUpdate(); - void hiddenFlagUpdate(); - void opaqueFlagUpdate(); - void secureFlagUpdate(); - void deferredTransactionUpdate(); - void runAllUpdates(); - void surfaceCreation(); + void positionUpdate(Transaction&); + void sizeUpdate(Transaction&); + void alphaUpdate(Transaction&); + void layerUpdate(Transaction&); + void cropUpdate(Transaction&); + void finalCropUpdate(Transaction&); + void matrixUpdate(Transaction&); + void overrideScalingModeUpdate(Transaction&); + void transparentRegionHintUpdate(Transaction&); + void layerStackUpdate(Transaction&); + void hiddenFlagUpdate(Transaction&); + void opaqueFlagUpdate(Transaction&); + void secureFlagUpdate(Transaction&); + void deferredTransactionUpdate(Transaction&); + void surfaceCreation(Transaction&); + void displayCreation(Transaction&); + void displayDeletion(Transaction&); + void nBufferUpdates(); - void displayCreation(); - void displayDeletion(); + void runAllUpdates(); }; -void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action)(void), +void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action)(Transaction&), bool (SurfaceInterceptorTest::* verification)(Trace *)) { runInTransaction(action, true); @@ -236,7 +241,7 @@ void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action) ASSERT_TRUE((this->*verification)(&capturedTrace)); } -void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action)(void), +void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action)(Transaction&), Increment::IncrementCase incrementCase) { runInTransaction(action, true); @@ -245,7 +250,7 @@ void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action) ASSERT_TRUE(singleIncrementFound(&capturedTrace, incrementCase)); } -void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action)(void), +void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action)(Transaction&), SurfaceChange::SurfaceChangeCase changeCase) { runInTransaction(action, true); @@ -254,83 +259,84 @@ void SurfaceInterceptorTest::captureTest(void (SurfaceInterceptorTest::* action) ASSERT_TRUE(surfaceUpdateFound(&capturedTrace, changeCase)); } -void SurfaceInterceptorTest::runInTransaction(void (SurfaceInterceptorTest::* action)(void), +void SurfaceInterceptorTest::runInTransaction(void (SurfaceInterceptorTest::* action)(Transaction&), bool intercepted) { if (intercepted) { enableInterceptor(); } - SurfaceComposerClient::openGlobalTransaction(); - (this->*action)(); - SurfaceComposerClient::closeGlobalTransaction(true); + Transaction t; + (this->*action)(t); + t.apply(true); + if (intercepted) { disableInterceptor(); } } -void SurfaceInterceptorTest::positionUpdate() { - mBGSurfaceControl->setPosition(POSITION_UPDATE, POSITION_UPDATE); +void SurfaceInterceptorTest::positionUpdate(Transaction& t) { + t.setPosition(mBGSurfaceControl, POSITION_UPDATE, POSITION_UPDATE); } -void SurfaceInterceptorTest::sizeUpdate() { - mBGSurfaceControl->setSize(SIZE_UPDATE, SIZE_UPDATE); +void SurfaceInterceptorTest::sizeUpdate(Transaction& t) { + t.setSize(mBGSurfaceControl, SIZE_UPDATE, SIZE_UPDATE); } -void SurfaceInterceptorTest::alphaUpdate() { - mBGSurfaceControl->setAlpha(ALPHA_UPDATE); +void SurfaceInterceptorTest::alphaUpdate(Transaction& t) { + t.setAlpha(mBGSurfaceControl, ALPHA_UPDATE); } -void SurfaceInterceptorTest::layerUpdate() { - mBGSurfaceControl->setLayer(LAYER_UPDATE); +void SurfaceInterceptorTest::layerUpdate(Transaction& t) { + t.setLayer(mBGSurfaceControl, LAYER_UPDATE); } -void SurfaceInterceptorTest::cropUpdate() { - mBGSurfaceControl->setCrop(CROP_UPDATE); +void SurfaceInterceptorTest::cropUpdate(Transaction& t) { + t.setCrop(mBGSurfaceControl, CROP_UPDATE); } -void SurfaceInterceptorTest::finalCropUpdate() { - mBGSurfaceControl->setFinalCrop(CROP_UPDATE); +void SurfaceInterceptorTest::finalCropUpdate(Transaction& t) { + t.setFinalCrop(mBGSurfaceControl, CROP_UPDATE); } -void SurfaceInterceptorTest::matrixUpdate() { - mBGSurfaceControl->setMatrix(M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2); +void SurfaceInterceptorTest::matrixUpdate(Transaction& t) { + t.setMatrix(mBGSurfaceControl, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2); } -void SurfaceInterceptorTest::overrideScalingModeUpdate() { - mBGSurfaceControl->setOverrideScalingMode(SCALING_UPDATE); +void SurfaceInterceptorTest::overrideScalingModeUpdate(Transaction& t) { + t.setOverrideScalingMode(mBGSurfaceControl, SCALING_UPDATE); } -void SurfaceInterceptorTest::transparentRegionHintUpdate() { +void SurfaceInterceptorTest::transparentRegionHintUpdate(Transaction& t) { Region region(CROP_UPDATE); - mBGSurfaceControl->setTransparentRegionHint(region); + t.setTransparentRegionHint(mBGSurfaceControl, region); } -void SurfaceInterceptorTest::layerStackUpdate() { - mBGSurfaceControl->setLayerStack(STACK_UPDATE); +void SurfaceInterceptorTest::layerStackUpdate(Transaction& t) { + t.setLayerStack(mBGSurfaceControl, STACK_UPDATE); } -void SurfaceInterceptorTest::hiddenFlagUpdate() { - mBGSurfaceControl->setFlags(layer_state_t::eLayerHidden, layer_state_t::eLayerHidden); +void SurfaceInterceptorTest::hiddenFlagUpdate(Transaction& t) { + t.setFlags(mBGSurfaceControl, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden); } -void SurfaceInterceptorTest::opaqueFlagUpdate() { - mBGSurfaceControl->setFlags(layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque); +void SurfaceInterceptorTest::opaqueFlagUpdate(Transaction& t) { + t.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque); } -void SurfaceInterceptorTest::secureFlagUpdate() { - mBGSurfaceControl->setFlags(layer_state_t::eLayerSecure, layer_state_t::eLayerSecure); +void SurfaceInterceptorTest::secureFlagUpdate(Transaction& t) { + t.setFlags(mBGSurfaceControl, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure); } -void SurfaceInterceptorTest::deferredTransactionUpdate() { - mBGSurfaceControl->deferTransactionUntil(mBGSurfaceControl->getHandle(), DEFERRED_UPDATE); +void SurfaceInterceptorTest::deferredTransactionUpdate(Transaction& t) { + t.deferTransactionUntil(mBGSurfaceControl, mBGSurfaceControl->getHandle(), DEFERRED_UPDATE); } -void SurfaceInterceptorTest::displayCreation() { +void SurfaceInterceptorTest::displayCreation(Transaction&) { sp testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true); SurfaceComposerClient::destroyDisplay(testDisplay); } -void SurfaceInterceptorTest::displayDeletion() { +void SurfaceInterceptorTest::displayDeletion(Transaction&) { sp testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false); mTargetId = getDisplayId(DISPLAY_NAME.string()); SurfaceComposerClient::destroyDisplay(testDisplay); @@ -353,7 +359,7 @@ void SurfaceInterceptorTest::runAllUpdates() { runInTransaction(&SurfaceInterceptorTest::deferredTransactionUpdate); } -void SurfaceInterceptorTest::surfaceCreation() { +void SurfaceInterceptorTest::surfaceCreation(Transaction&) { mComposerClient->createSurface(String8(LAYER_NAME), SIZE_UPDATE, SIZE_UPDATE, PIXEL_FORMAT_RGBA_8888, 0); } @@ -825,8 +831,10 @@ TEST_F(SurfaceInterceptorTest, InterceptDisplayDeletionWorks) { } TEST_F(SurfaceInterceptorTest, InterceptBufferUpdateWorks) { - captureTest(&SurfaceInterceptorTest::nBufferUpdates, - &SurfaceInterceptorTest::bufferUpdatesFound); + nBufferUpdates(); + Trace capturedTrace; + ASSERT_EQ(NO_ERROR, readProtoFile(&capturedTrace)); + ASSERT_TRUE(bufferUpdatesFound(&capturedTrace)); } // If the interceptor is enabled while buffer updates are being pushed, the interceptor should diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index d285785c83..f61a978487 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -19,10 +19,11 @@ #include #include +#include + #include #include #include -#include #include #include @@ -30,8 +31,12 @@ #include #include +#include + namespace android { +using Transaction = SurfaceComposerClient::Transaction; + // Fill an RGBA_8888 formatted surface with a single color. static void fillSurfaceRGBA8(const sp& sc, uint8_t r, uint8_t g, uint8_t b, bool unlock=true) { @@ -66,8 +71,8 @@ public: sp sf(ComposerService::getComposerService()); sp display(sf->getBuiltInDisplay( ISurfaceComposer::eDisplayIdMain)); - SurfaceComposerClient::openGlobalTransaction(); - SurfaceComposerClient::closeGlobalTransaction(true); + SurfaceComposerClient::Transaction().apply(true); + ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 0, 0, 0, INT_MAX, false)); *sc = new ScreenCapture(cpuConsumer); @@ -149,23 +154,21 @@ protected: fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - SurfaceComposerClient::openGlobalTransaction(); - - mComposerClient->setDisplayLayerStack(display, 0); - - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT32_MAX-2)); - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show()); + asTransaction([&](Transaction& t) { + t.setDisplayLayerStack(display, 0); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT32_MAX-1)); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64)); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); + t.setLayer(mBGSurfaceControl, INT32_MAX-2) + .show(mBGSurfaceControl); - ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setLayer(INT32_MAX-1)); - ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setPosition(displayWidth-2, - displayHeight-2)); - ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->show()); + t.setLayer(mFGSurfaceControl, INT32_MAX-1) + .setPosition(mFGSurfaceControl, 64, 64) + .show(mFGSurfaceControl); - SurfaceComposerClient::closeGlobalTransaction(true); + t.setLayer(mSyncSurfaceControl, INT32_MAX-1) + .setPosition(mSyncSurfaceControl, displayWidth-2, + displayHeight-2) + .show(mSyncSurfaceControl); + }); } virtual void TearDown() { @@ -186,6 +189,12 @@ protected: fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); } + void asTransaction(const std::function& exec) { + Transaction t; + exec(t); + t.apply(true); + } + sp mComposerClient; sp mBGSurfaceControl; sp mFGSurfaceControl; @@ -205,9 +214,10 @@ TEST_F(LayerUpdateTest, LayerMoveWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setPosition(mFGSurfaceControl, 128, 128); + }); + { // This should reflect the new position, but not the new color. SCOPED_TRACE("after move, before redraw"); @@ -240,9 +250,9 @@ TEST_F(LayerUpdateTest, LayerResizeWorks) { } ALOGD("resizing"); - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + }); ALOGD("resized"); { // This should not reflect the new size or color because SurfaceFlinger @@ -278,10 +288,10 @@ TEST_F(LayerUpdateTest, LayerCropWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - Rect cropRect(16, 16, 32, 32); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setCrop(cropRect)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + Rect cropRect(16, 16, 32, 32); + t.setCrop(mFGSurfaceControl, cropRect); + }); { // This should crop the foreground surface. SCOPED_TRACE("after crop"); @@ -303,10 +313,10 @@ TEST_F(LayerUpdateTest, LayerFinalCropWorks) { sc->expectFGColor(75, 75); sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - Rect cropRect(16, 16, 32, 32); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFinalCrop(cropRect)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + Rect cropRect(16, 16, 32, 32); + t.setFinalCrop(mFGSurfaceControl, cropRect); + }); { // This should crop the foreground surface. SCOPED_TRACE("after crop"); @@ -329,9 +339,10 @@ TEST_F(LayerUpdateTest, LayerSetLayerWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX - 3)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setLayer(mFGSurfaceControl, INT_MAX - 3); + }); + { // This should hide the foreground surface beneath the background. SCOPED_TRACE("after setLayer"); @@ -352,9 +363,10 @@ TEST_F(LayerUpdateTest, LayerShowHideWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide()); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.hide(mFGSurfaceControl); + }); + { // This should hide the foreground surface. SCOPED_TRACE("after hide, before show"); @@ -364,9 +376,10 @@ TEST_F(LayerUpdateTest, LayerShowHideWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mFGSurfaceControl); + }); + { // This should show the foreground surface. SCOPED_TRACE("after show"); @@ -387,9 +400,10 @@ TEST_F(LayerUpdateTest, LayerSetAlphaWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75f)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setAlpha(mFGSurfaceControl, 0.75f); + }); + { // This should set foreground to be 75% opaque. SCOPED_TRACE("after setAlpha"); @@ -410,9 +424,9 @@ TEST_F(LayerUpdateTest, LayerSetLayerStackWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayerStack(1)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setLayerStack(mFGSurfaceControl, 1); + }); { // This should hide the foreground surface since it goes to a different // layer stack. @@ -434,10 +448,10 @@ TEST_F(LayerUpdateTest, LayerSetFlagsWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFlags( - layer_state_t::eLayerHidden, layer_state_t::eLayerHidden)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setFlags(mFGSurfaceControl, + layer_state_t::eLayerHidden, layer_state_t::eLayerHidden); + }); { // This should hide the foreground surface SCOPED_TRACE("after setFlags"); @@ -459,10 +473,11 @@ TEST_F(LayerUpdateTest, LayerSetMatrixWorks) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setMatrix(M_SQRT1_2, M_SQRT1_2, - -M_SQRT1_2, M_SQRT1_2)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setMatrix(mFGSurfaceControl, + M_SQRT1_2, M_SQRT1_2, + -M_SQRT1_2, M_SQRT1_2); + }); { SCOPED_TRACE("after setMatrix"); ScreenCapture::captureScreen(&sc); @@ -498,12 +513,12 @@ protected: waitForPostedBuffers(); } void restoreInitialState() { - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setSize(64, 64); - mFGSurfaceControl->setPosition(64, 64); - mFGSurfaceControl->setCrop(Rect(0, 0, 64, 64)); - mFGSurfaceControl->setFinalCrop(Rect(0, 0, -1, -1)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 64, 64); + t.setPosition(mFGSurfaceControl, 64, 64); + t.setCrop(mFGSurfaceControl, Rect(0, 0, 64, 64)); + t.setFinalCrop(mFGSurfaceControl, Rect(0, 0, -1, -1)); + }); EXPECT_INITIAL_STATE("After restoring initial state"); } @@ -515,10 +530,10 @@ TEST_F(GeometryLatchingTest, SurfacePositionLatching) { // By default position can be updated even while // a resize is pending. - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setSize(32, 32); - mFGSurfaceControl->setPosition(100, 100); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 32, 32); + t.setPosition(mFGSurfaceControl, 100, 100); + }); { SCOPED_TRACE("After moving surface"); @@ -532,11 +547,11 @@ TEST_F(GeometryLatchingTest, SurfacePositionLatching) { // Now we repeat with setGeometryAppliesWithResize // and verify the position DOESN'T latch. - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setSize(32, 32); - mFGSurfaceControl->setPosition(100, 100); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setGeometryAppliesWithResize(mFGSurfaceControl); + t.setSize(mFGSurfaceControl, 32, 32); + t.setPosition(mFGSurfaceControl, 100, 100); + }); { SCOPED_TRACE("While resize is pending"); @@ -581,20 +596,20 @@ protected: TEST_F(CropLatchingTest, CropLatching) { EXPECT_INITIAL_STATE("before anything"); // Normally the crop applies immediately even while a resize is pending. - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setCrop(Rect(0, 0, 63, 63)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setCrop(mFGSurfaceControl, Rect(0, 0, 63, 63)); + }); EXPECT_CROPPED_STATE("after setting crop (without geometryAppliesWithResize)"); restoreInitialState(); - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setCrop(Rect(0, 0, 63, 63)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setGeometryAppliesWithResize(mFGSurfaceControl); + t.setCrop(mFGSurfaceControl, Rect(0, 0, 63, 63)); + }); EXPECT_INITIAL_STATE("after setting crop (with geometryAppliesWithResize)"); @@ -606,20 +621,20 @@ TEST_F(CropLatchingTest, CropLatching) { TEST_F(CropLatchingTest, FinalCropLatching) { 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); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); + }); EXPECT_CROPPED_STATE("after setting crop (without geometryAppliesWithResize)"); restoreInitialState(); - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setGeometryAppliesWithResize(mFGSurfaceControl); + t.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); + }); EXPECT_INITIAL_STATE("after setting crop (with geometryAppliesWithResize)"); @@ -633,10 +648,10 @@ TEST_F(CropLatchingTest, FinalCropLatching) { 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); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); + }); EXPECT_CROPPED_STATE("after setting crop (without geometryAppliesWithResize)"); @@ -646,11 +661,11 @@ TEST_F(CropLatchingTest, FinalCropLatchingBufferOldSize) { // initiating the resize. lockAndFillFGBuffer(); - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setGeometryAppliesWithResize(mFGSurfaceControl); + t.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); + }); EXPECT_INITIAL_STATE("after setting crop (with geometryAppliesWithResize)"); @@ -670,17 +685,17 @@ TEST_F(CropLatchingTest, FinalCropLatchingRegressionForb37531386) { // 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); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 128); + t.setGeometryAppliesWithResize(mFGSurfaceControl); + t.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); + }); EXPECT_INITIAL_STATE("after setting crops with geometryAppliesWithResize"); - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setFinalCrop(Rect(0, 0, -1, -1)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setFinalCrop(mFGSurfaceControl, Rect(0, 0, -1, -1)); + }); EXPECT_INITIAL_STATE("after setting another crop"); @@ -700,17 +715,17 @@ TEST_F(LayerUpdateTest, DeferredTransactionTest) { } // set up two deferred transactions on different frames - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75)); - mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), - mSyncSurfaceControl->getSurface()->getNextFrameNumber()); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setAlpha(mFGSurfaceControl, 0.75); + t.deferTransactionUntil(mFGSurfaceControl, mSyncSurfaceControl->getHandle(), + mSyncSurfaceControl->getSurface()->getNextFrameNumber()); + }); - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128,128)); - mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), - mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setPosition(mFGSurfaceControl, 128,128); + t.deferTransactionUntil(mFGSurfaceControl, mSyncSurfaceControl->getHandle(), + mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1); + }); { SCOPED_TRACE("before any trigger"); @@ -731,9 +746,9 @@ TEST_F(LayerUpdateTest, DeferredTransactionTest) { } // should show up immediately since it's not deferred - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(1.0)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setAlpha(mFGSurfaceControl, 1.0); + }); // trigger the second deferred transaction fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); @@ -762,12 +777,11 @@ TEST_F(LayerUpdateTest, LayerSetRelativeLayerWorks) { waitForPostedBuffers(); // Now we stack the surface above the foreground surface and make sure it is visible. - SurfaceComposerClient::openGlobalTransaction(); - relativeSurfaceControl->setPosition(64, 64); - relativeSurfaceControl->show(); - relativeSurfaceControl->setRelativeLayer(mFGSurfaceControl->getHandle(), 1); - SurfaceComposerClient::closeGlobalTransaction(true); - + asTransaction([&](Transaction& t) { + t.setPosition(relativeSurfaceControl, 64, 64); + t.show(relativeSurfaceControl); + t.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl->getHandle(), 1); + }); { SCOPED_TRACE("after adding relative surface"); @@ -777,9 +791,9 @@ TEST_F(LayerUpdateTest, LayerSetRelativeLayerWorks) { } // A call to setLayer will override a call to setRelativeLayer - SurfaceComposerClient::openGlobalTransaction(); - relativeSurfaceControl->setLayer(0); - SurfaceComposerClient::closeGlobalTransaction(); + asTransaction([&](Transaction& t) { + t.setLayer(relativeSurfaceControl, 0); + }); { SCOPED_TRACE("after set layer"); @@ -801,11 +815,10 @@ TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) { PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get()); fillSurfaceRGBA8(childBuffer, 200, 200, 200); - SurfaceComposerClient::openGlobalTransaction(); - childNoBuffer->show(); - childBuffer->show(); - SurfaceComposerClient::closeGlobalTransaction(); - + SurfaceComposerClient::Transaction{} + .show(childNoBuffer) + .show(childBuffer) + .apply(true); { ScreenCapture::captureScreen(&sc); @@ -813,9 +826,9 @@ TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) { sc->expectFGColor(74, 74); } - SurfaceComposerClient::openGlobalTransaction(); - childNoBuffer->setSize(20, 20); - SurfaceComposerClient::closeGlobalTransaction(true); + SurfaceComposerClient::Transaction{} + .setSize(childNoBuffer, 20, 20) + .apply(true); { ScreenCapture::captureScreen(&sc); @@ -850,11 +863,11 @@ protected: }; TEST_F(ChildLayerTest, ChildLayerPositioning) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 10, 10); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -866,9 +879,9 @@ TEST_F(ChildLayerTest, ChildLayerPositioning) { mCapture->expectFGColor(84, 84); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(0, 0)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setPosition(mFGSurfaceControl, 0, 0); + }); { ScreenCapture::captureScreen(&mCapture); @@ -882,12 +895,12 @@ TEST_F(ChildLayerTest, ChildLayerPositioning) { } 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); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 0, 0); + t.setPosition(mFGSurfaceControl, 0, 0); + t.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5)); + }); { ScreenCapture::captureScreen(&mCapture); @@ -898,12 +911,12 @@ TEST_F(ChildLayerTest, ChildLayerCropping) { } 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); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 0, 0); + t.setPosition(mFGSurfaceControl, 0, 0); + t.setFinalCrop(mFGSurfaceControl, Rect(0, 0, 5, 5)); + }); { ScreenCapture::captureScreen(&mCapture); @@ -914,11 +927,11 @@ TEST_F(ChildLayerTest, ChildLayerFinalCropping) { } TEST_F(ChildLayerTest, ChildLayerConstraints) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mFGSurfaceControl->setPosition(0, 0); - mChild->setPosition(63, 63); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mFGSurfaceControl, 0, 0); + t.setPosition(mChild, 63, 63); + }); { ScreenCapture::captureScreen(&mCapture); @@ -932,9 +945,9 @@ TEST_F(ChildLayerTest, ChildLayerConstraints) { } TEST_F(ChildLayerTest, ChildLayerScaling) { - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setPosition(0, 0); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setPosition(mFGSurfaceControl, 0, 0); + }); // Find the boundary between the parent and child { @@ -943,9 +956,9 @@ TEST_F(ChildLayerTest, ChildLayerScaling) { mCapture->expectFGColor(10, 10); } - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setMatrix(2.0, 0, 0, 2.0); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); + }); // The boundary should be twice as far from the origin now. // The pixels from the last test should all be child now @@ -964,11 +977,11 @@ TEST_F(ChildLayerTest, ChildLayerAlpha) { fillSurfaceRGBA8(mChild, 0, 254, 0); waitForPostedBuffers(); - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 0, 0); + t.setPosition(mFGSurfaceControl, 0, 0); + }); { ScreenCapture::captureScreen(&mCapture); @@ -976,9 +989,9 @@ TEST_F(ChildLayerTest, ChildLayerAlpha) { mCapture->checkPixel(0, 0, 0, 254, 0); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mChild->setAlpha(0.5)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setAlpha(mChild, 0.5); + }); { ScreenCapture::captureScreen(&mCapture); @@ -986,9 +999,9 @@ TEST_F(ChildLayerTest, ChildLayerAlpha) { mCapture->checkPixel(0, 0, 127, 127, 0); } - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.5)); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setAlpha(mFGSurfaceControl, 0.5); + }); { ScreenCapture::captureScreen(&mCapture); @@ -998,11 +1011,11 @@ TEST_F(ChildLayerTest, ChildLayerAlpha) { } TEST_F(ChildLayerTest, ReparentChildren) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 10, 10); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1013,7 +1026,11 @@ TEST_F(ChildLayerTest, ReparentChildren) { // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } - mFGSurfaceControl->reparentChildren(mBGSurfaceControl->getHandle()); + + asTransaction([&](Transaction& t) { + t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle()); + }); + { ScreenCapture::captureScreen(&mCapture); mCapture->expectFGColor(64, 64); @@ -1027,11 +1044,11 @@ TEST_F(ChildLayerTest, ReparentChildren) { } TEST_F(ChildLayerTest, DetachChildrenSameClient) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 10, 10); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1043,13 +1060,13 @@ TEST_F(ChildLayerTest, DetachChildrenSameClient) { mCapture->expectFGColor(84, 84); } - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->detachChildren(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.detachChildren(mFGSurfaceControl); + }); - SurfaceComposerClient::openGlobalTransaction(); - mChild->hide(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.hide(mChild); + }); // Since the child has the same client as the parent, it will not get // detached and will be hidden. @@ -1072,12 +1089,12 @@ TEST_F(ChildLayerTest, DetachChildrenDifferentClient) { fillSurfaceRGBA8(mChildNewClient, 200, 200, 200); - SurfaceComposerClient::openGlobalTransaction(); - mChild->hide(); - mChildNewClient->show(); - mChildNewClient->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.hide(mChild); + t.show(mChildNewClient); + t.setPosition(mChildNewClient, 10, 10); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1089,13 +1106,13 @@ TEST_F(ChildLayerTest, DetachChildrenDifferentClient) { mCapture->expectFGColor(84, 84); } - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->detachChildren(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.detachChildren(mFGSurfaceControl); + }); - SurfaceComposerClient::openGlobalTransaction(); - mChildNewClient->hide(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.hide(mChildNewClient); + }); // Nothing should have changed. { @@ -1107,11 +1124,11 @@ TEST_F(ChildLayerTest, DetachChildrenDifferentClient) { } TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 0, 0); + t.setPosition(mFGSurfaceControl, 0, 0); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1121,11 +1138,11 @@ TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { mCapture->expectFGColor(10, 10); } - SurfaceComposerClient::openGlobalTransaction(); - mFGSurfaceControl->setOverrideScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); - // We cause scaling by 2. - mFGSurfaceControl->setSize(128, 128); - SurfaceComposerClient::closeGlobalTransaction(); + asTransaction([&](Transaction& t) { + t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); + // We cause scaling by 2. + t.setSize(mFGSurfaceControl, 128, 128); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1140,11 +1157,11 @@ TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { // Regression test for b/37673612 TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 0, 0); + t.setPosition(mFGSurfaceControl, 0, 0); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1153,11 +1170,11 @@ TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) { // But it's only 10x10. mCapture->expectFGColor(10, 10); } - - // We set things up as in b/37673612 so that there is a mismatch between the buffer size and // the WM specified state size. - mFGSurfaceControl->setSize(128, 64); + asTransaction([&](Transaction& t) { + t.setSize(mFGSurfaceControl, 128, 64); + }); sp s = mFGSurfaceControl->getSurface(); auto anw = static_cast(s.get()); native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90); @@ -1184,11 +1201,11 @@ TEST_F(ChildLayerTest, Bug36858924) { mFGSurfaceControl.get()); // Show the child layer in a deferred transaction - SurfaceComposerClient::openGlobalTransaction(); - mChild->deferTransactionUntil(mFGSurfaceControl->getHandle(), - mFGSurfaceControl->getSurface()->getNextFrameNumber()); - mChild->show(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.deferTransactionUntil(mChild, mFGSurfaceControl->getHandle(), + mFGSurfaceControl->getSurface()->getNextFrameNumber()); + t.show(mChild); + }); // Render the foreground surface a few times // @@ -1206,11 +1223,11 @@ TEST_F(ChildLayerTest, Bug36858924) { } TEST_F(ChildLayerTest, Reparent) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 10, 10); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1221,7 +1238,11 @@ TEST_F(ChildLayerTest, Reparent) { // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } - mChild->reparent(mBGSurfaceControl->getHandle()); + + asTransaction([&](Transaction& t) { + t.reparent(mChild, mBGSurfaceControl->getHandle()); + }); + { ScreenCapture::captureScreen(&mCapture); mCapture->expectFGColor(64, 64); @@ -1235,11 +1256,11 @@ TEST_F(ChildLayerTest, Reparent) { } TEST_F(ChildLayerTest, ReparentToNoParent) { - SurfaceComposerClient::openGlobalTransaction(); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mChild); + t.setPosition(mChild, 10, 10); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1250,7 +1271,9 @@ TEST_F(ChildLayerTest, ReparentToNoParent) { // And 10 more pixels we should be back to the foreground surface mCapture->expectFGColor(84, 84); } - mChild->reparent(nullptr); + asTransaction([&](Transaction& t) { + t.reparent(mChild, nullptr); + }); { ScreenCapture::captureScreen(&mCapture); // Nothing should have changed. @@ -1267,13 +1290,13 @@ TEST_F(ChildLayerTest, ReparentFromNoParent) { ASSERT_TRUE(newSurface->isValid()); fillSurfaceRGBA8(newSurface, 63, 195, 63); - SurfaceComposerClient::openGlobalTransaction(); - mChild->hide(); - newSurface->show(); - newSurface->setPosition(10, 10); - newSurface->setLayer(INT32_MAX-2); - mFGSurfaceControl->setPosition(64, 64); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.hide(mChild); + t.show(newSurface); + t.setPosition(newSurface, 10, 10); + t.setLayer(newSurface, INT32_MAX-2); + t.setPosition(mFGSurfaceControl, 64, 64); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1283,9 +1306,9 @@ TEST_F(ChildLayerTest, ReparentFromNoParent) { mCapture->checkPixel(10, 10, 63, 195, 63); } - SurfaceComposerClient::openGlobalTransaction(); - newSurface->reparent(mFGSurfaceControl->getHandle()); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.reparent(newSurface, mFGSurfaceControl->getHandle()); + }); { ScreenCapture::captureScreen(&mCapture); @@ -1325,12 +1348,12 @@ class LayerColorTest : public LayerUpdateTest { ASSERT_TRUE(mLayerColorControl != NULL); ASSERT_TRUE(mLayerColorControl->isValid()); - SurfaceComposerClient::openGlobalTransaction(); - ASSERT_EQ(NO_ERROR, mLayerColorControl->setLayer(INT32_MAX-1)); - ASSERT_EQ(NO_ERROR, mLayerColorControl->setPosition(140, 140)); - ASSERT_EQ(NO_ERROR, mLayerColorControl->hide()); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide()); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.setLayer(mLayerColorControl, INT32_MAX-1); + t.setPosition(mLayerColorControl, 140, 140); + t.hide(mLayerColorControl); + t.hide(mFGSurfaceControl); + }); } void TearDown() override { @@ -1350,15 +1373,16 @@ TEST_F(LayerColorTest, ColorLayerNoAlpha) { sc->expectBGColor(145, 145); } + asTransaction([&](Transaction& t) { + half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f); + t.setColor(mLayerColorControl, color); + t.show(mLayerColorControl); + }); - SurfaceComposerClient::openGlobalTransaction(); - half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f); - mLayerColorControl->setColor(color); - mLayerColorControl->show(); - SurfaceComposerClient::closeGlobalTransaction(true); { // There should now be a color SCOPED_TRACE("after setColor"); + ScreenCapture::captureScreen(&sc); sc->checkPixel(145, 145, 43, 207, 131); } @@ -1372,12 +1396,13 @@ TEST_F(LayerColorTest, ColorLayerWithAlpha) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f); - mLayerColorControl->setColor(color); - mLayerColorControl->setAlpha(.75f); - mLayerColorControl->show(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + half3 color(43.0f/255.0f, 207.0f/255.0f, 131.0f/255.0f); + t.setColor(mLayerColorControl, color); + t.setAlpha(mLayerColorControl, .75f); + t.show(mLayerColorControl); + }); + { // There should now be a color with .75 alpha SCOPED_TRACE("after setColor"); @@ -1394,9 +1419,10 @@ TEST_F(LayerColorTest, ColorLayerWithNoColor) { sc->expectBGColor(145, 145); } - SurfaceComposerClient::openGlobalTransaction(); - mLayerColorControl->show(); - SurfaceComposerClient::closeGlobalTransaction(true); + asTransaction([&](Transaction& t) { + t.show(mLayerColorControl); + }); + { // There should now be set to 0,0,0 (black) as default. SCOPED_TRACE("after setColor"); diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h index 74dc0e51bb..1258a970c7 100644 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h +++ b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h @@ -87,7 +87,7 @@ public: /* * All surface state changes are supposed to happen inside a global - * transaction. GlobalTransactionScope object at the beginning of + * transaction. TransactionScope object at the beginning of * scope automates the process. The resulting scope gives a visual cue * on the span of the transaction as well. * @@ -96,23 +96,26 @@ public: * is built to explicitly request vsyncs one at the time. A delayed * request must be made before closing the transaction or the test * thread stalls until SurfaceFlinger does an emergency vsync by - * itself. GlobalTransactionScope encapsulates this vsync magic. + * itself. TransactionScope encapsulates this vsync magic. */ -class GlobalTransactionScope { +class TransactionScope : public android::SurfaceComposerClient::Transaction { public: - GlobalTransactionScope(FakeComposerClient& composer) : mComposer(composer) { - android::SurfaceComposerClient::openGlobalTransaction(); + TransactionScope(FakeComposerClient& composer) : + Transaction(), + mComposer(composer) { } - ~GlobalTransactionScope() { + + ~TransactionScope() { int frameCount = mComposer.getFrameCount(); mComposer.runVSyncAfter(1ms); - android::SurfaceComposerClient::closeGlobalTransaction(true); + LOG_ALWAYS_FATAL_IF(android::NO_ERROR != apply()); // Make sure that exactly one frame has been rendered. mComposer.waitUntilFrame(frameCount + 1); LOG_ALWAYS_FATAL_IF(frameCount + 1 != mComposer.getFrameCount(), "Unexpected frame advance. Delta: %d", mComposer.getFrameCount() - frameCount); } + FakeComposerClient& mComposer; }; diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index 9ac3331892..7f4c58a9ba 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -24,11 +24,11 @@ #include #include +#include #include #include #include -#include #include @@ -62,6 +62,8 @@ using ::testing::Return; using ::testing::SetArgPointee; using ::testing::_; +using Transaction = SurfaceComposerClient::Transaction; + /////////////////////////////////////////////// struct TestColor { @@ -248,11 +250,11 @@ TEST_F(DisplayTest, Hotplug) { fillSurfaceRGBA8(surfaceControl, BLUE); { - GlobalTransactionScope gts(*mMockComposer); - mComposerClient->setDisplayLayerStack(display, 0); + TransactionScope ts(*mMockComposer); + ts.setDisplayLayerStack(display, 0); - ASSERT_EQ(NO_ERROR, surfaceControl->setLayer(INT32_MAX - 2)); - ASSERT_EQ(NO_ERROR, surfaceControl->show()); + ts.setLayer(surfaceControl, INT32_MAX - 2) + .show(surfaceControl); } } @@ -278,11 +280,11 @@ TEST_F(DisplayTest, Hotplug) { fillSurfaceRGBA8(surfaceControl, BLUE); { - GlobalTransactionScope gts(*mMockComposer); - mComposerClient->setDisplayLayerStack(display, 0); + TransactionScope ts(*mMockComposer); + ts.setDisplayLayerStack(display, 0); - ASSERT_EQ(NO_ERROR, surfaceControl->setLayer(INT32_MAX - 2)); - ASSERT_EQ(NO_ERROR, surfaceControl->show()); + ts.setLayer(surfaceControl, INT32_MAX - 2) + .show(surfaceControl); } } mMockComposer->hotplugDisplay(EXTERNAL_DISPLAY, IComposerCallback::Connection::DISCONNECTED); @@ -370,25 +372,24 @@ void TransactionTest::SetUp() { fillSurfaceRGBA8(mFGSurfaceControl, RED); - SurfaceComposerClient::openGlobalTransaction(); - - mComposerClient->setDisplayLayerStack(display, 0); + Transaction t; + t.setDisplayLayerStack(display, 0); - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT32_MAX - 2)); - ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show()); + t.setLayer(mBGSurfaceControl, INT32_MAX - 2); + t.show(mBGSurfaceControl); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT32_MAX - 1)); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64)); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); + t.setLayer(mFGSurfaceControl, INT32_MAX - 1); + t.setPosition(mFGSurfaceControl, 64, 64); + t.show(mFGSurfaceControl); // Synchronous transaction will stop this thread, so we set up a // delayed, off-thread vsync request before closing the // transaction. In the test code this is usually done with - // GlobalTransactionScope. Leaving here in the 'vanilla' form for + // TransactionScope. Leaving here in the 'vanilla' form for // reference. ASSERT_EQ(0, sFakeComposer->getFrameCount()); sFakeComposer->runVSyncAfter(1ms); - SurfaceComposerClient::closeGlobalTransaction(true); + t.apply(); sFakeComposer->waitUntilFrame(1); // Reference data. This is what the HWC should see. @@ -445,8 +446,8 @@ TEST_F(TransactionTest, LayerMove) { // should be available in the latest frame stored by the fake // composer. { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128)); + TransactionScope ts(*sFakeComposer); + ts.setPosition(mFGSurfaceControl, 128, 128); // NOTE: No changes yet, so vsync will do nothing, HWC does not get any calls. // (How to verify that? Throw in vsync and wait a 2x frame time? Separate test?) // @@ -473,8 +474,8 @@ TEST_F(TransactionTest, LayerMove) { TEST_F(TransactionTest, LayerResize) { ALOGD("TransactionTest::LayerResize"); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); } fillSurfaceRGBA8(mFGSurfaceControl, GREEN); @@ -497,9 +498,9 @@ TEST_F(TransactionTest, LayerResize) { TEST_F(TransactionTest, LayerCrop) { // TODO: Add scaling to confirm that crop happens in buffer space? { - GlobalTransactionScope gts(*sFakeComposer); + TransactionScope ts(*sFakeComposer); Rect cropRect(16, 16, 32, 32); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setCrop(cropRect)); + ts.setCrop(mFGSurfaceControl, cropRect); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -512,9 +513,9 @@ TEST_F(TransactionTest, LayerCrop) { TEST_F(TransactionTest, LayerFinalCrop) { // TODO: Add scaling to confirm that crop happens in display space? { - GlobalTransactionScope gts(*sFakeComposer); + TransactionScope ts(*sFakeComposer); Rect cropRect(32, 32, 32 + 64, 32 + 64); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFinalCrop(cropRect)); + ts.setFinalCrop(mFGSurfaceControl, cropRect); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -530,9 +531,9 @@ TEST_F(TransactionTest, LayerFinalCrop) { TEST_F(TransactionTest, LayerFinalCropEmpty) { // TODO: Add scaling to confirm that crop happens in display space? { - GlobalTransactionScope gts(*sFakeComposer); + TransactionScope ts(*sFakeComposer); Rect cropRect(16, 16, 32, 32); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFinalCrop(cropRect)); + ts.setFinalCrop(mFGSurfaceControl, cropRect); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -545,8 +546,8 @@ TEST_F(TransactionTest, LayerFinalCropEmpty) { TEST_F(TransactionTest, LayerSetLayer) { { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX - 3)); + TransactionScope ts(*sFakeComposer); + ts.setLayer(mFGSurfaceControl, INT_MAX - 3); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -560,11 +561,10 @@ TEST_F(TransactionTest, LayerSetLayer) { TEST_F(TransactionTest, LayerSetLayerOpaque) { { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX - 3)); - ASSERT_EQ(NO_ERROR, - mBGSurfaceControl->setFlags(layer_state_t::eLayerOpaque, - layer_state_t::eLayerOpaque)); + TransactionScope ts(*sFakeComposer); + ts.setLayer(mFGSurfaceControl, INT_MAX - 3); + ts.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque, + layer_state_t::eLayerOpaque); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -577,8 +577,8 @@ TEST_F(TransactionTest, LayerSetLayerOpaque) { TEST_F(TransactionTest, SetLayerStack) { ALOGD("TransactionTest::SetLayerStack"); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayerStack(1)); + TransactionScope ts(*sFakeComposer); + ts.setLayerStack(mFGSurfaceControl, 1); } // Foreground layer should have disappeared. @@ -591,8 +591,8 @@ TEST_F(TransactionTest, SetLayerStack) { TEST_F(TransactionTest, LayerShowHide) { ALOGD("TransactionTest::LayerShowHide"); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide()); + TransactionScope ts(*sFakeComposer); + ts.hide(mFGSurfaceControl); } // Foreground layer should have disappeared. @@ -602,8 +602,8 @@ TEST_F(TransactionTest, LayerShowHide) { EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); + TransactionScope ts(*sFakeComposer); + ts.show(mFGSurfaceControl); } // Foreground layer should be back @@ -613,8 +613,8 @@ TEST_F(TransactionTest, LayerShowHide) { TEST_F(TransactionTest, LayerSetAlpha) { { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75f)); + TransactionScope ts(*sFakeComposer); + ts.setAlpha(mFGSurfaceControl, 0.75f); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -625,10 +625,9 @@ TEST_F(TransactionTest, LayerSetAlpha) { TEST_F(TransactionTest, LayerSetFlags) { { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, - mFGSurfaceControl->setFlags(layer_state_t::eLayerHidden, - layer_state_t::eLayerHidden)); + TransactionScope ts(*sFakeComposer); + ts.setFlags(mFGSurfaceControl, layer_state_t::eLayerHidden, + layer_state_t::eLayerHidden); } // Foreground layer should have disappeared. @@ -667,10 +666,9 @@ TEST_F(TransactionTest, LayerSetMatrix) { const matrixTestData& xform = MATRIX_TESTS[i]; SCOPED_TRACE(i); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, - mFGSurfaceControl->setMatrix(xform.matrix[0], xform.matrix[1], - xform.matrix[2], xform.matrix[3])); + TransactionScope ts(*sFakeComposer); + ts.setMatrix(mFGSurfaceControl, xform.matrix[0], xform.matrix[1], + xform.matrix[2], xform.matrix[3]); } auto referenceFrame = mBaseFrame; @@ -684,10 +682,10 @@ TEST_F(TransactionTest, LayerSetMatrix) { #if 0 TEST_F(TransactionTest, LayerSetMatrix2) { { - GlobalTransactionScope gts(*sFakeComposer); + TransactionScope ts(*sFakeComposer); // TODO: PLEASE SPEC THE FUNCTION! - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setMatrix(0.11f, 0.123f, - -2.33f, 0.22f)); + ts.setMatrix(mFGSurfaceControl, 0.11f, 0.123f, + -2.33f, 0.22f); } auto referenceFrame = mBaseFrame; // TODO: Is this correct for sure? @@ -708,10 +706,10 @@ TEST_F(TransactionTest, DeferredTransaction) { fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, syncSurfaceControl->setLayer(INT32_MAX - 1)); - ASSERT_EQ(NO_ERROR, syncSurfaceControl->setPosition(mDisplayWidth - 2, mDisplayHeight - 2)); - ASSERT_EQ(NO_ERROR, syncSurfaceControl->show()); + TransactionScope ts(*sFakeComposer); + ts.setLayer(syncSurfaceControl, INT32_MAX - 1); + ts.setPosition(syncSurfaceControl, mDisplayWidth - 2, mDisplayHeight - 2); + ts.show(syncSurfaceControl); } auto referenceFrame = mBaseFrame; referenceFrame.push_back(makeSimpleRect(mDisplayWidth - 2, mDisplayHeight - 2, @@ -723,20 +721,20 @@ TEST_F(TransactionTest, DeferredTransaction) { // set up two deferred transactions on different frames - these should not yield composited // frames { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75)); - mFGSurfaceControl - ->deferTransactionUntil(syncSurfaceControl->getHandle(), - syncSurfaceControl->getSurface()->getNextFrameNumber()); + TransactionScope ts(*sFakeComposer); + ts.setAlpha(mFGSurfaceControl, 0.75); + ts.deferTransactionUntil(mFGSurfaceControl, + syncSurfaceControl->getHandle(), + syncSurfaceControl->getSurface()->getNextFrameNumber()); } EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128)); - mFGSurfaceControl - ->deferTransactionUntil(syncSurfaceControl->getHandle(), - syncSurfaceControl->getSurface()->getNextFrameNumber() + 1); + TransactionScope ts(*sFakeComposer); + ts.setPosition(mFGSurfaceControl, 128, 128); + ts.deferTransactionUntil(mFGSurfaceControl, + syncSurfaceControl->getHandle(), + syncSurfaceControl->getSurface()->getNextFrameNumber() + 1); } EXPECT_EQ(4, sFakeComposer->getFrameCount()); EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); @@ -752,8 +750,8 @@ TEST_F(TransactionTest, DeferredTransaction) { // should show up immediately since it's not deferred { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(1.0)); + TransactionScope ts(*sFakeComposer); + ts.setAlpha(mFGSurfaceControl, 1.0); } referenceFrame[FG_LAYER].mPlaneAlpha = 1.f; EXPECT_EQ(6, sFakeComposer->getFrameCount()); @@ -777,10 +775,10 @@ TEST_F(TransactionTest, SetRelativeLayer) { // Now we stack the surface above the foreground surface and make sure it is visible. { - GlobalTransactionScope gts(*sFakeComposer); - relativeSurfaceControl->setPosition(64, 64); - relativeSurfaceControl->show(); - relativeSurfaceControl->setRelativeLayer(mFGSurfaceControl->getHandle(), 1); + TransactionScope ts(*sFakeComposer); + ts.setPosition(relativeSurfaceControl, 64, 64); + ts.show(relativeSurfaceControl); + ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl->getHandle(), 1); } auto referenceFrame = mBaseFrame; // NOTE: All three layers will be visible as the surfaces are @@ -791,8 +789,8 @@ TEST_F(TransactionTest, SetRelativeLayer) { // A call to setLayer will override a call to setRelativeLayer { - GlobalTransactionScope gts(*sFakeComposer); - relativeSurfaceControl->setLayer(0); + TransactionScope ts(*sFakeComposer); + ts.setLayer(relativeSurfaceControl, 0); } // Previous top layer will now appear at the bottom. @@ -828,11 +826,11 @@ protected: TEST_F(ChildLayerTest, Positioning) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(10, 10); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 10, 10); // Move to the same position as in the original setup. - mFGSurfaceControl->setPosition(64, 64); + ts.setPosition(mFGSurfaceControl, 64, 64); } auto referenceFrame = mBaseFrame; @@ -842,8 +840,8 @@ TEST_F(ChildLayerTest, Positioning) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(0, 0)); + TransactionScope ts(*sFakeComposer); + ts.setPosition(mFGSurfaceControl, 0, 0); } auto referenceFrame2 = mBaseFrame; @@ -855,11 +853,11 @@ TEST_F(ChildLayerTest, Positioning) { TEST_F(ChildLayerTest, Cropping) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); - mFGSurfaceControl->setCrop(Rect(0, 0, 5, 5)); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 0, 0); + ts.setPosition(mFGSurfaceControl, 0, 0); + ts.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5)); } // NOTE: The foreground surface would be occluded by the child // now, but is included in the stack because the child is @@ -874,11 +872,11 @@ TEST_F(ChildLayerTest, Cropping) { TEST_F(ChildLayerTest, FinalCropping) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); - mFGSurfaceControl->setFinalCrop(Rect(0, 0, 5, 5)); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 0, 0); + ts.setPosition(mFGSurfaceControl, 0, 0); + ts.setFinalCrop(mFGSurfaceControl, Rect(0, 0, 5, 5)); } auto referenceFrame = mBaseFrame; referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5}; @@ -890,10 +888,10 @@ TEST_F(ChildLayerTest, FinalCropping) { TEST_F(ChildLayerTest, Constraints) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mFGSurfaceControl->setPosition(0, 0); - mChild->setPosition(63, 63); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mFGSurfaceControl, 0, 0); + ts.setPosition(mChild, 63, 63); } auto referenceFrame = mBaseFrame; referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; @@ -904,8 +902,8 @@ TEST_F(ChildLayerTest, Constraints) { TEST_F(ChildLayerTest, Scaling) { { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setPosition(0, 0); + TransactionScope ts(*sFakeComposer); + ts.setPosition(mFGSurfaceControl, 0, 0); } auto referenceFrame = mBaseFrame; referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; @@ -913,8 +911,8 @@ TEST_F(ChildLayerTest, Scaling) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setMatrix(2.0, 0, 0, 2.0); + TransactionScope ts(*sFakeComposer); + ts.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); } auto referenceFrame2 = mBaseFrame; @@ -925,11 +923,11 @@ TEST_F(ChildLayerTest, Scaling) { TEST_F(ChildLayerTest, LayerAlpha) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); - ASSERT_EQ(NO_ERROR, mChild->setAlpha(0.5)); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 0, 0); + ts.setPosition(mFGSurfaceControl, 0, 0); + ts.setAlpha(mChild, 0.5); } auto referenceFrame = mBaseFrame; @@ -939,8 +937,8 @@ TEST_F(ChildLayerTest, LayerAlpha) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.5)); + TransactionScope ts(*sFakeComposer); + ts.setAlpha(mFGSurfaceControl, 0.5); } auto referenceFrame2 = referenceFrame; @@ -951,10 +949,10 @@ TEST_F(ChildLayerTest, LayerAlpha) { TEST_F(ChildLayerTest, ReparentChildren) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 10, 10); + ts.setPosition(mFGSurfaceControl, 64, 64); } auto referenceFrame = mBaseFrame; referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64}; @@ -963,8 +961,8 @@ TEST_F(ChildLayerTest, ReparentChildren) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->reparentChildren(mBGSurfaceControl->getHandle()); + TransactionScope ts(*sFakeComposer); + ts.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle()); } auto referenceFrame2 = referenceFrame; @@ -975,10 +973,10 @@ TEST_F(ChildLayerTest, ReparentChildren) { TEST_F(ChildLayerTest, DetachChildren) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(10, 10); - mFGSurfaceControl->setPosition(64, 64); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 10, 10); + ts.setPosition(mFGSurfaceControl, 64, 64); } auto referenceFrame = mBaseFrame; @@ -988,13 +986,13 @@ TEST_F(ChildLayerTest, DetachChildren) { EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->detachChildren(); + TransactionScope ts(*sFakeComposer); + ts.detachChildren(mFGSurfaceControl); } { - GlobalTransactionScope gts(*sFakeComposer); - mChild->hide(); + TransactionScope ts(*sFakeComposer); + ts.hide(mChild); } // Nothing should have changed. The child control becomes a no-op @@ -1005,17 +1003,17 @@ TEST_F(ChildLayerTest, DetachChildren) { TEST_F(ChildLayerTest, InheritNonTransformScalingFromParent) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 0, 0); + ts.setPosition(mFGSurfaceControl, 0, 0); } { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setOverrideScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); + TransactionScope ts(*sFakeComposer); + ts.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); // We cause scaling by 2. - mFGSurfaceControl->setSize(128, 128); + ts.setSize(mFGSurfaceControl, 128, 128); } auto referenceFrame = mBaseFrame; @@ -1029,17 +1027,17 @@ TEST_F(ChildLayerTest, InheritNonTransformScalingFromParent) { // Regression test for b/37673612 TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) { { - GlobalTransactionScope gts(*sFakeComposer); - mChild->show(); - mChild->setPosition(0, 0); - mFGSurfaceControl->setPosition(0, 0); + TransactionScope ts(*sFakeComposer); + ts.show(mChild); + ts.setPosition(mChild, 0, 0); + ts.setPosition(mFGSurfaceControl, 0, 0); } // We set things up as in b/37673612 so that there is a mismatch between the buffer size and // the WM specified state size. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 64); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 64); } sp s = mFGSurfaceControl->getSurface(); @@ -1070,10 +1068,10 @@ TEST_F(ChildLayerTest, Bug36858924) { // Show the child layer in a deferred transaction { - GlobalTransactionScope gts(*sFakeComposer); - mChild->deferTransactionUntil(mFGSurfaceControl->getHandle(), + TransactionScope ts(*sFakeComposer); + ts.deferTransactionUntil(mChild, mFGSurfaceControl->getHandle(), mFGSurfaceControl->getSurface()->getNextFrameNumber()); - mChild->show(); + ts.show(mChild); } // Render the foreground surface a few times @@ -1110,11 +1108,11 @@ protected: sFakeComposer->runVSyncAndWait(); } void restoreInitialState() { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(64, 64); - mFGSurfaceControl->setPosition(64, 64); - mFGSurfaceControl->setCrop(Rect(0, 0, 64, 64)); - mFGSurfaceControl->setFinalCrop(Rect(0, 0, -1, -1)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 64, 64); + ts.setPosition(mFGSurfaceControl, 64, 64); + ts.setCrop(mFGSurfaceControl, Rect(0, 0, 64, 64)); + ts.setFinalCrop(mFGSurfaceControl, Rect(0, 0, -1, -1)); } }; @@ -1122,9 +1120,9 @@ TEST_F(LatchingTest, SurfacePositionLatching) { // By default position can be updated even while // a resize is pending. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(32, 32); - mFGSurfaceControl->setPosition(100, 100); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 32, 32); + ts.setPosition(mFGSurfaceControl, 100, 100); } // The size should not have updated as we have not provided a new buffer. @@ -1137,10 +1135,10 @@ TEST_F(LatchingTest, SurfacePositionLatching) { // Now we repeat with setGeometryAppliesWithResize // and verify the position DOESN'T latch. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setSize(32, 32); - mFGSurfaceControl->setPosition(100, 100); + TransactionScope ts(*sFakeComposer); + ts.setGeometryAppliesWithResize(mFGSurfaceControl); + ts.setSize(mFGSurfaceControl, 32, 32); + ts.setPosition(mFGSurfaceControl, 100, 100); } EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); @@ -1156,9 +1154,9 @@ TEST_F(LatchingTest, SurfacePositionLatching) { TEST_F(LatchingTest, CropLatching) { // Normally the crop applies immediately even while a resize is pending. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setCrop(Rect(0, 0, 63, 63)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setCrop(mFGSurfaceControl, Rect(0, 0, 63, 63)); } auto referenceFrame1 = mBaseFrame; @@ -1169,10 +1167,10 @@ TEST_F(LatchingTest, CropLatching) { restoreInitialState(); { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setCrop(Rect(0, 0, 63, 63)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setGeometryAppliesWithResize(mFGSurfaceControl); + ts.setCrop(mFGSurfaceControl, Rect(0, 0, 63, 63)); } EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); @@ -1188,9 +1186,9 @@ TEST_F(LatchingTest, CropLatching) { TEST_F(LatchingTest, FinalCropLatching) { // Normally the crop applies immediately even while a resize is pending. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); } auto referenceFrame1 = mBaseFrame; @@ -1202,10 +1200,10 @@ TEST_F(LatchingTest, FinalCropLatching) { restoreInitialState(); { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setGeometryAppliesWithResize(mFGSurfaceControl); + ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); } EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); @@ -1224,9 +1222,9 @@ TEST_F(LatchingTest, FinalCropLatching) { TEST_F(LatchingTest, FinalCropLatchingBufferOldSize) { // Normally the crop applies immediately even while a resize is pending. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); } auto referenceFrame1 = mBaseFrame; @@ -1242,10 +1240,10 @@ TEST_F(LatchingTest, FinalCropLatchingBufferOldSize) { lockAndFillFGBuffer(); { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setGeometryAppliesWithResize(mFGSurfaceControl); + ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); } EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); @@ -1271,15 +1269,15 @@ TEST_F(LatchingTest, FinalCropLatchingRegressionForb37531386) { // is still pending, and ensure we are successful. Success meaning the second crop // is the one which eventually latches and not the first. { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setSize(128, 128); - mFGSurfaceControl->setGeometryAppliesWithResize(); - mFGSurfaceControl->setFinalCrop(Rect(64, 64, 127, 127)); + TransactionScope ts(*sFakeComposer); + ts.setSize(mFGSurfaceControl, 128, 128); + ts.setGeometryAppliesWithResize(mFGSurfaceControl); + ts.setFinalCrop(mFGSurfaceControl, Rect(64, 64, 127, 127)); } { - GlobalTransactionScope gts(*sFakeComposer); - mFGSurfaceControl->setFinalCrop(Rect(0, 0, -1, -1)); + TransactionScope ts(*sFakeComposer); + ts.setFinalCrop(mFGSurfaceControl, Rect(0, 0, -1, -1)); } EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); -- cgit v1.2.3-59-g8ed1b From 2c5f6d2257075c8b5ced78b07ed8b2c2323f0df2 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 26 Sep 2017 12:30:35 -0700 Subject: SurfaceFlinger: Implement merging of transaction objects. Useful for WindowManager to collect multiple transactions from independent units. Test: Transaction_test.cpp Change-Id: I52e89b038e3b375493169991e41cb75b67550264 --- libs/gui/LayerState.cpp | 96 ++++++++++++++++++++++ libs/gui/SurfaceComposerClient.cpp | 24 ++++++ libs/gui/include/gui/LayerState.h | 2 + libs/gui/include/gui/SurfaceComposerClient.h | 6 +- services/surfaceflinger/tests/Transaction_test.cpp | 24 ++++++ 5 files changed, 149 insertions(+), 3 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index bfc6f28704..b5295f2801 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -136,5 +136,101 @@ status_t DisplayState::read(const Parcel& input) { return NO_ERROR; } +void DisplayState::merge(const DisplayState& other) { + if (other.what & eSurfaceChanged) { + what |= eSurfaceChanged; + surface = other.surface; + } + if (other.what & eLayerStackChanged) { + what |= eLayerStackChanged; + layerStack = other.layerStack; + } + if (other.what & eDisplayProjectionChanged) { + what |= eDisplayProjectionChanged; + orientation = other.orientation; + viewport = other.viewport; + frame = other.frame; + } + if (other.what & eDisplaySizeChanged) { + what |= eDisplaySizeChanged; + width = other.width; + height = other.height; + } +} + +void layer_state_t::merge(const layer_state_t& other) { + if (other.what & ePositionChanged) { + what |= ePositionChanged; + x = other.x; + y = other.y; + } + if (other.what & eLayerChanged) { + what |= eLayerChanged; + z = other.z; + } + if (other.what & eSizeChanged) { + what |= eSizeChanged; + w = other.w; + h = other.h; + } + if (other.what & eAlphaChanged) { + what |= eAlphaChanged; + alpha = other.alpha; + } + if (other.what & eMatrixChanged) { + what |= eMatrixChanged; + matrix = other.matrix; + } + if (other.what & eTransparentRegionChanged) { + what |= eTransparentRegionChanged; + transparentRegion = other.transparentRegion; + } + if (other.what & eFlagsChanged) { + what |= eFlagsChanged; + flags = other.flags; + mask = other.mask; + } + if (other.what & eLayerStackChanged) { + what |= eLayerStackChanged; + layerStack = other.layerStack; + } + if (other.what & eCropChanged) { + what |= eCropChanged; + crop = other.crop; + } + if (other.what & eDeferTransaction) { + what |= eDeferTransaction; + barrierHandle = other.barrierHandle; + barrierGbp = other.barrierGbp; + frameNumber = other.frameNumber; + } + if (other.what & eFinalCropChanged) { + what |= eFinalCropChanged; + finalCrop = other.finalCrop; + } + if (other.what & eOverrideScalingModeChanged) { + what |= eOverrideScalingModeChanged; + overrideScalingMode = other.overrideScalingMode; + } + if (other.what & eGeometryAppliesWithResize) { + what |= eGeometryAppliesWithResize; + } + if (other.what & eReparentChildren) { + what |= eReparentChildren; + reparentHandle = other.reparentHandle; + } + if (other.what & eDetachChildren) { + what |= eDetachChildren; + } + if (other.what & eRelativeLayerChanged) { + what |= eRelativeLayerChanged; + z = other.z; + relativeLayerHandle = other.relativeLayerHandle; + } + if (other.what & eReparent) { + what |= eReparent; + parentHandleForChild = other.parentHandleForChild; + } +} }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 15c4c9a880..2adc273651 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -104,6 +104,30 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : mComposerStates = other.mComposerStates; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { + for (auto const& state : other.mComposerStates) { + ssize_t index = mComposerStates.indexOf(state); + if (index < 0) { + mComposerStates.add(state); + } else { + mComposerStates.editItemAt(static_cast(index)).state.merge(state.state); + } + } + other.mComposerStates.clear(); + + for (auto const& state : other.mDisplayStates) { + ssize_t index = mDisplayStates.indexOf(state); + if (index < 0) { + mDisplayStates.add(state); + } else { + mDisplayStates.editItemAt(static_cast(index)).merge(state); + } + } + other.mDisplayStates.clear(); + + return *this; +} + status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { if (mStatus != NO_ERROR) { return mStatus; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index ae6965a0fc..f3fb82feb3 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -77,6 +77,7 @@ struct layer_state_t { matrix.dsdy = matrix.dtdx = 0.0f; } + void merge(const layer_state_t& other); status_t write(Parcel& output) const; status_t read(const Parcel& input); @@ -144,6 +145,7 @@ struct DisplayState { }; DisplayState(); + void merge(const DisplayState& other); uint32_t what; sp token; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index d63dafea41..87fdfae111 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -144,7 +144,9 @@ public: Transaction(Transaction const& other); status_t apply(bool synchronous = false); - + // Merge another transaction in to this one, clearing other + // as if it had been applied. + Transaction& merge(Transaction&& other); Transaction& show(const sp& sc); Transaction& hide(const sp& sc); Transaction& setPosition(const sp& sc, @@ -175,8 +177,6 @@ public: float alpha); Transaction& setMatrix(const sp& sc, float dsdx, float dtdx, float dtdy, float dsdy); - Transaction& setOrientation(const sp& sc, - const Rect& crop); Transaction& setCrop(const sp& sc, const Rect& crop); Transaction& setFinalCrop(const sp& sc, const Rect& crop); Transaction& setLayerStack(const sp& sc, uint32_t layerStack); diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index ec87eeec77..16a16a53b1 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -891,6 +891,30 @@ TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) { } } +TEST_F(LayerUpdateTest, MergingTransactions) { + sp sc; + { + SCOPED_TRACE("before move"); + ScreenCapture::captureScreen(&sc); + sc->expectBGColor(0, 12); + sc->expectFGColor(75, 75); + sc->expectBGColor(145, 145); + } + + Transaction t1, t2; + t1.setPosition(mFGSurfaceControl, 128, 128); + t2.setPosition(mFGSurfaceControl, 0, 0); + // We expect that the position update from t2 now + // overwrites the position update from t1. + t1.merge(std::move(t2)); + t1.apply(); + + { + ScreenCapture::captureScreen(&sc); + sc->expectFGColor(1, 1); + } +} + class ChildLayerTest : public LayerUpdateTest { protected: void SetUp() override { -- cgit v1.2.3-59-g8ed1b From ca27f2500cff74ae1e08b3ae06f18e9b3414ffb7 Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 6 Feb 2018 16:46:39 -0800 Subject: Allow destroySurface to get called in transaction. Previously, destroy was always initiated immediatley and could not be synchronized with a client transaction. This change allows destroySurface to be called in the same transaction as other client state updates. Test: Unit tests pass Test: Call from Java fixes bugs. Change-Id: I841359530538961a0187216cc455cc388c0ede77 Fixes: 72953020 Fixes: 71499373 --- libs/gui/LayerState.cpp | 3 + libs/gui/SurfaceComposerClient.cpp | 11 ++++ libs/gui/include/gui/LayerState.h | 3 +- libs/gui/include/gui/SurfaceComposerClient.h | 2 + services/surfaceflinger/SurfaceFlinger.cpp | 96 +++++++++++++++++++--------- services/surfaceflinger/SurfaceFlinger.h | 5 +- 6 files changed, 89 insertions(+), 31 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index b5295f2801..01acc2de20 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -231,6 +231,9 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eReparent; parentHandleForChild = other.parentHandleForChild; } + if (other.what & eDestroySurface) { + what |= eDestroySurface; + } } }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c40cad3e99..0722038c5b 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -472,6 +472,17 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeome return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface( + const sp& sc) { + layer_state_t* s = getLayerStateLocked(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eDestroySurface; + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayStateLocked(const sp& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index f3fb82feb3..788962e490 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -62,7 +62,8 @@ struct layer_state_t { eDetachChildren = 0x00004000, eRelativeLayerChanged = 0x00008000, eReparent = 0x00010000, - eColorChanged = 0x00020000 + eColorChanged = 0x00020000, + eDestroySurface = 0x00040000 }; layer_state_t() diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 55b96ac93d..10caa76281 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -229,6 +229,8 @@ public: // freezing the total geometry of a surface until a resize is completed. Transaction& setGeometryAppliesWithResize(const sp& sc); + Transaction& destroySurface(const sp& sc); + status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 03f6bdc583..135bfbefa9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2901,7 +2901,11 @@ status_t SurfaceFlinger::addClientLayer(const sp& client, status_t SurfaceFlinger::removeLayer(const sp& layer, bool topLevelOnly) { Mutex::Autolock _l(mStateLock); + return removeLayerLocked(mStateLock, layer, topLevelOnly); +} +status_t SurfaceFlinger::removeLayerLocked(const Mutex&, const sp& layer, + bool topLevelOnly) { if (layer->isPendingRemoval()) { return NO_ERROR; } @@ -2965,8 +2969,30 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { return old; } +bool SurfaceFlinger::containsAnyInvalidClientState(const Vector& states) { + for (const ComposerState& state : states) { + // Here we need to check that the interface we're given is indeed + // one of our own. A malicious client could give us a nullptr + // IInterface, or one of its own or even one of our own but a + // different type. All these situations would cause us to crash. + if (state.client == nullptr) { + return true; + } + + sp binder = IInterface::asBinder(state.client); + if (binder == nullptr) { + return true; + } + + if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) == nullptr) { + return true; + } + } + return false; +} + void SurfaceFlinger::setTransactionState( - const Vector& state, + const Vector& states, const Vector& displays, uint32_t flags) { @@ -2974,6 +3000,10 @@ void SurfaceFlinger::setTransactionState( Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; + if (containsAnyInvalidClientState(states)) { + return; + } + if (flags & eAnimation) { // For window updates that are part of an animation we must wait for // previous animation "frames" to be handled. @@ -2990,31 +3020,20 @@ void SurfaceFlinger::setTransactionState( } } - size_t count = displays.size(); - for (size_t i=0 ; i binder = IInterface::asBinder(s.client); - if (binder != nullptr) { - if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != nullptr) { - sp client( static_cast(s.client.get()) ); - transactionFlags |= setClientStateLocked(client, s.state); - } - } - } + for (const ComposerState& state : states) { + transactionFlags |= setClientStateLocked(state); + } + + // Iterate through all layers again to determine if any need to be destroyed. Marking layers + // as destroyed should only occur after setting all other states. This is to allow for a + // child re-parent to happen before marking its original parent as destroyed (which would + // then mark the child as destroyed). + for (const ComposerState& state : states) { + setDestroyStateLocked(state); } // If a synchronous transaction is explicitly requested without any changes, force a transaction @@ -3028,7 +3047,7 @@ void SurfaceFlinger::setTransactionState( if (transactionFlags) { if (mInterceptor.isEnabled()) { - mInterceptor.saveTransaction(state, mCurrentState.displays, displays, flags); + mInterceptor.saveTransaction(states, mCurrentState.displays, displays, flags); } // this triggers the transaction @@ -3105,10 +3124,10 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) return flags; } -uint32_t SurfaceFlinger::setClientStateLocked( - const sp& client, - const layer_state_t& s) -{ +uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState) { + const layer_state_t& s = composerState.state; + sp client(static_cast(composerState.client.get())); + sp layer(client->getLayerUser(s.surface)); if (layer == nullptr) { return 0; @@ -3259,6 +3278,25 @@ uint32_t SurfaceFlinger::setClientStateLocked( return flags; } +void SurfaceFlinger::setDestroyStateLocked(const ComposerState& composerState) { + const layer_state_t& state = composerState.state; + sp client(static_cast(composerState.client.get())); + + sp layer(client->getLayerUser(state.surface)); + if (layer == nullptr) { + return; + } + + if (layer->isPendingRemoval()) { + ALOGW("Attempting to destroy on removed layer: %s", layer->getName().string()); + return; + } + + if (state.what & layer_state_t::eDestroySurface) { + removeLayerLocked(mStateLock, layer); + } +} + status_t SurfaceFlinger::createLayer( const String8& name, const sp& client, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index b7ebb1bcf3..08c4a5e3b1 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -473,8 +473,10 @@ private: // Can only be called from the main thread or with mStateLock held uint32_t setTransactionFlags(uint32_t flags); void commitTransaction(); - uint32_t setClientStateLocked(const sp& client, const layer_state_t& s); + bool containsAnyInvalidClientState(const Vector& states); + uint32_t setClientStateLocked(const ComposerState& composerState); uint32_t setDisplayStateLocked(const DisplayState& s); + void setDestroyStateLocked(const ComposerState& composerState); /* ------------------------------------------------------------------------ * Layer management @@ -506,6 +508,7 @@ private: // remove a layer from SurfaceFlinger immediately status_t removeLayer(const sp& layer, bool topLevelOnly = false); + status_t removeLayerLocked(const Mutex&, const sp& layer, bool topLevelOnly = false); // add a layer to SurfaceFlinger status_t addClientLayer(const sp& client, -- cgit v1.2.3-59-g8ed1b