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

Commit 013399dd authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge "Make PooledWindowDecorViewHostSupplier per-display." into main

parents 826091da 0677485d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -244,6 +244,8 @@ public enum DesktopExperienceFlags {
            Flags.FLAG_ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS),
    ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY(Flags::enablePerDisplayDesktopWallpaperActivity,
            true, Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY),
    ENABLE_PER_DISPLAY_WINDOW_DECOR_VIEW_HOST_POOL(Flags::enablePerDisplayWindowDecorViewHostPool,
            false, Flags.FLAG_ENABLE_PER_DISPLAY_WINDOW_DECOR_VIEW_HOST_POOL),
    ENABLE_PINNING_APP_WITH_CONTEXT_MENU(Flags::enablePinningAppWithContextMenu, true,
            Flags.FLAG_ENABLE_PINNING_APP_WITH_CONTEXT_MENU),
    ENABLE_PIP_PARAMS_UPDATE_NOTIFICATION_BUGFIX(
+10 −0
Original line number Diff line number Diff line
@@ -1246,6 +1246,16 @@ flag {
    }
}

flag {
    name: "enable_per_display_window_decor_view_host_pool"
    namespace: "lse_desktop_experience"
    description: "Enables per-display WindowDecoration ViewHost pooling"
    bug: "440247561"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "enable_persisting_display_size_for_connected_displays"
    namespace: "lse_desktop_experience"
+3 −1
Original line number Diff line number Diff line
@@ -509,13 +509,15 @@ public abstract class WMShellModule {
            @NonNull Context context,
            @ShellMainThread @NonNull CoroutineScope mainScope,
            @NonNull ShellInit shellInit,
            DisplayController displayController,
            DesktopState desktopState,
            DesktopConfig desktopConfig) {
        final int poolSize = desktopConfig.getWindowDecorScvhPoolSize();
        final int preWarmSize = desktopConfig.getWindowDecorPreWarmSize();
        if (desktopState.canEnterDesktopModeOrShowAppHandle() && poolSize > 0) {
            return new PooledWindowDecorViewHostSupplier(
                    context, mainScope, shellInit, poolSize, preWarmSize);
                    context, mainScope, shellInit, desktopState, displayController, poolSize,
                    preWarmSize);
        }
        return new DefaultWindowDecorViewHostSupplier(mainScope);
    }
+4 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ import kotlinx.coroutines.launch
class DefaultWindowDecorViewHost(
    context: Context,
    @ShellMainThread private val mainScope: CoroutineScope,
    display: Display,
    private val display: Display,
    @VisibleForTesting
    val viewHostAdapter: SurfaceControlViewHostAdapter =
        SurfaceControlViewHostAdapter(context, display),
@@ -48,6 +48,9 @@ class DefaultWindowDecorViewHost(
    override val surfaceControl: SurfaceControl
        get() = viewHostAdapter.rootSurface

    override val displayId: Int
        get() = display.displayId

    override fun updateView(
        view: View,
        attrs: WindowManager.LayoutParams,
+65 −9
Original line number Diff line number Diff line
@@ -19,9 +19,12 @@ import android.content.Context
import android.os.Trace
import android.util.Pools
import android.view.Display
import android.view.Display.DEFAULT_DISPLAY
import android.view.SurfaceControl
import android.window.DesktopExperienceFlags
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopState
import com.android.wm.shell.sysui.ShellInit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -42,12 +45,16 @@ class PooledWindowDecorViewHostSupplier(
    private val context: Context,
    @ShellMainThread private val mainScope: CoroutineScope,
    shellInit: ShellInit,
    maxPoolSize: Int,
    private val desktopState: DesktopState,
    private val displayController: DisplayController,
    private val maxPoolSize: Int,
    private val preWarmSize: Int,
) : WindowDecorViewHostSupplier<WindowDecorViewHost> {

    private val pool: Pools.Pool<WindowDecorViewHost> = Pools.SynchronizedPool(maxPoolSize)
    private val displayPools: HashMap<Int, Pools.Pool<WindowDecorViewHost>> = HashMap()
    private var nextDecorViewHostId = 0
    private val enablePerDisplayPool =
        DesktopExperienceFlags.ENABLE_PER_DISPLAY_WINDOW_DECOR_VIEW_HOST_POOL.isTrue

    init {
        require(preWarmSize <= maxPoolSize) { "Pre-warm size should not exceed pool size" }
@@ -55,18 +62,57 @@ class PooledWindowDecorViewHostSupplier(
    }

    private fun onShellInit() {
        if (!enablePerDisplayPool) {
            if (preWarmSize <= 0) {
                return
            }
            preWarmViewHosts(preWarmSize)
            return
        }

        displayController.addDisplayWindowListener(
            object : DisplayController.OnDisplaysChangedListener {
                override fun onDisplayAdded(displayId: Int) {
                    if (displayPools.containsKey(displayId)) {
                        return
                    }
                    displayPools[displayId] = Pools.SynchronizedPool(maxPoolSize)

    private fun preWarmViewHosts(preWarmSize: Int) {
                    if (
                        preWarmSize > 0 && desktopState.isDesktopModeSupportedOnDisplay(displayId)
                    ) {
                        preWarmViewHosts(preWarmSize, displayId)
                    }
                }

                override fun onDisplayRemoved(displayId: Int) {
                    val displayPool = displayPools.remove(displayId)
                    // Release all the viewHosts in the pool
                    var pooledViewHost = displayPool?.acquire()
                    val transaction = SurfaceControl.Transaction()
                    while (pooledViewHost != null) {
                        pooledViewHost.release(transaction)
                        pooledViewHost = displayPool?.acquire()
                    }
                    transaction.apply()
                }
            }
        )
    }

    private fun preWarmViewHosts(preWarmSize: Int, displayId: Int = DEFAULT_DISPLAY) {
        mainScope.launch {
            // Applying isn't needed, as the surface was never actually shown.
            val t = SurfaceControl.Transaction()
            val displayContext =
                if (enablePerDisplayPool) {
                    displayController.getDisplayContext(displayId) ?: return@launch
                } else {
                    context
                }
            repeat(preWarmSize) {
                val warmedViewHost = newInstance(context, context.display).apply { warmUp() }
                val warmedViewHost =
                    newInstance(displayContext, displayContext.display).apply { warmUp() }
                // Put the warmed view host in the pool by releasing it.
                release(warmedViewHost, t)
            }
@@ -74,7 +120,12 @@ class PooledWindowDecorViewHostSupplier(
    }

    override fun acquire(context: Context, display: Display): WindowDecorViewHost {
        val pooledViewHost = pool.acquire()
        val pooledViewHost =
            if (enablePerDisplayPool) {
                displayPools[display.displayId]?.acquire()
            } else {
                pool.acquire()
            }
        if (pooledViewHost != null) {
            return pooledViewHost
        }
@@ -88,8 +139,13 @@ class PooledWindowDecorViewHostSupplier(
        if (DesktopExperienceFlags.ENABLE_CLEAR_REUSABLE_SCVH_ON_RELEASE.isTrue) {
            viewHost.reset()
        }
        val pooled = pool.release(viewHost)
        if (!pooled) {
        val displayPool =
            if (enablePerDisplayPool) {
                displayPools[viewHost.displayId]
            } else {
                pool
            }
        if (displayPool == null || !displayPool.release(viewHost)) {
            viewHost.release(t)
        }
    }
Loading