diff options
-rw-r--r-- | libs/gui/LayerState.cpp | 27 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 37 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 15 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 15 | ||||
-rw-r--r-- | libs/ui/include/ui/PictureProfileHandle.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerSnapshot.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 6 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp | 42 |
8 files changed, 144 insertions, 7 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 139764ac0c..c1a03fcfea 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -21,6 +21,7 @@ #include <android/gui/ISurfaceComposerClient.h> #include <android/native_window.h> #include <binder/Parcel.h> +#include <com_android_graphics_libgui_flags.h> #include <gui/FrameRateUtils.h> #include <gui/IGraphicBufferProducer.h> #include <gui/LayerState.h> @@ -91,7 +92,9 @@ layer_state_t::layer_state_t() trustedOverlay(gui::TrustedOverlay::UNSET), bufferCrop(Rect::INVALID_RECT), destinationFrame(Rect::INVALID_RECT), - dropInputMode(gui::DropInputMode::NONE) { + dropInputMode(gui::DropInputMode::NONE), + pictureProfileHandle(PictureProfileHandle::NONE), + appContentPriority(0) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -202,6 +205,10 @@ status_t layer_state_t::write(Parcel& output) const if (hasBufferReleaseChannel) { SAFE_PARCEL(output.writeParcelable, *bufferReleaseChannel); } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS_APPLY_PICTURE_PROFILES + SAFE_PARCEL(output.writeInt64, pictureProfileHandle.getId()); + SAFE_PARCEL(output.writeInt32, appContentPriority); +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS_APPLY_PICTURE_PROFILES const bool hasLuts = (luts != nullptr); SAFE_PARCEL(output.writeBool, hasLuts); @@ -363,6 +370,12 @@ status_t layer_state_t::read(const Parcel& input) bufferReleaseChannel = std::make_shared<gui::BufferReleaseChannel::ProducerEndpoint>(); SAFE_PARCEL(input.readParcelable, bufferReleaseChannel.get()); } +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS_APPLY_PICTURE_PROFILES + int64_t pictureProfileId; + SAFE_PARCEL(input.readInt64, &pictureProfileId); + pictureProfileHandle = PictureProfileHandle(pictureProfileId); + SAFE_PARCEL(input.readInt32, &appContentPriority); +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS_APPLY_PICTURE_PROFILES bool hasLuts; SAFE_PARCEL(input.readBool, &hasLuts); @@ -760,6 +773,16 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eBufferReleaseChannelChanged; bufferReleaseChannel = other.bufferReleaseChannel; } + if (com_android_graphics_libgui_flags_apply_picture_profiles()) { + if (other.what & ePictureProfileHandleChanged) { + what |= ePictureProfileHandleChanged; + pictureProfileHandle = other.pictureProfileHandle; + } + if (other.what & eAppContentPriorityChanged) { + what |= eAppContentPriorityChanged; + appContentPriority = other.appContentPriority; + } + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64, @@ -841,6 +864,8 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { CHECK_DIFF(diff, eDimmingEnabledChanged, other, dimmingEnabled); if (other.what & eBufferReleaseChannelChanged) diff |= eBufferReleaseChannelChanged; if (other.what & eLutsChanged) diff |= eLutsChanged; + CHECK_DIFF(diff, ePictureProfileHandleChanged, other, pictureProfileHandle); + CHECK_DIFF(diff, eAppContentPriorityChanged, other, appContentPriority); return diff; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index a0a8b35acb..61aabaa7f6 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -20,8 +20,6 @@ #include <stdint.h> #include <sys/types.h> -#include <com_android_graphics_libgui_flags.h> - #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/DisplayState.h> #include <android/gui/EdgeExtensionParameters.h> @@ -29,6 +27,7 @@ #include <android/gui/IWindowInfosListener.h> #include <android/gui/TrustedPresentationThresholds.h> #include <android/os/IInputConstants.h> +#include <com_android_graphics_libgui_flags.h> #include <gui/DisplayLuts.h> #include <gui/FrameRateUtils.h> #include <gui/TraceUtils.h> @@ -2451,6 +2450,40 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPictureProfileHandle( + const sp<SurfaceControl>& sc, const PictureProfileHandle& pictureProfileHandle) { + if (com_android_graphics_libgui_flags_apply_picture_profiles()) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::ePictureProfileHandleChanged; + s->pictureProfileHandle = pictureProfileHandle; + + registerSurfaceControlForCallback(sc); + } + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setContentPriority( + const sp<SurfaceControl>& sc, int32_t priority) { + if (com_android_graphics_libgui_flags_apply_picture_profiles()) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eAppContentPriorityChanged; + s->appContentPriority = priority; + + registerSurfaceControlForCallback(sc); + } + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 6bfeaec26a..9098dffa8e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -47,6 +47,7 @@ #include <ui/BlurRegion.h> #include <ui/GraphicTypes.h> #include <ui/LayerStack.h> +#include <ui/PictureProfileHandle.h> #include <ui/Rect.h> #include <ui/Region.h> #include <ui/Rotation.h> @@ -224,6 +225,8 @@ struct layer_state_t { eExtendedRangeBrightnessChanged = 0x10000'00000000, eEdgeExtensionChanged = 0x20000'00000000, eBufferReleaseChannelChanged = 0x40000'00000000, + ePictureProfileHandleChanged = 0x80000'00000000, + eAppContentPriorityChanged = 0x100000'00000000, }; layer_state_t(); @@ -267,7 +270,8 @@ struct layer_state_t { layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged | layer_state_t::eDimmingEnabledChanged | layer_state_t::eHdrMetadataChanged | layer_state_t::eShadowRadiusChanged | - layer_state_t::eStretchChanged; + layer_state_t::eStretchChanged | layer_state_t::ePictureProfileHandleChanged | + layer_state_t::eAppContentPriorityChanged; // Changes which invalidates the layer's visible region in CE. static constexpr uint64_t CONTENT_DIRTY = layer_state_t::CONTENT_CHANGES | @@ -412,6 +416,15 @@ struct layer_state_t { float currentHdrSdrRatio = 1.f; float desiredHdrSdrRatio = 1.f; + // Enhance the quality of the buffer contents by configurating a picture processing pipeline + // with values as specified by this picture profile. + PictureProfileHandle pictureProfileHandle{PictureProfileHandle::NONE}; + + // A value indicating the significance of the layer's content to the app's desired user + // experience. A lower priority will result in more likelihood of getting access to limited + // resources, such as picture processing hardware. + int32_t appContentPriority = 0; + gui::CachingHint cachingHint = gui::CachingHint::Enabled; TrustedPresentationThresholds trustedPresentationThresholds; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 7c6b3416f8..0d7f8c2824 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -38,6 +38,7 @@ #include <ui/EdgeExtensionEffect.h> #include <ui/FrameStats.h> #include <ui/GraphicTypes.h> +#include <ui/PictureProfileHandle.h> #include <ui/PixelFormat.h> #include <ui/Rotation.h> #include <ui/StaticDisplayInfo.h> @@ -776,6 +777,20 @@ public: const sp<SurfaceControl>& sc, const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel); + /** + * Configures a surface control to use picture processing hardware, configured as specified + * by the picture profile, to enhance the quality of all subsequent buffer contents. + */ + Transaction& setPictureProfileHandle(const sp<SurfaceControl>& sc, + const PictureProfileHandle& pictureProfileHandle); + + /** + * Configures the relative importance of the contents of the layer with respect to the app's + * user experience. A lower priority value will give the layer preferred access to limited + * resources, such as picture processing, over a layer with a higher priority value. + */ + Transaction& setContentPriority(const sp<SurfaceControl>& sc, int32_t contentPriority); + status_t setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); diff --git a/libs/ui/include/ui/PictureProfileHandle.h b/libs/ui/include/ui/PictureProfileHandle.h index 9b709b6155..f8406501b4 100644 --- a/libs/ui/include/ui/PictureProfileHandle.h +++ b/libs/ui/include/ui/PictureProfileHandle.h @@ -39,7 +39,7 @@ public: static const PictureProfileHandle NONE; PictureProfileHandle() { *this = NONE; } - PictureProfileHandle(PictureProfileId id) : mId(id) {} + explicit PictureProfileHandle(PictureProfileId id) : mId(id) {} PictureProfileId const& getId() const { return mId; } diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index a8be50a074..58f6b96e57 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp @@ -413,6 +413,13 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate if (forceUpdate || requested.what & layer_state_t::eCropChanged) { geomCrop = requested.crop; } + if (forceUpdate || requested.what & layer_state_t::ePictureProfileHandleChanged) { + pictureProfileHandle = requested.pictureProfileHandle; + } + if (forceUpdate || requested.what & layer_state_t::eAppContentPriorityChanged) { + // TODO(b/337330263): Also consider the system-determined priority of the app + pictureProfilePriority = requested.appContentPriority; + } if (forceUpdate || requested.what & layer_state_t::eDefaultFrameRateCompatibilityChanged) { const auto compatibility = diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a7ab117679..0d03a6cef3 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3558,7 +3558,9 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl } state.isProtected = true; state.displayName = std::move(info.name); - + state.maxLayerPictureProfiles = getHwComposer().getMaxLayerPictureProfiles(displayId); + state.hasPictureProcessing = + getHwComposer().hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING); mCurrentState.displays.add(token, state); ALOGI("Connecting %s", displayString); return activeModeId; @@ -3719,6 +3721,8 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, builder.setPixels(resolution); builder.setIsSecure(state.isSecure); builder.setIsProtected(state.isProtected); + builder.setHasPictureProcessing(state.hasPictureProcessing); + builder.setMaxLayerPictureProfiles(state.maxLayerPictureProfiles); builder.setPowerAdvisor(mPowerAdvisor.get()); builder.setName(state.displayName); auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index e6b8a26487..6aec7434de 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -28,7 +28,6 @@ #include "ui/GraphicTypes.h" #include <com_android_graphics_libgui_flags.h> -#include <com_android_graphics_surfaceflinger_flags.h> #define UPDATE_AND_VERIFY(BUILDER, ...) \ ({ \ @@ -1985,4 +1984,45 @@ TEST_F(LayerSnapshotTest, contentDirtyWhenParentGeometryChanges) { UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); EXPECT_FALSE(getSnapshot(1)->contentDirty); } +TEST_F(LayerSnapshotTest, shouldUpdatePictureProfileHandle) { + if (!com_android_graphics_libgui_flags_apply_picture_profiles()) { + GTEST_SKIP() << "Flag disabled, skipping test"; + } + std::vector<TransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + transactions.back().states.front().layerId = 1; + transactions.back().states.front().state.layerId = 1; + transactions.back().states.front().state.what = layer_state_t::ePictureProfileHandleChanged; + transactions.back().states.front().state.pictureProfileHandle = PictureProfileHandle(3); + + mLifecycleManager.applyTransactions(transactions); + EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Content); + + update(mSnapshotBuilder); + + EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::ePictureProfileHandleChanged); + EXPECT_EQ(getSnapshot(1)->pictureProfileHandle, PictureProfileHandle(3)); +} + +TEST_F(LayerSnapshotTest, shouldUpdatePictureProfilePriorityFromAppContentPriority) { + if (!com_android_graphics_libgui_flags_apply_picture_profiles()) { + GTEST_SKIP() << "Flag disabled, skipping test"; + } + std::vector<TransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + transactions.back().states.front().layerId = 1; + transactions.back().states.front().state.layerId = 1; + transactions.back().states.front().state.what = layer_state_t::eAppContentPriorityChanged; + transactions.back().states.front().state.appContentPriority = 3; + + mLifecycleManager.applyTransactions(transactions); + EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Content); + + update(mSnapshotBuilder); + + EXPECT_EQ(getSnapshot(1)->pictureProfilePriority, 3); +} + } // namespace android::surfaceflinger::frontend |