Bug 204343 - Introduce a GPU process
Summary: Introduce a GPU process
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Tim Horton
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-11-18 23:23 PST by Tim Horton
Modified: 2021-02-17 11:24 PST (History)
25 users (show)

See Also:


Attachments
Patch (256.45 KB, patch)
2019-11-18 23:25 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews213 for win-future (14.21 MB, application/zip)
2019-11-19 20:43 PST, EWS Watchlist
no flags Details
Patch (257.44 KB, patch)
2019-11-20 14:57 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (257.70 KB, patch)
2019-11-23 18:42 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (257.88 KB, patch)
2019-11-24 22:26 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (257.83 KB, patch)
2019-11-24 23:41 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (257.79 KB, patch)
2019-11-25 21:25 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (257.79 KB, patch)
2019-11-26 00:46 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (251.10 KB, patch)
2019-12-02 01:40 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (251.23 KB, patch)
2019-12-02 22:07 PST, Tim Horton
no flags Details | Formatted Diff | Diff
Patch (224.37 KB, patch)
2019-12-03 23:12 PST, Tim Horton
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tim Horton 2019-11-18 23:23:50 PST
Introduce a GPU process
Comment 1 Tim Horton 2019-11-18 23:25:39 PST
Created attachment 383848 [details]
Patch
Comment 2 Tim Horton 2019-11-18 23:29:12 PST
Not quite ready for review yet (I haven't tried it on iOS), but pre-review welcome.

It doesn't actually *do* anything, though there is a switch to redirect UI-side compositing transactions through the GPU process (the first step towards doing OOP display list painting for layer contents).

The sandbox profile is stolen from the Web Content process to start, but we can definitely do waaaaay better.
Comment 3 Tim Horton 2019-11-18 23:41:41 PST
<rdar://problem/56921817>
Comment 4 EWS Watchlist 2019-11-19 20:43:50 PST
Comment on attachment 383848 [details]
Patch

Attachment 383848 [details] did not pass win-ews (win):
Output: https://webkit-queues.webkit.org/results/13268436

New failing tests:
http/tests/misc/repeat-open-cancel.html
Comment 5 EWS Watchlist 2019-11-19 20:43:52 PST
Created attachment 383941 [details]
Archive of layout-test-results from ews213 for win-future

The attached test failures were seen while running run-webkit-tests on the win-ews.
Bot: ews213  Port: win-future  Platform: CYGWIN_NT-10.0-17763-3.0.5-338.x86_64-x86_64-64bit
Comment 6 Tim Horton 2019-11-20 14:57:47 PST
Created attachment 383986 [details]
Patch
Comment 7 Tim Horton 2019-11-20 15:00:10 PST
Simon (correctly IMO) thinks we should have a Web Content process side class to coordinate all communication with the GPU process, instead of just messaging it willy-nilly.
Comment 8 Tim Horton 2019-11-23 18:42:06 PST
Created attachment 384248 [details]
Patch
Comment 9 Tim Horton 2019-11-24 22:26:27 PST
Created attachment 384270 [details]
Patch
Comment 10 Tim Horton 2019-11-24 23:41:13 PST
Created attachment 384272 [details]
Patch
Comment 11 Tim Horton 2019-11-25 21:24:55 PST
Ah, a classic misplaced close curly brace amongst many #ifs.
Comment 12 Tim Horton 2019-11-25 21:25:18 PST
Created attachment 384324 [details]
Patch
Comment 13 Tim Horton 2019-11-26 00:46:41 PST
Created attachment 384333 [details]
Patch
Comment 14 Tim Horton 2019-12-02 01:40:17 PST
Created attachment 384600 [details]
Patch
Comment 15 Alex Christensen 2019-12-02 11:06:16 PST
Comment on attachment 384600 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=384600&action=review

Incomplete review.

> Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp:86
> +void GPUConnectionToWebProcess::didClose(IPC::Connection& connection)

Unused parameter, extra space.

> Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in:25
> +messages -> GPUConnectionToWebProcess LegacyReceiver {

Please no new legacy receivers.

> Source/WebKit/GPUProcess/GPUProcess.cpp:52
> +static void callExitSoon(IPC::Connection*)

This should not be copied.  It is currently used for the network process, but not the web process.  If we need it for the gpu process, let's call the existing code.

> Source/WebKit/GPUProcess/GPUProcess.cpp:85
> +bool GPUProcess::shouldTerminate()
> +{
> +    return false;
> +}

FIXME here, or comment explaining why?  This seems optimistic.

> Source/WebKit/GPUProcess/GPUProcess.cpp:104
> +        return;
> +}

This looks silly.

> Source/WebKit/GPUProcess/GPUProcess.messages.in:25
> +messages -> GPUProcess LegacyReceiver {

Please no LegacyReceiver.

> Source/WebKit/GPUProcess/EntryPoint/Cocoa/XPCService/GPUServiceEntryPoint.mm:55
> +using namespace WebKit;

Could we not?

> Source/WebKit/GPUProcess/cocoa/GPUProcessCocoa.mm:37
> +void GPUProcess::platformInitializeGPUProcess(const GPUProcessCreationParameters&)
> +{
> +}

Let's just add this as needed.

> Source/WebKit/GPUProcess/ios/GPUProcessIOS.mm:49
> +void GPUProcess::initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&)

This definitely needs a fixme or not implemented or comment explaining that catalyst will need something here.

> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:198
> +        if (!ProcessThrottler::isValidForegroundActivity(m_activityFromWebProcesses)) {

This should be shared if needed.  I'm not sure what we'll do with background activities and GPU.

> Source/WebKit/UIProcess/GPU/GPUProcessProxy.messages.in:25
> +messages -> GPUProcessProxy LegacyReceiver NotRefCounted {

:(

> Source/WebKit/WebProcess/WebProcess.cpp:1266
> +    if (!connection.sendSync(Messages::WebProcessProxy::GetGPUProcessConnection(), Messages::WebProcessProxy::GetGPUProcessConnection::Reply(connectionInfo), 0)) {

It would be nice if we could avoid a new synchronous message when initializing things.  This could be done in parallel with the network process connection initialization.

> Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp:65
> +    Ref<GPUProcessConnection> protectedThis(*this);

??

> Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in:25
> +messages -> GPUProcessConnection LegacyReceiver {

ditto.  No legacy.
Also, this doesn't seem used in this patch.  Will it be?
Comment 16 Tim Horton 2019-12-02 21:04:14 PST
> > Source/WebKit/GPUProcess/ios/GPUProcessIOS.mm:49
> > +void GPUProcess::initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&)
> 
> This definitely needs a fixme or not implemented or comment explaining that
> catalyst will need something here.

It doesn't, it uses the Mac code!! (I hope). This is the same as the network process.

> > Source/WebKit/UIProcess/GPU/GPUProcessProxy.messages.in:25
> > +messages -> GPUProcessProxy LegacyReceiver NotRefCounted {
> 
> :(

Hush, I'll fix them all :)

> > Source/WebKit/WebProcess/WebProcess.cpp:1266
> > +    if (!connection.sendSync(Messages::WebProcessProxy::GetGPUProcessConnection(), Messages::WebProcessProxy::GetGPUProcessConnection::Reply(connectionInfo), 0)) {
> 
> It would be nice if we could avoid a new synchronous message when
> initializing things.  This could be done in parallel with the network
> process connection initialization.

The ChangeLog covers this. There is apparently a new mechanism Coming Soon. I need to check on the status of that.

> > Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in:25
> > +messages -> GPUProcessConnection LegacyReceiver {
> 
> Also, this doesn't seem used in this patch.  Will it be?

Definitely! Shortly.
Comment 17 Tim Horton 2019-12-02 22:07:47 PST
Created attachment 384690 [details]
Patch
Comment 18 Simon Fraser (smfr) 2019-12-03 10:20:36 PST
Comment on attachment 384690 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=384690&action=review

> Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp:73
> +void GPUConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
> +{
> +}

Log or abort or something?

> Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp:101
> +void GPUConnectionToWebProcess::willCommitLayerTree(TransactionID transactionID, WebPageProxyIdentifier pageID)
> +{
> +    gpuProcess().parentProcessConnection()->send(Messages::GPUProcessProxy::WillCommitLayerTree(transactionID, pageID), 0);
> +}
> +
> +void GPUConnectionToWebProcess::commitLayerTree(const RemoteLayerTreeTransaction& transaction, const RemoteScrollingCoordinatorTransaction& scrollingTransaction, WebPageProxyIdentifier pageID)
> +{
> +    // FIXME: This work (and most work in this process) should happen
> +    // on a secondary queue.
> +
> +    // We shouldn't need to map all of the IOSurfaces just to send them along
> +    // to the UI process, but just copying the send right doesn't work.
> +    // FIXME: Remove this once we don't actually need IOSurfaces to transit
> +    // this process, once they're just created here.
> +    for (const auto& changedLayerIter : transaction.changedLayerProperties()) {
> +        RemoteLayerTreeTransaction::LayerProperties* properties = changedLayerIter.value.get();
> +        if (!properties->backingStore)
> +            continue;
> +        properties->backingStore->mapBackingStoreIfNeeded();
> +    }
> +
> +    // FIXME: Only forward for page IDs that make sense for this connection.
> +    // This should probably be a MESSAGE_CHECK and kill the misbehaving
> +    // Web Content process.
> +    gpuProcess().parentProcessConnection()->send(Messages::GPUProcessProxy::CommitLayerTree(transaction, scrollingTransaction, pageID), 0);
> +}

Is this the right place for these?

> Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h:36
> +#include <WebCore/PageIdentifier.h>

Unused

> Source/WebKit/GPUProcess/GPUProcess.cpp:117
> +#if USE(UNIX_DOMAIN_SOCKETS)
> +    IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
> +    return std::make_pair(socketPair.server, IPC::Attachment { socketPair.client });
> +#elif OS(DARWIN)
> +    // Create the listening port.
> +    mach_port_t listeningPort = MACH_PORT_NULL;
> +    auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
> +    if (kr != KERN_SUCCESS) {
> +        RELEASE_LOG_ERROR(Process, "GPUProcess::createGPUConnectionToWebProcess: Could not allocate mach port, error %x", kr);
> +        CRASH();
> +    }
> +    if (!MACH_PORT_VALID(listeningPort)) {
> +        RELEASE_LOG_ERROR(Process, "GPUProcess::createGPUConnectionToWebProcess: Could not allocate mach port, returned port was invalid");
> +        CRASH();
> +    }
> +    return std::make_pair(IPC::Connection::Identifier { listeningPort }, IPC::Attachment { listeningPort, MACH_MSG_TYPE_MAKE_SEND });
> +#elif OS(WINDOWS)
> +    IPC::Connection::Identifier serverIdentifier, clientIdentifier;
> +    if (!IPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
> +        LOG_ERROR("Failed to create server and client identifiers");
> +        CRASH();
> +    }
> +    return std::make_pair(serverIdentifier, IPC::Attachment { clientIdentifier });
> +#else
> +    notImplemented();
> +    return { };
> +#endif

Seems like the kind of thing that should live in a base class.

> Source/WebKit/GPUProcess/GPUProcess.cpp:138
> +    RELEASE_LOG(ProcessSuspension, "%p - GPUProcess::prepareToSuspend(), isSuspensionImminent: %d", this, isSuspensionImminent);

We should probably log enough so we know which GPU Process PID a given pageID is using.

> Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:406
> +void RemoteLayerBackingStore::mapBackingStoreIfNeeded()
> +{
> +    if (m_frontBufferSendRight) {
> +        ASSERT(!m_frontBuffer.surface);
> +        m_frontBuffer.surface = WebCore::IOSurface::createFromSendRight(WTFMove(m_frontBufferSendRight), WebCore::sRGBColorSpaceRef());
> +    }
> +}

Maybe not in this patch?

> Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreeTransaction.mm:544
> -    encoder << static_cast<uint64_t>(m_changedLayers.size());
> +    encoder << static_cast<uint64_t>(m_changedLayers.size() + m_changedLayerProperties.size());
>  
>      for (const auto& layer : m_changedLayers) {
>          encoder << layer->layerID();
>          encoder << layer->properties();
>      }
> +
> +    for (const auto& layerIter : m_changedLayerProperties) {
> +        encoder << layerIter.key;
> +        encoder << *layerIter.value;
> +    }

Not in this patch?

> Source/WebKit/UIProcess/DrawingAreaProxy.h:111
> +    virtual void commitLayerTree(const RemoteLayerTreeTransaction&, const RemoteScrollingCoordinatorTransaction&) { ASSERT_NOT_REACHED(); }

Seems like a layering violation to have *remote* things here.

> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:110
> +void GPUProcessProxy::openGPUProcessConnection(uint64_t connectionRequestIdentifier, WebProcessProxy& webProcessProxy)

Can we make a typedef for connectionRequestIdentifier?

> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:132
> +#if USE(UNIX_DOMAIN_SOCKETS) || OS(WINDOWS)
> +        request.reply(GPUProcessConnectionInfo { WTFMove(*connectionIdentifier) });
> +#elif OS(DARWIN)
> +        MESSAGE_CHECK(MACH_PORT_VALID(connectionIdentifier->port()));
> +        request.reply(GPUProcessConnectionInfo { IPC::Attachment { connectionIdentifier->port(), MACH_MSG_TYPE_MOVE_SEND } });
> +#else
> +        notImplemented();
> +#endif

Should be hidden in a base class.

> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:181
> +    for (const auto& processPool : WebProcessPool::allProcessPools()) {
> +        hasAnyForegroundWebProcesses |= processPool->hasForegroundWebProcesses();
> +        hasAnyBackgroundWebProcesses |= processPool->hasBackgroundWebProcesses();
> +    }

Does this get the right set of clients for this process?

> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:212
> +void GPUProcessProxy::willCommitLayerTree(TransactionID transactionID, WebPageProxyIdentifier pageID)
> +{
> +    auto webPage = WebProcessProxy::webPage(pageID);
> +    webPage->drawingArea()->willCommitLayerTree(transactionID);
> +}
> +
> +void GPUProcessProxy::commitLayerTree(const RemoteLayerTreeTransaction& transaction, const RemoteScrollingCoordinatorTransaction& scrollingTransaction, WebPageProxyIdentifier pageID)
> +{
> +    auto webPage = WebProcessProxy::webPage(pageID);
> +    webPage->drawingArea()->commitLayerTree(transaction, scrollingTransaction);
> +
> +
> +}

Maybe not here (eventually?)

> Source/WebKit/WebProcess/GPU/GPUProcessConnectionInfo.h:46
> +#if USE(UNIX_DOMAIN_SOCKETS)
> +        return IPC::Connection::Identifier(connection.fileDescriptor());
> +#elif OS(DARWIN)
> +        return IPC::Connection::Identifier(connection.port());
> +#elif OS(WINDOWS)
> +        return IPC::Connection::Identifier(connection.handle());
> +#else
> +        ASSERT_NOT_REACHED();
> +        return IPC::Connection::Identifier();
> +#endif

Boo

> Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm:447
> +    Ref<IPC::Connection> connectionForCommits = *WebProcess::singleton().parentProcessConnection();
> +    std::unique_ptr<IPC::Encoder> commitEncoder;
> +
> +    if (m_useGPUProcess) {
> +#if ENABLE(GPU_PROCESS)
> +        connectionForCommits = WebProcess::singleton().ensureGPUProcessConnection().connection();
> +
> +        connectionForCommits->send(Messages::GPUConnectionToWebProcess::WillCommitLayerTree(layerTransaction.transactionID(), m_webPage.webPageProxyIdentifier()), 0);

Maybe all this could be a separate patch
Comment 19 Tim Horton 2019-12-03 22:36:52 PST
(In reply to Simon Fraser (smfr) from comment #18)
> Comment on attachment 384690 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=384690&action=review
> 
> > Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp:73
> > +void GPUConnectionToWebProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
> > +{
> > +}
> 
> Log or abort or something?

Oddly the other children do not, but yes, I'm going to do what the UI process does instead.

> > Source/WebKit/GPUProcess/GPUProcess.cpp:117
> > +#if USE(UNIX_DOMAIN_SOCKETS)
> > +    IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
> > +    return std::make_pair(socketPair.server, IPC::Attachment { socketPair.client 
> Seems like the kind of thing that should live in a base class.

I moved it up and renamed it. It just makes a pair, not specific to the web process.

> > Source/WebKit/GPUProcess/GPUProcess.cpp:138
> > +    RELEASE_LOG(ProcessSuspension, "%p - GPUProcess::prepareToSuspend(), isSuspensionImminent: %d", this, isSuspensionImminent);
> 
> We should probably log enough so we know which GPU Process PID a given
> pageID is using.
> 
> > Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:406
> > +void RemoteLayerBackingStore::mapBackingStoreIfNeeded()
> > +{
> > +    if (m_frontBufferSendRight) {
> > +        ASSERT(!m_frontBuffer.surface);
> > +        m_frontBuffer.surface = WebCore::IOSurface::createFromSendRight(WTFMove(m_frontBufferSendRight), WebCore::sRGBColorSpaceRef());
> > +    }
> > +}
> 
> Maybe not in this patch?

I removed all of this stuff.

> > Source/WebKit/UIProcess/DrawingAreaProxy.h:111
> > +    virtual void commitLayerTree(const RemoteLayerTreeTransaction&, const RemoteScrollingCoordinatorTransaction&) { ASSERT_NOT_REACHED(); }
> 
> Seems like a layering violation to have *remote* things here.

Err, yeah, what is wrong with me.

> > Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:132
> > +#if USE(UNIX_DOMAIN_SOCKETS) || OS(WINDOWS)
> > +        request.reply(GPUProcessConnectionInfo { WTFMove(*connectionIdentifier) });
> > +#elif OS(DARWIN)
> > +        MESSAGE_CHECK(MACH_PORT_VALID(connectionIdentifier->port()));
> > +        request.reply(GPUProcessConnectionInfo { IPC::Attachment { connectionIdentifier->port(), MACH_MSG_TYPE_MOVE_SEND } });
> > +#else
> > +        notImplemented();
> > +#endif
> 
> Should be hidden in a base class.

Maybe, though the types are unique to each child. Teeeeemplates?

> > Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:181
> > +    for (const auto& processPool : WebProcessPool::allProcessPools()) {
> > +        hasAnyForegroundWebProcesses |= processPool->hasForegroundWebProcesses();
> > +        hasAnyBackgroundWebProcesses |= processPool->hasBackgroundWebProcesses();
> > +    }
> 
> Does this get the right set of clients for this process?

This gets the set of ALL web processes for this UI process, which given the POR design are also the entire set of clients for the singleton GPU process. If that changes, we'll have to change this.

> > Source/WebKit/WebProcess/GPU/GPUProcessConnectionInfo.h:46
> > +#if USE(UNIX_DOMAIN_SOCKETS)
> > +        return IPC::Connection::Identifier(connection.fileDescriptor());
> > +#elif OS(DARWIN)
> > +        return IPC::Connection::Identifier(connection.port());
> > +#elif OS(WINDOWS)
> > +        return IPC::Connection::Identifier(connection.handle());
> > +#else
> > +        ASSERT_NOT_REACHED();
> > +        return IPC::Connection::Identifier();
> > +#endif
> 
> Boo

Are you a ghost.
Comment 20 Tim Horton 2019-12-03 22:51:10 PST
> > > Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:132
> > > +#if USE(UNIX_DOMAIN_SOCKETS) || OS(WINDOWS)
> > > +        request.reply(GPUProcessConnectionInfo { WTFMove(*connectionIdentifier) });
> > > +#elif OS(DARWIN)
> > > +        MESSAGE_CHECK(MACH_PORT_VALID(connectionIdentifier->port()));
> > > +        request.reply(GPUProcessConnectionInfo { IPC::Attachment { connectionIdentifier->port(), MACH_MSG_TYPE_MOVE_SEND } });
> > > +#else
> > > +        notImplemented();
> > > +#endif
> > 
> > Should be hidden in a base class.
> 
> Maybe, though the types are unique to each child. Teeeeemplates?

I'm going to leave this alone for this patch and revisit in a follow-up where we perhaps change how the Web Content process gets all of its connections (instead of factoring this out just to delete it).
Comment 21 Tim Horton 2019-12-03 23:12:49 PST
Created attachment 384790 [details]
Patch
Comment 22 WebKit Commit Bot 2019-12-04 01:58:30 PST
Comment on attachment 384790 [details]
Patch

Clearing flags on attachment: 384790

Committed r253098: <https://trac.webkit.org/changeset/253098>
Comment 23 WebKit Commit Bot 2019-12-04 01:58:33 PST
All reviewed patches have been landed.  Closing bug.