Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80d195e6 authored by Chandru S's avatar Chandru S
Browse files

Always use sync transactions to change surfaceflinger work duration for blur

Bug: 423953389
Test: verified with trace (in CL comment)
Flag: EXEMPT bugfix
Change-Id: I00d8414d120920e9a72f900bfb2c6c7151311d7d
parent 3e46e14c
Loading
Loading
Loading
Loading
+13 −17
Original line number Diff line number Diff line
@@ -433,7 +433,7 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {
    @DisableFlags(Flags.FLAG_BOUNCER_UI_REVAMP, Flags.FLAG_GLANCEABLE_HUB_BLURRED_BACKGROUND)
    fun ignoreShadeBlurUntilHidden_schedulesFrame() {
        notificationShadeDepthController.blursDisabledForAppLaunch = true
        verify(blurUtils).prepareBlur(any(), anyInt())
        verify(blurUtils).prepareBlur(anyInt())
        verify(choreographer)
            .postFrameCallback(eq(notificationShadeDepthController.updateBlurCallback))
    }
@@ -505,20 +505,18 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {

        notificationShadeDepthController.updateBlurCallback.doFrame(0)
        verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0))
        verify(blurUtils).prepareBlur(any(), eq(0))
        verify(blurUtils).applyBlur(
        verify(blurUtils).prepareBlur(eq(0))
        verify(blurUtils)
            .applyBlur(
                eq(viewRootImpl),
                eq(0),
                eq(false),
            eq(notificationShadeDepthController.zoomOutAsScale(0f))
                eq(notificationShadeDepthController.zoomOutAsScale(0f)),
            )
    }

    @Test
    @EnableFlags(
        Flags.FLAG_BOUNCER_UI_REVAMP,
        Flags.FLAG_SPATIAL_MODEL_APP_PUSHBACK,
    )
    @EnableFlags(Flags.FLAG_BOUNCER_UI_REVAMP, Flags.FLAG_SPATIAL_MODEL_APP_PUSHBACK)
    fun brightnessMirror_hidesShadeBlur_withWindowBlurFlagAndAppPushback() {
        // Brightness mirror is fully visible
        `when`(brightnessSpring.ratio).thenReturn(1f)
@@ -530,10 +528,8 @@ class NotificationShadeDepthControllerTest : SysuiTestCase() {

        notificationShadeDepthController.updateBlurCallback.doFrame(0)
        verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0))
        verify(windowRootViewBlurInteractor).requestBlurForShade(
            eq(0),
            eq(notificationShadeDepthController.zoomOutAsScale(0f))
        )
        verify(windowRootViewBlurInteractor)
            .requestBlurForShade(eq(0), eq(notificationShadeDepthController.zoomOutAsScale(0f)))
    }

    @Test
+54 −56
Original line number Diff line number Diff line
@@ -121,22 +121,11 @@ constructor(
     * This method should be called before [applyBlur] so that, if needed, we can set the
     * early-wakeup flag in SurfaceFlinger.
     */
    fun prepareBlur(viewRootImpl: ViewRootImpl?, radius: Int) {
        if (
            viewRootImpl == null ||
                !viewRootImpl.surfaceControl.isValid ||
                !shouldBlur(radius) ||
                earlyWakeupEnabled
        ) {
            return
        }
        updateTransactionApplier(viewRootImpl)
        val builder =
            SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(viewRootImpl.surfaceControl)
        earlyWakeupInfo.trace = PREPARE_BLUR_TRACE_NAME
    fun prepareBlur(radius: Int) {
        if (!shouldBlur(radius) || earlyWakeupEnabled) return

        if (lastAppliedBlur == 0 && radius != 0) {
            earlyWakeupStart(builder, "eEarlyWakeup (prepareBlur)")
            transactionApplier.scheduleApply(builder.build())
            immediateEarlyWakeupStart(PREPARE_BLUR_TRACE_NAME)
        }
    }

@@ -155,7 +144,6 @@ constructor(
        updateTransactionApplier(viewRootImpl)
        val builder =
            SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(viewRootImpl.surfaceControl)
        earlyWakeupInfo.trace = APPLY_BLUR_TRACE_NAME
        if (shouldBlur(radius)) {
            builder.withBackgroundBlurRadius(radius)
            if (shouldScaleWithTransaction()) {
@@ -166,7 +154,7 @@ constructor(
                viewRootImpl.notifyRendererForGpuLoadUp("applyBlur")

                if (!earlyWakeupEnabled) {
                    earlyWakeupStart(builder, "eEarlyWakeup (applyBlur)")
                    earlyWakeupStartNextFrame(builder, APPLY_BLUR_TRACE_NAME)
                }
            }
            if (
@@ -175,7 +163,7 @@ constructor(
                    radius == 0 &&
                    !persistentEarlyWakeupRequired
            ) {
                earlyWakeupEnd(builder, "applyBlur")
                earlyWakeupEndNextFrame(builder, APPLY_BLUR_TRACE_NAME)
            }
            lastAppliedBlur = radius
        }
@@ -194,40 +182,49 @@ constructor(
    }

    @SuppressLint("MissingPermission")
    private fun earlyWakeupStart(
        builder: SyncRtSurfaceTransactionApplier.SurfaceParams.Builder?,
        traceMethodName: String,
    private fun immediateEarlyWakeupStart(traceName: String) {
        earlyWakeupInfo.trace = traceName
        Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, "immediateEarlyWakeupStart", 0)
        Trace.instantForTrack(TRACE_TAG_APP, TRACK_NAME, "immediateEarlyWakeupStart")
        // Using a sync transaction to switch surfaceflinger work duration immediately before the
        // first frame of non-zero blur is applied. Relying on SyncRtSurfaceTransactionApplier might
        // make this switch happen on the first non-zero blur frame.
        createTransaction().setEarlyWakeupStart(earlyWakeupInfo).apply()
        earlyWakeupEnabled = true
    }

    @SuppressLint("MissingPermission")
    private fun immediateEarlyWakeupEnd(traceName: String) {
        earlyWakeupInfo.trace = traceName
        Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
        Trace.instantForTrack(TRACE_TAG_APP, TRACK_NAME, "immediateEarlyWakeupEnd")
        createTransaction().setEarlyWakeupEnd(earlyWakeupInfo).apply()
        earlyWakeupEnabled = false
    }

    @SuppressLint("MissingPermission")
    private fun earlyWakeupStartNextFrame(
        builder: SyncRtSurfaceTransactionApplier.SurfaceParams.Builder,
        traceName: String,
    ) {
        v("earlyWakeupStart from $traceMethodName")
        Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, traceMethodName, 0)
        if (builder != null) {
        v("earlyWakeupStart from $traceName")
        earlyWakeupInfo.trace = traceName
        Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, "earlyWakeupStartNextFrame", 0)
        Trace.instantForTrack(TRACE_TAG_APP, TRACK_NAME, "earlyWakeupStartNextFrame")
        builder.withEarlyWakeupStart(earlyWakeupInfo)
        } else {
            Log.w(
                TAG,
                "surfaceControl is not valid, using immediate transaction to set early wakeup",
            )
            createTransaction().use { it.setEarlyWakeupStart(earlyWakeupInfo).apply() }
        }
        earlyWakeupEnabled = true
    }

    @SuppressLint("MissingPermission")
    private fun earlyWakeupEnd(
        builder: SyncRtSurfaceTransactionApplier.SurfaceParams.Builder?,
        loggingContext: String,
    private fun earlyWakeupEndNextFrame(
        builder: SyncRtSurfaceTransactionApplier.SurfaceParams.Builder,
        traceName: String,
    ) {
        v("earlyWakeupEnd from $loggingContext")
        if (builder != null) {
            builder.withEarlyWakeupEnd(earlyWakeupInfo)
        } else {
            Log.w(
                TAG,
                "surfaceControl is not valid, using immediate transaction to reset early wakeup",
            )
            createTransaction().use { it.setEarlyWakeupEnd(earlyWakeupInfo).apply() }
        }
        v("earlyWakeupEnd from $traceName")
        earlyWakeupInfo.trace = traceName
        Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
        Trace.instantForTrack(TRACE_TAG_APP, TRACK_NAME, "earlyWakeupEndNextFrame")
        builder.withEarlyWakeupEnd(earlyWakeupInfo)
        earlyWakeupEnabled = false
    }

@@ -281,17 +278,14 @@ constructor(
        persistentEarlyWakeupRequired = persistentWakeup
        if (viewRootImpl == null || !supportsBlursOnWindows()) return

        val builder =
            if (viewRootImpl.surfaceControl?.isValid == true) {
                updateTransactionApplier(viewRootImpl)
                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(viewRootImpl.surfaceControl)
            } else {
                null
            }
        earlyWakeupInfo.trace = SET_PERSISTENT_EARLY_WAKEUP_TRACE_NAME
        if (persistentEarlyWakeupRequired) {
            if (earlyWakeupEnabled) return
            earlyWakeupStart(builder, "setEarlyWakeup")
            Trace.instantForTrack(
                TRACE_TAG_APP,
                TRACK_NAME,
                "setPersistentEarlyWakeup earlyWakeupStart",
            )
            immediateEarlyWakeupStart(SET_PERSISTENT_EARLY_WAKEUP_TRACE_NAME)
        } else {
            if (!earlyWakeupEnabled) return
            if (lastAppliedBlur > 0) {
@@ -302,9 +296,13 @@ constructor(
                        " was still active",
                )
            }
            earlyWakeupEnd(builder, "resetEarlyWakeup")
            Trace.instantForTrack(
                TRACE_TAG_APP,
                TRACK_NAME,
                "setPersistentEarlyWakeup earlyWakeupEnd",
            )
            immediateEarlyWakeupEnd(SET_PERSISTENT_EARLY_WAKEUP_TRACE_NAME)
        }
        builder?.let { transactionApplier.scheduleApply(it.build()) }
    }

    companion object {
+19 −13
Original line number Diff line number Diff line
@@ -101,8 +101,10 @@ constructor(
        private const val INTERACTION_BLUR_FRACTION = 0.8f
        private const val ANIMATION_BLUR_FRACTION = 1f - INTERACTION_BLUR_FRACTION
        private const val TRANSITION_THRESHOLD = 0.98f
        private const val PUSHBACK_SCALE_FOR_LAUNCHER = 0.05f;
        private const val PUSHBACK_SCALE_FOR_APP = 0.025f;
        private const val PUSHBACK_SCALE_FOR_LAUNCHER = 0.05f

        private const val PUSHBACK_SCALE_FOR_APP = 0.025f

        private const val TAG = "DepthController"
    }

@@ -294,7 +296,8 @@ constructor(
                // When the shade is in another display, we don't want to zoom out the background.
                // Only the default display is supported right now.
                !isShadeOnDefaultDisplay -> 0f
                shadeRadius != wakeAndUnlockBlurRadius -> blurRadiusToZoomOut(blurRadius = shadeRadius)
                shadeRadius != wakeAndUnlockBlurRadius ->
                    blurRadiusToZoomOut(blurRadius = shadeRadius)
                else -> 0f
            }
        // Make blur be 0 if it is necessary to stop blur effect.
@@ -344,7 +347,7 @@ constructor(
            val opaque = shouldBlurBeOpaque
            val blurScale = zoomOutAsScale(zoomOutFromShadeRadius)
            TrackTracer.instantForGroup("shade", "shade_blur_radius", blur)
            blurUtils.applyBlur(root.viewRootImpl, blur, opaque, blurScale);
            blurUtils.applyBlur(root.viewRootImpl, blur, opaque, blurScale)
            onBlurApplied(blur, zoomOutFromShadeRadius)
        }

@@ -419,9 +422,11 @@ constructor(
        object : StatusBarStateController.StateListener {
            override fun onStateChanged(newState: Int) {
                if (Flags.noShadeBlurOnDreamStart()) {
                    if (existingStatusBarState == StatusBarState.KEYGUARD
                        && newState == StatusBarState.SHADE
                        && keyguardInteractor.isDreaming.value) {
                    if (
                        existingStatusBarState == StatusBarState.KEYGUARD &&
                            newState == StatusBarState.SHADE &&
                            keyguardInteractor.isDreaming.value
                    ) {
                        return
                    }
                }
@@ -670,7 +675,8 @@ constructor(

        if (Flags.bouncerUiRevamp() || Flags.glanceableHubBlurredBackground()) {
            if (windowRootViewBlurInteractor.isBlurCurrentlySupported.value) {
                updateScheduled = windowRootViewBlurInteractor.requestBlurForShade(
                updateScheduled =
                    windowRootViewBlurInteractor.requestBlurForShade(
                        blur,
                        zoomOutAsScale(zoomOutFromShadeRadius),
                    )
@@ -688,7 +694,7 @@ constructor(
            return
        }
        updateScheduled = true
        blurUtils.prepareBlur(root.viewRootImpl, blur)
        blurUtils.prepareBlur(blur)
        choreographer.postFrameCallback(updateBlurCallback)
    }

@@ -710,7 +716,7 @@ constructor(
            it.println("shouldApplyShadeBlur: ${shouldApplyShadeBlur()}")
            it.println("shadeAnimation: ${shadeAnimation.radius}")
            it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
            it.println("wakeAndUnlockBlurRadius: ${wakeAndUnlockBlurRadius}")
            it.println("wakeAndUnlockBlurRadius: $wakeAndUnlockBlurRadius")
            it.println("blursDisabledForAppLaunch: $blursDisabledForAppLaunch")
            it.println("appLaunchTransitionIsInProgress: $appLaunchTransitionIsInProgress")
            it.println("qsPanelExpansion: $qsPanelExpansion")
+11 −7
Original line number Diff line number Diff line
@@ -96,7 +96,12 @@ object WindowRootViewBinder {
                            )
                        }

                        combine(viewModel.blurRadius, viewModel.blurScale, viewModel.isSurfaceOpaque, ::Triple)
                        combine(
                                viewModel.blurRadius,
                                viewModel.blurScale,
                                viewModel.isSurfaceOpaque,
                                ::Triple,
                            )
                            .filter { it.first >= 0 }
                            .collect { (blurRadius, blurScale, isOpaque) ->
                                val newBlurRadius = blurRadius.toInt()
@@ -105,8 +110,10 @@ object WindowRootViewBinder {
                                if (wasUpdateScheduledForThisFrame) {
                                    // Update this value so that the frame callback picks up this
                                    // value when it runs
                                    if (lastScheduledBlurRadius != newBlurRadius ||
                                            lastScheduledBlurScale != newBlurScale) {
                                    if (
                                        lastScheduledBlurRadius != newBlurRadius ||
                                            lastScheduledBlurScale != newBlurScale
                                    ) {
                                        Log.w(TAG, "Multiple blur values emitted in the same frame")
                                    }
                                    lastScheduledBlurRadius = newBlurRadius
@@ -122,10 +129,7 @@ object WindowRootViewBinder {
                                lastScheduledBlurRadius = newBlurRadius
                                lastScheduleSurfaceOpaqueness = isOpaque
                                wasUpdateScheduledForThisFrame = true
                                blurUtils.prepareBlur(
                                    view.rootView?.viewRootImpl,
                                    lastScheduledBlurRadius,
                                )
                                blurUtils.prepareBlur(lastScheduledBlurRadius)
                                choreographer.postFrameCallback(newFrameCallback)
                            }
                    }