Closed Bug 1741156 (gpu-process-android) Opened 3 years ago Closed 3 years ago

Implement GPU process on Android

Categories

(GeckoView Graveyard :: Sandboxing, task, P2)

Unspecified
All

Tracking

(firefox96 fixed)

RESOLVED FIXED
96 Branch
Tracking Status
firefox96 --- fixed

People

(Reporter: jnicol, Assigned: jnicol)

References

(Blocks 1 open bug)

Details

Attachments

(4 files)

This bug covers an initial implementation of the GPU process on Android.

We need to declare a GPU process service in the AndroidManifest.

We need to create a cross-process CompositorWidget implementation for Android, and a separate InProcessAndroidCompositorWidget for when the GPU process is disabled.

We need to send the Surface to the GPU process for us to render in to, using AIDL.

We must handle a GPU process crash/restart gracefully, by re-sending the Surface to the new GPU process and resuming rendering. When the GPU process is disabled after enough crashes, we must gracefully resume rendering in the parent process.

This bug will not cover allocating SurfaceTextures in the GPU process (for video and webgl). That will be landed separately to keep things in manageable chunks.

Declare a GPU process and corresponding Service in the
AndroidManifest. Additionally add a CompositorSurfaceManagerService,
which is used to send the Surface that should be rendered into over to
the GPU process using AIDL. Each nsWindow is given a unique ID, and
whenever the Surface changes due to an Android resume event, it sends
the new surface for that ID to the GPU process (if the GPU process is
enabled).

Stop inheriting AndroidCompositorWidget from InProcessCompositorWidget
and instead inherit from CompositorWidget directly. This class holds a
reference to the Surface that will be rendered in to. The
CompositorBridgeParent notifies the CompositorWidget whenever it has
been resumed, allowing it to fetch the new Surface. For the
cross-process CompositorWidgetParent implementation it fetches that
Surface from the CompositorSurfaceManagerService, whereas the
InProcessAndroidCompositorWidget can read it directly from the real
widget.

AndroidCompositorWidget::GetClientSize() can now calculate its size
from the Surface, rather than racily reading the value from the
nsWindow. This means RenderCompositorEGL and RenderCompositorOGLSWGL
can now use GetClientSize() again rather than querying their own size
from the Surface.

With this patch, setting layers.gpu-process.enabled to true will cause
us to launch a GPU process and render from it. We do not yet
gracefully recover from a GPU process crash, nor can we render
anything using SurfaceTextures (eg video or webgl). Those will come in
future patches.

This patch ensures that, following a GPU process crash, we
re-initialize the compositor and resume painting on Android.

nsWindow::GetWindowRenderer() is made to always reinitialize the
window renderer if there is none, like on other platforms. We
therefore no longer need to track whether webrender is being disabled,
as this is no longer a special case.

Previously we started the compositor as initially paused in
nsBaseWidget::CreateCompositorSession only if the widget did not yet
have a surface. Now we must unconditionally (re)start it as initially
paused, as even though the widget in the parent process may have a
surface, we will not have been able to send it to the GPU process
yet. We will send the surface to the compositor once control flow
returns to nsWindow::CreateLayerManager, where we will also now resume
the compositor if required.

Finally, we must ensure that we manually trigger a paint, both in the
parent and content processes. On other platforms this occurs
automatically following a GPU process loss through various refresh
driver events. On Android, however, nothing causes the refresh driver
to paint by itself, and we cannot receive input without first
initializing our APZ controllers, which does not happen until the
compositor receives a display list. We therefore must manually
schedule a paint. We do so from nsWindow::NotifyCompositorSessionLost
for the parent process, and BrowserChild::ReinitRendering for content
processes.

Depends on D131231

In order to render text using Skia (as webrender does for blob images)
we must ensure that the Freetype library has been initialized. In the
parent process this is done by gfxPlatform, but the GPU process does
not have a gfxPlatform so we should do so in GPUParent instead. We
already did this on Gtk, but this patch makes us do so on Android too.

Depends on D131232

When certain IPDL actors owned by the CompositorSession are destroyed,
such as CompositorBridgeChild or UiCompositorControllerChild, we call
GPUProcessManager::NotifyRemoteActorDestroyed() to notify the GPU
process manager that the connection to the GPU process has been lost,
causing it to restart or disable the GPU process.

To avoid doing this when the compositor session has been deliberately
destroyed (which occurs whenever a tab is closed on android, as each
tab has its own widget) we give each actor a "process token". This
token gets cleared when the actor is deliberately destroyed, and we
only notify the GPU process manager in ActorDestroy if the process
token is still set.

During an old refactoring of UiCompositorControllerChild, the
deliberate clearing of the process token was removed. This hasn't been
an issue up until now, as UiCompositorControllerChild is only created
on Android and there has been no GPU process on Android. However, with
the GPU process being implemented in this patch series, we now run in
to this issue: whenever a tab is closed we accidentally bring down the
GPU process.

This patch makes it so that we clear the process token once again in
UiCompositorControllerChild::Destroy, preventing us from accidentally
tearing down the GPU process.

Depends on D131233

Priority: -- → P2
Pushed by jnicol@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/4407622410e4 Initial GPU process implementation on Android. r=aosmond,agi https://hg.mozilla.org/integration/autoland/rev/8e95531fa96c Reinitialize compositor and request repaint after GPU process restart. r=aosmond,geckoview-reviewers,agi https://hg.mozilla.org/integration/autoland/rev/ab8777eb3373 Initialize FreeType library in GPU process on Android. r=aosmond https://hg.mozilla.org/integration/autoland/rev/88a709403fc4 Ensure deliberate CompositorSession shutdown doesn't take down GPU process. r=aosmond
See Also: → 1747116

Moving GPU process bugs to the new GeckoView::Sandboxing component.

Component: General → Sandboxing
See Also: → 1844829
Product: GeckoView → GeckoView Graveyard
Alias: gpu-process-android
Blocks: gpu-process
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: