зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1745996 - Send a memory pressure event when deactivating sessions. r=jnicol,calu
WebRender retains about 50MBs of memory for every window. When switching between lots of tabs on Android (where 1 tab = 1 window), this can cause problems as the app will consume a significant amount of memory. To avoid this problem, we send a memory pressure event whenever a session is deactivated, which signals to WebRender that it should deallocate the memory. This message is sent on a delay of 10s to avoid interfering with tab switching, and we cancel the message if the tab becomes active again before we fire the memory pressure event. Co-Authored-By: Cathy Lu <calu@mozilla.com> Co-Authored-By: Jonathan Almeida [:jonalmeida] <jonalmeida942@gmail.com> Differential Revision: https://phabricator.services.mozilla.com/D136965
This commit is contained in:
Родитель
16da0fc374
Коммит
b1f93026e6
|
@ -520,6 +520,11 @@ mozilla::ipc::IPCResult CompositorBridgeParent::RecvFlushRendering(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CompositorBridgeParent::RecvNotifyMemoryPressure() {
|
||||
NotifyMemoryPressure();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult CompositorBridgeParent::RecvFlushRenderingAsync(
|
||||
const wr::RenderReasons& aReasons) {
|
||||
if (mWrBridge) {
|
||||
|
|
|
@ -242,6 +242,7 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
|
|||
const LayersId& id, CompositorOptions* compositorOptions) = 0;
|
||||
virtual mozilla::ipc::IPCResult RecvFlushRendering(
|
||||
const wr::RenderReasons& aReasons) = 0;
|
||||
virtual mozilla::ipc::IPCResult RecvNotifyMemoryPressure() = 0;
|
||||
virtual mozilla::ipc::IPCResult RecvWaitOnTransactionProcessed() = 0;
|
||||
virtual mozilla::ipc::IPCResult RecvStartFrameTimeRecording(
|
||||
const int32_t& bufferSize, uint32_t* startIndex) = 0;
|
||||
|
@ -324,6 +325,7 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyMemoryPressure() override;
|
||||
mozilla::ipc::IPCResult RecvBeginRecording(
|
||||
const TimeStamp& aRecordingStart,
|
||||
BeginRecordingResolver&& aResolve) override;
|
||||
|
|
|
@ -242,6 +242,12 @@ ContentCompositorBridgeParent::RecvMapAndNotifyChildCreated(
|
|||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentCompositorBridgeParent::RecvNotifyMemoryPressure() {
|
||||
// This can only be called from the browser process.
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentCompositorBridgeParent::RecvCheckContentOnlyTDR(
|
||||
const uint32_t& sequenceNum, bool* isContentOnlyTDR) {
|
||||
*isContentOnlyTDR = false;
|
||||
|
|
|
@ -84,6 +84,8 @@ class ContentCompositorBridgeParent final : public CompositorBridgeParentBase {
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyMemoryPressure() override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(
|
||||
const uint32_t& sequenceNum, bool* isContentOnlyTDR) override;
|
||||
|
||||
|
|
|
@ -173,6 +173,8 @@ parent:
|
|||
sync NotifyChildRecreated(LayersId id)
|
||||
returns (CompositorOptions compositorOptions);
|
||||
|
||||
async NotifyMemoryPressure();
|
||||
|
||||
// Make sure any pending composites are started immediately and
|
||||
// block until they are completed.
|
||||
sync FlushRendering(RenderReasons aReasons);
|
||||
|
|
|
@ -60,6 +60,14 @@ public final class ThreadUtils {
|
|||
sUiHandler.post(runnable);
|
||||
}
|
||||
|
||||
public static void postToUiThreadDelayed(final Runnable runnable, final long delayMillis) {
|
||||
sUiHandler.postDelayed(runnable, delayMillis);
|
||||
}
|
||||
|
||||
public static void removeUiThreadCallbacks(final Runnable runnable) {
|
||||
sUiHandler.removeCallbacks(runnable);
|
||||
}
|
||||
|
||||
public static Handler getBackgroundHandler() {
|
||||
return GeckoBackgroundThread.getHandler();
|
||||
}
|
||||
|
|
|
@ -90,6 +90,19 @@ public class GeckoSession {
|
|||
|
||||
private static final int DATA_URI_MAX_LENGTH = 2 * 1024 * 1024;
|
||||
|
||||
// Delay running compositor memory pressure by 10s to avoid interfering with tab switching.
|
||||
private static final int NOTIFY_MEMORY_PRESSURE_DELAY_MS = 10 * 1000;
|
||||
|
||||
private final Runnable mNotifyMemoryPressure =
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mCompositorReady) {
|
||||
mCompositor.notifyMemoryPressure();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private enum State implements NativeQueue.State {
|
||||
INITIAL(0),
|
||||
READY(1);
|
||||
|
@ -195,6 +208,9 @@ public class GeckoSession {
|
|||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
public native void setDynamicToolbarMaxHeight(int height);
|
||||
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||
public native void notifyMemoryPressure();
|
||||
|
||||
// Gecko thread pauses compositor; blocks UI thread.
|
||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
|
||||
public native void syncPauseCompositor();
|
||||
|
@ -2090,6 +2106,10 @@ public class GeckoSession {
|
|||
|
||||
if (!active) {
|
||||
mEventDispatcher.dispatch("GeckoView:FlushSessionState", null);
|
||||
ThreadUtils.postToUiThreadDelayed(mNotifyMemoryPressure, NOTIFY_MEMORY_PRESSURE_DELAY_MS);
|
||||
} else {
|
||||
// Delete any pending memory pressure events since we're active again.
|
||||
ThreadUtils.removeUiThreadCallbacks(mNotifyMemoryPressure);
|
||||
}
|
||||
|
||||
ThreadUtils.runOnUiThread(() -> getAutofillSupport().onActiveChanged(active));
|
||||
|
|
|
@ -1117,6 +1117,21 @@ class LayerViewSupport final
|
|||
gkWindow->Resize(aLeft, aTop, aWidth, aHeight, /* repaint */ false);
|
||||
}
|
||||
|
||||
void NotifyMemoryPressure() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
auto acc = mWindow.Access();
|
||||
if (!acc) {
|
||||
return; // Already shut down.
|
||||
}
|
||||
|
||||
nsWindow* gkWindow = acc->GetNsWindow();
|
||||
if (!gkWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
gkWindow->mCompositorBridgeChild->SendNotifyMemoryPressure();
|
||||
}
|
||||
|
||||
void SetDynamicToolbarMaxHeight(int32_t aHeight) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
auto acc = mWindow.Access();
|
||||
|
|
Загрузка…
Ссылка в новой задаче