From 0783e99d457c9d9a3ede400bdb355ba35e828de6 Mon Sep 17 00:00:00 2001 From: Chris Ye Date: Tue, 2 Jun 2020 21:34:49 -0700 Subject: AIDL-ize InputManager IInputFlinger interface. Use AIDL interface to define the IInputFlinger interface and replace the manual interface. Bug:155425003 Test: atest libgui_test, atest libinput_test. Change-Id: Ibad036b8ceb3a3f5c6d58f8de4ea8c79379d29b5 --- libs/gui/LayerState.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e43446ac8c..1030b82f14 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -55,7 +55,7 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(color.g); output.writeFloat(color.b); #ifndef NO_INPUT - inputInfo.write(output); + inputHandle->writeToParcel(&output); #endif output.write(transparentRegion); output.writeUint32(transform); @@ -152,7 +152,7 @@ status_t layer_state_t::read(const Parcel& input) color.b = input.readFloat(); #ifndef NO_INPUT - inputInfo = InputWindowInfo::read(input); + inputHandle->readFromParcel(&input); #endif input.read(transparentRegion); @@ -404,7 +404,7 @@ void layer_state_t::merge(const layer_state_t& other) { #ifndef NO_INPUT if (other.what & eInputInfoChanged) { what |= eInputInfoChanged; - inputInfo = other.inputInfo; + inputHandle = new InputWindowHandle(*other.inputHandle); } #endif -- cgit v1.2.3-59-g8ed1b From e798b47821d07191a20bdb7a3a1fc3887b661635 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Thu, 23 Jul 2020 13:52:21 -0700 Subject: Add setFocusedWindow function stub This function, once implemented, will set focus on the specified window. This is the first step in changing focus selection from setInputWindows and using explicit call which will help us more easily decouple z-order from focus selection and support focus for SurfaceViewHost surfaces. Bug: 151179149 Test: presubmit Test: go/wm-smoke Test: atest inputflinger_tests Change-Id: Ib2254b4ab3ba8d579dfe49ddf3286f8ce2eecf9e --- libs/gui/Android.bp | 1 + libs/gui/LayerState.cpp | 19 ++++++- libs/gui/SurfaceComposerClient.cpp | 15 ++++++ libs/gui/include/gui/LayerState.h | 7 ++- libs/gui/include/gui/SurfaceComposerClient.h | 3 ++ libs/input/Android.bp | 1 + libs/input/android/FocusRequest.aidl | 39 ++++++++++++++ libs/input/android/os/IInputFlinger.aidl | 6 +++ services/inputflinger/InputManager.cpp | 5 ++ services/inputflinger/InputManager.h | 1 + .../inputflinger/dispatcher/InputDispatcher.cpp | 15 ++++++ services/inputflinger/dispatcher/InputDispatcher.h | 1 + .../dispatcher/include/InputDispatcherInterface.h | 6 +++ services/inputflinger/host/InputFlinger.h | 1 + services/inputflinger/tests/Android.bp | 4 +- .../inputflinger/tests/IInputFlingerQuery.aidl | 2 + .../tests/InputFlingerService_test.cpp | 61 +++++++++++++++++++++- services/surfaceflinger/SurfaceFlinger.cpp | 13 +++-- 18 files changed, 187 insertions(+), 13 deletions(-) create mode 100644 libs/input/android/FocusRequest.aidl (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 4a4510e047..686e274a11 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -92,6 +92,7 @@ cc_library_shared { export_shared_lib_headers: [ "libbinder", + "libinput", ], // bufferhub is not used when building libgui for vendors diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 1030b82f14..117ce58719 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -448,19 +448,36 @@ void layer_state_t::merge(const layer_state_t& other) { // ------------------------------- InputWindowCommands ---------------------------------------- -void InputWindowCommands::merge(const InputWindowCommands& other) { +bool InputWindowCommands::merge(const InputWindowCommands& other) { + bool changes = false; +#ifndef NO_INPUT + changes |= !other.focusRequests.empty(); + focusRequests.insert(focusRequests.end(), std::make_move_iterator(other.focusRequests.begin()), + std::make_move_iterator(other.focusRequests.end())); +#endif + changes |= other.syncInputWindows && !syncInputWindows; syncInputWindows |= other.syncInputWindows; + return changes; } void InputWindowCommands::clear() { +#ifndef NO_INPUT + focusRequests.clear(); +#endif syncInputWindows = false; } void InputWindowCommands::write(Parcel& output) const { +#ifndef NO_INPUT + output.writeParcelableVector(focusRequests); +#endif output.writeBool(syncInputWindows); } void InputWindowCommands::read(const Parcel& input) { +#ifndef NO_INPUT + input.readParcelableVector(&focusRequests); +#endif syncInputWindows = input.readBool(); } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index d797a3547a..229a5c2e62 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1364,6 +1364,21 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInput return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow( + const sp& token, const sp& focusedToken, nsecs_t timestampNanos) { + FocusRequest request; + request.token = token; + request.focusedToken = focusedToken; + request.timestamp = timestampNanos; + return setFocusedWindow(request); +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow( + const FocusRequest& request) { + mInputWindowCommands.focusRequests.push_back(request); + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::syncInputWindows() { mInputWindowCommands.syncInputWindows = true; return *this; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 00ae220906..41aad0d309 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -26,6 +26,7 @@ #include #ifndef NO_INPUT +#include #include not need to * be a valid refresh rate for this device's display - e.g., it's fine to pass 30fps to a device * that can only run the display at 60fps. * - * |compatibility| The frame rate compatibility of this surface. The compatibility value may + * \param compatibility The frame rate compatibility of this surface. The compatibility value may * influence the system's choice of display frame rate. To specify a compatibility use the * ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* enum. * - * Available since API level 30. + * \param shouldBeSeamless Whether display refresh rate transitions should be seamless. A + * seamless transition is one that doesn't have any visual interruptions, such as a black + * screen for a second or two. True indicates that any frame rate changes caused by this + * request should be seamless. False indicates that non-seamless refresh rates are also + * acceptable. + * + * Available since API level 31. */ -void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction, +void ASurfaceTransaction_setFrameRateWithSeamlessness(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, float frameRate, - int8_t compatibility) __INTRODUCED_IN(30); - -#endif // __ANDROID_API__ >= 30 + int8_t compatibility, bool shouldBeSeamless) + __INTRODUCED_IN(31); +#endif // __ANDROID_API__ >= 31 __END_DECLS #endif // ANDROID_SURFACE_CONTROL_H diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 678613b1ff..ac1c7369b6 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -378,11 +378,11 @@ public: }).detach(); } - status_t setFrameRate(float frameRate, int8_t compatibility) override { + status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless) override { if (!ValidateFrameRate(frameRate, compatibility, "BBQSurface::setFrameRate")) { return BAD_VALUE; } - return mBbq->setFrameRate(frameRate, compatibility); + return mBbq->setFrameRate(frameRate, compatibility, shouldBeSeamless); } status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId) override { @@ -392,12 +392,12 @@ public: // TODO: Can we coalesce this with frame updates? Need to confirm // no timing issues. -status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility) { +status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility, + bool shouldBeSeamless) { std::unique_lock _lock{mMutex}; SurfaceComposerClient::Transaction t; - return t.setFrameRate(mSurfaceControl, frameRate, compatibility) - .apply(); + return t.setFrameRate(mSurfaceControl, frameRate, compatibility, shouldBeSeamless).apply(); } status_t BLASTBufferQueue::setFrameTimelineVsync(int64_t frameTimelineVsyncId) { diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 6f92233935..a9fe5bf319 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -1114,7 +1114,7 @@ public: } virtual status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility) { + int8_t compatibility, bool shouldBeSeamless) { Parcel data, reply; status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { @@ -1140,6 +1140,12 @@ public: return err; } + err = data.writeBool(shouldBeSeamless); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed writing bool: %s (%d)", strerror(-err), -err); + return err; + } + err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply); if (err != NO_ERROR) { ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err); @@ -2033,7 +2039,13 @@ status_t BnSurfaceComposer::onTransact( ALOGE("setFrameRate: failed to read byte: %s (%d)", strerror(-err), -err); return err; } - status_t result = setFrameRate(surface, frameRate, compatibility); + bool shouldBeSeamless; + err = data.readBool(&shouldBeSeamless); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed to read bool: %s (%d)", strerror(-err), -err); + return err; + } + status_t result = setFrameRate(surface, frameRate, compatibility, shouldBeSeamless); reply->writeInt32(result); return NO_ERROR; } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 9722f368f4..90999faa78 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -59,6 +59,7 @@ layer_state_t::layer_state_t() frameRateSelectionPriority(-1), frameRate(0.0f), frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT), + shouldBeSeamless(true), fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0) { matrix.dsdx = matrix.dtdy = 1.0f; @@ -144,6 +145,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeInt32, frameRateSelectionPriority); SAFE_PARCEL(output.writeFloat, frameRate); SAFE_PARCEL(output.writeByte, frameRateCompatibility); + SAFE_PARCEL(output.writeBool, shouldBeSeamless); SAFE_PARCEL(output.writeUint32, fixedTransformHint); SAFE_PARCEL(output.writeUint64, frameNumber); SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId); @@ -262,6 +264,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readInt32, &frameRateSelectionPriority); SAFE_PARCEL(input.readFloat, &frameRate); SAFE_PARCEL(input.readByte, &frameRateCompatibility); + SAFE_PARCEL(input.readBool, &shouldBeSeamless); SAFE_PARCEL(input.readUint32, &tmpUint32); fixedTransformHint = static_cast(tmpUint32); SAFE_PARCEL(input.readUint64, &frameNumber); @@ -521,6 +524,7 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eFrameRateChanged; frameRate = other.frameRate; frameRateCompatibility = other.frameRateCompatibility; + shouldBeSeamless = other.shouldBeSeamless; } if (other.what & eFixedTransformHintChanged) { what |= eFixedTransformHintChanged; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index c1155ab73a..94390aa86c 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1443,7 +1443,8 @@ int Surface::dispatchGetLastQueueDuration(va_list args) { int Surface::dispatchSetFrameRate(va_list args) { float frameRate = static_cast(va_arg(args, double)); int8_t compatibility = static_cast(va_arg(args, int)); - return setFrameRate(frameRate, compatibility); + bool shouldBeSeamless = static_cast(va_arg(args, int)); + return setFrameRate(frameRate, compatibility, shouldBeSeamless); } int Surface::dispatchAddCancelInterceptor(va_list args) { @@ -2279,7 +2280,7 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vectoronBuffersDiscarded(discardedBufs); } -status_t Surface::setFrameRate(float frameRate, int8_t compatibility) { +status_t Surface::setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless) { ATRACE_CALL(); ALOGV("Surface::setFrameRate"); @@ -2287,7 +2288,8 @@ status_t Surface::setFrameRate(float frameRate, int8_t compatibility) { return BAD_VALUE; } - return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility); + return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility, + shouldBeSeamless); } status_t Surface::setFrameTimelineVsync(int64_t frameTimelineVsyncId) { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 039e9008e8..a822598d82 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1474,7 +1474,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShado } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate( - const sp& sc, float frameRate, int8_t compatibility) { + const sp& sc, float frameRate, int8_t compatibility, + bool shouldBeSeamless) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; @@ -1487,6 +1488,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame s->what |= layer_state_t::eFrameRateChanged; s->frameRate = frameRate; s->frameRateCompatibility = compatibility; + s->shouldBeSeamless = shouldBeSeamless; return *this; } diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index 2300e81aa7..7741d8c38a 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -85,7 +85,7 @@ public: void update(const sp& surface, uint32_t width, uint32_t height); void flushShadowQueue() { mFlushShadowQueue = true; } - status_t setFrameRate(float frameRate, int8_t compatibility); + status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId); virtual ~BLASTBufferQueue() = default; diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 5cd9356449..9e96b79b8c 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -475,7 +475,7 @@ public: * Sets the intended frame rate for a surface. See ANativeWindow_setFrameRate() for more info. */ virtual status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility) = 0; + int8_t compatibility, bool shouldBeSeamless) = 0; /* * Acquire a frame rate flexibility token from SurfaceFlinger. While this token is acquired, diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index a73d9a68a5..d9f280684f 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -218,6 +218,7 @@ struct layer_state_t { // Layer frame rate and compatibility. See ANativeWindow_setFrameRate(). float frameRate; int8_t frameRateCompatibility; + bool shouldBeSeamless; // Set by window manager indicating the layer and all its children are // in a different orientation than the display. The hint suggests that diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 4aa076e7b2..82bc5c9efb 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -186,7 +186,7 @@ public: status_t getUniqueId(uint64_t* outId) const; status_t getConsumerUsage(uint64_t* outUsage) const; - virtual status_t setFrameRate(float frameRate, int8_t compatibility); + virtual status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); virtual status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId); protected: diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 73909a30bb..6289c6a3cd 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -524,7 +524,7 @@ public: Transaction& setShadowRadius(const sp& sc, float cornerRadius); Transaction& setFrameRate(const sp& sc, float frameRate, - int8_t compatibility); + int8_t compatibility, bool shouldBeSeamless); // Set by window manager indicating the layer and all its children are // in a different orientation than the display. The hint suggests that diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 0cd3962aa1..2392ae5ccd 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -869,7 +869,7 @@ public: } status_t setFrameRate(const sp& /*surface*/, float /*frameRate*/, - int8_t /*compatibility*/) override { + int8_t /*compatibility*/, bool /*shouldBeSeamless*/) override { return NO_ERROR; } diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index fd1793b6bc..b406a9c2fe 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -159,10 +159,8 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) { } int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_t compatibility) { - if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) { - return -EINVAL; - } - return native_window_set_frame_rate(window, frameRate, compatibility); + return ANativeWindow_setFrameRateWithSeamlessness(window, frameRate, compatibility, + /*shouldBeSeamless*/ true); } void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { @@ -172,6 +170,13 @@ void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); } +int32_t ANativeWindow_setFrameRateWithSeamlessness(ANativeWindow* window, float frameRate, + int8_t compatibility, bool shouldBeSeamless) { + if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) { + return -EINVAL; + } + return native_window_set_frame_rate(window, frameRate, compatibility, shouldBeSeamless); +} /************************************************************************************************** * vndk-stable diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h index 36aad2eced..deea59b9fb 100644 --- a/libs/nativewindow/include/android/native_window.h +++ b/libs/nativewindow/include/android/native_window.h @@ -34,6 +34,7 @@ #define ANDROID_NATIVE_WINDOW_H #include +#include #include #include @@ -255,6 +256,31 @@ enum ANativeWindow_FrameRateCompatibility { ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1 }; +/** + * Same as ANativeWindow_setFrameRateWithSeamlessness(window, frameRate, compatibility, true). + * + * See ANativeWindow_setFrameRateWithSeamlessness(). + * + * Available since API level 30. + */ +int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_t compatibility) + __INTRODUCED_IN(30); + +/** + * Provides a hint to the window that buffers should be preallocated ahead of + * time. Note that the window implementation is not guaranteed to preallocate + * any buffers, for instance if an implementation disallows allocation of new + * buffers, or if there is insufficient memory in the system to preallocate + * additional buffers + * + * Available since API level 30. + */ +void ANativeWindow_tryAllocateBuffers(ANativeWindow* window); + +#endif // __ANDROID_API__ >= 30 + +#if __ANDROID_API__ >= 31 + /** * Sets the intended frame rate for this window. * @@ -271,7 +297,7 @@ enum ANativeWindow_FrameRateCompatibility { * this ANativeWindow is consumed by something other than the system compositor, * e.g. a media codec, this call has no effect. * - * Available since API level 30. + * Available since API level 31. * * \param frameRate The intended frame rate of this window, in frames per * second. 0 is a special value that indicates the app will accept the system's @@ -284,24 +310,19 @@ enum ANativeWindow_FrameRateCompatibility { * compatibility value may influence the system's choice of display refresh * rate. See the ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* values for more info. * + * \param shouldBeSeamless Whether display refresh rate transitions should be seamless. A + * seamless transition is one that doesn't have any visual interruptions, such as a black + * screen for a second or two. True indicates that any frame rate changes caused by this + * request should be seamless. False indicates that non-seamless refresh rates are also + * acceptable. + * * \return 0 for success, -EINVAL if the window, frame rate, or compatibility * value are invalid. */ -int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_t compatibility) - __INTRODUCED_IN(30); +int32_t ANativeWindow_setFrameRateWithSeamlessness(ANativeWindow* window, float frameRate, + int8_t compatibility, bool shouldBeSeamless) __INTRODUCED_IN(31); -/** - * Provides a hint to the window that buffers should be preallocated ahead of - * time. Note that the window implementation is not guaranteed to preallocate - * any buffers, for instance if an implementation disallows allocation of new - * buffers, or if there is insufficient memory in the system to preallocate - * additional buffers - * - * Available since API level 30. - */ -void ANativeWindow_tryAllocateBuffers(ANativeWindow* window); - -#endif // __ANDROID_API__ >= 30 +#endif // __ANDROID_API__ >= 31 #ifdef __cplusplus }; diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 138e08f490..82d2e661b4 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -1018,9 +1018,9 @@ static inline int native_window_set_auto_prerotation(struct ANativeWindow* windo } static inline int native_window_set_frame_rate(struct ANativeWindow* window, float frameRate, - int8_t compatibility) { + int8_t compatibility, bool shouldBeSeamless) { return window->perform(window, NATIVE_WINDOW_SET_FRAME_RATE, (double)frameRate, - (int)compatibility); + (int)compatibility, (int)shouldBeSeamless); } static inline int native_window_set_frame_timeline_vsync(struct ANativeWindow* window, diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 1b5d20dff7..de48ec25dd 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -46,6 +46,7 @@ LIBNATIVEWINDOW { ANativeWindow_setBuffersTransform; ANativeWindow_setDequeueTimeout; # apex # introduced=30 ANativeWindow_setFrameRate; # introduced=30 + ANativeWindow_setFrameRateWithSeamlessness; # introduced=31 ANativeWindow_setSharedBufferMode; # llndk ANativeWindow_setSwapInterval; # llndk ANativeWindow_setUsage; # llndk diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 94819664ce..79e2ad0dbd 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1687,8 +1687,9 @@ void Layer::miniDump(std::string& result, const DisplayDevice& display) const { crop.bottom); if (layerState.frameRate.rate != 0 || layerState.frameRate.type != FrameRateCompatibility::Default) { - StringAppendF(&result, "% 6.2ffps %15s", layerState.frameRate.rate, - frameRateCompatibilityString(layerState.frameRate.type).c_str()); + StringAppendF(&result, "% 6.2ffps %15s seamless=%d", layerState.frameRate.rate, + frameRateCompatibilityString(layerState.frameRate.type).c_str(), + layerState.frameRate.shouldBeSeamless); } else { StringAppendF(&result, " "); } @@ -2750,6 +2751,12 @@ bool Layer::getPrimaryDisplayOnly() const { // --------------------------------------------------------------------------- +std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) { + return stream << "{rate=" << rate.rate + << " type=" << Layer::frameRateCompatibilityString(rate.type) + << " shouldBeSeamless=" << rate.shouldBeSeamless << "}"; +} + }; // namespace android #if defined(__gl_h_) diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index b1ab9ec306..1a784aa778 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -153,12 +153,15 @@ public: struct FrameRate { float rate; FrameRateCompatibility type; + bool shouldBeSeamless; - FrameRate() : rate(0), type(FrameRateCompatibility::Default) {} - FrameRate(float rate, FrameRateCompatibility type) : rate(rate), type(type) {} + FrameRate() : rate(0), type(FrameRateCompatibility::Default), shouldBeSeamless(true) {} + FrameRate(float rate, FrameRateCompatibility type, bool shouldBeSeamless = true) + : rate(rate), type(type), shouldBeSeamless(shouldBeSeamless) {} bool operator==(const FrameRate& other) const { - return rate == other.rate && type == other.type; + return rate == other.rate && type == other.type && + shouldBeSeamless == other.shouldBeSeamless; } bool operator!=(const FrameRate& other) const { return !(*this == other); } @@ -1126,4 +1129,6 @@ private: const std::vector& getBlurRegions() const; }; +std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate); + } // namespace android diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 36433c20ed..28af930bbe 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -125,12 +125,23 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) { return LayerVoteType::NoVote; } }(); - summary.push_back({layer->getName(), voteType, frameRate.rate, /* weight */ 1.0f, - layerFocused}); + summary.push_back( + RefreshRateConfigs::LayerRequirement{.name = layer->getName(), + .vote = voteType, + .desiredRefreshRate = frameRate.rate, + .shouldBeSeamless = + frameRate.shouldBeSeamless, + .weight = 1.0f, + .focused = layerFocused}); } else if (recent) { - summary.push_back({layer->getName(), LayerVoteType::Heuristic, - info->getRefreshRate(now), - /* weight */ 1.0f, layerFocused}); + summary.push_back( + RefreshRateConfigs::LayerRequirement{.name = layer->getName(), + .vote = LayerVoteType::Heuristic, + .desiredRefreshRate = + info->getRefreshRate(now), + .shouldBeSeamless = true, + .weight = 1.0f, + .focused = layerFocused}); } if (CC_UNLIKELY(mTraceEnabled)) { diff --git a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp index 37e67e17fe..a63ccc1df0 100644 --- a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp @@ -130,9 +130,9 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) { ALOGV("%s has priority: %d %s focused", strong->getName().c_str(), frameRateSelectionPriority, layerFocused ? "" : "not"); - const auto [type, refreshRate] = info->getRefreshRate(now); + const auto vote = info->getRefreshRateVote(now); // Skip NoVote layer as those don't have any requirements - if (type == LayerHistory::LayerVoteType::NoVote) { + if (vote.type == LayerHistory::LayerVoteType::NoVote) { continue; } @@ -144,10 +144,11 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) { const float layerArea = transformed.getWidth() * transformed.getHeight(); float weight = mDisplayArea ? layerArea / mDisplayArea : 0.0f; - summary.push_back({strong->getName(), type, refreshRate, weight, layerFocused}); + summary.push_back({strong->getName(), vote.type, vote.fps, vote.shouldBeSeamless, weight, + layerFocused}); if (CC_UNLIKELY(mTraceEnabled)) { - trace(layer, *info, type, static_cast(std::round(refreshRate))); + trace(layer, *info, vote.type, static_cast(std::round(vote.fps))); } } @@ -178,7 +179,7 @@ void LayerHistoryV2::partitionLayers(nsecs_t now) { if (frameRate.rate > 0 || voteType == LayerVoteType::NoVote) { const auto type = layer->isVisible() ? voteType : LayerVoteType::NoVote; - info->setLayerVote(type, frameRate.rate); + info->setLayerVote({type, frameRate.rate, frameRate.shouldBeSeamless}); } else { info->resetLayerVote(); } diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp index 44f20d0063..94e7e20251 100644 --- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp @@ -198,10 +198,10 @@ std::optional LayerInfoV2::calculateRefreshRateIfPossible(nsecs_t now) { : std::make_optional(mLastRefreshRate.reported); } -std::pair LayerInfoV2::getRefreshRate(nsecs_t now) { +LayerInfoV2::LayerVote LayerInfoV2::getRefreshRateVote(nsecs_t now) { if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) { ALOGV("%s voted %d ", mName.c_str(), static_cast(mLayerVote.type)); - return {mLayerVote.type, mLayerVote.fps}; + return mLayerVote; } if (isAnimating(now)) { diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.h b/services/surfaceflinger/Scheduler/LayerInfoV2.h index 33dc66fd19..2305bc3055 100644 --- a/services/surfaceflinger/Scheduler/LayerInfoV2.h +++ b/services/surfaceflinger/Scheduler/LayerInfoV2.h @@ -56,6 +56,13 @@ class LayerInfoV2 { friend class LayerHistoryTestV2; public: + // Holds information about the layer vote + struct LayerVote { + LayerHistory::LayerVoteType type = LayerHistory::LayerVoteType::Heuristic; + float fps = 0.0f; + bool shouldBeSeamless = true; + }; + static void setTraceEnabled(bool enabled) { sTraceEnabled = enabled; } static void setRefreshRateConfigs(const RefreshRateConfigs& refreshRateConfigs) { @@ -76,7 +83,7 @@ public: // Sets an explicit layer vote. This usually comes directly from the application via // ANativeWindow_setFrameRate API - void setLayerVote(LayerHistory::LayerVoteType type, float fps) { mLayerVote = {type, fps}; } + void setLayerVote(LayerVote vote) { mLayerVote = vote; } // Sets the default layer vote. This will be the layer vote after calling to resetLayerVote(). // This is used for layers that called to setLayerVote() and then removed the vote, so that the @@ -84,9 +91,9 @@ public: void setDefaultLayerVote(LayerHistory::LayerVoteType type) { mDefaultVote = type; } // Resets the layer vote to its default. - void resetLayerVote() { mLayerVote = {mDefaultVote, 0.0f}; } + void resetLayerVote() { mLayerVote = {mDefaultVote, 0.0f, true}; } - std::pair getRefreshRate(nsecs_t now); + LayerVote getRefreshRateVote(nsecs_t now); // Return the last updated time. If the present time is farther in the future than the // updated time, the updated time is the present time. @@ -130,12 +137,6 @@ private: bool animatingOrInfrequent = false; }; - // Holds information about the layer vote - struct LayerVote { - LayerHistory::LayerVoteType type = LayerHistory::LayerVoteType::Heuristic; - float fps = 0.0f; - }; - // Class to store past calculated refresh rate and determine whether // the refresh rate calculated is consistent with past values class RefreshRateHistory { diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index 150f925fe0..0646c7dfd5 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -31,6 +31,12 @@ namespace android::scheduler { using AllRefreshRatesMapType = RefreshRateConfigs::AllRefreshRatesMapType; using RefreshRate = RefreshRateConfigs::RefreshRate; +std::string RefreshRate::toString() const { + return base::StringPrintf("{id=%d, hwcId=%d, fps=%.2f, width=%d, height=%d group=%d}", + getConfigId().value(), hwcConfig->getId(), getFps(), + hwcConfig->getWidth(), hwcConfig->getHeight(), getConfigGroup()); +} + std::string RefreshRateConfigs::layerVoteTypeString(LayerVoteType vote) { switch (vote) { case LayerVoteType::NoVote: @@ -125,7 +131,7 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( const std::vector& layers, const GlobalSignals& globalSignals, GlobalSignals* outSignalsConsidered) const { ATRACE_CALL(); - ALOGV("getRefreshRateForContent %zu layers", layers.size()); + ALOGV("getBestRefreshRate %zu layers", layers.size()); if (outSignalsConsidered) *outSignalsConsidered = {}; const auto setTouchConsidered = [&] { @@ -148,6 +154,7 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( int explicitDefaultVoteLayers = 0; int explicitExactOrMultipleVoteLayers = 0; float maxExplicitWeight = 0; + int seamedLayers = 0; for (const auto& layer : layers) { if (layer.vote == LayerVoteType::NoVote) { noVoteLayers++; @@ -162,6 +169,10 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( explicitExactOrMultipleVoteLayers++; maxExplicitWeight = std::max(maxExplicitWeight, layer.weight); } + + if (!layer.shouldBeSeamless) { + seamedLayers++; + } } const bool hasExplicitVoteLayers = @@ -206,6 +217,8 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( scores.emplace_back(refreshRate, 0.0f); } + const auto& defaultConfig = mRefreshRates.at(policy->defaultConfig); + for (const auto& layer : layers) { ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), layer.weight); @@ -216,6 +229,30 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( auto weight = layer.weight; for (auto i = 0u; i < scores.size(); i++) { + // If there are no layers with shouldBeSeamless=false and the current + // config group is different from the default one, this means a layer with + // shouldBeSeamless=false has just disappeared and we should switch back to + // the default config group. + const bool isSeamlessSwitch = seamedLayers > 0 + ? scores[i].first->getConfigGroup() == mCurrentRefreshRate->getConfigGroup() + : scores[i].first->getConfigGroup() == defaultConfig->getConfigGroup(); + + if (layer.shouldBeSeamless && !isSeamlessSwitch) { + ALOGV("%s (weight %.2f) ignores %s (group=%d) to avoid non-seamless switch." + "Current config = %s", + layer.name.c_str(), weight, scores[i].first->name.c_str(), + scores[i].first->getConfigGroup(), mCurrentRefreshRate->toString().c_str()); + continue; + } + + if (!layer.shouldBeSeamless && !isSeamlessSwitch && !layer.focused) { + ALOGV("%s (weight %.2f) ignores %s (group=%d) because it's not focused" + " and the switch is going to be seamed. Current config = %s", + layer.name.c_str(), weight, scores[i].first->name.c_str(), + scores[i].first->getConfigGroup(), mCurrentRefreshRate->toString().c_str()); + continue; + } + bool inPrimaryRange = scores[i].first->inPolicy(policy->primaryRange.min, policy->primaryRange.max); if ((primaryRangeIsSingleRate || !inPrimaryRange) && @@ -292,10 +329,13 @@ const RefreshRate& RefreshRateConfigs::getBestRefreshRate( return 1.0f / iter; }(); + // Slightly prefer seamless switches. + constexpr float kSeamedSwitchPenalty = 0.95f; + const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty; ALOGV("%s (%s, weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(), layerScore); - scores[i].second += weight * layerScore; + scores[i].second += weight * layerScore * seamlessness; continue; } } @@ -367,6 +407,15 @@ const RefreshRate& RefreshRateConfigs::getMinRefreshRateByPolicy() const { } const RefreshRate& RefreshRateConfigs::getMinRefreshRateByPolicyLocked() const { + for (auto refreshRate : mPrimaryRefreshRates) { + if (mCurrentRefreshRate->getConfigGroup() == refreshRate->getConfigGroup()) { + return *refreshRate; + } + } + ALOGE("Can't find min refresh rate by policy with the same config group" + " as the current config %s", + mCurrentRefreshRate->toString().c_str()); + // Defaulting to the lowest refresh rate return *mPrimaryRefreshRates.front(); } @@ -376,6 +425,16 @@ const RefreshRate& RefreshRateConfigs::getMaxRefreshRateByPolicy() const { } const RefreshRate& RefreshRateConfigs::getMaxRefreshRateByPolicyLocked() const { + for (auto it = mPrimaryRefreshRates.rbegin(); it != mPrimaryRefreshRates.rend(); it++) { + const auto& refreshRate = (**it); + if (mCurrentRefreshRate->getConfigGroup() == refreshRate.getConfigGroup()) { + return refreshRate; + } + } + ALOGE("Can't find max refresh rate by policy with the same config group" + " as the current config %s", + mCurrentRefreshRate->toString().c_str()); + // Defaulting to the highest refresh rate return *mPrimaryRefreshRates.back(); } @@ -414,7 +473,7 @@ RefreshRateConfigs::RefreshRateConfigs( const float fps = 1e9f / config->getVsyncPeriod(); mRefreshRates.emplace(configId, std::make_unique(configId, config, - base::StringPrintf("%.0ffps", fps), fps, + base::StringPrintf("%.2ffps", fps), fps, RefreshRate::ConstructorTag(0))); if (configId == currentConfigId) { mCurrentRefreshRate = mRefreshRates.at(configId).get(); diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h index 8ff92a095c..41e54a7e7b 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -86,6 +86,8 @@ public: bool operator==(const RefreshRate& other) const { return !(*this != other); } + std::string toString() const; + private: friend RefreshRateConfigs; friend class RefreshRateConfigsTest; @@ -216,6 +218,8 @@ public: LayerVoteType vote = LayerVoteType::NoVote; // Layer's desired refresh rate, if applicable. float desiredRefreshRate = 0.0f; + // If a seamless mode switch is required. + bool shouldBeSeamless = true; // Layer's weight in the range of [0, 1]. The higher the weight the more impact this layer // would have on choosing the refresh rate. float weight = 0.0f; diff --git a/services/surfaceflinger/Scheduler/StrongTyping.h b/services/surfaceflinger/Scheduler/StrongTyping.h index e8ca0ba836..6a60257c81 100644 --- a/services/surfaceflinger/Scheduler/StrongTyping.h +++ b/services/surfaceflinger/Scheduler/StrongTyping.h @@ -70,6 +70,10 @@ struct StrongTyping : Ability>... { T const& value() const { return mValue; } T& value() { return mValue; } + friend std::ostream& operator<<(std::ostream& os, const StrongTyping& value) { + return os << value.value(); + } + private: T mValue; }; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 57c4d52653..28a8e7ac12 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3781,7 +3781,8 @@ uint32_t SurfaceFlinger::setClientStateLocked( "SurfaceFlinger::setClientStateLocked") && layer->setFrameRate(Layer::FrameRate(s.frameRate, Layer::FrameRate::convertCompatibility( - s.frameRateCompatibility)))) { + s.frameRateCompatibility), + s.shouldBeSeamless))) { flags |= eTraversalNeeded; } } @@ -6135,7 +6136,7 @@ const std::unordered_map& SurfaceFlinger::getGenericLayer } status_t SurfaceFlinger::setFrameRate(const sp& surface, float frameRate, - int8_t compatibility) { + int8_t compatibility, bool shouldBeSeamless) { if (!ValidateFrameRate(frameRate, compatibility, "SurfaceFlinger::setFrameRate")) { return BAD_VALUE; } @@ -6148,10 +6149,10 @@ status_t SurfaceFlinger::setFrameRate(const sp& surface, ALOGE("Attempt to set frame rate on a layer that no longer exists"); return BAD_VALUE; } - if (layer->setFrameRate( Layer::FrameRate(frameRate, - Layer::FrameRate::convertCompatibility(compatibility)))) { + Layer::FrameRate::convertCompatibility(compatibility), + shouldBeSeamless))) { setTransactionFlags(eTraversalNeeded); } } else { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a821d4473f..9666f145b0 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -600,7 +600,7 @@ private: status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius) override; status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility) override; + int8_t compatibility, bool shouldBeSeamless) override; status_t acquireFrameRateFlexibilityToken(sp* outToken) override; status_t setFrameTimelineVsync(const sp& surface, diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index da71dad2d4..b87c734e27 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -123,7 +123,7 @@ protected: } virtual void fillBufferQueueLayerColor(const sp& layer, const Color& color, - int32_t bufferWidth, int32_t bufferHeight) { + uint32_t bufferWidth, uint32_t bufferHeight) { ANativeWindow_Buffer buffer; ASSERT_NO_FATAL_FAILURE(buffer = getBufferQueueLayerBuffer(layer)); TransactionUtils::fillANativeWindowBufferColor(buffer, @@ -145,7 +145,7 @@ protected: } void fillLayerColor(uint32_t mLayerType, const sp& layer, const Color& color, - int32_t bufferWidth, int32_t bufferHeight) { + uint32_t bufferWidth, uint32_t bufferHeight) { switch (mLayerType) { case ISurfaceComposerClient::eFXSurfaceBufferQueue: fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight); diff --git a/services/surfaceflinger/tests/SetFrameRate_test.cpp b/services/surfaceflinger/tests/SetFrameRate_test.cpp index 02ba9e290d..d1bed0cc83 100644 --- a/services/surfaceflinger/tests/SetFrameRate_test.cpp +++ b/services/surfaceflinger/tests/SetFrameRate_test.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" - #include #include @@ -50,8 +46,8 @@ protected: } } - const int mLayerWidth = 32; - const int mLayerHeight = 32; + const uint32_t mLayerWidth = 32; + const uint32_t mLayerHeight = 32; sp mLayer; uint32_t mLayerType; }; @@ -59,26 +55,27 @@ protected: TEST_F(SetFrameRateTest, BufferQueueLayerSetFrameRate) { CreateLayer(ISurfaceComposerClient::eFXSurfaceBufferQueue); native_window_set_frame_rate(mLayer->getSurface().get(), 100.f, - ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT); + ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + /* shouldBeSeamless */ true); ASSERT_NO_FATAL_FAILURE(PostBuffers(Color::RED)); Transaction() - .setFrameRate(mLayer, 200.f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT) + .setFrameRate(mLayer, 200.f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + /* shouldBeSeamless */ true) .apply(); ASSERT_NO_FATAL_FAILURE(PostBuffers(Color::RED)); native_window_set_frame_rate(mLayer->getSurface().get(), 300.f, - ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT); + ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + /* shouldBeSeamless */ true); ASSERT_NO_FATAL_FAILURE(PostBuffers(Color::RED)); } TEST_F(SetFrameRateTest, BufferStateLayerSetFrameRate) { CreateLayer(ISurfaceComposerClient::eFXSurfaceBufferState); Transaction() - .setFrameRate(mLayer, 400.f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT) + .setFrameRate(mLayer, 400.f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + /* shouldBeSeamless */ true) .apply(); ASSERT_NO_FATAL_FAILURE(PostBuffers(Color::GREEN)); } } // namespace android - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" \ No newline at end of file diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h index 01badf4ad9..a361b1e956 100644 --- a/services/surfaceflinger/tests/TransactionTestHarnesses.h +++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h @@ -98,14 +98,14 @@ public: outTransformHint, format); } - void fillLayerColor(const sp& layer, const Color& color, int32_t bufferWidth, - int32_t bufferHeight) { + void fillLayerColor(const sp& layer, const Color& color, uint32_t bufferWidth, + uint32_t bufferHeight) { ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerColor(mLayerType, layer, color, bufferWidth, bufferHeight)); } - void fillLayerQuadrant(const sp& layer, int32_t bufferWidth, - int32_t bufferHeight, const Color& topLeft, const Color& topRight, + void fillLayerQuadrant(const sp& layer, uint32_t bufferWidth, + uint32_t bufferHeight, const Color& topLeft, const Color& topRight, const Color& bottomLeft, const Color& bottomRight) { ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerQuadrant(mLayerType, layer, bufferWidth, bufferHeight, diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp index cb376cd7bb..3b50321102 100644 --- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp +++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp @@ -78,7 +78,7 @@ protected: for (auto& [weak, info] : history().mLayerInfos) { if (auto strong = weak.promote(); strong && strong.get() == layer) { info->setDefaultLayerVote(vote); - info->setLayerVote(vote, 0); + info->setLayerVote({vote, 0, false}); return; } } diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index 4762fd4b66..df7611043a 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -57,6 +57,8 @@ protected: static inline const HwcConfigIndexType HWC_CONFIG_ID_72 = HwcConfigIndexType(2); static inline const HwcConfigIndexType HWC_CONFIG_ID_120 = HwcConfigIndexType(3); static inline const HwcConfigIndexType HWC_CONFIG_ID_30 = HwcConfigIndexType(4); + static inline const HwcConfigIndexType HWC_CONFIG_ID_25 = HwcConfigIndexType(5); + static inline const HwcConfigIndexType HWC_CONFIG_ID_50 = HwcConfigIndexType(6); // Test configs std::shared_ptr mConfig60 = @@ -77,8 +79,16 @@ protected: createConfig(HWC_CONFIG_ID_120, 1, static_cast(1e9f / 120)); std::shared_ptr mConfig30 = createConfig(HWC_CONFIG_ID_30, 0, static_cast(1e9f / 30)); + std::shared_ptr mConfig30DifferentGroup = + createConfig(HWC_CONFIG_ID_30, 1, static_cast(1e9f / 30)); + std::shared_ptr mConfig25DifferentGroup = + createConfig(HWC_CONFIG_ID_25, 1, static_cast(1e9f / 25)); + std::shared_ptr mConfig50 = + createConfig(HWC_CONFIG_ID_50, 0, static_cast(1e9f / 50)); // Test device configurations + // The positions of the configs in the arrays below MUST match their IDs. For example, + // the first config should always be 60Hz, the second 90Hz etc. std::vector> m60OnlyConfigDevice = {mConfig60}; std::vector> m60_90Device = {mConfig60, mConfig90}; std::vector> m60_90DeviceWithDifferentGroups = @@ -104,6 +114,14 @@ protected: {mConfig60, mConfig90, mConfig72, mConfig120DifferentGroup, mConfig30}; std::vector> m30_60_90Device = {mConfig60, mConfig90, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30}; + std::vector> m25_30_50_60Device = + {mConfig60, + mConfig90, + mConfig72DifferentGroup, + mConfig120DifferentGroup, + mConfig30DifferentGroup, + mConfig25DifferentGroup, + mConfig50}; // Expected RefreshRate objects RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, "60fps", 60, @@ -292,8 +310,8 @@ TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) { /*currentConfigId=*/HWC_CONFIG_ID_60); const auto makeLayerRequirements = [](float refreshRate) -> std::vector { - return {{"testLayer", LayerVoteType::Heuristic, refreshRate, /*weight*/ 1.0f, - /*focused*/ false}}; + return {{"testLayer", LayerVoteType::Heuristic, refreshRate, /*shouldBeSeamless*/ true, + /*weight*/ 1.0f, /*focused*/ false}}; }; EXPECT_EQ(mExpected90Config, @@ -1245,7 +1263,9 @@ TEST_F(RefreshRateConfigsTest, groupSwitching) { auto& layer = layers[0]; layer.vote = LayerVoteType::ExplicitDefault; layer.desiredRefreshRate = 90.0f; + layer.shouldBeSeamless = false; layer.name = "90Hz ExplicitDefault"; + layer.focused = true; ASSERT_EQ(HWC_CONFIG_ID_60, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) @@ -1258,6 +1278,104 @@ TEST_F(RefreshRateConfigsTest, groupSwitching) { ASSERT_EQ(HWC_CONFIG_ID_90, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) .getConfigId()); + + // Verify that we won't change the group if seamless switch is required. + layer.shouldBeSeamless = true; + ASSERT_EQ(HWC_CONFIG_ID_60, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); + + // At this point the default config in the DisplayManager policy with be 60Hz. + // Verify that if the current config is in another group and there are no layers with + // shouldBeSeamless=false we'll go back to the default group. + refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90); + layer.desiredRefreshRate = 60.0f; + layer.name = "60Hz ExplicitDefault"; + layer.shouldBeSeamless = true; + ASSERT_EQ(HWC_CONFIG_ID_60, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); + + // If there's a layer with shouldBeSeamless=false, another layer with shouldBeSeamless=true + // can't change the config group. + refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90); + auto layer2 = LayerRequirement{.weight = 0.5f}; + layer2.vote = LayerVoteType::ExplicitDefault; + layer2.desiredRefreshRate = 90.0f; + layer2.name = "90Hz ExplicitDefault"; + layer2.shouldBeSeamless = false; + layer2.focused = false; + layers.push_back(layer2); + ASSERT_EQ(HWC_CONFIG_ID_90, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); +} + +TEST_F(RefreshRateConfigsTest, nonSeamlessVotePrefersSeamlessSwitches) { + auto refreshRateConfigs = + std::make_unique(m30_60Device, + /*currentConfigId=*/HWC_CONFIG_ID_60); + + // Allow group switching. + RefreshRateConfigs::Policy policy; + policy.defaultConfig = refreshRateConfigs->getCurrentPolicy().defaultConfig; + policy.allowGroupSwitching = true; + ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); + + auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; + auto& layer = layers[0]; + layer.vote = LayerVoteType::ExplicitExactOrMultiple; + layer.desiredRefreshRate = 60.0f; + layer.shouldBeSeamless = false; + layer.name = "60Hz ExplicitExactOrMultiple"; + layer.focused = true; + + ASSERT_EQ(HWC_CONFIG_ID_60, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); + + refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_120); + ASSERT_EQ(HWC_CONFIG_ID_120, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); +} + +TEST_F(RefreshRateConfigsTest, nonSeamlessExactAndSeamlessMultipleLayers) { + auto refreshRateConfigs = + std::make_unique(m25_30_50_60Device, + /*currentConfigId=*/HWC_CONFIG_ID_60); + + // Allow group switching. + RefreshRateConfigs::Policy policy; + policy.defaultConfig = refreshRateConfigs->getCurrentPolicy().defaultConfig; + policy.allowGroupSwitching = true; + ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0); + + auto layers = std::vector< + LayerRequirement>{LayerRequirement{.name = "60Hz ExplicitDefault", + .vote = LayerVoteType::ExplicitDefault, + .desiredRefreshRate = 60.0f, + .shouldBeSeamless = false, + .weight = 0.5f, + .focused = false}, + LayerRequirement{.name = "25Hz ExplicitExactOrMultiple", + .vote = LayerVoteType::ExplicitExactOrMultiple, + .desiredRefreshRate = 25.0f, + .shouldBeSeamless = true, + .weight = 1.0f, + .focused = true}}; + auto& seamedLayer = layers[0]; + + ASSERT_EQ(HWC_CONFIG_ID_50, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); + + seamedLayer.name = "30Hz ExplicitDefault", seamedLayer.desiredRefreshRate = 30.0f; + refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_30); + + ASSERT_EQ(HWC_CONFIG_ID_25, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}) + .getConfigId()); } TEST_F(RefreshRateConfigsTest, primaryVsAppRequestPolicy) { diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp index de66f8fb41..d0bb9e291a 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp @@ -108,7 +108,7 @@ TEST_F(RefreshRateStatsTest, oneConfigTest) { std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_LT(screenOff, times["ScreenOff"]); - EXPECT_EQ(0u, times.count("90fps")); + EXPECT_EQ(0u, times.count("90.00fps")); mRefreshRateStats->setConfigMode(CONFIG_ID_0); mRefreshRateStats->setPowerMode(PowerMode::ON); @@ -116,15 +116,15 @@ TEST_F(RefreshRateStatsTest, oneConfigTest) { std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_EQ(screenOff, times["ScreenOff"]); - ASSERT_EQ(1u, times.count("90fps")); - EXPECT_LT(0, times["90fps"]); + ASSERT_EQ(1u, times.count("90.00fps")); + EXPECT_LT(0, times["90.00fps"]); mRefreshRateStats->setPowerMode(PowerMode::DOZE); - int ninety = mRefreshRateStats->getTotalTimes()["90fps"]; + int ninety = mRefreshRateStats->getTotalTimes()["90.00fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_LT(screenOff, times["ScreenOff"]); - EXPECT_EQ(ninety, times["90fps"]); + EXPECT_EQ(ninety, times["90.00fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_0); screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"]; @@ -133,7 +133,7 @@ TEST_F(RefreshRateStatsTest, oneConfigTest) { // Because the power mode is not PowerMode::ON, switching the config // does not update refresh rates that come from the config. EXPECT_LT(screenOff, times["ScreenOff"]); - EXPECT_EQ(ninety, times["90fps"]); + EXPECT_EQ(ninety, times["90.00fps"]); } TEST_F(RefreshRateStatsTest, twoConfigsTest) { @@ -163,53 +163,53 @@ TEST_F(RefreshRateStatsTest, twoConfigsTest) { std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_EQ(screenOff, times["ScreenOff"]); - ASSERT_EQ(1u, times.count("90fps")); - EXPECT_LT(0, times["90fps"]); + ASSERT_EQ(1u, times.count("90.00fps")); + EXPECT_LT(0, times["90.00fps"]); // When power mode is normal, time for configs updates. mRefreshRateStats->setConfigMode(CONFIG_ID_1); - int ninety = mRefreshRateStats->getTotalTimes()["90fps"]; + int ninety = mRefreshRateStats->getTotalTimes()["90.00fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_EQ(screenOff, times["ScreenOff"]); - EXPECT_EQ(ninety, times["90fps"]); - ASSERT_EQ(1u, times.count("60fps")); - EXPECT_LT(0, times["60fps"]); + EXPECT_EQ(ninety, times["90.00fps"]); + ASSERT_EQ(1u, times.count("60.00fps")); + EXPECT_LT(0, times["60.00fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_0); - int sixty = mRefreshRateStats->getTotalTimes()["60fps"]; + int sixty = mRefreshRateStats->getTotalTimes()["60.00fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_EQ(screenOff, times["ScreenOff"]); - EXPECT_LT(ninety, times["90fps"]); - EXPECT_EQ(sixty, times["60fps"]); + EXPECT_LT(ninety, times["90.00fps"]); + EXPECT_EQ(sixty, times["60.00fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_1); - ninety = mRefreshRateStats->getTotalTimes()["90fps"]; + ninety = mRefreshRateStats->getTotalTimes()["90.00fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_EQ(screenOff, times["ScreenOff"]); - EXPECT_EQ(ninety, times["90fps"]); - EXPECT_LT(sixty, times["60fps"]); + EXPECT_EQ(ninety, times["90.00fps"]); + EXPECT_LT(sixty, times["60.00fps"]); // Because the power mode is not PowerMode::ON, switching the config // does not update refresh rates that come from the config. mRefreshRateStats->setPowerMode(PowerMode::DOZE); mRefreshRateStats->setConfigMode(CONFIG_ID_0); - sixty = mRefreshRateStats->getTotalTimes()["60fps"]; + sixty = mRefreshRateStats->getTotalTimes()["60.00fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_LT(screenOff, times["ScreenOff"]); - EXPECT_EQ(ninety, times["90fps"]); - EXPECT_EQ(sixty, times["60fps"]); + EXPECT_EQ(ninety, times["90.00fps"]); + EXPECT_EQ(sixty, times["60.00fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_1); screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); EXPECT_LT(screenOff, times["ScreenOff"]); - EXPECT_EQ(ninety, times["90fps"]); - EXPECT_EQ(sixty, times["60fps"]); + EXPECT_EQ(ninety, times["90.00fps"]); + EXPECT_EQ(sixty, times["60.00fps"]); } } // namespace } // namespace scheduler -- cgit v1.2.3-59-g8ed1b From cf26a0a9c5467ca6ff0ab71dc944ea7341ec62e1 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Fri, 13 Nov 2020 12:56:20 -0800 Subject: BlastBufferQueue: Add support for auto refresh When BQ is in shared bufer mode, the client can request the consumer to aquire frames as fast as possible before waiting for a frame to be available. To support this for BLAST, pass the state via a transaction. Fixes: 168506187 Test: atest SurfaceViewBufferTests Change-Id: I25ddd98671a08e56798612b7e5dc72095b2c4b7b --- libs/gui/BLASTBufferQueue.cpp | 5 +++++ libs/gui/LayerState.cpp | 20 +++++++++++++++++++- libs/gui/SurfaceComposerClient.cpp | 13 +++++++++++++ libs/gui/include/gui/BLASTBufferQueue.h | 4 ++++ libs/gui/include/gui/LayerState.h | 6 ++++++ libs/gui/include/gui/SurfaceComposerClient.h | 5 +++++ services/surfaceflinger/BufferLayer.h | 8 ++++++-- services/surfaceflinger/BufferQueueLayer.cpp | 12 +++--------- services/surfaceflinger/BufferQueueLayer.h | 6 ------ services/surfaceflinger/BufferStateLayer.cpp | 11 ++++------- services/surfaceflinger/BufferStateLayer.h | 6 +----- services/surfaceflinger/Layer.h | 1 + services/surfaceflinger/SurfaceFlinger.cpp | 3 +++ 13 files changed, 70 insertions(+), 30 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 6db6112762..e6aa02a8fe 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -289,6 +289,11 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { t->setDesiredPresentTime(bufferItem.mTimestamp); t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber); + if (mAutoRefresh != bufferItem.mAutoRefresh) { + t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh); + mAutoRefresh = bufferItem.mAutoRefresh; + } + if (applyTransaction) { t->apply(); } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 90999faa78..7d2c7b88df 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -61,7 +61,9 @@ layer_state_t::layer_state_t() frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT), shouldBeSeamless(true), fixedTransformHint(ui::Transform::ROT_INVALID), - frameNumber(0) { + frameNumber(0), + frameTimelineVsyncId(ISurfaceComposer::INVALID_VSYNC_ID), + autoRefresh(false) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -149,6 +151,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeUint32, fixedTransformHint); SAFE_PARCEL(output.writeUint64, frameNumber); SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId); + SAFE_PARCEL(output.writeBool, autoRefresh); SAFE_PARCEL(output.writeUint32, blurRegions.size()); for (auto region : blurRegions) { @@ -269,6 +272,7 @@ status_t layer_state_t::read(const Parcel& input) fixedTransformHint = static_cast(tmpUint32); SAFE_PARCEL(input.readUint64, &frameNumber); SAFE_PARCEL(input.readInt64, &frameTimelineVsyncId); + SAFE_PARCEL(input.readBool, &autoRefresh); uint32_t numRegions = 0; SAFE_PARCEL(input.readUint32, &numRegions); @@ -534,6 +538,20 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eFrameNumberChanged; frameNumber = other.frameNumber; } + if (other.what & eFrameTimelineVsyncChanged) { + // When merging vsync Ids we take the oldest valid one + if (frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID && + other.frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) { + frameTimelineVsyncId = std::max(frameTimelineVsyncId, other.frameTimelineVsyncId); + } else if (frameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) { + frameTimelineVsyncId = other.frameTimelineVsyncId; + } + what |= eFrameTimelineVsyncChanged; + } + if (other.what & eAutoRefreshChanged) { + what |= eAutoRefreshChanged; + autoRefresh = other.autoRefresh; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index a822598d82..47a08ab500 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1527,6 +1527,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAutoRefresh( + const sp& sc, bool autoRefresh) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eAutoRefreshChanged; + s->autoRefresh = autoRefresh; + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp& token) { diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index 42427c0539..9fb7d6fd36 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -139,6 +139,10 @@ private: // If set to true, the next queue buffer will wait until the shadow queue has been processed by // the adapter. bool mFlushShadowQueue = false; + // Last requested auto refresh state set by the producer. The state indicates that the consumer + // should acquire the next frame as soon as it can and not wait for a frame to become available. + // This is only relevant for shared buffer mode. + bool mAutoRefresh GUARDED_BY(mMutex) = false; }; } // namespace android diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index d9f280684f..f1c5d6712d 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -130,6 +130,7 @@ struct layer_state_t { eFrameNumberChanged = 0x400'00000000, eFrameTimelineVsyncChanged = 0x800'00000000, eBlurRegionsChanged = 0x1000'00000000, + eAutoRefreshChanged = 0x2000'00000000, }; layer_state_t(); @@ -234,6 +235,11 @@ struct layer_state_t { uint64_t frameNumber; int64_t frameTimelineVsyncId; + + // Indicates that the consumer should acquire the next frame as soon as it + // can and not wait for a frame to become available. This is only relevant + // in shared buffer mode. + bool autoRefresh; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 6289c6a3cd..2eb97f27a1 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -541,6 +541,11 @@ public: Transaction& setFrameTimelineVsync(const sp& sc, int64_t frameTimelineVsyncId); + // Indicates that the consumer should acquire the next frame as soon as it + // can and not wait for a frame to become available. This is only relevant + // in shared buffer mode. + Transaction& setAutoRefresh(const sp& sc, bool autoRefresh); + status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index deaf8461e8..63dfe5f5d9 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -178,13 +178,17 @@ protected: /// the mStateLock. ui::Transform::RotationFlags mTransformHint = ui::Transform::ROT_0; + bool getAutoRefresh() const { return mAutoRefresh; } + bool getSidebandStreamChanged() const { return mSidebandStreamChanged; } + + std::atomic mAutoRefresh{false}; + std::atomic mSidebandStreamChanged{false}; + private: virtual bool fenceHasSignaled() const = 0; virtual bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const = 0; virtual uint64_t getFrameNumber(nsecs_t expectedPresentTime) const = 0; - virtual bool getAutoRefresh() const = 0; - virtual bool getSidebandStreamChanged() const = 0; // Latch sideband stream and returns true if the dirty region should be updated. virtual bool latchSidebandStream(bool& recomputeVisibleRegions) = 0; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 71b05fd2bf..dc99986900 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -196,14 +196,6 @@ uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const { return frameNumber; } -bool BufferQueueLayer::getAutoRefresh() const { - return mAutoRefresh; -} - -bool BufferQueueLayer::getSidebandStreamChanged() const { - return mSidebandStreamChanged; -} - bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) { // We need to update the sideband stream if the layer has both a buffer and a sideband stream. const bool updateSidebandStream = hasFrameUpdate() && mSidebandStream.get(); @@ -265,8 +257,10 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t const uint64_t maxFrameNumberToAcquire = std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber); - status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, + bool autoRefresh; + status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &autoRefresh, &queuedBuffer, maxFrameNumberToAcquire); + mAutoRefresh = autoRefresh; if (updateResult == BufferQueue::PRESENT_LATER) { // Producer doesn't want buffer to be displayed yet. Signal a // layer update so we check again at the next opportunity. diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index fb8a0c22ee..b45900ef4c 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -90,9 +90,6 @@ protected: private: uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override; - bool getAutoRefresh() const override; - bool getSidebandStreamChanged() const override; - bool latchSidebandStream(bool& recomputeVisibleRegions) override; void setTransformHint(ui::Transform::RotationFlags displayTransformHint) override; @@ -140,11 +137,8 @@ private: std::vector mQueueItems; std::atomic mLastFrameNumberReceived{0}; - bool mAutoRefresh{false}; - // thread-safe std::atomic mQueuedFrames{0}; - std::atomic mSidebandStreamChanged{false}; sp mContentsChangedListener; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 234b6e219b..963e54105d 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -482,13 +482,10 @@ uint64_t BufferStateLayer::getHeadFrameNumber(nsecs_t /* expectedPresentTime */) return mCurrentState.frameNumber; } -bool BufferStateLayer::getAutoRefresh() const { - // TODO(marissaw): support shared buffer mode - return false; -} - -bool BufferStateLayer::getSidebandStreamChanged() const { - return mSidebandStreamChanged.load(); +void BufferStateLayer::setAutoRefresh(bool autoRefresh) { + if (!mAutoRefresh.exchange(autoRefresh)) { + mFlinger->signalLayerUpdate(); + } } bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) { diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 104a13be71..42be62a763 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -100,6 +100,7 @@ public: Rect getBufferSize(const State& s) const override; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; Layer::RoundedCornerState getRoundedCornerState() const override; + void setAutoRefresh(bool autoRefresh) override; // ----------------------------------------------------------------------- @@ -123,9 +124,6 @@ private: uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override; - bool getAutoRefresh() const override; - bool getSidebandStreamChanged() const override; - bool latchSidebandStream(bool& recomputeVisibleRegions) override; bool hasFrameUpdate() const override; @@ -149,8 +147,6 @@ private: std::unique_ptr mTextureImage; - std::atomic mSidebandStreamChanged{false}; - mutable uint64_t mFrameNumber{0}; uint64_t mFrameCounter{0}; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 1a784aa778..8d67ce52cd 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -444,6 +444,7 @@ public: virtual bool setColorSpaceAgnostic(const bool agnostic); virtual bool setFrameRateSelectionPriority(int32_t priority); virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint); + virtual void setAutoRefresh(bool /* autoRefresh */) {} // If the variable is not set on the layer, it traverses up the tree to inherit the frame // rate priority from its parent. virtual int32_t getFrameRateSelectionPriority() const; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 91f050c017..4e398d354b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3796,6 +3796,9 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded | eTransformHintUpdateNeeded; } } + if (what & layer_state_t::eAutoRefreshChanged) { + layer->setAutoRefresh(s.autoRefresh); + } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not -- cgit v1.2.3-59-g8ed1b From 0ef7caa3ee99f1043e1d922d59e6d56341e501af Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 5 Jan 2021 11:04:50 -0800 Subject: Convert IScreenCaptureListener to AIDL Test: Screen capture works Fixes: 166271443 Change-Id: Iecb991a0c8e0885adb87141ed85caa6dcc7c543f --- libs/binder/include/binder/IInterface.h | 1 - libs/gui/Android.bp | 2 +- libs/gui/IScreenCaptureListener.cpp | 70 ---------------------- libs/gui/LayerState.cpp | 29 --------- libs/gui/ScreenCaptureResults.cpp | 50 ++++++++++++++++ .../aidl/android/gui/IScreenCaptureListener.aidl | 24 ++++++++ .../gui/aidl/android/gui/ScreenCaptureResults.aidl | 19 ++++++ libs/gui/include/gui/IScreenCaptureListener.h | 45 -------------- libs/gui/include/gui/ISurfaceComposer.h | 5 +- libs/gui/include/gui/LayerState.h | 10 ---- libs/gui/include/gui/ScreenCaptureResults.h | 47 +++++++++++++++ libs/gui/include/gui/SyncScreenCaptureListener.h | 9 ++- services/surfaceflinger/SurfaceFlinger.h | 2 + services/surfaceflinger/tests/LayerState_test.cpp | 6 +- .../tests/unittests/TestableSurfaceFlinger.h | 1 + 15 files changed, 157 insertions(+), 163 deletions(-) delete mode 100644 libs/gui/IScreenCaptureListener.cpp create mode 100644 libs/gui/ScreenCaptureResults.cpp create mode 100644 libs/gui/aidl/android/gui/IScreenCaptureListener.aidl create mode 100644 libs/gui/aidl/android/gui/ScreenCaptureResults.aidl delete mode 100644 libs/gui/include/gui/IScreenCaptureListener.h create mode 100644 libs/gui/include/gui/ScreenCaptureResults.h (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h index 988508eaba..e2a0f874ff 100644 --- a/libs/binder/include/binder/IInterface.h +++ b/libs/binder/include/binder/IInterface.h @@ -232,7 +232,6 @@ constexpr const char* const kManualInterfaces[] = { "android.gui.IGraphicBufferConsumer", "android.gui.IRegionSamplingListener", "android.gui.ITransactionComposerListener", - "android.gui.IScreenCaptureListener", "android.gui.SensorEventConnection", "android.gui.SensorServer", "android.hardware.ICamera", diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 7dd584d552..0b8d216189 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -69,7 +69,6 @@ cc_library_shared { "IGraphicBufferProducer.cpp", "IProducerListener.cpp", "IRegionSamplingListener.cpp", - "IScreenCaptureListener.cpp", "ISurfaceComposer.cpp", "ISurfaceComposerClient.cpp", "ITransactionCompletedListener.cpp", @@ -78,6 +77,7 @@ cc_library_shared { "LayerState.cpp", "OccupancyTracker.cpp", "StreamSplitter.cpp", + "ScreenCaptureResults.cpp", "Surface.cpp", "SurfaceControl.cpp", "SurfaceComposerClient.cpp", diff --git a/libs/gui/IScreenCaptureListener.cpp b/libs/gui/IScreenCaptureListener.cpp deleted file mode 100644 index 0635e9cf34..0000000000 --- a/libs/gui/IScreenCaptureListener.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -#include -#include - -namespace android { - -namespace { // Anonymous - -enum class Tag : uint32_t { - ON_SCREEN_CAPTURE_COMPLETE = IBinder::FIRST_CALL_TRANSACTION, - LAST = ON_SCREEN_CAPTURE_COMPLETE, -}; - -} // Anonymous namespace - -class BpScreenCaptureListener : public SafeBpInterface { -public: - explicit BpScreenCaptureListener(const sp& impl) - : SafeBpInterface(impl, "BpScreenCaptureListener") {} - - ~BpScreenCaptureListener() override; - - status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override { - Parcel data, reply; - data.writeInterfaceToken(IScreenCaptureListener::getInterfaceDescriptor()); - - SAFE_PARCEL(captureResults.write, data); - return remote()->transact(static_cast(Tag::ON_SCREEN_CAPTURE_COMPLETE), data, - &reply, IBinder::FLAG_ONEWAY); - } -}; - -// Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see -// clang warning -Wweak-vtables) -BpScreenCaptureListener::~BpScreenCaptureListener() = default; - -IMPLEMENT_META_INTERFACE(ScreenCaptureListener, "android.gui.IScreenCaptureListener"); - -status_t BnScreenCaptureListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags) { - auto tag = static_cast(code); - switch (tag) { - case Tag::ON_SCREEN_CAPTURE_COMPLETE: { - CHECK_INTERFACE(IScreenCaptureListener, data, reply); - ScreenCaptureResults captureResults; - SAFE_PARCEL(captureResults.read, data); - return onScreenCaptureComplete(captureResults); - } - default: { - return BBinder::onTransact(code, data, reply, flags); - } - } -} - -} // namespace android \ No newline at end of file diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 7d2c7b88df..63be3edf94 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -714,33 +714,4 @@ status_t LayerCaptureArgs::read(const Parcel& input) { return NO_ERROR; } -status_t ScreenCaptureResults::write(Parcel& output) const { - if (buffer != nullptr) { - SAFE_PARCEL(output.writeBool, true); - SAFE_PARCEL(output.write, *buffer); - } else { - SAFE_PARCEL(output.writeBool, false); - } - SAFE_PARCEL(output.writeBool, capturedSecureLayers); - SAFE_PARCEL(output.writeUint32, static_cast(capturedDataspace)); - SAFE_PARCEL(output.writeInt32, result); - return NO_ERROR; -} - -status_t ScreenCaptureResults::read(const Parcel& input) { - bool hasGraphicBuffer; - SAFE_PARCEL(input.readBool, &hasGraphicBuffer); - if (hasGraphicBuffer) { - buffer = new GraphicBuffer(); - SAFE_PARCEL(input.read, *buffer); - } - - SAFE_PARCEL(input.readBool, &capturedSecureLayers); - uint32_t dataspace = 0; - SAFE_PARCEL(input.readUint32, &dataspace); - capturedDataspace = static_cast(dataspace); - SAFE_PARCEL(input.readInt32, &result); - return NO_ERROR; -} - }; // namespace android diff --git a/libs/gui/ScreenCaptureResults.cpp b/libs/gui/ScreenCaptureResults.cpp new file mode 100644 index 0000000000..2b29487268 --- /dev/null +++ b/libs/gui/ScreenCaptureResults.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2021 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. + */ + +#include + +namespace android::gui { + +status_t ScreenCaptureResults::writeToParcel(android::Parcel* parcel) const { + if (buffer != nullptr) { + SAFE_PARCEL(parcel->writeBool, true); + SAFE_PARCEL(parcel->write, *buffer); + } else { + SAFE_PARCEL(parcel->writeBool, false); + } + SAFE_PARCEL(parcel->writeBool, capturedSecureLayers); + SAFE_PARCEL(parcel->writeUint32, static_cast(capturedDataspace)); + SAFE_PARCEL(parcel->writeInt32, result); + return NO_ERROR; +} + +status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) { + bool hasGraphicBuffer; + SAFE_PARCEL(parcel->readBool, &hasGraphicBuffer); + if (hasGraphicBuffer) { + buffer = new GraphicBuffer(); + SAFE_PARCEL(parcel->read, *buffer); + } + + SAFE_PARCEL(parcel->readBool, &capturedSecureLayers); + uint32_t dataspace = 0; + SAFE_PARCEL(parcel->readUint32, &dataspace); + capturedDataspace = static_cast(dataspace); + SAFE_PARCEL(parcel->readInt32, &result); + return NO_ERROR; +} + +} // namespace android::gui diff --git a/libs/gui/aidl/android/gui/IScreenCaptureListener.aidl b/libs/gui/aidl/android/gui/IScreenCaptureListener.aidl new file mode 100644 index 0000000000..f490118b8f --- /dev/null +++ b/libs/gui/aidl/android/gui/IScreenCaptureListener.aidl @@ -0,0 +1,24 @@ +/* + * Copyright 2021 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. + */ + +package android.gui; + +import android.gui.ScreenCaptureResults; + +/** @hide */ +oneway interface IScreenCaptureListener { + void onScreenCaptureComplete(in ScreenCaptureResults captureResults); +} \ No newline at end of file diff --git a/libs/gui/aidl/android/gui/ScreenCaptureResults.aidl b/libs/gui/aidl/android/gui/ScreenCaptureResults.aidl new file mode 100644 index 0000000000..9908edd2ef --- /dev/null +++ b/libs/gui/aidl/android/gui/ScreenCaptureResults.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 2021 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. + */ + +package android.gui; + +parcelable ScreenCaptureResults cpp_header "gui/ScreenCaptureResults.h"; \ No newline at end of file diff --git a/libs/gui/include/gui/IScreenCaptureListener.h b/libs/gui/include/gui/IScreenCaptureListener.h deleted file mode 100644 index a2ddc9ffff..0000000000 --- a/libs/gui/include/gui/IScreenCaptureListener.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 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. - */ - -#pragma once - -#include -#include -#include -#include - -namespace android { - -struct ScreenCaptureResults; - -// TODO(b/166271443): Convert to AIDL -class IScreenCaptureListener : public IInterface { -public: - DECLARE_META_INTERFACE(ScreenCaptureListener) - - virtual status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) = 0; -}; - -class BnScreenCaptureListener : public SafeBnInterface { -public: - BnScreenCaptureListener() - : SafeBnInterface("BnScreenCaptureListener") {} - - status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags = 0) override; -}; - -} // namespace android diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 40316dbeea..86f3c605ab 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -22,8 +22,8 @@ #include #include +#include #include -#include #include #include @@ -59,7 +59,6 @@ struct DisplayStatInfo; struct DisplayState; struct InputWindowCommands; struct LayerCaptureArgs; -struct ScreenCaptureResults; class LayerDebugInfo; class HdrCapabilities; class IDisplayEventConnection; @@ -69,6 +68,8 @@ class IRegionSamplingListener; class Rect; enum class FrameEvent; +using gui::IScreenCaptureListener; + namespace ui { struct DisplayState; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index f1c5d6712d..4a291aeb02 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -362,16 +362,6 @@ struct LayerCaptureArgs : CaptureArgs { status_t read(const Parcel& input) override; }; -struct ScreenCaptureResults { - sp buffer; - bool capturedSecureLayers{false}; - ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB}; - status_t result = OK; - - 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/include/gui/ScreenCaptureResults.h b/libs/gui/include/gui/ScreenCaptureResults.h new file mode 100644 index 0000000000..fdb4b6985e --- /dev/null +++ b/libs/gui/include/gui/ScreenCaptureResults.h @@ -0,0 +1,47 @@ +/* + * Copyright 2021 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. + */ + +#pragma once + +#define SAFE_PARCEL(FUNC, ...) \ + { \ + status_t error = FUNC(__VA_ARGS__); \ + if (error) { \ + ALOGE("ERROR(%d). Failed to call parcel %s(%s)", error, #FUNC, #__VA_ARGS__); \ + return error; \ + } \ + } + +#include +#include +#include + +namespace android::gui { + +struct ScreenCaptureResults : public Parcelable { +public: + ScreenCaptureResults() = default; + virtual ~ScreenCaptureResults() = default; + status_t writeToParcel(android::Parcel* parcel) const override; + status_t readFromParcel(const android::Parcel* parcel) override; + + sp buffer; + bool capturedSecureLayers{false}; + ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB}; + status_t result = OK; +}; + +} // namespace android::gui diff --git a/libs/gui/include/gui/SyncScreenCaptureListener.h b/libs/gui/include/gui/SyncScreenCaptureListener.h index 2857996c23..8620b77c18 100644 --- a/libs/gui/include/gui/SyncScreenCaptureListener.h +++ b/libs/gui/include/gui/SyncScreenCaptureListener.h @@ -16,16 +16,19 @@ #pragma once +#include #include #include namespace android { -class SyncScreenCaptureListener : public BnScreenCaptureListener { +using gui::ScreenCaptureResults; + +struct SyncScreenCaptureListener : gui::BnScreenCaptureListener { public: - status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override { + binder::Status onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override { resultsPromise.set_value(captureResults); - return NO_ERROR; + return binder::Status::ok(); } ScreenCaptureResults waitForResults() { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 9f0f2eaf5d..7253593dfa 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -99,6 +99,8 @@ class RenderArea; class TimeStats; class FrameTracer; +using gui::ScreenCaptureResults; + namespace frametimeline { class FrameTimeline; } diff --git a/services/surfaceflinger/tests/LayerState_test.cpp b/services/surfaceflinger/tests/LayerState_test.cpp index e66df4a2b9..ecfed13adb 100644 --- a/services/surfaceflinger/tests/LayerState_test.cpp +++ b/services/surfaceflinger/tests/LayerState_test.cpp @@ -22,6 +22,8 @@ #include namespace android { +using gui::ScreenCaptureResults; + namespace test { TEST(LayerStateTest, ParcellingDisplayCaptureArgs) { @@ -86,11 +88,11 @@ TEST(LayerStateTest, ParcellingScreenCaptureResults) { results.result = BAD_VALUE; Parcel p; - results.write(p); + results.writeToParcel(&p); p.setDataPosition(0); ScreenCaptureResults results2; - results2.read(p); + results2.readFromParcel(&p); // GraphicBuffer object is reallocated so compare the data in the graphic buffer // rather than the object itself diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index b57d4733d2..b558581e65 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "BufferQueueLayer.h" #include "BufferStateLayer.h" -- cgit v1.2.3-59-g8ed1b From dd5bfa93b0c6633b7372c87fc8d7a83a73a5cd1c Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Thu, 7 Jan 2021 17:56:08 -0800 Subject: SurfaceFlinger: handle high refresh rate deny list Add visibility to SurfaceFlinger into the high refresh rate deny list and let SurfaceFlinger handle it. Previously WM was setting the preferredDisplayModeId on the denied app's window. The old way prevented SurfaceFlinger to use the frame rate override feature as it didn't know that a specific app is causing the refresh rate spec to be limited. With this change, SurfaceFlinger will limit the display refresh rate based on the high refresh rate deny list, and if possible, will use the frame rate override feature to change the display rate to a multiple, allowing other animations to be smooth while the denied app remains in the low refresh rate. Bug: 170502573 Test: SF unit tests Change-Id: Idc8a5fe6bc12dbd949ad5e09ff50e339ffaeac36 Merged-In: Idc8a5fe6bc12dbd949ad5e09ff50e339ffaeac36 --- libs/gui/LayerState.cpp | 10 +- libs/gui/SurfaceComposerClient.cpp | 5 +- libs/gui/include/gui/LayerState.h | 13 +- libs/nativewindow/include/apex/window.h | 13 ++ services/surfaceflinger/Layer.cpp | 9 +- services/surfaceflinger/Layer.h | 2 + services/surfaceflinger/Scheduler/LayerHistory.cpp | 3 + .../Scheduler/RefreshRateConfigs.cpp | 88 ++++++++--- .../surfaceflinger/Scheduler/RefreshRateConfigs.h | 20 ++- services/surfaceflinger/Scheduler/Scheduler.cpp | 10 +- services/surfaceflinger/SurfaceFlinger.cpp | 6 +- .../tests/unittests/RefreshRateConfigsTest.cpp | 176 +++++++++++++++++++-- .../tests/unittests/SetFrameRateTest.cpp | 15 ++ 13 files changed, 308 insertions(+), 62 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 63be3edf94..e5e10a0014 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "LayerState" +#include #include #include @@ -620,7 +621,8 @@ status_t InputWindowCommands::read(const Parcel& input) { return NO_ERROR; } -bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName) { +bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName, + bool privileged) { const char* functionName = inFunctionName != nullptr ? inFunctionName : "call"; int floatClassification = std::fpclassify(frameRate); if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) { @@ -629,8 +631,10 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunc } if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT && - compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE) { - ALOGE("%s failed - invalid compatibility value %d", functionName, compatibility); + compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE && + (!privileged || compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT)) { + ALOGE("%s failed - invalid compatibility value %d privileged: %s", functionName, + compatibility, privileged ? "yes" : "no"); return false; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 4a372bba1e..78f655a71b 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1518,7 +1518,10 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame mStatus = BAD_INDEX; return *this; } - if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate")) { + // Allow privileged values as well here, those will be ignored by SF if + // the caller is not privileged + if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate", + /*privileged=*/true)) { mStatus = BAD_VALUE; return *this; } diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 4a291aeb02..83a9d3356e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -309,11 +309,14 @@ static inline int compare_type(const DisplayState& lhs, const DisplayState& rhs) return compare_type(lhs.token, rhs.token); } -// Returns true if the frameRate and compatibility are valid values, false -// othwerise. If either of the params are invalid, an error log is printed, and -// functionName is added to the log to indicate which function call failed. -// functionName can be null. -bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName); +// Returns true if the frameRate is valid. +// +// @param frameRate the frame rate in Hz +// @param compatibility a ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* +// @param functionName calling function or nullptr. Used for logging +// @param privileged whether caller has unscoped surfaceflinger access +bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName, + bool privileged = false); struct CaptureArgs { const static int32_t UNSET_UID = -1; diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 2d1354cdf1..0923438eec 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -39,6 +39,19 @@ enum ANativeWindowPerform { // clang-format on }; +/* + * Internal extension of compatibility value for ANativeWindow_setFrameRate. */ +enum ANativeWindow_FrameRateCompatibilityInternal { + /** + * This surface belongs to an app on the High Refresh Rate Deny list, and needs the display + * to operate at the exact frame rate. + * + * This is used internally by the platform and should not be used by apps. + * @hide + */ + ANATIVEWINDOW_FRAME_RATE_EXACT = 100, +}; + /** * Prototype of the function that an ANativeWindow implementation would call * when ANativeWindow_cancelBuffer is called. diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 24d1b52a49..66ce3f1a44 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1441,11 +1441,14 @@ void Layer::updateTreeHasFrameRateVote() { layer->mCurrentState.frameRate.type == FrameRateCompatibility::Default; const auto layerVotedWithNoVote = layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote; + const auto layerVotedWithExactCompatibility = + layer->mCurrentState.frameRate.type == FrameRateCompatibility::Exact; // We do not count layers that are ExactOrMultiple for the same reason // we are allowing touch boost for those layers. See // RefreshRateConfigs::getBestRefreshRate for more details. - if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote) { + if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote || + layerVotedWithExactCompatibility) { layersWithVote++; } @@ -1662,6 +1665,8 @@ std::string Layer::frameRateCompatibilityString(Layer::FrameRateCompatibility co return "ExactOrMultiple"; case FrameRateCompatibility::NoVote: return "NoVote"; + case FrameRateCompatibility::Exact: + return "Exact"; } } @@ -2763,6 +2768,8 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp return FrameRateCompatibility::Default; case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE: return FrameRateCompatibility::ExactOrMultiple; + case ANATIVEWINDOW_FRAME_RATE_EXACT: + return FrameRateCompatibility::Exact; default: LOG_ALWAYS_FATAL("Invalid frame rate compatibility value %d", compatibility); return FrameRateCompatibility::Default; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index f78b5f31e9..359340eb64 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -145,6 +145,8 @@ public: enum class FrameRateCompatibility { Default, // Layer didn't specify any specific handling strategy + Exact, // Layer needs the exact frame rate. + ExactOrMultiple, // Layer needs the exact frame rate (or a multiple of it) to present the // content properly. Any other value will result in a pull down. diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 170933d9b3..7ef531df63 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -71,6 +71,7 @@ void trace(const wp& weak, const LayerInfo& info, LayerHistory::LayerVote traceType(LayerHistory::LayerVoteType::Heuristic, fps); traceType(LayerHistory::LayerVoteType::ExplicitDefault, fps); traceType(LayerHistory::LayerVoteType::ExplicitExactOrMultiple, fps); + traceType(LayerHistory::LayerVoteType::ExplicitExact, fps); traceType(LayerHistory::LayerVoteType::Min, 1); traceType(LayerHistory::LayerVoteType::Max, 1); @@ -172,6 +173,8 @@ void LayerHistory::partitionLayers(nsecs_t now) { return LayerVoteType::ExplicitExactOrMultiple; case Layer::FrameRateCompatibility::NoVote: return LayerVoteType::NoVote; + case Layer::FrameRateCompatibility::Exact: + return LayerVoteType::ExplicitExact; } }(); diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index 0f1e26750e..81ffe0f20e 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -83,6 +83,8 @@ std::string RefreshRateConfigs::layerVoteTypeString(LayerVoteType vote) { return "ExplicitDefault"; case LayerVoteType::ExplicitExactOrMultiple: return "ExplicitExactOrMultiple"; + case LayerVoteType::ExplicitExact: + return "ExplicitExact"; } } @@ -165,6 +167,18 @@ float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& laye return (1.0f / iter) * seamlessness; } + if (layer.vote == LayerVoteType::ExplicitExact) { + const int divider = getFrameRateDivider(refreshRate.getFps(), layer.desiredRefreshRate); + if (mSupportsFrameRateOverride) { + // Since we support frame rate override, allow refresh rates which are + // multiples of the layer's request, as those apps would be throttled + // down to run at the desired refresh rate. + return divider > 0; + } + + return divider == 1; + } + return 0; } @@ -199,21 +213,34 @@ RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vector 0 || explicitExactOrMultipleVoteLayers > 0; + const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 || + explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0; // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've // selected a refresh rate to see if we should apply touch boost. @@ -318,7 +345,9 @@ RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vectorinPolicy(policy->primaryRange.min, policy->primaryRange.max); if ((primaryRangeIsSingleRate || !inPrimaryRange) && - !(layer.focused && layer.vote == LayerVoteType::ExplicitDefault)) { + !(layer.focused && + (layer.vote == LayerVoteType::ExplicitDefault || + layer.vote == LayerVoteType::ExplicitExact))) { // Only focused layers with ExplicitDefault frame rate settings are allowed to score // refresh rates outside the primary range. continue; @@ -358,7 +387,8 @@ RefreshRate RefreshRateConfigs::getBestRefreshRate(const std::vectorfps.lessThanWithMargin(touchRefreshRate.fps)) { setTouchConsidered(); ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str()); @@ -412,7 +442,7 @@ std::vector initializeScoresForAllRefreshRates( } RefreshRateConfigs::UidToFrameRateOverride RefreshRateConfigs::getFrameRateOverrides( - const std::vector& layers, Fps displayFrameRate) const { + const std::vector& layers, Fps displayFrameRate, bool touch) const { ATRACE_CALL(); if (!mSupportsFrameRateOverride) return {}; @@ -423,6 +453,17 @@ RefreshRateConfigs::UidToFrameRateOverride RefreshRateConfigs::getFrameRateOverr groupLayersByUid(layers); UidToFrameRateOverride frameRateOverrides; for (const auto& [uid, layersWithSameUid] : layersByUid) { + // Layers with ExplicitExactOrMultiple expect touch boost + const bool hasExplicitExactOrMultiple = + std::any_of(layersWithSameUid.cbegin(), layersWithSameUid.cend(), + [](const auto& layer) { + return layer->vote == LayerVoteType::ExplicitExactOrMultiple; + }); + + if (touch && hasExplicitExactOrMultiple) { + continue; + } + for (auto& score : scores) { score.score = 0; } @@ -433,7 +474,8 @@ RefreshRateConfigs::UidToFrameRateOverride RefreshRateConfigs::getFrameRateOverr } LOG_ALWAYS_FATAL_IF(layer->vote != LayerVoteType::ExplicitDefault && - layer->vote != LayerVoteType::ExplicitExactOrMultiple); + layer->vote != LayerVoteType::ExplicitExactOrMultiple && + layer->vote != LayerVoteType::ExplicitExact); for (RefreshRateScore& score : scores) { const auto layerScore = calculateLayerScoreLocked(*layer, *score.refreshRate, /*isSeamlessSwitch*/ true); @@ -559,8 +601,10 @@ void RefreshRateConfigs::setCurrentConfigId(DisplayModeId configId) { mCurrentRefreshRate = mRefreshRates.at(configId).get(); } -RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId) - : mKnownFrameRates(constructKnownFrameRates(configs)) { +RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId, + bool enableFrameRateOverride) + : mKnownFrameRates(constructKnownFrameRates(configs)), + mEnableFrameRateOverride(enableFrameRateOverride) { updateDisplayConfigs(configs, currentConfigId); } @@ -589,7 +633,7 @@ void RefreshRateConfigs::updateDisplayConfigs(const DisplayModes& configs, mMaxSupportedRefreshRate = sortedConfigs.back(); mSupportsFrameRateOverride = false; - if (android::sysprop::enable_frame_rate_override(true)) { + if (mEnableFrameRateOverride) { for (const auto& config1 : sortedConfigs) { for (const auto& config2 : sortedConfigs) { if (getFrameRateDivider(config1->getFps(), config2->getFps()) >= 2) { @@ -826,4 +870,4 @@ void RefreshRateConfigs::dump(std::string& result) const { } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wextra" \ No newline at end of file +#pragma clang diagnostic pop // ignored "-Wextra" diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h index 29402f5a70..0c7dc0515c 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -211,8 +211,11 @@ public: Heuristic, // Specific refresh rate that was calculated by platform using a heuristic ExplicitDefault, // Specific refresh rate that was provided by the app with Default // compatibility - ExplicitExactOrMultiple // Specific refresh rate that was provided by the app with - // ExactOrMultiple compatibility + ExplicitExactOrMultiple, // Specific refresh rate that was provided by the app with + // ExactOrMultiple compatibility + ExplicitExact, // Specific refresh rate that was provided by the app with + // Exact compatibility + }; // Captures the layer requirements for a refresh rate. This will be used to determine the @@ -298,7 +301,8 @@ public: // Returns a known frame rate that is the closest to frameRate Fps findClosestKnownFrameRate(Fps frameRate) const; - RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId); + RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId, + bool enableFrameRateOverride = false); void updateDisplayConfigs(const DisplayModes& configs, DisplayModeId currentConfig) EXCLUDES(mLock); @@ -327,10 +331,15 @@ public: // Returns a divider for the current refresh rate int getRefreshRateDivider(Fps frameRate) const EXCLUDES(mLock); - // Returns the frame rate override for each uid using UidToFrameRateOverride = std::map; + // Returns the frame rate override for each uid. + // + // @param layers list of visible layers + // @param displayFrameRate the display frame rate + // @param touch whether touch timer is active (i.e. user touched the screen recently) UidToFrameRateOverride getFrameRateOverrides(const std::vector& layers, - Fps displayFrameRate) const EXCLUDES(mLock); + Fps displayFrameRate, bool touch) const + EXCLUDES(mLock); void dump(std::string& result) const EXCLUDES(mLock); @@ -410,6 +419,7 @@ private: // from based on the closest value. const std::vector mKnownFrameRates; + const bool mEnableFrameRateOverride; bool mSupportsFrameRateOverride; }; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 588b83d774..d8612098ec 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -763,17 +763,11 @@ bool Scheduler::updateFrameRateOverrides( return false; } - if (consideredSignals.touch) { - std::lock_guard lock(mFrameRateOverridesMutex); - const bool changed = !mFrameRateOverridesByContent.empty(); - mFrameRateOverridesByContent.clear(); - return changed; - } - if (!consideredSignals.idle) { const auto frameRateOverrides = mRefreshRateConfigs.getFrameRateOverrides(mFeatures.contentRequirements, - displayRefreshRate); + displayRefreshRate, + consideredSignals.touch); std::lock_guard lock(mFrameRateOverridesMutex); if (!std::equal(mFrameRateOverridesByContent.begin(), mFrameRateOverridesByContent.end(), frameRateOverrides.begin(), frameRateOverrides.end(), diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0a51659681..c1fabf8322 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2920,7 +2920,9 @@ void SurfaceFlinger::initScheduler(PhysicalDisplayId primaryDisplayId) { auto currentConfig = getHwComposer().getActiveMode(primaryDisplayId)->getId(); const auto modes = getHwComposer().getModes(primaryDisplayId); - mRefreshRateConfigs = std::make_unique(modes, currentConfig); + mRefreshRateConfigs = std::make_unique< + scheduler::RefreshRateConfigs>(modes, currentConfig, + android::sysprop::enable_frame_rate_override(true)); const auto& currRefreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig); mRefreshRateStats = std::make_unique(*mTimeStats, currRefreshRate.getFps(), @@ -3873,7 +3875,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( } if (what & layer_state_t::eFrameRateChanged) { if (ValidateFrameRate(s.frameRate, s.frameRateCompatibility, - "SurfaceFlinger::setClientStateLocked") && + "SurfaceFlinger::setClientStateLocked", privileged) && layer->setFrameRate(Layer::FrameRate(Fps(s.frameRate), Layer::FrameRate::convertCompatibility( s.frameRateCompatibility), diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index 0a747ab7e3..738ded18ac 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -1506,6 +1506,89 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) { } } +TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) { + auto refreshRateConfigs = + std::make_unique(m30_60_72_90_120Device, + /*currentConfigId=*/HWC_CONFIG_ID_60); + + auto layers = std::vector{LayerRequirement{.weight = 1.0f}, + LayerRequirement{.weight = 0.5f}}; + auto& explicitExactLayer = layers[0]; + auto& explicitExactOrMultipleLayer = layers[1]; + + explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; + explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; + explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60); + + explicitExactLayer.vote = LayerVoteType::ExplicitExact; + explicitExactLayer.name = "ExplicitExact"; + explicitExactLayer.desiredRefreshRate = Fps(30); + + EXPECT_EQ(mExpected30Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + EXPECT_EQ(mExpected30Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); + + explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120); + explicitExactLayer.desiredRefreshRate = Fps(60); + EXPECT_EQ(mExpected60Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + explicitExactLayer.desiredRefreshRate = Fps(72); + EXPECT_EQ(mExpected72Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + explicitExactLayer.desiredRefreshRate = Fps(90); + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + explicitExactLayer.desiredRefreshRate = Fps(120); + EXPECT_EQ(mExpected120Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); +} + +TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) { + auto refreshRateConfigs = + std::make_unique(m30_60_72_90_120Device, + /*currentConfigId=*/HWC_CONFIG_ID_60, + /*enableFrameRateOverride=*/true); + + auto layers = std::vector{LayerRequirement{.weight = 1.0f}, + LayerRequirement{.weight = 0.5f}}; + auto& explicitExactLayer = layers[0]; + auto& explicitExactOrMultipleLayer = layers[1]; + + explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple; + explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple"; + explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60); + + explicitExactLayer.vote = LayerVoteType::ExplicitExact; + explicitExactLayer.name = "ExplicitExact"; + explicitExactLayer.desiredRefreshRate = Fps(30); + + EXPECT_EQ(mExpected60Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + EXPECT_EQ(mExpected120Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false})); + + explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120); + explicitExactLayer.desiredRefreshRate = Fps(60); + EXPECT_EQ(mExpected120Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + explicitExactLayer.desiredRefreshRate = Fps(72); + EXPECT_EQ(mExpected72Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + explicitExactLayer.desiredRefreshRate = Fps(90); + EXPECT_EQ(mExpected90Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); + + explicitExactLayer.desiredRefreshRate = Fps(120); + EXPECT_EQ(mExpected120Config, + refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); +} + TEST_F(RefreshRateConfigsTest, testComparisonOperator) { EXPECT_TRUE(mExpected60Config < mExpected90Config); EXPECT_FALSE(mExpected60Config < mExpected60Config); @@ -1537,7 +1620,7 @@ TEST_F(RefreshRateConfigsTest, testKernelIdleTimerAction) { EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction()); } -TEST_F(RefreshRateConfigsTest, RefreshRateDividerForUid) { +TEST_F(RefreshRateConfigsTest, getRefreshRateDivider) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_30); @@ -1562,57 +1645,66 @@ TEST_F(RefreshRateConfigsTest, RefreshRateDividerForUid) { EXPECT_EQ(4, refreshRateConfigs->getRefreshRateDivider(Fps(22.6f))); } -TEST_F(RefreshRateConfigsTest, populatePreferredFrameRate_noLayers) { +TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120); auto layers = std::vector{}; - ASSERT_TRUE(refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)).empty()); + ASSERT_TRUE(refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false) + .empty()); } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ - HWC_CONFIG_ID_120); + HWC_CONFIG_ID_120, + /*enableFrameRateOverride=*/true); auto layers = std::vector{LayerRequirement{.weight = 1.0f}}; layers[0].name = "Test layer"; layers[0].ownerUid = 1234; layers[0].desiredRefreshRate = Fps(60.0f); layers[0].vote = LayerVoteType::ExplicitDefault; - auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + auto frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[0].vote = LayerVoteType::NoVote; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); layers[0].vote = LayerVoteType::Min; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); layers[0].vote = LayerVoteType::Max; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); layers[0].vote = LayerVoteType::Heuristic; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_TRUE(frameRateOverrides.empty()); } -TEST_F(RefreshRateConfigsTest, populatePreferredFrameRate_twoUids) { +TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { auto refreshRateConfigs = std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ - HWC_CONFIG_ID_120); + HWC_CONFIG_ID_120, + /*enableFrameRateOverride=*/true); auto layers = std::vector{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, @@ -1626,7 +1718,8 @@ TEST_F(RefreshRateConfigsTest, populatePreferredFrameRate_twoUids) { layers[1].name = "Test layer 5678"; layers[1].desiredRefreshRate = Fps(30.0f); layers[1].vote = LayerVoteType::ExplicitDefault; - auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + auto frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(2, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); @@ -1635,13 +1728,66 @@ TEST_F(RefreshRateConfigsTest, populatePreferredFrameRate_twoUids) { ASSERT_EQ(30.0f, frameRateOverrides.at(5678).getValue()); layers[1].vote = LayerVoteType::Heuristic; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); ASSERT_EQ(1, frameRateOverrides.size()); ASSERT_EQ(1, frameRateOverrides.count(1234)); ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); layers[1].ownerUid = 1234; - frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)); + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); + ASSERT_TRUE(frameRateOverrides.empty()); +} + +TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) { + auto refreshRateConfigs = + std::make_unique(m30_60_72_90_120Device, /*currentConfigId=*/ + HWC_CONFIG_ID_120, + /*enableFrameRateOverride=*/true); + + auto layers = std::vector{ + LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, + }; + + layers[0].name = "Test layer"; + layers[0].desiredRefreshRate = Fps(60.0f); + layers[0].vote = LayerVoteType::ExplicitDefault; + + auto frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); + ASSERT_EQ(1, frameRateOverrides.size()); + ASSERT_EQ(1, frameRateOverrides.count(1234)); + ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); + + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true); + ASSERT_EQ(1, frameRateOverrides.size()); + ASSERT_EQ(1, frameRateOverrides.count(1234)); + ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); + + layers[0].vote = LayerVoteType::ExplicitExact; + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); + ASSERT_EQ(1, frameRateOverrides.size()); + ASSERT_EQ(1, frameRateOverrides.count(1234)); + ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); + + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true); + ASSERT_EQ(1, frameRateOverrides.size()); + ASSERT_EQ(1, frameRateOverrides.count(1234)); + ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); + + layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false); + ASSERT_EQ(1, frameRateOverrides.size()); + ASSERT_EQ(1, frameRateOverrides.count(1234)); + ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue()); + + frameRateOverrides = + refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true); ASSERT_TRUE(frameRateOverrides.empty()); } diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp index c8f4cb4c19..e060df2420 100644 --- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp +++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp @@ -473,5 +473,20 @@ INSTANTIATE_TEST_SUITE_P(PerLayerType, SetFrameRateTest, std::make_shared()), PrintToStringParamName); +TEST_F(SetFrameRateTest, ValidateFrameRate) { + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, "", /*privileged=*/true)); + + EXPECT_FALSE(ValidateFrameRate(-1, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + EXPECT_FALSE( + ValidateFrameRate(1.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + EXPECT_FALSE( + ValidateFrameRate(0.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + + EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, "")); +} + } // namespace } // namespace android -- cgit v1.2.3-59-g8ed1b From 8ba8b076a0335155a57a9e8004614c302d07c154 Mon Sep 17 00:00:00 2001 From: chaviw Date: Mon, 25 Jan 2021 14:55:46 -0800 Subject: Remove detachChildren Since there are no longer callers of detachChildren, remove code and test that involve detachChildren Test: Builds and remaining tests pass Bug: 177557720 Change-Id: Id5b7120b7f2c289d4e7ffb5565b29e2be18d6587 --- cmds/surfacereplayer/proto/src/trace.proto | 13 +- cmds/surfacereplayer/replayer/Replayer.cpp | 8 - cmds/surfacereplayer/replayer/Replayer.h | 2 - libs/gui/LayerState.cpp | 3 - libs/gui/SurfaceComposerClient.cpp | 13 - libs/gui/include/gui/LayerState.h | 2 +- libs/gui/include/gui/SurfaceComposerClient.h | 12 - services/surfaceflinger/BufferStateLayer.cpp | 8 +- services/surfaceflinger/BufferStateLayer.h | 1 - services/surfaceflinger/Layer.cpp | 73 ---- services/surfaceflinger/Layer.h | 6 - services/surfaceflinger/SurfaceFlinger.cpp | 3 - services/surfaceflinger/SurfaceInterceptor.cpp | 11 - services/surfaceflinger/SurfaceInterceptor.h | 1 - services/surfaceflinger/tests/Android.bp | 1 - .../surfaceflinger/tests/DetachChildren_test.cpp | 377 --------------------- .../tests/SurfaceInterceptor_test.cpp | 26 -- .../tests/fakehwc/SFFakeHwc_test.cpp | 84 ----- 18 files changed, 6 insertions(+), 638 deletions(-) delete mode 100644 services/surfaceflinger/tests/DetachChildren_test.cpp (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto index c6f656ba0c..79aab822e4 100644 --- a/cmds/surfacereplayer/proto/src/trace.proto +++ b/cmds/surfacereplayer/proto/src/trace.proto @@ -50,11 +50,10 @@ message SurfaceChange { CornerRadiusChange corner_radius = 16; ReparentChange reparent = 17; RelativeParentChange relative_parent = 18; - DetachChildrenChange detach_children = 19; - ReparentChildrenChange reparent_children = 20; - BackgroundBlurRadiusChange background_blur_radius = 21; - ShadowRadiusChange shadow_radius = 22; - BlurRegionsChange blur_regions = 23; + ReparentChildrenChange reparent_children = 19; + BackgroundBlurRadiusChange background_blur_radius = 20; + ShadowRadiusChange shadow_radius = 21; + BlurRegionsChange blur_regions = 22; } } @@ -200,10 +199,6 @@ message RelativeParentChange { required int32 z = 2; } -message DetachChildrenChange { - required bool detach_children = 1; -} - message ShadowRadiusChange { required float radius = 1; } diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp index 5849212265..58d6582e0b 100644 --- a/cmds/surfacereplayer/replayer/Replayer.cpp +++ b/cmds/surfacereplayer/replayer/Replayer.cpp @@ -417,9 +417,6 @@ status_t Replayer::doSurfaceTransaction( case SurfaceChange::SurfaceChangeCase::kRelativeParent: setRelativeParentChange(transaction, change.id(), change.relative_parent()); break; - case SurfaceChange::SurfaceChangeCase::kDetachChildren: - setDetachChildrenChange(transaction, change.id(), change.detach_children()); - break; case SurfaceChange::SurfaceChangeCase::kShadowRadius: setShadowRadiusChange(transaction, change.id(), change.shadow_radius()); break; @@ -713,11 +710,6 @@ void Replayer::setRelativeParentChange(SurfaceComposerClient::Transaction& t, t.setRelativeLayer(mLayers[id], mLayers[c.relative_parent_id()], c.z()); } -void Replayer::setDetachChildrenChange(SurfaceComposerClient::Transaction& t, - layer_id id, const DetachChildrenChange& c) { - t.detachChildren(mLayers[id]); -} - void Replayer::setReparentChildrenChange(SurfaceComposerClient::Transaction& t, layer_id id, const ReparentChildrenChange& c) { if (mLayers.count(c.parent_id()) == 0 || mLayers[c.parent_id()] == nullptr) { diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h index a22262a24e..324d591eaa 100644 --- a/cmds/surfacereplayer/replayer/Replayer.h +++ b/cmds/surfacereplayer/replayer/Replayer.h @@ -116,8 +116,6 @@ class Replayer { layer_id id, const ReparentChange& c); void setRelativeParentChange(SurfaceComposerClient::Transaction& t, layer_id id, const RelativeParentChange& c); - void setDetachChildrenChange(SurfaceComposerClient::Transaction& t, - layer_id id, const DetachChildrenChange& c); void setReparentChildrenChange(SurfaceComposerClient::Transaction& t, layer_id id, const ReparentChildrenChange& c); void setShadowRadiusChange(SurfaceComposerClient::Transaction& t, diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 63be3edf94..e1aba42911 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -427,9 +427,6 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eReparentChildren; reparentSurfaceControl = other.reparentSurfaceControl; } - if (other.what & eDetachChildren) { - what |= eDetachChildren; - } if (other.what & eRelativeLayerChanged) { what |= eRelativeLayerChanged; what &= ~eLayerChanged; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 4a372bba1e..d203b3d513 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1390,19 +1390,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachChildren( - const sp& sc) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eDetachChildren; - - registerSurfaceControlForCallback(sc); - return *this; -} - #ifndef NO_INPUT SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo( const sp& sc, diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 4a291aeb02..042f901dc9 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -98,7 +98,7 @@ struct layer_state_t { /* was ScalingModeChanged, now available 0x00000400, */ eShadowRadiusChanged = 0x00000800, eReparentChildren = 0x00001000, - eDetachChildren = 0x00002000, + /* was eDetachChildren, now available 0x00002000, */ eRelativeLayerChanged = 0x00004000, eReparent = 0x00008000, eColorChanged = 0x00010000, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 11db658de2..884f0546d0 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -508,18 +508,6 @@ public: // Set the framenumber generated by the graphics producer to mimic BufferQueue behaviour. Transaction& setFrameNumber(const sp& sc, uint64_t frameNumber); - // 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); - #ifndef NO_INPUT Transaction& setInputWindowInfo(const sp& sc, const InputWindowInfo& info); Transaction& setFocusedWindow(const FocusRequest& request); diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 0cc15c2acd..3dc62e3091 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -216,8 +216,7 @@ bool BufferStateLayer::willPresentCurrentTransaction() const { // Returns true if the most recent Transaction applied to CurrentState will be presented. return (getSidebandStreamChanged() || getAutoRefresh() || (mCurrentState.modified && - (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr))) && - !mLayerDetached; + (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr))); } /* TODO: vhau uncomment once deferred transaction migration complete in @@ -461,11 +460,6 @@ bool BufferStateLayer::setTransactionCompletedListeners( return willPresent; } -void BufferStateLayer::forceSendCallbacks() { - mFlinger->getTransactionCompletedThread().finalizePendingCallbackHandles( - mCurrentState.callbackHandles, std::vector()); -} - bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) { mCurrentState.transparentRegionHint = transparent; mCurrentState.modified = true; diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index f638caa4f3..b93d567e20 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -80,7 +80,6 @@ public: bool setApi(int32_t api) override; bool setSidebandStream(const sp& sidebandStream) override; bool setTransactionCompletedListeners(const std::vector>& handles) override; - void forceSendCallbacks() override; bool addFrameEvent(const sp& acquireFence, nsecs_t postedTime, nsecs_t requestedPresentTime) override; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index a545d186dd..da888f64d1 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1004,19 +1004,6 @@ uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) { uint32_t Layer::doTransaction(uint32_t flags) { ATRACE_CALL(); - if (mLayerDetached) { - // Ensure BLAST buffer callbacks are processed. - // detachChildren and mLayerDetached were implemented to avoid geometry updates - // to layers in the cases of animation. For BufferQueue layers buffers are still - // consumed as normal. This is useful as otherwise the client could get hung - // inevitably waiting on a buffer to return. We recreate this semantic for BufferQueue - // even though it is a little consistent. detachChildren is shortly slated for removal - // by the hierarchy mirroring work so we don't need to worry about it too much. - forceSendCallbacks(); - mCurrentState.callbackHandles = {}; - return flags; - } - if (mChildrenChanged) { flags |= eVisibleRegion; mChildrenChanged = false; @@ -1512,12 +1499,6 @@ Layer::FrameRate Layer::getFrameRateForLayerTree() const { void Layer::deferTransactionUntil_legacy(const sp& barrierLayer, uint64_t frameNumber) { ATRACE_CALL(); - if (mLayerDetached) { - // If the layer is detached, then we don't defer this transaction since we will not - // commit the pending state while the layer is detached. Adding sync points may cause - // the barrier layer to wait for the states to be committed before dequeuing a buffer. - return; - } mCurrentState.barrierLayer_legacy = barrierLayer; mCurrentState.barrierFrameNumber = frameNumber; @@ -1801,10 +1782,6 @@ ssize_t Layer::removeChild(const sp& layer) { } void Layer::reparentChildren(const sp& newParent) { - if (attachChildren()) { - setTransactionFlags(eTransactionNeeded); - } - for (const sp& child : mCurrentChildren) { newParent->addChild(child); } @@ -1840,17 +1817,6 @@ void Layer::setChildrenDrawingParent(const sp& newParent) { } bool Layer::reparent(const sp& newParentHandle) { - bool callSetTransactionFlags = false; - - // While layers are detached, we allow most operations - // and simply halt performing the actual transaction. However - // for reparent != null we would enter the mRemovedFromCurrentState - // state, regardless of whether doTransaction was called, and - // so we need to prevent the update here. - if (mLayerDetached && newParentHandle == nullptr) { - return false; - } - sp newParent; if (newParentHandle != nullptr) { auto handle = static_cast(newParentHandle.get()); @@ -1877,52 +1843,13 @@ bool Layer::reparent(const sp& newParentHandle) { } else { onRemovedFromCurrentState(); } - - if (mLayerDetached) { - mLayerDetached = false; - callSetTransactionFlags = true; - } } else { onRemovedFromCurrentState(); } - if (attachChildren() || callSetTransactionFlags) { - setTransactionFlags(eTransactionNeeded); - } return true; } -bool Layer::detachChildren() { - for (const sp& child : mCurrentChildren) { - sp parentClient = mClientRef.promote(); - sp client(child->mClientRef.promote()); - if (client != nullptr && parentClient != client) { - child->mLayerDetached = true; - child->detachChildren(); - child->removeRemoteSyncPoints(); - } - } - - return true; -} - -bool Layer::attachChildren() { - bool changed = false; - for (const sp& child : mCurrentChildren) { - sp parentClient = mClientRef.promote(); - sp client(child->mClientRef.promote()); - if (client != nullptr && parentClient != client) { - if (child->mLayerDetached) { - child->mLayerDetached = false; - child->attachChildren(); - changed = true; - } - } - } - - return changed; -} - bool Layer::setColorTransform(const mat4& matrix) { static const mat4 identityMatrix = mat4(); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index f78b5f31e9..50c0597de2 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -432,7 +432,6 @@ public: virtual bool setMetadata(const LayerMetadata& data); virtual void setChildrenDrawingParent(const sp&); virtual bool reparent(const sp& newParentHandle); - virtual bool detachChildren(); virtual bool setColorTransform(const mat4& matrix); virtual mat4 getColorTransform() const; virtual bool hasColorTransform() const; @@ -459,7 +458,6 @@ public: const std::vector>& /*handles*/) { return false; }; - virtual void forceSendCallbacks() {} virtual bool addFrameEvent(const sp& /*acquireFence*/, nsecs_t /*postedTime*/, nsecs_t /*requestedPresentTime*/) { return false; @@ -664,8 +662,6 @@ public: bool reparentChildren(const sp& newParentHandle); void reparentChildren(const sp& newParent); - bool attachChildren(); - bool isLayerDetached() const { return mLayerDetached; } bool setShadowRadius(float shadowRadius); // Before color management is introduced, contents on Android have to be @@ -1097,8 +1093,6 @@ protected: wp mCurrentParent; wp mDrawingParent; - // Can only be accessed with the SF state lock held. - bool mLayerDetached{false}; // Can only be accessed with the SF state lock held. bool mChildrenChanged{false}; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0a51659681..83a83e05b1 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3811,9 +3811,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTransactionNeeded|eTraversalNeeded; } } - if (what & layer_state_t::eDetachChildren) { - layer->detachChildren(); - } if (what & layer_state_t::eTransformChanged) { if (layer->setTransform(s.transform)) flags |= eTraversalNeeded; } diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index 354892386b..61005c92df 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -150,7 +150,6 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, layer_state_t::eLayerHidden | layer_state_t::eLayerOpaque | layer_state_t::eLayerSecure); addReparentLocked(transaction, layerId, getLayerIdFromWeakRef(layer->mCurrentParent)); - addDetachChildrenLocked(transaction, layerId, layer->isLayerDetached()); addRelativeParentLocked(transaction, layerId, getLayerIdFromWeakRef(layer->mCurrentState.zOrderRelativeOf), layer->mCurrentState.z); @@ -409,13 +408,6 @@ void SurfaceInterceptor::addReparentChildrenLocked(Transaction* transaction, int overrideChange->set_parent_id(parentId); } -void SurfaceInterceptor::addDetachChildrenLocked(Transaction* transaction, int32_t layerId, - bool detached) { - SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); - DetachChildrenChange* overrideChange(change->mutable_detach_children()); - overrideChange->set_detach_children(detached); -} - void SurfaceInterceptor::addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId, int z) { SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); @@ -498,9 +490,6 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, addReparentChildrenLocked(transaction, layerId, getLayerIdFromHandle(state.reparentSurfaceControl->getHandle())); } - if (state.what & layer_state_t::eDetachChildren) { - addDetachChildrenLocked(transaction, layerId, true); - } if (state.what & layer_state_t::eRelativeLayerChanged) { addRelativeParentLocked(transaction, layerId, getLayerIdFromHandle( diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 3df79c6eb5..3e27e83b02 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -177,7 +177,6 @@ private: uint64_t transactionId); void addReparentLocked(Transaction* transaction, int32_t layerId, int32_t parentId); void addReparentChildrenLocked(Transaction* transaction, int32_t layerId, int32_t parentId); - void addDetachChildrenLocked(Transaction* transaction, int32_t layerId, bool detached); void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId, int z); void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius); diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index e8b24b49bc..cfaf229bde 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -21,7 +21,6 @@ cc_test { "CommonTypes_test.cpp", "Credentials_test.cpp", "DereferenceSurfaceControl_test.cpp", - "DetachChildren_test.cpp", "DisplayConfigs_test.cpp", "EffectLayer_test.cpp", "InvalidHandles_test.cpp", diff --git a/services/surfaceflinger/tests/DetachChildren_test.cpp b/services/surfaceflinger/tests/DetachChildren_test.cpp deleted file mode 100644 index abf8b1a2b9..0000000000 --- a/services/surfaceflinger/tests/DetachChildren_test.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" - -#include "LayerTransactionTest.h" - -namespace android { - -class DetachChildren : public LayerTransactionTest { -protected: - virtual void SetUp() { - LayerTransactionTest::SetUp(); - - mMainSurface = createLayer(String8("Main Test Surface"), mMainSurfaceBounds.width(), - mMainSurfaceBounds.height(), 0, mBlackBgSurface.get()); - - ASSERT_TRUE(mMainSurface != nullptr); - ASSERT_TRUE(mMainSurface->isValid()); - - TransactionUtils::fillSurfaceRGBA8(mMainSurface, mMainSurfaceColor); - - asTransaction([&](Transaction& t) { - t.setLayer(mMainSurface, INT32_MAX - 1) - .setPosition(mMainSurface, mMainSurfaceBounds.left, mMainSurfaceBounds.top) - .show(mMainSurface); - }); - } - - virtual void TearDown() { - LayerTransactionTest::TearDown(); - mMainSurface = 0; - } - - sp mMainSurface; - Color mMainSurfaceColor = {195, 63, 63, 255}; - Rect mMainSurfaceBounds = Rect(64, 64, 128, 128); - std::unique_ptr mCapture; -}; - -TEST_F(DetachChildren, RelativesAreNotDetached) { - Color relativeColor = {10, 10, 10, 255}; - Rect relBounds = Rect(64, 64, 74, 74); - - sp relative = - createLayer(String8("relativeTestSurface"), relBounds.width(), relBounds.height(), 0); - TransactionUtils::fillSurfaceRGBA8(relative, relativeColor); - - Transaction{} - .setRelativeLayer(relative, mMainSurface, 1) - .setPosition(relative, relBounds.left, relBounds.top) - .apply(); - - { - // The relative should be on top of the FG control. - mCapture = screenshot(); - mCapture->expectColor(relBounds, relativeColor); - } - Transaction{}.detachChildren(mMainSurface).apply(); - - { - // Nothing should change at this point. - mCapture = screenshot(); - mCapture->expectColor(relBounds, relativeColor); - } - - Transaction{}.hide(relative).apply(); - - { - // Ensure that the relative was actually hidden, rather than - // being left in the detached but visible state. - mCapture = screenshot(); - mCapture->expectColor(mMainSurfaceBounds, mMainSurfaceColor); - } -} - -TEST_F(DetachChildren, DetachChildrenSameClient) { - Color childColor = {200, 200, 200, 255}; - Rect childBounds = Rect(74, 74, 84, 84); - sp child = createLayer(String8("Child surface"), childBounds.width(), - childBounds.height(), 0, mMainSurface.get()); - ASSERT_TRUE(child->isValid()); - - TransactionUtils::fillSurfaceRGBA8(child, childColor); - - asTransaction([&](Transaction& t) { - t.show(child); - t.setPosition(child, childBounds.left - mMainSurfaceBounds.left, - childBounds.top - mMainSurfaceBounds.top); - }); - - { - mCapture = screenshot(); - // Expect main color around the child surface - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } - - asTransaction([&](Transaction& t) { t.detachChildren(mMainSurface); }); - - asTransaction([&](Transaction& t) { t.hide(child); }); - - // Since the child has the same client as the parent, it will not get - // detached and will be hidden. - { - mCapture = screenshot(); - mCapture->expectColor(mMainSurfaceBounds, mMainSurfaceColor); - } -} - -TEST_F(DetachChildren, DetachChildrenDifferentClient) { - Color childColor = {200, 200, 200, 255}; - Rect childBounds = Rect(74, 74, 84, 84); - - sp newComposerClient = new SurfaceComposerClient; - sp childNewClient = - createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), - childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); - ASSERT_TRUE(childNewClient->isValid()); - - TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); - - asTransaction([&](Transaction& t) { - t.show(childNewClient); - t.setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, - childBounds.top - mMainSurfaceBounds.top); - }); - - { - mCapture = screenshot(); - // Expect main color around the child surface - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } - - asTransaction([&](Transaction& t) { t.detachChildren(mMainSurface); }); - - asTransaction([&](Transaction& t) { t.hide(childNewClient); }); - - // Nothing should have changed. - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } -} - -TEST_F(DetachChildren, DetachChildrenThenAttach) { - Color childColor = {200, 200, 200, 255}; - Rect childBounds = Rect(74, 74, 84, 84); - - sp newComposerClient = new SurfaceComposerClient; - sp childNewClient = - createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), - childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); - ASSERT_TRUE(childNewClient->isValid()); - - TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); - - Transaction() - .show(childNewClient) - .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, - childBounds.top - mMainSurfaceBounds.top) - .apply(); - - { - mCapture = screenshot(); - // Expect main color around the child surface - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } - - Transaction().detachChildren(mMainSurface).apply(); - Transaction().hide(childNewClient).apply(); - - // Nothing should have changed. - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } - - Color newParentColor = Color::RED; - Rect newParentBounds = Rect(20, 20, 52, 52); - sp newParentSurface = - createLayer(String8("New Parent Surface"), newParentBounds.width(), - newParentBounds.height(), 0); - TransactionUtils::fillSurfaceRGBA8(newParentSurface, newParentColor); - Transaction() - .setLayer(newParentSurface, INT32_MAX - 1) - .show(newParentSurface) - .setPosition(newParentSurface, newParentBounds.left, newParentBounds.top) - .reparent(childNewClient, newParentSurface) - .apply(); - { - mCapture = screenshot(); - // Child is now hidden. - mCapture->expectColor(newParentBounds, newParentColor); - } -} - -TEST_F(DetachChildren, DetachChildrenWithDeferredTransaction) { - Color childColor = {200, 200, 200, 255}; - Rect childBounds = Rect(74, 74, 84, 84); - - sp newComposerClient = new SurfaceComposerClient; - sp childNewClient = - createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), - childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); - ASSERT_TRUE(childNewClient->isValid()); - - TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); - - Transaction() - .show(childNewClient) - .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, - childBounds.top - mMainSurfaceBounds.top) - .apply(); - - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } - - Transaction() - .deferTransactionUntil_legacy(childNewClient, mMainSurface, - mMainSurface->getSurface()->getNextFrameNumber()) - .apply(); - Transaction().detachChildren(mMainSurface).apply(); - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mMainSurface, Color::RED, - mMainSurfaceBounds.width(), - mMainSurfaceBounds.height())); - - // BufferLayer can still dequeue buffers even though there's a detached layer with a - // deferred transaction. - { - SCOPED_TRACE("new buffer"); - mCapture = screenshot(); - mCapture->expectBorder(childBounds, Color::RED); - mCapture->expectColor(childBounds, childColor); - } -} - -/** - * Tests that a deferring transaction on an already detached layer will be dropped gracefully and - * allow the barrier layer to dequeue buffers. - * - * Fixes b/150924737 - buffer cannot be latched because it waits for a detached layer - * to commit its pending states. - */ -TEST_F(DetachChildren, DeferredTransactionOnDetachedChildren) { - Color childColor = {200, 200, 200, 255}; - Rect childBounds = Rect(74, 74, 84, 84); - - sp newComposerClient = new SurfaceComposerClient; - sp childNewClient = - createSurface(newComposerClient, "New Child Test Surface", childBounds.width(), - childBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); - ASSERT_TRUE(childNewClient->isValid()); - - TransactionUtils::fillSurfaceRGBA8(childNewClient, childColor); - - Transaction() - .show(childNewClient) - .setPosition(childNewClient, childBounds.left - mMainSurfaceBounds.left, - childBounds.top - mMainSurfaceBounds.top) - .apply(); - - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectColor(childBounds, childColor); - } - - Transaction().detachChildren(mMainSurface).apply(); - Transaction() - .setCrop_legacy(childNewClient, {0, 0, childBounds.width(), childBounds.height()}) - .deferTransactionUntil_legacy(childNewClient, mMainSurface, - mMainSurface->getSurface()->getNextFrameNumber()) - .apply(); - - ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mMainSurface, Color::RED, - mMainSurfaceBounds.width(), - mMainSurfaceBounds.height())); - - // BufferLayer can still dequeue buffers even though there's a detached layer with a - // deferred transaction. - { - SCOPED_TRACE("new buffer"); - mCapture = screenshot(); - mCapture->expectBorder(childBounds, Color::RED); - mCapture->expectColor(childBounds, childColor); - } -} - -TEST_F(DetachChildren, ReparentParentLayerOfDetachedChildren) { - Color childColor = {200, 200, 200, 255}; - Rect childBounds = Rect(74, 74, 94, 94); - Color grandchildColor = Color::RED; - Rect grandchildBounds = Rect(80, 80, 90, 90); - - sp newClient1 = new SurfaceComposerClient; - sp newClient2 = new SurfaceComposerClient; - - sp childSurface = - createSurface(newClient1, "Child surface", childBounds.width(), childBounds.height(), - PIXEL_FORMAT_RGBA_8888, 0, mMainSurface.get()); - sp grandchildSurface = - createSurface(newClient2, "Grandchild Surface", grandchildBounds.width(), - grandchildBounds.height(), PIXEL_FORMAT_RGBA_8888, 0, childSurface.get()); - - TransactionUtils::fillSurfaceRGBA8(childSurface, childColor); - TransactionUtils::fillSurfaceRGBA8(grandchildSurface, grandchildColor); - - Transaction() - .show(childSurface) - .show(grandchildSurface) - .setPosition(childSurface, childBounds.left - mMainSurfaceBounds.left, - childBounds.top - mMainSurfaceBounds.top) - .setPosition(grandchildSurface, grandchildBounds.left - childBounds.left, - grandchildBounds.top - childBounds.top) - .apply(); - - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectBorder(grandchildBounds, childColor); - mCapture->expectColor(grandchildBounds, grandchildColor); - } - - Transaction().detachChildren(childSurface).apply(); - - // Remove main surface offscreen - Transaction().reparent(mMainSurface, nullptr).apply(); - { - mCapture = screenshot(); - mCapture->expectColor(mMainSurfaceBounds, Color::BLACK); - } - - Transaction().reparent(mMainSurface, mBlackBgSurface).apply(); - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectBorder(grandchildBounds, childColor); - mCapture->expectColor(grandchildBounds, grandchildColor); - } - - Transaction().hide(grandchildSurface).apply(); - - // grandchild is still detached so it will not hide - { - mCapture = screenshot(); - mCapture->expectBorder(childBounds, mMainSurfaceColor); - mCapture->expectBorder(grandchildBounds, childColor); - mCapture->expectColor(grandchildBounds, grandchildColor); - } -} - -} // namespace android - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" \ No newline at end of file diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index 8dc9a1212f..fa88ca5c57 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -194,7 +194,6 @@ public: bool deferredTransactionUpdateFound(const SurfaceChange& change, bool foundDeferred); bool reparentUpdateFound(const SurfaceChange& change, bool found); bool relativeParentUpdateFound(const SurfaceChange& change, bool found); - bool detachChildrenUpdateFound(const SurfaceChange& change, bool found); bool reparentChildrenUpdateFound(const SurfaceChange& change, bool found); bool shadowRadiusUpdateFound(const SurfaceChange& change, bool found); bool surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase); @@ -232,7 +231,6 @@ public: void deferredTransactionUpdate(Transaction&); void reparentUpdate(Transaction&); void relativeParentUpdate(Transaction&); - void detachChildrenUpdate(Transaction&); void reparentChildrenUpdate(Transaction&); void shadowRadiusUpdate(Transaction&); void surfaceCreation(Transaction&); @@ -412,10 +410,6 @@ void SurfaceInterceptorTest::relativeParentUpdate(Transaction& t) { t.setRelativeLayer(mBGSurfaceControl, mFGSurfaceControl, RELATIVE_Z); } -void SurfaceInterceptorTest::detachChildrenUpdate(Transaction& t) { - t.detachChildren(mBGSurfaceControl); -} - void SurfaceInterceptorTest::reparentChildrenUpdate(Transaction& t) { t.reparentChildren(mBGSurfaceControl, mFGSurfaceControl); } @@ -452,7 +446,6 @@ void SurfaceInterceptorTest::runAllUpdates() { runInTransaction(&SurfaceInterceptorTest::deferredTransactionUpdate); runInTransaction(&SurfaceInterceptorTest::reparentUpdate); runInTransaction(&SurfaceInterceptorTest::reparentChildrenUpdate); - runInTransaction(&SurfaceInterceptorTest::detachChildrenUpdate); runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate); runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate); } @@ -667,16 +660,6 @@ bool SurfaceInterceptorTest::relativeParentUpdateFound(const SurfaceChange& chan return found; } -bool SurfaceInterceptorTest::detachChildrenUpdateFound(const SurfaceChange& change, bool found) { - bool detachChildren(change.detach_children().detach_children()); - if (detachChildren && !found) { - found = true; - } else if (detachChildren && found) { - []() { FAIL(); }(); - } - return found; -} - bool SurfaceInterceptorTest::reparentChildrenUpdateFound(const SurfaceChange& change, bool found) { bool hasId(change.reparent_children().parent_id() == mFGLayerId); if (hasId && !found) { @@ -761,9 +744,6 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace, case SurfaceChange::SurfaceChangeCase::kRelativeParent: foundUpdate = relativeParentUpdateFound(change, foundUpdate); break; - case SurfaceChange::SurfaceChangeCase::kDetachChildren: - foundUpdate = detachChildrenUpdateFound(change, foundUpdate); - break; case SurfaceChange::SurfaceChangeCase::kShadowRadius: foundUpdate = shadowRadiusUpdateFound(change, foundUpdate); break; @@ -793,7 +773,6 @@ void SurfaceInterceptorTest::assertAllUpdatesFound(const Trace& trace) { ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kReparent)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kReparentChildren)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kRelativeParent)); - ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kDetachChildren)); } bool SurfaceInterceptorTest::surfaceCreationFound(const Increment& increment, bool foundSurface) { @@ -968,11 +947,6 @@ TEST_F(SurfaceInterceptorTest, InterceptRelativeParentUpdateWorks) { SurfaceChange::SurfaceChangeCase::kRelativeParent); } -TEST_F(SurfaceInterceptorTest, InterceptDetachChildrenUpdateWorks) { - captureTest(&SurfaceInterceptorTest::detachChildrenUpdate, - SurfaceChange::SurfaceChangeCase::kDetachChildren); -} - TEST_F(SurfaceInterceptorTest, InterceptShadowRadiusUpdateWorks) { captureTest(&SurfaceInterceptorTest::shadowRadiusUpdate, SurfaceChange::SurfaceChangeCase::kShadowRadius); diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index bd49728215..4d7b396dda 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -1639,82 +1639,6 @@ protected: EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); } - void Test_DetachChildrenSameClient() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(mChild); - ts.setPosition(mChild, 10, 10); - ts.setPosition(Base::mFGSurfaceControl, 64, 64); - } - - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = - hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.detachChildren(Base::mFGSurfaceControl); - } - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setPosition(Base::mFGSurfaceControl, 64, 64); - ts.hide(mChild); - } - - std::vector refFrame(2); - refFrame[Base::BG_LAYER] = Base::mBaseFrame[Base::BG_LAYER]; - refFrame[Base::FG_LAYER] = Base::mBaseFrame[Base::FG_LAYER]; - - EXPECT_TRUE(framesAreSame(refFrame, Base::sFakeComposer->getLatestFrame())); - } - - void Test_DetachChildrenDifferentClient() { - sp newComposerClient = new SurfaceComposerClient; - sp childNewClient = - newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, - PIXEL_FORMAT_RGBA_8888, 0, - Base::mFGSurfaceControl->getHandle()); - ASSERT_TRUE(childNewClient != nullptr); - ASSERT_TRUE(childNewClient->isValid()); - fillSurfaceRGBA8(childNewClient, LIGHT_GRAY); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.hide(mChild); - ts.show(childNewClient); - ts.setPosition(childNewClient, 10, 10); - ts.setPosition(Base::mFGSurfaceControl, 64, 64); - } - - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = - hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.detachChildren(Base::mFGSurfaceControl); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - } - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setPosition(Base::mFGSurfaceControl, 64, 64); - ts.setPosition(childNewClient, 0, 0); - ts.hide(childNewClient); - } - - // Nothing should have changed. The child control becomes a no-op - // zombie on detach. See comments for detachChildren in the - // SurfaceControl.h file. - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - } - // Regression test for b/37673612 void Test_ChildrenWithParentBufferTransform() { { @@ -1815,14 +1739,6 @@ TEST_F(ChildLayerTest_2_1, DISABLED_ReparentChildren) { Test_ReparentChildren(); } -TEST_F(ChildLayerTest_2_1, DISABLED_DetachChildrenSameClient) { - Test_DetachChildrenSameClient(); -} - -TEST_F(ChildLayerTest_2_1, DISABLED_DetachChildrenDifferentClient) { - Test_DetachChildrenDifferentClient(); -} - // Regression test for b/37673612 TEST_F(ChildLayerTest_2_1, DISABLED_ChildrenWithParentBufferTransform) { Test_ChildrenWithParentBufferTransform(); -- cgit v1.2.3-59-g8ed1b From f6eddb6b42a9548f1298e899ea06a7a042182783 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 27 Jan 2021 22:02:11 -0800 Subject: Enable backpressure for BufferStateLayer The default behaviour of buffer state layer is to drop older buffers if there are newer buffers that are ready to be presented. When emulating BufferQueue behavior via the adapter, we want to queue up buffers without any present timestamps. To solve this, we introduce a layer state flag to keep the buffer in the transaction queue if there is already a buffer that is ready to be applied. Test: atest SurfaceViewBufferTests:BufferPresentationTests Bug: 176967609 Change-Id: I33f6347bd1c7a2d80dc4214e596bb864abe8c6bf --- libs/gui/BLASTBufferQueue.cpp | 21 +++++++++++++++++---- libs/gui/LayerState.cpp | 8 +++----- libs/gui/SurfaceComposerClient.cpp | 3 ++- libs/gui/include/gui/LayerState.h | 8 ++++++-- services/surfaceflinger/Layer.cpp | 2 +- services/surfaceflinger/Layer.h | 7 +++++-- services/surfaceflinger/SurfaceFlinger.cpp | 29 ++++++++++++++++++++--------- services/surfaceflinger/SurfaceFlinger.h | 2 +- 8 files changed, 55 insertions(+), 25 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 0a3d44d336..490495596b 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -146,6 +146,10 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const spgetTransformHint(); mBufferItemConsumer->setTransformHint(mTransformHint); + SurfaceComposerClient::Transaction() + .setFlags(surface, layer_state_t::eEnableBackpressure, + layer_state_t::eEnableBackpressure) + .apply(); mNumAcquired = 0; mNumFrameAvailable = 0; @@ -169,13 +173,20 @@ BLASTBufferQueue::~BLASTBufferQueue() { void BLASTBufferQueue::update(const sp& surface, uint32_t width, uint32_t height, int32_t format) { std::unique_lock _lock{mMutex}; - mSurfaceControl = surface; - if (mFormat != format) { mFormat = format; mBufferItemConsumer->setDefaultBufferFormat(format); } + SurfaceComposerClient::Transaction t; + bool applyTransaction = false; + if (!SurfaceControl::isSameSurface(mSurfaceControl, surface)) { + mSurfaceControl = surface; + t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure, + layer_state_t::eEnableBackpressure); + applyTransaction = true; + } + ui::Size newSize(width, height); if (mRequestedSize != newSize) { mRequestedSize.set(newSize); @@ -184,13 +195,15 @@ void BLASTBufferQueue::update(const sp& surface, uint32_t width, // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; - SurfaceComposerClient::Transaction t; t.setFrame(mSurfaceControl, {0, 0, static_cast(mSize.width), static_cast(mSize.height)}); - t.apply(); + applyTransaction = true; } } + if (applyTransaction) { + t.apply(); + } } static void transactionCallbackThunk(void* context, nsecs_t latchTime, diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e5e10a0014..2946aaed37 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -183,12 +183,9 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readUint32, &layerStack); SAFE_PARCEL(input.readFloat, &alpha); - uint32_t tmpUint32 = 0; - SAFE_PARCEL(input.readUint32, &tmpUint32); - flags = static_cast(tmpUint32); + SAFE_PARCEL(input.readUint32, &flags); - SAFE_PARCEL(input.readUint32, &tmpUint32); - mask = static_cast(tmpUint32); + SAFE_PARCEL(input.readUint32, &mask); SAFE_PARCEL(matrix.read, input); SAFE_PARCEL(input.read, crop_legacy); @@ -229,6 +226,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, *acquireFence); } + uint32_t tmpUint32 = 0; SAFE_PARCEL(input.readUint32, &tmpUint32); dataspace = static_cast(tmpUint32); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 78f655a71b..96c099be23 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -934,7 +934,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags return *this; } if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) || - (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot)) { + (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) || + (mask & layer_state_t::eEnableBackpressure)) { s->what |= layer_state_t::eFlagsChanged; } s->flags &= ~mask; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 83a9d3356e..b1305c6607 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -82,6 +82,10 @@ struct layer_state_t { eLayerOpaque = 0x02, // SURFACE_OPAQUE eLayerSkipScreenshot = 0x40, // SKIP_SCREENSHOT eLayerSecure = 0x80, // SECURE + // Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is + // set. This blocks the client until all the buffers have been presented. If the buffers + // have presentation timestamps, then we may drop buffers. + eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE }; enum { @@ -157,8 +161,8 @@ struct layer_state_t { uint32_t h; uint32_t layerStack; float alpha; - uint8_t flags; - uint8_t mask; + uint32_t flags; + uint32_t mask; uint8_t reserved; matrix22_t matrix; Rect crop_legacy; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 66ce3f1a44..177a81a7bc 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1312,7 +1312,7 @@ bool Layer::setBlurRegions(const std::vector& blurRegions) { return true; } -bool Layer::setFlags(uint8_t flags, uint8_t mask) { +bool Layer::setFlags(uint32_t flags, uint32_t mask) { const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); if (mCurrentState.flags == newFlags) return false; mCurrentState.sequence++; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 359340eb64..357c4a4dee 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -207,7 +207,7 @@ public: // to achieve mirroring. uint32_t layerStack; - uint8_t flags; + uint32_t flags; uint8_t reserved[2]; int32_t sequence; // changes when visible regions can change bool modified; @@ -425,7 +425,7 @@ public: virtual bool setBackgroundBlurRadius(int backgroundBlurRadius); virtual bool setBlurRegions(const std::vector& effectRegions); virtual bool setTransparentRegionHint(const Region& transparent); - virtual bool setFlags(uint8_t flags, uint8_t mask); + virtual bool setFlags(uint32_t flags, uint32_t mask); virtual bool setLayerStack(uint32_t layerStack); virtual uint32_t getLayerStack() const; virtual void deferTransactionUntil_legacy(const sp& barrierHandle, @@ -906,6 +906,9 @@ public: bool mPendingHWCDestroy{false}; + bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; } + bool hasPendingBuffer() { return mCurrentState.buffer != mDrawingState.buffer; }; + protected: class SyncPoint { public: diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index c1fabf8322..bf0c2d69f5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3258,7 +3258,8 @@ bool SurfaceFlinger::flushTransactionQueues() { while (!transactionQueue.empty()) { const auto& transaction = transactionQueue.front(); - if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime, + if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp, + transaction.desiredPresentTime, transaction.states)) { setTransactionFlags(eTransactionFlushNeeded); break; @@ -3291,16 +3292,14 @@ bool SurfaceFlinger::transactionFlushNeeded() { return !mTransactionQueues.empty(); } - -bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime, +bool SurfaceFlinger::transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t desiredPresentTime, const Vector& states, bool updateTransactionCounters) { - const nsecs_t expectedPresentTime = mExpectedPresentTime.load(); bool ready = true; // Do not present if the desiredPresentTime has not passed unless it is more than one second // in the future. We ignore timestamps more than 1 second in the future for stability reasons. - if (desiredPresentTime > 0 && desiredPresentTime >= expectedPresentTime && + if (!isAutoTimestamp && desiredPresentTime >= expectedPresentTime && desiredPresentTime < expectedPresentTime + s2ns(1)) { ready = false; } @@ -3320,14 +3319,26 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime, ALOGW("Transaction with buffer, but no Layer?"); continue; } - if (layer && !mScheduler->isVsyncValid(expectedPresentTime, layer->getOwnerUid())) { + if (!layer) { + continue; + } + + if (!mScheduler->isVsyncValid(expectedPresentTime, layer->getOwnerUid())) { ATRACE_NAME("!isVsyncValidForUid"); ready = false; } if (updateTransactionCounters) { - // See BufferStateLayer::mPendingBufferTransactions - if (layer) layer->incrementPendingBufferCount(); + // See BufferStateLayer::mPendingBufferTransactions + layer->incrementPendingBufferCount(); + } + // If backpressure is enabled and we already have a buffer to commit, keep the transaction + // in the queue. + bool hasBuffer = s.what & layer_state_t::eBufferChanged || + s.what & layer_state_t::eCachedBufferChanged; + if (hasBuffer && layer->backpressureEnabled() && layer->hasPendingBuffer() && + isAutoTimestamp) { + ready = false; } } return ready; @@ -3385,7 +3396,7 @@ status_t SurfaceFlinger::setTransactionState( // Call transactionIsReadyToBeApplied first in case we need to incrementPendingBufferCount // if the transaction contains a buffer. - if (!transactionIsReadyToBeApplied(isAutoTimestamp ? 0 : desiredPresentTime, states, true) || + if (!transactionIsReadyToBeApplied(isAutoTimestamp, desiredPresentTime, states, true) || pendingTransactions) { mTransactionQueues[applyToken].emplace(frameTimelineVsyncId, states, displays, flags, desiredPresentTime, isAutoTimestamp, uncacheBuffer, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c90fb4aca3..194131db32 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -751,7 +751,7 @@ private: uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule); void commitTransaction() REQUIRES(mStateLock); void commitOffscreenLayers(); - bool transactionIsReadyToBeApplied(int64_t desiredPresentTime, + bool transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t desiredPresentTime, const Vector& states, bool updateTransactionCounters = false) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); -- cgit v1.2.3-59-g8ed1b From fc434acf530cbde198c8936bf1bc09fad5861031 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Wed, 13 Jan 2021 10:28:00 -1000 Subject: Add inputEventId to SurfaceFrame SurfaceFrame will now be aware of the id of the input event that caused the current frame. The flow of input event id is inputflinger -> app -> surfaceflinger. Here, we are adding the 'inputEventId' parameter to the 'setFrameTimelineVsync' call. This call will now be responsible for setting two pieces of information: the vsync id, and the input event id. Since it will no longer be limited to the vsync id, we rename this call to "setFrameTimelineInfo". Once the inputEventId is stored in SurfaceFrame, we will add a binder call to send the frame timing information to inputflinger (separate, future CL). This will allow input to reconstruct the entire sequence of events (at what time was input event getting processed in system_server, app, and surfaceflinger) and will provide the ability to measure end-to-end touch latency. In a separate change, we will also add ATRACE calls to allow manual / script-based latency analysis for local debugging. We will now know which input event is being processed in surfaceflinger. Bug: 169866723 Bug: 129481165 Design doc: https://docs.google.com/document/d/1G3bLaZYSmbe6AKcL-6ZChvrw_B_LXEz29Z6Ed9QoYXY/edit# Test: atest WMShellUnitTests SurfaceParcelable_test libgui_test IPC_test SurfaceFlinger_test Change-Id: If7e0eee82603b38b396b53ad7ced660973efcb50 Merged-In: If7e0eee82603b38b396b53ad7ced660973efcb50 --- libs/gui/Android.bp | 3 + libs/gui/BLASTBufferQueue.cpp | 14 +- libs/gui/FrameTimelineInfo.cpp | 62 +++++ libs/gui/ISurfaceComposer.cpp | 251 ++++++++++----------- libs/gui/ITransactionCompletedListener.cpp | 6 +- libs/gui/LayerState.cpp | 18 +- libs/gui/Surface.cpp | 16 +- libs/gui/SurfaceComposerClient.cpp | 41 ++-- libs/gui/include/gui/BLASTBufferQueue.h | 4 +- libs/gui/include/gui/DisplayEventDispatcher.h | 2 +- libs/gui/include/gui/FrameTimelineInfo.h | 43 ++++ libs/gui/include/gui/ISurfaceComposer.h | 14 +- libs/gui/include/gui/LayerState.h | 4 +- libs/gui/include/gui/Surface.h | 5 +- libs/gui/include/gui/SurfaceComposerClient.h | 13 +- libs/gui/tests/Surface_test.cpp | 6 +- libs/input/android/os/IInputConstants.aidl | 9 + libs/nativewindow/include/system/window.h | 11 +- services/surfaceflinger/BufferQueueLayer.cpp | 14 +- services/surfaceflinger/BufferQueueLayer.h | 6 +- .../surfaceflinger/FrameTimeline/FrameTimeline.cpp | 97 ++++---- .../surfaceflinger/FrameTimeline/FrameTimeline.h | 28 +-- services/surfaceflinger/Layer.cpp | 16 +- services/surfaceflinger/Layer.h | 9 +- services/surfaceflinger/SurfaceFlinger.cpp | 40 ++-- services/surfaceflinger/SurfaceFlinger.h | 18 +- services/surfaceflinger/tests/LayerState_test.cpp | 29 +++ .../tests/unittests/FrameTimelineTest.cpp | 187 +++++++-------- .../tests/unittests/TestableSurfaceFlinger.h | 18 +- .../tests/unittests/TransactionApplicationTest.cpp | 72 +++--- 30 files changed, 589 insertions(+), 467 deletions(-) create mode 100644 libs/gui/FrameTimelineInfo.cpp create mode 100644 libs/gui/include/gui/FrameTimelineInfo.h (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 38ae353a68..fa5044cc16 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -49,6 +49,7 @@ cc_library_shared { srcs: [ ":framework_native_aidl", + ":inputconstants_aidl", ":libgui_aidl", ":libgui_bufferqueue_sources", @@ -62,6 +63,7 @@ cc_library_shared { "DebugEGLImageTracker.cpp", "DisplayEventDispatcher.cpp", "DisplayEventReceiver.cpp", + "FrameTimelineInfo.cpp", "GLConsumer.cpp", "IConsumerListener.cpp", "IDisplayEventConnection.cpp", @@ -154,6 +156,7 @@ cc_library_static { defaults: ["libgui_bufferqueue-defaults"], srcs: [ + ":inputconstants_aidl", ":libgui_aidl", ":libgui_bufferqueue_sources", ], diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 42d2895950..c62d9ad440 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -370,9 +370,9 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { } t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber); - if (!mNextFrameTimelineVsyncIdQueue.empty()) { - t->setFrameTimelineVsync(mSurfaceControl, mNextFrameTimelineVsyncIdQueue.front()); - mNextFrameTimelineVsyncIdQueue.pop(); + if (!mNextFrameTimelineInfoQueue.empty()) { + t->setFrameTimelineInfo(mSurfaceControl, mNextFrameTimelineInfoQueue.front()); + mNextFrameTimelineInfoQueue.pop(); } if (mAutoRefresh != bufferItem.mAutoRefresh) { @@ -534,8 +534,8 @@ public: return mBbq->setFrameRate(frameRate, compatibility, shouldBeSeamless); } - status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId) override { - return mBbq->setFrameTimelineVsync(frameTimelineVsyncId); + status_t setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) override { + return mBbq->setFrameTimelineInfo(frameTimelineInfo); } }; @@ -549,9 +549,9 @@ status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility, return t.setFrameRate(mSurfaceControl, frameRate, compatibility, shouldBeSeamless).apply(); } -status_t BLASTBufferQueue::setFrameTimelineVsync(int64_t frameTimelineVsyncId) { +status_t BLASTBufferQueue::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) { std::unique_lock _lock{mMutex}; - mNextFrameTimelineVsyncIdQueue.push(frameTimelineVsyncId); + mNextFrameTimelineInfoQueue.push(frameTimelineInfo); return OK; } diff --git a/libs/gui/FrameTimelineInfo.cpp b/libs/gui/FrameTimelineInfo.cpp new file mode 100644 index 0000000000..f40077403a --- /dev/null +++ b/libs/gui/FrameTimelineInfo.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 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_TAG "FrameTimelineInfo" + +#include + +#include +#include +#include +#include + +#include + +using android::os::IInputConstants; + +namespace android { + +status_t FrameTimelineInfo::write(Parcel& output) const { + SAFE_PARCEL(output.writeInt64, vsyncId); + SAFE_PARCEL(output.writeInt32, inputEventId); + return NO_ERROR; +} + +status_t FrameTimelineInfo::read(const Parcel& input) { + SAFE_PARCEL(input.readInt64, &vsyncId); + SAFE_PARCEL(input.readInt32, &inputEventId); + return NO_ERROR; +} + +void FrameTimelineInfo::merge(const FrameTimelineInfo& other) { + // When merging vsync Ids we take the oldest valid one + if (vsyncId != INVALID_VSYNC_ID && other.vsyncId != INVALID_VSYNC_ID) { + if (other.vsyncId > vsyncId) { + vsyncId = other.vsyncId; + inputEventId = other.inputEventId; + } + } else if (vsyncId == INVALID_VSYNC_ID) { + vsyncId = other.vsyncId; + inputEventId = other.inputEventId; + } +} + +void FrameTimelineInfo::clear() { + vsyncId = INVALID_VSYNC_ID; + inputEventId = IInputConstants::INVALID_INPUT_EVENT_ID; +} + +}; // namespace android diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index a8d6832275..f68f3e134e 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -68,16 +68,19 @@ public: return interface_cast(reply.readStrongBinder()); } - virtual status_t setTransactionState( - int64_t frameTimelineVsyncId, const Vector& state, - const Vector& displays, uint32_t flags, const sp& applyToken, - const InputWindowCommands& commands, int64_t desiredPresentTime, bool isAutoTimestamp, - const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, - const std::vector& listenerCallbacks, uint64_t transactionId) { + status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, + const Vector& state, + const Vector& displays, uint32_t flags, + const sp& applyToken, const InputWindowCommands& commands, + int64_t desiredPresentTime, bool isAutoTimestamp, + const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, + const std::vector& listenerCallbacks, + uint64_t transactionId) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - SAFE_PARCEL(data.writeInt64, frameTimelineVsyncId); + SAFE_PARCEL(frameTimelineInfo.write, data); + SAFE_PARCEL(data.writeUint32, static_cast(state.size())); for (const auto& s : state) { SAFE_PARCEL(s.write, data); @@ -108,15 +111,14 @@ public: return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } - virtual void bootFinished() - { + void bootFinished() override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); } - virtual status_t captureDisplay(const DisplayCaptureArgs& args, - const sp& captureListener) { + status_t captureDisplay(const DisplayCaptureArgs& args, + const sp& captureListener) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); SAFE_PARCEL(args.write, data); @@ -125,8 +127,8 @@ public: return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply); } - virtual status_t captureDisplay(uint64_t displayOrLayerStack, - const sp& captureListener) { + status_t captureDisplay(uint64_t displayOrLayerStack, + const sp& captureListener) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); SAFE_PARCEL(data.writeUint64, displayOrLayerStack); @@ -135,8 +137,8 @@ public: return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply); } - virtual status_t captureLayers(const LayerCaptureArgs& args, - const sp& captureListener) { + status_t captureLayers(const LayerCaptureArgs& args, + const sp& captureListener) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); SAFE_PARCEL(args.write, data); @@ -145,9 +147,8 @@ public: return remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply); } - virtual bool authenticateSurfaceTexture( - const sp& bufferProducer) const - { + bool authenticateSurfaceTexture( + const sp& bufferProducer) const override { Parcel data, reply; int err = NO_ERROR; err = data.writeInterfaceToken( @@ -180,8 +181,7 @@ public: return result != 0; } - virtual status_t getSupportedFrameTimestamps( - std::vector* outSupported) const { + status_t getSupportedFrameTimestamps(std::vector* outSupported) const override { if (!outSupported) { return UNEXPECTED_NULL; } @@ -224,8 +224,8 @@ public: return NO_ERROR; } - virtual sp createDisplayEventConnection( - VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) { + sp createDisplayEventConnection( + VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) override { Parcel data, reply; sp result; int err = data.writeInterfaceToken( @@ -247,8 +247,7 @@ public: return result; } - virtual sp createDisplay(const String8& displayName, bool secure) - { + sp createDisplay(const String8& displayName, bool secure) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t status = data.writeString8(displayName); @@ -272,15 +271,14 @@ public: return display; } - virtual void destroyDisplay(const sp& display) - { + void destroyDisplay(const sp& display) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply); } - virtual std::vector getPhysicalDisplayIds() const { + std::vector getPhysicalDisplayIds() const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) == @@ -297,7 +295,7 @@ public: return {}; } - virtual sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const { + sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeUint64(displayId.value); @@ -305,8 +303,7 @@ public: return reply.readStrongBinder(); } - virtual void setPowerMode(const sp& display, int mode) - { + void setPowerMode(const sp& display, int mode) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -314,7 +311,7 @@ public: remote()->transact(BnSurfaceComposer::SET_POWER_MODE, data, &reply); } - virtual status_t getDisplayState(const sp& display, ui::DisplayState* state) { + status_t getDisplayState(const sp& display, ui::DisplayState* state) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -326,7 +323,7 @@ public: return result; } - virtual status_t getDisplayInfo(const sp& display, DisplayInfo* info) { + status_t getDisplayInfo(const sp& display, DisplayInfo* info) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -336,7 +333,8 @@ public: return reply.read(*info); } - virtual status_t getDisplayConfigs(const sp& display, Vector* configs) { + status_t getDisplayConfigs(const sp& display, + Vector* configs) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -354,9 +352,7 @@ public: return result; } - virtual status_t getDisplayStats(const sp& display, - DisplayStatInfo* stats) - { + status_t getDisplayStats(const sp& display, DisplayStatInfo* stats) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -370,8 +366,7 @@ public: return result; } - virtual int getActiveConfig(const sp& display) - { + int getActiveConfig(const sp& display) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -379,8 +374,8 @@ public: return reply.readInt32(); } - virtual status_t getDisplayColorModes(const sp& display, - Vector* outColorModes) { + status_t getDisplayColorModes(const sp& display, + Vector* outColorModes) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -409,8 +404,8 @@ public: return result; } - virtual status_t getDisplayNativePrimaries(const sp& display, - ui::DisplayPrimaries& primaries) { + status_t getDisplayNativePrimaries(const sp& display, + ui::DisplayPrimaries& primaries) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -435,7 +430,7 @@ public: return result; } - virtual ColorMode getActiveColorMode(const sp& display) { + ColorMode getActiveColorMode(const sp& display) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -455,8 +450,7 @@ public: return static_cast(reply.readInt32()); } - virtual status_t setActiveColorMode(const sp& display, - ColorMode colorMode) { + status_t setActiveColorMode(const sp& display, ColorMode colorMode) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -481,8 +475,8 @@ public: return static_cast(reply.readInt32()); } - virtual status_t getAutoLowLatencyModeSupport(const sp& display, - bool* outSupport) const { + status_t getAutoLowLatencyModeSupport(const sp& display, + bool* outSupport) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t result = data.writeStrongBinder(display); @@ -499,7 +493,7 @@ public: return reply.readBool(outSupport); } - virtual void setAutoLowLatencyMode(const sp& display, bool on) { + void setAutoLowLatencyMode(const sp& display, bool on) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -524,7 +518,8 @@ public: } } - virtual status_t getGameContentTypeSupport(const sp& display, bool* outSupport) const { + status_t getGameContentTypeSupport(const sp& display, + bool* outSupport) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t result = data.writeStrongBinder(display); @@ -540,7 +535,7 @@ public: return reply.readBool(outSupport); } - virtual void setGameContentType(const sp& display, bool on) { + void setGameContentType(const sp& display, bool on) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -563,7 +558,7 @@ public: } } - virtual status_t clearAnimationFrameStats() { + status_t clearAnimationFrameStats() override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -578,7 +573,7 @@ public: return reply.readInt32(); } - virtual status_t getAnimationFrameStats(FrameStats* outStats) const { + status_t getAnimationFrameStats(FrameStats* outStats) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, data, &reply); @@ -586,8 +581,8 @@ public: return reply.readInt32(); } - virtual status_t getHdrCapabilities(const sp& display, - HdrCapabilities* outCapabilities) const { + status_t getHdrCapabilities(const sp& display, + HdrCapabilities* outCapabilities) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t result = data.writeStrongBinder(display); @@ -608,7 +603,7 @@ public: return result; } - virtual status_t enableVSyncInjections(bool enable) { + status_t enableVSyncInjections(bool enable) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -629,7 +624,7 @@ public: return result; } - virtual status_t injectVSync(nsecs_t when) { + status_t injectVSync(nsecs_t when) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -650,7 +645,7 @@ public: return result; } - virtual status_t getLayerDebugInfo(std::vector* outLayers) { + status_t getLayerDebugInfo(std::vector* outLayers) override { if (!outLayers) { return UNEXPECTED_NULL; } @@ -680,10 +675,10 @@ public: return reply.readParcelableVector(outLayers); } - virtual status_t getCompositionPreference(ui::Dataspace* defaultDataspace, - ui::PixelFormat* defaultPixelFormat, - ui::Dataspace* wideColorGamutDataspace, - ui::PixelFormat* wideColorGamutPixelFormat) const { + status_t getCompositionPreference(ui::Dataspace* defaultDataspace, + ui::PixelFormat* defaultPixelFormat, + ui::Dataspace* wideColorGamutDataspace, + ui::PixelFormat* wideColorGamutPixelFormat) const override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -703,7 +698,7 @@ public: return error; } - virtual status_t getColorManagement(bool* outGetColorManagement) const { + status_t getColorManagement(bool* outGetColorManagement) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::GET_COLOR_MANAGEMENT, data, &reply); @@ -715,10 +710,10 @@ public: return err; } - virtual status_t getDisplayedContentSamplingAttributes(const sp& display, - ui::PixelFormat* outFormat, - ui::Dataspace* outDataspace, - uint8_t* outComponentMask) const { + status_t getDisplayedContentSamplingAttributes(const sp& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) const override { if (!outFormat || !outDataspace || !outComponentMask) return BAD_VALUE; Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); @@ -752,8 +747,8 @@ public: return error; } - virtual status_t setDisplayContentSamplingEnabled(const sp& display, bool enable, - uint8_t componentMask, uint64_t maxFrames) { + status_t setDisplayContentSamplingEnabled(const sp& display, bool enable, + uint8_t componentMask, uint64_t maxFrames) override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); @@ -766,9 +761,9 @@ public: return result; } - virtual status_t getDisplayedContentSample(const sp& display, uint64_t maxFrames, - uint64_t timestamp, - DisplayedFrameStats* outStats) const { + status_t getDisplayedContentSample(const sp& display, uint64_t maxFrames, + uint64_t timestamp, + DisplayedFrameStats* outStats) const override { if (!outStats) return BAD_VALUE; Parcel data, reply; @@ -805,7 +800,7 @@ public: return result; } - virtual status_t getProtectedContentSupport(bool* outSupported) const { + status_t getProtectedContentSupport(bool* outSupported) const override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t error = @@ -817,8 +812,8 @@ public: return error; } - virtual status_t isWideColorDisplay(const sp& token, - bool* outIsWideColorDisplay) const { + status_t isWideColorDisplay(const sp& token, + bool* outIsWideColorDisplay) const override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -837,9 +832,8 @@ public: return error; } - virtual status_t addRegionSamplingListener(const Rect& samplingArea, - const sp& stopLayerHandle, - const sp& listener) { + status_t addRegionSamplingListener(const Rect& samplingArea, const sp& stopLayerHandle, + const sp& listener) override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -868,7 +862,7 @@ public: return error; } - virtual status_t removeRegionSamplingListener(const sp& listener) { + status_t removeRegionSamplingListener(const sp& listener) override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -888,12 +882,11 @@ public: return error; } - virtual status_t setDesiredDisplayConfigSpecs(const sp& displayToken, - int32_t defaultConfig, bool allowGroupSwitching, - float primaryRefreshRateMin, - float primaryRefreshRateMax, - float appRequestRefreshRateMin, - float appRequestRefreshRateMax) { + status_t setDesiredDisplayConfigSpecs(const sp& displayToken, int32_t defaultConfig, + bool allowGroupSwitching, float primaryRefreshRateMin, + float primaryRefreshRateMax, + float appRequestRefreshRateMin, + float appRequestRefreshRateMax) override { Parcel data, reply; status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (result != NO_ERROR) { @@ -947,13 +940,12 @@ public: return reply.readInt32(); } - virtual status_t getDesiredDisplayConfigSpecs(const sp& displayToken, - int32_t* outDefaultConfig, - bool* outAllowGroupSwitching, - float* outPrimaryRefreshRateMin, - float* outPrimaryRefreshRateMax, - float* outAppRequestRefreshRateMin, - float* outAppRequestRefreshRateMax) { + status_t getDesiredDisplayConfigSpecs(const sp& displayToken, + int32_t* outDefaultConfig, bool* outAllowGroupSwitching, + float* outPrimaryRefreshRateMin, + float* outPrimaryRefreshRateMax, + float* outAppRequestRefreshRateMin, + float* outAppRequestRefreshRateMax) override { if (!outDefaultConfig || !outAllowGroupSwitching || !outPrimaryRefreshRateMin || !outPrimaryRefreshRateMax || !outAppRequestRefreshRateMin || !outAppRequestRefreshRateMax) { @@ -1011,8 +1003,8 @@ public: return reply.readInt32(); } - virtual status_t getDisplayBrightnessSupport(const sp& displayToken, - bool* outSupport) const { + status_t getDisplayBrightnessSupport(const sp& displayToken, + bool* outSupport) const override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -1039,7 +1031,7 @@ public: return NO_ERROR; } - virtual status_t setDisplayBrightness(const sp& displayToken, float brightness) { + status_t setDisplayBrightness(const sp& displayToken, float brightness) override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -1064,7 +1056,7 @@ public: return NO_ERROR; } - virtual status_t notifyPowerBoost(int32_t boostId) { + status_t notifyPowerBoost(int32_t boostId) override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -1085,8 +1077,8 @@ public: return NO_ERROR; } - virtual status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, - float lightPosY, float lightPosZ, float lightRadius) { + status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, + float lightPosY, float lightPosZ, float lightRadius) override { Parcel data, reply; status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (error != NO_ERROR) { @@ -1114,8 +1106,8 @@ public: return NO_ERROR; } - virtual status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility, bool shouldBeSeamless) { + status_t setFrameRate(const sp& surface, float frameRate, + int8_t compatibility, bool shouldBeSeamless) override { Parcel data, reply; status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { @@ -1156,7 +1148,7 @@ public: return reply.readInt32(); } - virtual status_t acquireFrameRateFlexibilityToken(sp* outToken) { + status_t acquireFrameRateFlexibilityToken(sp* outToken) override { if (!outToken) return BAD_VALUE; Parcel data, reply; @@ -1191,40 +1183,34 @@ public: return NO_ERROR; } - virtual status_t setFrameTimelineVsync(const sp& surface, - int64_t frameTimelineVsyncId) { + status_t setFrameTimelineInfo(const sp& surface, + const FrameTimelineInfo& frameTimelineInfo) override { Parcel data, reply; status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { - ALOGE("setFrameTimelineVsync: failed writing interface token: %s (%d)", strerror(-err), - -err); + ALOGE("%s: failed writing interface token: %s (%d)", __func__, strerror(-err), -err); return err; } err = data.writeStrongBinder(IInterface::asBinder(surface)); if (err != NO_ERROR) { - ALOGE("setFrameTimelineVsync: failed writing strong binder: %s (%d)", strerror(-err), - -err); + ALOGE("%s: failed writing strong binder: %s (%d)", __func__, strerror(-err), -err); return err; } - err = data.writeInt64(frameTimelineVsyncId); - if (err != NO_ERROR) { - ALOGE("setFrameTimelineVsync: failed writing int64_t: %s (%d)", strerror(-err), -err); - return err; - } + SAFE_PARCEL(frameTimelineInfo.write, data); - err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_VSYNC, data, &reply); + err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_INFO, data, &reply); if (err != NO_ERROR) { - ALOGE("setFrameTimelineVsync: failed to transact: %s (%d)", strerror(-err), err); + ALOGE("%s: failed to transact: %s (%d)", __func__, strerror(-err), err); return err; } return reply.readInt32(); } - virtual status_t addTransactionTraceListener( - const sp& listener) { + status_t addTransactionTraceListener( + const sp& listener) override { Parcel data, reply; SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor()); SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener)); @@ -1235,7 +1221,7 @@ public: /** * Get priority of the RenderEngine in surface flinger. */ - virtual int getGPUContextPriority() { + int getGPUContextPriority() override { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); status_t err = @@ -1269,8 +1255,9 @@ status_t BnSurfaceComposer::onTransact( case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - int64_t frameTimelineVsyncId; - SAFE_PARCEL(data.readInt64, &frameTimelineVsyncId); + FrameTimelineInfo frameTimelineInfo; + SAFE_PARCEL(frameTimelineInfo.read, data); + uint32_t count = 0; SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize()); Vector state; @@ -1324,10 +1311,10 @@ status_t BnSurfaceComposer::onTransact( uint64_t transactionId = -1; SAFE_PARCEL(data.readUint64, &transactionId); - return setTransactionState(frameTimelineVsyncId, state, displays, stateFlags, - applyToken, inputWindowCommands, desiredPresentTime, - isAutoTimestamp, uncachedBuffer, hasListenerCallbacks, - listenerCallbacks, transactionId); + return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken, + inputWindowCommands, desiredPresentTime, isAutoTimestamp, + uncachedBuffer, hasListenerCallbacks, listenerCallbacks, + transactionId); } case BOOT_FINISHED: { CHECK_INTERFACE(ISurfaceComposer, data, reply); @@ -2078,30 +2065,26 @@ status_t BnSurfaceComposer::onTransact( } return NO_ERROR; } - case SET_FRAME_TIMELINE_VSYNC: { + case SET_FRAME_TIMELINE_INFO: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp binder; status_t err = data.readStrongBinder(&binder); if (err != NO_ERROR) { - ALOGE("setFrameTimelineVsync: failed to read strong binder: %s (%d)", - strerror(-err), -err); + ALOGE("setFrameTimelineInfo: failed to read strong binder: %s (%d)", strerror(-err), + -err); return err; } sp surface = interface_cast(binder); if (!surface) { - ALOGE("setFrameTimelineVsync: failed to cast to IGraphicBufferProducer: %s (%d)", + ALOGE("setFrameTimelineInfo: failed to cast to IGraphicBufferProducer: %s (%d)", strerror(-err), -err); return err; } - int64_t frameTimelineVsyncId; - err = data.readInt64(&frameTimelineVsyncId); - if (err != NO_ERROR) { - ALOGE("setFrameTimelineVsync: failed to read int64_t: %s (%d)", strerror(-err), - -err); - return err; - } - status_t result = setFrameTimelineVsync(surface, frameTimelineVsyncId); + FrameTimelineInfo frameTimelineInfo; + SAFE_PARCEL(frameTimelineInfo.read, data); + + status_t result = setFrameTimelineInfo(surface, frameTimelineInfo); reply->writeInt32(result); return NO_ERROR; } diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp index 180857185c..0ded9361bf 100644 --- a/libs/gui/ITransactionCompletedListener.cpp +++ b/libs/gui/ITransactionCompletedListener.cpp @@ -92,10 +92,8 @@ status_t FrameEventHistoryStats::readFromParcel(const Parcel* input) { return err; } -JankData::JankData() : - frameVsyncId(ISurfaceComposer::INVALID_VSYNC_ID), - jankType(JankType::None) { -} +JankData::JankData() + : frameVsyncId(FrameTimelineInfo::INVALID_VSYNC_ID), jankType(JankType::None) {} status_t JankData::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeInt64, frameVsyncId); diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 2946aaed37..a4b054a5ff 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -63,7 +63,7 @@ layer_state_t::layer_state_t() shouldBeSeamless(true), fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0), - frameTimelineVsyncId(ISurfaceComposer::INVALID_VSYNC_ID), + frameTimelineInfo(), autoRefresh(false) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; @@ -151,7 +151,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeBool, shouldBeSeamless); SAFE_PARCEL(output.writeUint32, fixedTransformHint); SAFE_PARCEL(output.writeUint64, frameNumber); - SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId); + SAFE_PARCEL(frameTimelineInfo.write, output); SAFE_PARCEL(output.writeBool, autoRefresh); SAFE_PARCEL(output.writeUint32, blurRegions.size()); @@ -270,7 +270,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readUint32, &tmpUint32); fixedTransformHint = static_cast(tmpUint32); SAFE_PARCEL(input.readUint64, &frameNumber); - SAFE_PARCEL(input.readInt64, &frameTimelineVsyncId); + SAFE_PARCEL(frameTimelineInfo.read, input); SAFE_PARCEL(input.readBool, &autoRefresh); uint32_t numRegions = 0; @@ -537,15 +537,9 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eFrameNumberChanged; frameNumber = other.frameNumber; } - if (other.what & eFrameTimelineVsyncChanged) { - // When merging vsync Ids we take the oldest valid one - if (frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID && - other.frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) { - frameTimelineVsyncId = std::max(frameTimelineVsyncId, other.frameTimelineVsyncId); - } else if (frameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) { - frameTimelineVsyncId = other.frameTimelineVsyncId; - } - what |= eFrameTimelineVsyncChanged; + if (other.what & eFrameTimelineInfoChanged) { + what |= eFrameTimelineInfoChanged; + frameTimelineInfo.merge(other.frameTimelineInfo); } if (other.what & eAutoRefreshChanged) { what |= eAutoRefreshChanged; diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index e82f0cc9e9..59ad8d28bd 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1496,8 +1496,8 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER: res = dispatchGetLastQueuedBuffer(args); break; - case NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC: - res = dispatchSetFrameTimelineVsync(args); + case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO: + res = dispatchSetFrameTimelineInfo(args); break; default: res = NAME_NOT_FOUND; @@ -1806,12 +1806,13 @@ int Surface::dispatchGetLastQueuedBuffer(va_list args) { return result; } -int Surface::dispatchSetFrameTimelineVsync(va_list args) { +int Surface::dispatchSetFrameTimelineInfo(va_list args) { ATRACE_CALL(); auto frameTimelineVsyncId = static_cast(va_arg(args, int64_t)); + auto inputEventId = static_cast(va_arg(args, int32_t)); - ALOGV("Surface::dispatchSetFrameTimelineVsync"); - return setFrameTimelineVsync(frameTimelineVsyncId); + ALOGV("Surface::%s", __func__); + return setFrameTimelineInfo({frameTimelineVsyncId, inputEventId}); } bool Surface::transformToDisplayInverse() { @@ -2579,9 +2580,8 @@ status_t Surface::setFrameRate(float frameRate, int8_t compatibility, bool shoul shouldBeSeamless); } -status_t Surface::setFrameTimelineVsync(int64_t frameTimelineVsyncId) { - return composerService()->setFrameTimelineVsync(mGraphicBufferProducer, - frameTimelineVsyncId); +status_t Surface::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) { + return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo); } }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 96c099be23..a1bdc033b0 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -396,7 +396,7 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mContainsBuffer(other.mContainsBuffer), mDesiredPresentTime(other.mDesiredPresentTime), mIsAutoTimestamp(other.mIsAutoTimestamp), - mFrameTimelineVsyncId(other.mFrameTimelineVsyncId), + mFrameTimelineInfo(other.mFrameTimelineInfo), mApplyToken(other.mApplyToken) { mDisplayStates = other.mDisplayStates; mComposerStates = other.mComposerStates; @@ -427,7 +427,9 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel const bool containsBuffer = parcel->readBool(); const int64_t desiredPresentTime = parcel->readInt64(); const bool isAutoTimestamp = parcel->readBool(); - const int64_t frameTimelineVsyncId = parcel->readInt64(); + FrameTimelineInfo frameTimelineInfo; + SAFE_PARCEL(frameTimelineInfo.read, *parcel); + sp applyToken; parcel->readNullableStrongBinder(&applyToken); size_t count = static_cast(parcel->readUint32()); @@ -502,7 +504,7 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel mContainsBuffer = containsBuffer; mDesiredPresentTime = desiredPresentTime; mIsAutoTimestamp = isAutoTimestamp; - mFrameTimelineVsyncId = frameTimelineVsyncId; + mFrameTimelineInfo = frameTimelineInfo; mDisplayStates = displayStates; mListenerCallbacks = listenerCallbacks; mComposerStates = composerStates; @@ -534,7 +536,7 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const parcel->writeBool(mContainsBuffer); parcel->writeInt64(mDesiredPresentTime); parcel->writeBool(mIsAutoTimestamp); - parcel->writeInt64(mFrameTimelineVsyncId); + SAFE_PARCEL(mFrameTimelineInfo.write, *parcel); parcel->writeStrongBinder(mApplyToken); parcel->writeUint32(static_cast(mDisplayStates.size())); for (auto const& displayState : mDisplayStates) { @@ -613,13 +615,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr mExplicitEarlyWakeupEnd = mExplicitEarlyWakeupEnd || other.mExplicitEarlyWakeupEnd; mApplyToken = other.mApplyToken; - // When merging vsync Ids we take the oldest one - if (mFrameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID && - other.mFrameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) { - mFrameTimelineVsyncId = std::max(mFrameTimelineVsyncId, other.mFrameTimelineVsyncId); - } else if (mFrameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) { - mFrameTimelineVsyncId = other.mFrameTimelineVsyncId; - } + mFrameTimelineInfo.merge(other.mFrameTimelineInfo); other.clear(); return *this; @@ -639,7 +635,7 @@ void SurfaceComposerClient::Transaction::clear() { mExplicitEarlyWakeupEnd = false; mDesiredPresentTime = 0; mIsAutoTimestamp = true; - mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID; + mFrameTimelineInfo.clear(); mApplyToken = nullptr; } @@ -651,9 +647,8 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { uncacheBuffer.id = cacheId; sp applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); - sf->setTransactionState(ISurfaceComposer::INVALID_VSYNC_ID, {}, {}, 0, applyToken, {}, - systemTime(), true, uncacheBuffer, false, {}, - 0 /* Undefined transactionId */); + sf->setTransactionState(FrameTimelineInfo{}, {}, {}, 0, applyToken, {}, systemTime(), true, + uncacheBuffer, false, {}, 0 /* Undefined transactionId */); } void SurfaceComposerClient::Transaction::cacheBuffers() { @@ -773,7 +768,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { ? mApplyToken : IInterface::asBinder(TransactionCompletedListener::getIInstance()); - sf->setTransactionState(mFrameTimelineVsyncId, composerStates, displayStates, flags, applyToken, + sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp, {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/, hasListenerCallbacks, listenerCallbacks, mId); @@ -1549,22 +1544,22 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync( - int64_t frameTimelineVsyncId) { - mFrameTimelineVsyncId = frameTimelineVsyncId; +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo( + const FrameTimelineInfo& frameTimelineInfo) { + mFrameTimelineInfo = frameTimelineInfo; return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync( - const sp& sc, int64_t frameTimelineVsyncId) { +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo( + const sp& sc, const FrameTimelineInfo& frameTimelineInfo) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eFrameTimelineVsyncChanged; - s->frameTimelineVsyncId = frameTimelineVsyncId; + s->what |= layer_state_t::eFrameTimelineInfoChanged; + s->frameTimelineInfo = frameTimelineInfo; return *this; } diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index 7f69bc4244..fa3efe15db 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -92,7 +92,7 @@ public: void flushShadowQueue() { mFlushShadowQueue = true; } status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); - status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId); + status_t setFrameTimelineInfo(const FrameTimelineInfo& info); virtual ~BLASTBufferQueue(); @@ -156,7 +156,7 @@ private: // This is only relevant for shared buffer mode. bool mAutoRefresh GUARDED_BY(mMutex) = false; - std::queue mNextFrameTimelineVsyncIdQueue GUARDED_BY(mMutex); + std::queue mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); // Last acquired buffer's scaling mode. This is used to check if we should update the blast // layer size immediately or wait until we get the next buffer. This will support scenarios diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h index 5587acf08f..f446dd88ed 100644 --- a/libs/gui/include/gui/DisplayEventDispatcher.h +++ b/libs/gui/include/gui/DisplayEventDispatcher.h @@ -25,7 +25,7 @@ struct VsyncEventData { // The Vsync Id corresponsing to this vsync event. This will be used to // populate ISurfaceComposer::setFrameTimelineVsync and // SurfaceComposerClient::setFrameTimelineVsync - int64_t id = ISurfaceComposer::INVALID_VSYNC_ID; + int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID; // The deadline in CLOCK_MONOTONIC that the app needs to complete its // frame by (both on the CPU and the GPU) diff --git a/libs/gui/include/gui/FrameTimelineInfo.h b/libs/gui/include/gui/FrameTimelineInfo.h new file mode 100644 index 0000000000..3b4c009609 --- /dev/null +++ b/libs/gui/include/gui/FrameTimelineInfo.h @@ -0,0 +1,43 @@ +/* + * Copyright 2021 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. + */ + +#pragma once + +#include + +#include +#include + +namespace android { + +struct FrameTimelineInfo { + // Needs to be in sync with android.graphics.FrameInfo.INVALID_VSYNC_ID in java + static constexpr int64_t INVALID_VSYNC_ID = -1; + + // The vsync id that was used to start the transaction + int64_t vsyncId = INVALID_VSYNC_ID; + + // The id of the input event that caused this buffer + int32_t inputEventId = android::os::IInputConstants::INVALID_INPUT_EVENT_ID; + + status_t write(Parcel& output) const; + status_t read(const Parcel& input); + + void merge(const FrameTimelineInfo& other); + void clear(); +}; + +} // namespace android diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 86f3c605ab..81ff6b0d8d 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -117,9 +118,6 @@ public: using EventRegistrationFlags = Flags; - // Needs to be in sync with android.graphics.FrameInfo.INVALID_VSYNC_ID in java - static constexpr int64_t INVALID_VSYNC_ID = -1; - /* * Create a connection with SurfaceFlinger. */ @@ -164,7 +162,7 @@ public: /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ virtual status_t setTransactionState( - int64_t frameTimelineVsyncId, const Vector& state, + const FrameTimelineInfo& frameTimelineInfo, const Vector& state, const Vector& displays, uint32_t flags, const sp& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, @@ -494,11 +492,11 @@ public: virtual status_t acquireFrameRateFlexibilityToken(sp* outToken) = 0; /* - * Sets the frame timeline vsync id received from choreographer that corresponds to next + * Sets the frame timeline vsync info received from choreographer that corresponds to next * buffer submitted on that surface. */ - virtual status_t setFrameTimelineVsync(const sp& surface, - int64_t frameTimelineVsyncId) = 0; + virtual status_t setFrameTimelineInfo(const sp& surface, + const FrameTimelineInfo& frameTimelineInfo) = 0; /* * Adds a TransactionTraceListener to listen for transaction tracing state updates. @@ -569,7 +567,7 @@ public: SET_GAME_CONTENT_TYPE, SET_FRAME_RATE, ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN, - SET_FRAME_TIMELINE_VSYNC, + SET_FRAME_TIMELINE_INFO, ADD_TRANSACTION_TRACE_LISTENER, GET_GPU_CONTEXT_PRIORITY, // Always append new enum to the end. diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index b1305c6607..b3b074ad2f 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -132,7 +132,7 @@ struct layer_state_t { eProducerDisconnect = 0x100'00000000, eFixedTransformHintChanged = 0x200'00000000, eFrameNumberChanged = 0x400'00000000, - eFrameTimelineVsyncChanged = 0x800'00000000, + eFrameTimelineInfoChanged = 0x800'00000000, eBlurRegionsChanged = 0x1000'00000000, eAutoRefreshChanged = 0x2000'00000000, }; @@ -238,7 +238,7 @@ struct layer_state_t { // graphics producer. uint64_t frameNumber; - int64_t frameTimelineVsyncId; + FrameTimelineInfo frameTimelineInfo; // Indicates that the consumer should acquire the next frame as soon as it // can and not wait for a frame to become available. This is only relevant diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 43b5dcd60d..b6b5c7ca5e 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -18,6 +18,7 @@ #define ANDROID_GUI_SURFACE_H #include +#include #include #include #include @@ -187,7 +188,7 @@ public: status_t getConsumerUsage(uint64_t* outUsage) const; virtual status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); - virtual status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId); + virtual status_t setFrameTimelineInfo(const FrameTimelineInfo& info); protected: virtual ~Surface(); @@ -273,7 +274,7 @@ private: int dispatchAddQueueInterceptor(va_list args); int dispatchAddQueryInterceptor(va_list args); int dispatchGetLastQueuedBuffer(va_list args); - int dispatchSetFrameTimelineVsync(va_list args); + int dispatchSetFrameTimelineInfo(va_list args); bool transformToDisplayInverse(); protected: diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 11db658de2..bed5c44110 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -385,8 +385,8 @@ public: int64_t mDesiredPresentTime = 0; bool mIsAutoTimestamp = true; - // The vsync Id provided by Choreographer.getVsyncId - int64_t mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID; + // The vsync id provided by Choreographer.getVsyncId and the input event id + FrameTimelineInfo mFrameTimelineInfo; // If not null, transactions will be queued up using this token otherwise a common token // per process will be used. @@ -546,11 +546,12 @@ public: Transaction& setFixedTransformHint(const sp& sc, int32_t transformHint); // Sets the frame timeline vsync id received from choreographer that corresponds - // to the transaction. - Transaction& setFrameTimelineVsync(int64_t frameTimelineVsyncId); + // to the transaction, and the input event id that identifies the input event that caused + // the current frame. + Transaction& setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo); // Variant that only applies to a specific SurfaceControl. - Transaction& setFrameTimelineVsync(const sp& sc, - int64_t frameTimelineVsyncId); + Transaction& setFrameTimelineInfo(const sp& sc, + const FrameTimelineInfo& frameTimelineInfo); // Indicates that the consumer should acquire the next frame as soon as it // can and not wait for a frame to become available. This is only relevant diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 63db9a7b96..3f7a5b1785 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -695,7 +695,7 @@ public: void destroyDisplay(const sp& /*display */) override {} std::vector getPhysicalDisplayIds() const override { return {}; } sp getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; } - status_t setTransactionState(int64_t /*frameTimelineVsyncId*/, + status_t setTransactionState(const FrameTimelineInfo& /*frameTimelineInfo*/, const Vector& /*state*/, const Vector& /*displays*/, uint32_t /*flags*/, const sp& /*applyToken*/, @@ -877,8 +877,8 @@ public: return NO_ERROR; } - status_t setFrameTimelineVsync(const sp& /*surface*/, - int64_t /*frameTimelineVsyncId*/) override { + status_t setFrameTimelineInfo(const sp& /*surface*/, + const FrameTimelineInfo& /*frameTimelineInfo*/) override { return NO_ERROR; } diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl index 6316b59a57..bce0ec8367 100644 --- a/libs/input/android/os/IInputConstants.aidl +++ b/libs/input/android/os/IInputConstants.aidl @@ -28,4 +28,13 @@ interface IInputConstants * to identify apps that are using this flag. */ const long BLOCK_FLAG_SLIPPERY = 157929241; + + // Indicate invalid battery capacity + const int INVALID_BATTERY_CAPACITY = -1; + + /** + * Every input event has an id. This constant value is used when a valid input event id is not + * available. + */ + const int INVALID_INPUT_EVENT_ID = 0; } diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 82d2e661b4..ffe4412b72 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -255,7 +255,7 @@ enum { NATIVE_WINDOW_ALLOCATE_BUFFERS = 45, /* private */ NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER = 46, /* private */ NATIVE_WINDOW_SET_QUERY_INTERCEPTOR = 47, /* private */ - NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC = 48, /* private */ + NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO = 48, /* private */ // clang-format on }; @@ -1023,10 +1023,11 @@ static inline int native_window_set_frame_rate(struct ANativeWindow* window, flo (int)compatibility, (int)shouldBeSeamless); } -static inline int native_window_set_frame_timeline_vsync(struct ANativeWindow* window, - int64_t frameTimelineVsyncId) { - return window->perform(window, NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC, - frameTimelineVsyncId); +static inline int native_window_set_frame_timeline_info(struct ANativeWindow* window, + int64_t frameTimelineVsyncId, + int32_t inputEventId) { + return window->perform(window, NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO, + frameTimelineVsyncId, inputEventId); } // ------------------------------------------------------------------------------------------------ diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 32e6b1098f..52197873c5 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -384,8 +384,8 @@ status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) { return NO_ERROR; } -void BufferQueueLayer::setFrameTimelineVsyncForBuffer(int64_t frameTimelineVsyncId) { - mFrameTimelineVsyncId = frameTimelineVsyncId; +void BufferQueueLayer::setFrameTimelineInfoForBuffer(const FrameTimelineInfo& frameTimelineInfo) { + mFrameTimelineInfo = frameTimelineInfo; } // ----------------------------------------------------------------------- @@ -445,9 +445,8 @@ void BufferQueueLayer::onFrameAvailable(const BufferItem& item) { } auto surfaceFrame = - mFlinger->mFrameTimeline->createSurfaceFrameForToken(mFrameTimelineVsyncId, - mOwnerPid, mOwnerUid, mName, - mName); + mFlinger->mFrameTimeline->createSurfaceFrameForToken(mFrameTimelineInfo, mOwnerPid, + mOwnerUid, mName, mName); surfaceFrame->setActualQueueTime(systemTime()); mQueueItems.push_back({item, surfaceFrame}); @@ -485,9 +484,8 @@ void BufferQueueLayer::onFrameReplaced(const BufferItem& item) { } auto surfaceFrame = - mFlinger->mFrameTimeline->createSurfaceFrameForToken(mFrameTimelineVsyncId, - mOwnerPid, mOwnerUid, mName, - mName); + mFlinger->mFrameTimeline->createSurfaceFrameForToken(mFrameTimelineInfo, mOwnerPid, + mOwnerUid, mName, mName); surfaceFrame->setActualQueueTime(systemTime()); mQueueItems[mQueueItems.size() - 1].item = item; mQueueItems[mQueueItems.size() - 1].surfaceFrame = std::move(surfaceFrame); diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index 0e8fdbe092..41ff01262e 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -101,7 +101,7 @@ private: status_t updateActiveBuffer() override; status_t updateFrameNumber(nsecs_t latchTime) override; - void setFrameTimelineVsyncForBuffer(int64_t frameTimelineVsyncId) override; + void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& frameTimelineInfo) override; sp createClone() override; @@ -145,10 +145,10 @@ private: sp mContentsChangedListener; - // The last vsync id received on this layer. This will be used when we get + // The last vsync info received on this layer. This will be used when we get // a buffer to correlate the buffer with the vsync id. Can only be accessed // with the SF state lock held. - std::optional mFrameTimelineVsyncId; + FrameTimelineInfo mFrameTimelineInfo; // Keeps track of the time SF latched the last buffer from this layer. // Used in buffer stuffing analysis in FrameTimeline. diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp index 17d1f3bff7..3743716876 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp @@ -275,13 +275,15 @@ int64_t TraceCookieCounter::getCookieForTracing() { return ++mTraceCookie; } -SurfaceFrame::SurfaceFrame(int64_t token, pid_t ownerPid, uid_t ownerUid, std::string layerName, - std::string debugName, PredictionState predictionState, +SurfaceFrame::SurfaceFrame(const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, + uid_t ownerUid, std::string layerName, std::string debugName, + PredictionState predictionState, frametimeline::TimelineItem&& predictions, std::shared_ptr timeStats, JankClassificationThresholds thresholds, TraceCookieCounter* traceCookieCounter) - : mToken(token), + : mToken(frameTimelineInfo.vsyncId), + mInputEventId(frameTimelineInfo.inputEventId), mOwnerPid(ownerPid), mOwnerUid(ownerUid), mLayerName(std::move(layerName)), @@ -295,27 +297,27 @@ SurfaceFrame::SurfaceFrame(int64_t token, pid_t ownerPid, uid_t ownerUid, std::s mTraceCookieCounter(*traceCookieCounter) {} void SurfaceFrame::setActualStartTime(nsecs_t actualStartTime) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mActuals.startTime = actualStartTime; } void SurfaceFrame::setActualQueueTime(nsecs_t actualQueueTime) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mActualQueueTime = actualQueueTime; } void SurfaceFrame::setAcquireFenceTime(nsecs_t acquireFenceTime) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mActuals.endTime = std::max(acquireFenceTime, mActualQueueTime); } void SurfaceFrame::setPresentState(PresentState presentState, nsecs_t lastLatchTime) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mPresentState = presentState; mLastLatchTime = lastLatchTime; } std::optional SurfaceFrame::getJankType() const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); if (mActuals.presentTime == 0) { return std::nullopt; } @@ -323,32 +325,32 @@ std::optional SurfaceFrame::getJankType() const { } nsecs_t SurfaceFrame::getBaseTime() const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); return getMinTime(mPredictionState, mPredictions, mActuals); } TimelineItem SurfaceFrame::getActuals() const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); return mActuals; } SurfaceFrame::PresentState SurfaceFrame::getPresentState() const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); return mPresentState; } FramePresentMetadata SurfaceFrame::getFramePresentMetadata() const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); return mFramePresentMetadata; } FrameReadyMetadata SurfaceFrame::getFrameReadyMetadata() const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); return mFrameReadyMetadata; } void SurfaceFrame::dump(std::string& result, const std::string& indent, nsecs_t baseTime) const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); StringAppendF(&result, "%s", indent.c_str()); StringAppendF(&result, "Layer - %s", mDebugName.c_str()); if (mJankType != JankType::None) { @@ -387,7 +389,7 @@ void SurfaceFrame::dump(std::string& result, const std::string& indent, nsecs_t void SurfaceFrame::onPresent(nsecs_t presentTime, int32_t displayFrameJankType, nsecs_t vsyncPeriod) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); if (mPresentState != PresentState::Presented) { // No need to update dropped buffers return; @@ -479,6 +481,9 @@ void SurfaceFrame::onPresent(nsecs_t presentTime, int32_t displayFrameJankType, mTimeStats->incrementJankyFrames(mOwnerUid, mLayerName, mJankType); } +/** + * TODO(b/178637512): add inputEventId to the perfetto trace. + */ void SurfaceFrame::trace(int64_t displayFrameToken) { using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource; @@ -486,12 +491,12 @@ void SurfaceFrame::trace(int64_t displayFrameToken) { bool missingToken = false; // Expected timeline start FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) { - std::lock_guard lock(mMutex); - if (mToken == ISurfaceComposer::INVALID_VSYNC_ID) { + std::scoped_lock lock(mMutex); + if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) { ALOGD("Cannot trace SurfaceFrame - %s with invalid token", mLayerName.c_str()); missingToken = true; return; - } else if (displayFrameToken == ISurfaceComposer::INVALID_VSYNC_ID) { + } else if (displayFrameToken == FrameTimelineInfo::INVALID_VSYNC_ID) { ALOGD("Cannot trace SurfaceFrame - %s with invalid displayFrameToken", mLayerName.c_str()); missingToken = true; @@ -521,7 +526,7 @@ void SurfaceFrame::trace(int64_t displayFrameToken) { // Expected timeline end FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); auto packet = ctx.NewTracePacket(); packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC); packet->set_timestamp(static_cast(mPredictions.endTime)); @@ -535,7 +540,7 @@ void SurfaceFrame::trace(int64_t displayFrameToken) { int64_t actualTimelineCookie = mTraceCookieCounter.getCookieForTracing(); // Actual timeline start FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); auto packet = ctx.NewTracePacket(); packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC); // Actual start time is not yet available, so use expected start instead @@ -566,7 +571,7 @@ void SurfaceFrame::trace(int64_t displayFrameToken) { }); // Actual timeline end FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); auto packet = ctx.NewTracePacket(); packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC); packet->set_timestamp(static_cast(mActuals.endTime)); @@ -582,7 +587,7 @@ namespace impl { int64_t TokenManager::generateTokenForPredictions(TimelineItem&& predictions) { ATRACE_CALL(); - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); const int64_t assignedToken = mCurrentToken++; mPredictions[assignedToken] = {systemTime(), predictions}; flushTokens(systemTime()); @@ -590,7 +595,7 @@ int64_t TokenManager::generateTokenForPredictions(TimelineItem&& predictions) { } std::optional TokenManager::getPredictionsForToken(int64_t token) const { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); auto predictionsIterator = mPredictions.find(token); if (predictionsIterator != mPredictions.end()) { return predictionsIterator->second.predictions; @@ -634,26 +639,28 @@ void FrameTimeline::registerDataSource() { } std::shared_ptr FrameTimeline::createSurfaceFrameForToken( - std::optional token, pid_t ownerPid, uid_t ownerUid, std::string layerName, - std::string debugName) { + const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, + std::string layerName, std::string debugName) { ATRACE_CALL(); - if (!token) { - return std::make_shared(ISurfaceComposer::INVALID_VSYNC_ID, ownerPid, - ownerUid, std::move(layerName), std::move(debugName), + if (frameTimelineInfo.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { + return std::make_shared(frameTimelineInfo, ownerPid, ownerUid, + std::move(layerName), std::move(debugName), PredictionState::None, TimelineItem(), mTimeStats, mJankClassificationThresholds, &mTraceCookieCounter); } - std::optional predictions = mTokenManager.getPredictionsForToken(*token); + std::optional predictions = + mTokenManager.getPredictionsForToken(frameTimelineInfo.vsyncId); if (predictions) { - return std::make_shared(*token, ownerPid, ownerUid, std::move(layerName), - std::move(debugName), PredictionState::Valid, - std::move(*predictions), mTimeStats, - mJankClassificationThresholds, &mTraceCookieCounter); - } - return std::make_shared(*token, ownerPid, ownerUid, std::move(layerName), - std::move(debugName), PredictionState::Expired, - TimelineItem(), mTimeStats, mJankClassificationThresholds, - &mTraceCookieCounter); + return std::make_shared(frameTimelineInfo, ownerPid, ownerUid, + std::move(layerName), std::move(debugName), + PredictionState::Valid, std::move(*predictions), + mTimeStats, mJankClassificationThresholds, + &mTraceCookieCounter); + } + return std::make_shared(frameTimelineInfo, ownerPid, ownerUid, + std::move(layerName), std::move(debugName), + PredictionState::Expired, TimelineItem(), mTimeStats, + mJankClassificationThresholds, &mTraceCookieCounter); } FrameTimeline::DisplayFrame::DisplayFrame(std::shared_ptr timeStats, @@ -669,13 +676,13 @@ FrameTimeline::DisplayFrame::DisplayFrame(std::shared_ptr timeStats, void FrameTimeline::addSurfaceFrame(std::shared_ptr surfaceFrame) { ATRACE_CALL(); - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mCurrentDisplayFrame->addSurfaceFrame(surfaceFrame); } void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, nsecs_t vsyncPeriod) { ATRACE_CALL(); - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mCurrentDisplayFrame->onSfWakeUp(token, vsyncPeriod, mTokenManager.getPredictionsForToken(token), wakeUpTime); } @@ -683,7 +690,7 @@ void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, nsecs_t vsync void FrameTimeline::setSfPresent(nsecs_t sfPresentTime, const std::shared_ptr& presentFence) { ATRACE_CALL(); - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); mCurrentDisplayFrame->setActualEndTime(sfPresentTime); mPendingPresentFences.emplace_back(std::make_pair(presentFence, mCurrentDisplayFrame)); flushPendingPresentFences(); @@ -826,7 +833,7 @@ void FrameTimeline::DisplayFrame::trace(pid_t surfaceFlingerPid) const { // Expected timeline start FrameTimelineDataSource::Trace([&](FrameTimelineDataSource::TraceContext ctx) { auto packet = ctx.NewTracePacket(); - if (mToken == ISurfaceComposer::INVALID_VSYNC_ID) { + if (mToken == FrameTimelineInfo::INVALID_VSYNC_ID) { ALOGD("Cannot trace DisplayFrame with invalid token"); missingToken = true; return; @@ -999,7 +1006,7 @@ void FrameTimeline::DisplayFrame::dump(std::string& result, nsecs_t baseTime) co } void FrameTimeline::dumpAll(std::string& result) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); StringAppendF(&result, "Number of display frames : %d\n", (int)mDisplayFrames.size()); nsecs_t baseTime = (mDisplayFrames.empty()) ? 0 : mDisplayFrames[0]->getBaseTime(); for (size_t i = 0; i < mDisplayFrames.size(); i++) { @@ -1009,7 +1016,7 @@ void FrameTimeline::dumpAll(std::string& result) { } void FrameTimeline::dumpJank(std::string& result) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); nsecs_t baseTime = (mDisplayFrames.empty()) ? 0 : mDisplayFrames[0]->getBaseTime(); for (size_t i = 0; i < mDisplayFrames.size(); i++) { mDisplayFrames[i]->dumpJank(result, baseTime, static_cast(i)); @@ -1031,7 +1038,7 @@ void FrameTimeline::parseArgs(const Vector& args, std::string& result) } void FrameTimeline::setMaxDisplayFrames(uint32_t size) { - std::lock_guard lock(mMutex); + std::scoped_lock lock(mMutex); // The size can either increase or decrease, clear everything, to be consistent mDisplayFrames.clear(); diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h index ed38cc6375..54e8efbc92 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h @@ -154,10 +154,10 @@ public: // Only FrameTimeline can construct a SurfaceFrame as it provides Predictions(through // TokenManager), Thresholds and TimeStats pointer. - SurfaceFrame(int64_t token, pid_t ownerPid, uid_t ownerUid, std::string layerName, - std::string debugName, PredictionState predictionState, TimelineItem&& predictions, - std::shared_ptr timeStats, JankClassificationThresholds thresholds, - TraceCookieCounter* traceCookieCounter); + SurfaceFrame(const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, + std::string layerName, std::string debugName, PredictionState predictionState, + TimelineItem&& predictions, std::shared_ptr timeStats, + JankClassificationThresholds thresholds, TraceCookieCounter* traceCookieCounter); ~SurfaceFrame() = default; // Returns std::nullopt if the frame hasn't been classified yet. @@ -166,6 +166,7 @@ public: // Functions called by SF int64_t getToken() const { return mToken; }; + int32_t getInputEventId() const { return mInputEventId; }; TimelineItem getPredictions() const { return mPredictions; }; // Actual timestamps of the app are set individually at different functions. // Start time (if the app provides) and Queue time are accessible after queueing the frame, @@ -198,6 +199,7 @@ public: private: const int64_t mToken; + const int32_t mInputEventId; const pid_t mOwnerPid; const uid_t mOwnerUid; const std::string mLayerName; @@ -243,10 +245,9 @@ public: // Create a new surface frame, set the predictions based on a token and return it to the caller. // Debug name is the human-readable debugging string for dumpsys. - virtual std::shared_ptr createSurfaceFrameForToken(std::optional token, - pid_t ownerPid, uid_t ownerUid, - std::string layerName, - std::string debugName) = 0; + virtual std::shared_ptr createSurfaceFrameForToken( + const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, + std::string layerName, std::string debugName) = 0; // Adds a new SurfaceFrame to the current DisplayFrame. Frames from multiple layers can be // composited into one display frame. @@ -279,7 +280,7 @@ namespace impl { class TokenManager : public android::frametimeline::TokenManager { public: - TokenManager() : mCurrentToken(ISurfaceComposer::INVALID_VSYNC_ID + 1) {} + TokenManager() : mCurrentToken(FrameTimelineInfo::INVALID_VSYNC_ID + 1) {} ~TokenManager() = default; int64_t generateTokenForPredictions(TimelineItem&& predictions) override; @@ -353,7 +354,7 @@ public: private: void dump(std::string& result, nsecs_t baseTime) const; - int64_t mToken = ISurfaceComposer::INVALID_VSYNC_ID; + int64_t mToken = FrameTimelineInfo::INVALID_VSYNC_ID; /* Usage of TimelineItem w.r.t SurfaceFlinger * startTime Time when SurfaceFlinger wakes up to handle transactions and buffer updates @@ -393,10 +394,9 @@ public: ~FrameTimeline() = default; frametimeline::TokenManager* getTokenManager() override { return &mTokenManager; } - std::shared_ptr createSurfaceFrameForToken(std::optional token, - pid_t ownerPid, uid_t ownerUid, - std::string layerName, - std::string debugName) override; + std::shared_ptr createSurfaceFrameForToken( + const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, + std::string layerName, std::string debugName) override; void addSurfaceFrame(std::shared_ptr surfaceFrame) override; void setSfWakeUp(int64_t token, nsecs_t wakeupTime, nsecs_t vsyncPeriod) override; void setSfPresent(nsecs_t sfPresentTime, diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 177a81a7bc..f6440d3843 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -129,7 +129,7 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.shadowRadius = 0.f; mCurrentState.treeHasFrameRateVote = false; mCurrentState.fixedTransformHint = ui::Transform::ROT_INVALID; - mCurrentState.frameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID; + mCurrentState.frameTimelineInfo = {}; mCurrentState.postTime = -1; if (args.flags & ISurfaceComposerClient::eNoColorFill) { @@ -907,14 +907,10 @@ bool Layer::applyPendingStates(State* stateToCommit) { } if (stateUpdateAvailable) { - const auto vsyncId = - stateToCommit->frameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID - ? std::nullopt - : std::make_optional(stateToCommit->frameTimelineVsyncId); - mSurfaceFrame = - mFlinger->mFrameTimeline->createSurfaceFrameForToken(vsyncId, mOwnerPid, mOwnerUid, - mName, mTransactionName); + mFlinger->mFrameTimeline + ->createSurfaceFrameForToken(stateToCommit->frameTimelineInfo, mOwnerPid, + mOwnerUid, mName, mTransactionName); mSurfaceFrame->setActualQueueTime(stateToCommit->postTime); // For transactions we set the acquire fence time to the post time as we // don't have a buffer. For BufferStateLayer it is overridden in @@ -1491,8 +1487,8 @@ bool Layer::setFrameRate(FrameRate frameRate) { return true; } -void Layer::setFrameTimelineVsyncForTransaction(int64_t frameTimelineVsyncId, nsecs_t postTime) { - mCurrentState.frameTimelineVsyncId = frameTimelineVsyncId; +void Layer::setFrameTimelineInfoForTransaction(const FrameTimelineInfo& info, nsecs_t postTime) { + mCurrentState.frameTimelineInfo = info; mCurrentState.postTime = postTime; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 357c4a4dee..0660a4a998 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -304,8 +304,8 @@ public: // a fixed transform hint is not set. ui::Transform::RotationFlags fixedTransformHint; - // The vsync id that was used to start the transaction - int64_t frameTimelineVsyncId; + // The vsync info that was used to start the transaction + FrameTimelineInfo frameTimelineInfo; // When the transaction was posted nsecs_t postTime; @@ -869,8 +869,9 @@ public: bool setFrameRate(FrameRate); - virtual void setFrameTimelineVsyncForBuffer(int64_t /*frameTimelineVsyncId*/) {} - void setFrameTimelineVsyncForTransaction(int64_t frameTimelineVsyncId, nsecs_t postTime); + virtual void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {} + void setFrameTimelineInfoForTransaction(const FrameTimelineInfo& frameTimelineInfo, + nsecs_t postTime); // Creates a new handle each time, so we only expect // this to be called once. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 27df232472..8d448e0910 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3287,7 +3287,7 @@ bool SurfaceFlinger::flushTransactionQueues() { break; } transactions.push_back(transaction); - applyTransactionState(transaction.frameTimelineVsyncId, transaction.states, + applyTransactionState(transaction.frameTimelineInfo, transaction.states, transaction.displays, transaction.flags, mPendingInputWindowCommands, transaction.desiredPresentTime, transaction.isAutoTimestamp, transaction.buffer, @@ -3367,7 +3367,7 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t } status_t SurfaceFlinger::setTransactionState( - int64_t frameTimelineVsyncId, const Vector& states, + const FrameTimelineInfo& frameTimelineInfo, const Vector& states, const Vector& displays, uint32_t flags, const sp& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, @@ -3420,7 +3420,7 @@ status_t SurfaceFlinger::setTransactionState( // if the transaction contains a buffer. if (!transactionIsReadyToBeApplied(isAutoTimestamp, desiredPresentTime, states, true) || pendingTransactions) { - mTransactionQueues[applyToken].emplace(frameTimelineVsyncId, states, displays, flags, + mTransactionQueues[applyToken].emplace(frameTimelineInfo, states, displays, flags, desiredPresentTime, isAutoTimestamp, uncacheBuffer, postTime, privileged, hasListenerCallbacks, listenerCallbacks, originPid, originUid, @@ -3429,7 +3429,7 @@ status_t SurfaceFlinger::setTransactionState( return NO_ERROR; } - applyTransactionState(frameTimelineVsyncId, states, displays, flags, inputWindowCommands, + applyTransactionState(frameTimelineInfo, states, displays, flags, inputWindowCommands, desiredPresentTime, isAutoTimestamp, uncacheBuffer, postTime, privileged, hasListenerCallbacks, listenerCallbacks, originPid, originUid, transactionId, /*isMainThread*/ false); @@ -3437,7 +3437,7 @@ status_t SurfaceFlinger::setTransactionState( } void SurfaceFlinger::applyTransactionState( - int64_t frameTimelineVsyncId, const Vector& states, + const FrameTimelineInfo& frameTimelineInfo, const Vector& states, const Vector& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, const int64_t postTime, @@ -3478,9 +3478,9 @@ void SurfaceFlinger::applyTransactionState( uint32_t clientStateFlags = 0; for (const ComposerState& state : states) { clientStateFlags |= - setClientStateLocked(frameTimelineVsyncId, state, desiredPresentTime, - isAutoTimestamp, postTime, privileged, - listenerCallbacksWithSurfaces, originPid, originUid); + setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp, + postTime, privileged, listenerCallbacksWithSurfaces, originPid, + originUid); if ((flags & eAnimation) && state.state.surface) { if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) { mScheduler->recordLayerHistory(layer.get(), @@ -3658,7 +3658,7 @@ bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermis } uint32_t SurfaceFlinger::setClientStateLocked( - int64_t frameTimelineVsyncId, const ComposerState& composerState, + const FrameTimelineInfo& frameTimelineInfo, const ComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, bool privileged, std::unordered_set& listenerCallbacks, int originPid, int originUid) { @@ -3916,10 +3916,10 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded; } } - if (what & layer_state_t::eFrameTimelineVsyncChanged) { - layer->setFrameTimelineVsyncForTransaction(s.frameTimelineVsyncId, postTime); - } else if (frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) { - layer->setFrameTimelineVsyncForTransaction(frameTimelineVsyncId, postTime); + if (what & layer_state_t::eFrameTimelineInfoChanged) { + layer->setFrameTimelineInfoForTransaction(s.frameTimelineInfo, postTime); + } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { + layer->setFrameTimelineInfoForTransaction(frameTimelineInfo, postTime); } if (what & layer_state_t::eFixedTransformHintChanged) { if (layer->setFixedTransformHint(s.fixedTransformHint)) { @@ -4255,7 +4255,7 @@ void SurfaceFlinger::onInitializeDisplays() { d.width = 0; d.height = 0; displays.add(d); - setTransactionState(ISurfaceComposer::INVALID_VSYNC_ID, state, displays, 0, nullptr, + setTransactionState(FrameTimelineInfo{}, state, displays, 0, nullptr, mPendingInputWindowCommands, systemTime(), true, {}, false, {}, 0 /* Undefined transactionId */); @@ -5006,7 +5006,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case CAPTURE_LAYERS: case CAPTURE_DISPLAY: case SET_DISPLAY_BRIGHTNESS: - case SET_FRAME_TIMELINE_VSYNC: + case SET_FRAME_TIMELINE_INFO: // This is not sensitive information, so should not require permission control. case GET_GPU_CONTEXT_PRIORITY: { return OK; @@ -6374,21 +6374,21 @@ void SurfaceFlinger::onFrameRateFlexibilityTokenReleased() { })); } -status_t SurfaceFlinger::setFrameTimelineVsync(const sp& surface, - int64_t frameTimelineVsyncId) { +status_t SurfaceFlinger::setFrameTimelineInfo(const sp& surface, + const FrameTimelineInfo& frameTimelineInfo) { Mutex::Autolock lock(mStateLock); if (!authenticateSurfaceTextureLocked(surface)) { - ALOGE("Attempt to set frame timeline vsync on an unrecognized IGraphicBufferProducer"); + ALOGE("Attempt to set frame timeline info on an unrecognized IGraphicBufferProducer"); return BAD_VALUE; } sp layer = (static_cast(surface.get()))->getLayer(); if (layer == nullptr) { - ALOGE("Attempt to set frame timeline vsync on a layer that no longer exists"); + ALOGE("Attempt to set frame timeline info on a layer that no longer exists"); return BAD_VALUE; } - layer->setFrameTimelineVsyncForBuffer(frameTimelineVsyncId); + layer->setFrameTimelineInfoForBuffer(frameTimelineInfo); return NO_ERROR; } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 50d6099698..323ed40e36 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -343,7 +343,7 @@ protected: virtual ~SurfaceFlinger(); virtual uint32_t setClientStateLocked( - int64_t frameTimelineVsyncId, const ComposerState& composerState, + const FrameTimelineInfo& info, const ComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, bool privileged, std::unordered_set& listenerCallbacks, int originPid, int originUid) REQUIRES(mStateLock); @@ -435,14 +435,15 @@ private: }; struct TransactionState { - TransactionState(int64_t frameTimelineVsyncId, const Vector& composerStates, + TransactionState(const FrameTimelineInfo& frameTimelineInfo, + const Vector& composerStates, const Vector& displayStates, uint32_t transactionFlags, int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, int64_t postTime, bool privileged, bool hasListenerCallbacks, std::vector listenerCallbacks, int originPid, int originUid, uint64_t transactionId) - : frameTimelineVsyncId(frameTimelineVsyncId), + : frameTimelineInfo(frameTimelineInfo), states(composerStates), displays(displayStates), flags(transactionFlags), @@ -457,7 +458,7 @@ private: originUid(originUid), id(transactionId) {} - int64_t frameTimelineVsyncId; + FrameTimelineInfo frameTimelineInfo; Vector states; Vector displays; uint32_t flags; @@ -522,7 +523,8 @@ private: void destroyDisplay(const sp& displayToken) override; std::vector getPhysicalDisplayIds() const override; sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const override; - status_t setTransactionState(int64_t frameTimelineVsyncId, const Vector& state, + status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, + const Vector& state, const Vector& displays, uint32_t flags, const sp& applyToken, const InputWindowCommands& inputWindowCommands, @@ -608,8 +610,8 @@ private: int8_t compatibility, bool shouldBeSeamless) override; status_t acquireFrameRateFlexibilityToken(sp* outToken) override; - status_t setFrameTimelineVsync(const sp& surface, - int64_t frameTimelineVsyncId) override; + status_t setFrameTimelineInfo(const sp& surface, + const FrameTimelineInfo& frameTimelineInfo) override; status_t addTransactionTraceListener( const sp& listener) override; @@ -727,7 +729,7 @@ private: /* * Transactions */ - void applyTransactionState(int64_t frameTimelineVsyncId, const Vector& state, + void applyTransactionState(const FrameTimelineInfo& info, const Vector& state, const Vector& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, diff --git a/services/surfaceflinger/tests/LayerState_test.cpp b/services/surfaceflinger/tests/LayerState_test.cpp index 93d5f2f8ec..80dbd1b889 100644 --- a/services/surfaceflinger/tests/LayerState_test.cpp +++ b/services/surfaceflinger/tests/LayerState_test.cpp @@ -106,5 +106,34 @@ TEST(LayerStateTest, ParcellingScreenCaptureResults) { ASSERT_EQ(results.result, results2.result); } +/** + * Parcel a layer_state_t struct, and then unparcel. Ensure that the object that was parceled + * matches the object that's unparceled. + */ +TEST(LayerStateTest, ParcelUnparcelLayerStateT) { + layer_state_t input; + input.frameTimelineInfo.vsyncId = 1; + input.frameTimelineInfo.inputEventId = 2; + Parcel p; + input.write(p); + layer_state_t output; + p.setDataPosition(0); + output.read(p); + ASSERT_EQ(input.frameTimelineInfo.vsyncId, output.frameTimelineInfo.vsyncId); + ASSERT_EQ(input.frameTimelineInfo.inputEventId, output.frameTimelineInfo.inputEventId); +} + +TEST(LayerStateTest, LayerStateMerge_SelectsValidInputEvent) { + layer_state_t layer1; + layer1.frameTimelineInfo.inputEventId = android::os::IInputConstants::INVALID_INPUT_EVENT_ID; + layer_state_t layer2; + layer2.frameTimelineInfo.inputEventId = 1; + layer2.what |= layer_state_t::eFrameTimelineInfoChanged; + + layer1.merge(layer2); + + ASSERT_EQ(1, layer1.frameTimelineInfo.inputEventId); +} + } // namespace test } // namespace android diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp index e2584e266d..6e9f09bdaa 100644 --- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp @@ -14,9 +14,6 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wextra" #include "gmock/gmock-spec-builders.h" #include "mock/MockTimeStats.h" @@ -177,16 +174,17 @@ static const std::string sLayerNameTwo = "layer2"; static constexpr const uid_t sUidOne = 0; static constexpr pid_t sPidOne = 10; static constexpr pid_t sPidTwo = 20; +static constexpr int32_t sInputEventId = 5; TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); - EXPECT_EQ(getPredictions().size(), 1); + EXPECT_EQ(getPredictions().size(), 1u); flushTokens(systemTime() + maxTokenRetentionTime); int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30}); std::optional predictions = mTokenManager->getPredictionsForToken(token1); // token1 should have expired - EXPECT_EQ(getPredictions().size(), 1); + EXPECT_EQ(getPredictions().size(), 1u); EXPECT_EQ(predictions.has_value(), false); predictions = mTokenManager->getPredictionsForToken(token2); @@ -194,16 +192,16 @@ TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { } TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) { - auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne, + auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne, sLayerNameOne); - auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidTwo, sUidOne, + auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerNameOne, sLayerNameOne); EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne); EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo); } TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) { - auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne, + auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne, sLayerNameOne); EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None); } @@ -211,21 +209,33 @@ TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) { TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); flushTokens(systemTime() + maxTokenRetentionTime); - auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + auto surfaceFrame = + mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne, + sLayerNameOne, sLayerNameOne); EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired); } TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) { int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30}); - auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + auto surfaceFrame = + mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne, + sLayerNameOne, sLayerNameOne); EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid); EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true); } +TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) { + int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30}); + constexpr int32_t inputEventId = 1; + auto surfaceFrame = + mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne, + sLayerNameOne, sLayerNameOne); + + EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId()); +} + TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) { // Global increment EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)); @@ -234,8 +244,9 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) { int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30}); int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60}); - auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + auto surfaceFrame1 = + mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne, + sLayerNameOne, sLayerNameOne); // Set up the display frame mFrameTimeline->setSfWakeUp(token1, 20, 11); @@ -264,11 +275,11 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) { int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30}); int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); auto surfaceFrame2 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameTwo, sLayerNameTwo); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameTwo, sLayerNameTwo); mFrameTimeline->setSfWakeUp(sfToken1, 22, 11); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); mFrameTimeline->addSurfaceFrame(surfaceFrame1); @@ -288,8 +299,8 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) { // Trigger a flush by finalizing the next DisplayFrame auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto surfaceFrame3 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); mFrameTimeline->setSfWakeUp(sfToken2, 52, 11); surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Dropped); mFrameTimeline->addSurfaceFrame(surfaceFrame3); @@ -320,8 +331,9 @@ TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) { int64_t sfToken = mTokenManager->generateTokenForPredictions( {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor}); auto surfaceFrame = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, + sPidOne, sUidOne, sLayerNameOne, + sLayerNameOne); mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, 11); surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented); mFrameTimeline->addSurfaceFrame(surfaceFrame); @@ -341,8 +353,8 @@ TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) { int64_t sfToken = mTokenManager->generateTokenForPredictions( {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor}); auto surfaceFrame = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, 11); surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented); mFrameTimeline->addSurfaceFrame(surfaceFrame); @@ -356,18 +368,18 @@ TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) { } TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) { - auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, 0, - "acquireFenceAfterQueue", - "acquireFenceAfterQueue"); + auto surfaceFrame = + mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue", + "acquireFenceAfterQueue"); surfaceFrame->setActualQueueTime(123); surfaceFrame->setAcquireFenceTime(456); EXPECT_EQ(surfaceFrame->getActuals().endTime, 456); } TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) { - auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, 0, - "acquireFenceAfterQueue", - "acquireFenceAfterQueue"); + auto surfaceFrame = + mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue", + "acquireFenceAfterQueue"); surfaceFrame->setActualQueueTime(456); surfaceFrame->setAcquireFenceTime(123); EXPECT_EQ(surfaceFrame->getActuals().endTime, 456); @@ -383,8 +395,8 @@ TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) { // Size shouldn't exceed maxDisplayFrames - 64 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) { auto surfaceFrame = - mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne, + sLayerNameOne); int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30}); mFrameTimeline->setSfWakeUp(sfToken, 22, 11); surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented); @@ -395,15 +407,15 @@ TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) { // Increase the size to 256 mFrameTimeline->setMaxDisplayFrames(256); - EXPECT_EQ(*maxDisplayFrames, 256); + EXPECT_EQ(*maxDisplayFrames, 256u); // Global increment EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)) .Times(static_cast(*maxDisplayFrames + 10)); for (size_t i = 0; i < *maxDisplayFrames + 10; i++) { auto surfaceFrame = - mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne, + sLayerNameOne); int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30}); mFrameTimeline->setSfWakeUp(sfToken, 22, 11); surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented); @@ -414,15 +426,15 @@ TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) { // Shrink the size to 128 mFrameTimeline->setMaxDisplayFrames(128); - EXPECT_EQ(*maxDisplayFrames, 128); + EXPECT_EQ(*maxDisplayFrames, 128u); // Global increment EXPECT_CALL(*mTimeStats, incrementJankyFrames(testing::_)) .Times(static_cast(*maxDisplayFrames + 10)); for (size_t i = 0; i < *maxDisplayFrames + 10; i++) { auto surfaceFrame = - mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne, + sLayerNameOne); int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30}); mFrameTimeline->setSfWakeUp(sfToken, 22, 11); surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented); @@ -449,8 +461,8 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) { std::chrono::duration_cast(56ms).count(), std::chrono::duration_cast(60ms).count()}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::duration_cast(52ms).count(), 11); @@ -478,8 +490,8 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) { std::chrono::duration_cast(56ms).count(), std::chrono::duration_cast(60ms).count()}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::duration_cast(52ms).count(), 30); @@ -507,8 +519,8 @@ TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) { std::chrono::duration_cast(86ms).count(), std::chrono::duration_cast(90ms).count()}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setAcquireFenceTime( std::chrono::duration_cast(45ms).count()); mFrameTimeline->setSfWakeUp(sfToken1, @@ -542,8 +554,9 @@ TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) { int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30}); int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60}); - auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + auto surfaceFrame1 = + mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne, + sLayerNameOne, sLayerNameOne); // Set up the display frame mFrameTimeline->setSfWakeUp(token1, 20, 11); @@ -558,7 +571,7 @@ TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) { mFrameTimeline->setSfPresent(55, presentFence2); auto packets = readFrameTimelinePacketsBlocking(tracingSession.get()); - EXPECT_EQ(packets.size(), 0); + EXPECT_EQ(packets.size(), 0u); } TEST_F(FrameTimelineTest, tracing_sanityTest) { @@ -573,8 +586,9 @@ TEST_F(FrameTimelineTest, tracing_sanityTest) { tracingSession->StartBlocking(); int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30}); int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60}); - auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(token1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + auto surfaceFrame1 = + mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne, + sLayerNameOne, sLayerNameOne); // Set up the display frame mFrameTimeline->setSfWakeUp(token2, 20, 11); @@ -594,7 +608,7 @@ TEST_F(FrameTimelineTest, tracing_sanityTest) { auto packets = readFrameTimelinePacketsBlocking(tracingSession.get()); // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame. - EXPECT_EQ(packets.size(), 8); + EXPECT_EQ(packets.size(), 8u); } TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) { @@ -622,7 +636,7 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) tracingSession->StopBlocking(); auto packets = readFrameTimelinePacketsBlocking(tracingSession.get()); - EXPECT_EQ(packets.size(), 0); + EXPECT_EQ(packets.size(), 0u); } TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) { @@ -635,7 +649,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) tracingSession->StartBlocking(); int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30}); int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60}); - auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken(std::nullopt, sPidOne, sUidOne, + auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne, sLayerNameOne); // Set up the display frame @@ -657,7 +671,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) auto packets = readFrameTimelinePacketsBlocking(tracingSession.get()); // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid // token). - EXPECT_EQ(packets.size(), 4); + EXPECT_EQ(packets.size(), 4u); } void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received, @@ -791,12 +805,12 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { tracingSession->StopBlocking(); auto packets = readFrameTimelinePacketsBlocking(tracingSession.get()); - EXPECT_EQ(packets.size(), 4); + EXPECT_EQ(packets.size(), 4u); // Packet - 0 : ExpectedDisplayFrameStart const auto& packet0 = packets[0]; ASSERT_TRUE(packet0.has_timestamp()); - EXPECT_EQ(packet0.timestamp(), 10); + EXPECT_EQ(packet0.timestamp(), 10u); ASSERT_TRUE(packet0.has_frame_timeline_event()); const auto& event0 = packet0.frame_timeline_event(); @@ -807,7 +821,7 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { // Packet - 1 : FrameEnd (ExpectedDisplayFrame) const auto& packet1 = packets[1]; ASSERT_TRUE(packet1.has_timestamp()); - EXPECT_EQ(packet1.timestamp(), 25); + EXPECT_EQ(packet1.timestamp(), 25u); ASSERT_TRUE(packet1.has_frame_timeline_event()); const auto& event1 = packet1.frame_timeline_event(); @@ -818,7 +832,7 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { // Packet - 2 : ActualDisplayFrameStart const auto& packet2 = packets[2]; ASSERT_TRUE(packet2.has_timestamp()); - EXPECT_EQ(packet2.timestamp(), 20); + EXPECT_EQ(packet2.timestamp(), 20u); ASSERT_TRUE(packet2.has_frame_timeline_event()); const auto& event2 = packet2.frame_timeline_event(); @@ -829,7 +843,7 @@ TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) { // Packet - 3 : FrameEnd (ActualDisplayFrame) const auto& packet3 = packets[3]; ASSERT_TRUE(packet3.has_timestamp()); - EXPECT_EQ(packet3.timestamp(), 26); + EXPECT_EQ(packet3.timestamp(), 26u); ASSERT_TRUE(packet3.has_frame_timeline_event()); const auto& event3 = packet3.frame_timeline_event(); @@ -853,8 +867,8 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) { int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setActualStartTime(0); surfaceFrame1->setActualQueueTime(15); surfaceFrame1->setAcquireFenceTime(20); @@ -904,12 +918,12 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) { tracingSession->StopBlocking(); auto packets = readFrameTimelinePacketsBlocking(tracingSession.get()); - EXPECT_EQ(packets.size(), 8); + EXPECT_EQ(packets.size(), 8u); // Packet - 4 : ExpectedSurfaceFrameStart const auto& packet4 = packets[4]; ASSERT_TRUE(packet4.has_timestamp()); - EXPECT_EQ(packet4.timestamp(), 10); + EXPECT_EQ(packet4.timestamp(), 10u); ASSERT_TRUE(packet4.has_frame_timeline_event()); const auto& event4 = packet4.frame_timeline_event(); @@ -920,7 +934,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) { // Packet - 5 : FrameEnd (ExpectedSurfaceFrame) const auto& packet5 = packets[5]; ASSERT_TRUE(packet5.has_timestamp()); - EXPECT_EQ(packet5.timestamp(), 25); + EXPECT_EQ(packet5.timestamp(), 25u); ASSERT_TRUE(packet5.has_frame_timeline_event()); const auto& event5 = packet5.frame_timeline_event(); @@ -931,7 +945,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) { // Packet - 6 : ActualSurfaceFrameStart const auto& packet6 = packets[6]; ASSERT_TRUE(packet6.has_timestamp()); - EXPECT_EQ(packet6.timestamp(), 10); + EXPECT_EQ(packet6.timestamp(), 10u); ASSERT_TRUE(packet6.has_frame_timeline_event()); const auto& event6 = packet6.frame_timeline_event(); @@ -942,7 +956,7 @@ TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) { // Packet - 7 : FrameEnd (ActualSurfaceFrame) const auto& packet7 = packets[7]; ASSERT_TRUE(packet7.has_timestamp()); - EXPECT_EQ(packet7.timestamp(), 20); + EXPECT_EQ(packet7.timestamp(), 20u); ASSERT_TRUE(packet7.has_frame_timeline_event()); const auto& event7 = packet7.frame_timeline_event(); @@ -961,8 +975,8 @@ TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) { int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30}); int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30}); auto surfaceFrame = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); mFrameTimeline->setSfWakeUp(sfToken1, 22, 11); surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented); mFrameTimeline->addSurfaceFrame(surfaceFrame); @@ -1126,8 +1140,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresen int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40}); int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setAcquireFenceTime(16); mFrameTimeline->setSfWakeUp(sfToken1, 22, 11); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1145,8 +1159,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresen // Trigger a flush by finalizing the next DisplayFrame auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto surfaceFrame2 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame2->setAcquireFenceTime(36); mFrameTimeline->setSfWakeUp(sfToken2, 52, 11); surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1199,8 +1213,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40}); int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setAcquireFenceTime(16); mFrameTimeline->setSfWakeUp(sfToken1, 22, 11); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1218,8 +1232,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent // Trigger a flush by finalizing the next DisplayFrame auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto surfaceFrame2 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame2->setAcquireFenceTime(36); mFrameTimeline->setSfWakeUp(sfToken2, 52, 11); surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1270,8 +1284,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50}); int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setAcquireFenceTime(40); mFrameTimeline->setSfWakeUp(sfToken1, 42, 11); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1316,8 +1330,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30}); int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setAcquireFenceTime(26); mFrameTimeline->setSfWakeUp(sfToken1, 32, 11); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1335,8 +1349,8 @@ TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) // Trigger a flush by finalizing the next DisplayFrame auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto surfaceFrame2 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame2->setAcquireFenceTime(40); mFrameTimeline->setSfWakeUp(sfToken2, 43, 11); surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1390,8 +1404,8 @@ TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadli int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60}); int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120}); auto surfaceFrame1 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken1, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame1->setAcquireFenceTime(50); mFrameTimeline->setSfWakeUp(sfToken1, 52, 30); surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented); @@ -1409,8 +1423,8 @@ TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadli // Trigger a flush by finalizing the next DisplayFrame auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto surfaceFrame2 = - mFrameTimeline->createSurfaceFrameForToken(surfaceFrameToken2, sPidOne, sUidOne, - sLayerNameOne, sLayerNameOne); + mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne, + sUidOne, sLayerNameOne, sLayerNameOne); surfaceFrame2->setAcquireFenceTime(84); mFrameTimeline->setSfWakeUp(sfToken2, 112, 30); surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54); @@ -1456,6 +1470,3 @@ TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadli JankType::AppDeadlineMissed | JankType::BufferStuffing); } } // namespace android::frametimeline - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wextra" \ No newline at end of file diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 2701f472aa..8ca052f710 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -368,16 +368,14 @@ public: auto& getTransactionQueue() { return mFlinger->mTransactionQueues; } - auto setTransactionState(int64_t frameTimelineVsyncId, const Vector& states, - const Vector& displays, uint32_t flags, - const sp& applyToken, - const InputWindowCommands& inputWindowCommands, - int64_t desiredPresentTime, bool isAutoTimestamp, - const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, - std::vector& listenerCallbacks, - uint64_t transactionId) { - return mFlinger->setTransactionState(frameTimelineVsyncId, states, displays, flags, - applyToken, inputWindowCommands, desiredPresentTime, + auto setTransactionState( + const FrameTimelineInfo& frameTimelineInfo, const Vector& states, + const Vector& displays, uint32_t flags, const sp& applyToken, + const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, + bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, + std::vector& listenerCallbacks, uint64_t transactionId) { + return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken, + inputWindowCommands, desiredPresentTime, isAutoTimestamp, uncacheBuffer, hasListenerCallbacks, listenerCallbacks, transactionId); } diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index 06275c6b5b..6d2f672bce 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wextra" #undef LOG_TAG #define LOG_TAG "CompositionTest" @@ -100,43 +96,44 @@ public: InputWindowCommands inputWindowCommands; int64_t desiredPresentTime = 0; bool isAutoTimestamp = true; - int64_t frameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID; + FrameTimelineInfo frameTimelineInfo; client_cache_t uncacheBuffer; - int64_t id = -1; + uint64_t id = static_cast(-1); + static_assert(0xffffffffffffffff == static_cast(-1)); }; void checkEqual(TransactionInfo info, SurfaceFlinger::TransactionState state) { - EXPECT_EQ(0, info.states.size()); - EXPECT_EQ(0, state.states.size()); + EXPECT_EQ(0u, info.states.size()); + EXPECT_EQ(0u, state.states.size()); - EXPECT_EQ(0, info.displays.size()); - EXPECT_EQ(0, state.displays.size()); + EXPECT_EQ(0u, info.displays.size()); + EXPECT_EQ(0u, state.displays.size()); EXPECT_EQ(info.flags, state.flags); EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime); } void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t frameTimelineVsyncId) { + const FrameTimelineInfo& frameTimelineInfo) { mTransactionNumber++; transaction.flags |= flags; // ISurfaceComposer::eSynchronous; transaction.inputWindowCommands.syncInputWindows = syncInputWindows; transaction.desiredPresentTime = desiredPresentTime; transaction.isAutoTimestamp = isAutoTimestamp; - transaction.frameTimelineVsyncId = frameTimelineVsyncId; + transaction.frameTimelineInfo = frameTimelineInfo; } void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) { - ASSERT_EQ(0, mFlinger.getTransactionQueue().size()); + ASSERT_EQ(0u, mFlinger.getTransactionQueue().size()); // called in SurfaceFlinger::signalTransaction EXPECT_CALL(*mMessageQueue, invalidate()).Times(1); EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillOnce(Return(systemTime())); TransactionInfo transaction; setupSingle(transaction, flags, syncInputWindows, /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true, - ISurfaceComposer::INVALID_VSYNC_ID); + FrameTimelineInfo{}); nsecs_t applicationTime = systemTime(); - mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states, + mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states, transaction.displays, transaction.flags, transaction.applyToken, transaction.inputWindowCommands, transaction.desiredPresentTime, transaction.isAutoTimestamp, @@ -155,11 +152,11 @@ public: EXPECT_LE(returnedTime, applicationTime + s2ns(5)); } auto transactionQueue = mFlinger.getTransactionQueue(); - EXPECT_EQ(0, transactionQueue.size()); + EXPECT_EQ(0u, transactionQueue.size()); } void PlaceOnTransactionQueue(uint32_t flags, bool syncInputWindows) { - ASSERT_EQ(0, mFlinger.getTransactionQueue().size()); + ASSERT_EQ(0u, mFlinger.getTransactionQueue().size()); // called in SurfaceFlinger::signalTransaction EXPECT_CALL(*mMessageQueue, invalidate()).Times(1); @@ -170,10 +167,9 @@ public: .WillOnce(Return(time + nsecs_t(5 * 1e8))); TransactionInfo transaction; setupSingle(transaction, flags, syncInputWindows, - /*desiredPresentTime*/ time + s2ns(1), false, - ISurfaceComposer::INVALID_VSYNC_ID); + /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{}); nsecs_t applicationSentTime = systemTime(); - mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states, + mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states, transaction.displays, transaction.flags, transaction.applyToken, transaction.inputWindowCommands, transaction.desiredPresentTime, transaction.isAutoTimestamp, @@ -184,11 +180,11 @@ public: EXPECT_LE(returnedTime, applicationSentTime + s2ns(5)); // This transaction should have been placed on the transaction queue auto transactionQueue = mFlinger.getTransactionQueue(); - EXPECT_EQ(1, transactionQueue.size()); + EXPECT_EQ(1u, transactionQueue.size()); } void BlockedByPriorTransaction(uint32_t flags, bool syncInputWindows) { - ASSERT_EQ(0, mFlinger.getTransactionQueue().size()); + ASSERT_EQ(0u, mFlinger.getTransactionQueue().size()); // called in SurfaceFlinger::signalTransaction nsecs_t time = systemTime(); EXPECT_CALL(*mMessageQueue, invalidate()).Times(1); @@ -197,18 +193,17 @@ public: // transaction that should go on the pending thread TransactionInfo transactionA; setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false, - /*desiredPresentTime*/ time + s2ns(1), false, - ISurfaceComposer::INVALID_VSYNC_ID); + /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{}); // transaction that would not have gone on the pending thread if not // blocked TransactionInfo transactionB; setupSingle(transactionB, flags, syncInputWindows, /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true, - ISurfaceComposer::INVALID_VSYNC_ID); + FrameTimelineInfo{}); nsecs_t applicationSentTime = systemTime(); - mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states, + mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states, transactionA.displays, transactionA.flags, transactionA.applyToken, transactionA.inputWindowCommands, transactionA.desiredPresentTime, transactionA.isAutoTimestamp, @@ -221,7 +216,7 @@ public: EXPECT_LE(systemTime(), applicationSentTime + s2ns(5)); applicationSentTime = systemTime(); - mFlinger.setTransactionState(transactionB.frameTimelineVsyncId, transactionB.states, + mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states, transactionB.displays, transactionB.flags, transactionB.applyToken, transactionB.inputWindowCommands, transactionB.desiredPresentTime, transactionB.isAutoTimestamp, @@ -240,10 +235,10 @@ public: // check that there is one binder on the pending queue. auto transactionQueue = mFlinger.getTransactionQueue(); - EXPECT_EQ(1, transactionQueue.size()); + EXPECT_EQ(1u, transactionQueue.size()); auto& [applyToken, transactionStates] = *(transactionQueue.begin()); - EXPECT_EQ(2, transactionStates.size()); + EXPECT_EQ(2u, transactionStates.size()); auto& transactionStateA = transactionStates.front(); transactionStates.pop(); @@ -258,7 +253,7 @@ public: }; TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) { - ASSERT_EQ(0, mFlinger.getTransactionQueue().size()); + ASSERT_EQ(0u, mFlinger.getTransactionQueue().size()); // called in SurfaceFlinger::signalTransaction EXPECT_CALL(*mMessageQueue, invalidate()).Times(1); @@ -268,18 +263,18 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) { .WillOnce(Return(s2ns(2))); TransactionInfo transactionA; // transaction to go on pending queue setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false, - /*desiredPresentTime*/ s2ns(1), false, ISurfaceComposer::INVALID_VSYNC_ID); - mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states, + /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{}); + mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states, transactionA.displays, transactionA.flags, transactionA.applyToken, transactionA.inputWindowCommands, transactionA.desiredPresentTime, transactionA.isAutoTimestamp, transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks, transactionA.id); auto& transactionQueue = mFlinger.getTransactionQueue(); - ASSERT_EQ(1, transactionQueue.size()); + ASSERT_EQ(1u, transactionQueue.size()); auto& [applyToken, transactionStates] = *(transactionQueue.begin()); - ASSERT_EQ(1, transactionStates.size()); + ASSERT_EQ(1u, transactionStates.size()); auto& transactionState = transactionStates.front(); checkEqual(transactionA, transactionState); @@ -289,8 +284,8 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) { // different process) to re-query and reset the cached expected present time TransactionInfo empty; empty.applyToken = sp(); - mFlinger.setTransactionState(empty.frameTimelineVsyncId, empty.states, empty.displays, - empty.flags, empty.applyToken, empty.inputWindowCommands, + mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags, + empty.applyToken, empty.inputWindowCommands, empty.desiredPresentTime, empty.isAutoTimestamp, empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id); @@ -298,7 +293,7 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) { // passed mFlinger.flushTransactionQueues(); - EXPECT_EQ(0, transactionQueue.size()); + EXPECT_EQ(0u, transactionQueue.size()); } TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Synchronous) { @@ -343,6 +338,3 @@ TEST_F(TransactionApplicationTest, FromHandle) { EXPECT_EQ(nullptr, ret.promote().get()); } } // namespace android - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion -Wextra" -- cgit v1.2.3-59-g8ed1b From 17ac24b6c1252f88ccaf7089fa68bee3e1ef7ed9 Mon Sep 17 00:00:00 2001 From: chaviw Date: Thu, 28 Jan 2021 18:50:05 -0800 Subject: Added new arguments for screenshot request Added frameScaleX and frameScaleY to replace frameScale to allow callers to specify an X and Y scale separately. Added grayscale flag to allow the caller to take the screenshot in grayscale. Test: ScreenCaptureTest.CaptureWithGrayscale Bug: 155825630 Change-Id: Iea043b7074707df897d80bf057d7cc3870afad89 --- libs/gui/LayerState.cpp | 8 ++- libs/gui/include/gui/LayerState.h | 5 +- services/surfaceflinger/RegionSamplingThread.cpp | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 59 ++++++++++++---------- services/surfaceflinger/SurfaceFlinger.h | 9 ++-- services/surfaceflinger/tests/LayerState_test.cpp | 16 ++++-- .../surfaceflinger/tests/ScreenCapture_test.cpp | 39 +++++++++++++- .../tests/unittests/TestableSurfaceFlinger.h | 3 +- 8 files changed, 102 insertions(+), 39 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 2946aaed37..ab20725936 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -644,11 +644,13 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunc status_t CaptureArgs::write(Parcel& output) const { SAFE_PARCEL(output.writeInt32, static_cast(pixelFormat)); SAFE_PARCEL(output.write, sourceCrop); - SAFE_PARCEL(output.writeFloat, frameScale); + SAFE_PARCEL(output.writeFloat, frameScaleX); + SAFE_PARCEL(output.writeFloat, frameScaleY); SAFE_PARCEL(output.writeBool, captureSecureLayers); SAFE_PARCEL(output.writeInt32, uid); SAFE_PARCEL(output.writeInt32, static_cast(dataspace)); SAFE_PARCEL(output.writeBool, allowProtected); + SAFE_PARCEL(output.writeBool, grayscale); return NO_ERROR; } @@ -657,12 +659,14 @@ status_t CaptureArgs::read(const Parcel& input) { SAFE_PARCEL(input.readInt32, &value); pixelFormat = static_cast(value); SAFE_PARCEL(input.read, sourceCrop); - SAFE_PARCEL(input.readFloat, &frameScale); + SAFE_PARCEL(input.readFloat, &frameScaleX); + SAFE_PARCEL(input.readFloat, &frameScaleY); SAFE_PARCEL(input.readBool, &captureSecureLayers); SAFE_PARCEL(input.readInt32, &uid); SAFE_PARCEL(input.readInt32, &value); dataspace = static_cast(value); SAFE_PARCEL(input.readBool, &allowProtected); + SAFE_PARCEL(input.readBool, &grayscale); return NO_ERROR; } diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index b1305c6607..f643ab50a0 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -328,7 +328,8 @@ struct CaptureArgs { ui::PixelFormat pixelFormat{ui::PixelFormat::RGBA_8888}; Rect sourceCrop; - float frameScale{1}; + float frameScaleX{1}; + float frameScaleY{1}; bool captureSecureLayers{false}; int32_t uid{UNSET_UID}; // Force capture to be in a color space. If the value is ui::Dataspace::UNKNOWN, the captured @@ -346,6 +347,8 @@ struct CaptureArgs { // the contents being accessed/captured by screenshot or unsecure display. bool allowProtected = false; + bool grayscale = false; + virtual status_t write(Parcel& output) const; virtual status_t read(const Parcel& input); }; diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index 19b3d6e1a5..9186538c0a 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -451,7 +451,7 @@ void RegionSamplingThread::captureSample() { const sp captureListener = new SyncScreenCaptureListener(); mFlinger.captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, - true /* regionSampling */, captureListener); + true /* regionSampling */, false /* grayscale */, captureListener); ScreenCaptureResults captureResults = captureListener->waitForResults(); std::vector activeDescriptors; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 27df232472..f89b199636 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4900,23 +4900,24 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co result.append("\n"); } -void SurfaceFlinger::updateColorMatrixLocked() { - mat4 colorMatrix; - if (mGlobalSaturationFactor != 1.0f) { - // Rec.709 luma coefficients - float3 luminance{0.213f, 0.715f, 0.072f}; - luminance *= 1.0f - mGlobalSaturationFactor; - mat4 saturationMatrix = mat4( - vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f}, - vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f}, - vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f}, - vec4{0.0f, 0.0f, 0.0f, 1.0f} - ); - colorMatrix = mClientColorMatrix * saturationMatrix * mDaltonizer(); - } else { - colorMatrix = mClientColorMatrix * mDaltonizer(); +mat4 SurfaceFlinger::calculateColorMatrix(float saturation) { + if (saturation == 1) { + return mat4(); } + float3 luminance{0.213f, 0.715f, 0.072f}; + luminance *= 1.0f - saturation; + mat4 saturationMatrix = mat4(vec4{luminance.r + saturation, luminance.r, luminance.r, 0.0f}, + vec4{luminance.g, luminance.g + saturation, luminance.g, 0.0f}, + vec4{luminance.b, luminance.b, luminance.b + saturation, 0.0f}, + vec4{0.0f, 0.0f, 0.0f, 1.0f}); + return saturationMatrix; +} + +void SurfaceFlinger::updateColorMatrixLocked() { + mat4 colorMatrix = + mClientColorMatrix * calculateColorMatrix(mGlobalSaturationFactor) * mDaltonizer(); + if (mCurrentState.colorMatrix != colorMatrix) { mCurrentState.colorMatrix = colorMatrix; mCurrentState.colorMatrixChanged = true; @@ -5628,7 +5629,8 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, }; return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, - args.pixelFormat, args.allowProtected, captureListener); + args.pixelFormat, args.allowProtected, args.grayscale, + captureListener); } status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack, @@ -5664,7 +5666,7 @@ status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack, return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size, ui::PixelFormat::RGBA_8888, false /* allowProtected */, - captureListener); + false /* grayscale */, captureListener); } status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, @@ -5710,12 +5712,12 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, crop.bottom = parentSourceBounds.getHeight(); } - if (crop.isEmpty() || args.frameScale <= 0.0f) { + if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { // Error out if the layer has no source bounds (i.e. they are boundless) and a source // crop was not specified, or an invalid frame scale was provided. return BAD_VALUE; } - reqSize = ui::Size(crop.width() * args.frameScale, crop.height() * args.frameScale); + reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); for (const auto& handle : args.excludeHandles) { sp excludeLayer = fromHandleLocked(handle).promote(); @@ -5785,13 +5787,14 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, }; return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, - args.pixelFormat, args.allowProtected, captureListener); + args.pixelFormat, args.allowProtected, args.grayscale, + captureListener); } status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, - const bool allowProtected, + bool allowProtected, bool grayscale, const sp& captureListener) { ATRACE_CALL(); @@ -5822,12 +5825,13 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, static_cast(reqPixelFormat), 1 /* layerCount */, usage, "screenshot"); return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, - false /* regionSampling */, captureListener); + false /* regionSampling */, grayscale, captureListener); } status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers, - sp& buffer, const bool regionSampling, + sp& buffer, bool regionSampling, + bool grayscale, const sp& captureListener) { ATRACE_CALL(); @@ -5843,7 +5847,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, if (mRefreshPending) { ALOGW("Skipping screenshot for now"); captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, regionSampling, - captureListener); + grayscale, captureListener); return; } ScreenCaptureResults captureResults; @@ -5858,7 +5862,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, status_t result = NO_ERROR; renderArea->render([&] { result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, forSystem, - regionSampling, captureResults); + regionSampling, grayscale, captureResults); }); captureResults.result = result; @@ -5871,7 +5875,7 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const sp& buffer, bool forSystem, - bool regionSampling, + bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) { ATRACE_CALL(); @@ -5912,6 +5916,9 @@ status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace(); clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance; + const float colorSaturation = grayscale ? 0 : 1; + clientCompositionDisplay.colorTransform = calculateColorMatrix(colorSaturation); + const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill()); compositionengine::LayerFE::LayerSettings fillLayer; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 50d6099698..dc92f9817a 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -810,13 +810,14 @@ private: void startBootAnim(); status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize, - ui::PixelFormat, const bool allowProtected, + ui::PixelFormat, bool allowProtected, bool grayscale, const sp&); status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, sp&, - bool regionSampling, const sp&); + bool regionSampling, bool grayscale, + const sp&); status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, const sp&, bool forSystem, bool regionSampling, - ScreenCaptureResults&); + bool grayscale, ScreenCaptureResults&); sp getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); sp getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock); @@ -1019,6 +1020,8 @@ private: void onFrameRateFlexibilityTokenReleased(); + static mat4 calculateColorMatrix(float saturation); + void updateColorMatrixLocked(); // Verify that transaction is being called by an approved process: diff --git a/services/surfaceflinger/tests/LayerState_test.cpp b/services/surfaceflinger/tests/LayerState_test.cpp index 93d5f2f8ec..fa1a5ed6b0 100644 --- a/services/surfaceflinger/tests/LayerState_test.cpp +++ b/services/surfaceflinger/tests/LayerState_test.cpp @@ -30,12 +30,14 @@ TEST(LayerStateTest, ParcellingDisplayCaptureArgs) { DisplayCaptureArgs args; args.pixelFormat = ui::PixelFormat::RGB_565; args.sourceCrop = Rect(0, 0, 500, 200); - args.frameScale = 2; + args.frameScaleX = 2; + args.frameScaleY = 4; args.captureSecureLayers = true; args.displayToken = new BBinder(); args.width = 10; args.height = 20; args.useIdentityTransform = true; + args.grayscale = true; Parcel p; args.write(p); @@ -46,23 +48,27 @@ TEST(LayerStateTest, ParcellingDisplayCaptureArgs) { ASSERT_EQ(args.pixelFormat, args2.pixelFormat); ASSERT_EQ(args.sourceCrop, args2.sourceCrop); - ASSERT_EQ(args.frameScale, args2.frameScale); + ASSERT_EQ(args.frameScaleX, args2.frameScaleX); + ASSERT_EQ(args.frameScaleY, args2.frameScaleY); ASSERT_EQ(args.captureSecureLayers, args2.captureSecureLayers); ASSERT_EQ(args.displayToken, args2.displayToken); ASSERT_EQ(args.width, args2.width); ASSERT_EQ(args.height, args2.height); ASSERT_EQ(args.useIdentityTransform, args2.useIdentityTransform); + ASSERT_EQ(args.grayscale, args2.grayscale); } TEST(LayerStateTest, ParcellingLayerCaptureArgs) { LayerCaptureArgs args; args.pixelFormat = ui::PixelFormat::RGB_565; args.sourceCrop = Rect(0, 0, 500, 200); - args.frameScale = 2; + args.frameScaleX = 2; + args.frameScaleY = 4; args.captureSecureLayers = true; args.layerHandle = new BBinder(); args.excludeHandles = {new BBinder(), new BBinder()}; args.childrenOnly = false; + args.grayscale = true; Parcel p; args.write(p); @@ -73,11 +79,13 @@ TEST(LayerStateTest, ParcellingLayerCaptureArgs) { ASSERT_EQ(args.pixelFormat, args2.pixelFormat); ASSERT_EQ(args.sourceCrop, args2.sourceCrop); - ASSERT_EQ(args.frameScale, args2.frameScale); + ASSERT_EQ(args.frameScaleX, args2.frameScaleX); + ASSERT_EQ(args.frameScaleY, args2.frameScaleY); ASSERT_EQ(args.captureSecureLayers, args2.captureSecureLayers); ASSERT_EQ(args.layerHandle, args2.layerHandle); ASSERT_EQ(args.excludeHandles, args2.excludeHandles); ASSERT_EQ(args.childrenOnly, args2.childrenOnly); + ASSERT_EQ(args.grayscale, args2.grayscale); } TEST(LayerStateTest, ParcellingScreenCaptureResults) { diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp index 214a0cd276..51ce1d3ff9 100644 --- a/services/surfaceflinger/tests/ScreenCapture_test.cpp +++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp @@ -487,7 +487,9 @@ TEST_F(ScreenCaptureTest, CaptureSize) { // red area to the right of the blue area mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED); - captureArgs.frameScale = 0.5f; + captureArgs.frameScaleX = 0.5f; + captureArgs.frameScaleY = 0.5f; + ScreenCapture::captureLayers(&mCapture, captureArgs); // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area. mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE); @@ -768,6 +770,41 @@ TEST_F(ScreenCaptureTest, CaptureLayerWithUid) { mCapture->expectBorder(Rect(128, 128, 160, 160), {63, 63, 195, 255}); } +TEST_F(ScreenCaptureTest, CaptureWithGrayscale) { + sp layer; + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32, + ISurfaceComposerClient::eFXSurfaceBufferState, + mBGSurfaceControl.get())); + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + Transaction().show(layer).setLayer(layer, INT32_MAX).apply(); + + LayerCaptureArgs captureArgs; + captureArgs.layerHandle = layer->getHandle(); + + ScreenCapture::captureLayers(&mCapture, captureArgs); + mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED); + + captureArgs.grayscale = true; + + const uint8_t tolerance = 1; + + // Values based on SurfaceFlinger::calculateColorMatrix + float3 luminance{0.213f, 0.715f, 0.072f}; + + ScreenCapture::captureLayers(&mCapture, captureArgs); + + uint8_t expectedColor = luminance.r * 255; + mCapture->expectColor(Rect(0, 0, 32, 32), + Color{expectedColor, expectedColor, expectedColor, 255}, tolerance); + + ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32)); + ScreenCapture::captureLayers(&mCapture, captureArgs); + + expectedColor = luminance.b * 255; + mCapture->expectColor(Rect(0, 0, 32, 32), + Color{expectedColor, expectedColor, expectedColor, 255}, tolerance); +} + // In the following tests we verify successful skipping of a parent layer, // so we use the same verification logic and only change how we mutate // the parent layer to verify that various properties are ignored. diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 2701f472aa..eda8d79fd5 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -353,7 +353,8 @@ public: bool regionSampling) { ScreenCaptureResults captureResults; return mFlinger->renderScreenImplLocked(renderArea, traverseLayers, buffer, forSystem, - regionSampling, captureResults); + regionSampling, false /* grayscale */, + captureResults); } auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid, -- cgit v1.2.3-59-g8ed1b From cdb4ed7743f5abfa4e9a785b14a50ca25c906f3f Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 4 Feb 2021 13:39:33 -0500 Subject: Add plumbing for sending stretch effect to SF Bug: 179047472 Test: builds & boots, doesn't do anything yet Change-Id: Ib8cccdde518f0591c2f2ee3416684442f37a1e06 --- libs/gui/LayerState.cpp | 6 +++ libs/gui/SurfaceComposerClient.cpp | 17 +++++++ libs/gui/include/gui/LayerState.h | 5 ++ libs/gui/include/gui/SurfaceComposerClient.h | 4 ++ .../include/renderengine/LayerSettings.h | 3 ++ libs/renderengine/skia/SkiaGLRenderEngine.cpp | 3 ++ libs/ui/include/ui/StretchEffect.h | 57 ++++++++++++++++++++++ .../compositionengine/LayerFECompositionState.h | 3 ++ services/surfaceflinger/Layer.cpp | 19 +++++++- services/surfaceflinger/Layer.h | 6 +++ services/surfaceflinger/SurfaceFlinger.cpp | 5 ++ 11 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 libs/ui/include/ui/StretchEffect.h (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index fff33056e1..f053372cb0 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -167,6 +167,9 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeInt32, region.right); SAFE_PARCEL(output.writeInt32, region.bottom); } + + SAFE_PARCEL(output.write, stretchEffect); + return NO_ERROR; } @@ -290,6 +293,9 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readInt32, ®ion.bottom); blurRegions.push_back(region); } + + SAFE_PARCEL(input.read, stretchEffect); + return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 550803d453..73807c4bb6 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1569,6 +1569,23 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApply return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setStretchEffect( + const sp& sc, float left, float top, float right, float bottom, float vecX, + float vecY, float maxAmount) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eStretchChanged; + s->stretchEffect = StretchEffect{.area = {left, top, right, bottom}, + .vectorX = vecX, + .vectorY = vecY, + .maxAmount = maxAmount}; + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 2f9a0c01eb..b273805e25 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -135,6 +136,7 @@ struct layer_state_t { eFrameTimelineInfoChanged = 0x800'00000000, eBlurRegionsChanged = 0x1000'00000000, eAutoRefreshChanged = 0x2000'00000000, + eStretchChanged = 0x4000'00000000, }; layer_state_t(); @@ -244,6 +246,9 @@ struct layer_state_t { // can and not wait for a frame to become available. This is only relevant // in shared buffer mode. bool autoRefresh; + + // Stretch effect to be applied to this layer + StretchEffect stretchEffect; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index e7abfe6172..61c0ab66a1 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -551,6 +551,10 @@ public: // transactions from blocking each other. Transaction& setApplyToken(const sp& token); + Transaction& setStretchEffect(const sp& sc, float left, float top, + float right, float bottom, float vecX, float vecY, + float maxAmount); + status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h index 3a727c9caf..7661233967 100644 --- a/libs/renderengine/include/renderengine/LayerSettings.h +++ b/libs/renderengine/include/renderengine/LayerSettings.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace android { @@ -155,6 +156,8 @@ struct LayerSettings { std::vector blurRegions; + StretchEffect stretchEffect; + // Name associated with the layer for debugging purposes. std::string name; }; diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index dd26b17eb4..1eb8da9b25 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -491,6 +491,9 @@ sk_sp SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp sh const LayerSettings* layer, const DisplaySettings& display, bool undoPremultipliedAlpha) { + if (layer->stretchEffect.hasEffect()) { + // TODO: Implement + } if (mUseColorManagement && needsLinearEffect(layer->colorTransform, layer->sourceDataspace, display.outputDataspace)) { LinearEffect effect = LinearEffect{.inputDataspace = layer->sourceDataspace, diff --git a/libs/ui/include/ui/StretchEffect.h b/libs/ui/include/ui/StretchEffect.h new file mode 100644 index 0000000000..1d2460ccfc --- /dev/null +++ b/libs/ui/include/ui/StretchEffect.h @@ -0,0 +1,57 @@ +/* + * Copyright 2021 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. + */ + +#pragma once + +#include +#include "FloatRect.h" + +#include + +namespace android { + +struct StretchEffect : public LightFlattenablePod { + FloatRect area = {0, 0, 0, 0}; + float vectorX = 0; + float vectorY = 0; + float maxAmount = 0; + + bool operator==(const StretchEffect& other) const { + return area == other.area && vectorX == other.vectorX && vectorY == other.vectorY && + maxAmount == other.maxAmount; + } + + static bool isZero(float value) { + constexpr float NON_ZERO_EPSILON = 0.001f; + return fabsf(value) <= NON_ZERO_EPSILON; + } + + bool isNoOp() const { return isZero(vectorX) && isZero(vectorY); } + + bool hasEffect() const { return !isNoOp(); } + + void sanitize() { + // If the area is empty, or the max amount is zero, then reset back to defaults + if (area.bottom >= area.top || area.left >= area.right || isZero(maxAmount)) { + *this = StretchEffect{}; + } + } +}; + +static_assert(std::is_trivially_copyable::value, + "StretchEffect must be trivially copyable to be flattenable"); + +} // namespace android \ No newline at end of file diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h index c445d5b615..8402149c57 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "DisplayHardware/Hal.h" @@ -123,6 +124,8 @@ struct LayerFECompositionState { // List of regions that require blur std::vector blurRegions; + StretchEffect stretchEffect; + /* * Geometry state */ diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index df14003c75..1fe0e2624b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -488,6 +488,7 @@ void Layer::prepareBasicGeometryCompositionState() { compositionState->alpha = alpha; compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; compositionState->blurRegions = drawingState.blurRegions; + compositionState->stretchEffect = drawingState.stretchEffect; } void Layer::prepareGeometryCompositionState() { @@ -556,8 +557,8 @@ void Layer::preparePerFrameCompositionState() { isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf; // Force client composition for special cases known only to the front-end. - if (isHdrY410() || usesRoundedCorners || drawShadows() || - getDrawingState().blurRegions.size() > 0) { + if (isHdrY410() || usesRoundedCorners || drawShadows() || drawingState.blurRegions.size() > 0 || + drawingState.stretchEffect.hasEffect()) { compositionState->forceClientComposition = true; } } @@ -656,6 +657,7 @@ std::optional Layer::prepareClientCom layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); layerSettings.blurRegions = getBlurRegions(); } + layerSettings.stretchEffect = getDrawingState().stretchEffect; // Record the name of the layer for debugging further down the stack. layerSettings.name = getName(); return layerSettings; @@ -1423,6 +1425,19 @@ bool Layer::setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHin return true; } +bool Layer::setStretchEffect(const StretchEffect& effect) { + StretchEffect temp = effect; + temp.sanitize(); + if (mCurrentState.stretchEffect == temp) { + return false; + } + mCurrentState.sequence++; + mCurrentState.stretchEffect = temp; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + void Layer::updateTreeHasFrameRateVote() { const auto traverseTree = [&](const LayerVector::Visitor& visitor) { auto parent = getParent(); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 9cd15e8705..7d70d91bd3 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -323,6 +324,9 @@ public: // An arbitrary threshold for the number of BufferlessSurfaceFrames in the state. Used to // trigger a warning if the number of SurfaceFrames crosses the threshold. static constexpr uint32_t kStateSurfaceFramesThreshold = 25; + + // Stretch effect to apply to this layer + StretchEffect stretchEffect; }; /* @@ -938,6 +942,8 @@ public: bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; } + bool setStretchEffect(const StretchEffect& effect); + protected: class SyncPoint { public: diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 689a3024a3..bbbb0034ce 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3953,6 +3953,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & layer_state_t::eAutoRefreshChanged) { layer->setAutoRefresh(s.autoRefresh); } + if (what & layer_state_t::eStretchChanged) { + if (layer->setStretchEffect(s.stretchEffect)) { + flags |= eTraversalNeeded; + } + } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not -- cgit v1.2.3-59-g8ed1b From c00c669cbc76f201879ebf2e0ce60d386a0fa483 Mon Sep 17 00:00:00 2001 From: John Reck Date: Tue, 16 Feb 2021 11:37:33 -0500 Subject: StretchEffect changes Bug: 179047472 Test: StretchySurfaceViewActivity in HwAccelerationTests Change-Id: Ia1fcd6136a380bb7099fae08ceb024eae4f79ac8 --- libs/gui/LayerDebugInfo.cpp | 8 ++++++++ libs/gui/LayerState.cpp | 4 ++++ libs/gui/include/gui/LayerDebugInfo.h | 2 ++ libs/ui/include/ui/FloatRect.h | 2 ++ libs/ui/include/ui/StretchEffect.h | 3 ++- .../include/compositionengine/impl/DumpHelpers.h | 2 ++ .../CompositionEngine/src/DumpHelpers.cpp | 6 ++++++ .../src/LayerFECompositionState.cpp | 3 +++ services/surfaceflinger/Layer.cpp | 21 +++++++++++++++++++-- services/surfaceflinger/Layer.h | 1 + services/surfaceflinger/SurfaceInterceptor.cpp | 3 +++ 11 files changed, 52 insertions(+), 3 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp index cdde9a2308..e707684618 100644 --- a/libs/gui/LayerDebugInfo.cpp +++ b/libs/gui/LayerDebugInfo.cpp @@ -61,6 +61,7 @@ status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const { RETURN_ON_ERROR(parcel->writeBool(mRefreshPending)); RETURN_ON_ERROR(parcel->writeBool(mIsOpaque)); RETURN_ON_ERROR(parcel->writeBool(mContentDirty)); + RETURN_ON_ERROR(parcel->write(mStretchEffect)); return NO_ERROR; } @@ -105,6 +106,7 @@ status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) { RETURN_ON_ERROR(parcel->readBool(&mRefreshPending)); RETURN_ON_ERROR(parcel->readBool(&mIsOpaque)); RETURN_ON_ERROR(parcel->readBool(&mContentDirty)); + RETURN_ON_ERROR(parcel->read(mStretchEffect)); return NO_ERROR; } @@ -115,6 +117,12 @@ std::string to_string(const LayerDebugInfo& info) { info.mTransparentRegion.dump(result, "TransparentRegion"); info.mVisibleRegion.dump(result, "VisibleRegion"); info.mSurfaceDamageRegion.dump(result, "SurfaceDamageRegion"); + if (info.mStretchEffect.hasEffect()) { + const auto& se = info.mStretchEffect; + StringAppendF(&result, " StretchEffect area=[%f, %f, %f, %f] vec=(%f, %f) maxAmount=%f\n", + se.area.left, se.area.top, se.area.right, se.area.bottom, se.vectorX, + se.vectorY, se.maxAmount); + } StringAppendF(&result, " layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ", info.mLayerStack, info.mZ, static_cast(info.mX), diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index f053372cb0..288bf92c15 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -548,6 +548,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eAutoRefreshChanged; autoRefresh = other.autoRefresh; } + if (other.what & eStretchChanged) { + what |= eStretchChanged; + stretchEffect = other.stretchEffect; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h index 66a7b4dc06..8b7d32c0a5 100644 --- a/libs/gui/include/gui/LayerDebugInfo.h +++ b/libs/gui/include/gui/LayerDebugInfo.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -66,6 +67,7 @@ public: bool mRefreshPending = false; bool mIsOpaque = false; bool mContentDirty = false; + StretchEffect mStretchEffect = {}; }; std::string to_string(const LayerDebugInfo& info); diff --git a/libs/ui/include/ui/FloatRect.h b/libs/ui/include/ui/FloatRect.h index bec2552fde..5d329ea6a9 100644 --- a/libs/ui/include/ui/FloatRect.h +++ b/libs/ui/include/ui/FloatRect.h @@ -48,6 +48,8 @@ public: float top = 0.0f; float right = 0.0f; float bottom = 0.0f; + + constexpr bool isEmpty() const { return !(left < right && top < bottom); } }; inline bool operator==(const FloatRect& a, const FloatRect& b) { diff --git a/libs/ui/include/ui/StretchEffect.h b/libs/ui/include/ui/StretchEffect.h index 1d2460ccfc..0803df3828 100644 --- a/libs/ui/include/ui/StretchEffect.h +++ b/libs/ui/include/ui/StretchEffect.h @@ -19,6 +19,7 @@ #include #include "FloatRect.h" +#include #include namespace android { @@ -45,7 +46,7 @@ struct StretchEffect : public LightFlattenablePod { void sanitize() { // If the area is empty, or the max amount is zero, then reset back to defaults - if (area.bottom >= area.top || area.left >= area.right || isZero(maxAmount)) { + if (area.isEmpty() || isZero(maxAmount)) { *this = StretchEffect{}; } } diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h index 782c8d772f..6b9597b2d5 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace android::compositionengine::impl { @@ -58,5 +59,6 @@ void dumpVal(std::string& out, const char* name, const ui::Transform&); void dumpVal(std::string& out, const char* name, const ui::Size&); void dumpVal(std::string& out, const char* name, const mat4& tr); +void dumpVal(std::string& out, const char* name, const StretchEffect&); } // namespace android::compositionengine::impl diff --git a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp index 9d1bb02e7c..0cc2c6e637 100644 --- a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp +++ b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp @@ -100,4 +100,10 @@ void dumpVal(std::string& out, const char* name, const mat4& tr) { ); /* clang-format on */ } +void dumpVal(std::string& out, const char* name, const StretchEffect& effect) { + StringAppendF(&out, "%s={ area=[%f, %f, %f, %f], vec=(%f, %f), max=%f } ", name, + effect.area.left, effect.area.top, effect.area.right, effect.area.bottom, + effect.vectorX, effect.vectorY, effect.maxAmount); +} + } // namespace android::compositionengine::impl diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp index 1338538861..430945ab4c 100644 --- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp +++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp @@ -74,6 +74,9 @@ void LayerFECompositionState::dump(std::string& out) const { dumpVal(out, "blend", toString(blendMode), blendMode); dumpVal(out, "alpha", alpha); dumpVal(out, "backgroundBlurRadius", backgroundBlurRadius); + if (stretchEffect.hasEffect()) { + dumpVal(out, "stretchEffect", stretchEffect); + } if (!metadata.empty()) { out.append("\n metadata {"); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 237aaffa1f..cc7b2e7c1c 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -488,7 +488,7 @@ void Layer::prepareBasicGeometryCompositionState() { compositionState->alpha = alpha; compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; compositionState->blurRegions = drawingState.blurRegions; - compositionState->stretchEffect = drawingState.stretchEffect; + compositionState->stretchEffect = getStretchEffect(); } void Layer::prepareGeometryCompositionState() { @@ -558,7 +558,7 @@ void Layer::preparePerFrameCompositionState() { // Force client composition for special cases known only to the front-end. if (isHdrY410() || usesRoundedCorners || drawShadows() || drawingState.blurRegions.size() > 0 || - drawingState.stretchEffect.hasEffect()) { + compositionState->stretchEffect.hasEffect()) { compositionState->forceClientComposition = true; } } @@ -1436,6 +1436,22 @@ bool Layer::setStretchEffect(const StretchEffect& effect) { return true; } +StretchEffect Layer::getStretchEffect() const { + if (mDrawingState.stretchEffect.hasEffect()) { + return mDrawingState.stretchEffect; + } + + sp parent = getParent(); + if (parent != nullptr) { + auto effect = parent->getStretchEffect(); + if (effect.hasEffect()) { + // TODO(b/179047472): Map it? Or do we make the effect be in global space? + return effect; + } + } + return StretchEffect{}; +} + void Layer::updateTreeHasFrameRateVote() { const auto traverseTree = [&](const LayerVector::Visitor& visitor) { auto parent = getParent(); @@ -1740,6 +1756,7 @@ LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const { info.mRefreshPending = isBufferLatched(); info.mIsOpaque = isOpaque(ds); info.mContentDirty = contentDirty; + info.mStretchEffect = getStretchEffect(); return info; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 687f473a79..f87aec207a 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -943,6 +943,7 @@ public: bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; } bool setStretchEffect(const StretchEffect& effect); + StretchEffect getStretchEffect() const; protected: class SyncPoint { diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index 61005c92df..b0413f1c92 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -499,6 +499,9 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, if (state.what & layer_state_t::eShadowRadiusChanged) { addShadowRadiusLocked(transaction, layerId, state.shadowRadius); } + if (state.what & layer_state_t::eStretchChanged) { + ALOGW("SurfaceInterceptor not implemented for eStretchChanged"); + } } void SurfaceInterceptor::addDisplayChangesLocked(Transaction* transaction, -- cgit v1.2.3-59-g8ed1b From 25714500c80a7c4efa5cd82ccd914a57bc5d51e6 Mon Sep 17 00:00:00 2001 From: chaviw Date: Thu, 11 Feb 2021 10:01:08 -0800 Subject: Rename crop_legacy to just crop crop_legacy and crop should do the same thing so there's no need for two separate requests. Test: go/wm-smoke Test: SurfaceFlinger_test Bug: 170765639 Change-Id: I74a740d06d15f7cde9775557e65ad1e3a508bd61 --- cmds/surfacereplayer/replayer/Replayer.cpp | 2 +- libs/gui/LayerState.cpp | 9 ++--- libs/gui/SurfaceComposerClient.cpp | 22 +++--------- libs/gui/include/gui/LayerState.h | 3 +- libs/gui/include/gui/SurfaceComposerClient.h | 3 +- libs/gui/tests/BLASTBufferQueue_test.cpp | 2 +- libs/gui/tests/EndToEndNativeInputTest.cpp | 6 ++-- libs/gui/tests/SamplingDemo.cpp | 10 +++--- services/surfaceflinger/BufferStateLayer.h | 1 - services/surfaceflinger/Layer.cpp | 27 +++++++------- services/surfaceflinger/Layer.h | 10 +++--- services/surfaceflinger/LayerRejecter.cpp | 15 ++++---- services/surfaceflinger/SurfaceFlinger.cpp | 3 -- services/surfaceflinger/SurfaceInterceptor.cpp | 6 ++-- services/surfaceflinger/tests/EffectLayer_test.cpp | 12 +++---- .../tests/LayerRenderTypeTransaction_test.cpp | 42 +++++++++++----------- .../surfaceflinger/tests/LayerTransactionTest.h | 2 +- .../LayerTypeAndRenderTypeTransaction_test.cpp | 14 ++++---- .../tests/LayerTypeTransaction_test.cpp | 6 ++-- services/surfaceflinger/tests/LayerUpdate_test.cpp | 18 +++++----- services/surfaceflinger/tests/MirrorLayer_test.cpp | 4 +-- .../tests/MultiDisplayLayerBounds_test.cpp | 2 +- .../surfaceflinger/tests/ScreenCapture_test.cpp | 12 +++---- .../tests/SurfaceInterceptor_test.cpp | 2 +- .../tests/fakehwc/SFFakeHwc_test.cpp | 10 +++--- .../tests/unittests/CompositionTest.cpp | 2 +- 26 files changed, 105 insertions(+), 140 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp index 3c53c025ff..bbbe6f7ec4 100644 --- a/cmds/surfacereplayer/replayer/Replayer.cpp +++ b/cmds/surfacereplayer/replayer/Replayer.cpp @@ -495,7 +495,7 @@ void Replayer::setCrop(SurfaceComposerClient::Transaction& t, Rect r = Rect(cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), cc.rectangle().bottom()); - t.setCrop_legacy(mLayers[id], r); + t.setCrop(mLayers[id], r); } void Replayer::setCornerRadius(SurfaceComposerClient::Transaction& t, diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 288bf92c15..6bb8bf2d5b 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -41,7 +41,6 @@ layer_state_t::layer_state_t() flags(0), mask(0), reserved(0), - crop_legacy(Rect::INVALID_RECT), cornerRadius(0.0f), backgroundBlurRadius(0), barrierFrameNumber(0), @@ -85,7 +84,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeUint32, flags); SAFE_PARCEL(output.writeUint32, mask); SAFE_PARCEL(matrix.write, output); - SAFE_PARCEL(output.write, crop_legacy); + SAFE_PARCEL(output.write, crop); SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, barrierSurfaceControl_legacy); SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, reparentSurfaceControl); SAFE_PARCEL(output.writeUint64, barrierFrameNumber); @@ -191,7 +190,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readUint32, &mask); SAFE_PARCEL(matrix.read, input); - SAFE_PARCEL(input.read, crop_legacy); + SAFE_PARCEL(input.read, crop); SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &barrierSurfaceControl_legacy); SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &reparentSurfaceControl); SAFE_PARCEL(input.readUint64, &barrierFrameNumber); @@ -407,10 +406,6 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eLayerStackChanged; layerStack = other.layerStack; } - if (other.what & eCropChanged_legacy) { - what |= eCropChanged_legacy; - crop_legacy = other.crop_legacy; - } if (other.what & eCornerRadiusChanged) { what |= eCornerRadiusChanged; cornerRadius = other.cornerRadius; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 5e8ab929f5..f56578981b 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1048,15 +1048,15 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMatri return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop_legacy( +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( const sp& sc, const Rect& crop) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eCropChanged_legacy; - s->crop_legacy = crop; + s->what |= layer_state_t::eCropChanged; + s->crop = crop; registerSurfaceControlForCallback(sc); return *this; @@ -1204,20 +1204,6 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp& sc, const Rect& crop) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eCropChanged; - s->crop = crop; - - registerSurfaceControlForCallback(sc); - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame( const sp& sc, const Rect& frame) { layer_state_t* s = getLayerState(sc); @@ -1458,7 +1444,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeometry( const sp& sc, const Rect& source, const Rect& dst, int transform) { - setCrop_legacy(sc, source); + setCrop(sc, source); int x = dst.left; int y = dst.top; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index b273805e25..183ec40fba 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -98,7 +98,7 @@ struct layer_state_t { eTransparentRegionChanged = 0x00000020, eFlagsChanged = 0x00000040, eLayerStackChanged = 0x00000080, - eCropChanged_legacy = 0x00000100, + /* was eCropChanged_legacy, now available 0x00000100, */ eDeferTransaction_legacy = 0x00000200, /* was ScalingModeChanged, now available 0x00000400, */ eShadowRadiusChanged = 0x00000800, @@ -167,7 +167,6 @@ struct layer_state_t { uint32_t mask; uint8_t reserved; matrix22_t matrix; - Rect crop_legacy; float cornerRadius; uint32_t backgroundBlurRadius; sp barrierSurfaceControl_legacy; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index de88943cde..40c4135a51 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -436,7 +436,7 @@ public: float alpha); Transaction& setMatrix(const sp& sc, float dsdx, float dtdx, float dtdy, float dsdy); - Transaction& setCrop_legacy(const sp& sc, const Rect& crop); + Transaction& setCrop(const sp& sc, const Rect& crop); Transaction& setCornerRadius(const sp& sc, float cornerRadius); Transaction& setBackgroundBlurRadius(const sp& sc, int backgroundBlurRadius); @@ -469,7 +469,6 @@ public: Transaction& setTransform(const sp& sc, uint32_t transform); Transaction& setTransformToDisplayInverse(const sp& sc, bool transformToDisplayInverse); - Transaction& setCrop(const sp& sc, const Rect& crop); Transaction& setFrame(const sp& sc, const Rect& frame); Transaction& setBuffer(const sp& sc, const sp& buffer); Transaction& setCachedBuffer(const sp& sc, int32_t bufferId); diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index fb07a198ec..7895e99cc3 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -458,7 +458,7 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { ASSERT_NE(nullptr, bg.get()); Transaction t; t.setLayerStack(bg, 0) - .setCrop_legacy(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight)) + .setCrop(bg, Rect(0, 0, mDisplayWidth, mDisplayHeight)) .setColor(bg, half3{0, 0, 0}) .setLayer(bg, 0) .apply(); diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index d65a40baf6..59e5c13b0b 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -195,7 +195,7 @@ public: t.setInputWindowInfo(mSurfaceControl, mInputInfo); t.setLayer(mSurfaceControl, LAYER_BASE); t.setPosition(mSurfaceControl, x, y); - t.setCrop_legacy(mSurfaceControl, crop); + t.setCrop(mSurfaceControl, crop); t.setAlpha(mSurfaceControl, 1); t.apply(true); } @@ -670,7 +670,7 @@ TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) { parentSurface->showAt(100, 100); nonTouchableSurface->doTransaction([&](auto &t, auto &sc) { - t.setCrop_legacy(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50)); + t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50)); t.reparent(sc, parentSurface->mSurfaceControl); }); @@ -694,7 +694,7 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) { parentSurface->showAt(50, 50); nonTouchableSurface->doTransaction([&](auto &t, auto &sc) { - t.setCrop_legacy(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50)); + t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50)); t.reparent(sc, parentSurface->mSurfaceControl); }); diff --git a/libs/gui/tests/SamplingDemo.cpp b/libs/gui/tests/SamplingDemo.cpp index 5c1bebb960..0cd150d3cb 100644 --- a/libs/gui/tests/SamplingDemo.cpp +++ b/libs/gui/tests/SamplingDemo.cpp @@ -46,8 +46,7 @@ public: SurfaceComposerClient::Transaction{} .setLayer(mButton, 0x7fffffff) - .setCrop_legacy(mButton, - {0, 0, width - 2 * BUTTON_PADDING, height - 2 * BUTTON_PADDING}) + .setCrop(mButton, {0, 0, width - 2 * BUTTON_PADDING, height - 2 * BUTTON_PADDING}) .setPosition(mButton, samplingArea.left + BUTTON_PADDING, samplingArea.top + BUTTON_PADDING) .setColor(mButton, half3{1, 1, 1}) @@ -59,9 +58,8 @@ public: SurfaceComposerClient::Transaction{} .setLayer(mButtonBlend, 0x7ffffffe) - .setCrop_legacy(mButtonBlend, - {0, 0, width - 2 * SAMPLE_AREA_PADDING, - height - 2 * SAMPLE_AREA_PADDING}) + .setCrop(mButtonBlend, + {0, 0, width - 2 * SAMPLE_AREA_PADDING, height - 2 * SAMPLE_AREA_PADDING}) .setPosition(mButtonBlend, samplingArea.left + SAMPLE_AREA_PADDING, samplingArea.top + SAMPLE_AREA_PADDING) .setColor(mButtonBlend, half3{1, 1, 1}) @@ -77,7 +75,7 @@ public: SurfaceComposerClient::Transaction{} .setLayer(mSamplingArea, 0x7ffffffd) - .setCrop_legacy(mSamplingArea, {0, 0, 100, 32}) + .setCrop(mSamplingArea, {0, 0, 100, 32}) .setPosition(mSamplingArea, 490, 1606) .setColor(mSamplingArea, half3{0, 1, 0}) .setAlpha(mSamplingArea, 0.1) diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 93fb2cd2a4..ebf40cb6e4 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -89,7 +89,6 @@ public: bool /*allowNonRectPreservingTransforms*/) override { return false; } - bool setCrop_legacy(const Rect& /*crop*/) override { return false; } void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, uint64_t /*frameNumber*/) override {} void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 44f1a70e1c..0015bf27d1 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -102,8 +102,8 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.active_legacy.h = args.h; mCurrentState.flags = layerFlags; mCurrentState.active_legacy.transform.set(0, 0); - mCurrentState.crop_legacy.makeInvalid(); - mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy; + mCurrentState.crop.makeInvalid(); + mCurrentState.requestedCrop = mCurrentState.crop; mCurrentState.z = 0; mCurrentState.color.a = 1.0f; mCurrentState.layerStack = 0; @@ -949,13 +949,12 @@ uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) { " requested={ wh={%4u,%4u} }}\n", this, getName().c_str(), getBufferTransform(), getEffectiveScalingMode(), stateToCommit->active_legacy.w, stateToCommit->active_legacy.h, - stateToCommit->crop_legacy.left, stateToCommit->crop_legacy.top, - stateToCommit->crop_legacy.right, stateToCommit->crop_legacy.bottom, - stateToCommit->crop_legacy.getWidth(), stateToCommit->crop_legacy.getHeight(), - stateToCommit->requested_legacy.w, stateToCommit->requested_legacy.h, - s.active_legacy.w, s.active_legacy.h, s.crop_legacy.left, s.crop_legacy.top, - s.crop_legacy.right, s.crop_legacy.bottom, s.crop_legacy.getWidth(), - s.crop_legacy.getHeight(), s.requested_legacy.w, s.requested_legacy.h); + stateToCommit->crop.left, stateToCommit->crop.top, stateToCommit->crop.right, + stateToCommit->crop.bottom, stateToCommit->crop.getWidth(), + stateToCommit->crop.getHeight(), stateToCommit->requested_legacy.w, + stateToCommit->requested_legacy.h, s.active_legacy.w, s.active_legacy.h, + s.crop.left, s.crop.top, s.crop.right, s.crop.bottom, s.crop.getWidth(), + s.crop.getHeight(), s.requested_legacy.w, s.requested_legacy.h); } // Don't let Layer::doTransaction update the drawing state @@ -1335,11 +1334,11 @@ bool Layer::setFlags(uint32_t flags, uint32_t mask) { return true; } -bool Layer::setCrop_legacy(const Rect& crop) { - if (mCurrentState.requestedCrop_legacy == crop) return false; +bool Layer::setCrop(const Rect& crop) { + if (mCurrentState.requestedCrop == crop) return false; mCurrentState.sequence++; - mCurrentState.requestedCrop_legacy = crop; - mCurrentState.crop_legacy = crop; + mCurrentState.requestedCrop = crop; + mCurrentState.crop = crop; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); @@ -1744,7 +1743,7 @@ LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const { info.mZ = ds.z; info.mWidth = ds.active_legacy.w; info.mHeight = ds.active_legacy.h; - info.mCrop = ds.crop_legacy; + info.mCrop = ds.crop; info.mColor = ds.color; info.mFlags = ds.flags; info.mPixelFormat = getPixelFormat(); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 4a114e2688..26d8e7472a 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -214,8 +214,8 @@ public: bool modified; // Crop is expressed in layer space coordinate. - Rect crop_legacy; - Rect requestedCrop_legacy; + Rect crop; + Rect requestedCrop; // If set, defers this state update until the identified Layer // receives a frame with the given frameNumber @@ -257,7 +257,6 @@ public: uint32_t bufferTransform; bool transformToDisplayInverse; - Rect crop; Region transparentRegionHint; sp buffer; @@ -423,7 +422,7 @@ public: // space for top-level layers. virtual bool setPosition(float x, float y); // Buffer space - virtual bool setCrop_legacy(const Rect& crop); + virtual bool setCrop(const Rect& crop); // TODO(b/38182121): Could we eliminate the various latching modes by // using the layer hierarchy? @@ -462,7 +461,6 @@ public: // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; - virtual bool setCrop(const Rect& /*crop*/) { return false; }; virtual bool setFrame(const Rect& /*frame*/) { return false; }; virtual bool setBuffer(const sp& /*buffer*/, const sp& /*acquireFence*/, nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/, @@ -549,7 +547,7 @@ public: virtual Region getActiveTransparentRegion(const Layer::State& s) const { return s.activeTransparentRegion_legacy; } - virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; } + virtual Rect getCrop(const Layer::State& s) const { return s.crop; } virtual bool needsFiltering(const DisplayDevice*) const { return false; } // True if this layer requires filtering diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp index 053b7f741e..1c0263ba0b 100644 --- a/services/surfaceflinger/LayerRejecter.cpp +++ b/services/surfaceflinger/LayerRejecter.cpp @@ -80,24 +80,23 @@ bool LayerRejecter::reject(const sp& buf, const BufferItem& item) // recompute visible region mRecomputeVisibleRegions = true; - if (mFront.crop_legacy != mFront.requestedCrop_legacy) { - mFront.crop_legacy = mFront.requestedCrop_legacy; - mCurrent.crop_legacy = mFront.requestedCrop_legacy; + if (mFront.crop != mFront.requestedCrop) { + mFront.crop = mFront.requestedCrop; + mCurrent.crop = mFront.requestedCrop; mRecomputeVisibleRegions = true; } } ALOGD_IF(DEBUG_RESIZE, "[%s] latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" - " drawing={ active_legacy ={ wh={%4u,%4u} crop_legacy={%4d,%4d,%4d,%4d} " + " drawing={ active_legacy ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} " "(%4d,%4d) " "}\n" " requested_legacy={ wh={%4u,%4u} }}\n", mName.c_str(), bufWidth, bufHeight, item.mTransform, item.mScalingMode, - mFront.active_legacy.w, mFront.active_legacy.h, mFront.crop_legacy.left, - mFront.crop_legacy.top, mFront.crop_legacy.right, mFront.crop_legacy.bottom, - mFront.crop_legacy.getWidth(), mFront.crop_legacy.getHeight(), - mFront.requested_legacy.w, mFront.requested_legacy.h); + mFront.active_legacy.w, mFront.active_legacy.h, mFront.crop.left, mFront.crop.top, + mFront.crop.right, mFront.crop.bottom, mFront.crop.getWidth(), + mFront.crop.getHeight(), mFront.requested_legacy.w, mFront.requested_legacy.h); } if (!isFixedSize && !mStickyTransformSet) { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 09949540cd..a03560bf17 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3843,9 +3843,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (layer->setFlags(s.flags, s.mask)) flags |= eTraversalNeeded; } - if (what & layer_state_t::eCropChanged_legacy) { - if (layer->setCrop_legacy(s.crop_legacy)) flags |= eTraversalNeeded; - } if (what & layer_state_t::eCornerRadiusChanged) { if (layer->setCornerRadius(s.cornerRadius)) flags |= eTraversalNeeded; diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index b0413f1c92..8a3be9f4ed 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -137,7 +137,7 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion_legacy); addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack); - addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy); + addCropLocked(transaction, layerId, layer->mCurrentState.crop); addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius); addBackgroundBlurRadiusLocked(transaction, layerId, layer->mCurrentState.backgroundBlurRadius); addBlurRegionsLocked(transaction, layerId, layer->mCurrentState.blurRegions); @@ -459,8 +459,8 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, if (state.what & layer_state_t::eLayerStackChanged) { addLayerStackLocked(transaction, layerId, state.layerStack); } - if (state.what & layer_state_t::eCropChanged_legacy) { - addCropLocked(transaction, layerId, state.crop_legacy); + if (state.what & layer_state_t::eCropChanged) { + addCropLocked(transaction, layerId, state.crop); } if (state.what & layer_state_t::eCornerRadiusChanged) { addCornerRadiusLocked(transaction, layerId, state.cornerRadius); diff --git a/services/surfaceflinger/tests/EffectLayer_test.cpp b/services/surfaceflinger/tests/EffectLayer_test.cpp index 7a3c45dbba..f470eda7d3 100644 --- a/services/surfaceflinger/tests/EffectLayer_test.cpp +++ b/services/surfaceflinger/tests/EffectLayer_test.cpp @@ -55,7 +55,7 @@ TEST_F(EffectLayerTest, DefaultEffectLayerHasSolidBlackFill) { EXPECT_NE(nullptr, effectLayer.get()) << "failed to create SurfaceControl"; asTransaction([&](Transaction& t) { - t.setCrop_legacy(effectLayer, Rect(0, 0, 400, 400)); + t.setCrop(effectLayer, Rect(0, 0, 400, 400)); t.show(effectLayer); }); @@ -76,7 +76,7 @@ TEST_F(EffectLayerTest, EffectLayerWithNoFill) { EXPECT_NE(nullptr, effectLayer.get()) << "failed to create SurfaceControl"; asTransaction([&](Transaction& t) { - t.setCrop_legacy(effectLayer, Rect(0, 0, 400, 400)); + t.setCrop(effectLayer, Rect(0, 0, 400, 400)); t.show(effectLayer); }); @@ -97,7 +97,7 @@ TEST_F(EffectLayerTest, EffectLayerCanSetColor) { EXPECT_NE(nullptr, effectLayer.get()) << "failed to create SurfaceControl"; asTransaction([&](Transaction& t) { - t.setCrop_legacy(effectLayer, Rect(0, 0, 400, 400)); + t.setCrop(effectLayer, Rect(0, 0, 400, 400)); t.setColor(effectLayer, half3{Color::GREEN.r / 255.0f, Color::GREEN.g / 255.0f, Color::GREEN.b / 255.0f}); @@ -127,10 +127,10 @@ TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) { asTransaction([&](Transaction& t) { t.setLayer(leftLayer, mLayerZBase + 1); t.reparent(leftLayer, mParentLayer); - t.setCrop_legacy(leftLayer, leftRect); + t.setCrop(leftLayer, leftRect); t.setLayer(rightLayer, mLayerZBase + 2); t.reparent(rightLayer, mParentLayer); - t.setCrop_legacy(rightLayer, rightRect); + t.setCrop(rightLayer, rightRect); t.show(leftLayer); t.show(rightLayer); }); @@ -148,7 +148,7 @@ TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) { t.setLayer(blurLayer, mLayerZBase + 3); t.reparent(blurLayer, mParentLayer); t.setBackgroundBlurRadius(blurLayer, blurRadius); - t.setCrop_legacy(blurLayer, blurRect); + t.setCrop(blurLayer, blurRect); t.setFrame(blurLayer, blurRect); t.setAlpha(blurLayer, 0.0f); t.show(blurLayer); diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp index b35eaa980c..7505e6ea9b 100644 --- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp @@ -515,7 +515,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorBasic) { ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() - .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) + .setCrop(colorLayer, Rect(0, 0, 32, 32)) .setLayer(colorLayer, mLayerZBase + 1) .apply(); @@ -554,7 +554,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType case ISurfaceComposerClient::eFXSurfaceEffect: ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 0, 0, layerType)); Transaction() - .setCrop_legacy(layer, Rect(0, 0, width, height)) + .setCrop(layer, Rect(0, 0, width, height)) .setColor(layer, half3(1.0f, 0, 0)) .apply(); expectedColor = fillColor; @@ -565,7 +565,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, fillColor, width, height)); expectedColor = fillColor; } - Transaction().setCrop_legacy(layer, Rect(0, 0, width, height)).apply(); + Transaction().setCrop(layer, Rect(0, 0, width, height)).apply(); break; case ISurfaceComposerClient::eFXSurfaceBufferState: ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height, layerType)); @@ -727,7 +727,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorClamped) { createLayer("test", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() - .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) + .setCrop(colorLayer, Rect(0, 0, 32, 32)) .setColor(colorLayer, half3(2.0f, 0.0f, 0.0f)) .apply(); @@ -741,7 +741,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetInvalidColor) { createLayer("test", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() - .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) + .setCrop(colorLayer, Rect(0, 0, 32, 32)) .setColor(colorLayer, half3(1.0f, -1.0f, 0.5f)) .apply(); @@ -756,7 +756,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorWithAlpha) { ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceEffect)); - Transaction().setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)).apply(); + Transaction().setCrop(colorLayer, Rect(0, 0, 32, 32)).apply(); const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f); const float alpha = 0.25f; @@ -783,7 +783,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorWithParentAlpha_Bug74220420) { ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("childWithColor", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceEffect)); - Transaction().setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)).apply(); + Transaction().setCrop(colorLayer, Rect(0, 0, 32, 32)).apply(); const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f); const float alpha = 0.25f; const ubyte3 expected((vec3(color) * alpha + vec3(1.0f, 0.0f, 0.0f) * (1.0f - alpha)) * 255.0f); @@ -940,7 +940,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropBasic_BufferQueue) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); const Rect crop(8, 8, 24, 24); - Transaction().setCrop_legacy(layer, crop).apply(); + Transaction().setCrop(layer, crop).apply(); auto shot = getScreenCapture(); shot->expectColor(crop, Color::RED); shot->expectBorder(crop, Color::BLACK); @@ -966,13 +966,13 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferQueue) { { SCOPED_TRACE("empty rect"); - Transaction().setCrop_legacy(layer, Rect(8, 8, 8, 8)).apply(); + Transaction().setCrop(layer, Rect(8, 8, 8, 8)).apply(); getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); } { SCOPED_TRACE("negative rect"); - Transaction().setCrop_legacy(layer, Rect(8, 8, 0, 0)).apply(); + Transaction().setCrop(layer, Rect(8, 8, 0, 0)).apply(); getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); } } @@ -1001,7 +1001,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferQueue) { ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - Transaction().setCrop_legacy(layer, Rect(-128, -64, 128, 64)).apply(); + Transaction().setCrop(layer, Rect(-128, -64, 128, 64)).apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(0, 0, 32, 32), Color::RED); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); @@ -1056,7 +1056,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropWithTranslation_BufferQueue) { const Point position(32, 32); const Rect crop(8, 8, 24, 24); - Transaction().setPosition(layer, position.x, position.y).setCrop_legacy(layer, crop).apply(); + Transaction().setPosition(layer, position.x, position.y).setCrop(layer, crop).apply(); auto shot = getScreenCapture(); shot->expectColor(crop + position, Color::RED); shot->expectBorder(crop + position, Color::BLACK); @@ -1081,10 +1081,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropWithScale_BufferQueue) { ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - // crop_legacy is affected by matrix + // crop is affected by matrix Transaction() .setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f) - .setCrop_legacy(layer, Rect(8, 8, 24, 24)) + .setCrop(layer, Rect(8, 8, 24, 24)) .apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(16, 16, 48, 48), Color::RED); @@ -1096,8 +1096,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropWithResize_BufferQueue) { ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32)); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32)); - // setCrop_legacy is applied immediately by default, with or without resize pending - Transaction().setCrop_legacy(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply(); + // setCrop is applied immediately by default, with or without resize pending + Transaction().setCrop(layer, Rect(8, 8, 24, 24)).setSize(layer, 16, 16).apply(); { SCOPED_TRACE("resize pending"); auto shot = getScreenCapture(); @@ -1596,7 +1596,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorTransformBasic) { createLayer("test", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() - .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) + .setCrop(colorLayer, Rect(0, 0, 32, 32)) .setLayer(colorLayer, mLayerZBase + 1) .apply(); { @@ -1653,8 +1653,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorTransformOnParent) { ISurfaceComposerClient::eFXSurfaceEffect, parentLayer.get())); Transaction() - .setCrop_legacy(parentLayer, Rect(0, 0, 100, 100)) - .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) + .setCrop(parentLayer, Rect(0, 0, 100, 100)) + .setCrop(colorLayer, Rect(0, 0, 32, 32)) .setLayer(parentLayer, mLayerZBase + 1) .apply(); { @@ -1714,8 +1714,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorTransformOnChildAndParent) { ISurfaceComposerClient::eFXSurfaceEffect, parentLayer.get())); Transaction() - .setCrop_legacy(parentLayer, Rect(0, 0, 100, 100)) - .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) + .setCrop(parentLayer, Rect(0, 0, 100, 100)) + .setCrop(colorLayer, Rect(0, 0, 32, 32)) .setLayer(parentLayer, mLayerZBase + 1) .apply(); { diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index be6665b5ff..87c7b7d829 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -298,7 +298,7 @@ private: // set layer stack (b/68888219) Transaction t; t.setDisplayLayerStack(mDisplay, mDisplayLayerStack); - t.setCrop_legacy(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight)); + t.setCrop(mBlackBgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight)); t.setLayerStack(mBlackBgSurface, mDisplayLayerStack); t.setColor(mBlackBgSurface, half3{0, 0, 0}); t.setLayer(mBlackBgSurface, mLayerZBase); diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp index 67db717296..ac5e297e43 100644 --- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp @@ -145,7 +145,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetZNegative) { sp parent = LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceContainer); - Transaction().setCrop_legacy(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)).apply(); + Transaction().setCrop(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)).apply(); sp layerR; sp layerG; ASSERT_NO_FATAL_FAILURE(layerR = createLayer("test R", 32, 32)); @@ -199,7 +199,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadius) { if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { Transaction() .setCornerRadius(layer, cornerRadius) - .setCrop_legacy(layer, Rect(0, 0, size, size)) + .setCrop(layer, Rect(0, 0, size, size)) .apply(); } else { Transaction() @@ -236,13 +236,13 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusRotated) { auto transaction = Transaction() .setCornerRadius(parent, cornerRadius) - .setCrop_legacy(parent, Rect(0, 0, size, size)) + .setCrop(parent, Rect(0, 0, size, size)) .reparent(child, parent) .setPosition(child, 0, size) // Rotate by half PI .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f); if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - transaction.setCrop_legacy(parent, Rect(0, 0, size, size)); + transaction.setCrop(parent, Rect(0, 0, size, size)); } else { transaction.setFrame(parent, Rect(0, 0, size, size)); } @@ -278,7 +278,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusChildCrop) { if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { Transaction() .setCornerRadius(parent, cornerRadius) - .setCrop_legacy(parent, Rect(0, 0, size, size)) + .setCrop(parent, Rect(0, 0, size, size)) .reparent(child, parent) .setPosition(child, 0, size / 2) .apply(); @@ -351,7 +351,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { Transaction() .setLayer(blurLayer, mLayerZBase + 3) .setBackgroundBlurRadius(blurLayer, blurRadius) - .setCrop_legacy(blurLayer, blurRect) + .setCrop(blurLayer, blurRect) .setFrame(blurLayer, blurRect) .setSize(blurLayer, blurRect.getWidth(), blurRect.getHeight()) .setAlpha(blurLayer, 0.0f) @@ -516,7 +516,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBufferFormat) { .setLayer(layer, INT32_MAX - 1) .show(layer) .setLayerStack(behindLayer, mDisplayLayerStack) - .setCrop_legacy(behindLayer, crop) + .setCrop(behindLayer, crop) .setLayer(behindLayer, INT32_MAX - 2) .show(behindLayer) .apply(); diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp index f8a0bc1124..4753362292 100644 --- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp @@ -43,7 +43,7 @@ TEST_P(LayerTypeTransactionTest, SetRelativeZNegative) { sp parent = LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */, ISurfaceComposerClient::eFXSurfaceContainer); - Transaction().setCrop_legacy(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)).apply(); + Transaction().setCrop(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)).apply(); sp layerR; sp layerG; sp layerB; @@ -84,8 +84,8 @@ TEST_P(LayerTypeTransactionTest, SetLayerAndRelative) { .setColor(parent, half3{0.0f, 0.0f, 0.0f}) .show(childLayer) .show(parent) - .setCrop_legacy(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)) - .setCrop_legacy(childLayer, Rect(0, 0, 20, 30)) + .setCrop(parent, Rect(0, 0, mDisplayWidth, mDisplayHeight)) + .setCrop(childLayer, Rect(0, 0, 20, 30)) .apply(); Transaction().setRelativeLayer(childLayer, parent, -1).setLayer(childLayer, 1).apply(); diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp index ec826aed9c..e4a1f6697d 100644 --- a/services/surfaceflinger/tests/LayerUpdate_test.cpp +++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp @@ -131,7 +131,7 @@ protected: asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 64, 64); t.setPosition(mFGSurfaceControl, 64, 64); - t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64)); + t.setCrop(mFGSurfaceControl, Rect(0, 0, 64, 64)); }); EXPECT_INITIAL_STATE("After restoring initial state"); @@ -225,7 +225,7 @@ TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) { PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get()); TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200); SurfaceComposerClient::Transaction{} - .setCrop_legacy(childNoBuffer, Rect(0, 0, 10, 10)) + .setCrop(childNoBuffer, Rect(0, 0, 10, 10)) .show(childNoBuffer) .show(childBuffer) .apply(true); @@ -234,9 +234,7 @@ TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) { sc->expectChildColor(73, 73); sc->expectFGColor(74, 74); } - SurfaceComposerClient::Transaction{} - .setCrop_legacy(childNoBuffer, Rect(0, 0, 20, 20)) - .apply(true); + SurfaceComposerClient::Transaction{}.setCrop(childNoBuffer, Rect(0, 0, 20, 20)).apply(true); { ScreenCapture::captureScreen(&sc); sc->expectChildColor(73, 73); @@ -351,7 +349,7 @@ TEST_F(ChildLayerTest, ChildLayerCropping) { t.show(mChild); t.setPosition(mChild, 0, 0); t.setPosition(mFGSurfaceControl, 0, 0); - t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5)); + t.setCrop(mFGSurfaceControl, Rect(0, 0, 5, 5)); }); { @@ -947,7 +945,7 @@ TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) { ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get()); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { - t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10)); + t.setCrop(cropLayer, Rect(5, 5, 10, 10)); t.setColor(colorLayer, half3{0, 0, 0}); t.show(cropLayer); t.show(colorLayer); @@ -1007,7 +1005,7 @@ TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) { t.show(boundlessLayerRightShift); t.setPosition(boundlessLayerDownShift, 0, 32); t.show(boundlessLayerDownShift); - t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64)); + t.setCrop(colorLayer, Rect(0, 0, 64, 64)); t.setColor(colorLayer, half3{0, 0, 0}); t.show(colorLayer); }); @@ -1043,7 +1041,7 @@ TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) { // expect the child layer to be cropped. t.setPosition(boundlessLayer, 32, 32); t.show(boundlessLayer); - t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64)); + t.setCrop(colorLayer, Rect(0, 0, 64, 64)); // undo shift by parent t.setPosition(colorLayer, -32, -32); t.setColor(colorLayer, half3{0, 0, 0}); @@ -1074,7 +1072,7 @@ TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) { t.setLayer(rootBoundlessLayer, INT32_MAX - 1); t.setPosition(rootBoundlessLayer, 32, 32); t.show(rootBoundlessLayer); - t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64)); + t.setCrop(colorLayer, Rect(0, 0, 64, 64)); t.setColor(colorLayer, half3{0, 0, 0}); t.show(colorLayer); t.hide(mFGSurfaceControl); diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp index 16826c1f61..613b21ef04 100644 --- a/services/surfaceflinger/tests/MirrorLayer_test.cpp +++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp @@ -36,7 +36,7 @@ protected: asTransaction([&](Transaction& t) { t.setDisplayLayerStack(display, 0); t.setLayer(mParentLayer, INT32_MAX - 2).show(mParentLayer); - t.setCrop_legacy(mChildLayer, Rect(0, 0, 400, 400)).show(mChildLayer); + t.setCrop(mChildLayer, Rect(0, 0, 400, 400)).show(mChildLayer); t.setPosition(mChildLayer, 50, 50); t.setFlags(mParentLayer, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque); t.setFlags(mChildLayer, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque); @@ -58,7 +58,7 @@ TEST_F(MirrorLayerTest, MirrorColorLayer) { createColorLayer("Grandchild layer", Color::BLUE, mChildLayer.get()); Transaction() .setFlags(grandchild, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque) - .setCrop_legacy(grandchild, Rect(0, 0, 200, 200)) + .setCrop(grandchild, Rect(0, 0, 200, 200)) .show(grandchild) .apply(); diff --git a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp index eaf54e38ec..08de01cdfb 100644 --- a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp +++ b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp @@ -71,7 +71,7 @@ protected: ASSERT_TRUE(mColorLayer->isValid()); asTransaction([&](Transaction& t) { t.setLayerStack(mColorLayer, layerStack); - t.setCrop_legacy(mColorLayer, Rect(0, 0, 30, 40)); + t.setCrop(mColorLayer, Rect(0, 0, 30, 40)); t.setLayer(mColorLayer, INT32_MAX - 2); t.setColor(mColorLayer, half3{mExpectedColor.r / 255.0f, mExpectedColor.g / 255.0f, diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp index 4598f9dc84..b0753c842e 100644 --- a/services/surfaceflinger/tests/ScreenCapture_test.cpp +++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp @@ -328,7 +328,7 @@ TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) { TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) { sp child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get()); Rect layerCrop(0, 0, 10, 10); - SurfaceComposerClient::Transaction().setCrop_legacy(child, layerCrop).show(child).apply(true); + SurfaceComposerClient::Transaction().setCrop(child, layerCrop).show(child).apply(true); LayerCaptureArgs captureArgs; captureArgs.layerHandle = child->getHandle(); @@ -623,7 +623,7 @@ TEST_F(ScreenCaptureTest, CaptureDisplayPrimaryDisplayOnly) { .setLayerStack(layer, 0) .setLayer(layer, INT32_MAX) .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255}) - .setCrop_legacy(layer, bounds) + .setCrop(layer, bounds) .apply(); DisplayCaptureArgs captureArgs; @@ -671,8 +671,8 @@ TEST_F(ScreenCaptureTest, CaptureDisplayChildPrimaryDisplayOnly) { .setLayer(layer, INT32_MAX) .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255}) .setColor(childLayer, {childColor.r / 255, childColor.g / 255, childColor.b / 255}) - .setCrop_legacy(layer, bounds) - .setCrop_legacy(childLayer, childBounds) + .setCrop(layer, bounds) + .setCrop(childLayer, childBounds) .apply(); DisplayCaptureArgs captureArgs; @@ -853,9 +853,7 @@ TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) { } TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) { - SurfaceComposerClient::Transaction() - .setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 1, 1)) - .apply(true); + SurfaceComposerClient::Transaction().setCrop(mFGSurfaceControl, Rect(0, 0, 1, 1)).apply(true); // Even though the parent is cropped out we should still capture the child. diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index a20d5c62d5..d9cab42aae 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -370,7 +370,7 @@ void SurfaceInterceptorTest::layerUpdate(Transaction& t) { } void SurfaceInterceptorTest::cropUpdate(Transaction& t) { - t.setCrop_legacy(mBGSurfaceControl, CROP_UPDATE); + t.setCrop(mBGSurfaceControl, CROP_UPDATE); } void SurfaceInterceptorTest::matrixUpdate(Transaction& t) { diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index 11bd9ebbb8..820f248dbb 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -1324,7 +1324,7 @@ protected: { TransactionScope ts(*sFakeComposer); Rect cropRect(16, 16, 32, 32); - ts.setCrop_legacy(mFGSurfaceControl, cropRect); + ts.setCrop(mFGSurfaceControl, cropRect); } ASSERT_EQ(2, sFakeComposer->getFrameCount()); @@ -1692,7 +1692,7 @@ protected: ts.show(mChild); ts.setPosition(mChild, 0, 0); ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.setCrop_legacy(Base::mFGSurfaceControl, Rect(0, 0, 5, 5)); + ts.setCrop(Base::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 @@ -1915,7 +1915,7 @@ protected: TransactionScope ts(*Base::sFakeComposer); ts.setColor(Base::mChild, {LIGHT_GRAY.r / 255.0f, LIGHT_GRAY.g / 255.0f, LIGHT_GRAY.b / 255.0f}); - ts.setCrop_legacy(Base::mChild, Rect(0, 0, 10, 10)); + ts.setCrop(Base::mChild, Rect(0, 0, 10, 10)); } Base::sFakeComposer->runVSyncAndWait(); @@ -2010,7 +2010,7 @@ protected: TransactionScope ts(*Base::sFakeComposer); ts.setSize(Base::mFGSurfaceControl, 64, 64); ts.setPosition(Base::mFGSurfaceControl, 64, 64); - ts.setCrop_legacy(Base::mFGSurfaceControl, Rect(0, 0, 64, 64)); + ts.setCrop(Base::mFGSurfaceControl, Rect(0, 0, 64, 64)); } void Test_SurfacePositionLatching() { @@ -2043,7 +2043,7 @@ protected: { TransactionScope ts(*Base::sFakeComposer); ts.setSize(Base::mFGSurfaceControl, 128, 128); - ts.setCrop_legacy(Base::mFGSurfaceControl, Rect(0, 0, 63, 63)); + ts.setCrop(Base::mFGSurfaceControl, Rect(0, 0, 63, 63)); } auto referenceFrame1 = Base::mBaseFrame; diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index c3946cb1b3..4e1c0c77ea 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -884,7 +884,7 @@ struct EffectLayerVariant : public BaseLayerVariant { }); auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer); - layerDrawingState.crop_legacy = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH); + layerDrawingState.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH); return layer; } -- cgit v1.2.3-59-g8ed1b From 1506b181085e1f2156283d0e7b62fe94a918427f Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Mon, 22 Feb 2021 14:35:15 -0800 Subject: Introduce release buffer callback for BufferStateLayer Currently BLAST clients use the TransactionCompleted callbacks to determine when to release buffers. The TransactionCompleted callback is overloaded. For transactions without buffers, the callback is called when the transaction is applied on the server. If the Transaction contains one or more buffers, the callback is called when all the buffers are latched and ready to be presented. If we have multiple buffers on multiple transactions, where one or more buffers maybe dropped, the pending callbacks are called together. This may delay signaling the client when a buffer can be released. To fix this, we introduce a new buffer release callback that is called as soon as a buffer is dropped by the server or when a new buffer has been latched and the buffer will no longer be presented. This new callback provides a graphic bufferid to identify the buffer that can be released and a release fence to wait on. BlastBufferQueue has been switched to use this new callback. Other BLAST users continue to use the existing callback. Test: go/wm-smoke Test: atest ReleaseBufferCallbackTest Bug: 178385281 Change-Id: Idd88e4994e543443198a5a8cfa0e3f5f67d5d482 --- libs/gui/BLASTBufferQueue.cpp | 107 +++---- libs/gui/ITransactionCompletedListener.cpp | 13 +- libs/gui/LayerState.cpp | 17 +- libs/gui/SurfaceComposerClient.cpp | 84 +++++- libs/gui/include/gui/BLASTBufferQueue.h | 18 +- .../include/gui/ITransactionCompletedListener.h | 8 +- libs/gui/include/gui/LayerState.h | 7 +- libs/gui/include/gui/SurfaceComposerClient.h | 19 +- libs/gui/tests/BLASTBufferQueue_test.cpp | 53 +++- services/surfaceflinger/BufferStateLayer.cpp | 54 +++- services/surfaceflinger/BufferStateLayer.h | 8 +- services/surfaceflinger/Layer.cpp | 3 + services/surfaceflinger/Layer.h | 10 +- services/surfaceflinger/RefreshRateOverlay.cpp | 6 +- services/surfaceflinger/SurfaceFlinger.cpp | 3 +- .../surfaceflinger/TransactionCallbackInvoker.cpp | 3 +- .../surfaceflinger/TransactionCallbackInvoker.h | 1 + services/surfaceflinger/tests/Android.bp | 1 + .../surfaceflinger/tests/LayerCallback_test.cpp | 21 +- .../tests/ReleaseBufferCallback_test.cpp | 312 +++++++++++++++++++++ .../tests/unittests/TransactionFrameTracerTest.cpp | 3 +- .../unittests/TransactionSurfaceFrameTest.cpp | 26 +- 22 files changed, 652 insertions(+), 125 deletions(-) create mode 100644 services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 82c9268feb..f778232803 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -169,8 +169,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp= mTransactionCompleteFrameNumber) { + if (currFrameNumber > mTransactionCompleteFrameNumber) { + BQA_LOGE("transactionCallback received for a newer framenumber=%" PRIu64 + " than expected=%" PRIu64, + currFrameNumber, mTransactionCompleteFrameNumber); + } + transactionCompleteCallback = std::move(mTransactionCompleteCallback); + mTransactionCompleteFrameNumber = 0; } - mBufferItemConsumer->releaseBuffer(mPendingReleaseItem.item, - mPendingReleaseItem.releaseFence - ? mPendingReleaseItem.releaseFence - : Fence::NO_FENCE); - mNumAcquired--; - mPendingReleaseItem.item = BufferItem(); - mPendingReleaseItem.releaseFence = nullptr; - } - - if (mSubmitted.empty()) { - BQA_LOGE("ERROR: callback with no corresponding submitted buffer item"); } - mPendingReleaseItem.item = std::move(mSubmitted.front()); - mSubmitted.pop(); - - processNextBufferLocked(false /* useNextTransaction */); - currFrameNumber = mPendingReleaseItem.item.mFrameNumber; - if (mTransactionCompleteCallback && mTransactionCompleteFrameNumber == currFrameNumber) { - transactionCompleteCallback = std::move(mTransactionCompleteCallback); - mTransactionCompleteFrameNumber = 0; - } - - mCallbackCV.notify_all(); decStrong((void*)transactionCallbackThunk); } @@ -295,15 +274,46 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp context, uint64_t graphicBufferId, + const sp& releaseFence) { + sp blastBufferQueue = context.promote(); + ALOGV("releaseBufferCallbackThunk graphicBufferId=%" PRIu64 " blastBufferQueue=%s", + graphicBufferId, blastBufferQueue ? "alive" : "dead"); + if (blastBufferQueue) { + blastBufferQueue->releaseBufferCallback(graphicBufferId, releaseFence); + } +} + +void BLASTBufferQueue::releaseBufferCallback(uint64_t graphicBufferId, + const sp& releaseFence) { ATRACE_CALL(); - BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction)); + std::unique_lock _lock{mMutex}; + BQA_LOGV("releaseBufferCallback graphicBufferId=%" PRIu64, graphicBufferId); + + auto it = mSubmitted.find(graphicBufferId); + if (it == mSubmitted.end()) { + BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %" PRIu64, + graphicBufferId); + return; + } + mBufferItemConsumer->releaseBuffer(it->second, releaseFence); + mSubmitted.erase(it); + mNumAcquired--; + processNextBufferLocked(false /* useNextTransaction */); + mCallbackCV.notify_all(); +} + +void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { + ATRACE_CALL(); // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't // include the extra buffer when checking if we can acquire the next buffer. const bool includeExtraAcquire = !useNextTransaction; if (mNumFrameAvailable == 0 || maxBuffersAcquired(includeExtraAcquire)) { - BQA_LOGV("processNextBufferLocked waiting for frame available or callback"); mCallbackCV.notify_all(); return; } @@ -353,7 +363,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { } mNumAcquired++; - mSubmitted.push(bufferItem); + mSubmitted[buffer->getId()] = bufferItem; bool needsDisconnect = false; mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect); @@ -369,7 +379,10 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { mLastBufferScalingMode = bufferItem.mScalingMode; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; - t->setBuffer(mSurfaceControl, buffer); + auto releaseBufferCallback = + std::bind(releaseBufferCallbackThunk, wp(this) /* callbackContext */, + std::placeholders::_1, std::placeholders::_2); + t->setBuffer(mSurfaceControl, buffer, releaseBufferCallback); t->setDataspace(mSurfaceControl, static_cast(bufferItem.mDataSpace)); t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata); t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage); @@ -427,9 +440,12 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { } BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64 - " applyTransaction=%s mTimestamp=%" PRId64 " mPendingTransactions.size=%d", + " applyTransaction=%s mTimestamp=%" PRId64 "%s mPendingTransactions.size=%d" + " graphicBufferId=%" PRIu64, mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction), - bufferItem.mTimestamp, static_cast(mPendingTransactions.size())); + bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "", + static_cast(mPendingTransactions.size()), + bufferItem.mGraphicBuffer->getId()); } Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { @@ -444,18 +460,17 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { std::unique_lock _lock{mMutex}; const bool nextTransactionSet = mNextTransaction != nullptr; - BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " nextTransactionSet=%s mFlushShadowQueue=%s", - item.mFrameNumber, toString(nextTransactionSet), toString(mFlushShadowQueue)); - - if (nextTransactionSet || mFlushShadowQueue) { + if (nextTransactionSet) { while (mNumFrameAvailable > 0 || maxBuffersAcquired(false /* includeExtraAcquire */)) { BQA_LOGV("waiting in onFrameAvailable..."); mCallbackCV.wait(_lock); } } - mFlushShadowQueue = false; // add to shadow queue mNumFrameAvailable++; + + BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " nextTransactionSet=%s", item.mFrameNumber, + toString(nextTransactionSet)); processNextBufferLocked(nextTransactionSet /* useNextTransaction */); } @@ -514,14 +529,12 @@ void BLASTBufferQueue::setTransactionCompleteCallback( } // Check if we have acquired the maximum number of buffers. -// As a special case, we wait for the first callback before acquiring the second buffer so we -// can ensure the first buffer is presented if multiple buffers are queued in succession. // Consumer can acquire an additional buffer if that buffer is not droppable. Set // includeExtraAcquire is true to include this buffer to the count. Since this depends on the state // of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE. bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const { int maxAcquiredBuffers = MAX_ACQUIRED_BUFFERS + (includeExtraAcquire ? 2 : 1); - return mNumAcquired == maxAcquiredBuffers || (!mInitialCallbackReceived && mNumAcquired == 1); + return mNumAcquired == maxAcquiredBuffers; } class BBQSurface : public Surface { diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp index 0ded9361bf..9b5be1f15a 100644 --- a/libs/gui/ITransactionCompletedListener.cpp +++ b/libs/gui/ITransactionCompletedListener.cpp @@ -27,7 +27,8 @@ namespace { // Anonymous enum class Tag : uint32_t { ON_TRANSACTION_COMPLETED = IBinder::FIRST_CALL_TRANSACTION, - LAST = ON_TRANSACTION_COMPLETED, + ON_RELEASE_BUFFER, + LAST = ON_RELEASE_BUFFER, }; } // Anonymous namespace @@ -122,6 +123,7 @@ status_t SurfaceStats::writeToParcel(Parcel* output) const { for (const auto& data : jankData) { SAFE_PARCEL(output->writeParcelable, data); } + SAFE_PARCEL(output->writeUint64, previousBufferId); return NO_ERROR; } @@ -144,6 +146,7 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->readParcelable, &data); jankData.push_back(data); } + SAFE_PARCEL(input->readUint64, &previousBufferId); return NO_ERROR; } @@ -245,6 +248,12 @@ public: onTransactionCompleted)>(Tag::ON_TRANSACTION_COMPLETED, stats); } + + void onReleaseBuffer(uint64_t graphicBufferId, sp releaseFence) override { + callRemoteAsync(Tag::ON_RELEASE_BUFFER, + graphicBufferId, releaseFence); + } }; // Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see @@ -263,6 +272,8 @@ status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel& case Tag::ON_TRANSACTION_COMPLETED: return callLocalAsync(data, reply, &ITransactionCompletedListener::onTransactionCompleted); + case Tag::ON_RELEASE_BUFFER: + return callLocalAsync(data, reply, &ITransactionCompletedListener::onReleaseBuffer); } } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 6bb8bf2d5b..7a18ca61fe 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -63,7 +63,8 @@ layer_state_t::layer_state_t() fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0), frameTimelineInfo(), - autoRefresh(false) { + autoRefresh(false), + releaseBufferListener(nullptr) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -152,6 +153,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeUint64, frameNumber); SAFE_PARCEL(frameTimelineInfo.write, output); SAFE_PARCEL(output.writeBool, autoRefresh); + SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(releaseBufferListener)); SAFE_PARCEL(output.writeUint32, blurRegions.size()); for (auto region : blurRegions) { @@ -275,6 +277,12 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(frameTimelineInfo.read, input); SAFE_PARCEL(input.readBool, &autoRefresh); + tmpBinder = nullptr; + SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder); + if (tmpBinder) { + releaseBufferListener = checked_interface_cast(tmpBinder); + } + uint32_t numRegions = 0; SAFE_PARCEL(input.readUint32, &numRegions); blurRegions.clear(); @@ -543,6 +551,13 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eAutoRefreshChanged; autoRefresh = other.autoRefresh; } + if (other.what & eReleaseBufferListenerChanged) { + if (releaseBufferListener) { + ALOGW("Overriding releaseBufferListener"); + } + what |= eReleaseBufferListenerChanged; + releaseBufferListener = other.releaseBufferListener; + } if (other.what & eStretchChanged) { what |= eStretchChanged; stretchEffect = other.stretchEffect; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c16a98f42f..11fe49039d 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -195,6 +195,17 @@ void TransactionCompletedListener::removeJankListener(const sp } } +void TransactionCompletedListener::setReleaseBufferCallback(uint64_t graphicBufferId, + ReleaseBufferCallback listener) { + std::scoped_lock lock(mMutex); + mReleaseBufferCallbacks[graphicBufferId] = listener; +} + +void TransactionCompletedListener::removeReleaseBufferCallback(uint64_t graphicBufferId) { + std::scoped_lock lock(mMutex); + mReleaseBufferCallbacks.erase(graphicBufferId); +} + void TransactionCompletedListener::addSurfaceStatsListener(void* context, void* cookie, sp surfaceControl, SurfaceStatsCallback listener) { std::lock_guard lock(mMutex); @@ -275,6 +286,20 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener .surfaceControls[surfaceStats.surfaceControl] ->setTransformHint(surfaceStats.transformHint); } + // If there is buffer id set, we look up any pending client release buffer callbacks + // and call them. This is a performance optimization when we have a transaction + // callback and a release buffer callback happening at the same time to avoid an + // additional ipc call from the server. + if (surfaceStats.previousBufferId) { + ReleaseBufferCallback callback = + popReleaseBufferCallbackLocked(surfaceStats.previousBufferId); + if (callback) { + callback(surfaceStats.previousBufferId, + surfaceStats.previousReleaseFence + ? surfaceStats.previousReleaseFence + : Fence::NO_FENCE); + } + } } callbackFunction(transactionStats.latchTime, transactionStats.presentFence, @@ -297,6 +322,32 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } } +void TransactionCompletedListener::onReleaseBuffer(uint64_t graphicBufferId, + sp releaseFence) { + ReleaseBufferCallback callback; + { + std::scoped_lock lock(mMutex); + callback = popReleaseBufferCallbackLocked(graphicBufferId); + } + if (!callback) { + ALOGE("Could not call release buffer callback, buffer not found %" PRIu64, graphicBufferId); + return; + } + callback(graphicBufferId, releaseFence); +} + +ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLocked( + uint64_t graphicBufferId) { + ReleaseBufferCallback callback; + auto itr = mReleaseBufferCallbacks.find(graphicBufferId); + if (itr == mReleaseBufferCallbacks.end()) { + return nullptr; + } + callback = itr->second; + mReleaseBufferCallbacks.erase(itr); + return callback; +} + // --------------------------------------------------------------------------- void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId); @@ -1219,17 +1270,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( - const sp& sc, const sp& buffer) { + const sp& sc, const sp& buffer, + ReleaseBufferCallback callback) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } + removeReleaseBufferCallback(s); s->what |= layer_state_t::eBufferChanged; s->buffer = buffer; if (mIsAutoTimestamp) { mDesiredPresentTime = systemTime(); } + setReleaseBufferCallback(s, callback); registerSurfaceControlForCallback(sc); @@ -1237,6 +1291,34 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe return *this; } +void SurfaceComposerClient::Transaction::removeReleaseBufferCallback(layer_state_t* s) { + if (!s->releaseBufferListener) { + return; + } + + s->what &= ~static_cast(layer_state_t::eReleaseBufferListenerChanged); + s->releaseBufferListener = nullptr; + TransactionCompletedListener::getInstance()->removeReleaseBufferCallback(s->buffer->getId()); +} + +void SurfaceComposerClient::Transaction::setReleaseBufferCallback(layer_state_t* s, + ReleaseBufferCallback callback) { + if (!callback) { + return; + } + + if (!s->buffer) { + ALOGW("Transaction::setReleaseBufferCallback" + "ignored trying to set a callback on a null buffer."); + return; + } + + s->what |= layer_state_t::eReleaseBufferListenerChanged; + s->releaseBufferListener = TransactionCompletedListener::getIInstance(); + auto listener = TransactionCompletedListener::getInstance(); + listener->setReleaseBufferCallback(s->buffer->getId(), callback); +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAcquireFence( const sp& sc, const sp& fence) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index dd8e714e23..0173ffd68e 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -89,13 +89,14 @@ public: void transactionCallback(nsecs_t latchTime, const sp& presentFence, const std::vector& stats); + void releaseBufferCallback(uint64_t graphicBufferId, const sp& releaseFence); void setNextTransaction(SurfaceComposerClient::Transaction *t); void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber); void setTransactionCompleteCallback(uint64_t frameNumber, std::function&& transactionCompleteCallback); void update(const sp& surface, uint32_t width, uint32_t height, int32_t format); - void flushShadowQueue() { mFlushShadowQueue = true; } + void flushShadowQueue() {} status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); status_t setFrameTimelineInfo(const FrameTimelineInfo& info); @@ -132,16 +133,10 @@ private: int32_t mNumFrameAvailable GUARDED_BY(mMutex); int32_t mNumAcquired GUARDED_BY(mMutex); - bool mInitialCallbackReceived GUARDED_BY(mMutex) = false; - struct PendingReleaseItem { - BufferItem item; - sp releaseFence; - }; - std::queue mSubmitted GUARDED_BY(mMutex); - // Keep a reference to the currently presented buffer so we can release it when the next buffer - // is ready to be presented. - PendingReleaseItem mPendingReleaseItem GUARDED_BY(mMutex); + // Keep a reference to the submitted buffers so we can release when surfaceflinger drops the + // buffer or the buffer has been presented and a new buffer is ready to be presented. + std::unordered_map mSubmitted GUARDED_BY(mMutex); ui::Size mSize GUARDED_BY(mMutex); ui::Size mRequestedSize GUARDED_BY(mMutex); @@ -157,9 +152,6 @@ private: std::vector> mPendingTransactions GUARDED_BY(mMutex); - // If set to true, the next queue buffer will wait until the shadow queue has been processed by - // the adapter. - bool mFlushShadowQueue = false; // Last requested auto refresh state set by the producer. The state indicates that the consumer // should acquire the next frame as soon as it can and not wait for a frame to become available. // This is only relevant for shared buffer mode. diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h index cb17ceecd3..098760e89d 100644 --- a/libs/gui/include/gui/ITransactionCompletedListener.h +++ b/libs/gui/include/gui/ITransactionCompletedListener.h @@ -87,13 +87,14 @@ public: SurfaceStats() = default; SurfaceStats(const sp& sc, nsecs_t time, const sp& prevReleaseFence, uint32_t hint, FrameEventHistoryStats frameEventStats, - std::vector jankData) + std::vector jankData, uint64_t previousBufferId) : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence), transformHint(hint), eventStats(frameEventStats), - jankData(std::move(jankData)) {} + jankData(std::move(jankData)), + previousBufferId(previousBufferId) {} sp surfaceControl; nsecs_t acquireTime = -1; @@ -101,6 +102,7 @@ public: uint32_t transformHint = 0; FrameEventHistoryStats eventStats; std::vector jankData; + uint64_t previousBufferId; }; class TransactionStats : public Parcelable { @@ -139,6 +141,8 @@ public: DECLARE_META_INTERFACE(TransactionCompletedListener) virtual void onTransactionCompleted(ListenerStats stats) = 0; + + virtual void onReleaseBuffer(uint64_t graphicBufferId, sp releaseFence) = 0; }; class BnTransactionCompletedListener : public SafeBnInterface { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 183ec40fba..d68a9cfa4a 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -100,7 +100,7 @@ struct layer_state_t { eLayerStackChanged = 0x00000080, /* was eCropChanged_legacy, now available 0x00000100, */ eDeferTransaction_legacy = 0x00000200, - /* was ScalingModeChanged, now available 0x00000400, */ + eReleaseBufferListenerChanged = 0x00000400, eShadowRadiusChanged = 0x00000800, eReparentChildren = 0x00001000, /* was eDetachChildren, now available 0x00002000, */ @@ -248,6 +248,11 @@ struct layer_state_t { // Stretch effect to be applied to this layer StretchEffect stretchEffect; + + // Listens to when the buffer is safe to be released. This is used for blast + // layers only. The callback includes a release fence as well as the graphic + // buffer id to identify the buffer. + sp releaseBufferListener; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 88484c0bbf..f29983cef7 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -80,6 +80,9 @@ using TransactionCompletedCallbackTakesContext = using TransactionCompletedCallback = std::function& /*presentFence*/, const std::vector& /*stats*/)>; +using ReleaseBufferCallback = + std::function& /*releaseFence*/)>; + using SurfaceStatsCallback = std::function& /*presentFence*/, @@ -388,6 +391,8 @@ public: void cacheBuffers(); void registerSurfaceControlForCallback(const sp& sc); + void setReleaseBufferCallback(layer_state_t* state, ReleaseBufferCallback callback); + void removeReleaseBufferCallback(layer_state_t* state); public: Transaction(); @@ -471,7 +476,8 @@ public: Transaction& setTransformToDisplayInverse(const sp& sc, bool transformToDisplayInverse); Transaction& setFrame(const sp& sc, const Rect& frame); - Transaction& setBuffer(const sp& sc, const sp& buffer); + Transaction& setBuffer(const sp& sc, const sp& buffer, + ReleaseBufferCallback callback = nullptr); Transaction& setCachedBuffer(const sp& sc, int32_t bufferId); Transaction& setAcquireFence(const sp& sc, const sp& fence); Transaction& setDataspace(const sp& sc, ui::Dataspace dataspace); @@ -650,6 +656,8 @@ class TransactionCompletedListener : public BnTransactionCompletedListener { std::unordered_map mCallbacks GUARDED_BY(mMutex); std::multimap, sp> mJankListeners GUARDED_BY(mMutex); + std::unordered_map + mReleaseBufferCallbacks GUARDED_BY(mMutex); std::multimap, SurfaceStatsCallbackEntry> mSurfaceStatsListeners GUARDED_BY(mMutex); @@ -683,8 +691,15 @@ public: SurfaceStatsCallback listener); void removeSurfaceStatsListener(void* context, void* cookie); - // Overrides BnTransactionCompletedListener's onTransactionCompleted + void setReleaseBufferCallback(uint64_t /* graphicsBufferId */, ReleaseBufferCallback); + void removeReleaseBufferCallback(uint64_t /* graphicsBufferId */); + + // BnTransactionCompletedListener overrides void onTransactionCompleted(ListenerStats stats) override; + void onReleaseBuffer(uint64_t /* graphicsBufferId */, sp releaseFence) override; + +private: + ReleaseBufferCallback popReleaseBufferCallbackLocked(uint64_t /* graphicsBufferId */); }; } // namespace android diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index 7895e99cc3..fe48d88376 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -73,13 +73,34 @@ public: void waitForCallbacks() { std::unique_lock lock{mBlastBufferQueueAdapter->mMutex}; - while (mBlastBufferQueueAdapter->mSubmitted.size() > 0) { + // Wait until all but one of the submitted buffers have been released. + while (mBlastBufferQueueAdapter->mSubmitted.size() > 1) { mBlastBufferQueueAdapter->mCallbackCV.wait(lock); } } + void setTransactionCompleteCallback(int64_t frameNumber) { + mBlastBufferQueueAdapter->setTransactionCompleteCallback(frameNumber, [&](int64_t frame) { + std::unique_lock lock{mMutex}; + mLastTransactionCompleteFrameNumber = frame; + mCallbackCV.notify_all(); + }); + } + + void waitForCallback(int64_t frameNumber) { + std::unique_lock lock{mMutex}; + // Wait until all but one of the submitted buffers have been released. + while (mLastTransactionCompleteFrameNumber < frameNumber) { + mCallbackCV.wait(lock); + } + } + private: sp mBlastBufferQueueAdapter; + + std::mutex mMutex; + std::condition_variable mCallbackCV; + int64_t mLastTransactionCompleteFrameNumber = -1; }; class BLASTBufferQueueTest : public ::testing::Test { @@ -128,7 +149,7 @@ protected: mCaptureArgs.dataspace = ui::Dataspace::V0_SRGB; } - void setUpProducer(BLASTBufferQueueHelper adapter, sp& producer) { + void setUpProducer(BLASTBufferQueueHelper& adapter, sp& producer) { producer = adapter.getIGraphicBufferProducer(); setUpProducer(producer); } @@ -205,10 +226,10 @@ protected: EXPECT_GE(epsilon, abs(g - *(pixel + 1))); EXPECT_GE(epsilon, abs(b - *(pixel + 2))); } + ASSERT_EQ(false, ::testing::Test::HasFailure()); } } captureBuf->unlock(); - ASSERT_EQ(false, ::testing::Test::HasFailure()); } static status_t captureDisplay(DisplayCaptureArgs& captureArgs, @@ -315,7 +336,8 @@ TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) nsecs_t desiredPresentTime = systemTime() + nsecs_t(5 * 1e8); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(desiredPresentTime, true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mDisplayWidth, mDisplayHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); @@ -351,7 +373,8 @@ TEST_F(BLASTBufferQueueTest, onFrameAvailable_Apply) { buf->unlock(); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mDisplayWidth, mDisplayHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); @@ -396,7 +419,8 @@ TEST_F(BLASTBufferQueueTest, TripleBuffering) { nullptr, nullptr); ASSERT_EQ(NO_ERROR, ret); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mDisplayWidth, mDisplayHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); @@ -429,7 +453,8 @@ TEST_F(BLASTBufferQueueTest, SetCrop_Item) { buf->unlock(); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mDisplayWidth, mDisplayHeight / 2), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); @@ -486,7 +511,8 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { buf->unlock(); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(bufferSideLength, finalCropSideLength), NATIVE_WINDOW_SCALING_MODE_SCALE_CROP, 0, Fence::NO_FENCE); @@ -537,7 +563,8 @@ TEST_F(BLASTBufferQueueTest, CustomProducerListener) { ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, ret); ASSERT_EQ(OK, igbProducer->requestBuffer(slot, &buf)); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(mDisplayWidth, mDisplayHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE); @@ -577,7 +604,7 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { sp slowIgbProducer; setUpProducer(slowAdapter, slowIgbProducer); nsecs_t presentTimeDelay = std::chrono::nanoseconds(500ms).count(); - queueBuffer(slowIgbProducer, 0 /* r */, 0 /* g */, 0 /* b */, presentTimeDelay); + queueBuffer(slowIgbProducer, 0 /* r */, 255 /* g */, 0 /* b */, presentTimeDelay); BLASTBufferQueueHelper fastAdapter(bgSurface, mDisplayWidth, mDisplayHeight); sp fastIgbProducer; @@ -617,7 +644,8 @@ public: fillQuadrants(buf); IGraphicBufferProducer::QueueBufferOutput qbOutput; - IGraphicBufferProducer::QueueBufferInput input(systemTime(), false, HAL_DATASPACE_UNKNOWN, + IGraphicBufferProducer::QueueBufferInput input(systemTime(), true /* autotimestamp */, + HAL_DATASPACE_UNKNOWN, Rect(bufWidth, bufHeight), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, tr, Fence::NO_FENCE); @@ -838,6 +866,7 @@ TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) { IGraphicBufferProducer::QueueBufferOutput qbOutput; nsecs_t requestedPresentTimeA = 0; nsecs_t postedTimeA = 0; + adapter.setTransactionCompleteCallback(1); setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true); history.applyDelta(qbOutput.frameTimestamps); @@ -848,7 +877,7 @@ TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_Basic) { ASSERT_EQ(requestedPresentTimeA, events->requestedPresentTime); ASSERT_GE(events->postedTime, postedTimeA); - adapter.waitForCallbacks(); + adapter.waitForCallback(1); // queue another buffer so we query for frame event deltas nsecs_t requestedPresentTimeB = 0; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 96a0c3cd75..89dfb6fb6b 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -41,6 +41,16 @@ namespace android { using PresentState = frametimeline::SurfaceFrame::PresentState; +namespace { +void callReleaseBufferCallback(const sp& listener, + const sp& buffer, const sp& releaseFence) { + if (!listener) { + return; + } + listener->onReleaseBuffer(buffer->getId(), releaseFence ? releaseFence : Fence::NO_FENCE); +} +} // namespace + // clang-format off const std::array BufferStateLayer::IDENTITY_MATRIX{ 1, 0, 0, 0, @@ -65,7 +75,10 @@ BufferStateLayer::~BufferStateLayer() { // RenderEngine may have been using the buffer as an external texture // after the client uncached the buffer. auto& engine(mFlinger->getRenderEngine()); - engine.unbindExternalTextureBuffer(mBufferInfo.mBuffer->getId()); + const uint64_t bufferId = mBufferInfo.mBuffer->getId(); + engine.unbindExternalTextureBuffer(bufferId); + callReleaseBufferCallback(mDrawingState.releaseBufferListener, mBufferInfo.mBuffer, + mBufferInfo.mFence); } } @@ -74,6 +87,7 @@ status_t BufferStateLayer::addReleaseFence(const sp& ch, if (ch == nullptr) { return OK; } + ch->previousBufferId = mPreviousBufferId; if (!ch->previousReleaseFence.get()) { ch->previousReleaseFence = fence; return OK; @@ -190,6 +204,19 @@ void BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { handle->dequeueReadyTime = dequeueReadyTime; } + // If there are multiple transactions in this frame, set the previous id on the earliest + // transacton. We don't need to pass in the released buffer id to multiple transactions. + // The buffer id does not have to correspond to any particular transaction as long as the + // listening end point is the same but the client expects the first transaction callback that + // replaces the presented buffer to contain the release fence. This follows the same logic. + // see BufferStateLayer::onLayerDisplayed. + for (auto& handle : mDrawingState.callbackHandles) { + if (handle->releasePreviousBuffer) { + handle->previousBufferId = mPreviousBufferId; + break; + } + } + std::vector jankData; jankData.reserve(mPendingJankClassifications.size()); while (!mPendingJankClassifications.empty() @@ -344,8 +371,8 @@ bool BufferStateLayer::addFrameEvent(const sp& acquireFence, nsecs_t post bool BufferStateLayer::setBuffer(const sp& buffer, const sp& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, - std::optional dequeueTime, - const FrameTimelineInfo& info) { + std::optional dequeueTime, const FrameTimelineInfo& info, + const sp& releaseBufferListener) { ATRACE_CALL(); if (mCurrentState.buffer) { @@ -353,7 +380,10 @@ bool BufferStateLayer::setBuffer(const sp& buffer, const sp& buffer, const sp& newBuffer) { + if (mDrawingState.buffer != nullptr && mDrawingState.buffer != mBufferInfo.mBuffer && + newBuffer != mDrawingState.buffer) { // If we are about to update mDrawingState.buffer but it has not yet latched - // then we will drop a buffer and should decrement the pending buffer count. - // This logic may not work perfectly in the face of a BufferStateLayer being the - // deferred side of a deferred transaction, but we don't expect this use case. + // then we will drop a buffer and should decrement the pending buffer count and + // call any release buffer callbacks if set. + callReleaseBufferCallback(mDrawingState.releaseBufferListener, mDrawingState.buffer, + mDrawingState.acquireFence); decrementPendingBufferCount(); } - return Layer::doTransaction(flags); } } // namespace android diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index ebf40cb6e4..036e8d2e85 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -70,7 +70,8 @@ public: bool setBuffer(const sp& buffer, const sp& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, - std::optional dequeueTime, const FrameTimelineInfo& info) override; + std::optional dequeueTime, const FrameTimelineInfo& info, + const sp& transactionListener) override; bool setAcquireFence(const sp& fence) override; bool setDataspace(ui::Dataspace dataspace) override; bool setHdrMetadata(const HdrMetadata& hdrMetadata) override; @@ -111,7 +112,7 @@ public: // See mPendingBufferTransactions void decrementPendingBufferCount(); - uint32_t doTransaction(uint32_t flags) override; + void bufferMayChange(sp& newBuffer) override; std::atomic* getPendingBufferCounter() override { return &mPendingBufferTransactions; } std::string getPendingBufferCounterName() override { return mBlastTransactionName; } @@ -170,6 +171,9 @@ private: mutable bool mCurrentStateModified = false; bool mReleasePreviousBuffer = false; + + // Stores the last set acquire fence signal time used to populate the callback handle's acquire + // time. nsecs_t mCallbackHandleAcquireTime = -1; std::deque> mPendingJankClassifications; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 0015bf27d1..cd3e8add9a 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1048,6 +1048,9 @@ uint32_t Layer::doTransaction(uint32_t flags) { c.callbackHandles.push_back(handle); } + // Allow BufferStateLayer to release any unlatched buffers in drawing state. + bufferMayChange(c.buffer); + // Commit the transaction commitTransaction(c); mPendingStatesSnapshot = mPendingStates; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 26d8e7472a..85ff479344 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -312,6 +312,7 @@ public: // When the transaction was posted nsecs_t postTime; + sp releaseBufferListener; // SurfaceFrame that tracks the timeline of Transactions that contain a Buffer. Only one // such SurfaceFrame exists because only one buffer can be presented on the layer per vsync. // If multiple buffers are queued, the prior ones will be dropped, along with the @@ -466,7 +467,8 @@ public: nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/, uint64_t /* frameNumber */, std::optional /* dequeueTime */, - const FrameTimelineInfo& /*info*/) { + const FrameTimelineInfo& /*info*/, + const sp& /* releaseBufferListener */) { return false; }; virtual bool setAcquireFence(const sp& /*fence*/) { return false; }; @@ -773,6 +775,12 @@ public: */ virtual uint32_t doTransaction(uint32_t transactionFlags); + /* + * Called before updating the drawing state buffer. Used by BufferStateLayer to release any + * unlatched buffers in the drawing state. + */ + virtual void bufferMayChange(sp& /* newBuffer */){}; + /* * Remove relative z for the layer if its relative parent is not part of the * provided layer tree. diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index b29c624d00..1d00cc38f2 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -241,7 +241,8 @@ void RefreshRateOverlay::changeRefreshRate(const Fps& fps) { auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame]; mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {}, mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */), - std::nullopt /* dequeueTime */, FrameTimelineInfo{}); + std::nullopt /* dequeueTime */, FrameTimelineInfo{}, + nullptr /* releaseBufferListener */); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } @@ -254,7 +255,8 @@ void RefreshRateOverlay::onInvalidate() { auto buffer = buffers[mFrame]; mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {}, mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */), - std::nullopt /* dequeueTime */, FrameTimelineInfo{}); + std::nullopt /* dequeueTime */, FrameTimelineInfo{}, + nullptr /* releaseBufferListener */); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d048380dd2..61cc8a2ff0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4027,7 +4027,8 @@ uint32_t SurfaceFlinger::setClientStateLocked( : layer->getHeadFrameNumber(-1 /* expectedPresentTime */) + 1; if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime, isAutoTimestamp, - s.cachedBuffer, frameNumber, dequeueBufferTimestamp, info)) { + s.cachedBuffer, frameNumber, dequeueBufferTimestamp, info, + s.releaseBufferListener)) { flags |= eTraversalNeeded; } } else if (info.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp index a78510e902..3590e76cb9 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.cpp +++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp @@ -201,7 +201,8 @@ status_t TransactionCallbackInvoker::addCallbackHandle(const sp& handle->dequeueReadyTime); transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTime, handle->previousReleaseFence, - handle->transformHint, eventStats, jankData); + handle->transformHint, eventStats, jankData, + handle->previousBufferId); } return NO_ERROR; } diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h index a240c824a1..caa8a4fb45 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.h +++ b/services/surfaceflinger/TransactionCallbackInvoker.h @@ -50,6 +50,7 @@ public: nsecs_t refreshStartTime = 0; nsecs_t dequeueReadyTime = 0; uint64_t frameNumber = 0; + uint64_t previousBufferId = 0; }; class TransactionCallbackInvoker { diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index 78187f7e9d..b96725fa12 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -44,6 +44,7 @@ cc_test { "MultiDisplayLayerBounds_test.cpp", "RefreshRateOverlay_test.cpp", "RelativeZ_test.cpp", + "ReleaseBufferCallback_test.cpp", "ScreenCapture_test.cpp", "SetFrameRate_test.cpp", "SetGeometry_test.cpp", diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp index aa1cce2586..158801a705 100644 --- a/services/surfaceflinger/tests/LayerCallback_test.cpp +++ b/services/surfaceflinger/tests/LayerCallback_test.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" - #include #include @@ -25,6 +21,8 @@ #include "LayerTransactionTest.h" #include "utils/CallbackUtils.h" +using namespace std::chrono_literals; + namespace android { using android::hardware::graphics::common::V1_1::BufferUsage; @@ -801,7 +799,7 @@ TEST_F(LayerCallbackTest, DesiredPresentTime) { } // Try to present 100ms in the future - nsecs_t time = systemTime() + (100 * 1e6); + nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count(); transaction.setDesiredPresentTime(time); transaction.apply(); @@ -825,7 +823,7 @@ TEST_F(LayerCallbackTest, DesiredPresentTime_Multiple) { } // Try to present 100ms in the future - nsecs_t time = systemTime() + (100 * 1e6); + nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count(); transaction.setDesiredPresentTime(time); transaction.apply(); @@ -842,7 +840,7 @@ TEST_F(LayerCallbackTest, DesiredPresentTime_Multiple) { } // Try to present 33ms after the first frame - time += (33.3 * 1e6); + time += std::chrono::nanoseconds(33ms).count(); transaction.setDesiredPresentTime(time); transaction.apply(); @@ -870,7 +868,7 @@ TEST_F(LayerCallbackTest, DesiredPresentTime_OutOfOrder) { } // Try to present 100ms in the future - nsecs_t time = systemTime() + (100 * 1e6); + nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count(); transaction.setDesiredPresentTime(time); transaction.apply(); @@ -887,7 +885,7 @@ TEST_F(LayerCallbackTest, DesiredPresentTime_OutOfOrder) { } // Try to present 33ms before the previous frame - time -= (33.3 * 1e6); + time -= std::chrono::nanoseconds(33ms).count(); transaction.setDesiredPresentTime(time); transaction.apply(); @@ -914,7 +912,7 @@ TEST_F(LayerCallbackTest, DesiredPresentTime_Past) { } // Try to present 100ms in the past - nsecs_t time = systemTime() - (100 * 1e6); + nsecs_t time = systemTime() - std::chrono::nanoseconds(100ms).count(); transaction.setDesiredPresentTime(time); transaction.apply(); @@ -948,6 +946,3 @@ TEST_F(LayerCallbackTest, ExpectedPresentTime) { } } // namespace android - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" diff --git a/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp b/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp new file mode 100644 index 0000000000..fb7d41c81e --- /dev/null +++ b/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2021 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. + */ + +#include "LayerTransactionTest.h" +#include "utils/CallbackUtils.h" + +using namespace std::chrono_literals; + +namespace android { + +using android::hardware::graphics::common::V1_1::BufferUsage; + +::testing::Environment* const binderEnv = + ::testing::AddGlobalTestEnvironment(new BinderEnvironment()); + +// b/181132765 - disabled until cuttlefish failures are investigated +class ReleaseBufferCallbackHelper { +public: + static void function(void* callbackContext, uint64_t graphicsBufferId, + const sp& releaseFence) { + if (!callbackContext) { + FAIL() << "failed to get callback context"; + } + ReleaseBufferCallbackHelper* helper = + static_cast(callbackContext); + std::lock_guard lock(helper->mMutex); + helper->mCallbackDataQueue.emplace(graphicsBufferId, releaseFence); + helper->mConditionVariable.notify_all(); + } + + void getCallbackData(uint64_t* bufferId) { + std::unique_lock lock(mMutex); + if (mCallbackDataQueue.empty()) { + if (!mConditionVariable.wait_for(lock, std::chrono::seconds(3), + [&] { return !mCallbackDataQueue.empty(); })) { + FAIL() << "failed to get releaseBuffer callback"; + } + } + + auto callbackData = mCallbackDataQueue.front(); + mCallbackDataQueue.pop(); + *bufferId = callbackData.first; + } + + void verifyNoCallbacks() { + // Wait to see if there are extra callbacks + std::this_thread::sleep_for(300ms); + + std::lock_guard lock(mMutex); + EXPECT_EQ(mCallbackDataQueue.size(), 0) << "extra callbacks received"; + mCallbackDataQueue = {}; + } + + android::ReleaseBufferCallback getCallback() { + return std::bind(function, static_cast(this) /* callbackContext */, + std::placeholders::_1, std::placeholders::_2); + } + + std::mutex mMutex; + std::condition_variable mConditionVariable; + std::queue>> mCallbackDataQueue; +}; + +class ReleaseBufferCallbackTest : public LayerTransactionTest { +public: + virtual sp createBufferStateLayer() { + return createLayer(mClient, "test", 0, 0, ISurfaceComposerClient::eFXSurfaceBufferState); + } + + static void submitBuffer(const sp& layer, sp buffer, + sp fence, CallbackHelper& callback, + ReleaseBufferCallbackHelper& releaseCallback) { + Transaction t; + t.setBuffer(layer, buffer, releaseCallback.getCallback()); + t.setAcquireFence(layer, fence); + t.addTransactionCompletedCallback(callback.function, callback.getContext()); + t.apply(); + } + + static void waitForCallback(CallbackHelper& helper, const ExpectedResult& expectedResult) { + CallbackData callbackData; + helper.getCallbackData(&callbackData); + expectedResult.verifyCallbackData(callbackData); + } + + static void waitForReleaseBufferCallback(ReleaseBufferCallbackHelper& releaseCallback, + uint64_t expectedReleaseBufferId) { + uint64_t actualReleaseBufferId; + releaseCallback.getCallbackData(&actualReleaseBufferId); + EXPECT_EQ(expectedReleaseBufferId, actualReleaseBufferId); + releaseCallback.verifyNoCallbacks(); + } + static ReleaseBufferCallbackHelper* getReleaseBufferCallbackHelper() { + static std::vector sCallbacks; + sCallbacks.emplace_back(new ReleaseBufferCallbackHelper()); + return sCallbacks.back(); + } + + static sp getBuffer() { + return new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1, + BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::COMPOSER_OVERLAY, + "test"); + } +}; + +TEST_F(ReleaseBufferCallbackTest, DISABLED_PresentBuffer) { + sp layer = createBufferStateLayer(); + CallbackHelper transactionCallback; + ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper(); + + // If a buffer is being presented, we should not emit a release callback. + sp firstBuffer = getBuffer(); + submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, *releaseCallback); + ExpectedResult expected; + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks()); + + // if state doesn't change, no release callbacks are expected + Transaction t; + t.addTransactionCompletedCallback(transactionCallback.function, + transactionCallback.getContext()); + t.apply(); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, ExpectedResult())); + EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks()); + + // If a presented buffer is replaced, we should emit a release callback for the + // previously presented buffer. + sp secondBuffer = getBuffer(); + submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, *releaseCallback); + expected = ExpectedResult(); + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED, + ExpectedResult::PreviousBuffer::RELEASED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBuffer->getId())); +} + +TEST_F(ReleaseBufferCallbackTest, DISABLED_OffScreenLayer) { + sp layer = createBufferStateLayer(); + + CallbackHelper transactionCallback; + ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper(); + + // If a buffer is being presented, we should not emit a release callback. + sp firstBuffer = getBuffer(); + submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, *releaseCallback); + ExpectedResult expected; + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + releaseCallback->verifyNoCallbacks(); + + // If a layer is parented offscreen then it should not emit a callback since sf still owns + // the buffer and can render it again. + Transaction t; + t.reparent(layer, nullptr); + t.addTransactionCompletedCallback(transactionCallback.function, + transactionCallback.getContext()); + t.apply(); + expected = ExpectedResult(); + expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED, + ExpectedResult::PreviousBuffer::NOT_RELEASED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks()); + + // If a presented buffer is replaced, we should emit a release callback for the + // previously presented buffer. + sp secondBuffer = getBuffer(); + submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, *releaseCallback); + expected = ExpectedResult(); + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED, + ExpectedResult::PreviousBuffer::NOT_RELEASED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBuffer->getId())); + + // If continue to submit buffer we continue to get release callbacks + sp thirdBuffer = getBuffer(); + submitBuffer(layer, thirdBuffer, Fence::NO_FENCE, transactionCallback, *releaseCallback); + expected = ExpectedResult(); + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED, + ExpectedResult::PreviousBuffer::NOT_RELEASED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBuffer->getId())); +} + +TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_layerdestroy) { + sp layer = createBufferStateLayer(); + CallbackHelper* transactionCallback = new CallbackHelper(); + ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper(); + + // If a buffer is being presented, we should not emit a release callback. + sp firstBuffer = getBuffer(); + submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, *releaseCallback); + { + ExpectedResult expected; + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks()); + } + + // Destroying a currently presenting layer emits a callback. + Transaction t; + t.reparent(layer, nullptr); + t.apply(); + layer = nullptr; + + ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBuffer->getId())); +} + +// Destroying a never presented layer emits a callback. +TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_OffScreenLayerDestroy) { + sp layer = createBufferStateLayer(); + + // make layer offscreen + Transaction t; + t.reparent(layer, nullptr); + t.apply(); + + CallbackHelper* transactionCallback = new CallbackHelper(); + ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper(); + + // Submitting a buffer does not emit a callback. + sp firstBuffer = getBuffer(); + submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, *releaseCallback); + { + ExpectedResult expected; + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks()); + } + + // Submitting a second buffer will replace the drawing state buffer and emit a callback. + sp secondBuffer = getBuffer(); + submitBuffer(layer, secondBuffer, Fence::NO_FENCE, *transactionCallback, *releaseCallback); + { + ExpectedResult expected; + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE( + waitForReleaseBufferCallback(*releaseCallback, firstBuffer->getId())); + } + + // Destroying the offscreen layer emits a callback. + layer = nullptr; + ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBuffer->getId())); +} + +TEST_F(ReleaseBufferCallbackTest, DISABLED_FrameDropping) { + sp layer = createBufferStateLayer(); + CallbackHelper transactionCallback; + ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper(); + + // If a buffer is being presented, we should not emit a release callback. + sp firstBuffer = getBuffer(); + + // Try to present 100ms in the future + nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count(); + + Transaction t; + t.setBuffer(layer, firstBuffer, releaseCallback->getCallback()); + t.setAcquireFence(layer, Fence::NO_FENCE); + t.addTransactionCompletedCallback(transactionCallback.function, + transactionCallback.getContext()); + t.setDesiredPresentTime(time); + t.apply(); + + ExpectedResult expected; + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks()); + + // Dropping frames in transaction queue emits a callback + sp secondBuffer = getBuffer(); + t.setBuffer(layer, secondBuffer, releaseCallback->getCallback()); + t.setAcquireFence(layer, Fence::NO_FENCE); + t.addTransactionCompletedCallback(transactionCallback.function, + transactionCallback.getContext()); + t.setDesiredPresentTime(time); + t.apply(); + + expected = ExpectedResult(); + expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, + ExpectedResult::Buffer::NOT_ACQUIRED, + ExpectedResult::PreviousBuffer::RELEASED); + ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected)); + ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBuffer->getId())); +} + +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp index dbadf75d44..b5ef0a1334 100644 --- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp @@ -123,7 +123,8 @@ public: traceTimestamp(layerId, bufferId, frameNumber, postTime, FrameTracer::FrameEvent::QUEUE, /*duration*/ 0)); layer->setBuffer(buffer, fence, postTime, /*desiredPresentTime*/ 30, false, mClientCache, - frameNumber, dequeueTime, FrameTimelineInfo{}); + frameNumber, dequeueTime, FrameTimelineInfo{}, + nullptr /* releaseBufferCallback */); commitTransaction(layer.get()); bool computeVisisbleRegions; diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp index 623a5e0608..c75538f476 100644 --- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp @@ -126,7 +126,7 @@ public: auto acquireFence = fenceFactory.createFenceTimeForTest(fence); sp buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); acquireFence->signalForTest(12); commitTransaction(layer.get()); @@ -151,7 +151,7 @@ public: auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); sp buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); const auto droppedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX; @@ -161,7 +161,7 @@ public: sp buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; nsecs_t start = systemTime(); layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); nsecs_t end = systemTime(); acquireFence2->signalForTest(12); @@ -199,7 +199,7 @@ public: sp buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); acquireFence->signalForTest(12); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); @@ -225,7 +225,7 @@ public: sp buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); @@ -255,7 +255,7 @@ public: sp buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 3, /*inputEventId*/ 0}); + {/*vsyncId*/ 3, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(2u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); const auto& bufferSurfaceFrameTX = layer->mCurrentState.bufferSurfaceFrameTX; @@ -353,7 +353,7 @@ public: auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); sp buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); const auto droppedSurfaceFrame = layer->mCurrentState.bufferSurfaceFrameTX; @@ -361,7 +361,7 @@ public: auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); sp buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); acquireFence2->signalForTest(12); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); @@ -388,7 +388,7 @@ public: auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); sp buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); const auto droppedSurfaceFrame1 = layer->mCurrentState.bufferSurfaceFrameTX; @@ -398,7 +398,8 @@ public: sp buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; auto dropStartTime1 = systemTime(); layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0}); + {/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0}, + nullptr /* releaseBufferCallback */); auto dropEndTime1 = systemTime(); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); @@ -409,7 +410,7 @@ public: sp buffer3{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; auto dropStartTime2 = systemTime(); layer->setBuffer(buffer3, fence3, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 2, /*inputEventId*/ 0}); + {/*vsyncId*/ 2, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); auto dropEndTime2 = systemTime(); acquireFence3->signalForTest(12); @@ -448,7 +449,8 @@ public: sp fence1(new Fence()); sp buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, - {/*vsyncId*/ 1, /*inputEventId*/ 0}); + {/*vsyncId*/ 1, /*inputEventId*/ 0}, + nullptr /* releaseBufferCallback */); layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 2, /*inputEventId*/ 0}, 10); -- cgit v1.2.3-59-g8ed1b From 3b1f7bcf8fd0ca2458eb26ec31a1bddf4bf7fd43 Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Tue, 16 Mar 2021 15:51:53 +0100 Subject: Extract ParcelableUtils to avoid code duplication Currently the SAFE_PARCEL macros are copies on multiple places. This CL extracts them in a single ParcelableUtils. Additionally in SAFE_PARCEL also the stringified error is printed. Bug: 179116474 Test: presubmit Change-Id: Ie09c3a9753b5742be14fe3cdb0061d5c64465e66 --- libs/gui/FrameTimelineInfo.cpp | 1 + libs/gui/ISurfaceComposer.cpp | 1 + libs/gui/ITransactionCompletedListener.cpp | 3 ++- libs/gui/LayerState.cpp | 1 + libs/gui/ScreenCaptureResults.cpp | 2 ++ libs/gui/SurfaceComposerClient.cpp | 1 + libs/gui/SurfaceControl.cpp | 1 + libs/gui/include/gui/LayerState.h | 18 +------------- libs/gui/include/gui/ScreenCaptureResults.h | 9 ------- libs/gui/include/private/gui/ParcelUtils.h | 38 +++++++++++++++++++++++++++++ 10 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 libs/gui/include/private/gui/ParcelUtils.h (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/FrameTimelineInfo.cpp b/libs/gui/FrameTimelineInfo.cpp index f40077403a..9231a570fc 100644 --- a/libs/gui/FrameTimelineInfo.cpp +++ b/libs/gui/FrameTimelineInfo.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 989abd9a15..f44f10a2ce 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp index 0ded9361bf..2579f50f2a 100644 --- a/libs/gui/ITransactionCompletedListener.cpp +++ b/libs/gui/ITransactionCompletedListener.cpp @@ -17,9 +17,10 @@ #define LOG_TAG "ITransactionCompletedListener" //#define LOG_NDEBUG 0 -#include #include #include +#include +#include namespace android { diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 6bb8bf2d5b..04a878563e 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/libs/gui/ScreenCaptureResults.cpp b/libs/gui/ScreenCaptureResults.cpp index f3849bcdcd..e91f74f3d3 100644 --- a/libs/gui/ScreenCaptureResults.cpp +++ b/libs/gui/ScreenCaptureResults.cpp @@ -16,6 +16,8 @@ #include +#include + namespace android::gui { status_t ScreenCaptureResults::writeToParcel(android::Parcel* parcel) const { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index f56578981b..18a0cbd1c0 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 1dcfe2e804..7e2f8f9d36 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -39,6 +39,7 @@ #include #include #include +#include namespace android { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 183ec40fba..f7a66985b7 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -16,23 +16,7 @@ #ifndef ANDROID_SF_LAYER_STATE_H #define ANDROID_SF_LAYER_STATE_H -#define SAFE_PARCEL(FUNC, ...) \ - { \ - status_t error = FUNC(__VA_ARGS__); \ - if (error) { \ - ALOGE("ERROR(%d). Failed to call parcel %s(%s)", error, #FUNC, #__VA_ARGS__); \ - return error; \ - } \ - } - -#define SAFE_PARCEL_READ_SIZE(FUNC, COUNT, SIZE) \ - { \ - SAFE_PARCEL(FUNC, COUNT); \ - if (static_cast(*COUNT) > SIZE) { \ - ALOGE("ERROR(BAD_VALUE). %s was greater than dataSize", #COUNT); \ - return BAD_VALUE; \ - } \ - } + #include #include diff --git a/libs/gui/include/gui/ScreenCaptureResults.h b/libs/gui/include/gui/ScreenCaptureResults.h index 0ccc6e8b8a..99c35c1a3d 100644 --- a/libs/gui/include/gui/ScreenCaptureResults.h +++ b/libs/gui/include/gui/ScreenCaptureResults.h @@ -16,15 +16,6 @@ #pragma once -#define SAFE_PARCEL(FUNC, ...) \ - { \ - status_t error = FUNC(__VA_ARGS__); \ - if (error) { \ - ALOGE("ERROR(%d). Failed to call parcel %s(%s)", error, #FUNC, #__VA_ARGS__); \ - return error; \ - } \ - } - #include #include #include diff --git a/libs/gui/include/private/gui/ParcelUtils.h b/libs/gui/include/private/gui/ParcelUtils.h new file mode 100644 index 0000000000..1cdd07e36e --- /dev/null +++ b/libs/gui/include/private/gui/ParcelUtils.h @@ -0,0 +1,38 @@ +/* + * Copyright 2021 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. + */ + +#pragma once + +#include + +#define SAFE_PARCEL(FUNC, ...) \ + { \ + status_t error = FUNC(__VA_ARGS__); \ + if (error) { \ + ALOGE("ERROR(%s, %d). Failed to call parcel %s(%s)", strerror(-error), error, #FUNC, \ + #__VA_ARGS__); \ + return error; \ + } \ + } + +#define SAFE_PARCEL_READ_SIZE(FUNC, COUNT, SIZE) \ + { \ + SAFE_PARCEL(FUNC, COUNT); \ + if (static_cast(*COUNT) > SIZE) { \ + ALOGE("ERROR(BAD_VALUE). %s was greater than dataSize", #COUNT); \ + return BAD_VALUE; \ + } \ + } \ No newline at end of file -- cgit v1.2.3-59-g8ed1b From 8db101095526c49a58fd54bfb9d3501ea5351027 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 15 Mar 2021 17:19:23 -0700 Subject: SurfaceFlinger: remove SurfaceControl level vsyncId setting FrameTimelineInfo can be set on the entire transaction, or for an individual SurfaceControl. Later in the code the FrameTimelineInfo is unified based on the most recent vsyncId. For this reason we are removing the setting of a FrameTimelineInfo on a SurfaceControl and instead we use the transaction's one. Test: adb shell /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test Bug: 181978893 Bug: 169901895 Change-Id: Id4a8e46d57fbda66f6d478be82313482053dce20 --- libs/gui/BLASTBufferQueue.cpp | 2 +- libs/gui/LayerState.cpp | 7 ---- libs/gui/SurfaceComposerClient.cpp | 15 +------ libs/gui/include/gui/LayerState.h | 9 ++--- libs/gui/include/gui/SurfaceComposerClient.h | 3 -- services/surfaceflinger/BufferLayer.cpp | 18 --------- services/surfaceflinger/BufferLayer.h | 11 ------ services/surfaceflinger/BufferQueueLayer.cpp | 15 ------- services/surfaceflinger/BufferQueueLayer.h | 2 - services/surfaceflinger/BufferStateLayer.cpp | 10 ----- services/surfaceflinger/BufferStateLayer.h | 2 - services/surfaceflinger/Layer.h | 4 -- services/surfaceflinger/SurfaceFlinger.cpp | 48 +++++++++++++++-------- services/surfaceflinger/SurfaceFlinger.h | 1 + services/surfaceflinger/tests/LayerState_test.cpp | 29 -------------- 15 files changed, 38 insertions(+), 138 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index f778232803..5b1b975283 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -401,7 +401,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber); if (!mNextFrameTimelineInfoQueue.empty()) { - t->setFrameTimelineInfo(mSurfaceControl, mNextFrameTimelineInfoQueue.front()); + t->setFrameTimelineInfo(mNextFrameTimelineInfoQueue.front()); mNextFrameTimelineInfoQueue.pop(); } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 7a18ca61fe..a84e741482 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -62,7 +62,6 @@ layer_state_t::layer_state_t() shouldBeSeamless(true), fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0), - frameTimelineInfo(), autoRefresh(false), releaseBufferListener(nullptr) { matrix.dsdx = matrix.dtdy = 1.0f; @@ -151,7 +150,6 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeBool, shouldBeSeamless); SAFE_PARCEL(output.writeUint32, fixedTransformHint); SAFE_PARCEL(output.writeUint64, frameNumber); - SAFE_PARCEL(frameTimelineInfo.write, output); SAFE_PARCEL(output.writeBool, autoRefresh); SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(releaseBufferListener)); @@ -274,7 +272,6 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readUint32, &tmpUint32); fixedTransformHint = static_cast(tmpUint32); SAFE_PARCEL(input.readUint64, &frameNumber); - SAFE_PARCEL(frameTimelineInfo.read, input); SAFE_PARCEL(input.readBool, &autoRefresh); tmpBinder = nullptr; @@ -543,10 +540,6 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eFrameNumberChanged; frameNumber = other.frameNumber; } - if (other.what & eFrameTimelineInfoChanged) { - what |= eFrameTimelineInfoChanged; - frameTimelineInfo.merge(other.frameTimelineInfo); - } if (other.what & eAutoRefreshChanged) { what |= eAutoRefreshChanged; autoRefresh = other.autoRefresh; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 11fe49039d..eaccc5bab5 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1630,20 +1630,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo( const FrameTimelineInfo& frameTimelineInfo) { - mFrameTimelineInfo = frameTimelineInfo; - return *this; -} - -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo( - const sp& sc, const FrameTimelineInfo& frameTimelineInfo) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - - s->what |= layer_state_t::eFrameTimelineInfoChanged; - s->frameTimelineInfo = frameTimelineInfo; + mFrameTimelineInfo.merge(frameTimelineInfo); return *this; } diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index d68a9cfa4a..4a52168315 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -133,10 +133,9 @@ struct layer_state_t { eProducerDisconnect = 0x100'00000000, eFixedTransformHintChanged = 0x200'00000000, eFrameNumberChanged = 0x400'00000000, - eFrameTimelineInfoChanged = 0x800'00000000, - eBlurRegionsChanged = 0x1000'00000000, - eAutoRefreshChanged = 0x2000'00000000, - eStretchChanged = 0x4000'00000000, + eBlurRegionsChanged = 0x800'00000000, + eAutoRefreshChanged = 0x1000'00000000, + eStretchChanged = 0x2000'00000000, }; layer_state_t(); @@ -239,8 +238,6 @@ struct layer_state_t { // graphics producer. uint64_t frameNumber; - FrameTimelineInfo frameTimelineInfo; - // Indicates that the consumer should acquire the next frame as soon as it // can and not wait for a frame to become available. This is only relevant // in shared buffer mode. diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index f29983cef7..ae7170e1aa 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -530,9 +530,6 @@ public: // to the transaction, and the input event id that identifies the input event that caused // the current frame. Transaction& setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo); - // Variant that only applies to a specific SurfaceControl. - Transaction& setFrameTimelineInfo(const sp& sc, - const FrameTimelineInfo& frameTimelineInfo); // Indicates that the consumer should acquire the next frame as soon as it // can and not wait for a frame to become available. This is only relevant diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index eac3d95d8a..b3f97924bd 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -424,24 +424,6 @@ bool BufferLayer::shouldPresentNow(nsecs_t expectedPresentTime) const { return isBufferDue(expectedPresentTime); } -bool BufferLayer::frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const { - // TODO(b/169901895): kEarlyLatchVsyncThreshold should be based on the - // vsync period. We can do this change as soon as ag/13100772 is merged. - constexpr static std::chrono::nanoseconds kEarlyLatchVsyncThreshold = 5ms; - - const auto presentTime = nextPredictedPresentTime(vsyncId); - if (!presentTime.has_value()) { - return false; - } - - if (std::abs(*presentTime - expectedPresentTime) >= kEarlyLatchMaxThreshold.count()) { - return false; - } - - return *presentTime >= expectedPresentTime && - *presentTime - expectedPresentTime >= kEarlyLatchVsyncThreshold.count(); -} - bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { ATRACE_CALL(); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 5fed79ffed..b8d3f12322 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -189,10 +189,6 @@ protected: // specific logic virtual bool isBufferDue(nsecs_t /*expectedPresentTime*/) const = 0; - // Returns true if the next frame is considered too early to present - // at the given expectedPresentTime - bool frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const; - std::atomic mAutoRefresh{false}; std::atomic mSidebandStreamChanged{false}; @@ -236,13 +232,6 @@ private: std::unique_ptr mCompositionState; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; - - // Returns the predicted present time of the next frame if available - virtual std::optional nextPredictedPresentTime(int64_t vsyncId) const = 0; - - // The amount of time SF can delay a frame if it is considered early based - // on the VsyncModulator::VsyncConfig::appWorkDuration - static constexpr std::chrono::nanoseconds kEarlyLatchMaxThreshold = 100ms; }; } // namespace android diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 63dd25f72f..51e85c4dcc 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -215,21 +215,6 @@ bool BufferQueueLayer::hasFrameUpdate() const { return mQueuedFrames > 0; } -std::optional BufferQueueLayer::nextPredictedPresentTime(int64_t /*vsyncId*/) const { - Mutex::Autolock lock(mQueueItemLock); - if (mQueueItems.empty()) { - return std::nullopt; - } - - const auto& bufferData = mQueueItems[0]; - - if (!bufferData.item.mIsAutoTimestamp || !bufferData.surfaceFrame) { - return std::nullopt; - } - - return bufferData.surfaceFrame->getPredictions().presentTime; -} - status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { // This boolean is used to make sure that SurfaceFlinger's shadow copy diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index 3a34b952f2..b3b7948935 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -117,8 +117,6 @@ private: // Temporary - Used only for LEGACY camera mode. uint32_t getProducerStickyTransform() const; - std::optional nextPredictedPresentTime(int64_t vsyncId) const override; - sp mConsumer; sp mProducer; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 89dfb6fb6b..00a6d661c0 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -644,16 +644,6 @@ bool BufferStateLayer::hasFrameUpdate() const { return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr); } -std::optional BufferStateLayer::nextPredictedPresentTime(int64_t vsyncId) const { - const auto prediction = - mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(vsyncId); - if (!prediction.has_value()) { - return std::nullopt; - } - - return prediction->presentTime; -} - status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime, nsecs_t /*expectedPresentTime*/) { const State& s(getDrawingState()); diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 036e8d2e85..7a3da6fec1 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -156,8 +156,6 @@ private: bool bufferNeedsFiltering() const override; - std::optional nextPredictedPresentTime(int64_t vsyncId) const override; - static const std::array IDENTITY_MATRIX; std::unique_ptr mTextureImage; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 85ff479344..1c5d6ecb03 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -930,10 +930,6 @@ public: pid_t getOwnerPid() { return mOwnerPid; } - virtual bool frameIsEarly(nsecs_t /*expectedPresentTime*/, int64_t /*vsyncId*/) const { - return false; - } - // This layer is not a clone, but it's the parent to the cloned hierarchy. The // variable mClonedChild represents the top layer that will be cloned so this // layer will be the parent of mClonedChild. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 61cc8a2ff0..e580a97b90 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3379,6 +3379,28 @@ bool SurfaceFlinger::transactionFlushNeeded() { return !mPendingTransactionQueues.empty() || !mTransactionQueue.empty(); } +bool SurfaceFlinger::frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const { + // The amount of time SF can delay a frame if it is considered early based + // on the VsyncModulator::VsyncConfig::appWorkDuration + constexpr static std::chrono::nanoseconds kEarlyLatchMaxThreshold = 100ms; + + const auto currentVsyncPeriod = mScheduler->getDisplayStatInfo(systemTime()).vsyncPeriod; + const auto earlyLatchVsyncThreshold = currentVsyncPeriod / 2; + + const auto prediction = mFrameTimeline->getTokenManager()->getPredictionsForToken(vsyncId); + if (!prediction.has_value()) { + return false; + } + + if (std::abs(prediction->presentTime - expectedPresentTime) >= + kEarlyLatchMaxThreshold.count()) { + return false; + } + + return prediction->presentTime >= expectedPresentTime && + prediction->presentTime - expectedPresentTime >= earlyLatchVsyncThreshold; +} + bool SurfaceFlinger::transactionIsReadyToBeApplied( const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime, uid_t originUid, const Vector& states, @@ -3399,6 +3421,13 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( ready = false; } + // If the client didn't specify desiredPresentTime, use the vsyncId to determine the expected + // present time of this transaction. + if (isAutoTimestamp && frameIsEarly(expectedPresentTime, info.vsyncId)) { + ATRACE_NAME("frameIsEarly"); + ready = false; + } + for (const ComposerState& state : states) { const layer_state_t& s = state.state; const bool acquireFenceChanged = (s.what & layer_state_t::eAcquireFenceChanged); @@ -3420,13 +3449,6 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( ATRACE_NAME(layer->getName().c_str()); - const bool frameTimelineInfoChanged = (s.what & layer_state_t::eFrameTimelineInfoChanged); - const auto vsyncId = frameTimelineInfoChanged ? s.frameTimelineInfo.vsyncId : info.vsyncId; - if (isAutoTimestamp && layer->frameIsEarly(expectedPresentTime, vsyncId)) { - ATRACE_NAME("frameIsEarly()"); - ready = false; - } - if (acquireFenceChanged) { // If backpressure is enabled and we already have a buffer to commit, keep the // transaction in the queue. @@ -3959,12 +3981,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded; } } - FrameTimelineInfo info; - if (what & layer_state_t::eFrameTimelineInfoChanged) { - info = s.frameTimelineInfo; - } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { - info = frameTimelineInfo; - } if (what & layer_state_t::eFixedTransformHintChanged) { if (layer->setFixedTransformHint(s.fixedTransformHint)) { flags |= eTraversalNeeded | eTransformHintUpdateNeeded; @@ -4027,12 +4043,12 @@ uint32_t SurfaceFlinger::setClientStateLocked( : layer->getHeadFrameNumber(-1 /* expectedPresentTime */) + 1; if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime, isAutoTimestamp, - s.cachedBuffer, frameNumber, dequeueBufferTimestamp, info, + s.cachedBuffer, frameNumber, dequeueBufferTimestamp, frameTimelineInfo, s.releaseBufferListener)) { flags |= eTraversalNeeded; } - } else if (info.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { - layer->setFrameTimelineVsyncForBufferlessTransaction(info, postTime); + } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { + layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime); } if (layer->setTransactionCompletedListeners(callbackHandles)) flags |= eTraversalNeeded; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a5b06dfbd4..a7cdcd1719 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -844,6 +844,7 @@ private: uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock); + bool frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const; /* * Layer management */ diff --git a/services/surfaceflinger/tests/LayerState_test.cpp b/services/surfaceflinger/tests/LayerState_test.cpp index f010786601..fa1a5ed6b0 100644 --- a/services/surfaceflinger/tests/LayerState_test.cpp +++ b/services/surfaceflinger/tests/LayerState_test.cpp @@ -114,34 +114,5 @@ TEST(LayerStateTest, ParcellingScreenCaptureResults) { ASSERT_EQ(results.result, results2.result); } -/** - * Parcel a layer_state_t struct, and then unparcel. Ensure that the object that was parceled - * matches the object that's unparceled. - */ -TEST(LayerStateTest, ParcelUnparcelLayerStateT) { - layer_state_t input; - input.frameTimelineInfo.vsyncId = 1; - input.frameTimelineInfo.inputEventId = 2; - Parcel p; - input.write(p); - layer_state_t output; - p.setDataPosition(0); - output.read(p); - ASSERT_EQ(input.frameTimelineInfo.vsyncId, output.frameTimelineInfo.vsyncId); - ASSERT_EQ(input.frameTimelineInfo.inputEventId, output.frameTimelineInfo.inputEventId); -} - -TEST(LayerStateTest, LayerStateMerge_SelectsValidInputEvent) { - layer_state_t layer1; - layer1.frameTimelineInfo.inputEventId = android::os::IInputConstants::INVALID_INPUT_EVENT_ID; - layer_state_t layer2; - layer2.frameTimelineInfo.inputEventId = 1; - layer2.what |= layer_state_t::eFrameTimelineInfoChanged; - - layer1.merge(layer2); - - ASSERT_EQ(1, layer1.frameTimelineInfo.inputEventId); -} - } // namespace test } // namespace android -- cgit v1.2.3-59-g8ed1b From c5986778d0d6c7ab3f96fafb1b84887e901ed92b Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Tue, 16 Mar 2021 16:09:49 +0100 Subject: setFrameRate: Make shouldBeSeamless an enum Change the shouldBeSeamless parameter to an enum in order to make the API easier to understand. This changes - SurfaceControl.setFrameRate - Surface.setFrameRate - ANativeWindow_setFrameRateWithChangeStrategy - ASurfaceTransaction_setFrameRateWithChangeStrategy Bug: 179116474 Test: atest SetFrameRateTest Change-Id: I28a8863ea77101f90b878fbda5f00d98e075b7cc --- include/android/surface_control.h | 18 +++-- libs/gui/BLASTBufferQueue.cpp | 8 ++- libs/gui/ISurfaceComposer.cpp | 76 ++++++---------------- libs/gui/LayerState.cpp | 19 ++++-- libs/gui/Surface.cpp | 12 ++-- libs/gui/SurfaceComposerClient.cpp | 7 +- libs/gui/include/gui/ISurfaceComposer.h | 2 +- libs/gui/include/gui/LayerState.h | 7 +- libs/gui/include/gui/Surface.h | 3 +- libs/gui/include/gui/SurfaceComposerClient.h | 2 +- libs/gui/tests/Surface_test.cpp | 2 +- libs/nativewindow/ANativeWindow.cpp | 10 +-- libs/nativewindow/include/android/native_window.h | 31 ++++++--- libs/nativewindow/include/system/window.h | 4 +- libs/nativewindow/libnativewindow.map.txt | 2 +- services/surfaceflinger/Layer.cpp | 12 ++++ services/surfaceflinger/Layer.h | 13 ++-- services/surfaceflinger/SurfaceFlinger.cpp | 26 +++++--- services/surfaceflinger/SurfaceFlinger.h | 2 +- .../tests/unittests/SetFrameRateTest.cpp | 38 ++++++++--- 20 files changed, 159 insertions(+), 135 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/include/android/surface_control.h b/include/android/surface_control.h index c17f8224c2..26b63d2005 100644 --- a/include/android/surface_control.h +++ b/include/android/surface_control.h @@ -420,10 +420,10 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio __INTRODUCED_IN(29); /** - * Same as ASurfaceTransaction_setFrameRateWithSeamlessness(transaction, surface_control, - * frameRate, compatibility, true). + * Same as ASurfaceTransaction_setFrameRateWithChangeStrategy(transaction, surface_control, + * frameRate, compatibility, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS). * - * See ASurfaceTransaction_setFrameRateWithSeamlessness(). + * See ASurfaceTransaction_setFrameRateWithChangeStrategy(). * * Available since API level 30. */ @@ -451,17 +451,15 @@ void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction, * influence the system's choice of display frame rate. To specify a compatibility use the * ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* enum. * - * \param shouldBeSeamless Whether display refresh rate transitions should be seamless. A - * seamless transition is one that doesn't have any visual interruptions, such as a black - * screen for a second or two. True indicates that any frame rate changes caused by this - * request should be seamless. False indicates that non-seamless refresh rates are also - * acceptable. + * \param changeFrameRateStrategy Whether display refresh rate transitions should be seamless. + * A seamless transition is one that doesn't have any visual interruptions, such as a black + * screen for a second or two. See the ANATIVEWINDOW_CHANGE_FRAME_RATE_* values. * * Available since API level 31. */ -void ASurfaceTransaction_setFrameRateWithSeamlessness(ASurfaceTransaction* transaction, +void ASurfaceTransaction_setFrameRateWithChangeStrategy(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, float frameRate, - int8_t compatibility, bool shouldBeSeamless) + int8_t compatibility, int8_t changeFrameRateStrategy) __INTRODUCED_IN(31); __END_DECLS diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 82c9268feb..3f545b25e5 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -544,11 +544,13 @@ public: }).detach(); } - status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless) override { - if (!ValidateFrameRate(frameRate, compatibility, "BBQSurface::setFrameRate")) { + status_t setFrameRate(float frameRate, int8_t compatibility, + int8_t changeFrameRateStrategy) override { + if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy, + "BBQSurface::setFrameRate")) { return BAD_VALUE; } - return mBbq->setFrameRate(frameRate, compatibility, shouldBeSeamless); + return mBbq->setFrameRate(frameRate, compatibility, changeFrameRateStrategy); } status_t setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) override { diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index f44f10a2ce..71215fef36 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -1012,39 +1012,15 @@ public: } status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility, bool shouldBeSeamless) override { + int8_t compatibility, int8_t changeFrameRateStrategy) override { Parcel data, reply; - status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed writing interface token: %s (%d)", strerror(-err), -err); - return err; - } - - err = data.writeStrongBinder(IInterface::asBinder(surface)); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed writing strong binder: %s (%d)", strerror(-err), -err); - return err; - } - - err = data.writeFloat(frameRate); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed writing float: %s (%d)", strerror(-err), -err); - return err; - } - - err = data.writeByte(compatibility); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed writing byte: %s (%d)", strerror(-err), -err); - return err; - } - - err = data.writeBool(shouldBeSeamless); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed writing bool: %s (%d)", strerror(-err), -err); - return err; - } + SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor()); + SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(surface)); + SAFE_PARCEL(data.writeFloat, frameRate); + SAFE_PARCEL(data.writeByte, compatibility); + SAFE_PARCEL(data.writeByte, changeFrameRateStrategy); - err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply); + status_t err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply); if (err != NO_ERROR) { ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err); return err; @@ -1873,36 +1849,24 @@ status_t BnSurfaceComposer::onTransact( case SET_FRAME_RATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp binder; - status_t err = data.readStrongBinder(&binder); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed to read strong binder: %s (%d)", strerror(-err), -err); - return err; - } + SAFE_PARCEL(data.readStrongBinder, &binder); + sp surface = interface_cast(binder); if (!surface) { - ALOGE("setFrameRate: failed to cast to IGraphicBufferProducer: %s (%d)", - strerror(-err), -err); - return err; + ALOGE("setFrameRate: failed to cast to IGraphicBufferProducer"); + return BAD_VALUE; } float frameRate; - err = data.readFloat(&frameRate); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed to read float: %s (%d)", strerror(-err), -err); - return err; - } + SAFE_PARCEL(data.readFloat, &frameRate); + int8_t compatibility; - err = data.readByte(&compatibility); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed to read byte: %s (%d)", strerror(-err), -err); - return err; - } - bool shouldBeSeamless; - err = data.readBool(&shouldBeSeamless); - if (err != NO_ERROR) { - ALOGE("setFrameRate: failed to read bool: %s (%d)", strerror(-err), -err); - return err; - } - status_t result = setFrameRate(surface, frameRate, compatibility, shouldBeSeamless); + SAFE_PARCEL(data.readByte, &compatibility); + + int8_t changeFrameRateStrategy; + SAFE_PARCEL(data.readByte, &changeFrameRateStrategy); + + status_t result = + setFrameRate(surface, frameRate, compatibility, changeFrameRateStrategy); reply->writeInt32(result); return NO_ERROR; } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 04a878563e..2c4dfc54f3 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -60,7 +61,7 @@ layer_state_t::layer_state_t() frameRateSelectionPriority(-1), frameRate(0.0f), frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT), - shouldBeSeamless(true), + changeFrameRateStrategy(ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS), fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0), frameTimelineInfo(), @@ -148,7 +149,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeInt32, frameRateSelectionPriority); SAFE_PARCEL(output.writeFloat, frameRate); SAFE_PARCEL(output.writeByte, frameRateCompatibility); - SAFE_PARCEL(output.writeBool, shouldBeSeamless); + SAFE_PARCEL(output.writeByte, changeFrameRateStrategy); SAFE_PARCEL(output.writeUint32, fixedTransformHint); SAFE_PARCEL(output.writeUint64, frameNumber); SAFE_PARCEL(frameTimelineInfo.write, output); @@ -269,7 +270,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readInt32, &frameRateSelectionPriority); SAFE_PARCEL(input.readFloat, &frameRate); SAFE_PARCEL(input.readByte, &frameRateCompatibility); - SAFE_PARCEL(input.readBool, &shouldBeSeamless); + SAFE_PARCEL(input.readByte, &changeFrameRateStrategy); SAFE_PARCEL(input.readUint32, &tmpUint32); fixedTransformHint = static_cast(tmpUint32); SAFE_PARCEL(input.readUint64, &frameNumber); @@ -526,7 +527,7 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eFrameRateChanged; frameRate = other.frameRate; frameRateCompatibility = other.frameRateCompatibility; - shouldBeSeamless = other.shouldBeSeamless; + changeFrameRateStrategy = other.changeFrameRateStrategy; } if (other.what & eFixedTransformHintChanged) { what |= eFixedTransformHintChanged; @@ -616,8 +617,8 @@ status_t InputWindowCommands::read(const Parcel& input) { return NO_ERROR; } -bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName, - bool privileged) { +bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy, + const char* inFunctionName, bool privileged) { const char* functionName = inFunctionName != nullptr ? inFunctionName : "call"; int floatClassification = std::fpclassify(frameRate); if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) { @@ -633,6 +634,12 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunc return false; } + if (changeFrameRateStrategy != ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS && + changeFrameRateStrategy != ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS) { + ALOGE("%s failed - invalid change frame rate strategy value %d", functionName, + changeFrameRateStrategy); + } + return true; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 6de3e971b2..2fc9d47b89 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1729,8 +1729,8 @@ int Surface::dispatchGetLastQueueDuration(va_list args) { int Surface::dispatchSetFrameRate(va_list args) { float frameRate = static_cast(va_arg(args, double)); int8_t compatibility = static_cast(va_arg(args, int)); - bool shouldBeSeamless = static_cast(va_arg(args, int)); - return setFrameRate(frameRate, compatibility, shouldBeSeamless); + int8_t changeFrameRateStrategy = static_cast(va_arg(args, int)); + return setFrameRate(frameRate, compatibility, changeFrameRateStrategy); } int Surface::dispatchAddCancelInterceptor(va_list args) { @@ -2575,16 +2575,18 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vectoronBuffersDiscarded(discardedBufs); } -status_t Surface::setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless) { +status_t Surface::setFrameRate(float frameRate, int8_t compatibility, + int8_t changeFrameRateStrategy) { ATRACE_CALL(); ALOGV("Surface::setFrameRate"); - if (!ValidateFrameRate(frameRate, compatibility, "Surface::setFrameRate")) { + if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy, + "Surface::setFrameRate")) { return BAD_VALUE; } return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility, - shouldBeSeamless); + changeFrameRateStrategy); } status_t Surface::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 18a0cbd1c0..3c10858dfe 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1511,7 +1511,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShado SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate( const sp& sc, float frameRate, int8_t compatibility, - bool shouldBeSeamless) { + int8_t changeFrameRateStrategy) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; @@ -1519,7 +1519,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame } // Allow privileged values as well here, those will be ignored by SF if // the caller is not privileged - if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate", + if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy, + "Transaction::setFrameRate", /*privileged=*/true)) { mStatus = BAD_VALUE; return *this; @@ -1527,7 +1528,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame s->what |= layer_state_t::eFrameRateChanged; s->frameRate = frameRate; s->frameRateCompatibility = compatibility; - s->shouldBeSeamless = shouldBeSeamless; + s->changeFrameRateStrategy = changeFrameRateStrategy; return *this; } diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 88cfe4b9ac..3cf9a733b6 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -461,7 +461,7 @@ public: * Sets the intended frame rate for a surface. See ANativeWindow_setFrameRate() for more info. */ virtual status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility, bool shouldBeSeamless) = 0; + int8_t compatibility, int8_t changeFrameRateStrategy) = 0; /* * Acquire a frame rate flexibility token from SurfaceFlinger. While this token is acquired, diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index f7a66985b7..cc8cc0d3ae 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -208,7 +208,7 @@ struct layer_state_t { // Layer frame rate and compatibility. See ANativeWindow_setFrameRate(). float frameRate; int8_t frameRateCompatibility; - bool shouldBeSeamless; + int8_t changeFrameRateStrategy; // Set by window manager indicating the layer and all its children are // in a different orientation than the display. The hint suggests that @@ -305,10 +305,11 @@ static inline int compare_type(const DisplayState& lhs, const DisplayState& rhs) // // @param frameRate the frame rate in Hz // @param compatibility a ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* +// @param changeFrameRateStrategy a ANATIVEWINDOW_CHANGE_FRAME_RATE_* // @param functionName calling function or nullptr. Used for logging // @param privileged whether caller has unscoped surfaceflinger access -bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName, - bool privileged = false); +bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy, + const char* functionName, bool privileged = false); struct CaptureArgs { const static int32_t UNSET_UID = -1; diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 58812214d2..d22bdaaa98 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -187,7 +187,8 @@ public: status_t getUniqueId(uint64_t* outId) const; status_t getConsumerUsage(uint64_t* outUsage) const; - virtual status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); + virtual status_t setFrameRate(float frameRate, int8_t compatibility, + int8_t changeFrameRateStrategy); virtual status_t setFrameTimelineInfo(const FrameTimelineInfo& info); virtual status_t getExtraBufferCount(int* extraBuffers) const; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 40c4135a51..4997e36899 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -509,7 +509,7 @@ public: Transaction& setShadowRadius(const sp& sc, float cornerRadius); Transaction& setFrameRate(const sp& sc, float frameRate, - int8_t compatibility, bool shouldBeSeamless); + int8_t compatibility, int8_t changeFrameRateStrategy); // Set by window manager indicating the layer and all its children are // in a different orientation than the display. The hint suggests that diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index e8fb71dc1d..68c834de63 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -855,7 +855,7 @@ public: } status_t setFrameRate(const sp& /*surface*/, float /*frameRate*/, - int8_t /*compatibility*/, bool /*shouldBeSeamless*/) override { + int8_t /*compatibility*/, int8_t /*changeFrameRateStrategy*/) override { return NO_ERROR; } diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index b406a9c2fe..ada689ac42 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -159,8 +159,8 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) { } int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_t compatibility) { - return ANativeWindow_setFrameRateWithSeamlessness(window, frameRate, compatibility, - /*shouldBeSeamless*/ true); + return ANativeWindow_setFrameRateWithChangeStrategy(window, frameRate, compatibility, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); } void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { @@ -170,12 +170,12 @@ void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); } -int32_t ANativeWindow_setFrameRateWithSeamlessness(ANativeWindow* window, float frameRate, - int8_t compatibility, bool shouldBeSeamless) { +int32_t ANativeWindow_setFrameRateWithChangeStrategy(ANativeWindow* window, float frameRate, + int8_t compatibility, int8_t changeFrameRateStrategy) { if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) { return -EINVAL; } - return native_window_set_frame_rate(window, frameRate, compatibility, shouldBeSeamless); + return native_window_set_frame_rate(window, frameRate, compatibility, changeFrameRateStrategy); } /************************************************************************************************** diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h index 285f2fb7fe..50e9d53604 100644 --- a/libs/nativewindow/include/android/native_window.h +++ b/libs/nativewindow/include/android/native_window.h @@ -247,9 +247,10 @@ enum ANativeWindow_FrameRateCompatibility { }; /** - * Same as ANativeWindow_setFrameRateWithSeamlessness(window, frameRate, compatibility, true). + * Same as ANativeWindow_setFrameRateWithChangeStrategy(window, frameRate, compatibility, + * ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS). * - * See ANativeWindow_setFrameRateWithSeamlessness(). + * See ANativeWindow_setFrameRateWithChangeStrategy(). * * Available since API level 30. */ @@ -267,6 +268,19 @@ int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_ */ void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) __INTRODUCED_IN(30); +/** Change frame rate strategy value for ANativeWindow_setFrameRate. */ +enum ANativeWindow_ChangeFrameRateStrategy { + /** + * Change the frame rate only if the transition is going to be seamless. + */ + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0, + /** + * Change the frame rate even if the transition is going to be non-seamless, + * i.e. with visual interruptions for the user. + */ + ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS = 1 +} __INTRODUCED_IN(31); + /** * Sets the intended frame rate for this window. * @@ -296,17 +310,16 @@ void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) __INTRODUCED_IN(30) * compatibility value may influence the system's choice of display refresh * rate. See the ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* values for more info. * - * \param shouldBeSeamless Whether display refresh rate transitions should be seamless. A - * seamless transition is one that doesn't have any visual interruptions, such as a black - * screen for a second or two. True indicates that any frame rate changes caused by this - * request should be seamless. False indicates that non-seamless refresh rates are also - * acceptable. + * \param changeFrameRateStrategy Whether display refresh rate transitions should be seamless. + * A seamless transition is one that doesn't have any visual interruptions, such as a black + * screen for a second or two. See the ANATIVEWINDOW_CHANGE_FRAME_RATE_* values. * * \return 0 for success, -EINVAL if the window, frame rate, or compatibility * value are invalid. */ -int32_t ANativeWindow_setFrameRateWithSeamlessness(ANativeWindow* window, float frameRate, - int8_t compatibility, bool shouldBeSeamless) __INTRODUCED_IN(31); +int32_t ANativeWindow_setFrameRateWithChangeStrategy(ANativeWindow* window, float frameRate, + int8_t compatibility, int8_t changeFrameRateStrategy) + __INTRODUCED_IN(31); #ifdef __cplusplus }; diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 7aa2cf4404..cc82bb4699 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -1019,9 +1019,9 @@ static inline int native_window_set_auto_prerotation(struct ANativeWindow* windo } static inline int native_window_set_frame_rate(struct ANativeWindow* window, float frameRate, - int8_t compatibility, bool shouldBeSeamless) { + int8_t compatibility, int8_t changeFrameRateStrategy) { return window->perform(window, NATIVE_WINDOW_SET_FRAME_RATE, (double)frameRate, - (int)compatibility, (int)shouldBeSeamless); + (int)compatibility, (int)changeFrameRateStrategy); } static inline int native_window_set_frame_timeline_info(struct ANativeWindow* window, diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 24d0e3badc..988132cd1c 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -47,7 +47,7 @@ LIBNATIVEWINDOW { ANativeWindow_setBuffersTransform; ANativeWindow_setDequeueTimeout; # apex # introduced=30 ANativeWindow_setFrameRate; # introduced=30 - ANativeWindow_setFrameRateWithSeamlessness; # introduced=31 + ANativeWindow_setFrameRateWithChangeStrategy; # introduced=31 ANativeWindow_setSharedBufferMode; # llndk ANativeWindow_setSwapInterval; # llndk ANativeWindow_setUsage; # llndk diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 0015bf27d1..782a7553f0 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2864,6 +2864,18 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp } } +scheduler::Seamlessness Layer::FrameRate::convertChangeFrameRateStrategy(int8_t strategy) { + switch (strategy) { + case ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS: + return Seamlessness::OnlySeamless; + case ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS: + return Seamlessness::SeamedAndSeamless; + default: + LOG_ALWAYS_FATAL("Invalid change frame sate strategy value %d", strategy); + return Seamlessness::Default; + } +} + bool Layer::getPrimaryDisplayOnly() const { const State& s(mDrawingState); if (s.flags & layer_state_t::eLayerSkipScreenshot) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 26d8e7472a..8534844a41 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -168,8 +168,9 @@ public: : rate(0), type(FrameRateCompatibility::Default), seamlessness(Seamlessness::Default) {} - FrameRate(Fps rate, FrameRateCompatibility type, bool shouldBeSeamless = true) - : rate(rate), type(type), seamlessness(getSeamlessness(rate, shouldBeSeamless)) {} + FrameRate(Fps rate, FrameRateCompatibility type, + Seamlessness seamlessness = Seamlessness::OnlySeamless) + : rate(rate), type(type), seamlessness(getSeamlessness(rate, seamlessness)) {} bool operator==(const FrameRate& other) const { return rate.equalsWithMargin(other.rate) && type == other.type && @@ -181,18 +182,16 @@ public: // Convert an ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value to a // Layer::FrameRateCompatibility. Logs fatal if the compatibility value is invalid. static FrameRateCompatibility convertCompatibility(int8_t compatibility); + static scheduler::Seamlessness convertChangeFrameRateStrategy(int8_t strategy); private: - static Seamlessness getSeamlessness(Fps rate, bool shouldBeSeamless) { + static Seamlessness getSeamlessness(Fps rate, Seamlessness seamlessness) { if (!rate.isValid()) { // Refresh rate of 0 is a special value which should reset the vote to // its default value. return Seamlessness::Default; - } else if (shouldBeSeamless) { - return Seamlessness::OnlySeamless; - } else { - return Seamlessness::SeamedAndSeamless; } + return seamlessness; } }; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 9da94832ae..7e8df89a4b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3948,13 +3948,16 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } if (what & layer_state_t::eFrameRateChanged) { - if (ValidateFrameRate(s.frameRate, s.frameRateCompatibility, - "SurfaceFlinger::setClientStateLocked", privileged) && - layer->setFrameRate(Layer::FrameRate(Fps(s.frameRate), - Layer::FrameRate::convertCompatibility( - s.frameRateCompatibility), - s.shouldBeSeamless))) { - flags |= eTraversalNeeded; + if (ValidateFrameRate(s.frameRate, s.frameRateCompatibility, s.changeFrameRateStrategy, + "SurfaceFlinger::setClientStateLocked", privileged)) { + const auto compatibility = + Layer::FrameRate::convertCompatibility(s.frameRateCompatibility); + const auto strategy = + Layer::FrameRate::convertChangeFrameRateStrategy(s.changeFrameRateStrategy); + + if (layer->setFrameRate(Layer::FrameRate(Fps(s.frameRate), compatibility, strategy))) { + flags |= eTraversalNeeded; + } } } FrameTimelineInfo info; @@ -6367,8 +6370,9 @@ const std::unordered_map& SurfaceFlinger::getGenericLayer } status_t SurfaceFlinger::setFrameRate(const sp& surface, float frameRate, - int8_t compatibility, bool shouldBeSeamless) { - if (!ValidateFrameRate(frameRate, compatibility, "SurfaceFlinger::setFrameRate")) { + int8_t compatibility, int8_t changeFrameRateStrategy) { + if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy, + "SurfaceFlinger::setFrameRate")) { return BAD_VALUE; } @@ -6380,10 +6384,12 @@ status_t SurfaceFlinger::setFrameRate(const sp& surface, ALOGE("Attempt to set frame rate on a layer that no longer exists"); return BAD_VALUE; } + const auto strategy = + Layer::FrameRate::convertChangeFrameRateStrategy(changeFrameRateStrategy); if (layer->setFrameRate( Layer::FrameRate(Fps{frameRate}, Layer::FrameRate::convertCompatibility(compatibility), - shouldBeSeamless))) { + strategy))) { setTransactionFlags(eTraversalNeeded); } } else { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 3787b9db89..65e00198b3 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -685,7 +685,7 @@ private: status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius) override; status_t setFrameRate(const sp& surface, float frameRate, - int8_t compatibility, bool shouldBeSeamless) override; + int8_t compatibility, int8_t changeFrameRateStrategy) override; status_t acquireFrameRateFlexibilityToken(sp* outToken) override; status_t setFrameTimelineInfo(const sp& surface, diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp index 5c8c2d888c..7ef1f2b378 100644 --- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp +++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp @@ -475,18 +475,36 @@ INSTANTIATE_TEST_SUITE_P(PerLayerType, SetFrameRateTest, PrintToStringParamName); TEST_F(SetFrameRateTest, ValidateFrameRate) { - EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); - EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); - EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, "")); - EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, "", /*privileged=*/true)); - - EXPECT_FALSE(ValidateFrameRate(-1, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); - EXPECT_FALSE( - ValidateFrameRate(1.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "", + /*privileged=*/true)); + + EXPECT_FALSE(ValidateFrameRate(-1, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_FALSE(ValidateFrameRate(1.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_FALSE(ValidateFrameRate(0.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + + EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, + ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + + // Invalid compatibility EXPECT_FALSE( - ValidateFrameRate(0.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, "")); + ValidateFrameRate(60.0f, -1, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); + EXPECT_FALSE(ValidateFrameRate(60.0f, 2, ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, "")); - EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, "")); + // Invalid change frame rate strategy + EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, -1, "")); + EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, 2, "")); } TEST_P(SetFrameRateTest, SetOnParentActivatesTree) { -- cgit v1.2.3-59-g8ed1b From 9a93ea66bb7116b8821877a69991ae94557b1303 Mon Sep 17 00:00:00 2001 From: chaviw Date: Thu, 11 Mar 2021 16:44:42 -0600 Subject: Remove setFrame from BufferStateLayer Replace setFrame with setCrop, setMatrix, and setPosition Test: SurfaceFlinger_tests Test: ASurfaceControlTest Bug: 170765639 Change-Id: I32ee0e3e48e5171d99a5f5af0b7583165d4dd9f9 --- libs/gui/BLASTBufferQueue.cpp | 29 +++- libs/gui/LayerState.cpp | 4 - libs/gui/SurfaceComposerClient.cpp | 14 -- libs/gui/include/gui/BLASTBufferQueue.h | 32 +++- libs/gui/include/gui/LayerState.h | 2 +- libs/gui/include/gui/SurfaceComposerClient.h | 1 - libs/gui/tests/BLASTBufferQueue_test.cpp | 34 ++-- services/surfaceflinger/BufferStateLayer.cpp | 98 +++++------- services/surfaceflinger/BufferStateLayer.h | 10 +- services/surfaceflinger/Layer.cpp | 4 +- services/surfaceflinger/Layer.h | 1 - services/surfaceflinger/RefreshRateOverlay.cpp | 8 +- services/surfaceflinger/SurfaceFlinger.cpp | 3 - services/surfaceflinger/tests/BufferGenerator.cpp | 14 +- services/surfaceflinger/tests/BufferGenerator.h | 2 + services/surfaceflinger/tests/EffectLayer_test.cpp | 1 - services/surfaceflinger/tests/IPC_test.cpp | 1 - .../surfaceflinger/tests/LayerCallback_test.cpp | 131 +++++++++++++--- .../tests/LayerRenderTypeTransaction_test.cpp | 174 ++++++++++----------- .../surfaceflinger/tests/LayerTransactionTest.h | 5 + .../LayerTypeAndRenderTypeTransaction_test.cpp | 60 ++----- services/surfaceflinger/tests/MirrorLayer_test.cpp | 2 +- .../surfaceflinger/tests/utils/TransactionUtils.h | 18 ++- 23 files changed, 353 insertions(+), 295 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 1976b493b2..1d7ed2f97b 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -204,13 +204,16 @@ void BLASTBufferQueue::update(const sp& surface, uint32_t width, if (mRequestedSize != newSize) { mRequestedSize.set(newSize); mBufferItemConsumer->setDefaultBufferSize(mRequestedSize.width, mRequestedSize.height); - if (mLastBufferScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { + if (mLastBufferInfo.scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; - t.setFrame(mSurfaceControl, - {0, 0, static_cast(mSize.width), - static_cast(mSize.height)}); + // We only need to update the scale if we've received at least one buffer. The reason + // for this is the scale is calculated based on the requested size and buffer size. + // If there's no buffer, the scale will always be 1. + if (mLastBufferInfo.hasBuffer) { + setMatrix(&t, mLastBufferInfo); + } applyTransaction = true; } } @@ -374,8 +377,10 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback. incStrong((void*)transactionCallbackThunk); - mLastBufferScalingMode = bufferItem.mScalingMode; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; + mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(), + bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform, + bufferItem.mScalingMode); auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp(this) /* callbackContext */, @@ -388,8 +393,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE); t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast(this)); - t->setFrame(mSurfaceControl, - {0, 0, static_cast(mSize.width), static_cast(mSize.height)}); + setMatrix(t, mLastBufferInfo); t->setCrop(mSurfaceControl, computeCrop(bufferItem)); t->setTransform(mSurfaceControl, bufferItem.mTransform); t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse); @@ -515,6 +519,17 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { return mSize != bufferSize; } +void BLASTBufferQueue::setMatrix(SurfaceComposerClient::Transaction* t, + const BufferInfo& bufferInfo) { + uint32_t bufWidth = bufferInfo.width; + uint32_t bufHeight = bufferInfo.height; + + float dsdx = mSize.width / static_cast(bufWidth); + float dsdy = mSize.height / static_cast(bufHeight); + + t->setMatrix(mSurfaceControl, dsdx, 0, 0, dsdy); +} + void BLASTBufferQueue::setTransactionCompleteCallback( uint64_t frameNumber, std::function&& transactionCompleteCallback) { std::lock_guard _lock{mMutex}; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index d653ae71be..8c21553bff 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -458,10 +458,6 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eCropChanged; crop = other.crop; } - if (other.what & eFrameChanged) { - what |= eFrameChanged; - orientedDisplaySpaceRect = other.orientedDisplaySpaceRect; - } if (other.what & eBufferChanged) { what |= eBufferChanged; buffer = other.buffer; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 0b01084633..f12b77e48f 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1246,20 +1246,6 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp& sc, const Rect& frame) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eFrameChanged; - s->orientedDisplaySpaceRect = frame; - - registerSurfaceControlForCallback(sc); - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( const sp& sc, const sp& buffer, ReleaseBufferCallback callback) { diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index fbd16f4ea2..a48f95ae73 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -142,6 +142,33 @@ private: ui::Size mRequestedSize GUARDED_BY(mMutex); int32_t mFormat GUARDED_BY(mMutex); + struct BufferInfo { + bool hasBuffer = false; + uint32_t width; + uint32_t height; + uint32_t transform; + // This is used to check if we should update the blast layer size immediately or wait until + // we get the next buffer. This will support scenarios where the layer can change sizes + // and the buffer will scale to fit the new size. + uint32_t scalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; + + void update(bool hasBuffer, uint32_t width, uint32_t height, uint32_t transform, + uint32_t scalingMode) { + this->hasBuffer = hasBuffer; + this->width = width; + this->height = height; + this->transform = transform; + this->scalingMode = scalingMode; + } + }; + + // Last acquired buffer's info. This is used to calculate the correct scale when size change is + // requested. We need to use the old buffer's info to determine what scale we need to apply to + // ensure the correct size. + BufferInfo mLastBufferInfo GUARDED_BY(mMutex); + void setMatrix(SurfaceComposerClient::Transaction* t, const BufferInfo& bufferInfo) + REQUIRES(mMutex); + uint32_t mTransformHint GUARDED_BY(mMutex); sp mConsumer; @@ -159,11 +186,6 @@ private: std::queue mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); - // Last acquired buffer's scaling mode. This is used to check if we should update the blast - // layer size immediately or wait until we get the next buffer. This will support scenarios - // where the layer can change sizes and the buffer will scale to fit the new size. - uint32_t mLastBufferScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; - // Tracks the last acquired frame number uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 92747779fd..9186ed289e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -106,7 +106,7 @@ struct layer_state_t { eHasListenerCallbacksChanged = 0x20000000, eInputInfoChanged = 0x40000000, eCornerRadiusChanged = 0x80000000, - eFrameChanged = 0x1'00000000, + /* was eFrameChanged, now available 0x1'00000000, */ eCachedBufferChanged = 0x2'00000000, eBackgroundColorChanged = 0x4'00000000, eMetadataChanged = 0x8'00000000, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index c38375cf77..19d898c96a 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -474,7 +474,6 @@ public: Transaction& setTransform(const sp& sc, uint32_t transform); Transaction& setTransformToDisplayInverse(const sp& sc, bool transformToDisplayInverse); - Transaction& setFrame(const sp& sc, const Rect& frame); Transaction& setBuffer(const sp& sc, const sp& buffer, ReleaseBufferCallback callback = nullptr); Transaction& setCachedBuffer(const sp& sc, int32_t bufferId); diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index fe48d88376..9b1f0db83b 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -140,7 +140,6 @@ protected: /*parent*/ nullptr); t.setLayerStack(mSurfaceControl, 0) .setLayer(mSurfaceControl, std::numeric_limits::max()) - .setFrame(mSurfaceControl, Rect(resolution)) .show(mSurfaceControl) .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB) .apply(); @@ -218,13 +217,13 @@ protected: col >= region.left - border && col < region.right + border; } if (!outsideRegion && inRegion) { - EXPECT_GE(epsilon, abs(r - *(pixel))); - EXPECT_GE(epsilon, abs(g - *(pixel + 1))); - EXPECT_GE(epsilon, abs(b - *(pixel + 2))); + ASSERT_GE(epsilon, abs(r - *(pixel))); + ASSERT_GE(epsilon, abs(g - *(pixel + 1))); + ASSERT_GE(epsilon, abs(b - *(pixel + 2))); } else if (outsideRegion && !inRegion) { - EXPECT_GE(epsilon, abs(r - *(pixel))); - EXPECT_GE(epsilon, abs(g - *(pixel + 1))); - EXPECT_GE(epsilon, abs(b - *(pixel + 2))); + ASSERT_GE(epsilon, abs(r - *(pixel))); + ASSERT_GE(epsilon, abs(g - *(pixel + 1))); + ASSERT_GE(epsilon, abs(b - *(pixel + 2))); } ASSERT_EQ(false, ::testing::Test::HasFailure()); } @@ -466,7 +465,8 @@ TEST_F(BLASTBufferQueueTest, SetCrop_Item) { ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); + checkScreenCapture(r, g, b, + {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); } TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { @@ -523,13 +523,15 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { // capture screen and verify that it is red ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); + Rect bounds; + bounds.left = finalCropSideLength / 2; + bounds.top = 0; + bounds.right = bounds.left + finalCropSideLength; + bounds.bottom = finalCropSideLength; + + ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b, bounds)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, - {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength})); - ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(0, 0, 0, - {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}, - /*border*/ 0, /*outsideRegion*/ true)); + checkScreenCapture(0, 0, 0, bounds, /*border*/ 0, /*outsideRegion*/ true)); } class TestProducerListener : public BnProducerListener { @@ -596,7 +598,6 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { t.setLayerStack(bgSurface, 0) .show(bgSurface) .setDataspace(bgSurface, ui::Dataspace::V0_SRGB) - .setFrame(bgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight)) .setLayer(bgSurface, std::numeric_limits::max() - 1) .apply(); @@ -619,7 +620,8 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); + checkScreenCapture(r, g, b, + {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); } class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest { diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index a974dc4488..7a10769757 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -278,9 +278,8 @@ bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { return stateUpdateAvailable; } -// Crop that applies to the window -Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const { - return Rect::INVALID_RECT; +Rect BufferStateLayer::getCrop(const Layer::State& s) const { + return s.crop; } bool BufferStateLayer::setTransform(uint32_t transform) { @@ -301,57 +300,53 @@ bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInver } bool BufferStateLayer::setCrop(const Rect& crop) { - Rect c = crop; - if (c.left < 0) { - c.left = 0; - } - if (c.top < 0) { - c.top = 0; - } - // If the width and/or height are < 0, make it [0, 0, -1, -1] so the equality comparision below - // treats all invalid rectangles the same. - if (!c.isValid()) { - c.makeInvalid(); - } + if (mCurrentState.crop == crop) return false; + mCurrentState.sequence++; + mCurrentState.crop = crop; - if (mCurrentState.crop == c) return false; - mCurrentState.crop = c; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } -bool BufferStateLayer::setFrame(const Rect& frame) { - int x = frame.left; - int y = frame.top; - int w = frame.getWidth(); - int h = frame.getHeight(); - - if (x < 0) { - x = 0; - w = frame.right; +bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, + bool allowNonRectPreservingTransforms) { + if (mCurrentState.transform.dsdx() == matrix.dsdx && + mCurrentState.transform.dtdy() == matrix.dtdy && + mCurrentState.transform.dtdx() == matrix.dtdx && + mCurrentState.transform.dsdy() == matrix.dsdy) { + return false; } - if (y < 0) { - y = 0; - h = frame.bottom; - } + ui::Transform t; + t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); - if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y && - mCurrentState.width == w && mCurrentState.height == h) { + if (!allowNonRectPreservingTransforms && !t.preserveRects()) { + ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER nor " + "ROTATE_SURFACE_FLINGER ignored"); return false; } - if (!frame.isValid()) { - x = y = w = h = 0; + mCurrentState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + + mCurrentState.sequence++; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + + return true; +} + +bool BufferStateLayer::setPosition(float x, float y) { + if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) { + return false; } + mCurrentState.transform.set(x, y); - mCurrentState.width = w; - mCurrentState.height = h; mCurrentState.sequence++; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); + return true; } @@ -428,6 +423,10 @@ bool BufferStateLayer::setBuffer(const sp& buffer, const spmFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime, FrameTracer::FrameEvent::QUEUE); } + + mCurrentState.width = mCurrentState.buffer->width; + mCurrentState.height = mCurrentState.buffer->height; + return true; } @@ -855,33 +854,6 @@ sp BufferStateLayer::createClone() { return layer; } -Layer::RoundedCornerState BufferStateLayer::getRoundedCornerState() const { - const auto& p = mDrawingParent.promote(); - if (p != nullptr) { - RoundedCornerState parentState = p->getRoundedCornerState(); - if (parentState.radius > 0) { - ui::Transform t = getActiveTransform(getDrawingState()); - t = t.inverse(); - parentState.cropRect = t.transform(parentState.cropRect); - // The rounded corners shader only accepts 1 corner radius for performance reasons, - // but a transform matrix can define horizontal and vertical scales. - // Let's take the average between both of them and pass into the shader, practically we - // never do this type of transformation on windows anyway. - parentState.radius *= (t[0][0] + t[1][1]) / 2.0f; - return parentState; - } - } - const float radius = getDrawingState().cornerRadius; - const State& s(getDrawingState()); - if (radius <= 0 || (getActiveWidth(s) == UINT32_MAX && getActiveHeight(s) == UINT32_MAX)) - return RoundedCornerState(); - return RoundedCornerState(FloatRect(static_cast(s.transform.tx()), - static_cast(s.transform.ty()), - static_cast(s.transform.tx() + s.width), - static_cast(s.transform.ty() + s.height)), - radius); -} - bool BufferStateLayer::bufferNeedsFiltering() const { const State& s(getDrawingState()); if (!s.buffer) { diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 7a3da6fec1..af2819eac7 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -66,7 +66,6 @@ public: bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; bool setCrop(const Rect& crop) override; - bool setFrame(const Rect& frame) override; bool setBuffer(const sp& buffer, const sp& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, @@ -81,15 +80,13 @@ public: bool setTransactionCompletedListeners(const std::vector>& handles) override; bool addFrameEvent(const sp& acquireFence, nsecs_t postedTime, nsecs_t requestedPresentTime) override; + bool setPosition(float /*x*/, float /*y*/) override; + bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/, + bool /*allowNonRectPreservingTransforms*/); // Override to ignore legacy layer state properties that are not used by BufferStateLayer bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; } - bool setPosition(float /*x*/, float /*y*/) override { return false; } bool setTransparentRegionHint(const Region& transparent) override; - bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/, - bool /*allowNonRectPreservingTransforms*/) override { - return false; - } void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, uint64_t /*frameNumber*/) override {} void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, @@ -97,7 +94,6 @@ public: Rect getBufferSize(const State& s) const override; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; - Layer::RoundedCornerState getRoundedCornerState() const override; void setAutoRefresh(bool autoRefresh) override; // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index cd3e8add9a..447cbb3854 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2312,8 +2312,8 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const { } } const float radius = getDrawingState().cornerRadius; - return radius > 0 && getCrop(getDrawingState()).isValid() - ? RoundedCornerState(getCrop(getDrawingState()).toFloatRect(), radius) + return radius > 0 && getCroppedBufferSize(getDrawingState()).isValid() + ? RoundedCornerState(getCroppedBufferSize(getDrawingState()).toFloatRect(), radius) : RoundedCornerState(); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 1c5d6ecb03..4cd379b963 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -462,7 +462,6 @@ public: // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; - virtual bool setFrame(const Rect& /*frame*/) { return false; }; virtual bool setBuffer(const sp& /*buffer*/, const sp& /*acquireFence*/, nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/, diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index 1d00cc38f2..7a3e433660 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -231,8 +231,14 @@ const std::vector>& RefreshRateOverlay::getOrCreateBuffers(uin void RefreshRateOverlay::setViewport(ui::Size viewport) { Rect frame((3 * viewport.width) >> 4, viewport.height >> 5); frame.offsetBy(viewport.width >> 5, viewport.height >> 4); - mLayer->setFrame(frame); + layer_state_t::matrix22_t matrix; + matrix.dsdx = frame.getWidth() / static_cast(SevenSegmentDrawer::getWidth()); + matrix.dtdx = 0; + matrix.dtdy = 0; + matrix.dsdy = frame.getHeight() / static_cast(SevenSegmentDrawer::getHeight()); + mLayer->setMatrix(matrix, true); + mLayer->setPosition(frame.left, frame.top); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a387587d7f..b1d63f0ce7 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3936,9 +3936,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & layer_state_t::eCropChanged) { if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; } - if (what & layer_state_t::eFrameChanged) { - if (layer->setFrame(s.orientedDisplaySpaceRect)) flags |= eTraversalNeeded; - } if (what & layer_state_t::eAcquireFenceChanged) { if (layer->setAcquireFence(s.acquireFence)) flags |= eTraversalNeeded; } diff --git a/services/surfaceflinger/tests/BufferGenerator.cpp b/services/surfaceflinger/tests/BufferGenerator.cpp index 03f8e1afba..47a150dd35 100644 --- a/services/surfaceflinger/tests/BufferGenerator.cpp +++ b/services/surfaceflinger/tests/BufferGenerator.cpp @@ -296,12 +296,12 @@ private: BufferGenerator::BufferGenerator() : mSurfaceManager(new SurfaceManager), mEglManager(new EglManager), mProgram(new Program) { - const float width = 1000.0; - const float height = 1000.0; + mBufferSize.set(1000.0, 1000.0); auto setBufferWithContext = std::bind(setBuffer, std::placeholders::_1, std::placeholders::_2, this); - mSurfaceManager->initialize(width, height, HAL_PIXEL_FORMAT_RGBA_8888, setBufferWithContext); + mSurfaceManager->initialize(mBufferSize.width, mBufferSize.height, HAL_PIXEL_FORMAT_RGBA_8888, + setBufferWithContext); if (!mEglManager->initialize(mSurfaceManager->getSurface())) return; @@ -309,7 +309,9 @@ BufferGenerator::BufferGenerator() if (!mProgram->initialize(VERTEX_SHADER, FRAGMENT_SHADER)) return; mProgram->use(); - mProgram->bindVec4(0, vec4{width, height, 1.0f / width, 1.0f / height}); + mProgram->bindVec4(0, + vec4{mBufferSize.width, mBufferSize.height, 1.0f / mBufferSize.width, + 1.0f / mBufferSize.height}); mProgram->bindVec3(2, &SPHERICAL_HARMONICS[0], 4); glEnableVertexAttribArray(0); @@ -372,6 +374,10 @@ status_t BufferGenerator::get(sp* outBuffer, sp* outFence) return NO_ERROR; } +ui::Size BufferGenerator::getSize() { + return mBufferSize; +} + // static void BufferGenerator::setBuffer(const sp& buffer, int32_t fence, void* bufferGenerator) { diff --git a/services/surfaceflinger/tests/BufferGenerator.h b/services/surfaceflinger/tests/BufferGenerator.h index a3ffe86572..f7d548b6bf 100644 --- a/services/surfaceflinger/tests/BufferGenerator.h +++ b/services/surfaceflinger/tests/BufferGenerator.h @@ -37,6 +37,7 @@ public: /* Static callback that sets the fence on a particular instance */ static void setBuffer(const sp& buffer, int32_t fence, void* fenceGenerator); + ui::Size getSize(); private: bool mInitialized = false; @@ -53,6 +54,7 @@ private: using Epoch = std::chrono::time_point; Epoch mEpoch = std::chrono::steady_clock::now(); + ui::Size mBufferSize; }; } // namespace android diff --git a/services/surfaceflinger/tests/EffectLayer_test.cpp b/services/surfaceflinger/tests/EffectLayer_test.cpp index f470eda7d3..af00ec7fc9 100644 --- a/services/surfaceflinger/tests/EffectLayer_test.cpp +++ b/services/surfaceflinger/tests/EffectLayer_test.cpp @@ -149,7 +149,6 @@ TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) { t.reparent(blurLayer, mParentLayer); t.setBackgroundBlurRadius(blurLayer, blurRadius); t.setCrop(blurLayer, blurRect); - t.setFrame(blurLayer, blurRect); t.setAlpha(blurLayer, 0.0f); t.show(blurLayer); }); diff --git a/services/surfaceflinger/tests/IPC_test.cpp b/services/surfaceflinger/tests/IPC_test.cpp index a8647c3e50..9fa3d4c417 100644 --- a/services/surfaceflinger/tests/IPC_test.cpp +++ b/services/surfaceflinger/tests/IPC_test.cpp @@ -161,7 +161,6 @@ public: Color::RED); transaction->setLayerStack(mSurfaceControl, 0) .setLayer(mSurfaceControl, std::numeric_limits::max()) - .setFrame(mSurfaceControl, Rect(0, 0, width, height)) .setBuffer(mSurfaceControl, gb) .setAcquireFence(mSurfaceControl, fence) .show(mSurfaceControl) diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp index 158801a705..011ff70409 100644 --- a/services/surfaceflinger/tests/LayerCallback_test.cpp +++ b/services/surfaceflinger/tests/LayerCallback_test.cpp @@ -164,7 +164,10 @@ TEST_F(LayerCallbackTest, NoBufferNoColor) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer, @@ -184,7 +187,10 @@ TEST_F(LayerCallbackTest, BufferNoColor) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -203,7 +209,10 @@ TEST_F(LayerCallbackTest, NoBufferColor) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, @@ -238,7 +247,10 @@ TEST_F(LayerCallbackTest, OffScreen) { return; } - transaction.setFrame(layer, Rect(-100, -100, 100, 100)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(-100, -100, 100, 100)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -263,8 +275,15 @@ TEST_F(LayerCallbackTest, MergeBufferNoColor) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -290,8 +309,15 @@ TEST_F(LayerCallbackTest, MergeNoBufferColor) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -318,8 +344,15 @@ TEST_F(LayerCallbackTest, MergeOneBufferOneColor) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer1); @@ -405,8 +438,15 @@ TEST_F(LayerCallbackTest, Merge_DifferentClients) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -491,7 +531,11 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SameStateChange) { } } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface((i == 0) ? ExpectedResult::Transaction::PRESENTED @@ -523,8 +567,16 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -564,8 +616,16 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -606,8 +666,15 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_NoStateCha return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -661,8 +728,15 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateC return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -682,7 +756,10 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateC return; } - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + transaction2.merge(std::move(transaction1)).apply(); expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer2, ExpectedResult::Buffer::NOT_ACQUIRED); @@ -762,7 +839,10 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expectedResult; expectedResult.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -781,7 +861,10 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + TransactionUtils::setFrame(transaction, layer, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); } EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true)); } diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp index 7505e6ea9b..53d230abe7 100644 --- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp @@ -204,11 +204,7 @@ void LayerRenderTypeTransactionTest::setRelativeZBasicHelper(uint32_t layerType) Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply(); break; case ISurfaceComposerClient::eFXSurfaceBufferState: - Transaction() - .setFrame(layerR, Rect(0, 0, 32, 32)) - .setFrame(layerG, Rect(16, 16, 48, 48)) - .setRelativeLayer(layerG, layerR, 1) - .apply(); + Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply(); break; default: ASSERT_FALSE(true) << "Unsupported layer type"; @@ -260,10 +256,9 @@ void LayerRenderTypeTransactionTest::setRelativeZGroupHelper(uint32_t layerType) break; case ISurfaceComposerClient::eFXSurfaceBufferState: Transaction() - .setFrame(layerR, Rect(0, 0, 32, 32)) - .setFrame(layerG, Rect(8, 8, 40, 40)) + .setPosition(layerG, 8, 8) .setRelativeLayer(layerG, layerR, 3) - .setFrame(layerB, Rect(16, 16, 48, 48)) + .setPosition(layerB, 16, 16) .setLayer(layerB, mLayerZBase + 2) .apply(); break; @@ -388,7 +383,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintBasic_BufferState Transaction() .setTransparentRegionHint(layer, Region(top)) .setBuffer(layer, buffer) - .setFrame(layer, Rect(0, 0, 32, 32)) .apply(); { SCOPED_TRACE("top transparent"); @@ -447,7 +441,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintOutOfBounds_Buffe // check that transparent region hint is bound by the layer size Transaction() .setTransparentRegionHint(layerTransparent, Region(mDisplayRect)) - .setFrame(layerR, Rect(16, 16, 48, 48)) + .setPosition(layerR, 16, 16) .setLayer(layerR, mLayerZBase + 1) .apply(); ASSERT_NO_FATAL_FAILURE( @@ -477,8 +471,7 @@ void LayerRenderTypeTransactionTest::setAlphaBasicHelper(uint32_t layerType) { Transaction() .setAlpha(layer1, 0.25f) .setAlpha(layer2, 0.75f) - .setFrame(layer1, Rect(0, 0, 32, 32)) - .setFrame(layer2, Rect(16, 0, 48, 32)) + .setPosition(layer2, 16, 0) .setLayer(layer2, mLayerZBase + 1) .apply(); break; @@ -573,7 +566,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, fillColor, width, height)); expectedColor = fillColor; } - Transaction().setFrame(layer, Rect(0, 0, width, height)).apply(); + Transaction().setCrop(layer, Rect(0, 0, width, height)).apply(); break; default: GTEST_FAIL() << "Unknown layer type in setBackgroundColorHelper"; @@ -849,42 +842,39 @@ TEST_P(LayerRenderTypeTransactionTest, SetMatrixBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); - Transaction() - .setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f) - .setFrame(layer, Rect(0, 0, 32, 32)) - .apply(); + Transaction().setPosition(layer, 32, 32).setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f).apply(); { SCOPED_TRACE("IDENTITY"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, + getScreenCapture()->expectQuadrant(Rect(32, 32, 64, 64), Color::RED, Color::GREEN, Color::BLUE, Color::WHITE); } Transaction().setMatrix(layer, -1.0f, 0.0f, 0.0f, 1.0f).apply(); { SCOPED_TRACE("FLIP_H"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(0, 32, 32, 64), Color::GREEN, Color::RED, + Color::WHITE, Color::BLUE); } Transaction().setMatrix(layer, 1.0f, 0.0f, 0.0f, -1.0f).apply(); { SCOPED_TRACE("FLIP_V"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(32, 0, 64, 32), Color::BLUE, Color::WHITE, + Color::RED, Color::GREEN); } Transaction().setMatrix(layer, 0.0f, 1.0f, -1.0f, 0.0f).apply(); { SCOPED_TRACE("ROT_90"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(0, 32, 32, 64), Color::BLUE, Color::RED, + Color::WHITE, Color::GREEN); } Transaction().setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f).apply(); { SCOPED_TRACE("SCALE"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(32, 32, 96, 96), Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE, 1 /* tolerance */); } } @@ -955,8 +945,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropBasic_BufferState) { Transaction().setCrop(layer, crop).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(crop, Color::RED); + shot->expectBorder(crop, Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferQueue) { @@ -986,13 +976,13 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferState) { { SCOPED_TRACE("empty rect"); Transaction().setCrop(layer, Rect(8, 8, 8, 8)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); } { SCOPED_TRACE("negative rect"); Transaction().setCrop(layer, Rect(8, 8, 0, 0)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); } } @@ -1016,8 +1006,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 16), Color::BLUE); TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 16, 32, 64), Color::RED); - Transaction().setFrame(layer, Rect(0, 0, 64, 64)).apply(); - Transaction().setBuffer(layer, buffer).apply(); // Partially out of bounds in the negative (upper left) direction @@ -1025,8 +1013,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("out of bounds, negative (upper left) direction"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 64), Color::BLUE); - shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 16), Color::BLUE); + shot->expectBorder(Rect(0, 0, 32, 16), Color::BLACK); } // Partially out of bounds in the positive (lower right) direction @@ -1034,8 +1022,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("out of bounds, positive (lower right) direction"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 64), Color::RED); - shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 16, 32, 64), Color::RED); + shot->expectBorder(Rect(0, 16, 32, 64), Color::BLACK); } // Fully out of buffer space bounds @@ -1043,9 +1031,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("Fully out of bounds"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 16), Color::BLUE); - shot->expectColor(Rect(0, 16, 64, 64), Color::RED); - shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 0, 64, 64), Color::BLACK); } } @@ -1068,12 +1054,11 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropWithTranslation_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); - const Rect frame(32, 32, 64, 64); const Rect crop(8, 8, 24, 24); - Transaction().setFrame(layer, frame).setCrop(layer, crop).apply(); + Transaction().setPosition(layer, 32, 32).setCrop(layer, crop).apply(); auto shot = getScreenCapture(); - shot->expectColor(frame, Color::RED); - shot->expectBorder(frame, Color::BLACK); + shot->expectColor(Rect(40, 40, 56, 56), Color::RED); + shot->expectBorder(Rect(40, 40, 56, 56), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetCropWithScale_BufferQueue) { @@ -1121,7 +1106,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); const Rect frame(8, 8, 24, 24); - Transaction().setFrame(layer, frame).apply(); + Transaction t; + TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), frame); + t.apply(); + auto shot = getScreenCapture(); shot->expectColor(frame, Color::RED); shot->expectBorder(frame, Color::BLACK); @@ -1133,16 +1121,23 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameEmpty_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + Transaction t; { SCOPED_TRACE("empty rect"); - Transaction().setFrame(layer, Rect(8, 8, 8, 8)).apply(); + TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), Rect(8, 8, 8, 8)); + t.apply(); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); } { SCOPED_TRACE("negative rect"); - Transaction().setFrame(layer, Rect(8, 8, 0, 0)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); + TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), Rect(8, 8, 0, 0)); + t.apply(); + + auto shot = getScreenCapture(); + shot->expectColor(Rect(0, 0, 8, 8), Color::RED); + shot->expectBorder(Rect(0, 0, 8, 8), Color::BLACK); } } @@ -1152,10 +1147,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultParentless_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 10, 10)); - // A parentless layer will default to a frame with the same size as the buffer + // A layer with a buffer will have a computed size that matches the buffer size. auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 10, 10), Color::RED); + shot->expectBorder(Rect(0, 0, 10, 10), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBSParent_BufferState) { @@ -1163,17 +1158,16 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBSParent_BufferState) { ASSERT_NO_FATAL_FAILURE( parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32)); - Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply(); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); Transaction().reparent(child, parent).apply(); - // A layer will default to the frame of its parent + // A layer with a buffer will have a computed size that matches the buffer size. auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectColor(Rect(0, 0, 10, 10), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1183,14 +1177,14 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBQParent_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parent, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); Transaction().reparent(child, parent).apply(); - // A layer will default to the frame of its parent + // A layer with a buffer will have a computed size that matches the buffer size. auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectColor(Rect(0, 0, 10, 10), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1199,11 +1193,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameUpdate_BufferState) { ASSERT_NO_FATAL_FAILURE( layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); - Transaction().setFrame(layer, Rect(0, 0, 32, 32)).apply(); std::this_thread::sleep_for(500ms); - Transaction().setFrame(layer, Rect(16, 16, 48, 48)).apply(); + Transaction().setPosition(layer, 16, 16).apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(16, 16, 48, 48), Color::RED); @@ -1215,18 +1208,20 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameOutsideBounds_BufferState) { ASSERT_NO_FATAL_FAILURE( parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); Transaction().reparent(child, parent).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32)); - Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); - Transaction().setFrame(child, Rect(0, 16, 32, 32)).apply(); + Rect childDst(0, 16, 32, 32); + Transaction t; + TransactionUtils::setFrame(t, child, Rect(0, 0, 10, 10), childDst); + t.apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(0, 0, 32, 16), Color::RED); - shot->expectColor(Rect(0, 16, 32, 32), Color::BLUE); + shot->expectColor(childDst, Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1238,8 +1233,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { @@ -1252,8 +1247,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 1"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32)); @@ -1261,8 +1256,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 2"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLUE); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); @@ -1270,8 +1265,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 3"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } } @@ -1286,7 +1281,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleLayers_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::RED, 64, 64)); - Transaction().setFrame(layer1, Rect(0, 0, 64, 64)).apply(); { SCOPED_TRACE("set layer 1 buffer red"); auto shot = getScreenCapture(); @@ -1295,7 +1289,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleLayers_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::BLUE, 32, 32)); - Transaction().setFrame(layer2, Rect(0, 0, 32, 32)).apply(); { SCOPED_TRACE("set layer 2 buffer blue"); auto shot = getScreenCapture(); @@ -1350,8 +1343,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_BufferState) { Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), color); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } idx++; } @@ -1383,8 +1376,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_LeastRecentlyUsed_Buffer Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), color); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } idx++; } @@ -1416,8 +1409,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_DestroyedBuffer_BufferSt Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), color); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } if (idx == 0) { buffers[0].clear(); @@ -1435,7 +1428,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformRotate90_BufferState) { Color::BLUE, Color::WHITE)); Transaction() - .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_ROT_90) .apply(); @@ -1452,7 +1444,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformFlipH_BufferState) { Color::BLUE, Color::WHITE)); Transaction() - .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_H) .apply(); @@ -1469,7 +1460,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformFlipV_BufferState) { Color::BLUE, Color::WHITE)); Transaction() - .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_V) .apply(); @@ -1518,8 +1508,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetFenceNull_BufferState) { Transaction().setBuffer(layer, buffer).setAcquireFence(layer, fence).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) { @@ -1534,8 +1524,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) { Transaction().setBuffer(layer, buffer).setDataspace(layer, ui::Dataspace::UNKNOWN).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetHdrMetadataBasic_BufferState) { @@ -1552,8 +1542,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetHdrMetadataBasic_BufferState) { Transaction().setBuffer(layer, buffer).setHdrMetadata(layer, hdrMetadata).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetSurfaceDamageRegionBasic_BufferState) { @@ -1570,8 +1560,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetSurfaceDamageRegionBasic_BufferState) Transaction().setBuffer(layer, buffer).setSurfaceDamageRegion(layer, region).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetApiBasic_BufferState) { @@ -1586,8 +1576,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetApiBasic_BufferState) { Transaction().setBuffer(layer, buffer).setApi(layer, NATIVE_WINDOW_API_CPU).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetColorTransformBasic) { diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index 87c7b7d829..0bc8fe7aa0 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -244,6 +244,11 @@ protected: return bufferGenerator.get(outBuffer, outFence); } + static ui::Size getBufferSize() { + static BufferGenerator bufferGenerator; + return bufferGenerator.getSize(); + } + sp mClient; bool deviceSupportsBlurs() { diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp index ac5e297e43..edf55ea6ef 100644 --- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp @@ -196,17 +196,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadius) { ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size)); - if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - Transaction() - .setCornerRadius(layer, cornerRadius) - .setCrop(layer, Rect(0, 0, size, size)) - .apply(); - } else { - Transaction() - .setCornerRadius(layer, cornerRadius) - .setFrame(layer, Rect(0, 0, size, size)) - .apply(); - } + Transaction().setCornerRadius(layer, cornerRadius).apply(); { const uint8_t bottom = size - 1; const uint8_t right = size - 1; @@ -234,19 +224,13 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusRotated) { ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size)); - auto transaction = Transaction() - .setCornerRadius(parent, cornerRadius) - .setCrop(parent, Rect(0, 0, size, size)) - .reparent(child, parent) - .setPosition(child, 0, size) - // Rotate by half PI - .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f); - if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - transaction.setCrop(parent, Rect(0, 0, size, size)); - } else { - transaction.setFrame(parent, Rect(0, 0, size, size)); - } - transaction.apply(); + Transaction() + .setCornerRadius(parent, cornerRadius) + .reparent(child, parent) + .setPosition(child, 0, size) + // Rotate by half PI + .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f) + .apply(); { const uint8_t bottom = size - 1; @@ -275,21 +259,12 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusChildCrop) { ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size / 2)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size / 2)); - if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - Transaction() - .setCornerRadius(parent, cornerRadius) - .setCrop(parent, Rect(0, 0, size, size)) - .reparent(child, parent) - .setPosition(child, 0, size / 2) - .apply(); - } else { - Transaction() - .setCornerRadius(parent, cornerRadius) - .setFrame(parent, Rect(0, 0, size, size)) - .reparent(child, parent) - .setFrame(child, Rect(0, size / 2, size, size)) - .apply(); - } + Transaction() + .setCornerRadius(parent, cornerRadius) + .reparent(child, parent) + .setPosition(child, 0, size / 2) + .apply(); + { const uint8_t bottom = size - 1; const uint8_t right = size - 1; @@ -331,12 +306,9 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { Transaction() .setLayer(greenLayer, mLayerZBase) - .setFrame(leftLayer, {0, 0, canvasSize * 2, canvasSize * 2}) .setLayer(leftLayer, mLayerZBase + 1) - .setFrame(leftLayer, leftRect) .setLayer(rightLayer, mLayerZBase + 2) .setPosition(rightLayer, rightRect.left, rightRect.top) - .setFrame(rightLayer, rightRect) .apply(); { @@ -352,7 +324,6 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { .setLayer(blurLayer, mLayerZBase + 3) .setBackgroundBlurRadius(blurLayer, blurRadius) .setCrop(blurLayer, blurRect) - .setFrame(blurLayer, blurRect) .setSize(blurLayer, blurRect.getWidth(), blurRect.getHeight()) .setAlpha(blurLayer, 0.0f) .apply(); @@ -435,10 +406,8 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentA Transaction() .setLayer(left, mLayerZBase + 1) - .setFrame(left, {0, 0, size, size}) .setLayer(right, mLayerZBase + 2) .setPosition(right, size, 0) - .setFrame(right, {size, 0, size * 2, size}) .apply(); { @@ -457,7 +426,6 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentA .setAlpha(blurParent, 0.5) .setLayer(blur, mLayerZBase + 4) .setBackgroundBlurRadius(blur, size) // set the blur radius to the size of one rect - .setFrame(blur, {0, 0, size * 2, size}) .reparent(blur, blurParent) .apply(); diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp index 613b21ef04..ccf434d63a 100644 --- a/services/surfaceflinger/tests/MirrorLayer_test.cpp +++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp @@ -195,7 +195,7 @@ TEST_F(MirrorLayerTest, MirrorBufferLayer) { createLayer("BufferStateLayer", 200, 200, ISurfaceComposerClient::eFXSurfaceBufferState, mChildLayer.get()); fillBufferStateLayerColor(bufferStateLayer, Color::BLUE, 200, 200); - Transaction().setFrame(bufferStateLayer, Rect(0, 0, 200, 200)).show(bufferStateLayer).apply(); + Transaction().show(bufferStateLayer).apply(); { SCOPED_TRACE("Initial Mirror BufferStateLayer"); diff --git a/services/surfaceflinger/tests/utils/TransactionUtils.h b/services/surfaceflinger/tests/utils/TransactionUtils.h index 3cbfed98f5..8c448e2f96 100644 --- a/services/surfaceflinger/tests/utils/TransactionUtils.h +++ b/services/surfaceflinger/tests/utils/TransactionUtils.h @@ -126,7 +126,7 @@ public: const uint8_t* src = pixels + (outBuffer->getStride() * (y + j) + x) * 4; for (int32_t i = 0; i < width; i++) { const uint8_t expected[4] = {color.r, color.g, color.b, color.a}; - EXPECT_TRUE(std::equal(src, src + 4, expected, colorCompare)) + ASSERT_TRUE(std::equal(src, src + 4, expected, colorCompare)) << "pixel @ (" << x + i << ", " << y + j << "): " << "expected (" << color << "), " << "got (" << Color{src[0], src[1], src[2], src[3]} << ")"; @@ -161,6 +161,22 @@ public: ASSERT_EQ(NO_ERROR, s->unlockAndPost()); } } + + static void setFrame(Transaction& t, const sp& sc, Rect source, Rect dest, + int32_t transform = 0) { + uint32_t sourceWidth = source.getWidth(); + uint32_t sourceHeight = source.getHeight(); + + if (transform & ui::Transform::ROT_90) { + std::swap(sourceWidth, sourceHeight); + } + + float dsdx = dest.getWidth() / static_cast(sourceWidth); + float dsdy = dest.getHeight() / static_cast(sourceHeight); + + t.setMatrix(sc, dsdx, 0, 0, dsdy); + t.setPosition(sc, dest.left, dest.top); + } }; enum class RenderPath { SCREENSHOT, VIRTUAL_DISPLAY }; -- cgit v1.2.3-59-g8ed1b From ddf9b5c4248c40dccff5b55c47a5125709f1109c Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Mon, 29 Mar 2021 18:53:41 -0700 Subject: Check for buffer changes explicitly instead of relying on acquire fence changes Bug: 183997574 Test: atest ASurfaceControlTest Change-Id: I4eabec13faa09b3d1f61d62e637b83baa720797d --- libs/gui/LayerState.cpp | 4 ++++ libs/gui/include/gui/LayerState.h | 1 + services/surfaceflinger/SurfaceFlinger.cpp | 6 +++--- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index d653ae71be..467dcdaf18 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -563,6 +563,10 @@ void layer_state_t::merge(const layer_state_t& other) { } } +bool layer_state_t::hasBufferChanges() const { + return (what & layer_state_t::eBufferChanged) || (what & layer_state_t::eCachedBufferChanged); +} + status_t layer_state_t::matrix22_t::write(Parcel& output) const { SAFE_PARCEL(output.writeFloat, dsdx); SAFE_PARCEL(output.writeFloat, dtdx); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 92747779fd..11f0961c4c 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -127,6 +127,7 @@ struct layer_state_t { void merge(const layer_state_t& other); status_t write(Parcel& output) const; status_t read(const Parcel& input); + bool hasBufferChanges() const; struct matrix22_t { float dsdx{0}; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a387587d7f..f7a2669ee3 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3457,7 +3457,7 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( sp layer = nullptr; if (s.surface) { layer = fromHandleLocked(s.surface).promote(); - } else if (acquireFenceChanged) { + } else if (s.hasBufferChanges()) { ALOGW("Transaction with buffer, but no Layer?"); continue; } @@ -3467,7 +3467,7 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( ATRACE_NAME(layer->getName().c_str()); - if (acquireFenceChanged) { + if (s.hasBufferChanges()) { // If backpressure is enabled and we already have a buffer to commit, keep the // transaction in the queue. const bool hasPendingBuffer = pendingBuffers.find(s.surface) != pendingBuffers.end(); @@ -3550,7 +3550,7 @@ status_t SurfaceFlinger::setTransactionState( // Check for incoming buffer updates and increment the pending buffer count. for (const auto& state : states) { - if ((state.state.what & layer_state_t::eAcquireFenceChanged) && (state.state.surface)) { + if (state.state.hasBufferChanges() && (state.state.surface)) { mBufferCountTracker.increment(state.state.surface->localBinder()); } } -- cgit v1.2.3-59-g8ed1b From 1014c4bf14f5c250b78d7e917fb59aaa9b0d9b0a Mon Sep 17 00:00:00 2001 From: Orion Hodson Date: Thu, 8 Apr 2021 12:30:21 +0000 Subject: Revert "Remove setFrame from BufferStateLayer" Revert "Update tests to reflect the new behavior for setGeometry" Revert submission 13843937-sc_remove_set_frame Reason for revert: Candidate CL for b/184807094 Reverted Changes: Iffbd955a3:Remove setFrame I27f17bc61:Update tests to reflect the new behavior for setGe... I5720276c1:Remove setFrame from surface_control setGeometry I32ee0e3e4:Remove setFrame from BufferStateLayer Bug: 184807094 Change-Id: I8330f374c50c76d8c2e70b79815bc2bc32b89480 --- libs/gui/BLASTBufferQueue.cpp | 29 +--- libs/gui/LayerState.cpp | 4 + libs/gui/SurfaceComposerClient.cpp | 14 ++ libs/gui/include/gui/BLASTBufferQueue.h | 32 +--- libs/gui/include/gui/LayerState.h | 2 +- libs/gui/include/gui/SurfaceComposerClient.h | 1 + libs/gui/tests/BLASTBufferQueue_test.cpp | 34 ++-- services/surfaceflinger/BufferStateLayer.cpp | 98 +++++++----- services/surfaceflinger/BufferStateLayer.h | 10 +- services/surfaceflinger/Layer.cpp | 4 +- services/surfaceflinger/Layer.h | 1 + services/surfaceflinger/RefreshRateOverlay.cpp | 8 +- services/surfaceflinger/SurfaceFlinger.cpp | 3 + services/surfaceflinger/tests/BufferGenerator.cpp | 14 +- services/surfaceflinger/tests/BufferGenerator.h | 2 - services/surfaceflinger/tests/EffectLayer_test.cpp | 1 + services/surfaceflinger/tests/IPC_test.cpp | 1 + .../surfaceflinger/tests/LayerCallback_test.cpp | 131 +++------------- .../tests/LayerRenderTypeTransaction_test.cpp | 174 +++++++++++---------- .../surfaceflinger/tests/LayerTransactionTest.h | 5 - .../LayerTypeAndRenderTypeTransaction_test.cpp | 60 +++++-- services/surfaceflinger/tests/MirrorLayer_test.cpp | 2 +- .../surfaceflinger/tests/utils/TransactionUtils.h | 18 +-- 23 files changed, 295 insertions(+), 353 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 1d7ed2f97b..1976b493b2 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -204,16 +204,13 @@ void BLASTBufferQueue::update(const sp& surface, uint32_t width, if (mRequestedSize != newSize) { mRequestedSize.set(newSize); mBufferItemConsumer->setDefaultBufferSize(mRequestedSize.width, mRequestedSize.height); - if (mLastBufferInfo.scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { + if (mLastBufferScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; - // We only need to update the scale if we've received at least one buffer. The reason - // for this is the scale is calculated based on the requested size and buffer size. - // If there's no buffer, the scale will always be 1. - if (mLastBufferInfo.hasBuffer) { - setMatrix(&t, mLastBufferInfo); - } + t.setFrame(mSurfaceControl, + {0, 0, static_cast(mSize.width), + static_cast(mSize.height)}); applyTransaction = true; } } @@ -377,10 +374,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback. incStrong((void*)transactionCallbackThunk); + mLastBufferScalingMode = bufferItem.mScalingMode; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; - mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(), - bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform, - bufferItem.mScalingMode); auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp(this) /* callbackContext */, @@ -393,7 +388,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE); t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast(this)); - setMatrix(t, mLastBufferInfo); + t->setFrame(mSurfaceControl, + {0, 0, static_cast(mSize.width), static_cast(mSize.height)}); t->setCrop(mSurfaceControl, computeCrop(bufferItem)); t->setTransform(mSurfaceControl, bufferItem.mTransform); t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse); @@ -519,17 +515,6 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { return mSize != bufferSize; } -void BLASTBufferQueue::setMatrix(SurfaceComposerClient::Transaction* t, - const BufferInfo& bufferInfo) { - uint32_t bufWidth = bufferInfo.width; - uint32_t bufHeight = bufferInfo.height; - - float dsdx = mSize.width / static_cast(bufWidth); - float dsdy = mSize.height / static_cast(bufHeight); - - t->setMatrix(mSurfaceControl, dsdx, 0, 0, dsdy); -} - void BLASTBufferQueue::setTransactionCompleteCallback( uint64_t frameNumber, std::function&& transactionCompleteCallback) { std::lock_guard _lock{mMutex}; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 8c21553bff..d653ae71be 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -458,6 +458,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eCropChanged; crop = other.crop; } + if (other.what & eFrameChanged) { + what |= eFrameChanged; + orientedDisplaySpaceRect = other.orientedDisplaySpaceRect; + } if (other.what & eBufferChanged) { what |= eBufferChanged; buffer = other.buffer; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index f12b77e48f..0b01084633 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1246,6 +1246,20 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp& sc, const Rect& frame) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eFrameChanged; + s->orientedDisplaySpaceRect = frame; + + registerSurfaceControlForCallback(sc); + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( const sp& sc, const sp& buffer, ReleaseBufferCallback callback) { diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index a48f95ae73..fbd16f4ea2 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -142,33 +142,6 @@ private: ui::Size mRequestedSize GUARDED_BY(mMutex); int32_t mFormat GUARDED_BY(mMutex); - struct BufferInfo { - bool hasBuffer = false; - uint32_t width; - uint32_t height; - uint32_t transform; - // This is used to check if we should update the blast layer size immediately or wait until - // we get the next buffer. This will support scenarios where the layer can change sizes - // and the buffer will scale to fit the new size. - uint32_t scalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; - - void update(bool hasBuffer, uint32_t width, uint32_t height, uint32_t transform, - uint32_t scalingMode) { - this->hasBuffer = hasBuffer; - this->width = width; - this->height = height; - this->transform = transform; - this->scalingMode = scalingMode; - } - }; - - // Last acquired buffer's info. This is used to calculate the correct scale when size change is - // requested. We need to use the old buffer's info to determine what scale we need to apply to - // ensure the correct size. - BufferInfo mLastBufferInfo GUARDED_BY(mMutex); - void setMatrix(SurfaceComposerClient::Transaction* t, const BufferInfo& bufferInfo) - REQUIRES(mMutex); - uint32_t mTransformHint GUARDED_BY(mMutex); sp mConsumer; @@ -186,6 +159,11 @@ private: std::queue mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); + // Last acquired buffer's scaling mode. This is used to check if we should update the blast + // layer size immediately or wait until we get the next buffer. This will support scenarios + // where the layer can change sizes and the buffer will scale to fit the new size. + uint32_t mLastBufferScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; + // Tracks the last acquired frame number uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 9186ed289e..92747779fd 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -106,7 +106,7 @@ struct layer_state_t { eHasListenerCallbacksChanged = 0x20000000, eInputInfoChanged = 0x40000000, eCornerRadiusChanged = 0x80000000, - /* was eFrameChanged, now available 0x1'00000000, */ + eFrameChanged = 0x1'00000000, eCachedBufferChanged = 0x2'00000000, eBackgroundColorChanged = 0x4'00000000, eMetadataChanged = 0x8'00000000, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 19d898c96a..c38375cf77 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -474,6 +474,7 @@ public: Transaction& setTransform(const sp& sc, uint32_t transform); Transaction& setTransformToDisplayInverse(const sp& sc, bool transformToDisplayInverse); + Transaction& setFrame(const sp& sc, const Rect& frame); Transaction& setBuffer(const sp& sc, const sp& buffer, ReleaseBufferCallback callback = nullptr); Transaction& setCachedBuffer(const sp& sc, int32_t bufferId); diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index 9b1f0db83b..fe48d88376 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -140,6 +140,7 @@ protected: /*parent*/ nullptr); t.setLayerStack(mSurfaceControl, 0) .setLayer(mSurfaceControl, std::numeric_limits::max()) + .setFrame(mSurfaceControl, Rect(resolution)) .show(mSurfaceControl) .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB) .apply(); @@ -217,13 +218,13 @@ protected: col >= region.left - border && col < region.right + border; } if (!outsideRegion && inRegion) { - ASSERT_GE(epsilon, abs(r - *(pixel))); - ASSERT_GE(epsilon, abs(g - *(pixel + 1))); - ASSERT_GE(epsilon, abs(b - *(pixel + 2))); + EXPECT_GE(epsilon, abs(r - *(pixel))); + EXPECT_GE(epsilon, abs(g - *(pixel + 1))); + EXPECT_GE(epsilon, abs(b - *(pixel + 2))); } else if (outsideRegion && !inRegion) { - ASSERT_GE(epsilon, abs(r - *(pixel))); - ASSERT_GE(epsilon, abs(g - *(pixel + 1))); - ASSERT_GE(epsilon, abs(b - *(pixel + 2))); + EXPECT_GE(epsilon, abs(r - *(pixel))); + EXPECT_GE(epsilon, abs(g - *(pixel + 1))); + EXPECT_GE(epsilon, abs(b - *(pixel + 2))); } ASSERT_EQ(false, ::testing::Test::HasFailure()); } @@ -465,8 +466,7 @@ TEST_F(BLASTBufferQueueTest, SetCrop_Item) { ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, - {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); + checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); } TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { @@ -523,15 +523,13 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { // capture screen and verify that it is red ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); - Rect bounds; - bounds.left = finalCropSideLength / 2; - bounds.top = 0; - bounds.right = bounds.left + finalCropSideLength; - bounds.bottom = finalCropSideLength; - - ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b, bounds)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(0, 0, 0, bounds, /*border*/ 0, /*outsideRegion*/ true)); + checkScreenCapture(r, g, b, + {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength})); + ASSERT_NO_FATAL_FAILURE( + checkScreenCapture(0, 0, 0, + {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}, + /*border*/ 0, /*outsideRegion*/ true)); } class TestProducerListener : public BnProducerListener { @@ -598,6 +596,7 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { t.setLayerStack(bgSurface, 0) .show(bgSurface) .setDataspace(bgSurface, ui::Dataspace::V0_SRGB) + .setFrame(bgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight)) .setLayer(bgSurface, std::numeric_limits::max() - 1) .apply(); @@ -620,8 +619,7 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, - {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); + checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); } class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest { diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 7a10769757..a974dc4488 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -278,8 +278,9 @@ bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { return stateUpdateAvailable; } -Rect BufferStateLayer::getCrop(const Layer::State& s) const { - return s.crop; +// Crop that applies to the window +Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const { + return Rect::INVALID_RECT; } bool BufferStateLayer::setTransform(uint32_t transform) { @@ -300,53 +301,57 @@ bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInver } bool BufferStateLayer::setCrop(const Rect& crop) { - if (mCurrentState.crop == crop) return false; - mCurrentState.sequence++; - mCurrentState.crop = crop; + Rect c = crop; + if (c.left < 0) { + c.left = 0; + } + if (c.top < 0) { + c.top = 0; + } + // If the width and/or height are < 0, make it [0, 0, -1, -1] so the equality comparision below + // treats all invalid rectangles the same. + if (!c.isValid()) { + c.makeInvalid(); + } + if (mCurrentState.crop == c) return false; + mCurrentState.crop = c; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } -bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, - bool allowNonRectPreservingTransforms) { - if (mCurrentState.transform.dsdx() == matrix.dsdx && - mCurrentState.transform.dtdy() == matrix.dtdy && - mCurrentState.transform.dtdx() == matrix.dtdx && - mCurrentState.transform.dsdy() == matrix.dsdy) { - return false; - } +bool BufferStateLayer::setFrame(const Rect& frame) { + int x = frame.left; + int y = frame.top; + int w = frame.getWidth(); + int h = frame.getHeight(); - ui::Transform t; - t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); - - if (!allowNonRectPreservingTransforms && !t.preserveRects()) { - ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER nor " - "ROTATE_SURFACE_FLINGER ignored"); - return false; + if (x < 0) { + x = 0; + w = frame.right; } - mCurrentState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); - - mCurrentState.sequence++; - mCurrentState.modified = true; - setTransactionFlags(eTransactionNeeded); - - return true; -} + if (y < 0) { + y = 0; + h = frame.bottom; + } -bool BufferStateLayer::setPosition(float x, float y) { - if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) { + if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y && + mCurrentState.width == w && mCurrentState.height == h) { return false; } + if (!frame.isValid()) { + x = y = w = h = 0; + } mCurrentState.transform.set(x, y); + mCurrentState.width = w; + mCurrentState.height = h; mCurrentState.sequence++; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); - return true; } @@ -423,10 +428,6 @@ bool BufferStateLayer::setBuffer(const sp& buffer, const spmFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime, FrameTracer::FrameEvent::QUEUE); } - - mCurrentState.width = mCurrentState.buffer->width; - mCurrentState.height = mCurrentState.buffer->height; - return true; } @@ -854,6 +855,33 @@ sp BufferStateLayer::createClone() { return layer; } +Layer::RoundedCornerState BufferStateLayer::getRoundedCornerState() const { + const auto& p = mDrawingParent.promote(); + if (p != nullptr) { + RoundedCornerState parentState = p->getRoundedCornerState(); + if (parentState.radius > 0) { + ui::Transform t = getActiveTransform(getDrawingState()); + t = t.inverse(); + parentState.cropRect = t.transform(parentState.cropRect); + // The rounded corners shader only accepts 1 corner radius for performance reasons, + // but a transform matrix can define horizontal and vertical scales. + // Let's take the average between both of them and pass into the shader, practically we + // never do this type of transformation on windows anyway. + parentState.radius *= (t[0][0] + t[1][1]) / 2.0f; + return parentState; + } + } + const float radius = getDrawingState().cornerRadius; + const State& s(getDrawingState()); + if (radius <= 0 || (getActiveWidth(s) == UINT32_MAX && getActiveHeight(s) == UINT32_MAX)) + return RoundedCornerState(); + return RoundedCornerState(FloatRect(static_cast(s.transform.tx()), + static_cast(s.transform.ty()), + static_cast(s.transform.tx() + s.width), + static_cast(s.transform.ty() + s.height)), + radius); +} + bool BufferStateLayer::bufferNeedsFiltering() const { const State& s(getDrawingState()); if (!s.buffer) { diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index af2819eac7..7a3da6fec1 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -66,6 +66,7 @@ public: bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; bool setCrop(const Rect& crop) override; + bool setFrame(const Rect& frame) override; bool setBuffer(const sp& buffer, const sp& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, @@ -80,13 +81,15 @@ public: bool setTransactionCompletedListeners(const std::vector>& handles) override; bool addFrameEvent(const sp& acquireFence, nsecs_t postedTime, nsecs_t requestedPresentTime) override; - bool setPosition(float /*x*/, float /*y*/) override; - bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/, - bool /*allowNonRectPreservingTransforms*/); // Override to ignore legacy layer state properties that are not used by BufferStateLayer bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; } + bool setPosition(float /*x*/, float /*y*/) override { return false; } bool setTransparentRegionHint(const Region& transparent) override; + bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/, + bool /*allowNonRectPreservingTransforms*/) override { + return false; + } void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, uint64_t /*frameNumber*/) override {} void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, @@ -94,6 +97,7 @@ public: Rect getBufferSize(const State& s) const override; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; + Layer::RoundedCornerState getRoundedCornerState() const override; void setAutoRefresh(bool autoRefresh) override; // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 447cbb3854..cd3e8add9a 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2312,8 +2312,8 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const { } } const float radius = getDrawingState().cornerRadius; - return radius > 0 && getCroppedBufferSize(getDrawingState()).isValid() - ? RoundedCornerState(getCroppedBufferSize(getDrawingState()).toFloatRect(), radius) + return radius > 0 && getCrop(getDrawingState()).isValid() + ? RoundedCornerState(getCrop(getDrawingState()).toFloatRect(), radius) : RoundedCornerState(); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 4cd379b963..1c5d6ecb03 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -462,6 +462,7 @@ public: // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; + virtual bool setFrame(const Rect& /*frame*/) { return false; }; virtual bool setBuffer(const sp& /*buffer*/, const sp& /*acquireFence*/, nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/, diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index 7a3e433660..1d00cc38f2 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -231,14 +231,8 @@ const std::vector>& RefreshRateOverlay::getOrCreateBuffers(uin void RefreshRateOverlay::setViewport(ui::Size viewport) { Rect frame((3 * viewport.width) >> 4, viewport.height >> 5); frame.offsetBy(viewport.width >> 5, viewport.height >> 4); + mLayer->setFrame(frame); - layer_state_t::matrix22_t matrix; - matrix.dsdx = frame.getWidth() / static_cast(SevenSegmentDrawer::getWidth()); - matrix.dtdx = 0; - matrix.dtdy = 0; - matrix.dsdy = frame.getHeight() / static_cast(SevenSegmentDrawer::getHeight()); - mLayer->setMatrix(matrix, true); - mLayer->setPosition(frame.left, frame.top); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index b1d63f0ce7..a387587d7f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3936,6 +3936,9 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & layer_state_t::eCropChanged) { if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; } + if (what & layer_state_t::eFrameChanged) { + if (layer->setFrame(s.orientedDisplaySpaceRect)) flags |= eTraversalNeeded; + } if (what & layer_state_t::eAcquireFenceChanged) { if (layer->setAcquireFence(s.acquireFence)) flags |= eTraversalNeeded; } diff --git a/services/surfaceflinger/tests/BufferGenerator.cpp b/services/surfaceflinger/tests/BufferGenerator.cpp index 47a150dd35..03f8e1afba 100644 --- a/services/surfaceflinger/tests/BufferGenerator.cpp +++ b/services/surfaceflinger/tests/BufferGenerator.cpp @@ -296,12 +296,12 @@ private: BufferGenerator::BufferGenerator() : mSurfaceManager(new SurfaceManager), mEglManager(new EglManager), mProgram(new Program) { - mBufferSize.set(1000.0, 1000.0); + const float width = 1000.0; + const float height = 1000.0; auto setBufferWithContext = std::bind(setBuffer, std::placeholders::_1, std::placeholders::_2, this); - mSurfaceManager->initialize(mBufferSize.width, mBufferSize.height, HAL_PIXEL_FORMAT_RGBA_8888, - setBufferWithContext); + mSurfaceManager->initialize(width, height, HAL_PIXEL_FORMAT_RGBA_8888, setBufferWithContext); if (!mEglManager->initialize(mSurfaceManager->getSurface())) return; @@ -309,9 +309,7 @@ BufferGenerator::BufferGenerator() if (!mProgram->initialize(VERTEX_SHADER, FRAGMENT_SHADER)) return; mProgram->use(); - mProgram->bindVec4(0, - vec4{mBufferSize.width, mBufferSize.height, 1.0f / mBufferSize.width, - 1.0f / mBufferSize.height}); + mProgram->bindVec4(0, vec4{width, height, 1.0f / width, 1.0f / height}); mProgram->bindVec3(2, &SPHERICAL_HARMONICS[0], 4); glEnableVertexAttribArray(0); @@ -374,10 +372,6 @@ status_t BufferGenerator::get(sp* outBuffer, sp* outFence) return NO_ERROR; } -ui::Size BufferGenerator::getSize() { - return mBufferSize; -} - // static void BufferGenerator::setBuffer(const sp& buffer, int32_t fence, void* bufferGenerator) { diff --git a/services/surfaceflinger/tests/BufferGenerator.h b/services/surfaceflinger/tests/BufferGenerator.h index f7d548b6bf..a3ffe86572 100644 --- a/services/surfaceflinger/tests/BufferGenerator.h +++ b/services/surfaceflinger/tests/BufferGenerator.h @@ -37,7 +37,6 @@ public: /* Static callback that sets the fence on a particular instance */ static void setBuffer(const sp& buffer, int32_t fence, void* fenceGenerator); - ui::Size getSize(); private: bool mInitialized = false; @@ -54,7 +53,6 @@ private: using Epoch = std::chrono::time_point; Epoch mEpoch = std::chrono::steady_clock::now(); - ui::Size mBufferSize; }; } // namespace android diff --git a/services/surfaceflinger/tests/EffectLayer_test.cpp b/services/surfaceflinger/tests/EffectLayer_test.cpp index af00ec7fc9..f470eda7d3 100644 --- a/services/surfaceflinger/tests/EffectLayer_test.cpp +++ b/services/surfaceflinger/tests/EffectLayer_test.cpp @@ -149,6 +149,7 @@ TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) { t.reparent(blurLayer, mParentLayer); t.setBackgroundBlurRadius(blurLayer, blurRadius); t.setCrop(blurLayer, blurRect); + t.setFrame(blurLayer, blurRect); t.setAlpha(blurLayer, 0.0f); t.show(blurLayer); }); diff --git a/services/surfaceflinger/tests/IPC_test.cpp b/services/surfaceflinger/tests/IPC_test.cpp index 9fa3d4c417..a8647c3e50 100644 --- a/services/surfaceflinger/tests/IPC_test.cpp +++ b/services/surfaceflinger/tests/IPC_test.cpp @@ -161,6 +161,7 @@ public: Color::RED); transaction->setLayerStack(mSurfaceControl, 0) .setLayer(mSurfaceControl, std::numeric_limits::max()) + .setFrame(mSurfaceControl, Rect(0, 0, width, height)) .setBuffer(mSurfaceControl, gb) .setAcquireFence(mSurfaceControl, fence) .show(mSurfaceControl) diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp index 011ff70409..158801a705 100644 --- a/services/surfaceflinger/tests/LayerCallback_test.cpp +++ b/services/surfaceflinger/tests/LayerCallback_test.cpp @@ -164,10 +164,7 @@ TEST_F(LayerCallbackTest, NoBufferNoColor) { return; } - ui::Size bufferSize = getBufferSize(); - TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - transaction.apply(); + transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer, @@ -187,10 +184,7 @@ TEST_F(LayerCallbackTest, BufferNoColor) { return; } - ui::Size bufferSize = getBufferSize(); - TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - transaction.apply(); + transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -209,10 +203,7 @@ TEST_F(LayerCallbackTest, NoBufferColor) { return; } - ui::Size bufferSize = getBufferSize(); - TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - transaction.apply(); + transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, @@ -247,10 +238,7 @@ TEST_F(LayerCallbackTest, OffScreen) { return; } - ui::Size bufferSize = getBufferSize(); - TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(-100, -100, 100, 100)); - transaction.apply(); + transaction.setFrame(layer, Rect(-100, -100, 100, 100)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -275,15 +263,8 @@ TEST_F(LayerCallbackTest, MergeBufferNoColor) { return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -309,15 +290,8 @@ TEST_F(LayerCallbackTest, MergeNoBufferColor) { return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -344,15 +318,8 @@ TEST_F(LayerCallbackTest, MergeOneBufferOneColor) { return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer1); @@ -438,15 +405,8 @@ TEST_F(LayerCallbackTest, Merge_DifferentClients) { return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -531,11 +491,7 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SameStateChange) { } } - ui::Size bufferSize = getBufferSize(); - TransactionUtils::setFrame(transaction, layer, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - transaction.apply(); + transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); ExpectedResult expected; expected.addSurface((i == 0) ? ExpectedResult::Transaction::PRESENTED @@ -567,16 +523,8 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge) { return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -616,16 +564,8 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients) { return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -666,15 +606,8 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_NoStateCha return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -728,15 +661,8 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateC return; } - ui::Size bufferSize = getBufferSize(); - - TransactionUtils::setFrame(transaction1, layer1, - Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - - transaction2.merge(std::move(transaction1)).apply(); + transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -756,10 +682,7 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateC return; } - TransactionUtils::setFrame(transaction2, layer2, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(32, 32, 64, 64)); - transaction2.merge(std::move(transaction1)).apply(); + transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer2, ExpectedResult::Buffer::NOT_ACQUIRED); @@ -839,10 +762,7 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) { return; } - ui::Size bufferSize = getBufferSize(); - TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - transaction.apply(); + transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); ExpectedResult expectedResult; expectedResult.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -861,10 +781,7 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) { return; } - TransactionUtils::setFrame(transaction, layer, - Rect(0, 0, bufferSize.width, bufferSize.height), - Rect(0, 0, 32, 32)); - transaction.apply(); + transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); } EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true)); } diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp index 53d230abe7..7505e6ea9b 100644 --- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp @@ -204,7 +204,11 @@ void LayerRenderTypeTransactionTest::setRelativeZBasicHelper(uint32_t layerType) Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply(); break; case ISurfaceComposerClient::eFXSurfaceBufferState: - Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply(); + Transaction() + .setFrame(layerR, Rect(0, 0, 32, 32)) + .setFrame(layerG, Rect(16, 16, 48, 48)) + .setRelativeLayer(layerG, layerR, 1) + .apply(); break; default: ASSERT_FALSE(true) << "Unsupported layer type"; @@ -256,9 +260,10 @@ void LayerRenderTypeTransactionTest::setRelativeZGroupHelper(uint32_t layerType) break; case ISurfaceComposerClient::eFXSurfaceBufferState: Transaction() - .setPosition(layerG, 8, 8) + .setFrame(layerR, Rect(0, 0, 32, 32)) + .setFrame(layerG, Rect(8, 8, 40, 40)) .setRelativeLayer(layerG, layerR, 3) - .setPosition(layerB, 16, 16) + .setFrame(layerB, Rect(16, 16, 48, 48)) .setLayer(layerB, mLayerZBase + 2) .apply(); break; @@ -383,6 +388,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintBasic_BufferState Transaction() .setTransparentRegionHint(layer, Region(top)) .setBuffer(layer, buffer) + .setFrame(layer, Rect(0, 0, 32, 32)) .apply(); { SCOPED_TRACE("top transparent"); @@ -441,7 +447,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintOutOfBounds_Buffe // check that transparent region hint is bound by the layer size Transaction() .setTransparentRegionHint(layerTransparent, Region(mDisplayRect)) - .setPosition(layerR, 16, 16) + .setFrame(layerR, Rect(16, 16, 48, 48)) .setLayer(layerR, mLayerZBase + 1) .apply(); ASSERT_NO_FATAL_FAILURE( @@ -471,7 +477,8 @@ void LayerRenderTypeTransactionTest::setAlphaBasicHelper(uint32_t layerType) { Transaction() .setAlpha(layer1, 0.25f) .setAlpha(layer2, 0.75f) - .setPosition(layer2, 16, 0) + .setFrame(layer1, Rect(0, 0, 32, 32)) + .setFrame(layer2, Rect(16, 0, 48, 32)) .setLayer(layer2, mLayerZBase + 1) .apply(); break; @@ -566,7 +573,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, fillColor, width, height)); expectedColor = fillColor; } - Transaction().setCrop(layer, Rect(0, 0, width, height)).apply(); + Transaction().setFrame(layer, Rect(0, 0, width, height)).apply(); break; default: GTEST_FAIL() << "Unknown layer type in setBackgroundColorHelper"; @@ -842,39 +849,42 @@ TEST_P(LayerRenderTypeTransactionTest, SetMatrixBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); - Transaction().setPosition(layer, 32, 32).setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f).apply(); + Transaction() + .setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f) + .setFrame(layer, Rect(0, 0, 32, 32)) + .apply(); { SCOPED_TRACE("IDENTITY"); - getScreenCapture()->expectQuadrant(Rect(32, 32, 64, 64), Color::RED, Color::GREEN, + getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, Color::BLUE, Color::WHITE); } Transaction().setMatrix(layer, -1.0f, 0.0f, 0.0f, 1.0f).apply(); { SCOPED_TRACE("FLIP_H"); - getScreenCapture()->expectQuadrant(Rect(0, 32, 32, 64), Color::GREEN, Color::RED, - Color::WHITE, Color::BLUE); + getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE); } Transaction().setMatrix(layer, 1.0f, 0.0f, 0.0f, -1.0f).apply(); { SCOPED_TRACE("FLIP_V"); - getScreenCapture()->expectQuadrant(Rect(32, 0, 64, 32), Color::BLUE, Color::WHITE, - Color::RED, Color::GREEN); + getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE); } Transaction().setMatrix(layer, 0.0f, 1.0f, -1.0f, 0.0f).apply(); { SCOPED_TRACE("ROT_90"); - getScreenCapture()->expectQuadrant(Rect(0, 32, 32, 64), Color::BLUE, Color::RED, - Color::WHITE, Color::GREEN); + getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE); } Transaction().setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f).apply(); { SCOPED_TRACE("SCALE"); - getScreenCapture()->expectQuadrant(Rect(32, 32, 96, 96), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE, 1 /* tolerance */); + getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE); } } @@ -945,8 +955,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropBasic_BufferState) { Transaction().setCrop(layer, crop).apply(); auto shot = getScreenCapture(); - shot->expectColor(crop, Color::RED); - shot->expectBorder(crop, Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferQueue) { @@ -976,13 +986,13 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferState) { { SCOPED_TRACE("empty rect"); Transaction().setCrop(layer, Rect(8, 8, 8, 8)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); + getScreenCapture()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); } { SCOPED_TRACE("negative rect"); Transaction().setCrop(layer, Rect(8, 8, 0, 0)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); + getScreenCapture()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); } } @@ -1006,6 +1016,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 16), Color::BLUE); TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 16, 32, 64), Color::RED); + Transaction().setFrame(layer, Rect(0, 0, 64, 64)).apply(); + Transaction().setBuffer(layer, buffer).apply(); // Partially out of bounds in the negative (upper left) direction @@ -1013,8 +1025,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("out of bounds, negative (upper left) direction"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 16), Color::BLUE); - shot->expectBorder(Rect(0, 0, 32, 16), Color::BLACK); + shot->expectColor(Rect(0, 0, 64, 64), Color::BLUE); + shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); } // Partially out of bounds in the positive (lower right) direction @@ -1022,8 +1034,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("out of bounds, positive (lower right) direction"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 16, 32, 64), Color::RED); - shot->expectBorder(Rect(0, 16, 32, 64), Color::BLACK); + shot->expectColor(Rect(0, 0, 64, 64), Color::RED); + shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); } // Fully out of buffer space bounds @@ -1031,7 +1043,9 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("Fully out of bounds"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 0, 64, 16), Color::BLUE); + shot->expectColor(Rect(0, 16, 64, 64), Color::RED); + shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); } } @@ -1054,11 +1068,12 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropWithTranslation_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + const Rect frame(32, 32, 64, 64); const Rect crop(8, 8, 24, 24); - Transaction().setPosition(layer, 32, 32).setCrop(layer, crop).apply(); + Transaction().setFrame(layer, frame).setCrop(layer, crop).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(40, 40, 56, 56), Color::RED); - shot->expectBorder(Rect(40, 40, 56, 56), Color::BLACK); + shot->expectColor(frame, Color::RED); + shot->expectBorder(frame, Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetCropWithScale_BufferQueue) { @@ -1106,10 +1121,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); const Rect frame(8, 8, 24, 24); - Transaction t; - TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), frame); - t.apply(); - + Transaction().setFrame(layer, frame).apply(); auto shot = getScreenCapture(); shot->expectColor(frame, Color::RED); shot->expectBorder(frame, Color::BLACK); @@ -1121,23 +1133,16 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameEmpty_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); - Transaction t; { SCOPED_TRACE("empty rect"); - TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), Rect(8, 8, 8, 8)); - t.apply(); - + Transaction().setFrame(layer, Rect(8, 8, 8, 8)).apply(); getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); } { SCOPED_TRACE("negative rect"); - TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), Rect(8, 8, 0, 0)); - t.apply(); - - auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 8, 8), Color::RED); - shot->expectBorder(Rect(0, 0, 8, 8), Color::BLACK); + Transaction().setFrame(layer, Rect(8, 8, 0, 0)).apply(); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); } } @@ -1147,10 +1152,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultParentless_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 10, 10)); - // A layer with a buffer will have a computed size that matches the buffer size. + // A parentless layer will default to a frame with the same size as the buffer auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 10, 10), Color::RED); - shot->expectBorder(Rect(0, 0, 10, 10), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBSParent_BufferState) { @@ -1158,16 +1163,17 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBSParent_BufferState) { ASSERT_NO_FATAL_FAILURE( parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32)); + Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply(); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); Transaction().reparent(child, parent).apply(); - // A layer with a buffer will have a computed size that matches the buffer size. + // A layer will default to the frame of its parent auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 10, 10), Color::BLUE); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1177,14 +1183,14 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBQParent_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parent, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); Transaction().reparent(child, parent).apply(); - // A layer with a buffer will have a computed size that matches the buffer size. + // A layer will default to the frame of its parent auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 10, 10), Color::BLUE); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1193,10 +1199,11 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameUpdate_BufferState) { ASSERT_NO_FATAL_FAILURE( layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + Transaction().setFrame(layer, Rect(0, 0, 32, 32)).apply(); std::this_thread::sleep_for(500ms); - Transaction().setPosition(layer, 16, 16).apply(); + Transaction().setFrame(layer, Rect(16, 16, 48, 48)).apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(16, 16, 48, 48), Color::RED); @@ -1208,20 +1215,18 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameOutsideBounds_BufferState) { ASSERT_NO_FATAL_FAILURE( parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); Transaction().reparent(child, parent).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32)); + Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); - Rect childDst(0, 16, 32, 32); - Transaction t; - TransactionUtils::setFrame(t, child, Rect(0, 0, 10, 10), childDst); - t.apply(); + Transaction().setFrame(child, Rect(0, 16, 32, 32)).apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(0, 0, 32, 16), Color::RED); - shot->expectColor(childDst, Color::BLUE); + shot->expectColor(Rect(0, 16, 32, 32), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1233,8 +1238,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { @@ -1247,8 +1252,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 1"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32)); @@ -1256,8 +1261,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 2"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLUE); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); @@ -1265,8 +1270,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 3"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } } @@ -1281,6 +1286,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleLayers_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::RED, 64, 64)); + Transaction().setFrame(layer1, Rect(0, 0, 64, 64)).apply(); { SCOPED_TRACE("set layer 1 buffer red"); auto shot = getScreenCapture(); @@ -1289,6 +1295,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleLayers_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::BLUE, 32, 32)); + Transaction().setFrame(layer2, Rect(0, 0, 32, 32)).apply(); { SCOPED_TRACE("set layer 2 buffer blue"); auto shot = getScreenCapture(); @@ -1343,8 +1350,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_BufferState) { Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 32, 32), color); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } idx++; } @@ -1376,8 +1383,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_LeastRecentlyUsed_Buffer Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 32, 32), color); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } idx++; } @@ -1409,8 +1416,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_DestroyedBuffer_BufferSt Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, 32, 32), color); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } if (idx == 0) { buffers[0].clear(); @@ -1428,6 +1435,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformRotate90_BufferState) { Color::BLUE, Color::WHITE)); Transaction() + .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_ROT_90) .apply(); @@ -1444,6 +1452,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformFlipH_BufferState) { Color::BLUE, Color::WHITE)); Transaction() + .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_H) .apply(); @@ -1460,6 +1469,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformFlipV_BufferState) { Color::BLUE, Color::WHITE)); Transaction() + .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_V) .apply(); @@ -1508,8 +1518,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetFenceNull_BufferState) { Transaction().setBuffer(layer, buffer).setAcquireFence(layer, fence).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) { @@ -1524,8 +1534,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) { Transaction().setBuffer(layer, buffer).setDataspace(layer, ui::Dataspace::UNKNOWN).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetHdrMetadataBasic_BufferState) { @@ -1542,8 +1552,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetHdrMetadataBasic_BufferState) { Transaction().setBuffer(layer, buffer).setHdrMetadata(layer, hdrMetadata).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetSurfaceDamageRegionBasic_BufferState) { @@ -1560,8 +1570,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetSurfaceDamageRegionBasic_BufferState) Transaction().setBuffer(layer, buffer).setSurfaceDamageRegion(layer, region).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetApiBasic_BufferState) { @@ -1576,8 +1586,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetApiBasic_BufferState) { Transaction().setBuffer(layer, buffer).setApi(layer, NATIVE_WINDOW_API_CPU).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::RED); - shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); + shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetColorTransformBasic) { diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index 0bc8fe7aa0..87c7b7d829 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -244,11 +244,6 @@ protected: return bufferGenerator.get(outBuffer, outFence); } - static ui::Size getBufferSize() { - static BufferGenerator bufferGenerator; - return bufferGenerator.getSize(); - } - sp mClient; bool deviceSupportsBlurs() { diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp index edf55ea6ef..ac5e297e43 100644 --- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp @@ -196,7 +196,17 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadius) { ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size)); - Transaction().setCornerRadius(layer, cornerRadius).apply(); + if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { + Transaction() + .setCornerRadius(layer, cornerRadius) + .setCrop(layer, Rect(0, 0, size, size)) + .apply(); + } else { + Transaction() + .setCornerRadius(layer, cornerRadius) + .setFrame(layer, Rect(0, 0, size, size)) + .apply(); + } { const uint8_t bottom = size - 1; const uint8_t right = size - 1; @@ -224,13 +234,19 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusRotated) { ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size)); - Transaction() - .setCornerRadius(parent, cornerRadius) - .reparent(child, parent) - .setPosition(child, 0, size) - // Rotate by half PI - .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f) - .apply(); + auto transaction = Transaction() + .setCornerRadius(parent, cornerRadius) + .setCrop(parent, Rect(0, 0, size, size)) + .reparent(child, parent) + .setPosition(child, 0, size) + // Rotate by half PI + .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f); + if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { + transaction.setCrop(parent, Rect(0, 0, size, size)); + } else { + transaction.setFrame(parent, Rect(0, 0, size, size)); + } + transaction.apply(); { const uint8_t bottom = size - 1; @@ -259,12 +275,21 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusChildCrop) { ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size / 2)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size / 2)); - Transaction() - .setCornerRadius(parent, cornerRadius) - .reparent(child, parent) - .setPosition(child, 0, size / 2) - .apply(); - + if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { + Transaction() + .setCornerRadius(parent, cornerRadius) + .setCrop(parent, Rect(0, 0, size, size)) + .reparent(child, parent) + .setPosition(child, 0, size / 2) + .apply(); + } else { + Transaction() + .setCornerRadius(parent, cornerRadius) + .setFrame(parent, Rect(0, 0, size, size)) + .reparent(child, parent) + .setFrame(child, Rect(0, size / 2, size, size)) + .apply(); + } { const uint8_t bottom = size - 1; const uint8_t right = size - 1; @@ -306,9 +331,12 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { Transaction() .setLayer(greenLayer, mLayerZBase) + .setFrame(leftLayer, {0, 0, canvasSize * 2, canvasSize * 2}) .setLayer(leftLayer, mLayerZBase + 1) + .setFrame(leftLayer, leftRect) .setLayer(rightLayer, mLayerZBase + 2) .setPosition(rightLayer, rightRect.left, rightRect.top) + .setFrame(rightLayer, rightRect) .apply(); { @@ -324,6 +352,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { .setLayer(blurLayer, mLayerZBase + 3) .setBackgroundBlurRadius(blurLayer, blurRadius) .setCrop(blurLayer, blurRect) + .setFrame(blurLayer, blurRect) .setSize(blurLayer, blurRect.getWidth(), blurRect.getHeight()) .setAlpha(blurLayer, 0.0f) .apply(); @@ -406,8 +435,10 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentA Transaction() .setLayer(left, mLayerZBase + 1) + .setFrame(left, {0, 0, size, size}) .setLayer(right, mLayerZBase + 2) .setPosition(right, size, 0) + .setFrame(right, {size, 0, size * 2, size}) .apply(); { @@ -426,6 +457,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentA .setAlpha(blurParent, 0.5) .setLayer(blur, mLayerZBase + 4) .setBackgroundBlurRadius(blur, size) // set the blur radius to the size of one rect + .setFrame(blur, {0, 0, size * 2, size}) .reparent(blur, blurParent) .apply(); diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp index ccf434d63a..613b21ef04 100644 --- a/services/surfaceflinger/tests/MirrorLayer_test.cpp +++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp @@ -195,7 +195,7 @@ TEST_F(MirrorLayerTest, MirrorBufferLayer) { createLayer("BufferStateLayer", 200, 200, ISurfaceComposerClient::eFXSurfaceBufferState, mChildLayer.get()); fillBufferStateLayerColor(bufferStateLayer, Color::BLUE, 200, 200); - Transaction().show(bufferStateLayer).apply(); + Transaction().setFrame(bufferStateLayer, Rect(0, 0, 200, 200)).show(bufferStateLayer).apply(); { SCOPED_TRACE("Initial Mirror BufferStateLayer"); diff --git a/services/surfaceflinger/tests/utils/TransactionUtils.h b/services/surfaceflinger/tests/utils/TransactionUtils.h index 8c448e2f96..3cbfed98f5 100644 --- a/services/surfaceflinger/tests/utils/TransactionUtils.h +++ b/services/surfaceflinger/tests/utils/TransactionUtils.h @@ -126,7 +126,7 @@ public: const uint8_t* src = pixels + (outBuffer->getStride() * (y + j) + x) * 4; for (int32_t i = 0; i < width; i++) { const uint8_t expected[4] = {color.r, color.g, color.b, color.a}; - ASSERT_TRUE(std::equal(src, src + 4, expected, colorCompare)) + EXPECT_TRUE(std::equal(src, src + 4, expected, colorCompare)) << "pixel @ (" << x + i << ", " << y + j << "): " << "expected (" << color << "), " << "got (" << Color{src[0], src[1], src[2], src[3]} << ")"; @@ -161,22 +161,6 @@ public: ASSERT_EQ(NO_ERROR, s->unlockAndPost()); } } - - static void setFrame(Transaction& t, const sp& sc, Rect source, Rect dest, - int32_t transform = 0) { - uint32_t sourceWidth = source.getWidth(); - uint32_t sourceHeight = source.getHeight(); - - if (transform & ui::Transform::ROT_90) { - std::swap(sourceWidth, sourceHeight); - } - - float dsdx = dest.getWidth() / static_cast(sourceWidth); - float dsdy = dest.getHeight() / static_cast(sourceHeight); - - t.setMatrix(sc, dsdx, 0, 0, dsdy); - t.setPosition(sc, dest.left, dest.top); - } }; enum class RenderPath { SCREENSHOT, VIRTUAL_DISPLAY }; -- cgit v1.2.3-59-g8ed1b From 257fdaecb53fdec10dbe187ec523641da21b55cb Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 8 Apr 2021 17:30:52 -0700 Subject: SurfaceFlinger: Remove reparentChildren No callers left outside of tests. Bug: 161937501 Test: Existing tests pass Change-Id: Id5c2b68d1be05fce9f698813d83044b02bb2764d --- cmds/surfacereplayer/proto/src/trace.proto | 5 --- cmds/surfacereplayer/replayer/Replayer.cpp | 12 ------- cmds/surfacereplayer/replayer/Replayer.h | 2 -- libs/gui/LayerState.cpp | 4 --- libs/gui/SurfaceComposerClient.cpp | 14 -------- libs/gui/include/gui/LayerState.h | 1 - libs/gui/include/gui/SurfaceComposerClient.h | 6 ---- services/surfaceflinger/Layer.cpp | 26 -------------- services/surfaceflinger/Layer.h | 2 -- services/surfaceflinger/SurfaceFlinger.cpp | 5 --- services/surfaceflinger/SurfaceInterceptor.cpp | 11 ------ services/surfaceflinger/SurfaceInterceptor.h | 1 - services/surfaceflinger/tests/LayerUpdate_test.cpp | 34 +----------------- .../tests/SurfaceInterceptor_test.cpp | 26 -------------- .../tests/fakehwc/SFFakeHwc_test.cpp | 28 --------------- .../tests/unittests/SetFrameRateTest.cpp | 40 ---------------------- 16 files changed, 1 insertion(+), 216 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto index 79aab822e4..06afefd3c8 100644 --- a/cmds/surfacereplayer/proto/src/trace.proto +++ b/cmds/surfacereplayer/proto/src/trace.proto @@ -50,7 +50,6 @@ message SurfaceChange { CornerRadiusChange corner_radius = 16; ReparentChange reparent = 17; RelativeParentChange relative_parent = 18; - ReparentChildrenChange reparent_children = 19; BackgroundBlurRadiusChange background_blur_radius = 20; ShadowRadiusChange shadow_radius = 21; BlurRegionsChange blur_regions = 22; @@ -190,10 +189,6 @@ message ReparentChange { required int32 parent_id = 1; } -message ReparentChildrenChange { - required int32 parent_id = 1; -} - message RelativeParentChange { required int32 relative_parent_id = 1; required int32 z = 2; diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp index bbbe6f7ec4..a6d9a3feb6 100644 --- a/cmds/surfacereplayer/replayer/Replayer.cpp +++ b/cmds/surfacereplayer/replayer/Replayer.cpp @@ -410,9 +410,6 @@ status_t Replayer::doSurfaceTransaction( case SurfaceChange::SurfaceChangeCase::kReparent: setReparentChange(transaction, change.id(), change.reparent()); break; - case SurfaceChange::SurfaceChangeCase::kReparentChildren: - setReparentChildrenChange(transaction, change.id(), change.reparent_children()); - break; case SurfaceChange::SurfaceChangeCase::kRelativeParent: setRelativeParentChange(transaction, change.id(), change.relative_parent()); break; @@ -709,15 +706,6 @@ void Replayer::setRelativeParentChange(SurfaceComposerClient::Transaction& t, t.setRelativeLayer(mLayers[id], mLayers[c.relative_parent_id()], c.z()); } -void Replayer::setReparentChildrenChange(SurfaceComposerClient::Transaction& t, - layer_id id, const ReparentChildrenChange& c) { - if (mLayers.count(c.parent_id()) == 0 || mLayers[c.parent_id()] == nullptr) { - ALOGE("Layer %d not found in reparent children transaction", c.parent_id()); - return; - } - t.reparentChildren(mLayers[id], mLayers[c.parent_id()]); -} - void Replayer::setShadowRadiusChange(SurfaceComposerClient::Transaction& t, layer_id id, const ShadowRadiusChange& c) { t.setShadowRadius(mLayers[id], c.radius()); diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h index 324d591eaa..252db2bfbb 100644 --- a/cmds/surfacereplayer/replayer/Replayer.h +++ b/cmds/surfacereplayer/replayer/Replayer.h @@ -116,8 +116,6 @@ class Replayer { layer_id id, const ReparentChange& c); void setRelativeParentChange(SurfaceComposerClient::Transaction& t, layer_id id, const RelativeParentChange& c); - void setReparentChildrenChange(SurfaceComposerClient::Transaction& t, - layer_id id, const ReparentChildrenChange& c); void setShadowRadiusChange(SurfaceComposerClient::Transaction& t, layer_id id, const ShadowRadiusChange& c); void setBlurRegionsChange(SurfaceComposerClient::Transaction& t, diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 0ca497795b..809438534c 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -430,10 +430,6 @@ void layer_state_t::merge(const layer_state_t& other) { barrierSurfaceControl_legacy = other.barrierSurfaceControl_legacy; barrierFrameNumber = other.barrierFrameNumber; } - if (other.what & eReparentChildren) { - what |= eReparentChildren; - reparentSurfaceControl = other.reparentSurfaceControl; - } if (other.what & eRelativeLayerChanged) { what |= eRelativeLayerChanged; what &= ~eLayerChanged; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c888312184..9ce094aa77 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1157,20 +1157,6 @@ SurfaceComposerClient::Transaction::deferTransactionUntil_legacy( return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparentChildren( - const sp& sc, const sp& newParent) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eReparentChildren; - s->reparentSurfaceControl = newParent; - - registerSurfaceControlForCallback(sc); - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent( const sp& sc, const sp& newParent) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 706a09c3c7..41a022f90e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -86,7 +86,6 @@ struct layer_state_t { eDeferTransaction_legacy = 0x00000200, eReleaseBufferListenerChanged = 0x00000400, eShadowRadiusChanged = 0x00000800, - eReparentChildren = 0x00001000, /* was eDetachChildren, now available 0x00002000, */ eRelativeLayerChanged = 0x00004000, eReparent = 0x00008000, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 731af58e85..1590b10a00 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -461,13 +461,7 @@ public: Transaction& deferTransactionUntil_legacy(const sp& sc, const sp& barrierSurfaceControl, uint64_t frameNumber); - // Reparents all children of this layer to the new parent handle. - Transaction& reparentChildren(const sp& sc, - const sp& newParent); - /// 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& newParent); Transaction& setColor(const sp& sc, const half3& color); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 2fcd8215eb..c7e798b74b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1949,32 +1949,6 @@ ssize_t Layer::removeChild(const sp& layer) { return removeResult; } -void Layer::reparentChildren(const sp& newParent) { - for (const sp& child : mCurrentChildren) { - newParent->addChild(child); - } - mCurrentChildren.clear(); - updateTreeHasFrameRateVote(); -} - -bool Layer::reparentChildren(const sp& newParentHandle) { - sp handle = nullptr; - sp newParent = nullptr; - if (newParentHandle == nullptr) { - return false; - } - handle = static_cast(newParentHandle.get()); - newParent = handle->owner.promote(); - if (newParent == nullptr) { - ALOGE("Unable to promote Layer handle"); - return false; - } - - reparentChildren(newParent); - - return true; -} - void Layer::setChildrenDrawingParent(const sp& newParent) { for (const sp& child : mDrawingChildren) { child->mDrawingParent = newParent; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 4a105ebeda..e993b7b9e1 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -637,8 +637,6 @@ public: void onLayerDisplayed(const sp& releaseFence) override; const char* getDebugName() const override; - bool reparentChildren(const sp& newParentHandle); - void reparentChildren(const sp& newParent); bool setShadowRadius(float shadowRadius); // Before color management is introduced, contents on Android have to be diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1b7158b825..57349124dd 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4019,11 +4019,6 @@ 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 } - if (what & layer_state_t::eReparentChildren) { - if (layer->reparentChildren(s.reparentSurfaceControl->getHandle())) { - flags |= eTransactionNeeded|eTraversalNeeded; - } - } if (what & layer_state_t::eTransformChanged) { if (layer->setTransform(s.transform)) flags |= eTraversalNeeded; } diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index 8a3be9f4ed..b49562a0a5 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -401,13 +401,6 @@ void SurfaceInterceptor::addReparentLocked(Transaction* transaction, int32_t lay overrideChange->set_parent_id(parentId); } -void SurfaceInterceptor::addReparentChildrenLocked(Transaction* transaction, int32_t layerId, - int32_t parentId) { - SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); - ReparentChildrenChange* overrideChange(change->mutable_reparent_children()); - overrideChange->set_parent_id(parentId); -} - void SurfaceInterceptor::addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId, int z) { SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); @@ -486,10 +479,6 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, : nullptr; addReparentLocked(transaction, layerId, getLayerIdFromHandle(parentHandle)); } - if (state.what & layer_state_t::eReparentChildren) { - addReparentChildrenLocked(transaction, layerId, - getLayerIdFromHandle(state.reparentSurfaceControl->getHandle())); - } if (state.what & layer_state_t::eRelativeLayerChanged) { addRelativeParentLocked(transaction, layerId, getLayerIdFromHandle( diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 3e27e83b02..d2cbf40426 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -176,7 +176,6 @@ private: uint32_t transactionFlags, int originPid, int originUid, uint64_t transactionId); void addReparentLocked(Transaction* transaction, int32_t layerId, int32_t parentId); - void addReparentChildrenLocked(Transaction* transaction, int32_t layerId, int32_t parentId); void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId, int z); void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius); diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp index e5c2ec8bfb..39d9206e1a 100644 --- a/services/surfaceflinger/tests/LayerUpdate_test.cpp +++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp @@ -462,38 +462,6 @@ TEST_F(ChildLayerTest, ChildLayerAlpha) { } } -TEST_F(ChildLayerTest, ReparentChildren) { - asTransaction([&](Transaction& t) { - t.show(mChild); - t.setPosition(mChild, 10, 10); - t.setPosition(mFGSurfaceControl, 64, 64); - }); - - { - mCapture = screenshot(); - // 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); - } - - asTransaction( - [&](Transaction& t) { t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl); }); - - { - mCapture = screenshot(); - mCapture->expectFGColor(64, 64); - // In reparenting we should have exposed the entire foreground surface. - mCapture->expectFGColor(74, 74); - // And the child layer should now begin at 10, 10 (since the BG - // layer is at (0, 0)). - mCapture->expectBGColor(9, 9); - mCapture->expectChildColor(10, 10); - } -} - TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) { sp mGrandChild = createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get()); @@ -539,7 +507,7 @@ TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) { asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); - t.reparentChildren(mChild, mFGSurfaceControl); + t.reparent(mGrandChild, mFGSurfaceControl); }); { diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index d9cab42aae..09bd775872 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -194,7 +194,6 @@ public: bool deferredTransactionUpdateFound(const SurfaceChange& change, bool foundDeferred); bool reparentUpdateFound(const SurfaceChange& change, bool found); bool relativeParentUpdateFound(const SurfaceChange& change, bool found); - bool reparentChildrenUpdateFound(const SurfaceChange& change, bool found); bool shadowRadiusUpdateFound(const SurfaceChange& change, bool found); bool surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase); @@ -231,7 +230,6 @@ public: void deferredTransactionUpdate(Transaction&); void reparentUpdate(Transaction&); void relativeParentUpdate(Transaction&); - void reparentChildrenUpdate(Transaction&); void shadowRadiusUpdate(Transaction&); void surfaceCreation(Transaction&); void displayCreation(Transaction&); @@ -410,10 +408,6 @@ void SurfaceInterceptorTest::relativeParentUpdate(Transaction& t) { t.setRelativeLayer(mBGSurfaceControl, mFGSurfaceControl, RELATIVE_Z); } -void SurfaceInterceptorTest::reparentChildrenUpdate(Transaction& t) { - t.reparentChildren(mBGSurfaceControl, mFGSurfaceControl); -} - void SurfaceInterceptorTest::shadowRadiusUpdate(Transaction& t) { t.setShadowRadius(mBGSurfaceControl, SHADOW_RADIUS_UPDATE); } @@ -445,7 +439,6 @@ void SurfaceInterceptorTest::runAllUpdates() { runInTransaction(&SurfaceInterceptorTest::secureFlagUpdate); runInTransaction(&SurfaceInterceptorTest::deferredTransactionUpdate); runInTransaction(&SurfaceInterceptorTest::reparentUpdate); - runInTransaction(&SurfaceInterceptorTest::reparentChildrenUpdate); runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate); runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate); } @@ -660,16 +653,6 @@ bool SurfaceInterceptorTest::relativeParentUpdateFound(const SurfaceChange& chan return found; } -bool SurfaceInterceptorTest::reparentChildrenUpdateFound(const SurfaceChange& change, bool found) { - bool hasId(change.reparent_children().parent_id() == mFGLayerId); - if (hasId && !found) { - found = true; - } else if (hasId && found) { - []() { FAIL(); }(); - } - return found; -} - bool SurfaceInterceptorTest::shadowRadiusUpdateFound(const SurfaceChange& change, bool foundShadowRadius) { bool hasShadowRadius(change.shadow_radius().radius() == SHADOW_RADIUS_UPDATE); @@ -738,9 +721,6 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace, case SurfaceChange::SurfaceChangeCase::kReparent: foundUpdate = reparentUpdateFound(change, foundUpdate); break; - case SurfaceChange::SurfaceChangeCase::kReparentChildren: - foundUpdate = reparentChildrenUpdateFound(change, foundUpdate); - break; case SurfaceChange::SurfaceChangeCase::kRelativeParent: foundUpdate = relativeParentUpdateFound(change, foundUpdate); break; @@ -771,7 +751,6 @@ void SurfaceInterceptorTest::assertAllUpdatesFound(const Trace& trace) { ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kSecureFlag)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kDeferredTransaction)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kReparent)); - ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kReparentChildren)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kRelativeParent)); } @@ -937,11 +916,6 @@ TEST_F(SurfaceInterceptorTest, InterceptReparentUpdateWorks) { SurfaceChange::SurfaceChangeCase::kReparent); } -TEST_F(SurfaceInterceptorTest, InterceptReparentChildrenUpdateWorks) { - captureTest(&SurfaceInterceptorTest::reparentChildrenUpdate, - SurfaceChange::SurfaceChangeCase::kReparentChildren); -} - TEST_F(SurfaceInterceptorTest, InterceptRelativeParentUpdateWorks) { captureTest(&SurfaceInterceptorTest::relativeParentUpdate, SurfaceChange::SurfaceChangeCase::kRelativeParent); diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index 820f248dbb..c081f9b642 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -1766,30 +1766,6 @@ protected: EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); } - void Test_ReparentChildren() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(mChild); - ts.setPosition(mChild, 10, 10); - ts.setPosition(Base::mFGSurfaceControl, 64, 64); - } - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = - hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.reparentChildren(Base::mFGSurfaceControl, Base::mBGSurfaceControl); - } - - auto referenceFrame2 = referenceFrame; - referenceFrame2[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64}; - referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{10, 10, 10 + 10, 10 + 10}; - EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); - } - // Regression test for b/37673612 void Test_ChildrenWithParentBufferTransform() { { @@ -1886,10 +1862,6 @@ TEST_F(ChildLayerTest_2_1, DISABLED_LayerAlpha) { Test_LayerAlpha(); } -TEST_F(ChildLayerTest_2_1, DISABLED_ReparentChildren) { - Test_ReparentChildren(); -} - // Regression test for b/37673612 TEST_F(ChildLayerTest_2_1, DISABLED_ChildrenWithParentBufferTransform) { Test_ChildrenWithParentBufferTransform(); diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp index 7e602a29a0..0bb7e31194 100644 --- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp +++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp @@ -122,7 +122,6 @@ protected: void addChild(sp layer, sp child); void removeChild(sp layer, sp child); - void reparentChildren(sp layer, sp child); void commitTransaction(); TestableSurfaceFlinger mFlinger; @@ -152,10 +151,6 @@ void SetFrameRateTest::removeChild(sp layer, sp child) { layer.get()->removeChild(child.get()); } -void SetFrameRateTest::reparentChildren(sp parent, sp newParent) { - parent.get()->reparentChildren(newParent); -} - void SetFrameRateTest::commitTransaction() { for (auto layer : mLayers) { layer->pushPendingState(); @@ -433,41 +428,6 @@ TEST_P(SetFrameRateTest, SetAndGetParentNotInTree) { EXPECT_EQ(FRAME_RATE_NO_VOTE, child2_1->getFrameRateForLayerTree()); } -TEST_P(SetFrameRateTest, SetAndGetReparentChildren) { - EXPECT_CALL(*mMessageQueue, invalidate()).Times(1); - - const auto& layerFactory = GetParam(); - - auto parent = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); - auto parent2 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); - auto child1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); - auto child2 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); - - addChild(parent, child1); - addChild(child1, child2); - - child2->setFrameRate(FRAME_RATE_VOTE1); - commitTransaction(); - EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_NO_VOTE, parent2->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree()); - - reparentChildren(parent, parent2); - commitTransaction(); - EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_TREE, parent2->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree()); - - child2->setFrameRate(FRAME_RATE_NO_VOTE); - commitTransaction(); - EXPECT_EQ(FRAME_RATE_NO_VOTE, parent->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_NO_VOTE, parent2->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_NO_VOTE, child1->getFrameRateForLayerTree()); - EXPECT_EQ(FRAME_RATE_NO_VOTE, child2->getFrameRateForLayerTree()); -} - INSTANTIATE_TEST_SUITE_P(PerLayerType, SetFrameRateTest, testing::Values(std::make_shared(), std::make_shared(), -- cgit v1.2.3-59-g8ed1b From a5aedbd7ffaf42b7f287b587035018b42d61a41c Mon Sep 17 00:00:00 2001 From: Chavi Weingarten Date: Fri, 9 Apr 2021 13:37:33 +0000 Subject: Revert^2 "Remove setFrame from BufferStateLayer" 1014c4bf14f5c250b78d7e917fb59aaa9b0d9b0a Change-Id: I4c1cbc2b40e4f5f68bd5e6dcbe6c77405ad155b0 --- libs/gui/BLASTBufferQueue.cpp | 29 +++- libs/gui/LayerState.cpp | 4 - libs/gui/SurfaceComposerClient.cpp | 14 -- libs/gui/include/gui/BLASTBufferQueue.h | 32 +++- libs/gui/include/gui/LayerState.h | 2 +- libs/gui/include/gui/SurfaceComposerClient.h | 1 - libs/gui/tests/BLASTBufferQueue_test.cpp | 34 ++-- services/surfaceflinger/BufferStateLayer.cpp | 98 +++++------- services/surfaceflinger/BufferStateLayer.h | 10 +- services/surfaceflinger/Layer.cpp | 4 +- services/surfaceflinger/Layer.h | 1 - services/surfaceflinger/RefreshRateOverlay.cpp | 8 +- services/surfaceflinger/SurfaceFlinger.cpp | 3 - services/surfaceflinger/tests/BufferGenerator.cpp | 14 +- services/surfaceflinger/tests/BufferGenerator.h | 2 + services/surfaceflinger/tests/EffectLayer_test.cpp | 1 - services/surfaceflinger/tests/IPC_test.cpp | 1 - .../surfaceflinger/tests/LayerCallback_test.cpp | 131 +++++++++++++--- .../tests/LayerRenderTypeTransaction_test.cpp | 174 ++++++++++----------- .../surfaceflinger/tests/LayerTransactionTest.h | 5 + .../LayerTypeAndRenderTypeTransaction_test.cpp | 60 ++----- services/surfaceflinger/tests/MirrorLayer_test.cpp | 2 +- .../surfaceflinger/tests/utils/TransactionUtils.h | 18 ++- 23 files changed, 353 insertions(+), 295 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index bcdd06b6c8..e5afd408a9 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -204,13 +204,16 @@ void BLASTBufferQueue::update(const sp& surface, uint32_t width, if (mRequestedSize != newSize) { mRequestedSize.set(newSize); mBufferItemConsumer->setDefaultBufferSize(mRequestedSize.width, mRequestedSize.height); - if (mLastBufferScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { + if (mLastBufferInfo.scalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) { // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; - t.setFrame(mSurfaceControl, - {0, 0, static_cast(mSize.width), - static_cast(mSize.height)}); + // We only need to update the scale if we've received at least one buffer. The reason + // for this is the scale is calculated based on the requested size and buffer size. + // If there's no buffer, the scale will always be 1. + if (mLastBufferInfo.hasBuffer) { + setMatrix(&t, mLastBufferInfo); + } applyTransaction = true; } } @@ -374,8 +377,10 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback. incStrong((void*)transactionCallbackThunk); - mLastBufferScalingMode = bufferItem.mScalingMode; mLastAcquiredFrameNumber = bufferItem.mFrameNumber; + mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(), + bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform, + bufferItem.mScalingMode); auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp(this) /* callbackContext */, @@ -388,8 +393,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE); t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast(this)); - t->setFrame(mSurfaceControl, - {0, 0, static_cast(mSize.width), static_cast(mSize.height)}); + setMatrix(t, mLastBufferInfo); t->setCrop(mSurfaceControl, computeCrop(bufferItem)); t->setTransform(mSurfaceControl, bufferItem.mTransform); t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse); @@ -515,6 +519,17 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { return mSize != bufferSize; } +void BLASTBufferQueue::setMatrix(SurfaceComposerClient::Transaction* t, + const BufferInfo& bufferInfo) { + uint32_t bufWidth = bufferInfo.width; + uint32_t bufHeight = bufferInfo.height; + + float dsdx = mSize.width / static_cast(bufWidth); + float dsdy = mSize.height / static_cast(bufHeight); + + t->setMatrix(mSurfaceControl, dsdx, 0, 0, dsdy); +} + void BLASTBufferQueue::setTransactionCompleteCallback( uint64_t frameNumber, std::function&& transactionCompleteCallback) { std::lock_guard _lock{mMutex}; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 5b213ad5c3..809438534c 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -455,10 +455,6 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eCropChanged; crop = other.crop; } - if (other.what & eFrameChanged) { - what |= eFrameChanged; - orientedDisplaySpaceRect = other.orientedDisplaySpaceRect; - } if (other.what & eBufferChanged) { what |= eBufferChanged; buffer = other.buffer; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index e01a5aee32..9ce094aa77 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1232,20 +1232,6 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp& sc, const Rect& frame) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eFrameChanged; - s->orientedDisplaySpaceRect = frame; - - registerSurfaceControlForCallback(sc); - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( const sp& sc, const sp& buffer, ReleaseBufferCallback callback) { diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index fbd16f4ea2..a48f95ae73 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -142,6 +142,33 @@ private: ui::Size mRequestedSize GUARDED_BY(mMutex); int32_t mFormat GUARDED_BY(mMutex); + struct BufferInfo { + bool hasBuffer = false; + uint32_t width; + uint32_t height; + uint32_t transform; + // This is used to check if we should update the blast layer size immediately or wait until + // we get the next buffer. This will support scenarios where the layer can change sizes + // and the buffer will scale to fit the new size. + uint32_t scalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; + + void update(bool hasBuffer, uint32_t width, uint32_t height, uint32_t transform, + uint32_t scalingMode) { + this->hasBuffer = hasBuffer; + this->width = width; + this->height = height; + this->transform = transform; + this->scalingMode = scalingMode; + } + }; + + // Last acquired buffer's info. This is used to calculate the correct scale when size change is + // requested. We need to use the old buffer's info to determine what scale we need to apply to + // ensure the correct size. + BufferInfo mLastBufferInfo GUARDED_BY(mMutex); + void setMatrix(SurfaceComposerClient::Transaction* t, const BufferInfo& bufferInfo) + REQUIRES(mMutex); + uint32_t mTransformHint GUARDED_BY(mMutex); sp mConsumer; @@ -159,11 +186,6 @@ private: std::queue mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); - // Last acquired buffer's scaling mode. This is used to check if we should update the blast - // layer size immediately or wait until we get the next buffer. This will support scenarios - // where the layer can change sizes and the buffer will scale to fit the new size. - uint32_t mLastBufferScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; - // Tracks the last acquired frame number uint64_t mLastAcquiredFrameNumber GUARDED_BY(mMutex) = 0; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 65d771053b..41a022f90e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -105,7 +105,7 @@ struct layer_state_t { eHasListenerCallbacksChanged = 0x20000000, eInputInfoChanged = 0x40000000, eCornerRadiusChanged = 0x80000000, - eFrameChanged = 0x1'00000000, + /* was eFrameChanged, now available 0x1'00000000, */ eCachedBufferChanged = 0x2'00000000, eBackgroundColorChanged = 0x4'00000000, eMetadataChanged = 0x8'00000000, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 2487961426..1590b10a00 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -473,7 +473,6 @@ public: Transaction& setTransform(const sp& sc, uint32_t transform); Transaction& setTransformToDisplayInverse(const sp& sc, bool transformToDisplayInverse); - Transaction& setFrame(const sp& sc, const Rect& frame); Transaction& setBuffer(const sp& sc, const sp& buffer, ReleaseBufferCallback callback = nullptr); Transaction& setCachedBuffer(const sp& sc, int32_t bufferId); diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index fe48d88376..9b1f0db83b 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -140,7 +140,6 @@ protected: /*parent*/ nullptr); t.setLayerStack(mSurfaceControl, 0) .setLayer(mSurfaceControl, std::numeric_limits::max()) - .setFrame(mSurfaceControl, Rect(resolution)) .show(mSurfaceControl) .setDataspace(mSurfaceControl, ui::Dataspace::V0_SRGB) .apply(); @@ -218,13 +217,13 @@ protected: col >= region.left - border && col < region.right + border; } if (!outsideRegion && inRegion) { - EXPECT_GE(epsilon, abs(r - *(pixel))); - EXPECT_GE(epsilon, abs(g - *(pixel + 1))); - EXPECT_GE(epsilon, abs(b - *(pixel + 2))); + ASSERT_GE(epsilon, abs(r - *(pixel))); + ASSERT_GE(epsilon, abs(g - *(pixel + 1))); + ASSERT_GE(epsilon, abs(b - *(pixel + 2))); } else if (outsideRegion && !inRegion) { - EXPECT_GE(epsilon, abs(r - *(pixel))); - EXPECT_GE(epsilon, abs(g - *(pixel + 1))); - EXPECT_GE(epsilon, abs(b - *(pixel + 2))); + ASSERT_GE(epsilon, abs(r - *(pixel))); + ASSERT_GE(epsilon, abs(g - *(pixel + 1))); + ASSERT_GE(epsilon, abs(b - *(pixel + 2))); } ASSERT_EQ(false, ::testing::Test::HasFailure()); } @@ -466,7 +465,8 @@ TEST_F(BLASTBufferQueueTest, SetCrop_Item) { ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); + checkScreenCapture(r, g, b, + {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); } TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { @@ -523,13 +523,15 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { // capture screen and verify that it is red ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); + Rect bounds; + bounds.left = finalCropSideLength / 2; + bounds.top = 0; + bounds.right = bounds.left + finalCropSideLength; + bounds.bottom = finalCropSideLength; + + ASSERT_NO_FATAL_FAILURE(checkScreenCapture(r, g, b, bounds)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, - {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength})); - ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(0, 0, 0, - {0, 0, (int32_t)bufferSideLength, (int32_t)bufferSideLength}, - /*border*/ 0, /*outsideRegion*/ true)); + checkScreenCapture(0, 0, 0, bounds, /*border*/ 0, /*outsideRegion*/ true)); } class TestProducerListener : public BnProducerListener { @@ -596,7 +598,6 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { t.setLayerStack(bgSurface, 0) .show(bgSurface) .setDataspace(bgSurface, ui::Dataspace::V0_SRGB) - .setFrame(bgSurface, Rect(0, 0, mDisplayWidth, mDisplayHeight)) .setLayer(bgSurface, std::numeric_limits::max() - 1) .apply(); @@ -619,7 +620,8 @@ TEST_F(BLASTBufferQueueTest, OutOfOrderTransactionTest) { ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults)); ASSERT_NO_FATAL_FAILURE( - checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight})); + checkScreenCapture(r, g, b, + {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight / 2})); } class BLASTBufferQueueTransformTest : public BLASTBufferQueueTest { diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 48a0be2c45..ed826a0100 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -278,9 +278,8 @@ bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { return stateUpdateAvailable; } -// Crop that applies to the window -Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const { - return Rect::INVALID_RECT; +Rect BufferStateLayer::getCrop(const Layer::State& s) const { + return s.crop; } bool BufferStateLayer::setTransform(uint32_t transform) { @@ -301,57 +300,53 @@ bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInver } bool BufferStateLayer::setCrop(const Rect& crop) { - Rect c = crop; - if (c.left < 0) { - c.left = 0; - } - if (c.top < 0) { - c.top = 0; - } - // If the width and/or height are < 0, make it [0, 0, -1, -1] so the equality comparision below - // treats all invalid rectangles the same. - if (!c.isValid()) { - c.makeInvalid(); - } + if (mCurrentState.crop == crop) return false; + mCurrentState.sequence++; + mCurrentState.crop = crop; - if (mCurrentState.crop == c) return false; - mCurrentState.crop = c; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } -bool BufferStateLayer::setFrame(const Rect& frame) { - int x = frame.left; - int y = frame.top; - int w = frame.getWidth(); - int h = frame.getHeight(); - - if (x < 0) { - x = 0; - w = frame.right; +bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, + bool allowNonRectPreservingTransforms) { + if (mCurrentState.transform.dsdx() == matrix.dsdx && + mCurrentState.transform.dtdy() == matrix.dtdy && + mCurrentState.transform.dtdx() == matrix.dtdx && + mCurrentState.transform.dsdy() == matrix.dsdy) { + return false; } - if (y < 0) { - y = 0; - h = frame.bottom; - } + ui::Transform t; + t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); - if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y && - mCurrentState.width == w && mCurrentState.height == h) { + if (!allowNonRectPreservingTransforms && !t.preserveRects()) { + ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER nor " + "ROTATE_SURFACE_FLINGER ignored"); return false; } - if (!frame.isValid()) { - x = y = w = h = 0; + mCurrentState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + + mCurrentState.sequence++; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + + return true; +} + +bool BufferStateLayer::setPosition(float x, float y) { + if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) { + return false; } + mCurrentState.transform.set(x, y); - mCurrentState.width = w; - mCurrentState.height = h; mCurrentState.sequence++; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); + return true; } @@ -428,6 +423,10 @@ bool BufferStateLayer::setBuffer(const sp& buffer, const spmFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime, FrameTracer::FrameEvent::QUEUE); } + + mCurrentState.width = mCurrentState.buffer->width; + mCurrentState.height = mCurrentState.buffer->height; + return true; } @@ -858,33 +857,6 @@ sp BufferStateLayer::createClone() { return layer; } -Layer::RoundedCornerState BufferStateLayer::getRoundedCornerState() const { - const auto& p = mDrawingParent.promote(); - if (p != nullptr) { - RoundedCornerState parentState = p->getRoundedCornerState(); - if (parentState.radius > 0) { - ui::Transform t = getActiveTransform(getDrawingState()); - t = t.inverse(); - parentState.cropRect = t.transform(parentState.cropRect); - // The rounded corners shader only accepts 1 corner radius for performance reasons, - // but a transform matrix can define horizontal and vertical scales. - // Let's take the average between both of them and pass into the shader, practically we - // never do this type of transformation on windows anyway. - parentState.radius *= (t[0][0] + t[1][1]) / 2.0f; - return parentState; - } - } - const float radius = getDrawingState().cornerRadius; - const State& s(getDrawingState()); - if (radius <= 0 || (getActiveWidth(s) == UINT32_MAX && getActiveHeight(s) == UINT32_MAX)) - return RoundedCornerState(); - return RoundedCornerState(FloatRect(static_cast(s.transform.tx()), - static_cast(s.transform.ty()), - static_cast(s.transform.tx() + s.width), - static_cast(s.transform.ty() + s.height)), - radius); -} - bool BufferStateLayer::bufferNeedsFiltering() const { const State& s(getDrawingState()); if (!s.buffer) { diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 3878f50776..8ce3e1f55b 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -66,7 +66,6 @@ public: bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; bool setCrop(const Rect& crop) override; - bool setFrame(const Rect& frame) override; bool setBuffer(const sp& buffer, const sp& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, @@ -81,15 +80,13 @@ public: bool setTransactionCompletedListeners(const std::vector>& handles) override; bool addFrameEvent(const sp& acquireFence, nsecs_t postedTime, nsecs_t requestedPresentTime) override; + bool setPosition(float /*x*/, float /*y*/) override; + bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/, + bool /*allowNonRectPreservingTransforms*/); // Override to ignore legacy layer state properties that are not used by BufferStateLayer bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; } - bool setPosition(float /*x*/, float /*y*/) override { return false; } bool setTransparentRegionHint(const Region& transparent) override; - bool setMatrix(const layer_state_t::matrix22_t& /*matrix*/, - bool /*allowNonRectPreservingTransforms*/) override { - return false; - } void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, uint64_t /*frameNumber*/) override {} void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, @@ -97,7 +94,6 @@ public: Rect getBufferSize(const State& s) const override; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; - Layer::RoundedCornerState getRoundedCornerState() const override; void setAutoRefresh(bool autoRefresh) override; // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 94fd62fa7a..6038658ee6 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2287,8 +2287,8 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const { } } const float radius = getDrawingState().cornerRadius; - return radius > 0 && getCrop(getDrawingState()).isValid() - ? RoundedCornerState(getCrop(getDrawingState()).toFloatRect(), radius) + return radius > 0 && getCroppedBufferSize(getDrawingState()).isValid() + ? RoundedCornerState(getCroppedBufferSize(getDrawingState()).toFloatRect(), radius) : RoundedCornerState(); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 3a45c949a4..5528a8190f 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -412,7 +412,6 @@ public: // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; - virtual bool setFrame(const Rect& /*frame*/) { return false; }; virtual bool setBuffer(const sp& /*buffer*/, const sp& /*acquireFence*/, nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/, diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index 1d00cc38f2..7a3e433660 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -231,8 +231,14 @@ const std::vector>& RefreshRateOverlay::getOrCreateBuffers(uin void RefreshRateOverlay::setViewport(ui::Size viewport) { Rect frame((3 * viewport.width) >> 4, viewport.height >> 5); frame.offsetBy(viewport.width >> 5, viewport.height >> 4); - mLayer->setFrame(frame); + layer_state_t::matrix22_t matrix; + matrix.dsdx = frame.getWidth() / static_cast(SevenSegmentDrawer::getWidth()); + matrix.dtdx = 0; + matrix.dtdy = 0; + matrix.dsdy = frame.getHeight() / static_cast(SevenSegmentDrawer::getHeight()); + mLayer->setMatrix(matrix, true); + mLayer->setPosition(frame.left, frame.top); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 825834bb4f..8a8ccb91c0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4033,9 +4033,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & layer_state_t::eCropChanged) { if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; } - if (what & layer_state_t::eFrameChanged) { - if (layer->setFrame(s.orientedDisplaySpaceRect)) flags |= eTraversalNeeded; - } if (what & layer_state_t::eAcquireFenceChanged) { if (layer->setAcquireFence(s.acquireFence)) flags |= eTraversalNeeded; } diff --git a/services/surfaceflinger/tests/BufferGenerator.cpp b/services/surfaceflinger/tests/BufferGenerator.cpp index 03f8e1afba..47a150dd35 100644 --- a/services/surfaceflinger/tests/BufferGenerator.cpp +++ b/services/surfaceflinger/tests/BufferGenerator.cpp @@ -296,12 +296,12 @@ private: BufferGenerator::BufferGenerator() : mSurfaceManager(new SurfaceManager), mEglManager(new EglManager), mProgram(new Program) { - const float width = 1000.0; - const float height = 1000.0; + mBufferSize.set(1000.0, 1000.0); auto setBufferWithContext = std::bind(setBuffer, std::placeholders::_1, std::placeholders::_2, this); - mSurfaceManager->initialize(width, height, HAL_PIXEL_FORMAT_RGBA_8888, setBufferWithContext); + mSurfaceManager->initialize(mBufferSize.width, mBufferSize.height, HAL_PIXEL_FORMAT_RGBA_8888, + setBufferWithContext); if (!mEglManager->initialize(mSurfaceManager->getSurface())) return; @@ -309,7 +309,9 @@ BufferGenerator::BufferGenerator() if (!mProgram->initialize(VERTEX_SHADER, FRAGMENT_SHADER)) return; mProgram->use(); - mProgram->bindVec4(0, vec4{width, height, 1.0f / width, 1.0f / height}); + mProgram->bindVec4(0, + vec4{mBufferSize.width, mBufferSize.height, 1.0f / mBufferSize.width, + 1.0f / mBufferSize.height}); mProgram->bindVec3(2, &SPHERICAL_HARMONICS[0], 4); glEnableVertexAttribArray(0); @@ -372,6 +374,10 @@ status_t BufferGenerator::get(sp* outBuffer, sp* outFence) return NO_ERROR; } +ui::Size BufferGenerator::getSize() { + return mBufferSize; +} + // static void BufferGenerator::setBuffer(const sp& buffer, int32_t fence, void* bufferGenerator) { diff --git a/services/surfaceflinger/tests/BufferGenerator.h b/services/surfaceflinger/tests/BufferGenerator.h index a3ffe86572..f7d548b6bf 100644 --- a/services/surfaceflinger/tests/BufferGenerator.h +++ b/services/surfaceflinger/tests/BufferGenerator.h @@ -37,6 +37,7 @@ public: /* Static callback that sets the fence on a particular instance */ static void setBuffer(const sp& buffer, int32_t fence, void* fenceGenerator); + ui::Size getSize(); private: bool mInitialized = false; @@ -53,6 +54,7 @@ private: using Epoch = std::chrono::time_point; Epoch mEpoch = std::chrono::steady_clock::now(); + ui::Size mBufferSize; }; } // namespace android diff --git a/services/surfaceflinger/tests/EffectLayer_test.cpp b/services/surfaceflinger/tests/EffectLayer_test.cpp index f470eda7d3..af00ec7fc9 100644 --- a/services/surfaceflinger/tests/EffectLayer_test.cpp +++ b/services/surfaceflinger/tests/EffectLayer_test.cpp @@ -149,7 +149,6 @@ TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) { t.reparent(blurLayer, mParentLayer); t.setBackgroundBlurRadius(blurLayer, blurRadius); t.setCrop(blurLayer, blurRect); - t.setFrame(blurLayer, blurRect); t.setAlpha(blurLayer, 0.0f); t.show(blurLayer); }); diff --git a/services/surfaceflinger/tests/IPC_test.cpp b/services/surfaceflinger/tests/IPC_test.cpp index a8647c3e50..9fa3d4c417 100644 --- a/services/surfaceflinger/tests/IPC_test.cpp +++ b/services/surfaceflinger/tests/IPC_test.cpp @@ -161,7 +161,6 @@ public: Color::RED); transaction->setLayerStack(mSurfaceControl, 0) .setLayer(mSurfaceControl, std::numeric_limits::max()) - .setFrame(mSurfaceControl, Rect(0, 0, width, height)) .setBuffer(mSurfaceControl, gb) .setAcquireFence(mSurfaceControl, fence) .show(mSurfaceControl) diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp index 158801a705..011ff70409 100644 --- a/services/surfaceflinger/tests/LayerCallback_test.cpp +++ b/services/surfaceflinger/tests/LayerCallback_test.cpp @@ -164,7 +164,10 @@ TEST_F(LayerCallbackTest, NoBufferNoColor) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer, @@ -184,7 +187,10 @@ TEST_F(LayerCallbackTest, BufferNoColor) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -203,7 +209,10 @@ TEST_F(LayerCallbackTest, NoBufferColor) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer, @@ -238,7 +247,10 @@ TEST_F(LayerCallbackTest, OffScreen) { return; } - transaction.setFrame(layer, Rect(-100, -100, 100, 100)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(-100, -100, 100, 100)); + transaction.apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -263,8 +275,15 @@ TEST_F(LayerCallbackTest, MergeBufferNoColor) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -290,8 +309,15 @@ TEST_F(LayerCallbackTest, MergeNoBufferColor) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -318,8 +344,15 @@ TEST_F(LayerCallbackTest, MergeOneBufferOneColor) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer1); @@ -405,8 +438,15 @@ TEST_F(LayerCallbackTest, Merge_DifferentClients) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -491,7 +531,11 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SameStateChange) { } } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expected; expected.addSurface((i == 0) ? ExpectedResult::Transaction::PRESENTED @@ -523,8 +567,16 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -564,8 +616,16 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients) { return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}, @@ -606,8 +666,15 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_NoStateCha return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -661,8 +728,15 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateC return; } - transaction1.setFrame(layer1, Rect(0, 0, 32, 32)); - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + ui::Size bufferSize = getBufferSize(); + + TransactionUtils::setFrame(transaction1, layer1, + Rect(0, 0, bufferSize.width, bufferSize.height), Rect(0, 0, 32, 32)); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + + transaction2.merge(std::move(transaction1)).apply(); ExpectedResult expected; expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2}); @@ -682,7 +756,10 @@ TEST_F(LayerCallbackTest, MultipleTransactions_Merge_DifferentClients_SameStateC return; } - transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply(); + TransactionUtils::setFrame(transaction2, layer2, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(32, 32, 64, 64)); + transaction2.merge(std::move(transaction1)).apply(); expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer2, ExpectedResult::Buffer::NOT_ACQUIRED); @@ -762,7 +839,10 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + ui::Size bufferSize = getBufferSize(); + TransactionUtils::setFrame(transaction, layer, Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); ExpectedResult expectedResult; expectedResult.addSurface(ExpectedResult::Transaction::PRESENTED, layer); @@ -781,7 +861,10 @@ TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) { return; } - transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply(); + TransactionUtils::setFrame(transaction, layer, + Rect(0, 0, bufferSize.width, bufferSize.height), + Rect(0, 0, 32, 32)); + transaction.apply(); } EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true)); } diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp index 7505e6ea9b..53d230abe7 100644 --- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp @@ -204,11 +204,7 @@ void LayerRenderTypeTransactionTest::setRelativeZBasicHelper(uint32_t layerType) Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply(); break; case ISurfaceComposerClient::eFXSurfaceBufferState: - Transaction() - .setFrame(layerR, Rect(0, 0, 32, 32)) - .setFrame(layerG, Rect(16, 16, 48, 48)) - .setRelativeLayer(layerG, layerR, 1) - .apply(); + Transaction().setPosition(layerG, 16, 16).setRelativeLayer(layerG, layerR, 1).apply(); break; default: ASSERT_FALSE(true) << "Unsupported layer type"; @@ -260,10 +256,9 @@ void LayerRenderTypeTransactionTest::setRelativeZGroupHelper(uint32_t layerType) break; case ISurfaceComposerClient::eFXSurfaceBufferState: Transaction() - .setFrame(layerR, Rect(0, 0, 32, 32)) - .setFrame(layerG, Rect(8, 8, 40, 40)) + .setPosition(layerG, 8, 8) .setRelativeLayer(layerG, layerR, 3) - .setFrame(layerB, Rect(16, 16, 48, 48)) + .setPosition(layerB, 16, 16) .setLayer(layerB, mLayerZBase + 2) .apply(); break; @@ -388,7 +383,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintBasic_BufferState Transaction() .setTransparentRegionHint(layer, Region(top)) .setBuffer(layer, buffer) - .setFrame(layer, Rect(0, 0, 32, 32)) .apply(); { SCOPED_TRACE("top transparent"); @@ -447,7 +441,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransparentRegionHintOutOfBounds_Buffe // check that transparent region hint is bound by the layer size Transaction() .setTransparentRegionHint(layerTransparent, Region(mDisplayRect)) - .setFrame(layerR, Rect(16, 16, 48, 48)) + .setPosition(layerR, 16, 16) .setLayer(layerR, mLayerZBase + 1) .apply(); ASSERT_NO_FATAL_FAILURE( @@ -477,8 +471,7 @@ void LayerRenderTypeTransactionTest::setAlphaBasicHelper(uint32_t layerType) { Transaction() .setAlpha(layer1, 0.25f) .setAlpha(layer2, 0.75f) - .setFrame(layer1, Rect(0, 0, 32, 32)) - .setFrame(layer2, Rect(16, 0, 48, 32)) + .setPosition(layer2, 16, 0) .setLayer(layer2, mLayerZBase + 1) .apply(); break; @@ -573,7 +566,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, fillColor, width, height)); expectedColor = fillColor; } - Transaction().setFrame(layer, Rect(0, 0, width, height)).apply(); + Transaction().setCrop(layer, Rect(0, 0, width, height)).apply(); break; default: GTEST_FAIL() << "Unknown layer type in setBackgroundColorHelper"; @@ -849,42 +842,39 @@ TEST_P(LayerRenderTypeTransactionTest, SetMatrixBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerQuadrant(layer, 32, 32, Color::RED, Color::GREEN, Color::BLUE, Color::WHITE)); - Transaction() - .setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f) - .setFrame(layer, Rect(0, 0, 32, 32)) - .apply(); + Transaction().setPosition(layer, 32, 32).setMatrix(layer, 1.0f, 0.0f, 0.0f, 1.0f).apply(); { SCOPED_TRACE("IDENTITY"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, + getScreenCapture()->expectQuadrant(Rect(32, 32, 64, 64), Color::RED, Color::GREEN, Color::BLUE, Color::WHITE); } Transaction().setMatrix(layer, -1.0f, 0.0f, 0.0f, 1.0f).apply(); { SCOPED_TRACE("FLIP_H"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(0, 32, 32, 64), Color::GREEN, Color::RED, + Color::WHITE, Color::BLUE); } Transaction().setMatrix(layer, 1.0f, 0.0f, 0.0f, -1.0f).apply(); { SCOPED_TRACE("FLIP_V"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(32, 0, 64, 32), Color::BLUE, Color::WHITE, + Color::RED, Color::GREEN); } Transaction().setMatrix(layer, 0.0f, 1.0f, -1.0f, 0.0f).apply(); { SCOPED_TRACE("ROT_90"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(0, 32, 32, 64), Color::BLUE, Color::RED, + Color::WHITE, Color::GREEN); } Transaction().setMatrix(layer, 2.0f, 0.0f, 0.0f, 2.0f).apply(); { SCOPED_TRACE("SCALE"); - getScreenCapture()->expectQuadrant(Rect(0, 0, 32, 32), Color::RED, Color::GREEN, - Color::BLUE, Color::WHITE); + getScreenCapture()->expectQuadrant(Rect(32, 32, 96, 96), Color::RED, Color::GREEN, + Color::BLUE, Color::WHITE, 1 /* tolerance */); } } @@ -955,8 +945,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropBasic_BufferState) { Transaction().setCrop(layer, crop).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(crop, Color::RED); + shot->expectBorder(crop, Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferQueue) { @@ -986,13 +976,13 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropEmpty_BufferState) { { SCOPED_TRACE("empty rect"); Transaction().setCrop(layer, Rect(8, 8, 8, 8)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); } { SCOPED_TRACE("negative rect"); Transaction().setCrop(layer, Rect(8, 8, 0, 0)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED); } } @@ -1016,8 +1006,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 32, 16), Color::BLUE); TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 16, 32, 64), Color::RED); - Transaction().setFrame(layer, Rect(0, 0, 64, 64)).apply(); - Transaction().setBuffer(layer, buffer).apply(); // Partially out of bounds in the negative (upper left) direction @@ -1025,8 +1013,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("out of bounds, negative (upper left) direction"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 64), Color::BLUE); - shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 16), Color::BLUE); + shot->expectBorder(Rect(0, 0, 32, 16), Color::BLACK); } // Partially out of bounds in the positive (lower right) direction @@ -1034,8 +1022,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("out of bounds, positive (lower right) direction"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 64), Color::RED); - shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 16, 32, 64), Color::RED); + shot->expectBorder(Rect(0, 16, 32, 64), Color::BLACK); } // Fully out of buffer space bounds @@ -1043,9 +1031,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropOutOfBounds_BufferState) { { SCOPED_TRACE("Fully out of bounds"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 64, 16), Color::BLUE); - shot->expectColor(Rect(0, 16, 64, 64), Color::RED); - shot->expectBorder(Rect(0, 0, 64, 64), Color::BLACK); + shot->expectColor(Rect(0, 0, 64, 64), Color::BLACK); } } @@ -1068,12 +1054,11 @@ TEST_P(LayerRenderTypeTransactionTest, SetCropWithTranslation_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); - const Rect frame(32, 32, 64, 64); const Rect crop(8, 8, 24, 24); - Transaction().setFrame(layer, frame).setCrop(layer, crop).apply(); + Transaction().setPosition(layer, 32, 32).setCrop(layer, crop).apply(); auto shot = getScreenCapture(); - shot->expectColor(frame, Color::RED); - shot->expectBorder(frame, Color::BLACK); + shot->expectColor(Rect(40, 40, 56, 56), Color::RED); + shot->expectBorder(Rect(40, 40, 56, 56), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetCropWithScale_BufferQueue) { @@ -1121,7 +1106,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); const Rect frame(8, 8, 24, 24); - Transaction().setFrame(layer, frame).apply(); + Transaction t; + TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), frame); + t.apply(); + auto shot = getScreenCapture(); shot->expectColor(frame, Color::RED); shot->expectBorder(frame, Color::BLACK); @@ -1133,16 +1121,23 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameEmpty_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); + Transaction t; { SCOPED_TRACE("empty rect"); - Transaction().setFrame(layer, Rect(8, 8, 8, 8)).apply(); + TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), Rect(8, 8, 8, 8)); + t.apply(); + getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); } { SCOPED_TRACE("negative rect"); - Transaction().setFrame(layer, Rect(8, 8, 0, 0)).apply(); - getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::BLACK); + TransactionUtils::setFrame(t, layer, Rect(0, 0, 32, 32), Rect(8, 8, 0, 0)); + t.apply(); + + auto shot = getScreenCapture(); + shot->expectColor(Rect(0, 0, 8, 8), Color::RED); + shot->expectBorder(Rect(0, 0, 8, 8), Color::BLACK); } } @@ -1152,10 +1147,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultParentless_BufferState) { layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 10, 10)); - // A parentless layer will default to a frame with the same size as the buffer + // A layer with a buffer will have a computed size that matches the buffer size. auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 10, 10), Color::RED); + shot->expectBorder(Rect(0, 0, 10, 10), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBSParent_BufferState) { @@ -1163,17 +1158,16 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBSParent_BufferState) { ASSERT_NO_FATAL_FAILURE( parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32)); - Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply(); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); Transaction().reparent(child, parent).apply(); - // A layer will default to the frame of its parent + // A layer with a buffer will have a computed size that matches the buffer size. auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectColor(Rect(0, 0, 10, 10), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1183,14 +1177,14 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameDefaultBQParent_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parent, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); Transaction().reparent(child, parent).apply(); - // A layer will default to the frame of its parent + // A layer with a buffer will have a computed size that matches the buffer size. auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectColor(Rect(0, 0, 10, 10), Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1199,11 +1193,10 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameUpdate_BufferState) { ASSERT_NO_FATAL_FAILURE( layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); - Transaction().setFrame(layer, Rect(0, 0, 32, 32)).apply(); std::this_thread::sleep_for(500ms); - Transaction().setFrame(layer, Rect(16, 16, 48, 48)).apply(); + Transaction().setPosition(layer, 16, 16).apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(16, 16, 48, 48), Color::RED); @@ -1215,18 +1208,20 @@ TEST_P(LayerRenderTypeTransactionTest, SetFrameOutsideBounds_BufferState) { ASSERT_NO_FATAL_FAILURE( parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); ASSERT_NO_FATAL_FAILURE( - child = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState)); + child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState)); Transaction().reparent(child, parent).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32)); - Transaction().setFrame(parent, Rect(0, 0, 32, 32)).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10)); - Transaction().setFrame(child, Rect(0, 16, 32, 32)).apply(); + Rect childDst(0, 16, 32, 32); + Transaction t; + TransactionUtils::setFrame(t, child, Rect(0, 0, 10, 10), childDst); + t.apply(); auto shot = getScreenCapture(); shot->expectColor(Rect(0, 0, 32, 16), Color::RED); - shot->expectColor(Rect(0, 16, 32, 32), Color::BLUE); + shot->expectColor(childDst, Color::BLUE); shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } @@ -1238,8 +1233,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferBasic_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { @@ -1252,8 +1247,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 1"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32)); @@ -1261,8 +1256,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 2"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLUE); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32)); @@ -1270,8 +1265,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleBuffers_BufferState) { { SCOPED_TRACE("set buffer 3"); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } } @@ -1286,7 +1281,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleLayers_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::RED, 64, 64)); - Transaction().setFrame(layer1, Rect(0, 0, 64, 64)).apply(); { SCOPED_TRACE("set layer 1 buffer red"); auto shot = getScreenCapture(); @@ -1295,7 +1289,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferMultipleLayers_BufferState) { ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::BLUE, 32, 32)); - Transaction().setFrame(layer2, Rect(0, 0, 32, 32)).apply(); { SCOPED_TRACE("set layer 2 buffer blue"); auto shot = getScreenCapture(); @@ -1350,8 +1343,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_BufferState) { Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), color); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } idx++; } @@ -1383,8 +1376,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_LeastRecentlyUsed_Buffer Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), color); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } idx++; } @@ -1416,8 +1409,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetBufferCaching_DestroyedBuffer_BufferSt Color color = colors[idx % colors.size()]; auto shot = screenshot(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), color); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), color); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } if (idx == 0) { buffers[0].clear(); @@ -1435,7 +1428,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformRotate90_BufferState) { Color::BLUE, Color::WHITE)); Transaction() - .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_ROT_90) .apply(); @@ -1452,7 +1444,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformFlipH_BufferState) { Color::BLUE, Color::WHITE)); Transaction() - .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_H) .apply(); @@ -1469,7 +1460,6 @@ TEST_P(LayerRenderTypeTransactionTest, SetTransformFlipV_BufferState) { Color::BLUE, Color::WHITE)); Transaction() - .setFrame(layer, Rect(0, 0, 32, 32)) .setTransform(layer, NATIVE_WINDOW_TRANSFORM_FLIP_V) .apply(); @@ -1518,8 +1508,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetFenceNull_BufferState) { Transaction().setBuffer(layer, buffer).setAcquireFence(layer, fence).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) { @@ -1534,8 +1524,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) { Transaction().setBuffer(layer, buffer).setDataspace(layer, ui::Dataspace::UNKNOWN).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetHdrMetadataBasic_BufferState) { @@ -1552,8 +1542,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetHdrMetadataBasic_BufferState) { Transaction().setBuffer(layer, buffer).setHdrMetadata(layer, hdrMetadata).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetSurfaceDamageRegionBasic_BufferState) { @@ -1570,8 +1560,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetSurfaceDamageRegionBasic_BufferState) Transaction().setBuffer(layer, buffer).setSurfaceDamageRegion(layer, region).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetApiBasic_BufferState) { @@ -1586,8 +1576,8 @@ TEST_P(LayerRenderTypeTransactionTest, SetApiBasic_BufferState) { Transaction().setBuffer(layer, buffer).setApi(layer, NATIVE_WINDOW_API_CPU).apply(); auto shot = getScreenCapture(); - shot->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::RED); - shot->expectBorder(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::BLACK); + shot->expectColor(Rect(0, 0, 32, 32), Color::RED); + shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK); } TEST_P(LayerRenderTypeTransactionTest, SetColorTransformBasic) { diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index 87c7b7d829..0bc8fe7aa0 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -244,6 +244,11 @@ protected: return bufferGenerator.get(outBuffer, outFence); } + static ui::Size getBufferSize() { + static BufferGenerator bufferGenerator; + return bufferGenerator.getSize(); + } + sp mClient; bool deviceSupportsBlurs() { diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp index ac5e297e43..edf55ea6ef 100644 --- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp @@ -196,17 +196,7 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadius) { ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size)); - if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - Transaction() - .setCornerRadius(layer, cornerRadius) - .setCrop(layer, Rect(0, 0, size, size)) - .apply(); - } else { - Transaction() - .setCornerRadius(layer, cornerRadius) - .setFrame(layer, Rect(0, 0, size, size)) - .apply(); - } + Transaction().setCornerRadius(layer, cornerRadius).apply(); { const uint8_t bottom = size - 1; const uint8_t right = size - 1; @@ -234,19 +224,13 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusRotated) { ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size)); - auto transaction = Transaction() - .setCornerRadius(parent, cornerRadius) - .setCrop(parent, Rect(0, 0, size, size)) - .reparent(child, parent) - .setPosition(child, 0, size) - // Rotate by half PI - .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f); - if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - transaction.setCrop(parent, Rect(0, 0, size, size)); - } else { - transaction.setFrame(parent, Rect(0, 0, size, size)); - } - transaction.apply(); + Transaction() + .setCornerRadius(parent, cornerRadius) + .reparent(child, parent) + .setPosition(child, 0, size) + // Rotate by half PI + .setMatrix(child, 0.0f, -1.0f, 1.0f, 0.0f) + .apply(); { const uint8_t bottom = size - 1; @@ -275,21 +259,12 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusChildCrop) { ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size / 2)); ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size / 2)); - if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) { - Transaction() - .setCornerRadius(parent, cornerRadius) - .setCrop(parent, Rect(0, 0, size, size)) - .reparent(child, parent) - .setPosition(child, 0, size / 2) - .apply(); - } else { - Transaction() - .setCornerRadius(parent, cornerRadius) - .setFrame(parent, Rect(0, 0, size, size)) - .reparent(child, parent) - .setFrame(child, Rect(0, size / 2, size, size)) - .apply(); - } + Transaction() + .setCornerRadius(parent, cornerRadius) + .reparent(child, parent) + .setPosition(child, 0, size / 2) + .apply(); + { const uint8_t bottom = size - 1; const uint8_t right = size - 1; @@ -331,12 +306,9 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { Transaction() .setLayer(greenLayer, mLayerZBase) - .setFrame(leftLayer, {0, 0, canvasSize * 2, canvasSize * 2}) .setLayer(leftLayer, mLayerZBase + 1) - .setFrame(leftLayer, leftRect) .setLayer(rightLayer, mLayerZBase + 2) .setPosition(rightLayer, rightRect.left, rightRect.top) - .setFrame(rightLayer, rightRect) .apply(); { @@ -352,7 +324,6 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { .setLayer(blurLayer, mLayerZBase + 3) .setBackgroundBlurRadius(blurLayer, blurRadius) .setCrop(blurLayer, blurRect) - .setFrame(blurLayer, blurRect) .setSize(blurLayer, blurRect.getWidth(), blurRect.getHeight()) .setAlpha(blurLayer, 0.0f) .apply(); @@ -435,10 +406,8 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentA Transaction() .setLayer(left, mLayerZBase + 1) - .setFrame(left, {0, 0, size, size}) .setLayer(right, mLayerZBase + 2) .setPosition(right, size, 0) - .setFrame(right, {size, 0, size * 2, size}) .apply(); { @@ -457,7 +426,6 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentA .setAlpha(blurParent, 0.5) .setLayer(blur, mLayerZBase + 4) .setBackgroundBlurRadius(blur, size) // set the blur radius to the size of one rect - .setFrame(blur, {0, 0, size * 2, size}) .reparent(blur, blurParent) .apply(); diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp index 613b21ef04..ccf434d63a 100644 --- a/services/surfaceflinger/tests/MirrorLayer_test.cpp +++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp @@ -195,7 +195,7 @@ TEST_F(MirrorLayerTest, MirrorBufferLayer) { createLayer("BufferStateLayer", 200, 200, ISurfaceComposerClient::eFXSurfaceBufferState, mChildLayer.get()); fillBufferStateLayerColor(bufferStateLayer, Color::BLUE, 200, 200); - Transaction().setFrame(bufferStateLayer, Rect(0, 0, 200, 200)).show(bufferStateLayer).apply(); + Transaction().show(bufferStateLayer).apply(); { SCOPED_TRACE("Initial Mirror BufferStateLayer"); diff --git a/services/surfaceflinger/tests/utils/TransactionUtils.h b/services/surfaceflinger/tests/utils/TransactionUtils.h index 3cbfed98f5..8c448e2f96 100644 --- a/services/surfaceflinger/tests/utils/TransactionUtils.h +++ b/services/surfaceflinger/tests/utils/TransactionUtils.h @@ -126,7 +126,7 @@ public: const uint8_t* src = pixels + (outBuffer->getStride() * (y + j) + x) * 4; for (int32_t i = 0; i < width; i++) { const uint8_t expected[4] = {color.r, color.g, color.b, color.a}; - EXPECT_TRUE(std::equal(src, src + 4, expected, colorCompare)) + ASSERT_TRUE(std::equal(src, src + 4, expected, colorCompare)) << "pixel @ (" << x + i << ", " << y + j << "): " << "expected (" << color << "), " << "got (" << Color{src[0], src[1], src[2], src[3]} << ")"; @@ -161,6 +161,22 @@ public: ASSERT_EQ(NO_ERROR, s->unlockAndPost()); } } + + static void setFrame(Transaction& t, const sp& sc, Rect source, Rect dest, + int32_t transform = 0) { + uint32_t sourceWidth = source.getWidth(); + uint32_t sourceHeight = source.getHeight(); + + if (transform & ui::Transform::ROT_90) { + std::swap(sourceWidth, sourceHeight); + } + + float dsdx = dest.getWidth() / static_cast(sourceWidth); + float dsdy = dest.getHeight() / static_cast(sourceHeight); + + t.setMatrix(sc, dsdx, 0, 0, dsdy); + t.setPosition(sc, dest.left, dest.top); + } }; enum class RenderPath { SCREENSHOT, VIRTUAL_DISPLAY }; -- cgit v1.2.3-59-g8ed1b From 0758e5d1bcf68751b3b847cc542be2ec27f9b816 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 11 Mar 2021 22:15:04 -0800 Subject: SurfaceFlinger: Remove deferTransactionUntil There are no users left Bug: 168505645 Change-Id: I81725bf3c0ef4704e9da25da9a75854b4f172885 --- cmds/surfacereplayer/proto/src/trace.proto | 6 - cmds/surfacereplayer/replayer/Replayer.cpp | 25 --- cmds/surfacereplayer/replayer/Replayer.h | 4 - libs/gui/LayerState.cpp | 10 - libs/gui/SurfaceComposerClient.cpp | 17 -- libs/gui/include/gui/LayerState.h | 4 - libs/gui/include/gui/SurfaceComposerClient.h | 8 +- services/surfaceflinger/BufferLayer.cpp | 76 -------- services/surfaceflinger/BufferLayer.h | 7 - services/surfaceflinger/BufferStateLayer.cpp | 19 -- services/surfaceflinger/BufferStateLayer.h | 9 - services/surfaceflinger/Layer.cpp | 208 +-------------------- services/surfaceflinger/Layer.h | 99 +--------- services/surfaceflinger/SurfaceFlinger.cpp | 19 -- services/surfaceflinger/SurfaceInterceptor.cpp | 28 --- services/surfaceflinger/SurfaceInterceptor.h | 2 - services/surfaceflinger/tests/LayerUpdate_test.cpp | 85 --------- .../tests/SurfaceInterceptor_test.cpp | 29 --- .../tests/fakehwc/SFFakeHwc_test.cpp | 118 ------------ .../tests/unittests/RefreshRateSelectionTest.cpp | 5 +- .../tests/unittests/SetFrameRateTest.cpp | 5 +- .../tests/unittests/TransactionFrameTracerTest.cpp | 7 +- .../unittests/TransactionSurfaceFrameTest.cpp | 82 +------- 23 files changed, 14 insertions(+), 858 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto index 06afefd3c8..3798ba73a4 100644 --- a/cmds/surfacereplayer/proto/src/trace.proto +++ b/cmds/surfacereplayer/proto/src/trace.proto @@ -46,7 +46,6 @@ message SurfaceChange { HiddenFlagChange hidden_flag = 12; OpaqueFlagChange opaque_flag = 13; SecureFlagChange secure_flag = 14; - DeferredTransactionChange deferred_transaction = 15; CornerRadiusChange corner_radius = 16; ReparentChange reparent = 17; RelativeParentChange relative_parent = 18; @@ -113,11 +112,6 @@ message SecureFlagChange { required bool secure_flag = 1; } -message DeferredTransactionChange { - required int32 layer_id = 1; - required uint64 frame_number = 2; -} - message DisplayChange { required int32 id = 1; diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp index a6d9a3feb6..cfd42fec30 100644 --- a/cmds/surfacereplayer/replayer/Replayer.cpp +++ b/cmds/surfacereplayer/replayer/Replayer.cpp @@ -402,11 +402,6 @@ status_t Replayer::doSurfaceTransaction( case SurfaceChange::SurfaceChangeCase::kSecureFlag: setSecureFlag(transaction, change.id(), change.secure_flag()); break; - case SurfaceChange::SurfaceChangeCase::kDeferredTransaction: - waitUntilDeferredTransactionLayerExists(change.deferred_transaction(), lock); - setDeferredTransaction(transaction, change.id(), - change.deferred_transaction()); - break; case SurfaceChange::SurfaceChangeCase::kReparent: setReparentChange(transaction, change.id(), change.reparent()); break; @@ -560,19 +555,6 @@ void Replayer::setSecureFlag(SurfaceComposerClient::Transaction& t, t.setFlags(mLayers[id], flag, layer_state_t::eLayerSecure); } -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; - } - - t.deferTransactionUntil_legacy(mLayers[id], mLayers[dtc.layer_id()], dtc.frame_number()); -} - void Replayer::setDisplaySurface(SurfaceComposerClient::Transaction& t, display_id id, const DispSurfaceChange& /*dsc*/) { sp outProducer; @@ -676,13 +658,6 @@ void Replayer::waitUntilTimestamp(int64_t timestamp) { std::this_thread::sleep_for(std::chrono::nanoseconds(timestamp - mCurrentTime)); } -void Replayer::waitUntilDeferredTransactionLayerExists( - const DeferredTransactionChange& dtc, std::unique_lock& lock) { - if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { - mLayerCond.wait(lock, [&] { return (mLayers[dtc.layer_id()] != nullptr); }); - } -} - status_t Replayer::loadSurfaceComposerClient() { mComposerClient = new SurfaceComposerClient; return mComposerClient->initCheck(); diff --git a/cmds/surfacereplayer/replayer/Replayer.h b/cmds/surfacereplayer/replayer/Replayer.h index 252db2bfbb..d62522a497 100644 --- a/cmds/surfacereplayer/replayer/Replayer.h +++ b/cmds/surfacereplayer/replayer/Replayer.h @@ -110,8 +110,6 @@ class Replayer { 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 setReparentChange(SurfaceComposerClient::Transaction& t, layer_id id, const ReparentChange& c); void setRelativeParentChange(SurfaceComposerClient::Transaction& t, @@ -131,8 +129,6 @@ class Replayer { display_id id, const ProjectionChange& pc); void waitUntilTimestamp(int64_t timestamp); - void waitUntilDeferredTransactionLayerExists( - const DeferredTransactionChange& dtc, std::unique_lock& lock); status_t loadSurfaceComposerClient(); Trace mTrace; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 809438534c..55ed7fe298 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -45,7 +45,6 @@ layer_state_t::layer_state_t() reserved(0), cornerRadius(0.0f), backgroundBlurRadius(0), - barrierFrameNumber(0), transform(0), transformToDisplayInverse(false), crop(Rect::INVALID_RECT), @@ -87,9 +86,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeUint32, mask); SAFE_PARCEL(matrix.write, output); SAFE_PARCEL(output.write, crop); - SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, barrierSurfaceControl_legacy); SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, reparentSurfaceControl); - SAFE_PARCEL(output.writeUint64, barrierFrameNumber); SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, relativeLayerSurfaceControl); SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, parentSurfaceControlForChild); SAFE_PARCEL(output.writeFloat, color.r); @@ -193,9 +190,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(matrix.read, input); SAFE_PARCEL(input.read, crop); - SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &barrierSurfaceControl_legacy); SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &reparentSurfaceControl); - SAFE_PARCEL(input.readUint64, &barrierFrameNumber); SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &relativeLayerSurfaceControl); SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &parentSurfaceControlForChild); @@ -425,11 +420,6 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eBlurRegionsChanged; blurRegions = other.blurRegions; } - if (other.what & eDeferTransaction_legacy) { - what |= eDeferTransaction_legacy; - barrierSurfaceControl_legacy = other.barrierSurfaceControl_legacy; - barrierFrameNumber = other.barrierFrameNumber; - } if (other.what & eRelativeLayerChanged) { what |= eRelativeLayerChanged; what &= ~eLayerChanged; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 9ce094aa77..e6baba6e1d 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1140,23 +1140,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBlurR return *this; } -SurfaceComposerClient::Transaction& -SurfaceComposerClient::Transaction::deferTransactionUntil_legacy( - const sp& sc, const sp& barrierSurfaceControl, - uint64_t frameNumber) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eDeferTransaction_legacy; - s->barrierSurfaceControl_legacy = barrierSurfaceControl; - s->barrierFrameNumber = frameNumber; - - registerSurfaceControlForCallback(sc); - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent( const sp& sc, const sp& newParent) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 41a022f90e..d2d1e5b91c 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -82,8 +82,6 @@ struct layer_state_t { eTransparentRegionChanged = 0x00000020, eFlagsChanged = 0x00000040, eLayerStackChanged = 0x00000080, - /* was eCropChanged_legacy, now available 0x00000100, */ - eDeferTransaction_legacy = 0x00000200, eReleaseBufferListenerChanged = 0x00000400, eShadowRadiusChanged = 0x00000800, /* was eDetachChildren, now available 0x00002000, */ @@ -152,9 +150,7 @@ struct layer_state_t { matrix22_t matrix; float cornerRadius; uint32_t backgroundBlurRadius; - sp barrierSurfaceControl_legacy; sp reparentSurfaceControl; - uint64_t barrierFrameNumber; sp relativeLayerSurfaceControl; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 1590b10a00..fe6a30aa42 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -454,13 +454,7 @@ public: const std::vector& regions); Transaction& setLayerStack(const sp& sc, uint32_t layerStack); Transaction& setMetadata(const sp& sc, uint32_t key, const Parcel& p); - // 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_legacy(const sp& sc, - const sp& barrierSurfaceControl, - uint64_t frameNumber); + /// Reparents the current layer to the new parent handle. The new parent must not be null. Transaction& reparent(const sp& sc, const sp& newParent); diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index be9bce0795..12f63dbbf1 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -507,11 +507,6 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, BufferInfo oldBufferInfo = mBufferInfo; - if (!allTransactionsSignaled(expectedPresentTime)) { - mFlinger->setTransactionFlags(eTraversalNeeded); - return false; - } - status_t err = updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime); if (err != NO_ERROR) { return false; @@ -556,53 +551,9 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, recomputeVisibleRegions = true; } - // Remove any sync points corresponding to the buffer which was just - // latched - { - Mutex::Autolock lock(mLocalSyncPointMutex); - auto point = mLocalSyncPoints.begin(); - while (point != mLocalSyncPoints.end()) { - if (!(*point)->frameIsAvailable() || !(*point)->transactionIsApplied()) { - // This sync point must have been added since we started - // latching. Don't drop it yet. - ++point; - continue; - } - - if ((*point)->getFrameNumber() <= mCurrentFrameNumber) { - std::stringstream ss; - ss << "Dropping sync point " << (*point)->getFrameNumber(); - ATRACE_NAME(ss.str().c_str()); - point = mLocalSyncPoints.erase(point); - } else { - ++point; - } - } - } - return true; } -// transaction -void BufferLayer::notifyAvailableFrames(nsecs_t expectedPresentTime) { - const auto headFrameNumber = getHeadFrameNumber(expectedPresentTime); - const bool headFenceSignaled = fenceHasSignaled(); - const bool presentTimeIsCurrent = framePresentTimeIsCurrent(expectedPresentTime); - Mutex::Autolock lock(mLocalSyncPointMutex); - for (auto& point : mLocalSyncPoints) { - if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled && - presentTimeIsCurrent) { - point->setFrameAvailable(); - sp requestedSyncLayer = point->getRequestedSyncLayer(); - if (requestedSyncLayer) { - // Need to update the transaction flag to ensure the layer's pending transaction - // gets applied. - requestedSyncLayer->setTransactionFlags(eTransactionNeeded); - } - } - } -} - bool BufferLayer::hasReadyFrame() const { return hasFrameUpdate() || getSidebandStreamChanged() || getAutoRefresh(); } @@ -616,33 +567,6 @@ bool BufferLayer::isProtected() const { return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED); } -// h/w composer set-up -bool BufferLayer::allTransactionsSignaled(nsecs_t expectedPresentTime) { - const auto headFrameNumber = getHeadFrameNumber(expectedPresentTime); - bool matchingFramesFound = false; - bool allTransactionsApplied = true; - Mutex::Autolock lock(mLocalSyncPointMutex); - - for (auto& point : mLocalSyncPoints) { - if (point->getFrameNumber() > headFrameNumber) { - break; - } - matchingFramesFound = true; - - if (!point->frameIsAvailable()) { - // We haven't notified the remote layer that the frame for - // this point is available yet. Notify it now, and then - // abort this attempt to latch. - point->setFrameAvailable(); - allTransactionsApplied = false; - break; - } - - allTransactionsApplied = allTransactionsApplied && point->transactionIsApplied(); - } - return !matchingFramesFound || allTransactionsApplied; -} - // As documented in libhardware header, formats in the range // 0x100 - 0x1FF are specific to the HAL implementation, and // are known to have no alpha channel diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index b8d3f12322..0a5235aa08 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -90,8 +90,6 @@ public: bool isBufferLatched() const override { return mRefreshPending; } - void notifyAvailableFrames(nsecs_t expectedPresentTime) override; - bool hasReadyFrame() const override; // Returns the current scaling mode @@ -153,11 +151,6 @@ protected: bool onPreComposition(nsecs_t) override; void preparePerFrameCompositionState() override; - // Check all of the local sync points to ensure that all transactions - // which need to have been applied prior to the frame which is about to - // be latched have signaled - bool allTransactionsSignaled(nsecs_t expectedPresentTime); - static bool getOpacityForFormat(uint32_t format); // from graphics API diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index ed826a0100..fa9cecf787 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -259,25 +259,6 @@ bool BufferStateLayer::willPresentCurrentTransaction() const { (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr))); } -/* TODO: vhau uncomment once deferred transaction migration complete in - * WindowManager -void BufferStateLayer::pushPendingState() { - if (!mCurrentState.modified) { - return; - } - mPendingStates.push_back(mCurrentState); - ATRACE_INT(mTransactionName.c_str(), mPendingStates.size()); -} -*/ - -bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { - mCurrentStateModified = mCurrentState.modified; - bool stateUpdateAvailable = Layer::applyPendingStates(stateToCommit); - mCurrentStateModified = stateUpdateAvailable && mCurrentStateModified; - mCurrentState.modified = false; - return stateUpdateAvailable; -} - Rect BufferStateLayer::getCrop(const Layer::State& s) const { return s.crop; } diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 8ce3e1f55b..24e0ad290f 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -50,10 +50,6 @@ public: uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override { return flags; } - /*TODO:vhau return to using BufferStateLayer override once WM - * has removed deferred transactions! - void pushPendingState() override;*/ - bool applyPendingStates(Layer::State* stateToCommit) override; uint32_t getActiveWidth(const Layer::State& s) const override { return s.width; } uint32_t getActiveHeight(const Layer::State& s) const override { return s.height; } @@ -87,10 +83,6 @@ public: // Override to ignore legacy layer state properties that are not used by BufferStateLayer bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; } bool setTransparentRegionHint(const Region& transparent) override; - void deferTransactionUntil_legacy(const sp& /*barrierHandle*/, - uint64_t /*frameNumber*/) override {} - void deferTransactionUntil_legacy(const sp& /*barrierLayer*/, - uint64_t /*frameNumber*/) override {} Rect getBufferSize(const State& s) const override; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; @@ -165,7 +157,6 @@ private: uint64_t mPreviousBufferId = 0; uint64_t mPreviousReleasedFrameNumber = 0; - mutable bool mCurrentStateModified = false; bool mReleasePreviousBuffer = false; // Stores the last set acquire fence signal time used to populate the callback handle's acquire diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6038658ee6..ebf845cb95 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -202,19 +202,6 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp client, */ void Layer::onLayerDisplayed(const sp& /*releaseFence*/) {} -void Layer::removeRemoteSyncPoints() { - for (auto& point : mRemoteSyncPoints) { - point->setTransactionApplied(); - } - mRemoteSyncPoints.clear(); - - { - for (State pendingState : mPendingStates) { - pendingState.barrierLayer_legacy = nullptr; - } - } -} - void Layer::removeRelativeZ(const std::vector& layersInTree) { if (mCurrentState.zOrderRelativeOf == nullptr) { return; @@ -236,21 +223,6 @@ void Layer::removeRelativeZ(const std::vector& layersInTree) { void Layer::removeFromCurrentState() { mRemovedFromCurrentState = true; - // Since we are no longer reachable from CurrentState SurfaceFlinger - // will no longer invoke doTransaction for us, and so we will - // never finish applying transactions. We signal the sync point - // now so that another layer will not become indefinitely - // blocked. - removeRemoteSyncPoints(); - - { - Mutex::Autolock syncLock(mLocalSyncPointMutex); - for (auto& point : mLocalSyncPoints) { - point->setFrameAvailable(); - } - mLocalSyncPoints.clear(); - } - mFlinger->markLayerPendingRemovalLocked(this); } @@ -775,21 +747,6 @@ Hwc2::IComposerClient::Composition Layer::getCompositionType(const DisplayDevice } } -bool Layer::addSyncPoint(const std::shared_ptr& point) { - if (point->getFrameNumber() <= mCurrentFrameNumber) { - // Don't bother with a SyncPoint, since we've already latched the - // relevant frame - return false; - } - if (isRemovedFromCurrentState()) { - return false; - } - - Mutex::Autolock lock(mLocalSyncPointMutex); - mLocalSyncPoints.push_back(point); - return true; -} - // ---------------------------------------------------------------------------- // local state // ---------------------------------------------------------------------------- @@ -808,132 +765,6 @@ bool Layer::isSecure() const { // transaction // ---------------------------------------------------------------------------- -void Layer::pushPendingState() { - if (!mCurrentState.modified) { - return; - } - ATRACE_CALL(); - - // If this transaction is waiting on the receipt of a frame, generate a sync - // point and send it to the remote layer. - // We don't allow installing sync points after we are removed from the current state - // as we won't be able to signal our end. - if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) { - sp barrierLayer = mCurrentState.barrierLayer_legacy.promote(); - if (barrierLayer == nullptr) { - ALOGE("[%s] Unable to promote barrier Layer.", getDebugName()); - // If we can't promote the layer we are intended to wait on, - // then it is expired or otherwise invalid. Allow this transaction - // to be applied as per normal (no synchronization). - mCurrentState.barrierLayer_legacy = nullptr; - } else { - auto syncPoint = std::make_shared(mCurrentState.barrierFrameNumber, this, - barrierLayer); - if (barrierLayer->addSyncPoint(syncPoint)) { - std::stringstream ss; - ss << "Adding sync point " << mCurrentState.barrierFrameNumber; - ATRACE_NAME(ss.str().c_str()); - mRemoteSyncPoints.push_back(std::move(syncPoint)); - } else { - // We already missed the frame we're supposed to synchronize - // on, so go ahead and apply the state update - mCurrentState.barrierLayer_legacy = nullptr; - } - } - - // Wake us up to check if the frame has been received - setTransactionFlags(eTransactionNeeded); - mFlinger->setTransactionFlags(eTraversalNeeded); - } - if (mCurrentState.bufferlessSurfaceFramesTX.size() >= State::kStateSurfaceFramesThreshold) { - // Ideally, the currentState would only contain one SurfaceFrame per transaction (assuming - // each Tx uses a different token). We don't expect the current state to hold a huge amount - // of SurfaceFrames. However, in the event it happens, this debug statement will leave a - // trail that can help in debugging. - ALOGW("Bufferless SurfaceFrames size on current state of layer %s is %" PRIu32 "", - mName.c_str(), static_cast(mCurrentState.bufferlessSurfaceFramesTX.size())); - } - mPendingStates.push_back(mCurrentState); - // Since the current state along with the SurfaceFrames has been pushed into the pendingState, - // we no longer need to retain them. If multiple states are pushed and applied together, we have - // a merging logic to address the SurfaceFrames at mergeSurfaceFrames(). - mCurrentState.bufferlessSurfaceFramesTX.clear(); - ATRACE_INT(mTransactionName.c_str(), mPendingStates.size()); -} - -void Layer::mergeSurfaceFrames(State& source, State& target) { - // No need to merge BufferSurfaceFrame as the target's surfaceFrame, if it exists, will be used - // directly. Dropping of source's SurfaceFrame is taken care of at setBuffer(). - target.bufferlessSurfaceFramesTX.merge(source.bufferlessSurfaceFramesTX); - source.bufferlessSurfaceFramesTX.clear(); -} - -void Layer::popPendingState(State* stateToCommit) { - ATRACE_CALL(); - - mergeSurfaceFrames(*stateToCommit, mPendingStates[0]); - *stateToCommit = mPendingStates[0]; - mPendingStates.pop_front(); - ATRACE_INT(mTransactionName.c_str(), mPendingStates.size()); -} - -bool Layer::applyPendingStates(State* stateToCommit) { - bool stateUpdateAvailable = false; - while (!mPendingStates.empty()) { - if (mPendingStates[0].barrierLayer_legacy != nullptr) { - if (mRemoteSyncPoints.empty()) { - // If we don't have a sync point for this, apply it anyway. It - // will be visually wrong, but it should keep us from getting - // into too much trouble. - ALOGV("[%s] No local sync point found", getDebugName()); - popPendingState(stateToCommit); - stateUpdateAvailable = true; - continue; - } - - if (mRemoteSyncPoints.front()->getFrameNumber() != - mPendingStates[0].barrierFrameNumber) { - ALOGE("[%s] Unexpected sync point frame number found", getDebugName()); - - // Signal our end of the sync point and then dispose of it - mRemoteSyncPoints.front()->setTransactionApplied(); - mRemoteSyncPoints.pop_front(); - continue; - } - - if (mRemoteSyncPoints.front()->frameIsAvailable()) { - ATRACE_NAME("frameIsAvailable"); - // Apply the state update - popPendingState(stateToCommit); - stateUpdateAvailable = true; - - // Signal our end of the sync point and then dispose of it - mRemoteSyncPoints.front()->setTransactionApplied(); - mRemoteSyncPoints.pop_front(); - } else { - ATRACE_NAME("!frameIsAvailable"); - mRemoteSyncPoints.front()->checkTimeoutAndLog(); - break; - } - } else { - popPendingState(stateToCommit); - stateUpdateAvailable = true; - } - } - - // If we still have pending updates, we need to ensure SurfaceFlinger - // will keep calling doTransaction, and so we force a traversal. - // However, our pending states won't clear until a frame is available, - // and so there is no need to specifically trigger a wakeup. - if (!mPendingStates.empty()) { - setTransactionFlags(eTransactionNeeded); - mFlinger->setTraversalNeeded(); - } - - mCurrentState.modified = false; - return stateUpdateAvailable; -} - uint32_t Layer::doTransactionResize(uint32_t flags, State* stateToCommit) { const State& s(getDrawingState()); @@ -1014,15 +845,14 @@ uint32_t Layer::doTransaction(uint32_t flags) { mChildrenChanged = false; } - pushPendingState(); - State c = getCurrentState(); - if (!applyPendingStates(&c)) { - return flags; - } + // TODO: This is unfortunate. + mCurrentStateModified = mCurrentState.modified; + mCurrentState.modified = false; - flags = doTransactionResize(flags, &c); + flags = doTransactionResize(flags, &mCurrentState); const State& s(getDrawingState()); + State& c(getCurrentState()); if (getActiveGeometry(c) != getActiveGeometry(s)) { // invalidate and recompute the visible regions if needed @@ -1054,7 +884,6 @@ uint32_t Layer::doTransaction(uint32_t flags) { // Commit the transaction commitTransaction(c); - mPendingStatesSnapshot = mPendingStates; mCurrentState.callbackHandles = {}; return flags; @@ -1662,25 +1491,6 @@ Layer::FrameRate Layer::getFrameRateForLayerTree() const { return frameRate; } -void Layer::deferTransactionUntil_legacy(const sp& barrierLayer, uint64_t frameNumber) { - ATRACE_CALL(); - - mCurrentState.barrierLayer_legacy = barrierLayer; - mCurrentState.barrierFrameNumber = frameNumber; - // We don't set eTransactionNeeded, because just receiving a deferral - // request without any other state updates shouldn't actually induce a delay - mCurrentState.modified = true; - pushPendingState(); - mCurrentState.barrierLayer_legacy = nullptr; - mCurrentState.barrierFrameNumber = 0; - mCurrentState.modified = false; -} - -void Layer::deferTransactionUntil_legacy(const sp& barrierHandle, uint64_t frameNumber) { - sp handle = static_cast(barrierHandle.get()); - deferTransactionUntil_legacy(handle->owner.promote(), frameNumber); -} - // ---------------------------------------------------------------------------- // pageflip handling... // ---------------------------------------------------------------------------- @@ -2362,14 +2172,6 @@ void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags, const ui::Transform transform = getTransform(); if (traceFlags & SurfaceTracing::TRACE_CRITICAL) { - for (const auto& pendingState : mPendingStatesSnapshot) { - auto barrierLayer = pendingState.barrierLayer_legacy.promote(); - if (barrierLayer != nullptr) { - BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer(); - barrierLayerProto->set_id(barrierLayer->sequence); - barrierLayerProto->set_frame_number(pendingState.barrierFrameNumber); - } - } auto buffer = getBuffer(); if (buffer != nullptr) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 5528a8190f..304eb36b9d 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -166,11 +166,6 @@ public: Rect crop; Rect requestedCrop; - // If set, defers this state update until the identified Layer - // receives a frame with the given frameNumber - wp barrierLayer_legacy; - uint64_t barrierFrameNumber; - // the transparentRegion hint is a bit special, it's latched only // when we receive a buffer -- this is because it's "content" // dependent. @@ -398,9 +393,6 @@ public: virtual bool setFlags(uint32_t flags, uint32_t mask); virtual bool setLayerStack(uint32_t layerStack); virtual uint32_t getLayerStack() const; - virtual void deferTransactionUntil_legacy(const sp& barrierHandle, - uint64_t frameNumber); - virtual void deferTransactionUntil_legacy(const sp& barrierLayer, uint64_t frameNumber); virtual bool setMetadata(const LayerMetadata& data); virtual void setChildrenDrawingParent(const sp&); virtual bool reparent(const sp& newParentHandle); @@ -578,14 +570,6 @@ public: virtual int32_t getQueuedFrameCount() const { return 0; } - virtual void pushPendingState(); - - /* - * Merges the BufferlessSurfaceFrames from source with the target. If the same token exists in - * both source and target, target's SurfaceFrame will be retained. - */ - void mergeSurfaceFrames(State& source, State& target); - /** * Returns active buffer size in the correct orientation. Buffer size is determined by undoing * any buffer transformations. If the layer has no buffer then return INVALID_RECT. @@ -615,7 +599,6 @@ public: // ignored. virtual RoundedCornerState getRoundedCornerState() const; - virtual void notifyAvailableFrames(nsecs_t /*expectedPresentTime*/) {} virtual PixelFormat getPixelFormat() const { return PIXEL_FORMAT_NONE; } /** * Return whether this layer needs an input info. For most layer types @@ -903,65 +886,6 @@ public: virtual std::string getPendingBufferCounterName() { return ""; } protected: - class SyncPoint { - public: - explicit SyncPoint(uint64_t frameNumber, wp requestedSyncLayer, - wp barrierLayer_legacy) - : mFrameNumber(frameNumber), - mFrameIsAvailable(false), - mTransactionIsApplied(false), - mRequestedSyncLayer(requestedSyncLayer), - mBarrierLayer_legacy(barrierLayer_legacy) {} - uint64_t getFrameNumber() const { return mFrameNumber; } - - bool frameIsAvailable() const { return mFrameIsAvailable; } - - void setFrameAvailable() { mFrameIsAvailable = true; } - - bool transactionIsApplied() const { return mTransactionIsApplied; } - - void setTransactionApplied() { mTransactionIsApplied = true; } - - sp getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); } - - sp getBarrierLayer() const { return mBarrierLayer_legacy.promote(); } - - bool isTimeout() const { - using namespace std::chrono_literals; - static constexpr std::chrono::nanoseconds TIMEOUT_THRESHOLD = 1s; - - return std::chrono::steady_clock::now() - mCreateTimeStamp > TIMEOUT_THRESHOLD; - } - - void checkTimeoutAndLog() { - using namespace std::chrono_literals; - static constexpr std::chrono::nanoseconds LOG_PERIOD = 1s; - - if (!frameIsAvailable() && isTimeout()) { - const auto now = std::chrono::steady_clock::now(); - if (now - mLastLogTime > LOG_PERIOD) { - mLastLogTime = now; - sp requestedSyncLayer = getRequestedSyncLayer(); - sp barrierLayer = getBarrierLayer(); - ALOGW("[%s] sync point %" PRIu64 " wait timeout %lld for %s", - requestedSyncLayer ? requestedSyncLayer->getDebugName() : "Removed", - mFrameNumber, (now - mCreateTimeStamp).count(), - barrierLayer ? barrierLayer->getDebugName() : "Removed"); - } - } - } - - private: - const uint64_t mFrameNumber; - std::atomic mFrameIsAvailable; - std::atomic mTransactionIsApplied; - wp mRequestedSyncLayer; - wp mBarrierLayer_legacy; - const std::chrono::time_point mCreateTimeStamp = - std::chrono::steady_clock::now(); - std::chrono::time_point mLastLogTime; - }; - friend class impl::SurfaceInterceptor; // For unit tests @@ -980,7 +904,6 @@ protected: ui::Dataspace outputDataspace); virtual void preparePerFrameCompositionState(); virtual void commitTransaction(State& stateToCommit); - virtual bool applyPendingStates(State* stateToCommit); virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit); virtual void onSurfaceFrameCreated(const std::shared_ptr&) {} @@ -1026,21 +949,6 @@ protected: virtual ui::Transform getInputTransform() const; virtual Rect getInputBounds() const; - // SyncPoints which will be signaled when the correct frame is at the head - // of the queue and dropped after the frame has been latched. Protected by - // mLocalSyncPointMutex. - Mutex mLocalSyncPointMutex; - std::list> mLocalSyncPoints; - - // SyncPoints which will be signaled and then dropped when the transaction - // is applied - std::list> mRemoteSyncPoints; - - // Returns false if the relevant frame has already been latched - bool addSyncPoint(const std::shared_ptr& point); - - void popPendingState(State* stateToCommit); - // constant sp mFlinger; @@ -1050,14 +958,10 @@ protected: // These are only accessed by the main thread or the tracing thread. State mDrawingState; - // Store a copy of the pending state so that the drawing thread can access the - // states without a lock. - std::deque mPendingStatesSnapshot; // these are protected by an external lock (mStateLock) State mCurrentState; std::atomic mTransactionFlags{0}; - std::deque mPendingStates; // Timestamp history for UIAutomation. Thread safe. FrameTracker mFrameTracker; @@ -1119,6 +1023,8 @@ protected: // Used in buffer stuffing analysis in FrameTimeline. nsecs_t mLastLatchTime = 0; + mutable bool mCurrentStateModified = false; + private: virtual void setTransformHint(ui::Transform::RotationFlags) {} @@ -1143,7 +1049,6 @@ private: void updateTreeHasFrameRateVote(); void setZOrderRelativeOf(const wp& relativeOf); - void removeRemoteSyncPoints(); // Find the root of the cloned hierarchy, this means the first non cloned parent. // This will return null if first non cloned parent is not found. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 02579c6bde..274d2833b2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2815,13 +2815,6 @@ void SurfaceFlinger::processDisplayChangesLocked() { } void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) { - const nsecs_t expectedPresentTime = mExpectedPresentTime.load(); - - // Notify all layers of available frames - mCurrentState.traverse([expectedPresentTime](Layer* layer) { - layer->notifyAvailableFrames(expectedPresentTime); - }); - /* * Traversal of the children * (perform the transaction for each of them if needed) @@ -3833,12 +3826,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( const uint64_t what = s.what; - // If we are deferring transaction, make sure to push the pending state, as otherwise the - // pending state will also be deferred. - if (what & layer_state_t::eDeferTransaction_legacy) { - layer->pushPendingState(); - } - // Only set by BLAST adapter layers if (what & layer_state_t::eProducerDisconnect) { layer->onDisconnect(); @@ -3973,12 +3960,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTransactionNeeded | eTraversalNeeded | eTransformHintUpdateNeeded; } } - if (what & layer_state_t::eDeferTransaction_legacy) { - layer->deferTransactionUntil_legacy(s.barrierSurfaceControl_legacy->getHandle(), - s.barrierFrameNumber); - // We don't trigger a traversal here because if no other state is - // changed, we don't want this to cause any more work - } if (what & layer_state_t::eTransformChanged) { if (layer->setTransform(s.transform)) flags |= eTraversalNeeded; } diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index b49562a0a5..113f463c39 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -141,11 +141,6 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius); addBackgroundBlurRadiusLocked(transaction, layerId, layer->mCurrentState.backgroundBlurRadius); addBlurRegionsLocked(transaction, layerId, layer->mCurrentState.blurRegions); - if (layer->mCurrentState.barrierLayer_legacy != nullptr) { - addDeferTransactionLocked(transaction, layerId, - layer->mCurrentState.barrierLayer_legacy.promote(), - layer->mCurrentState.barrierFrameNumber); - } addFlagsLocked(transaction, layerId, layer->mCurrentState.flags, layer_state_t::eLayerHidden | layer_state_t::eLayerOpaque | layer_state_t::eLayerSecure); @@ -380,20 +375,6 @@ void SurfaceInterceptor::addBlurRegionsLocked(Transaction* transaction, int32_t } } -void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId, - const sp& layer, uint64_t frameNumber) -{ - SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); - if (layer == nullptr) { - ALOGE("An existing layer could not be retrieved with the handle" - " for the deferred transaction"); - return; - } - DeferredTransactionChange* deferTransaction(change->mutable_deferred_transaction()); - deferTransaction->set_layer_id(getLayerId(layer)); - deferTransaction->set_frame_number(frameNumber); -} - void SurfaceInterceptor::addReparentLocked(Transaction* transaction, int32_t layerId, int32_t parentId) { SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); @@ -464,15 +445,6 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, if (state.what & layer_state_t::eBlurRegionsChanged) { addBlurRegionsLocked(transaction, layerId, state.blurRegions); } - if (state.what & layer_state_t::eDeferTransaction_legacy) { - sp otherLayer = nullptr; - if (state.barrierSurfaceControl_legacy != nullptr) { - otherLayer = static_cast( - state.barrierSurfaceControl_legacy->getHandle().get()) - ->owner.promote(); - } - addDeferTransactionLocked(transaction, layerId, otherLayer, state.barrierFrameNumber); - } if (state.what & layer_state_t::eReparent) { auto parentHandle = (state.parentSurfaceControlForChild) ? state.parentSurfaceControlForChild->getHandle() diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index d2cbf40426..30aca8340e 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -167,8 +167,6 @@ private: int32_t backgroundBlurRadius); void addBlurRegionsLocked(Transaction* transaction, int32_t layerId, const std::vector& effectRegions); - void addDeferTransactionLocked(Transaction* transaction, int32_t layerId, - const sp& layer, uint64_t frameNumber); void addSurfaceChangesLocked(Transaction* transaction, const layer_state_t& state); void addTransactionLocked(Increment* increment, const Vector& stateUpdates, const DefaultKeyedVector, DisplayDeviceState>& displays, diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp index 39d9206e1a..adb5d58e8c 100644 --- a/services/surfaceflinger/tests/LayerUpdate_test.cpp +++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp @@ -160,61 +160,6 @@ protected: } }; -TEST_F(LayerUpdateTest, DeferredTransactionTest) { - std::unique_ptr sc; - { - SCOPED_TRACE("before anything"); - ScreenCapture::captureScreen(&sc); - sc->expectBGColor(32, 32); - sc->expectFGColor(96, 96); - sc->expectBGColor(160, 160); - } - - // set up two deferred transactions on different frames - asTransaction([&](Transaction& t) { - t.setAlpha(mFGSurfaceControl, 0.75); - t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl, - mSyncSurfaceControl->getSurface()->getNextFrameNumber()); - }); - - asTransaction([&](Transaction& t) { - t.setPosition(mFGSurfaceControl, 128, 128); - t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl, - mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1); - }); - - { - SCOPED_TRACE("before any trigger"); - ScreenCapture::captureScreen(&sc); - sc->expectBGColor(32, 32); - sc->expectFGColor(96, 96); - sc->expectBGColor(160, 160); - } - - // should trigger the first deferred transaction, but not the second one - TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - { - SCOPED_TRACE("after first trigger"); - ScreenCapture::captureScreen(&sc); - sc->expectBGColor(32, 32); - sc->checkPixel(96, 96, 162, 63, 96); - sc->expectBGColor(160, 160); - } - - // should show up immediately since it's not deferred - asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 1.0); }); - - // trigger the second deferred transaction - TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); - { - SCOPED_TRACE("after second trigger"); - ScreenCapture::captureScreen(&sc); - sc->expectBGColor(32, 32); - sc->expectBGColor(96, 96); - sc->expectFGColor(160, 160); - } -} - TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) { std::unique_ptr sc; @@ -702,36 +647,6 @@ TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) { } } -TEST_F(ChildLayerTest, Bug36858924) { - // Destroy the child layer - mChild.clear(); - - // Now recreate it as hidden - mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eHidden, mFGSurfaceControl.get()); - - // Show the child layer in a deferred transaction - asTransaction([&](Transaction& t) { - t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl, - mFGSurfaceControl->getSurface()->getNextFrameNumber()); - t.show(mChild); - }); - - // Render the foreground surface a few times - // - // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third - // frame because SurfaceFlinger would never process the deferred transaction and would therefore - // never acquire/release the first buffer - ALOGI("Filling 1"); - TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0); - ALOGI("Filling 2"); - TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255); - ALOGI("Filling 3"); - TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0); - ALOGI("Filling 4"); - TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0); -} - TEST_F(ChildLayerTest, Reparent) { asTransaction([&](Transaction& t) { t.show(mChild); diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index 09bd775872..af23e2a9cc 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -44,7 +44,6 @@ constexpr uint32_t BUFFER_UPDATES = 18; constexpr uint32_t LAYER_UPDATE = INT_MAX - 2; constexpr uint32_t SIZE_UPDATE = 134; constexpr uint32_t STACK_UPDATE = 1; -constexpr uint64_t DEFERRED_UPDATE = 0; constexpr int32_t RELATIVE_Z = 42; constexpr float ALPHA_UPDATE = 0.29f; constexpr float CORNER_RADIUS_UPDATE = 0.2f; @@ -191,7 +190,6 @@ public: bool hiddenFlagUpdateFound(const SurfaceChange& change, bool foundHiddenFlag); bool opaqueFlagUpdateFound(const SurfaceChange& change, bool foundOpaqueFlag); bool secureFlagUpdateFound(const SurfaceChange& change, bool foundSecureFlag); - bool deferredTransactionUpdateFound(const SurfaceChange& change, bool foundDeferred); bool reparentUpdateFound(const SurfaceChange& change, bool found); bool relativeParentUpdateFound(const SurfaceChange& change, bool found); bool shadowRadiusUpdateFound(const SurfaceChange& change, bool found); @@ -227,7 +225,6 @@ public: void hiddenFlagUpdate(Transaction&); void opaqueFlagUpdate(Transaction&); void secureFlagUpdate(Transaction&); - void deferredTransactionUpdate(Transaction&); void reparentUpdate(Transaction&); void relativeParentUpdate(Transaction&); void shadowRadiusUpdate(Transaction&); @@ -396,10 +393,6 @@ void SurfaceInterceptorTest::secureFlagUpdate(Transaction& t) { t.setFlags(mBGSurfaceControl, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure); } -void SurfaceInterceptorTest::deferredTransactionUpdate(Transaction& t) { - t.deferTransactionUntil_legacy(mBGSurfaceControl, mBGSurfaceControl, DEFERRED_UPDATE); -} - void SurfaceInterceptorTest::reparentUpdate(Transaction& t) { t.reparent(mBGSurfaceControl, mFGSurfaceControl); } @@ -437,7 +430,6 @@ void SurfaceInterceptorTest::runAllUpdates() { runInTransaction(&SurfaceInterceptorTest::hiddenFlagUpdate); runInTransaction(&SurfaceInterceptorTest::opaqueFlagUpdate); runInTransaction(&SurfaceInterceptorTest::secureFlagUpdate); - runInTransaction(&SurfaceInterceptorTest::deferredTransactionUpdate); runInTransaction(&SurfaceInterceptorTest::reparentUpdate); runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate); runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate); @@ -621,18 +613,6 @@ bool SurfaceInterceptorTest::secureFlagUpdateFound(const SurfaceChange& change, return foundSecureFlag; } -bool SurfaceInterceptorTest::deferredTransactionUpdateFound(const SurfaceChange& change, - bool foundDeferred) { - bool hasId(change.deferred_transaction().layer_id() == mBGLayerId); - bool hasFrameNumber(change.deferred_transaction().frame_number() == DEFERRED_UPDATE); - if (hasId && hasFrameNumber && !foundDeferred) { - foundDeferred = true; - } else if (hasId && hasFrameNumber && foundDeferred) { - [] () { FAIL(); }(); - } - return foundDeferred; -} - bool SurfaceInterceptorTest::reparentUpdateFound(const SurfaceChange& change, bool found) { bool hasId(change.reparent().parent_id() == mFGLayerId); if (hasId && !found) { @@ -715,9 +695,6 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace, case SurfaceChange::SurfaceChangeCase::kSecureFlag: foundUpdate = secureFlagUpdateFound(change, foundUpdate); break; - case SurfaceChange::SurfaceChangeCase::kDeferredTransaction: - foundUpdate = deferredTransactionUpdateFound(change, foundUpdate); - break; case SurfaceChange::SurfaceChangeCase::kReparent: foundUpdate = reparentUpdateFound(change, foundUpdate); break; @@ -749,7 +726,6 @@ void SurfaceInterceptorTest::assertAllUpdatesFound(const Trace& trace) { ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kHiddenFlag)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kOpaqueFlag)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kSecureFlag)); - ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kDeferredTransaction)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kReparent)); ASSERT_TRUE(surfaceUpdateFound(trace, SurfaceChange::SurfaceChangeCase::kRelativeParent)); } @@ -906,11 +882,6 @@ TEST_F(SurfaceInterceptorTest, InterceptSecureFlagUpdateWorks) { SurfaceChange::SurfaceChangeCase::kSecureFlag); } -TEST_F(SurfaceInterceptorTest, InterceptDeferredTransactionUpdateWorks) { - captureTest(&SurfaceInterceptorTest::deferredTransactionUpdate, - SurfaceChange::SurfaceChangeCase::kDeferredTransaction); -} - TEST_F(SurfaceInterceptorTest, InterceptReparentUpdateWorks) { captureTest(&SurfaceInterceptorTest::reparentUpdate, SurfaceChange::SurfaceChangeCase::kReparent); diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index c081f9b642..eb31e2eca1 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -91,7 +91,6 @@ constexpr static TestColor RED = {195, 63, 63, 255}; constexpr static TestColor LIGHT_RED = {255, 177, 177, 255}; constexpr static TestColor GREEN = {63, 195, 63, 255}; constexpr static TestColor BLUE = {63, 63, 195, 255}; -constexpr static TestColor DARK_GRAY = {63, 63, 63, 255}; constexpr static TestColor LIGHT_GRAY = {200, 200, 200, 255}; // Fill an RGBA_8888 formatted surface with a single color. @@ -1469,77 +1468,6 @@ protected: } } - void Test_DeferredTransaction() { - // Synchronization surface - constexpr static int SYNC_LAYER = 2; - auto syncSurfaceControl = mComposerClient->createSurface(String8("Sync Test Surface"), 1, 1, - PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(syncSurfaceControl != nullptr); - ASSERT_TRUE(syncSurfaceControl->isValid()); - - fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY); - - { - 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, - mDisplayWidth - 1, mDisplayHeight - 1)); - referenceFrame[SYNC_LAYER].mSwapCount = 1; - EXPECT_EQ(2, sFakeComposer->getFrameCount()); - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - - // set up two deferred transactions on different frames - these should not yield composited - // frames - { - TransactionScope ts(*sFakeComposer); - ts.setAlpha(mFGSurfaceControl, 0.75); - ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl, - syncSurfaceControl->getSurface()->getNextFrameNumber()); - } - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*sFakeComposer); - ts.setPosition(mFGSurfaceControl, 128, 128); - ts.deferTransactionUntil_legacy(mFGSurfaceControl, syncSurfaceControl, - syncSurfaceControl->getSurface()->getNextFrameNumber() + - 1); - } - EXPECT_EQ(4, sFakeComposer->getFrameCount()); - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - - // should trigger the first deferred transaction, but not the second one - fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY); - sFakeComposer->runVSyncAndWait(); - EXPECT_EQ(5, sFakeComposer->getFrameCount()); - - referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f; - referenceFrame[SYNC_LAYER].mSwapCount++; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - - // should show up immediately since it's not deferred - { - TransactionScope ts(*sFakeComposer); - ts.setAlpha(mFGSurfaceControl, 1.0); - } - referenceFrame[FG_LAYER].mPlaneAlpha = 1.f; - EXPECT_EQ(6, sFakeComposer->getFrameCount()); - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - - // trigger the second deferred transaction - fillSurfaceRGBA8(syncSurfaceControl, DARK_GRAY); - sFakeComposer->runVSyncAndWait(); - // TODO: Compute from layer size? - referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{128, 128, 128 + 64, 128 + 64}; - referenceFrame[SYNC_LAYER].mSwapCount++; - EXPECT_EQ(7, sFakeComposer->getFrameCount()); - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - } - void Test_SetRelativeLayer() { constexpr int RELATIVE_LAYER = 2; auto relativeSurfaceControl = mComposerClient->createSurface(String8("Test Surface"), 64, @@ -1625,10 +1553,6 @@ TEST_F(TransactionTest_2_1, DISABLED_LayerSetMatrix) { Test_LayerSetMatrix(); } -TEST_F(TransactionTest_2_1, DISABLED_DeferredTransaction) { - Test_DeferredTransaction(); -} - TEST_F(TransactionTest_2_1, DISABLED_SetRelativeLayer) { Test_SetRelativeLayer(); } @@ -1799,44 +1723,6 @@ protected: EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); } - void Test_Bug36858924() { - // Destroy the child layer - mChild.clear(); - - // Now recreate it as hidden - mChild = Base::mComposerClient->createSurface(String8("Child surface"), 10, 10, - PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eHidden, - Base::mFGSurfaceControl->getHandle()); - - // Show the child layer in a deferred transaction - { - TransactionScope ts(*Base::sFakeComposer); - ts.deferTransactionUntil_legacy(mChild, Base::mFGSurfaceControl, - Base::mFGSurfaceControl->getSurface() - ->getNextFrameNumber()); - ts.show(mChild); - } - - // Render the foreground surface a few times - // - // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the - // third frame because SurfaceFlinger would never process the deferred transaction and would - // therefore never acquire/release the first buffer - ALOGI("Filling 1"); - fillSurfaceRGBA8(Base::mFGSurfaceControl, GREEN); - Base::sFakeComposer->runVSyncAndWait(); - ALOGI("Filling 2"); - fillSurfaceRGBA8(Base::mFGSurfaceControl, BLUE); - Base::sFakeComposer->runVSyncAndWait(); - ALOGI("Filling 3"); - fillSurfaceRGBA8(Base::mFGSurfaceControl, RED); - Base::sFakeComposer->runVSyncAndWait(); - ALOGI("Filling 4"); - fillSurfaceRGBA8(Base::mFGSurfaceControl, GREEN); - Base::sFakeComposer->runVSyncAndWait(); - } - sp mChild; }; @@ -1867,10 +1753,6 @@ TEST_F(ChildLayerTest_2_1, DISABLED_ChildrenWithParentBufferTransform) { Test_ChildrenWithParentBufferTransform(); } -TEST_F(ChildLayerTest_2_1, DISABLED_Bug36858924) { - Test_Bug36858924(); -} - template class ChildColorLayerTest : public ChildLayerTest { using Base = ChildLayerTest; diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp index abecd4b45b..9c6ad06e1d 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp @@ -118,11 +118,8 @@ void RefreshRateSelectionTest::setParent(Layer* child, Layer* parent) { } void RefreshRateSelectionTest::commitTransaction(Layer* layer) { - layer->pushPendingState(); auto c = layer->getCurrentState(); - if (layer->applyPendingStates(&c)) { - layer->commitTransaction(c); - } + layer->commitTransaction(c); } void RefreshRateSelectionTest::setupScheduler() { diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp index 0bb7e31194..c088ddc971 100644 --- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp +++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp @@ -153,11 +153,8 @@ void SetFrameRateTest::removeChild(sp layer, sp child) { void SetFrameRateTest::commitTransaction() { for (auto layer : mLayers) { - layer->pushPendingState(); auto c = layer->getCurrentState(); - if (layer->applyPendingStates(&c)) { - layer->commitTransaction(c); - } + layer->commitTransaction(c); } } diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp index b5ef0a1334..ea1ce47b70 100644 --- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp @@ -60,11 +60,8 @@ public: } void commitTransaction(Layer* layer) { - layer->pushPendingState(); auto c = layer->getCurrentState(); - if (layer->applyPendingStates(&c)) { - layer->commitTransaction(c); - } + layer->commitTransaction(c); } void setupScheduler() { @@ -151,4 +148,4 @@ TEST_F(TransactionFrameTracerTest, BLASTTransactionSendsFrameTracerEvents) { BLASTTransactionSendsFrameTracerEvents(); } -} // namespace android \ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp index c75538f476..09a1c2af75 100644 --- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp @@ -60,13 +60,8 @@ public: } void commitTransaction(Layer* layer) { - layer->pushPendingState(); - // After pushing the state, the currentState should not store any BufferlessSurfaceFrames - EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); auto c = layer->getCurrentState(); - if (layer->applyPendingStates(&c)) { - layer->commitTransaction(c); - } + layer->commitTransaction(c); } void setupScheduler() { @@ -283,69 +278,6 @@ public: EXPECT_EQ(PresentState::Presented, bufferSurfaceFrameTX->getPresentState()); } - void MergePendingStates_BufferlessSurfaceFramesWithoutOverlappingToken() { - sp layer = createBufferStateLayer(); - layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, - 10); - EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); - ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); - const auto bufferlessSurfaceFrame1 = - layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*token*/ 1); - - layer->pushPendingState(); - EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); - - layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 2, /*inputEventId*/ 0}, - 12); - EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); - ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); - const auto bufferlessSurfaceFrame2 = - layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*token*/ 2); - - commitTransaction(layer.get()); - - EXPECT_EQ(1, bufferlessSurfaceFrame1->getToken()); - EXPECT_EQ(false, bufferlessSurfaceFrame1->getIsBuffer()); - EXPECT_EQ(PresentState::Presented, bufferlessSurfaceFrame1->getPresentState()); - EXPECT_EQ(10, bufferlessSurfaceFrame1->getActuals().endTime); - - EXPECT_EQ(2, bufferlessSurfaceFrame2->getToken()); - EXPECT_EQ(false, bufferlessSurfaceFrame2->getIsBuffer()); - EXPECT_EQ(PresentState::Presented, bufferlessSurfaceFrame2->getPresentState()); - EXPECT_EQ(12, bufferlessSurfaceFrame2->getActuals().endTime); - } - - void MergePendingStates_BufferlessSurfaceFramesWithOverlappingToken() { - sp layer = createBufferStateLayer(); - layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, - 10); - EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); - ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); - const auto bufferlessSurfaceFrame1 = - layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*token*/ 1); - - layer->pushPendingState(); - EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); - - layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, - 12); - EXPECT_EQ(1u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); - ASSERT_EQ(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); - const auto bufferlessSurfaceFrame2 = - layer->mCurrentState.bufferlessSurfaceFramesTX.at(/*token*/ 1); - - commitTransaction(layer.get()); - - EXPECT_EQ(1, bufferlessSurfaceFrame1->getToken()); - EXPECT_EQ(false, bufferlessSurfaceFrame1->getIsBuffer()); - EXPECT_EQ(PresentState::Unknown, bufferlessSurfaceFrame1->getPresentState()); - - EXPECT_EQ(1, bufferlessSurfaceFrame2->getToken()); - EXPECT_EQ(false, bufferlessSurfaceFrame2->getIsBuffer()); - EXPECT_EQ(PresentState::Presented, bufferlessSurfaceFrame2->getPresentState()); - EXPECT_EQ(12, bufferlessSurfaceFrame2->getActuals().endTime); - } - void PendingSurfaceFramesRemovedAfterClassification() { sp layer = createBufferStateLayer(); @@ -529,16 +461,6 @@ TEST_F(TransactionSurfaceFrameTest, MultipleSurfaceFramesPresentedTogether) { MultipleSurfaceFramesPresentedTogether(); } -TEST_F(TransactionSurfaceFrameTest, - MergePendingStates_BufferlessSurfaceFramesWithoutOverlappingToken) { - MergePendingStates_BufferlessSurfaceFramesWithoutOverlappingToken(); -} - -TEST_F(TransactionSurfaceFrameTest, - MergePendingStates_BufferlessSurfaceFramesWithOverlappingToken) { - MergePendingStates_BufferlessSurfaceFramesWithOverlappingToken(); -} - TEST_F(TransactionSurfaceFrameTest, PendingSurfaceFramesRemovedAfterClassification) { PendingSurfaceFramesRemovedAfterClassification(); } @@ -552,4 +474,4 @@ TEST_F(TransactionSurfaceFrameTest, MultipleCommitsBeforeLatch) { MultipleCommitsBeforeLatch(); } -} // namespace android \ No newline at end of file +} // namespace android -- cgit v1.2.3-59-g8ed1b From fc46c1e6e58ff5acdc72feea409e4aa03f978be9 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 21 Apr 2021 08:31:32 -0700 Subject: Introduce ASurfaceTransaction_setOnCommit api Introduce a new callback for SurfaceControl transactions that fire after we commit a transaction in SurfaceFlinger. This will help some clients pace when they should apply the next transaction so it get applied on the next vsync. If they wait for the existing transaction complete callback, there may not be enough time between when the client applies the transaction and surface flinger waking up and apply it on the new vsync. This would mean the update would arrive a frame late. This callback is guaranteed to fire before the transaction complete callback. It includes all the stats as the transaction complete callback with the exception of jank data, present fence and the previous buffer release fence. This callback piggybacks of the oncomplete callback implementation by modifying the callback id to provide a callback type. The callbacks are filtered in SurfaceFlinger to invoke them earlier. In SurfaceComposerClient, they are filtered again to make sure the callbacks are invoked in order, oncommit before oncomplete. Bug: 185843251 Test: atest ASurfaceControlTest Change-Id: I57e85d75214376935e366d3825a6f3f1a8a4e79b --- include/android/surface_control.h | 36 +++++++++ libs/gui/ISurfaceComposer.cpp | 4 +- libs/gui/ITransactionCompletedListener.cpp | 33 +++++++- libs/gui/LayerState.cpp | 4 +- libs/gui/SurfaceComposerClient.cpp | 68 +++++++++++++--- .../include/gui/ITransactionCompletedListener.h | 34 ++++++-- libs/gui/include/gui/SurfaceComposerClient.h | 24 ++++-- services/surfaceflinger/BufferStateLayer.cpp | 5 ++ services/surfaceflinger/SurfaceFlinger.cpp | 29 +++++-- .../surfaceflinger/TransactionCallbackInvoker.cpp | 91 +++++++++++++++------- .../surfaceflinger/TransactionCallbackInvoker.h | 5 ++ 11 files changed, 265 insertions(+), 68 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/include/android/surface_control.h b/include/android/surface_control.h index c349024839..b7eafcd6cd 100644 --- a/include/android/surface_control.h +++ b/include/android/surface_control.h @@ -147,6 +147,28 @@ typedef struct ASurfaceTransactionStats ASurfaceTransactionStats; typedef void (*ASurfaceTransaction_OnComplete)(void* context, ASurfaceTransactionStats* stats) __INTRODUCED_IN(29); + +/** + * The ASurfaceTransaction_OnCommit callback is invoked when transaction is applied and the updates + * are ready to be presented. This callback will be invoked before the + * ASurfaceTransaction_OnComplete callback. + * + * \param context Optional context provided by the client that is passed into the callback. + * + * \param stats Opaque handle that can be passed to ASurfaceTransactionStats functions to query + * information about the transaction. The handle is only valid during the callback. + * Present and release fences are not available for this callback. Querying them using + * ASurfaceTransactionStats_getPresentFenceFd and ASurfaceTransactionStats_getPreviousReleaseFenceFd + * will result in failure. + * + * THREADING + * The transaction committed callback can be invoked on any thread. + * + * Available since API level 31. + */ +typedef void (*ASurfaceTransaction_OnCommit)(void* context, ASurfaceTransactionStats* stats) + __INTRODUCED_IN(31); + /** * Returns the timestamp of when the frame was latched by the framework. Once a frame is * latched by the framework, it is presented at the following hardware vsync. @@ -161,6 +183,8 @@ int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* surface_ * The recipient of the callback takes ownership of the fence and is responsible for closing * it. If a device does not support present fences, a -1 will be returned. * + * This query is not valid for ASurfaceTransaction_OnCommit callback. + * * Available since API level 29. */ int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* surface_transaction_stats) @@ -218,6 +242,8 @@ int64_t ASurfaceTransactionStats_getAcquireTime(ASurfaceTransactionStats* surfac * The client must ensure that all pending refs on a buffer are released before attempting to reuse * this buffer, otherwise synchronization errors may occur. * + * This query is not valid for ASurfaceTransaction_OnCommit callback. + * * Available since API level 29. */ int ASurfaceTransactionStats_getPreviousReleaseFenceFd( @@ -235,6 +261,16 @@ int ASurfaceTransactionStats_getPreviousReleaseFenceFd( void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* transaction, void* context, ASurfaceTransaction_OnComplete func) __INTRODUCED_IN(29); +/** + * Sets the callback that will be invoked when the updates from this transaction are applied and are + * ready to be presented. This callback will be invoked before the ASurfaceTransaction_OnComplete + * callback. + * + * Available since API level 31. + */ +void ASurfaceTransaction_setOnCommit(ASurfaceTransaction* transaction, void* context, + ASurfaceTransaction_OnCommit func) __INTRODUCED_IN(31); + /** * Reparents the \a surface_control from its old parent to the \a new_parent surface control. * Any children of the reparented \a surface_control will remain children of the \a surface_control. diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 454aa9eb7b..0e28966a9b 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -99,7 +99,7 @@ public: SAFE_PARCEL(data.writeVectorSize, listenerCallbacks); for (const auto& [listener, callbackIds] : listenerCallbacks) { SAFE_PARCEL(data.writeStrongBinder, listener); - SAFE_PARCEL(data.writeInt64Vector, callbackIds); + SAFE_PARCEL(data.writeParcelableVector, callbackIds); } SAFE_PARCEL(data.writeUint64, transactionId); @@ -1246,7 +1246,7 @@ status_t BnSurfaceComposer::onTransact( for (int32_t i = 0; i < listenersSize; i++) { SAFE_PARCEL(data.readStrongBinder, &tmpBinder); std::vector callbackIds; - SAFE_PARCEL(data.readInt64Vector, &callbackIds); + SAFE_PARCEL(data.readParcelableVector, &callbackIds); listenerCallbacks.emplace_back(tmpBinder, callbackIds); } diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp index b42793b8ac..f74f91e034 100644 --- a/libs/gui/ITransactionCompletedListener.cpp +++ b/libs/gui/ITransactionCompletedListener.cpp @@ -152,7 +152,7 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) { } status_t TransactionStats::writeToParcel(Parcel* output) const { - status_t err = output->writeInt64Vector(callbackIds); + status_t err = output->writeParcelableVector(callbackIds); if (err != NO_ERROR) { return err; } @@ -176,7 +176,7 @@ status_t TransactionStats::writeToParcel(Parcel* output) const { } status_t TransactionStats::readFromParcel(const Parcel* input) { - status_t err = input->readInt64Vector(&callbackIds); + status_t err = input->readParcelableVector(&callbackIds); if (err != NO_ERROR) { return err; } @@ -227,8 +227,9 @@ status_t ListenerStats::readFromParcel(const Parcel* input) { return NO_ERROR; } -ListenerStats ListenerStats::createEmpty(const sp& listener, - const std::unordered_set& callbackIds) { +ListenerStats ListenerStats::createEmpty( + const sp& listener, + const std::unordered_set& callbackIds) { ListenerStats listenerStats; listenerStats.listener = listener; listenerStats.transactionStats.emplace_back(callbackIds); @@ -278,4 +279,28 @@ status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel& } } +ListenerCallbacks ListenerCallbacks::filter(CallbackId::Type type) const { + std::vector filteredCallbackIds; + for (const auto& callbackId : callbackIds) { + if (callbackId.type == type) { + filteredCallbackIds.push_back(callbackId); + } + } + return ListenerCallbacks(transactionCompletedListener, filteredCallbackIds); +} + +status_t CallbackId::writeToParcel(Parcel* output) const { + SAFE_PARCEL(output->writeInt64, id); + SAFE_PARCEL(output->writeInt32, static_cast(type)); + return NO_ERROR; +} + +status_t CallbackId::readFromParcel(const Parcel* input) { + SAFE_PARCEL(input->readInt64, &id); + int32_t typeAsInt; + SAFE_PARCEL(input->readInt32, &typeAsInt); + type = static_cast(typeAsInt); + return NO_ERROR; +} + }; // namespace android diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 55ed7fe298..517b49e6b5 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -140,7 +140,7 @@ status_t layer_state_t::write(Parcel& output) const for (auto listener : listeners) { SAFE_PARCEL(output.writeStrongBinder, listener.transactionCompletedListener); - SAFE_PARCEL(output.writeInt64Vector, listener.callbackIds); + SAFE_PARCEL(output.writeParcelableVector, listener.callbackIds); } SAFE_PARCEL(output.writeFloat, shadowRadius); SAFE_PARCEL(output.writeInt32, frameRateSelectionPriority); @@ -258,7 +258,7 @@ status_t layer_state_t::read(const Parcel& input) sp listener; std::vector callbackIds; SAFE_PARCEL(input.readNullableStrongBinder, &listener); - SAFE_PARCEL(input.readInt64Vector, &callbackIds); + SAFE_PARCEL(input.readParcelableVector, &callbackIds); listeners.emplace_back(listener, callbackIds); } SAFE_PARCEL(input.readFloat, &shadowRadius); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6d198a105f..49a10300b8 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -139,7 +139,7 @@ JankDataListener::~JankDataListener() { // 0 is an invalid callback id TransactionCompletedListener::TransactionCompletedListener() : mCallbackIdCounter(1) {} -CallbackId TransactionCompletedListener::getNextIdLocked() { +int64_t TransactionCompletedListener::getNextIdLocked() { return mCallbackIdCounter++; } @@ -163,13 +163,13 @@ void TransactionCompletedListener::startListeningLocked() { CallbackId TransactionCompletedListener::addCallbackFunction( const TransactionCompletedCallback& callbackFunction, const std::unordered_set, SurfaceComposerClient::SCHash>& - surfaceControls) { + surfaceControls, + CallbackId::Type callbackType) { std::lock_guard lock(mMutex); startListeningLocked(); - CallbackId callbackId = getNextIdLocked(); + CallbackId callbackId(getNextIdLocked(), callbackType); mCallbacks[callbackId].callbackFunction = callbackFunction; - auto& callbackSurfaceControls = mCallbacks[callbackId].surfaceControls; for (const auto& surfaceControl : surfaceControls) { @@ -228,7 +228,7 @@ void TransactionCompletedListener::removeSurfaceStatsListener(void* context, voi void TransactionCompletedListener::addSurfaceControlToCallbacks( const sp& surfaceControl, - const std::unordered_set& callbackIds) { + const std::unordered_set& callbackIds) { std::lock_guard lock(mMutex); for (auto callbackId : callbackIds) { @@ -240,7 +240,7 @@ void TransactionCompletedListener::addSurfaceControlToCallbacks( } void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { - std::unordered_map callbacksMap; + std::unordered_map callbacksMap; std::multimap, sp> jankListenersMap; std::multimap, SurfaceStatsCallbackEntry> surfaceListeners; { @@ -267,7 +267,36 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } } for (const auto& transactionStats : listenerStats.transactionStats) { + // handle on commit callbacks + for (auto callbackId : transactionStats.callbackIds) { + if (callbackId.type != CallbackId::Type::ON_COMMIT) { + continue; + } + auto& [callbackFunction, callbackSurfaceControls] = callbacksMap[callbackId]; + if (!callbackFunction) { + ALOGE("cannot call null callback function, skipping"); + continue; + } + std::vector surfaceControlStats; + for (const auto& surfaceStats : transactionStats.surfaceStats) { + surfaceControlStats + .emplace_back(callbacksMap[callbackId] + .surfaceControls[surfaceStats.surfaceControl], + transactionStats.latchTime, surfaceStats.acquireTime, + transactionStats.presentFence, + surfaceStats.previousReleaseFence, surfaceStats.transformHint, + surfaceStats.eventStats); + } + + callbackFunction(transactionStats.latchTime, transactionStats.presentFence, + surfaceControlStats); + } + + // handle on complete callbacks for (auto callbackId : transactionStats.callbackIds) { + if (callbackId.type != CallbackId::Type::ON_COMPLETE) { + continue; + } auto& [callbackFunction, callbackSurfaceControls] = callbacksMap[callbackId]; if (!callbackFunction) { ALOGE("cannot call null callback function, skipping"); @@ -542,7 +571,9 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel return BAD_VALUE; } for (size_t j = 0; j < numCallbackIds; j++) { - listenerCallbacks[listener].callbackIds.insert(parcel->readInt64()); + CallbackId id; + parcel->readParcelable(&id); + listenerCallbacks[listener].callbackIds.insert(id); } size_t numSurfaces = parcel->readUint32(); if (numSurfaces > parcel->dataSize()) { @@ -628,7 +659,7 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const parcel->writeStrongBinder(ITransactionCompletedListener::asBinder(listener)); parcel->writeUint32(static_cast(callbackInfo.callbackIds.size())); for (auto callbackId : callbackInfo.callbackIds) { - parcel->writeInt64(callbackId); + parcel->writeParcelable(callbackId); } parcel->writeUint32(static_cast(callbackInfo.surfaceControls.size())); for (auto surfaceControl : callbackInfo.surfaceControls) { @@ -1389,9 +1420,9 @@ SurfaceComposerClient::Transaction::setFrameRateSelectionPriority(const spaddCallbackFunction(callbackWithContext, surfaceControls); + CallbackId callbackId = + listener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType); mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( callbackId); return *this; } +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::addTransactionCompletedCallback( + TransactionCompletedCallbackTakesContext callback, void* callbackContext) { + return addTransactionCallback(callback, callbackContext, CallbackId::Type::ON_COMPLETE); +} + +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::addTransactionCommittedCallback( + TransactionCompletedCallbackTakesContext callback, void* callbackContext) { + return addTransactionCallback(callback, callbackContext, CallbackId::Type::ON_COMMIT); +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::notifyProducerDisconnect( const sp& sc) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h index 098760e89d..2d71194f70 100644 --- a/libs/gui/include/gui/ITransactionCompletedListener.h +++ b/libs/gui/include/gui/ITransactionCompletedListener.h @@ -36,7 +36,22 @@ namespace android { class ITransactionCompletedListener; class ListenerCallbacks; -using CallbackId = int64_t; +class CallbackId : public Parcelable { +public: + int64_t id; + enum class Type : int32_t { ON_COMPLETE, ON_COMMIT } type; + + CallbackId() {} + CallbackId(int64_t id, Type type) : id(id), type(type) {} + status_t writeToParcel(Parcel* output) const override; + status_t readFromParcel(const Parcel* input) override; + + bool operator==(const CallbackId& rhs) const { return id == rhs.id && type == rhs.type; } +}; + +struct CallbackIdHash { + std::size_t operator()(const CallbackId& key) const { return std::hash()(key.id); } +}; class FrameEventHistoryStats : public Parcelable { public: @@ -112,7 +127,7 @@ public: TransactionStats() = default; TransactionStats(const std::vector& ids) : callbackIds(ids) {} - TransactionStats(const std::unordered_set& ids) + TransactionStats(const std::unordered_set& ids) : callbackIds(ids.begin(), ids.end()) {} TransactionStats(const std::vector& ids, nsecs_t latch, const sp& present, const std::vector& surfaces) @@ -129,8 +144,9 @@ public: status_t writeToParcel(Parcel* output) const override; status_t readFromParcel(const Parcel* input) override; - static ListenerStats createEmpty(const sp& listener, - const std::unordered_set& callbackIds); + static ListenerStats createEmpty( + const sp& listener, + const std::unordered_set& callbackIds); sp listener; std::vector transactionStats; @@ -156,7 +172,8 @@ public: class ListenerCallbacks { public: - ListenerCallbacks(const sp& listener, const std::unordered_set& callbacks) + ListenerCallbacks(const sp& listener, + const std::unordered_set& callbacks) : transactionCompletedListener(listener), callbackIds(callbacks.begin(), callbacks.end()) {} @@ -170,9 +187,12 @@ public: if (callbackIds.empty()) { return rhs.callbackIds.empty(); } - return callbackIds.front() == rhs.callbackIds.front(); + return callbackIds.front().id == rhs.callbackIds.front().id; } + // Returns a new ListenerCallbacks filtered by type + ListenerCallbacks filter(CallbackId::Type type) const; + sp transactionCompletedListener; std::vector callbackIds; }; @@ -191,7 +211,7 @@ struct CallbackIdsHash { // same members. It is sufficient to just check the first CallbackId in the vectors. If // they match, they are the same. If they do not match, they are not the same. std::size_t operator()(const std::vector& callbackIds) const { - return std::hash{}((callbackIds.empty()) ? 0 : callbackIds.front()); + return std::hash{}((callbackIds.empty()) ? 0 : callbackIds.front().id); } }; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index fe6a30aa42..171c05e0c5 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -336,7 +336,7 @@ public: struct CallbackInfo { // All the callbacks that have been requested for a TransactionCompletedListener in the // Transaction - std::unordered_set callbackIds; + std::unordered_set callbackIds; // All the SurfaceControls that have been modified in this TransactionCompletedListener's // process that require a callback if there is one or more callbackIds set. std::unordered_set, SCHash> surfaceControls; @@ -484,9 +484,15 @@ public: // Sets information about the priority of the frame. Transaction& setFrameRateSelectionPriority(const sp& sc, int32_t priority); + Transaction& addTransactionCallback(TransactionCompletedCallbackTakesContext callback, + void* callbackContext, CallbackId::Type callbackType); + Transaction& addTransactionCompletedCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext); + Transaction& addTransactionCommittedCallback( + TransactionCompletedCallbackTakesContext callback, void* callbackContext); + // ONLY FOR BLAST ADAPTER Transaction& notifyProducerDisconnect(const sp& sc); // Set the framenumber generated by the graphics producer to mimic BufferQueue behaviour. @@ -619,14 +625,13 @@ public: class TransactionCompletedListener : public BnTransactionCompletedListener { TransactionCompletedListener(); - CallbackId getNextIdLocked() REQUIRES(mMutex); + int64_t getNextIdLocked() REQUIRES(mMutex); std::mutex mMutex; bool mListening GUARDED_BY(mMutex) = false; - CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1; - + int64_t mCallbackIdCounter GUARDED_BY(mMutex) = 1; struct CallbackTranslation { TransactionCompletedCallback callbackFunction; std::unordered_map, sp, SurfaceComposerClient::IBinderHash> @@ -644,7 +649,8 @@ class TransactionCompletedListener : public BnTransactionCompletedListener { SurfaceStatsCallback callback; }; - std::unordered_map mCallbacks GUARDED_BY(mMutex); + std::unordered_map mCallbacks + GUARDED_BY(mMutex); std::multimap, sp> mJankListeners GUARDED_BY(mMutex); std::unordered_map mReleaseBufferCallbacks GUARDED_BY(mMutex); @@ -660,10 +666,12 @@ public: CallbackId addCallbackFunction( const TransactionCompletedCallback& callbackFunction, const std::unordered_set, SurfaceComposerClient::SCHash>& - surfaceControls); + surfaceControls, + CallbackId::Type callbackType); - void addSurfaceControlToCallbacks(const sp& surfaceControl, - const std::unordered_set& callbackIds); + void addSurfaceControlToCallbacks( + const sp& surfaceControl, + const std::unordered_set& callbackIds); /* * Adds a jank listener to be informed about SurfaceFlinger's jank classification for a specific diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index ac2edbe717..627ff53abf 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -674,6 +674,11 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse latchTime); } + std::deque> remainingHandles; + mFlinger->getTransactionCallbackInvoker() + .finalizeOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles); + mDrawingState.callbackHandles = remainingHandles; + mCurrentStateModified = false; return NO_ERROR; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5f5987f8a3..8e2d5e5253 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2029,6 +2029,9 @@ bool SurfaceFlinger::handleMessageInvalidate() { ATRACE_CALL(); bool refreshNeeded = handlePageFlip(); + // Send on commit callbacks + mTransactionCallbackInvoker.sendCallbacks(); + if (mVisibleRegionsDirty) { computeLayerBounds(); } @@ -3789,14 +3792,30 @@ bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermis uint32_t SurfaceFlinger::setClientStateLocked( const FrameTimelineInfo& frameTimelineInfo, const ComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint32_t permissions, - std::unordered_set& listenerCallbacks) { + std::unordered_set& outListenerCallbacks) { const layer_state_t& s = composerState.state; const bool privileged = permissions & Permission::ACCESS_SURFACE_FLINGER; + + std::vector filteredListeners; for (auto& listener : s.listeners) { + // Starts a registration but separates the callback ids according to callback type. This + // allows the callback invoker to send on latch callbacks earlier. // note that startRegistration will not re-register if the listener has // already be registered for a prior surface control - mTransactionCallbackInvoker.startRegistration(listener); - listenerCallbacks.insert(listener); + + ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT); + if (!onCommitCallbacks.callbackIds.empty()) { + mTransactionCallbackInvoker.startRegistration(onCommitCallbacks); + filteredListeners.push_back(onCommitCallbacks); + outListenerCallbacks.insert(onCommitCallbacks); + } + + ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE); + if (!onCompleteCallbacks.callbackIds.empty()) { + mTransactionCallbackInvoker.startRegistration(onCompleteCallbacks); + filteredListeners.push_back(onCompleteCallbacks); + outListenerCallbacks.insert(onCompleteCallbacks); + } } sp layer = nullptr; @@ -4049,8 +4068,8 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } std::vector> callbackHandles; - if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!s.listeners.empty())) { - for (auto& [listener, callbackIds] : s.listeners) { + if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) { + for (auto& [listener, callbackIds] : filteredListeners) { callbackHandles.emplace_back(new CallbackHandle(listener, callbackIds, s.surface)); } } diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp index 3590e76cb9..4f4c02be6c 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.cpp +++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp @@ -36,13 +36,17 @@ namespace android { // <0 if the first id that doesn't match is lower in c2 or all ids match but c2 is shorter // >0 if the first id that doesn't match is greater in c2 or all ids match but c2 is longer // -// See CallbackIdsHash for a explaniation of why this works +// See CallbackIdsHash for a explanation of why this works static int compareCallbackIds(const std::vector& c1, const std::vector& c2) { if (c1.empty()) { return !c2.empty(); } - return c1.front() - c2.front(); + return c1.front().id - c2.front().id; +} + +static bool containsOnCommitCallbacks(const std::vector& callbacks) { + return !callbacks.empty() && callbacks.front().type == CallbackId::Type::ON_COMMIT; } TransactionCallbackInvoker::~TransactionCallbackInvoker() { @@ -114,39 +118,69 @@ status_t TransactionCallbackInvoker::registerPendingCallbackHandle( return NO_ERROR; } -status_t TransactionCallbackInvoker::finalizePendingCallbackHandles( - const std::deque>& handles, const std::vector& jankData) { +status_t TransactionCallbackInvoker::finalizeCallbackHandle(const sp& handle, + const std::vector& jankData) { + auto listener = mPendingTransactions.find(handle->listener); + if (listener != mPendingTransactions.end()) { + auto& pendingCallbacks = listener->second; + auto pendingCallback = pendingCallbacks.find(handle->callbackIds); + + if (pendingCallback != pendingCallbacks.end()) { + auto& pendingCount = pendingCallback->second; + + // Decrease the pending count for this listener + if (--pendingCount == 0) { + pendingCallbacks.erase(pendingCallback); + } + } else { + ALOGW("there are more latched callbacks than there were registered callbacks"); + } + if (listener->second.size() == 0) { + mPendingTransactions.erase(listener); + } + } else { + ALOGW("cannot find listener in mPendingTransactions"); + } + + status_t err = addCallbackHandle(handle, jankData); + if (err != NO_ERROR) { + ALOGE("could not add callback handle"); + return err; + } + return NO_ERROR; +} + +status_t TransactionCallbackInvoker::finalizeOnCommitCallbackHandles( + const std::deque>& handles, + std::deque>& outRemainingHandles) { if (handles.empty()) { return NO_ERROR; } std::lock_guard lock(mMutex); - + const std::vector& jankData = std::vector(); for (const auto& handle : handles) { - auto listener = mPendingTransactions.find(handle->listener); - if (listener != mPendingTransactions.end()) { - auto& pendingCallbacks = listener->second; - auto pendingCallback = pendingCallbacks.find(handle->callbackIds); - - if (pendingCallback != pendingCallbacks.end()) { - auto& pendingCount = pendingCallback->second; - - // Decrease the pending count for this listener - if (--pendingCount == 0) { - pendingCallbacks.erase(pendingCallback); - } - } else { - ALOGW("there are more latched callbacks than there were registered callbacks"); - } - if (listener->second.size() == 0) { - mPendingTransactions.erase(listener); - } - } else { - ALOGW("cannot find listener in mPendingTransactions"); + if (!containsOnCommitCallbacks(handle->callbackIds)) { + outRemainingHandles.push_back(handle); + continue; } + status_t err = finalizeCallbackHandle(handle, jankData); + if (err != NO_ERROR) { + return err; + } + } - status_t err = addCallbackHandle(handle, jankData); + return NO_ERROR; +} + +status_t TransactionCallbackInvoker::finalizePendingCallbackHandles( + const std::deque>& handles, const std::vector& jankData) { + if (handles.empty()) { + return NO_ERROR; + } + std::lock_guard lock(mMutex); + for (const auto& handle : handles) { + status_t err = finalizeCallbackHandle(handle, jankData); if (err != NO_ERROR) { - ALOGE("could not add callback handle"); return err; } } @@ -243,7 +277,8 @@ void TransactionCallbackInvoker::sendCallbacks() { } // If the transaction has been latched - if (transactionStats.latchTime >= 0) { + if (transactionStats.latchTime >= 0 && + !containsOnCommitCallbacks(transactionStats.callbackIds)) { if (!mPresentFence) { break; } diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h index caa8a4fb45..184b15103e 100644 --- a/services/surfaceflinger/TransactionCallbackInvoker.h +++ b/services/surfaceflinger/TransactionCallbackInvoker.h @@ -74,6 +74,8 @@ public: // Notifies the TransactionCallbackInvoker that a pending CallbackHandle has been presented. status_t finalizePendingCallbackHandles(const std::deque>& handles, const std::vector& jankData); + status_t finalizeOnCommitCallbackHandles(const std::deque>& handles, + std::deque>& outRemainingHandles); // Adds the Transaction CallbackHandle from a layer that does not need to be relatched and // presented this frame. @@ -95,6 +97,9 @@ private: status_t addCallbackHandle(const sp& handle, const std::vector& jankData) REQUIRES(mMutex); + status_t finalizeCallbackHandle(const sp& handle, + const std::vector& jankData) REQUIRES(mMutex); + class CallbackDeathRecipient : public IBinder::DeathRecipient { public: // This function is a no-op. isBinderAlive needs a linked DeathRecipient to work. -- cgit v1.2.3-59-g8ed1b From f3f40fefdd67eab97aefdd62a08ab99eef442039 Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 27 Apr 2021 15:54:02 -0500 Subject: Added setBufferCrop Added setBufferCrop to handle setGeometry calls from the public SurfaceControl. This is because setGeometry gets crop in buffer space, but setCrop can only handle layer space crop. Added setBufferCrop to handle this case Test: ASurfaceControlTest Fixes: 186266903 Change-Id: I14fb329d2d6f504ca8fa8e330c8a036cbde56f28 --- libs/gui/LayerState.cpp | 8 ++++++-- libs/gui/SurfaceComposerClient.cpp | 15 +++++++++++++++ libs/gui/include/gui/LayerState.h | 4 +++- libs/gui/include/gui/SurfaceComposerClient.h | 2 ++ services/surfaceflinger/BufferStateLayer.cpp | 20 ++++++++++++++++++-- services/surfaceflinger/BufferStateLayer.h | 2 ++ services/surfaceflinger/Layer.h | 3 +++ services/surfaceflinger/SurfaceFlinger.cpp | 5 +++++ 8 files changed, 54 insertions(+), 5 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 517b49e6b5..267db7686a 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -98,7 +98,6 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.write, transparentRegion); SAFE_PARCEL(output.writeUint32, transform); SAFE_PARCEL(output.writeBool, transformToDisplayInverse); - SAFE_PARCEL(output.write, crop); SAFE_PARCEL(output.write, orientedDisplaySpaceRect); if (buffer) { @@ -167,6 +166,7 @@ status_t layer_state_t::write(Parcel& output) const } SAFE_PARCEL(output.write, stretchEffect); + SAFE_PARCEL(output.write, bufferCrop); return NO_ERROR; } @@ -209,7 +209,6 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, transparentRegion); SAFE_PARCEL(input.readUint32, &transform); SAFE_PARCEL(input.readBool, &transformToDisplayInverse); - SAFE_PARCEL(input.read, crop); SAFE_PARCEL(input.read, orientedDisplaySpaceRect); bool tmpBool = false; @@ -296,6 +295,7 @@ status_t layer_state_t::read(const Parcel& input) } SAFE_PARCEL(input.read, stretchEffect); + SAFE_PARCEL(input.read, bufferCrop); return NO_ERROR; } @@ -539,6 +539,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eStretchChanged; stretchEffect = other.stretchEffect; } + if (other.what & eBufferCropChanged) { + what |= eBufferCropChanged; + bufferCrop = other.bufferCrop; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 5db0eae416..808b731d8f 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1664,6 +1664,21 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setStret return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBufferCrop( + const sp& sc, const Rect& bufferCrop) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eBufferCropChanged; + s->bufferCrop = bufferCrop; + + registerSurfaceControlForCallback(sc); + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index b4f62f2206..3947f22462 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -85,7 +85,7 @@ struct layer_state_t { eReleaseBufferListenerChanged = 0x00000400, eShadowRadiusChanged = 0x00000800, eLayerCreated = 0x00001000, - /* was eDetachChildren, now available 0x00002000, */ + eBufferCropChanged = 0x00002000, eRelativeLayerChanged = 0x00004000, eReparent = 0x00008000, eColorChanged = 0x00010000, @@ -227,6 +227,8 @@ struct layer_state_t { // Stretch effect to be applied to this layer StretchEffect stretchEffect; + Rect bufferCrop; + // Listens to when the buffer is safe to be released. This is used for blast // layers only. The callback includes a release fence as well as the graphic // buffer id to identify the buffer. diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 5bbd8e3d85..f3439c4c84 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -542,6 +542,8 @@ public: float right, float bottom, float vecX, float vecY, float maxAmount); + Transaction& setBufferCrop(const sp& sc, const Rect& bufferCrop); + status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 7a5b20d78e..24b35997b9 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -284,6 +284,17 @@ bool BufferStateLayer::setCrop(const Rect& crop) { return true; } +bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) { + if (mCurrentState.bufferCrop == bufferCrop) return false; + + mCurrentState.sequence++; + mCurrentState.bufferCrop = bufferCrop; + + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms) { if (mCurrentState.transform.dsdx() == matrix.dsdx && @@ -809,10 +820,15 @@ uint32_t BufferStateLayer::getEffectiveScalingMode() const { } Rect BufferStateLayer::computeBufferCrop(const State& s) { - if (s.buffer) { + if (s.buffer && !s.bufferCrop.isEmpty()) { + Rect bufferCrop; + s.buffer->getBuffer()->getBounds().intersect(s.bufferCrop, &bufferCrop); + return bufferCrop; + } else if (s.buffer) { return s.buffer->getBuffer()->getBounds(); + } else { + return s.bufferCrop; } - return Rect::INVALID_RECT; } sp BufferStateLayer::createClone() { diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index af4fcae7ba..570a41afc3 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -88,6 +88,8 @@ public: FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; void setAutoRefresh(bool autoRefresh) override; + bool setBufferCrop(const Rect& bufferCrop) override; + // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 688a2c3aff..a83408b7f0 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -274,6 +274,8 @@ public: // Stretch effect to apply to this layer StretchEffect stretchEffect; + + Rect bufferCrop; }; /* @@ -885,6 +887,7 @@ public: bool setStretchEffect(const StretchEffect& effect); StretchEffect getStretchEffect() const; + virtual bool setBufferCrop(const Rect& /* bufferCrop */) { return false; } virtual std::atomic* getPendingBufferCounter() { return nullptr; } virtual std::string getPendingBufferCounterName() { return ""; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index b04868225e..2dace92eaa 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4033,6 +4033,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded; } } + if (what & layer_state_t::eBufferCropChanged) { + if (layer->setBufferCrop(s.bufferCrop)) { + flags |= eTraversalNeeded; + } + } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not -- cgit v1.2.3-59-g8ed1b From 6bdec7d9c62ed47f9fd0e0cb9e59f0cbe48b4bae Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Mon, 10 May 2021 15:01:13 -0700 Subject: Remove rotation based scaling In order to simplify some of the geometry logic in BufferStateLayer, and unify with the rest of the layer in SurfaceFlinger we translate the concept of source and dest frame into crop, scale and position. This is currently done on the client side. But if there is buffer rotation transform, we will generate an additional scale, to scale the buffer size to the new orientation. This causes issues with rounded corners because the additional scale stretches the rounded corner incorrectly. And translating the buffer rotation into a rotation matrix affects child layers. This solution only adjusts the buffer size based on the rotation matrix and the scale is generated based on the rotated buffer. This cannot be done in the client side because we do not have the current display orientation to unflip the buffer if the client sets the transformToDisplayInverse flag. In the future the plan is to drive the transform hint and the display orientation down from WM so this calculation can go back to the client. Test: atest SurfaceControlTest ASurfaceControlTest libgui_test SurfaceFlinger_test Test: go/wm-smoke Bug: 185597146, 186191378 Change-Id: Ia566f952f5efe765382434dbc460b4815165f4f5 --- libs/gui/BLASTBufferQueue.cpp | 20 +---- libs/gui/LayerState.cpp | 8 ++ libs/gui/SurfaceComposerClient.cpp | 15 ++++ libs/gui/include/gui/LayerState.h | 3 +- libs/gui/include/gui/SurfaceComposerClient.h | 2 + services/surfaceflinger/BufferStateLayer.cpp | 106 +++++++++++++++++++++------ services/surfaceflinger/BufferStateLayer.h | 6 ++ services/surfaceflinger/Layer.cpp | 63 ++-------------- services/surfaceflinger/Layer.h | 13 +--- services/surfaceflinger/SurfaceFlinger.cpp | 32 ++++---- 10 files changed, 147 insertions(+), 121 deletions(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 37fb8448ee..08800f7a85 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -213,7 +213,8 @@ void BLASTBufferQueue::update(const sp& surface, uint32_t width, // for this is the scale is calculated based on the requested size and buffer size. // If there's no buffer, the scale will always be 1. if (mLastBufferInfo.hasBuffer) { - setMatrix(&t, mLastBufferInfo); + t.setDestinationFrame(mSurfaceControl, + Rect(0, 0, newSize.getWidth(), newSize.getHeight())); } applyTransaction = true; } @@ -416,8 +417,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast(this)); mSurfaceControlsWithPendingCallback.push(mSurfaceControl); - setMatrix(t, mLastBufferInfo); - t->setCrop(mSurfaceControl, crop); + t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight())); + t->setBufferCrop(mSurfaceControl, crop); t->setTransform(mSurfaceControl, bufferItem.mTransform); t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse); if (!bufferItem.mIsAutoTimestamp) { @@ -543,19 +544,6 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) { return mSize != bufferSize; } -void BLASTBufferQueue::setMatrix(SurfaceComposerClient::Transaction* t, - const BufferInfo& bufferInfo) { - uint32_t bufWidth = bufferInfo.crop.getWidth(); - uint32_t bufHeight = bufferInfo.crop.getHeight(); - - float sx = mSize.width / static_cast(bufWidth); - float sy = mSize.height / static_cast(bufHeight); - - t->setMatrix(mSurfaceControl, sx, 0, 0, sy); - // Update position based on crop. - t->setPosition(mSurfaceControl, bufferInfo.crop.left * sx * -1, bufferInfo.crop.top * sy * -1); -} - void BLASTBufferQueue::setTransactionCompleteCallback( uint64_t frameNumber, std::function&& transactionCompleteCallback) { std::lock_guard _lock{mMutex}; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 267db7686a..e65c721ae1 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -64,6 +64,8 @@ layer_state_t::layer_state_t() fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0), autoRefresh(false), + bufferCrop(Rect::INVALID_RECT), + destinationFrame(Rect::INVALID_RECT), releaseBufferListener(nullptr) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; @@ -167,6 +169,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.write, stretchEffect); SAFE_PARCEL(output.write, bufferCrop); + SAFE_PARCEL(output.write, destinationFrame); return NO_ERROR; } @@ -296,6 +299,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, stretchEffect); SAFE_PARCEL(input.read, bufferCrop); + SAFE_PARCEL(input.read, destinationFrame); return NO_ERROR; } @@ -543,6 +547,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eBufferCropChanged; bufferCrop = other.bufferCrop; } + if (other.what & eDestinationFrameChanged) { + what |= eDestinationFrameChanged; + destinationFrame = other.destinationFrame; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 11b8ebac81..aa938087e8 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1675,6 +1675,21 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDestinationFrame( + const sp& sc, const Rect& destinationFrame) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eDestinationFrameChanged; + s->destinationFrame = destinationFrame; + + registerSurfaceControlForCallback(sc); + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 3947f22462..16430b324d 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -104,7 +104,7 @@ struct layer_state_t { eHasListenerCallbacksChanged = 0x20000000, eInputInfoChanged = 0x40000000, eCornerRadiusChanged = 0x80000000, - /* was eFrameChanged, now available 0x1'00000000, */ + eDestinationFrameChanged = 0x1'00000000, eCachedBufferChanged = 0x2'00000000, eBackgroundColorChanged = 0x4'00000000, eMetadataChanged = 0x8'00000000, @@ -228,6 +228,7 @@ struct layer_state_t { StretchEffect stretchEffect; Rect bufferCrop; + Rect destinationFrame; // Listens to when the buffer is safe to be released. This is used for blast // layers only. The callback includes a release fence as well as the graphic diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 35757be988..0940e9d178 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -554,6 +554,8 @@ public: const StretchEffect& stretchEffect); Transaction& setBufferCrop(const sp& sc, const Rect& bufferCrop); + Transaction& setDestinationFrame(const sp& sc, + const Rect& destinationFrame); status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 24b35997b9..fcf8299b72 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -295,12 +295,72 @@ bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) { return true; } +bool BufferStateLayer::setDestinationFrame(const Rect& destinationFrame) { + if (mCurrentState.destinationFrame == destinationFrame) return false; + + mCurrentState.sequence++; + mCurrentState.destinationFrame = destinationFrame; + + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +// Translate destination frame into scale and position. If a destination frame is not set, use the +// provided scale and position +void BufferStateLayer::updateGeometry() { + if (mCurrentState.destinationFrame.isEmpty()) { + // If destination frame is not set, use the requested transform set via + // BufferStateLayer::setPosition and BufferStateLayer::setMatrix. + mCurrentState.transform = mRequestedTransform; + return; + } + + Rect destRect = mCurrentState.destinationFrame; + int32_t destW = destRect.width(); + int32_t destH = destRect.height(); + if (destRect.left < 0) { + destRect.left = 0; + destRect.right = destW; + } + if (destRect.top < 0) { + destRect.top = 0; + destRect.bottom = destH; + } + + if (!mCurrentState.buffer) { + ui::Transform t; + t.set(destRect.left, destRect.top); + mCurrentState.transform = t; + return; + } + + uint32_t bufferWidth = mCurrentState.buffer->getBuffer()->getWidth(); + uint32_t bufferHeight = mCurrentState.buffer->getBuffer()->getHeight(); + // Undo any transformations on the buffer. + if (mCurrentState.bufferTransform & ui::Transform::ROT_90) { + std::swap(bufferWidth, bufferHeight); + } + uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags(); + if (mCurrentState.transformToDisplayInverse) { + if (invTransform & ui::Transform::ROT_90) { + std::swap(bufferWidth, bufferHeight); + } + } + + float sx = destW / static_cast(bufferWidth); + float sy = destH / static_cast(bufferHeight); + ui::Transform t; + t.set(sx, 0, 0, sy); + t.set(destRect.left, destRect.top); + mCurrentState.transform = t; + return; +} + bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, bool allowNonRectPreservingTransforms) { - if (mCurrentState.transform.dsdx() == matrix.dsdx && - mCurrentState.transform.dtdy() == matrix.dtdy && - mCurrentState.transform.dtdx() == matrix.dtdx && - mCurrentState.transform.dsdy() == matrix.dsdy) { + if (mRequestedTransform.dsdx() == matrix.dsdx && mRequestedTransform.dtdy() == matrix.dtdy && + mRequestedTransform.dtdx() == matrix.dtdx && mRequestedTransform.dsdy() == matrix.dsdy) { return false; } @@ -313,7 +373,7 @@ bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, return false; } - mCurrentState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mCurrentState.sequence++; mCurrentState.modified = true; @@ -323,11 +383,11 @@ bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix, } bool BufferStateLayer::setPosition(float x, float y) { - if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) { + if (mRequestedTransform.tx() == x && mRequestedTransform.ty() == y) { return false; } - mCurrentState.transform.set(x, y); + mRequestedTransform.set(x, y); mCurrentState.sequence++; mCurrentState.modified = true; @@ -523,35 +583,35 @@ bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) { Rect BufferStateLayer::getBufferSize(const State& s) const { // for buffer state layers we use the display frame size as the buffer size. - if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) { - return Rect(getActiveWidth(s), getActiveHeight(s)); - } if (mBufferInfo.mBuffer == nullptr) { return Rect::INVALID_RECT; } - // if the display frame is not defined, use the parent bounds as the buffer size. - const auto& p = mDrawingParent.promote(); - if (p != nullptr) { - Rect parentBounds = Rect(p->getBounds(Region())); - if (!parentBounds.isEmpty()) { - return parentBounds; + uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth(); + uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight(); + + // Undo any transformations on the buffer and return the result. + if (mBufferInfo.mTransform & ui::Transform::ROT_90) { + std::swap(bufWidth, bufHeight); + } + + if (getTransformToDisplayInverse()) { + uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags(); + if (invTransform & ui::Transform::ROT_90) { + std::swap(bufWidth, bufHeight); } } - return Rect::INVALID_RECT; + return Rect(0, 0, bufWidth, bufHeight); } FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const { - const State& s(getDrawingState()); - // for buffer state layers we use the display frame size as the buffer size. - if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) { - return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s)); + if (mBufferInfo.mBuffer == nullptr) { + return parentBounds; } - // if the display frame is not defined, use the parent bounds as the buffer size. - return parentBounds; + return getBufferSize(getDrawingState()).toFloatRect(); } // ----------------------------------------------------------------------- diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index a273230cc8..2e484524a1 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -86,6 +86,8 @@ public: void setAutoRefresh(bool autoRefresh) override; bool setBufferCrop(const Rect& bufferCrop) override; + bool setDestinationFrame(const Rect& destinationFrame) override; + void updateGeometry() override; // ----------------------------------------------------------------------- @@ -178,6 +180,10 @@ private: // - If the integer decreases in setBuffer or doTransaction, a buffer was dropped std::atomic mPendingBufferTransactions{0}; + // Contains requested position and matrix updates. This will be applied if the client does + // not specify a destination frame. + ui::Transform mRequestedTransform; + // TODO(marissaw): support sticky transform for LEGACY camera mode class HwcSlotGenerator : public ClientCache::ErasedRecipient { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 21c9d74409..def271196d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -133,6 +133,7 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.fixedTransformHint = ui::Transform::ROT_INVALID; mCurrentState.frameTimelineInfo = {}; mCurrentState.postTime = -1; + mCurrentState.destinationFrame.makeInvalid(); if (args.flags & ISurfaceComposerClient::eNoColorFill) { // Set an invalid color so there is no color fill. @@ -315,55 +316,6 @@ FloatRect Layer::getBounds(const Region& activeTransparentRegion) const { return reduce(mBounds, activeTransparentRegion); } -ui::Transform Layer::getBufferScaleTransform() const { - // If the layer is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g. - // it isFixedSize) then there may be additional scaling not accounted - // for in the layer transform. - if (!isFixedSize() || getBuffer() == nullptr) { - return {}; - } - - // If the layer is a buffer state layer, the active width and height - // could be infinite. In that case, return the effective transform. - const uint32_t activeWidth = getActiveWidth(getDrawingState()); - const uint32_t activeHeight = getActiveHeight(getDrawingState()); - if (activeWidth >= UINT32_MAX && activeHeight >= UINT32_MAX) { - return {}; - } - - int bufferWidth = getBuffer()->getWidth(); - int bufferHeight = getBuffer()->getHeight(); - - if (getBufferTransform() & NATIVE_WINDOW_TRANSFORM_ROT_90) { - std::swap(bufferWidth, bufferHeight); - } - - float sx = activeWidth / static_cast(bufferWidth); - float sy = activeHeight / static_cast(bufferHeight); - - ui::Transform extraParentScaling; - extraParentScaling.set(sx, 0, 0, sy); - return extraParentScaling; -} - -ui::Transform Layer::getTransformWithScale(const ui::Transform& bufferScaleTransform) const { - // We need to mirror this scaling to child surfaces or we will break the contract where WM can - // treat child surfaces as pixels in the parent surface. - if (!isFixedSize() || getBuffer() == nullptr) { - return mEffectiveTransform; - } - return mEffectiveTransform * bufferScaleTransform; -} - -FloatRect Layer::getBoundsPreScaling(const ui::Transform& bufferScaleTransform) const { - // We need the pre scaled layer bounds when computing child bounds to make sure the child is - // cropped to its parent layer after any buffer transform scaling is applied. - if (!isFixedSize() || getBuffer() == nullptr) { - return mBounds; - } - return bufferScaleTransform.inverse().transform(mBounds); -} - void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform, float parentShadowRadius) { const State& s(getDrawingState()); @@ -400,11 +352,8 @@ void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform, // don't pass it to its children. const float childShadowRadius = canDrawShadows() ? 0.f : mEffectiveShadowRadius; - // Add any buffer scaling to the layer's children. - ui::Transform bufferScaleTransform = getBufferScaleTransform(); for (const sp& child : mDrawingChildren) { - child->computeBounds(getBoundsPreScaling(bufferScaleTransform), - getTransformWithScale(bufferScaleTransform), childShadowRadius); + child->computeBounds(mBounds, mEffectiveTransform, childShadowRadius); } } @@ -858,6 +807,11 @@ uint32_t Layer::doTransaction(uint32_t flags) { const State& s(getDrawingState()); State& c(getCurrentState()); + // Translates dest frame into scale and position updates. This helps align geometry calculations + // for BufferStateLayer with other layers. This should ideally happen in the client once client + // has the display orientation details from WM. + updateGeometry(); + if (c.width != s.width || c.height != s.height || !(c.transform == s.transform)) { // invalidate and recompute the visible regions if needed flags |= Layer::eVisibleRegion; @@ -1768,8 +1722,7 @@ ssize_t Layer::removeChild(const sp& layer) { void Layer::setChildrenDrawingParent(const sp& newParent) { for (const sp& child : mDrawingChildren) { child->mDrawingParent = newParent; - child->computeBounds(newParent->mBounds, - newParent->getTransformWithScale(newParent->getBufferScaleTransform()), + child->computeBounds(newParent->mBounds, newParent->mEffectiveTransform, newParent->mEffectiveShadowRadius); } } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 284adbda66..ad4166b969 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -276,6 +276,7 @@ public: StretchEffect stretchEffect; Rect bufferCrop; + Rect destinationFrame; }; /* @@ -646,16 +647,6 @@ public: // Compute bounds for the layer and cache the results. void computeBounds(FloatRect parentBounds, ui::Transform parentTransform, float shadowRadius); - // Returns the buffer scale transform if a scaling mode is set. - ui::Transform getBufferScaleTransform() const; - - // Get effective layer transform, taking into account all its parent transform with any - // scaling if the parent scaling more is not NATIVE_WINDOW_SCALING_MODE_FREEZE. - ui::Transform getTransformWithScale(const ui::Transform& bufferScaleTransform) const; - - // Returns the bounds of the layer without any buffer scaling. - FloatRect getBoundsPreScaling(const ui::Transform& bufferScaleTransform) const; - int32_t getSequence() const override { return sequence; } // For tracing. @@ -885,8 +876,10 @@ public: StretchEffect getStretchEffect() const; virtual bool setBufferCrop(const Rect& /* bufferCrop */) { return false; } + virtual bool setDestinationFrame(const Rect& /* destinationFrame */) { return false; } virtual std::atomic* getPendingBufferCounter() { return nullptr; } virtual std::string getPendingBufferCounterName() { return ""; } + virtual void updateGeometry() {} protected: friend class impl::SurfaceInterceptor; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index beda834f9a..3edbe1da02 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2816,16 +2816,19 @@ void SurfaceFlinger::processDisplayChangesLocked() { } void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) { - /* - * Traversal of the children - * (perform the transaction for each of them if needed) - */ + // Commit display transactions + const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded; + if (displayTransactionNeeded) { + processDisplayChangesLocked(); + processDisplayHotplugEventsLocked(); + } - if ((transactionFlags & eTraversalNeeded) || mForceTraversal) { - mForceTraversal = false; + // Commit layer transactions. This needs to happen after display transactions are + // committed because some geometry logic relies on display orientation. + if ((transactionFlags & eTraversalNeeded) || mForceTraversal || displayTransactionNeeded) { mCurrentState.traverse([&](Layer* layer) { uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); - if (!trFlags) return; + if (!trFlags && !displayTransactionNeeded) return; const uint32_t flags = layer->doTransaction(0); if (flags & Layer::eVisibleRegion) @@ -2837,15 +2840,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) { }); } - /* - * Perform display own transactions if needed - */ - - if (transactionFlags & eDisplayTransactionNeeded) { - processDisplayChangesLocked(); - processDisplayHotplugEventsLocked(); - } - + // Update transform hint if (transactionFlags & (eTransformHintUpdateNeeded | eDisplayTransactionNeeded)) { // The transform hint might have changed for some layers // (either because a display has changed, or because a layer @@ -4039,6 +4034,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( flags |= eTraversalNeeded; } } + if (what & layer_state_t::eDestinationFrameChanged) { + if (layer->setDestinationFrame(s.destinationFrame)) { + flags |= eTraversalNeeded; + } + } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not -- cgit v1.2.3-59-g8ed1b From 6e8e36486152c3602c5ba3214f34fc01a6a13937 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Thu, 8 Jul 2021 19:44:07 -0700 Subject: SF: fix BufferTX counter for null buffers Don't increment the BufferTX counter is the transaction includes a buffer change but that buffer is null. Test: Open https://jsfiddle.net/8q7nuwh9/show in Chrome and scroll up down Bug: 192352790 Change-Id: Ia0a27ff32fb20f20a1ac671f2b4fdb3ae22a8aea --- libs/gui/LayerState.cpp | 4 ++++ libs/gui/include/gui/LayerState.h | 1 + services/surfaceflinger/SurfaceFlinger.cpp | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'libs/gui/LayerState.cpp') diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e65c721ae1..2d99fc1903 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -562,6 +562,10 @@ bool layer_state_t::hasBufferChanges() const { return (what & layer_state_t::eBufferChanged) || (what & layer_state_t::eCachedBufferChanged); } +bool layer_state_t::hasValidBuffer() const { + return buffer || cachedBuffer.isValid(); +} + status_t layer_state_t::matrix22_t::write(Parcel& output) const { SAFE_PARCEL(output.writeFloat, dsdx); SAFE_PARCEL(output.writeFloat, dtdx); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 8ac1e5d9e9..465e34ca33 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -126,6 +126,7 @@ struct layer_state_t { status_t write(Parcel& output) const; status_t read(const Parcel& input); bool hasBufferChanges() const; + bool hasValidBuffer() const; struct matrix22_t { float dsdx{0}; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0c23dc1dbd..ea23263830 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6858,7 +6858,7 @@ int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) con void SurfaceFlinger::TransactionState::traverseStatesWithBuffers( std::function visitor) { for (const auto& state : states) { - if (state.state.hasBufferChanges() && (state.state.surface)) { + if (state.state.hasBufferChanges() && state.state.hasValidBuffer() && state.state.surface) { visitor(state.state); } } -- cgit v1.2.3-59-g8ed1b From a30f7c99749f48d3c13c3c1ac96fc54a80ba1295 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 29 Jun 2021 15:42:56 -0700 Subject: Add mechanism for a task's windows to be trusted overlays (SF) - Add a layer state to indicate that this layer and its children in the hierarchy are trusted. This can only be set by callers holding ACCESS_SURFACE_FLINGER, and will be used for the PIP task layer to indicate that activities in PIP are trusted (as they are controlled only by the user and SystemUI) Bug: 191529039 Test: TBD Change-Id: Id92ccb087bd0d8dbaeeef3ba50b67fe015e53db8 --- cmds/surfacereplayer/proto/src/trace.proto | 5 +++++ libs/gui/LayerState.cpp | 7 ++++++ libs/gui/SurfaceComposerClient.cpp | 13 +++++++++++ libs/gui/include/gui/LayerState.h | 5 +++++ libs/gui/include/gui/SurfaceComposerClient.h | 3 +++ services/surfaceflinger/Layer.cpp | 23 +++++++++++++++++++ services/surfaceflinger/Layer.h | 5 +++++ services/surfaceflinger/SurfaceFlinger.cpp | 9 ++++++++ services/surfaceflinger/SurfaceInterceptor.cpp | 11 +++++++++ services/surfaceflinger/SurfaceInterceptor.h | 1 + .../surfaceflinger/layerproto/LayerProtoParser.cpp | 2 ++ .../include/layerproto/LayerProtoParser.h | 1 + services/surfaceflinger/layerproto/layers.proto | 2 ++ .../tests/SurfaceInterceptor_test.cpp | 26 ++++++++++++++++++++++ 14 files changed, 113 insertions(+) (limited to 'libs/gui/LayerState.cpp') diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto index 3798ba73a4..03a2709075 100644 --- a/cmds/surfacereplayer/proto/src/trace.proto +++ b/cmds/surfacereplayer/proto/src/trace.proto @@ -52,6 +52,7 @@ message SurfaceChange { BackgroundBlurRadiusChange background_blur_radius = 20; ShadowRadiusChange shadow_radius = 21; BlurRegionsChange blur_regions = 22; + TrustedOverlayChange trusted_overlay = 23; } } @@ -192,6 +193,10 @@ message ShadowRadiusChange { required float radius = 1; } +message TrustedOverlayChange { + required float is_trusted_overlay = 1; +} + message BlurRegionsChange { repeated BlurRegionChange blur_regions = 1; } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 2d99fc1903..076c90dd23 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -64,6 +64,7 @@ layer_state_t::layer_state_t() fixedTransformHint(ui::Transform::ROT_INVALID), frameNumber(0), autoRefresh(false), + isTrustedOverlay(false), bufferCrop(Rect::INVALID_RECT), destinationFrame(Rect::INVALID_RECT), releaseBufferListener(nullptr) { @@ -170,6 +171,7 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.write, stretchEffect); SAFE_PARCEL(output.write, bufferCrop); SAFE_PARCEL(output.write, destinationFrame); + SAFE_PARCEL(output.writeBool, isTrustedOverlay); return NO_ERROR; } @@ -300,6 +302,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, stretchEffect); SAFE_PARCEL(input.read, bufferCrop); SAFE_PARCEL(input.read, destinationFrame); + SAFE_PARCEL(input.readBool, &isTrustedOverlay); return NO_ERROR; } @@ -532,6 +535,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eAutoRefreshChanged; autoRefresh = other.autoRefresh; } + if (other.what & eTrustedOverlayChanged) { + what |= eTrustedOverlayChanged; + isTrustedOverlay = other.isTrustedOverlay; + } if (other.what & eReleaseBufferListenerChanged) { if (releaseBufferListener) { ALOGW("Overriding releaseBufferListener"); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6ea070ea2f..96da8efd19 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1656,6 +1656,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAutoR return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrustedOverlay( + const sp& sc, bool isTrustedOverlay) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eTrustedOverlayChanged; + s->isTrustedOverlay = isTrustedOverlay; + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApplyToken( const sp& applyToken) { mApplyToken = applyToken; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 465e34ca33..3e57ff611e 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -118,6 +118,7 @@ struct layer_state_t { eBlurRegionsChanged = 0x800'00000000, eAutoRefreshChanged = 0x1000'00000000, eStretchChanged = 0x2000'00000000, + eTrustedOverlayChanged = 0x4000'00000000, }; layer_state_t(); @@ -225,6 +226,10 @@ struct layer_state_t { // in shared buffer mode. bool autoRefresh; + // An inherited state that indicates that this surface control and its children + // should be trusted for input occlusion detection purposes + bool isTrustedOverlay; + // Stretch effect to be applied to this layer StretchEffect stretchEffect; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index c2963b58df..baa0567617 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -537,6 +537,9 @@ public: // in shared buffer mode. Transaction& setAutoRefresh(const sp& sc, bool autoRefresh); + // Sets that this surface control and its children are trusted overlays for input + Transaction& setTrustedOverlay(const sp& sc, bool isTrustedOverlay); + // Queues up transactions using this token in SurfaceFlinger. By default, all transactions // from a client are placed on the same queue. This can be used to prevent multiple // transactions from blocking each other. diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index e2b6a36794..dbd2793276 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -851,6 +851,23 @@ bool Layer::setRelativeLayer(const sp& relativeToHandle, int32_t relati return true; } +bool Layer::setTrustedOverlay(bool isTrustedOverlay) { + if (mDrawingState.isTrustedOverlay == isTrustedOverlay) return false; + mDrawingState.isTrustedOverlay = isTrustedOverlay; + mDrawingState.modified = true; + mFlinger->mInputInfoChanged = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool Layer::isTrustedOverlay() const { + if (getDrawingState().isTrustedOverlay) { + return true; + } + const auto& p = mDrawingParent.promote(); + return (p != nullptr) && p->isTrustedOverlay(); +} + bool Layer::setSize(uint32_t w, uint32_t h) { if (mDrawingState.requested_legacy.w == w && mDrawingState.requested_legacy.h == h) return false; @@ -2041,6 +2058,7 @@ void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags, layerInfo->set_corner_radius(getRoundedCornerState().radius); layerInfo->set_background_blur_radius(getBackgroundBlurRadius()); + layerInfo->set_is_trusted_overlay(isTrustedOverlay()); LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform()); LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(), [&]() { return layerInfo->mutable_position(); }); @@ -2327,6 +2345,11 @@ InputWindowInfo Layer::fillInputInfo(const sp& display) { toPhysicalDisplay.transform(Rect{cropLayer->mScreenBounds})); } + // Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state + // if it was set by WM for a known system overlay + info.trustedOverlay = info.trustedOverlay || isTrustedOverlay(); + + // If the layer is a clone, we need to crop the input region to cloned root to prevent // touches from going outside the cloned area. if (isClone()) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 6b56b2d924..c5cb17ffc7 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -275,6 +275,9 @@ public: // Stretch effect to apply to this layer StretchEffect stretchEffect; + // Whether or not this layer is a trusted overlay for input + bool isTrustedOverlay; + Rect bufferCrop; Rect destinationFrame; }; @@ -393,6 +396,7 @@ public: virtual bool setBackgroundBlurRadius(int backgroundBlurRadius); virtual bool setBlurRegions(const std::vector& effectRegions); virtual bool setTransparentRegionHint(const Region& transparent); + virtual bool setTrustedOverlay(bool); virtual bool setFlags(uint32_t flags, uint32_t mask); virtual bool setLayerStack(uint32_t layerStack); virtual uint32_t getLayerStack() const; @@ -1050,6 +1054,7 @@ private: void updateTreeHasFrameRateVote(); void setZOrderRelativeOf(const wp& relativeOf); + bool isTrustedOverlay() const; // Find the root of the cloned hierarchy, this means the first non cloned parent. // This will return null if first non cloned parent is not found. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2cc810986f..f44ae71896 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4156,6 +4156,15 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & layer_state_t::eAutoRefreshChanged) { layer->setAutoRefresh(s.autoRefresh); } + if (what & layer_state_t::eTrustedOverlayChanged) { + if (privileged) { + if (layer->setTrustedOverlay(s.isTrustedOverlay)) { + flags |= eTraversalNeeded; + } + } else { + ALOGE("Attempt to set trusted overlay without permission ACCESS_SURFACE_FLINGER"); + } + } if (what & layer_state_t::eStretchChanged) { if (layer->setStretchEffect(s.stretchEffect)) { flags |= eTraversalNeeded; diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index 8ca241e53d..23ab7c8bab 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -149,6 +149,7 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, getLayerIdFromWeakRef(layer->mDrawingState.zOrderRelativeOf), layer->mDrawingState.z); addShadowRadiusLocked(transaction, layerId, layer->mDrawingState.shadowRadius); + addTrustedOverlayLocked(transaction, layerId, layer->mDrawingState.isTrustedOverlay); } void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment, @@ -397,6 +398,13 @@ void SurfaceInterceptor::addShadowRadiusLocked(Transaction* transaction, int32_t overrideChange->set_radius(shadowRadius); } +void SurfaceInterceptor::addTrustedOverlayLocked(Transaction* transaction, int32_t layerId, + bool isTrustedOverlay) { + SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); + TrustedOverlayChange* overrideChange(change->mutable_trusted_overlay()); + overrideChange->set_is_trusted_overlay(isTrustedOverlay); +} + void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, const layer_state_t& state) { @@ -460,6 +468,9 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, if (state.what & layer_state_t::eShadowRadiusChanged) { addShadowRadiusLocked(transaction, layerId, state.shadowRadius); } + if (state.what & layer_state_t::eTrustedOverlayChanged) { + addTrustedOverlayLocked(transaction, layerId, state.isTrustedOverlay); + } if (state.what & layer_state_t::eStretchChanged) { ALOGW("SurfaceInterceptor not implemented for eStretchChanged"); } diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 30aca8340e..673f9e789d 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -177,6 +177,7 @@ private: void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId, int z); void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius); + void addTrustedOverlayLocked(Transaction* transaction, int32_t layerId, bool isTrustedOverlay); // Add display transactions to the trace DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t sequenceId); diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp index aef670da33..2841f7c2fd 100644 --- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp +++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp @@ -105,6 +105,7 @@ LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerP layer.queuedFrames = layerProto.queued_frames(); layer.refreshPending = layerProto.refresh_pending(); layer.isProtected = layerProto.is_protected(); + layer.isTrustedOverlay = layerProto.is_trusted_overlay(); layer.cornerRadius = layerProto.corner_radius(); layer.backgroundBlurRadius = layerProto.background_blur_radius(); for (const auto& entry : layerProto.metadata()) { @@ -289,6 +290,7 @@ std::string LayerProtoParser::Layer::to_string() const { StringAppendF(&result, "crop=%s, ", crop.to_string().c_str()); StringAppendF(&result, "cornerRadius=%f, ", cornerRadius); StringAppendF(&result, "isProtected=%1d, ", isProtected); + StringAppendF(&result, "isTrustedOverlay=%1d, ", isTrustedOverlay); StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate); StringAppendF(&result, "dataspace=%s, ", dataspace.c_str()); StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str()); diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h index c48354fe95..52503bad3a 100644 --- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h @@ -109,6 +109,7 @@ public: int32_t queuedFrames; bool refreshPending; bool isProtected; + bool isTrustedOverlay; float cornerRadius; int backgroundBlurRadius; LayerMetadata metadata; diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto index 9f25674f1b..dddc677715 100644 --- a/services/surfaceflinger/layerproto/layers.proto +++ b/services/surfaceflinger/layerproto/layers.proto @@ -128,6 +128,8 @@ message LayerProto { // Regions of a layer, where blur should be applied. repeated BlurRegion blur_regions = 54; + + bool is_trusted_overlay = 55; } message PositionProto { diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index ee4e863474..d5890ffa79 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -193,6 +193,7 @@ public: bool reparentUpdateFound(const SurfaceChange& change, bool found); bool relativeParentUpdateFound(const SurfaceChange& change, bool found); bool shadowRadiusUpdateFound(const SurfaceChange& change, bool found); + bool trustedOverlayUpdateFound(const SurfaceChange& change, bool found); bool surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase); // Find all of the updates in the single trace @@ -228,6 +229,7 @@ public: void reparentUpdate(Transaction&); void relativeParentUpdate(Transaction&); void shadowRadiusUpdate(Transaction&); + void trustedOverlayUpdate(Transaction&); void surfaceCreation(Transaction&); void displayCreation(Transaction&); void displayDeletion(Transaction&); @@ -405,6 +407,10 @@ void SurfaceInterceptorTest::shadowRadiusUpdate(Transaction& t) { t.setShadowRadius(mBGSurfaceControl, SHADOW_RADIUS_UPDATE); } +void SurfaceInterceptorTest::trustedOverlayUpdate(Transaction& t) { + t.setTrustedOverlay(mBGSurfaceControl, true); +} + void SurfaceInterceptorTest::displayCreation(Transaction&) { sp testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false); SurfaceComposerClient::destroyDisplay(testDisplay); @@ -433,6 +439,7 @@ void SurfaceInterceptorTest::runAllUpdates() { runInTransaction(&SurfaceInterceptorTest::reparentUpdate); runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate); runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate); + runInTransaction(&SurfaceInterceptorTest::trustedOverlayUpdate); } void SurfaceInterceptorTest::surfaceCreation(Transaction&) { @@ -644,6 +651,17 @@ bool SurfaceInterceptorTest::shadowRadiusUpdateFound(const SurfaceChange& change return foundShadowRadius; } +bool SurfaceInterceptorTest::trustedOverlayUpdateFound(const SurfaceChange& change, + bool foundTrustedOverlay) { + bool hasTrustedOverlay(change.trusted_overlay().is_trusted_overlay()); + if (hasTrustedOverlay && !foundTrustedOverlay) { + foundTrustedOverlay = true; + } else if (hasTrustedOverlay && foundTrustedOverlay) { + []() { FAIL(); }(); + } + return foundTrustedOverlay; +} + bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase) { bool foundUpdate = false; @@ -704,6 +722,9 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace, case SurfaceChange::SurfaceChangeCase::kShadowRadius: foundUpdate = shadowRadiusUpdateFound(change, foundUpdate); break; + case SurfaceChange::SurfaceChangeCase::kTrustedOverlay: + foundUpdate = trustedOverlayUpdateFound(change, foundUpdate); + break; case SurfaceChange::SurfaceChangeCase::SURFACECHANGE_NOT_SET: break; } @@ -897,6 +918,11 @@ TEST_F(SurfaceInterceptorTest, InterceptShadowRadiusUpdateWorks) { SurfaceChange::SurfaceChangeCase::kShadowRadius); } +TEST_F(SurfaceInterceptorTest, InterceptTrustedOverlayUpdateWorks) { + captureTest(&SurfaceInterceptorTest::trustedOverlayUpdate, + SurfaceChange::SurfaceChangeCase::kTrustedOverlay); +} + TEST_F(SurfaceInterceptorTest, InterceptAllUpdatesWorks) { captureTest(&SurfaceInterceptorTest::runAllUpdates, &SurfaceInterceptorTest::assertAllUpdatesFound); -- cgit v1.2.3-59-g8ed1b