Title: [269824] trunk/Source
Revision
269824
Author
[email protected]
Date
2020-11-15 01:30:54 -0800 (Sun, 15 Nov 2020)

Log Message

Initial implementation of DOM rendering via the GPU process
https://bugs.webkit.org/show_bug.cgi?id=218928

Reviewed by Simon Fraser.

Source/WebCore:

No new tests; will be covered by all existing DOM rendering tests in GPU process mode.

* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/ConcreteImageBuffer.h:
* platform/graphics/ImageBuffer.h:
* platform/graphics/ImageBufferBackend.h:
(WebCore::ImageBufferBackend::isInUse const):
(WebCore::ImageBufferBackend::releaseGraphicsContext):
(WebCore::ImageBufferBackend::setVolatile):
(WebCore::ImageBufferBackend::releaseBufferToPool):
(WebCore::ImageBufferBackend::createFlusher):
* platform/graphics/cg/IOSurfacePool.cpp:
(WebCore::IOSurfacePool::takeSurface):
(WebCore::IOSurfacePool::markOlderSurfacesPurgeable):
* platform/graphics/cg/ImageBufferCGBackend.cpp:
(WebCore::ThreadSafeImageBufferFlusherCG::ThreadSafeImageBufferFlusherCG):
(WebCore::ImageBufferCGBackend::contextColorSpace):
(WebCore::ImageBufferCGBackend::setupContext const):
(WebCore::ImageBufferCGBackend::createFlusher):
(WebCore::ImageBufferCGBackend::setupContext): Deleted.
* platform/graphics/cg/ImageBufferCGBackend.h:
* platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:
(WebCore::ImageBufferIOSurfaceBackend::context const):
(WebCore::ImageBufferIOSurfaceBackend::isInUse const):
(WebCore::ImageBufferIOSurfaceBackend::releaseGraphicsContext):
(WebCore::ImageBufferIOSurfaceBackend::setVolatile):
(WebCore::ImageBufferIOSurfaceBackend::releaseBufferToPool):
* platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
Add isInUse, setVolatile, and releaseGraphicsContext to ImageBuffer,
to manage volatile surfaces; they're only implemented for in-process
IOSurface right now, in order to keep RemoteLayerBackingStore working
after transitioning it to ImageBuffer. A future patch will determine
how to implement this mechanism for remote IOSurfaces.

Add createFlusher to ImageBuffer, which returns an object that can
be tossed to a background queue, and has one method: flush(), which
blocks until the ImageBuffer's oustanding painting is flushed. This is
currently implemented for CG just by calling CGContextFlush. This
is used to abstract out RemoteLayerBackingStore's background-thread
flush of all surfaces.

* platform/graphics/cocoa/IOSurface.h:
* platform/graphics/cocoa/IOSurface.mm:
(WebCore::IOSurface::state const):
(WebCore::IOSurface::setVolatile):
(WebCore::operator<<):
(WebCore::IOSurface::setIsVolatile): Deleted.
Make use of VolatilityState instead of SurfaceState.

Source/WebKit:

* Shared/RemoteLayerTree/RemoteLayerBackingStore.h:
(WebKit::RemoteLayerBackingStore::hasFrontBuffer const):
(WebKit::RemoteLayerBackingStore::Buffer::operator bool const):
* Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::encode const):
(WebKit::RemoteLayerBackingStore::decode):
(WebKit::RemoteLayerBackingStore::pixelFormat const):
(WebKit::RemoteLayerBackingStore::bytesPerPixel const):
(WebKit::RemoteLayerBackingStore::swapToValidFrontBuffer):
(WebKit::RemoteLayerBackingStore::display):
(WebKit::RemoteLayerBackingStore::applyBackingStoreToLayer):
(WebKit::RemoteLayerBackingStore::takePendingFlusher):
(WebKit::RemoteLayerBackingStore::setBufferVolatility):
(WebKit::RemoteLayerBackingStore::Buffer::discard):
(WebKit::RemoteLayerBackingStore::drawInContext): Deleted.
(WebKit::RemoteLayerBackingStore::takeFrontContextPendingFlush): Deleted.
(WebKit::RemoteLayerBackingStore::surfaceBufferFormat const): Deleted.
Reimplement RemoteLayerBackingStore in terms of ImageBuffer instead of
using ShareableBitmap + IOSurface explicitly.
We use ConcreteImageBuffer versions of the shareable backends in the WebContent process
in the non-GPU-process case, and normal DisplayList-backed RemoteImageBufferProxies
in the GPU process case.

* UIProcess/ViewSnapshotStore.h:
* UIProcess/mac/ViewSnapshotStoreMac.mm:
(WebKit::ViewSnapshot::setVolatile):
(WebKit::ViewSnapshot::asLayerContents):
* WebProcess/GPU/graphics/ImageBufferBackendHandle.h:
* WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
(WebKit::ThreadSafeRemoteImageBufferFlusher::ThreadSafeRemoteImageBufferFlusher):
Add a hack to emulate ThreadSafeRemoteImageBufferFlusher; right now,
we'll synchronously flush on the main thread when creating the flusher;
a future patch will move this into the flush() method so that RemoteLayerBackingStore
can do it on a secondary queue.

(WebKit::RemoteImageBufferProxy::createImageBufferBackendHandle):
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::createImageBuffer const):
(WebKit::WebChromeClient::ensureRemoteRenderingBackendProxy const): Deleted.
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h:
* WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm:
(WebKit::RemoteLayerTreeContext::ensureRemoteRenderingBackendProxy):
* WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::updateRendering):
(WebKit::RemoteLayerTreeDrawingArea::BackingStoreFlusher::create):
(WebKit::RemoteLayerTreeDrawingArea::BackingStoreFlusher::BackingStoreFlusher):
(WebKit::RemoteLayerTreeDrawingArea::BackingStoreFlusher::flush):
Reimplement BackingStoreFlusher in terms of the abstract ThreadSafeImageBufferFlusher.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::ensureRemoteRenderingBackendProxy):
* WebProcess/WebPage/WebPage.h:
Move RemoteRenderingBackendProxy from WebChromeClient to WebPage, so that
other non-WebCore clients can use it without having to think about WebChromeClient.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (269823 => 269824)


--- trunk/Source/WebCore/ChangeLog	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/ChangeLog	2020-11-15 09:30:54 UTC (rev 269824)
@@ -1,3 +1,60 @@
+2020-11-15  Tim Horton  <[email protected]>
+
+        Initial implementation of DOM rendering via the GPU process
+        https://bugs.webkit.org/show_bug.cgi?id=218928
+
+        Reviewed by Simon Fraser.
+
+        No new tests; will be covered by all existing DOM rendering tests in GPU process mode.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/ConcreteImageBuffer.h:
+        * platform/graphics/ImageBuffer.h:
+        * platform/graphics/ImageBufferBackend.h:
+        (WebCore::ImageBufferBackend::isInUse const):
+        (WebCore::ImageBufferBackend::releaseGraphicsContext):
+        (WebCore::ImageBufferBackend::setVolatile):
+        (WebCore::ImageBufferBackend::releaseBufferToPool):
+        (WebCore::ImageBufferBackend::createFlusher):
+        * platform/graphics/cg/IOSurfacePool.cpp:
+        (WebCore::IOSurfacePool::takeSurface):
+        (WebCore::IOSurfacePool::markOlderSurfacesPurgeable):
+        * platform/graphics/cg/ImageBufferCGBackend.cpp:
+        (WebCore::ThreadSafeImageBufferFlusherCG::ThreadSafeImageBufferFlusherCG):
+        (WebCore::ImageBufferCGBackend::contextColorSpace):
+        (WebCore::ImageBufferCGBackend::setupContext const):
+        (WebCore::ImageBufferCGBackend::createFlusher):
+        (WebCore::ImageBufferCGBackend::setupContext): Deleted.
+        * platform/graphics/cg/ImageBufferCGBackend.h:
+        * platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:
+        (WebCore::ImageBufferIOSurfaceBackend::context const):
+        (WebCore::ImageBufferIOSurfaceBackend::isInUse const):
+        (WebCore::ImageBufferIOSurfaceBackend::releaseGraphicsContext):
+        (WebCore::ImageBufferIOSurfaceBackend::setVolatile):
+        (WebCore::ImageBufferIOSurfaceBackend::releaseBufferToPool):
+        * platform/graphics/cg/ImageBufferIOSurfaceBackend.h:
+        Add isInUse, setVolatile, and releaseGraphicsContext to ImageBuffer,
+        to manage volatile surfaces; they're only implemented for in-process
+        IOSurface right now, in order to keep RemoteLayerBackingStore working
+        after transitioning it to ImageBuffer. A future patch will determine
+        how to implement this mechanism for remote IOSurfaces.
+
+        Add createFlusher to ImageBuffer, which returns an object that can
+        be tossed to a background queue, and has one method: flush(), which
+        blocks until the ImageBuffer's oustanding painting is flushed. This is
+        currently implemented for CG just by calling CGContextFlush. This
+        is used to abstract out RemoteLayerBackingStore's background-thread
+        flush of all surfaces.
+
+        * platform/graphics/cocoa/IOSurface.h:
+        * platform/graphics/cocoa/IOSurface.mm:
+        (WebCore::IOSurface::state const):
+        (WebCore::IOSurface::setVolatile):
+        (WebCore::operator<<):
+        (WebCore::IOSurface::setIsVolatile): Deleted.
+        Make use of VolatilityState instead of SurfaceState.
+
+
 2020-11-15  Julian Gonzalez  <[email protected]>
 
         Font::platformBoundsForGlyph() should provide a boundingRect pointer to CTFontGetBoundingRectsForGlyphs()

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (269823 => 269824)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-11-15 09:30:54 UTC (rev 269824)
@@ -753,6 +753,8 @@
 		2D6F3E911C1ECB2F0061DBD4 /* MockPageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D6F3E8B1C1ECB1C0061DBD4 /* MockPageOverlay.h */; };
 		2D70BA1318074DDF0001908A /* PlatformCALayerCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D70BA1218074DDF0001908A /* PlatformCALayerCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2D76BB821945632400CFD29A /* RunLoopObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D76BB801945632400CFD29A /* RunLoopObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		2D7705C7255276CD001D0C94 /* PlatformImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BAC3A623E17328008D741C /* PlatformImageBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		2D7705C925528D34001D0C94 /* ImageBufferCGBitmapBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BAC3AA23E1E544008D741C /* ImageBufferCGBitmapBackend.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2D7DA0F22435EB1900F048D1 /* WebViewVisualIdentificationOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7DA0EF2435EB1700F048D1 /* WebViewVisualIdentificationOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		2D7ED0AB1BAE99170043B3E5 /* TimerEventBasedMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D7ED0A91BAE99170043B3E5 /* TimerEventBasedMock.h */; };
 		2D8287F716E4A0380086BD00 /* HitTestLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D8287F516E4A0380086BD00 /* HitTestLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -32181,6 +32183,7 @@
 				B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */,
 				72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */,
 				550640B02407587E00AAE045 /* ImageBufferCGBackend.h in Headers */,
+				2D7705C925528D34001D0C94 /* ImageBufferCGBitmapBackend.h in Headers */,
 				727A7F3A24078B84004D2931 /* ImageBufferIOSurfaceBackend.h in Headers */,
 				B2A10D910B3818BD00099AA4 /* ImageBufferPipe.h in Headers */,
 				CD3E21DD2183444A00E66F55 /* ImageBufferUtilitiesCG.h in Headers */,
@@ -33714,6 +33717,7 @@
 				A723F77B1484CA4C008C6DBE /* PlatformExportMacros.h in Headers */,
 				515BE1951D54F5FB00DD7C68 /* PlatformGamepad.h in Headers */,
 				726D56E2253AE28D0002EF90 /* PlatformImage.h in Headers */,
+				2D7705C7255276CD001D0C94 /* PlatformImageBuffer.h in Headers */,
 				550640AF2407582D00AAE045 /* PlatformImageBufferBackend.h in Headers */,
 				935C476809AC4D4300A6AAB4 /* PlatformKeyboardEvent.h in Headers */,
 				0562F9611573F88F0031CA16 /* PlatformLayer.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/ConcreteImageBuffer.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -258,6 +258,39 @@
         return false;
     }
 
+    bool isInUse() const override
+    {
+        if (auto* backend = ensureBackendCreated())
+            return backend->isInUse();
+        return false;
+    }
+
+    void releaseGraphicsContext() override
+    {
+        if (auto* backend = ensureBackendCreated())
+            return backend->releaseGraphicsContext();
+    }
+
+    VolatilityState setVolatile(bool isVolatile) override
+    {
+        if (auto* backend = ensureBackendCreated())
+            return backend->setVolatile(isVolatile);
+        return VolatilityState::Valid;
+    }
+
+    std::unique_ptr<ThreadSafeImageBufferFlusher> createFlusher() override
+    {
+        if (auto* backend = ensureBackendCreated())
+            return backend->createFlusher();
+        return nullptr;
+    }
+
+    void releaseBufferToPool() override
+    {
+        if (auto* backend = ensureBackendCreated())
+            backend->releaseBufferToPool();
+    }
+
     std::unique_ptr<BackendType> m_backend;
     RenderingResourceIdentifier m_renderingResourceIdentifier;
 };

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.h (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -83,6 +83,13 @@
     virtual size_t memoryCost() const = 0;
     virtual size_t externalMemoryCost() const = 0;
 
+    virtual bool isInUse() const = 0;
+    virtual void releaseGraphicsContext() = 0;
+    virtual VolatilityState setVolatile(bool) = 0;
+    virtual void releaseBufferToPool() = 0;
+
+    virtual std::unique_ptr<ThreadSafeImageBufferFlusher> createFlusher() = 0;
+
     virtual RefPtr<NativeImage> copyNativeImage(BackingStoreCopy = CopyBackingStore) const = 0;
     virtual RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const = 0;
 

Modified: trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/ImageBufferBackend.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -61,6 +61,20 @@
     RGB10A8,
 };
 
+enum class VolatilityState : uint8_t {
+    Valid,
+    Empty
+};
+
+class ThreadSafeImageBufferFlusher {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(ThreadSafeImageBufferFlusher);
+public:
+    ThreadSafeImageBufferFlusher() = default;
+    virtual ~ThreadSafeImageBufferFlusher() = default;
+    virtual void flush() = 0;
+};
+
 class ImageBufferBackend {
 public:
     WEBCORE_EXPORT virtual ~ImageBufferBackend() = default;
@@ -104,6 +118,13 @@
 
     virtual PlatformLayer* platformLayer() const { return nullptr; }
     virtual bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; }
+
+    virtual bool isInUse() const { return false; }
+    virtual void releaseGraphicsContext() { ASSERT_NOT_REACHED(); }
+    virtual VolatilityState setVolatile(bool) { return VolatilityState::Valid; }
+    virtual void releaseBufferToPool() { }
+
+    virtual std::unique_ptr<ThreadSafeImageBufferFlusher> createFlusher() { return nullptr; }
     
     static constexpr bool isOriginAtUpperLeftCorner = false;
     static constexpr bool isAccelerated = false;

Modified: trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cg/IOSurfacePool.cpp	2020-11-15 09:30:54 UTC (rev 269824)
@@ -131,7 +131,7 @@
 
         didRemoveSurface(*surface, false);
 
-        surface->setIsVolatile(false);
+        surface->setVolatile(false);
 
         DUMP_POOL_STATISTICS("takeSurface - taking");
         return surface;
@@ -148,7 +148,7 @@
         m_inUseSurfaces.remove(surfaceIter);
         didRemoveSurface(*surface, true);
 
-        surface->setIsVolatile(false);
+        surface->setVolatile(false);
 
         DUMP_POOL_STATISTICS("takeSurface - taking in-use");
         return surface;
@@ -298,7 +298,7 @@
             continue;
         }
 
-        surfaceAndDetails.key->setIsVolatile(true);
+        surfaceAndDetails.key->setVolatile(true);
         surfaceAndDetails.value.hasMarkedPurgeable = true;
     }
 

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp	2020-11-15 09:30:54 UTC (rev 269824)
@@ -43,6 +43,23 @@
 
 namespace WebCore {
 
+class ThreadSafeImageBufferFlusherCG : public ThreadSafeImageBufferFlusher {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ThreadSafeImageBufferFlusherCG(CGContextRef context)
+        : m_context(context)
+    {
+    }
+
+    void flush() override
+    {
+        CGContextFlush(m_context.get());
+    }
+
+private:
+    RetainPtr<CGContextRef> m_context;
+};
+
 RetainPtr<CGColorSpaceRef> ImageBufferCGBackend::contextColorSpace(const GraphicsContext& context)
 {
 #if PLATFORM(COCOA)
@@ -57,9 +74,8 @@
     return nullptr;
 #endif
 }
-#
 
-void ImageBufferCGBackend::setupContext()
+void ImageBufferCGBackend::setupContext() const
 {
     // The initial CTM matches DisplayList::Recorder::clipToDrawingCommands()'s initial CTM.
     context().scale(FloatSize(1, -1));
@@ -207,6 +223,11 @@
     return "data:,"_s;
 }
 
+std::unique_ptr<ThreadSafeImageBufferFlusher> ImageBufferCGBackend::createFlusher()
+{
+    return WTF::makeUnique<ThreadSafeImageBufferFlusherCG>(context().platformContext());
+}
+
 #if USE(ACCELERATE)
 static inline vImage_Buffer makeVImageBuffer(unsigned bytesPerRow, uint8_t* rows, const IntSize& size)
 {

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.h (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -46,11 +46,13 @@
     String toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const override;
     Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override;
 
+    std::unique_ptr<ThreadSafeImageBufferFlusher> createFlusher() override;
+
 protected:
     using ImageBufferBackend::ImageBufferBackend;
 
     static RetainPtr<CGColorSpaceRef> contextColorSpace(const GraphicsContext&);
-    void setupContext();
+    void setupContext() const;
     virtual RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const;
 
 #if USE(ACCELERATE)

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp	2020-11-15 09:30:54 UTC (rev 269824)
@@ -106,7 +106,13 @@
 
 GraphicsContext& ImageBufferIOSurfaceBackend::context() const
 {
-    return m_surface->ensureGraphicsContext();
+
+    GraphicsContext& context = m_surface->ensureGraphicsContext();
+    if (m_needsSetupContext) {
+        m_needsSetupContext = false;
+        setupContext();
+    }
+    return context;
 }
 
 void ImageBufferIOSurfaceBackend::flushContext()
@@ -184,6 +190,27 @@
     return m_surface.get();
 }
 
+bool ImageBufferIOSurfaceBackend::isInUse() const
+{
+    return m_surface->isInUse();
+}
+
+void ImageBufferIOSurfaceBackend::releaseGraphicsContext()
+{
+    m_needsSetupContext = true;
+    return m_surface->releaseGraphicsContext();
+}
+
+VolatilityState ImageBufferIOSurfaceBackend::setVolatile(bool isVolatile)
+{
+    return m_surface->setVolatile(isVolatile);
+}
+
+void ImageBufferIOSurfaceBackend::releaseBufferToPool()
+{
+    IOSurface::moveToPool(WTFMove(m_surface));
+}
+
 } // namespace WebCore
 
 #endif // HAVE(IOSURFACE)

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -63,6 +63,11 @@
     void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint, AlphaPremultiplication destFormat) override;
     IOSurface* surface();
 
+    bool isInUse() const override;
+    void releaseGraphicsContext() override;
+    VolatilityState setVolatile(bool) override;
+    void releaseBufferToPool() override;
+
     static constexpr bool isOriginAtUpperLeftCorner = true;
     static constexpr bool isAccelerated = true;
 
@@ -72,6 +77,8 @@
 
     std::unique_ptr<IOSurface> m_surface;
     mutable bool m_requiresDrawAfterPutImageData { false };
+
+    mutable bool m_needsSetupContext { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -50,6 +50,7 @@
 #endif
 
 enum class PixelFormat : uint8_t;
+enum class VolatilityState : uint8_t;
 
 class IOSurface final {
     WTF_MAKE_FAST_ALLOCATED;
@@ -128,19 +129,13 @@
     WEBCORE_EXPORT GraphicsContext& ensureGraphicsContext();
     WEBCORE_EXPORT CGContextRef ensurePlatformContext(const HostWindow* = nullptr);
 
-    enum class SurfaceState {
-        Valid,
-        Empty
-    };
-
     // Querying volatility can be expensive, so in cases where the surface is
-    // going to be used immediately, use the return value of setIsVolatile to
+    // going to be used immediately, use the return value of setVolatile to
     // determine whether the data was purged, instead of first calling state() or isVolatile().
-    SurfaceState state() const;
+    VolatilityState state() const;
     bool isVolatile() const;
 
-    // setIsVolatile only has an effect on iOS and OS 10.9 and above.
-    WEBCORE_EXPORT SurfaceState setIsVolatile(bool);
+    WEBCORE_EXPORT VolatilityState setVolatile(bool);
 
     IntSize size() const { return m_size; }
     size_t totalBytes() const { return m_totalBytes; }

Modified: trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm (269823 => 269824)


--- trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebCore/platform/graphics/cocoa/IOSurface.mm	2020-11-15 09:30:54 UTC (rev 269824)
@@ -324,12 +324,12 @@
     return *m_graphicsContext;
 }
 
-IOSurface::SurfaceState IOSurface::state() const
+VolatilityState IOSurface::state() const
 {
     uint32_t previousState = 0;
     IOReturn ret = IOSurfaceSetPurgeable(m_surface.get(), kIOSurfacePurgeableKeepCurrent, &previousState);
     ASSERT_UNUSED(ret, ret == kIOReturnSuccess);
-    return previousState == kIOSurfacePurgeableEmpty ? IOSurface::SurfaceState::Empty : IOSurface::SurfaceState::Valid;
+    return previousState == kIOSurfacePurgeableEmpty ? VolatilityState::Empty : VolatilityState::Valid;
 }
 
 bool IOSurface::isVolatile() const
@@ -340,7 +340,7 @@
     return previousState != kIOSurfacePurgeableNonVolatile;
 }
 
-IOSurface::SurfaceState IOSurface::setIsVolatile(bool isVolatile)
+VolatilityState IOSurface::setVolatile(bool isVolatile)
 {
     uint32_t previousState = 0;
     IOReturn ret = IOSurfaceSetPurgeable(m_surface.get(), isVolatile ? kIOSurfacePurgeableVolatile : kIOSurfacePurgeableNonVolatile, &previousState);
@@ -347,9 +347,9 @@
     ASSERT_UNUSED(ret, ret == kIOReturnSuccess);
 
     if (previousState == kIOSurfacePurgeableEmpty)
-        return IOSurface::SurfaceState::Empty;
+        return VolatilityState::Empty;
 
-    return IOSurface::SurfaceState::Valid;
+    return VolatilityState::Valid;
 }
 
 IOSurface::Format IOSurface::format() const
@@ -505,13 +505,13 @@
     return ts;
 }
 
-static TextStream& operator<<(TextStream& ts, IOSurface::SurfaceState state)
+static TextStream& operator<<(TextStream& ts, VolatilityState state)
 {
     switch (state) {
-    case IOSurface::SurfaceState::Valid:
+    case VolatilityState::Valid:
         ts << "valid";
         break;
-    case IOSurface::SurfaceState::Empty:
+    case VolatilityState::Empty:
         ts << "empty";
         break;
     }

Modified: trunk/Source/WebKit/ChangeLog (269823 => 269824)


--- trunk/Source/WebKit/ChangeLog	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/ChangeLog	2020-11-15 09:30:54 UTC (rev 269824)
@@ -1,3 +1,67 @@
+2020-11-15  Tim Horton  <[email protected]>
+
+        Initial implementation of DOM rendering via the GPU process
+        https://bugs.webkit.org/show_bug.cgi?id=218928
+
+        Reviewed by Simon Fraser.
+
+        * Shared/RemoteLayerTree/RemoteLayerBackingStore.h:
+        (WebKit::RemoteLayerBackingStore::hasFrontBuffer const):
+        (WebKit::RemoteLayerBackingStore::Buffer::operator bool const):
+        * Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
+        (WebKit::RemoteLayerBackingStore::encode const):
+        (WebKit::RemoteLayerBackingStore::decode):
+        (WebKit::RemoteLayerBackingStore::pixelFormat const):
+        (WebKit::RemoteLayerBackingStore::bytesPerPixel const):
+        (WebKit::RemoteLayerBackingStore::swapToValidFrontBuffer):
+        (WebKit::RemoteLayerBackingStore::display):
+        (WebKit::RemoteLayerBackingStore::applyBackingStoreToLayer):
+        (WebKit::RemoteLayerBackingStore::takePendingFlusher):
+        (WebKit::RemoteLayerBackingStore::setBufferVolatility):
+        (WebKit::RemoteLayerBackingStore::Buffer::discard):
+        (WebKit::RemoteLayerBackingStore::drawInContext): Deleted.
+        (WebKit::RemoteLayerBackingStore::takeFrontContextPendingFlush): Deleted.
+        (WebKit::RemoteLayerBackingStore::surfaceBufferFormat const): Deleted.
+        Reimplement RemoteLayerBackingStore in terms of ImageBuffer instead of
+        using ShareableBitmap + IOSurface explicitly.
+        We use ConcreteImageBuffer versions of the shareable backends in the WebContent process
+        in the non-GPU-process case, and normal DisplayList-backed RemoteImageBufferProxies
+        in the GPU process case.
+
+        * UIProcess/ViewSnapshotStore.h:
+        * UIProcess/mac/ViewSnapshotStoreMac.mm:
+        (WebKit::ViewSnapshot::setVolatile):
+        (WebKit::ViewSnapshot::asLayerContents):
+        * WebProcess/GPU/graphics/ImageBufferBackendHandle.h:
+        * WebProcess/GPU/graphics/RemoteImageBufferProxy.h:
+        (WebKit::ThreadSafeRemoteImageBufferFlusher::ThreadSafeRemoteImageBufferFlusher):
+        Add a hack to emulate ThreadSafeRemoteImageBufferFlusher; right now,
+        we'll synchronously flush on the main thread when creating the flusher;
+        a future patch will move this into the flush() method so that RemoteLayerBackingStore
+        can do it on a secondary queue.
+
+        (WebKit::RemoteImageBufferProxy::createImageBufferBackendHandle):
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::createImageBuffer const):
+        (WebKit::WebChromeClient::ensureRemoteRenderingBackendProxy const): Deleted.
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h:
+        * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm:
+        (WebKit::RemoteLayerTreeContext::ensureRemoteRenderingBackendProxy):
+        * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h:
+        * WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::updateRendering):
+        (WebKit::RemoteLayerTreeDrawingArea::BackingStoreFlusher::create):
+        (WebKit::RemoteLayerTreeDrawingArea::BackingStoreFlusher::BackingStoreFlusher):
+        (WebKit::RemoteLayerTreeDrawingArea::BackingStoreFlusher::flush):
+        Reimplement BackingStoreFlusher in terms of the abstract ThreadSafeImageBufferFlusher.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::ensureRemoteRenderingBackendProxy):
+        * WebProcess/WebPage/WebPage.h:
+        Move RemoteRenderingBackendProxy from WebChromeClient to WebPage, so that
+        other non-WebCore clients can use it without having to think about WebChromeClient.
+
 2020-11-14  Zan Dobersek  <[email protected]>
 
         Unreviewed, suppressing GCC compilation warnings.

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h (269823 => 269824)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "ShareableBitmap.h"
+#include "ImageBufferBackendHandle.h"
 #include <WebCore/FloatRect.h>
 #include <WebCore/IOSurface.h>
 #include <WebCore/Region.h>
@@ -37,6 +37,7 @@
 // FIXME: Make PlatformCALayerRemote.cpp Objective-C so we can include WebLayer.h here and share the typedef.
 namespace WebCore {
 class NativeImage;
+class ThreadSafeImageBufferFlusher;
 typedef Vector<WebCore::FloatRect, 5> RepaintRectList;
 }
 
@@ -76,14 +77,10 @@
 
     bool hasFrontBuffer() const
     {
-#if HAVE(IOSURFACE)
-        if (m_acceleratesDrawing)
-            return !!m_frontBuffer.surface;
-#endif
-        return !!m_frontBuffer.bitmap;
+        return !!m_frontBuffer.imageBuffer;
     }
 
-    RetainPtr<CGContextRef> takeFrontContextPendingFlush();
+    std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> takePendingFlusher();
 
     enum class BufferType {
         Front,
@@ -97,14 +94,11 @@
     MonotonicTime lastDisplayTime() const { return m_lastDisplayTime; }
 
 private:
-    void drawInContext(WebCore::GraphicsContext&, RefPtr<WebCore::NativeImage>&& backImage);
+    void drawInContext(WebCore::GraphicsContext&);
     void clearBackingStore();
     void swapToValidFrontBuffer();
 
-#if HAVE(IOSURFACE)
-    WebCore::IOSurface::Format surfaceBufferFormat() const;
-#endif
-
+    WebCore::PixelFormat pixelFormat() const;
     WebCore::IntSize backingStoreSize() const;
 
     PlatformCALayerRemote* m_layer;
@@ -116,22 +110,12 @@
     WebCore::Region m_dirtyRegion;
 
     struct Buffer {
-        RefPtr<ShareableBitmap> bitmap;
-#if HAVE(IOSURFACE)
-        std::unique_ptr<WebCore::IOSurface> surface;
+        RefPtr<WebCore::ImageBuffer> imageBuffer;
         bool isVolatile = false;
-#endif
 
         explicit operator bool() const
         {
-#if HAVE(IOSURFACE)
-            if (surface)
-                return true;
-#endif
-            if (bitmap)
-                return true;
-
-            return false;
+            return !!imageBuffer;
         }
 
         void discard();
@@ -139,12 +123,10 @@
 
     Buffer m_frontBuffer;
     Buffer m_backBuffer;
-#if HAVE(IOSURFACE)
     Buffer m_secondaryBackBuffer;
-    WTF::MachSendRight m_frontBufferSendRight;
-#endif
+    Optional<ImageBufferBackendHandle> m_bufferHandle;
 
-    RetainPtr<CGContextRef> m_frontContextPendingFlush;
+    std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> m_frontBufferFlusher;
 
     bool m_acceleratesDrawing { false };
     bool m_deepColor { false };

Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm (269823 => 269824)


--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm	2020-11-15 09:30:54 UTC (rev 269824)
@@ -29,13 +29,16 @@
 #import "ArgumentCoders.h"
 #import "MachPort.h"
 #import "PlatformCALayerRemote.h"
+#import "PlatformRemoteImageBufferProxy.h"
 #import "RemoteLayerBackingStoreCollection.h"
 #import "RemoteLayerTreeContext.h"
 #import "ShareableBitmap.h"
 #import "WebCoreArgumentCoders.h"
+#import "WebProcess.h"
 #import <QuartzCore/QuartzCore.h>
 #import <WebCore/GraphicsContextCG.h>
 #import <WebCore/IOSurface.h>
+#import <WebCore/ImageBuffer.h>
 #import <WebCore/PlatformCALayerClient.h>
 #import <WebCore/WebLayer.h>
 #import <mach/mach_port.h>
@@ -99,18 +102,15 @@
     encoder << m_acceleratesDrawing;
     encoder << m_isOpaque;
 
-    if (m_acceleratesDrawing) {
-        if (m_frontBuffer.surface)
-            encoder << m_frontBuffer.surface->createSendRight();
+    Optional<ImageBufferBackendHandle> handle;
+    if (m_frontBuffer.imageBuffer) {
+        // FIXME: We need to flatten the class hierarchy so we can avoid this bifurcation.
+        if (m_acceleratesDrawing)
+            handle = static_cast<AcceleratedRemoteImageBufferProxy *>(m_frontBuffer.imageBuffer.get())->createImageBufferBackendHandle();
         else
-            encoder << WTF::MachSendRight();
-        return;
+            handle = static_cast<UnacceleratedRemoteImageBufferProxy *>(m_frontBuffer.imageBuffer.get())->createImageBufferBackendHandle();
     }
 
-    ASSERT(!m_acceleratesDrawing);
-
-    ShareableBitmap::Handle handle;
-    m_frontBuffer.bitmap->createHandle(handle);
     encoder << handle;
 }
 
@@ -128,20 +128,8 @@
     if (!decoder.decode(result.m_isOpaque))
         return false;
 
-    if (result.m_acceleratesDrawing) {
-        MachSendRight sendRight;
-        if (!decoder.decode(sendRight))
-            return false;
-        result.m_frontBufferSendRight = WTFMove(sendRight);
-        return true;
-    }
-
-    ASSERT(!result.m_acceleratesDrawing);
-
-    ShareableBitmap::Handle handle;
-    if (!decoder.decode(handle))
+    if (!decoder.decode(result.m_bufferHandle))
         return false;
-    result.m_frontBuffer.bitmap = ShareableBitmap::create(handle);
 
     return true;
 }
@@ -163,15 +151,23 @@
     return roundedIntSize(scaledSize);
 }
 
-unsigned RemoteLayerBackingStore::bytesPerPixel() const
+WebCore::PixelFormat RemoteLayerBackingStore::pixelFormat() const
 {
-    switch (surfaceBufferFormat()) {
-    case WebCore::IOSurface::Format::BGRA: return 4;
-    case WebCore::IOSurface::Format::YUV422: return 2;
 #if HAVE(IOSURFACE_RGB10)
-    case WebCore::IOSurface::Format::RGB10: return 4;
-    case WebCore::IOSurface::Format::RGB10A8: return 5;
+    if (m_acceleratesDrawing && m_deepColor)
+        return m_isOpaque ? WebCore::PixelFormat::RGB10 : WebCore::PixelFormat::RGB10A8;
 #endif
+
+    return WebCore::PixelFormat::BGRA8;
+}
+
+unsigned RemoteLayerBackingStore::bytesPerPixel() const
+{
+    switch (pixelFormat()) {
+    case WebCore::PixelFormat::RGBA8: return 4;
+    case WebCore::PixelFormat::BGRA8: return 4;
+    case WebCore::PixelFormat::RGB10: return 4;
+    case WebCore::PixelFormat::RGB10A8: return 5;
     }
     return 4;
 }
@@ -178,37 +174,25 @@
 
 void RemoteLayerBackingStore::swapToValidFrontBuffer()
 {
-    WebCore::IntSize expandedScaledSize = backingStoreSize();
+    std::swap(m_frontBuffer, m_backBuffer);
 
-    if (m_acceleratesDrawing) {
-        if (!m_backBuffer.surface || m_backBuffer.surface->isInUse()) {
-            std::swap(m_backBuffer, m_secondaryBackBuffer);
-            if (m_backBuffer.surface && m_backBuffer.surface->isInUse())
-                m_backBuffer.discard();
-        }
+    if (m_frontBuffer.imageBuffer)
+        return;
 
-        std::swap(m_frontBuffer, m_backBuffer);
-
-        if (!m_frontBuffer.surface)
-            m_frontBuffer.surface = WebCore::IOSurface::create(expandedScaledSize, WebCore::sRGBColorSpaceRef(), surfaceBufferFormat());
-
-        setBufferVolatility(BufferType::Front, false);
+    if (WebProcess::singleton().shouldUseRemoteRenderingFor(WebCore::RenderingPurpose::DOM)) {
+        m_frontBuffer.imageBuffer = m_layer->context()->ensureRemoteRenderingBackendProxy().createImageBuffer(backingStoreSize(), m_acceleratesDrawing ? WebCore::RenderingMode::Accelerated : WebCore::RenderingMode::Unaccelerated, 1, WebCore::ColorSpace::SRGB, pixelFormat());
         return;
     }
 
-    ASSERT(!m_acceleratesDrawing);
-    std::swap(m_frontBuffer, m_backBuffer);
-
-    if (!m_frontBuffer.bitmap) {
-        ShareableBitmap::Configuration bitmapConfiguration;
-        bitmapConfiguration.isOpaque = m_isOpaque;
-        m_frontBuffer.bitmap = ShareableBitmap::createShareable(expandedScaledSize, bitmapConfiguration);
-    }
+    if (m_acceleratesDrawing)
+        m_frontBuffer.imageBuffer = WebCore::ConcreteImageBuffer<AcceleratedImageBufferShareableBackend>::create(backingStoreSize(), 1, WebCore::ColorSpace::SRGB, pixelFormat(), nullptr);
+    else
+        m_frontBuffer.imageBuffer = WebCore::ConcreteImageBuffer<UnacceleratedImageBufferShareableBackend>::create(backingStoreSize(), 1, WebCore::ColorSpace::SRGB, pixelFormat(), nullptr);
 }
 
 bool RemoteLayerBackingStore::display()
 {
-    ASSERT(!m_frontContextPendingFlush);
+    ASSERT(!m_frontBufferFlusher);
 
     m_lastDisplayTime = MonotonicTime::now();
 
@@ -234,43 +218,13 @@
     }
 
     WebCore::IntRect expandedScaledLayerBounds(WebCore::IntPoint(), expandedScaledSize);
-    bool willPaintEntireBackingStore = m_dirtyRegion.contains(layerBounds);
 
     swapToValidFrontBuffer();
 
-    if (m_acceleratesDrawing) {
-        RefPtr<WebCore::NativeImage> backImage;
-        if (m_backBuffer.surface && !willPaintEntireBackingStore)
-            backImage = WebCore::NativeImage::create(m_backBuffer.surface->createImage().get());
+    WebCore::GraphicsContext& context = m_frontBuffer.imageBuffer->context();
 
-        if (m_frontBuffer.surface) {
-            WebCore::GraphicsContext& context = m_frontBuffer.surface->ensureGraphicsContext();
+    WebCore::GraphicsContextStateSaver stateSaver(context);
 
-            context.scale(WebCore::FloatSize(1, -1));
-            context.translate(0, -expandedScaledSize.height());
-            drawInContext(context, WTFMove(backImage));
-
-            m_frontBuffer.surface->releaseGraphicsContext();
-        }
-    } else {
-        ASSERT(!m_acceleratesDrawing);
-        std::unique_ptr<WebCore::GraphicsContext> context = m_frontBuffer.bitmap->createGraphicsContext();
-
-        RefPtr<WebCore::NativeImage> backImage;
-        if (m_backBuffer.bitmap && !willPaintEntireBackingStore)
-            backImage = WebCore::NativeImage::create(m_backBuffer.bitmap->makeCGImage().get());
-
-        if (context)
-            drawInContext(*context, WTFMove(backImage));
-    }
-    
-    m_layer->owner()->platformCALayerLayerDidDisplay(m_layer);
-    
-    return true;
-}
-
-void RemoteLayerBackingStore::drawInContext(WebCore::GraphicsContext& context, RefPtr<WebCore::NativeImage>&& backImage)
-{
     WebCore::FloatSize scaledSize = m_size;
     scaledSize.scale(m_scale);
     WebCore::IntRect scaledLayerBounds(WebCore::IntPoint(), WebCore::roundedIntSize(scaledSize));
@@ -295,8 +249,10 @@
         m_paintingRects.append(scaledRect);
     }
 
-    if (backImage)
-        context.drawNativeImage(*backImage, scaledLayerBounds.size(), scaledLayerBounds, scaledLayerBounds, { WebCore::CompositeOperator::Copy });
+    if (!m_dirtyRegion.contains(layerBounds)) {
+        ASSERT(m_backBuffer.imageBuffer);
+        context.drawImageBuffer(*m_backBuffer.imageBuffer, { 0, 0 });
+    }
 
     if (m_paintingRects.size() == 1) {
         WebCore::FloatRect scaledPaintingRect = m_paintingRects[0];
@@ -357,7 +313,14 @@
     m_dirtyRegion = WebCore::Region();
     m_paintingRects.clear();
 
-    m_frontContextPendingFlush = context.platformContext();
+    m_frontBufferFlusher = m_frontBuffer.imageBuffer->createFlusher();
+
+    m_layer->owner()->platformCALayerLayerDidDisplay(m_layer);
+
+    // FIXME: This method has a weird name. This is "submit work".
+    m_frontBuffer.imageBuffer->flushDrawingContextAndCommit();
+
+    return true;
 }
 
 void RemoteLayerBackingStore::enumerateRectsBeingDrawn(WebCore::GraphicsContext& context, void (^block)(WebCore::FloatRect))
@@ -377,20 +340,18 @@
 
 void RemoteLayerBackingStore::applyBackingStoreToLayer(CALayer *layer, LayerContentsType contentsType)
 {
+    ASSERT(m_bufferHandle);
     layer.contentsOpaque = m_isOpaque;
 
     if (acceleratesDrawing()) {
         switch (contentsType) {
-        case LayerContentsType::IOSurface:
-            if (!m_frontBuffer.surface) {
-                ASSERT(m_frontBufferSendRight);
-                m_frontBuffer.surface = WebCore::IOSurface::createFromSendRight(WTFMove(m_frontBufferSendRight), WebCore::sRGBColorSpaceRef());
-            }
-            layer.contents = m_frontBuffer.surface ? m_frontBuffer.surface->asLayerContents() : nil;
+        case LayerContentsType::IOSurface: {
+            auto surface = WebCore::IOSurface::createFromSendRight(WTFMove(WTF::get<MachSendRight>(*m_bufferHandle)), WebCore::sRGBColorSpaceRef());
+            layer.contents = surface ? surface->asLayerContents() : nil;
             break;
+        }
         case LayerContentsType::CAMachPort:
-            ASSERT(m_frontBufferSendRight);
-            layer.contents = (__bridge id)adoptCF(CAMachPortCreate(m_frontBufferSendRight.leakSendRight())).get();
+            layer.contents = (__bridge id)adoptCF(CAMachPortCreate(WTF::get<MachSendRight>(*m_bufferHandle).leakSendRight())).get();
             break;
         }
         return;
@@ -397,25 +358,29 @@
     }
 
     ASSERT(!acceleratesDrawing());
-    layer.contents = (__bridge id)m_frontBuffer.bitmap->makeCGImageCopy().get();
+    auto bitmap = ShareableBitmap::create(WTF::get<ShareableBitmap::Handle>(*m_bufferHandle));
+    layer.contents = (__bridge id)bitmap->makeCGImageCopy().get();
 }
 
-RetainPtr<CGContextRef> RemoteLayerBackingStore::takeFrontContextPendingFlush()
+std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> RemoteLayerBackingStore::takePendingFlusher()
 {
-    return WTFMove(m_frontContextPendingFlush);
+    return std::exchange(m_frontBufferFlusher, nullptr);
 }
 
 bool RemoteLayerBackingStore::setBufferVolatility(BufferType type, bool isVolatile)
 {
+    if (!acceleratesDrawing())
+        return true;
+
     // Return value is true if we succeeded in making volatile.
     auto makeVolatile = [] (Buffer& buffer) -> bool {
-        if (!buffer.surface || buffer.isVolatile)
+        if (!buffer.imageBuffer || buffer.isVolatile)
             return true;
 
-        buffer.surface->releaseGraphicsContext();
+        buffer.imageBuffer->releaseGraphicsContext();
 
-        if (!buffer.surface->isInUse()) {
-            buffer.surface->setIsVolatile(true);
+        if (!buffer.imageBuffer->isInUse()) {
+            buffer.imageBuffer->setVolatile(true);
             buffer.isVolatile = true;
             return true;
         }
@@ -425,13 +390,13 @@
 
     // Return value is true if we need to repaint.
     auto makeNonVolatile = [] (Buffer& buffer) -> bool {
-        if (!buffer.surface || !buffer.isVolatile)
+        if (!buffer.imageBuffer || !buffer.isVolatile)
             return false;
 
-        auto previousState = buffer.surface->setIsVolatile(false);
+        auto previousState = buffer.imageBuffer->setVolatile(false);
         buffer.isVolatile = false;
 
-        return previousState == WebCore::IOSurface::SurfaceState::Empty;
+        return previousState == WebCore::VolatilityState::Empty;
     };
 
     switch (type) {
@@ -461,20 +426,10 @@
 
 void RemoteLayerBackingStore::Buffer::discard()
 {
-    if (surface)
-        WebCore::IOSurface::moveToPool(WTFMove(surface));
     isVolatile = false;
-    bitmap = nullptr;
+    if (imageBuffer)
+        imageBuffer->releaseBufferToPool();
+    imageBuffer = nullptr;
 }
 
-WebCore::IOSurface::Format RemoteLayerBackingStore::surfaceBufferFormat() const
-{
-#if HAVE(IOSURFACE_RGB10)
-    if (m_deepColor)
-        return m_isOpaque ? WebCore::IOSurface::Format::RGB10 : WebCore::IOSurface::Format::RGB10A8;
-#endif
-
-    return WebCore::IOSurface::Format::BGRA;
-}
-
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/ViewSnapshotStore.h (269823 => 269824)


--- trunk/Source/WebKit/UIProcess/ViewSnapshotStore.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/UIProcess/ViewSnapshotStore.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -83,7 +83,7 @@
 
     void setSurface(std::unique_ptr<WebCore::IOSurface>);
 
-    WebCore::IOSurface::SurfaceState setVolatile(bool);
+    WebCore::VolatilityState setVolatile(bool);
 #endif
 
 #if PLATFORM(GTK)

Modified: trunk/Source/WebKit/UIProcess/mac/ViewSnapshotStoreMac.mm (269823 => 269824)


--- trunk/Source/WebKit/UIProcess/mac/ViewSnapshotStoreMac.mm	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/UIProcess/mac/ViewSnapshotStoreMac.mm	2020-11-15 09:30:54 UTC (rev 269824)
@@ -28,6 +28,7 @@
 
 #import <CoreGraphics/CoreGraphics.h>
 #import <WebCore/IOSurface.h>
+#import <WebCore/ImageBuffer.h>
 
 #if PLATFORM(IOS_FAMILY)
 #import <pal/spi/cocoa/QuartzCoreSPI.h>
@@ -74,15 +75,15 @@
     m_surface = nullptr;
 }
 
-WebCore::IOSurface::SurfaceState ViewSnapshot::setVolatile(bool becomeVolatile)
+WebCore::VolatilityState ViewSnapshot::setVolatile(bool becomeVolatile)
 {
     if (ViewSnapshotStore::singleton().disableSnapshotVolatilityForTesting())
-        return WebCore::IOSurface::SurfaceState::Valid;
+        return WebCore::VolatilityState::Valid;
 
     if (!m_surface)
-        return WebCore::IOSurface::SurfaceState::Empty;
+        return WebCore::VolatilityState::Empty;
 
-    return m_surface->setIsVolatile(becomeVolatile);
+    return m_surface->setVolatile(becomeVolatile);
 }
 
 id ViewSnapshot::asLayerContents()
@@ -90,7 +91,7 @@
     if (!m_surface)
         return nullptr;
 
-    if (setVolatile(false) != WebCore::IOSurface::SurfaceState::Valid) {
+    if (setVolatile(false) != WebCore::VolatilityState::Valid) {
         clearImage();
         return nullptr;
     }

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferBackendHandle.h (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferBackendHandle.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/ImageBufferBackendHandle.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -34,7 +34,7 @@
 namespace WebKit {
 
 using ImageBufferBackendHandle = Variant<
-#if PLATFORM(COCOA)
+#if PLATFORM(COCOA) // FIXME: This is really about IOSurface.
     MachSendRight,
 #endif
     ShareableBitmap::Handle

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -40,6 +40,23 @@
 
 class RemoteRenderingBackend;
 
+class ThreadSafeRemoteImageBufferFlusher : public WebCore::ThreadSafeImageBufferFlusher {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ThreadSafeRemoteImageBufferFlusher(WebCore::ImageBuffer& imageBuffer)
+    {
+        // FIXME: We shouldn't synchronously wait on the flush until flush() is called, but have to invent
+        // a thread-safe way to wait on the incoming message.
+        imageBuffer.flushDrawingContext();
+    }
+
+    void flush() override
+    {
+    }
+
+private:
+};
+
 template<typename BackendType>
 class RemoteImageBufferProxy : public WebCore::DisplayList::ImageBuffer<BackendType>, public WebCore::DisplayList::Recorder::Delegate, public WebCore::DisplayList::ItemBufferWritingClient {
     using BaseDisplayListImageBuffer = WebCore::DisplayList::ImageBuffer<BackendType>;
@@ -84,6 +101,12 @@
     WebCore::ColorSpace colorSpace() const { return m_colorSpace; }
     WebCore::PixelFormat pixelFormat() const { return m_pixelFormat; }
 
+    ImageBufferBackendHandle createImageBufferBackendHandle()
+    {
+        ensureBackendCreated();
+        return m_backend->createImageBufferBackendHandle();
+    }
+
 protected:
     RemoteImageBufferProxy(const WebCore::FloatSize& size, WebCore::RenderingMode renderingMode, float resolutionScale, WebCore::ColorSpace colorSpace, WebCore::PixelFormat pixelFormat, RemoteRenderingBackendProxy& remoteRenderingBackendProxy)
         : BaseDisplayListImageBuffer(size, this)
@@ -312,6 +335,11 @@
             flushDrawingContext();
     }
 
+    std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher> createFlusher() override
+    {
+        return WTF::makeUnique<ThreadSafeRemoteImageBufferFlusher>(*this);
+    }
+
     WebCore::DisplayList::FlushIdentifier m_sentFlushIdentifier;
     WebCore::DisplayList::FlushIdentifier m_receivedFlushIdentifier;
     WeakPtr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy;

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2020-11-15 09:30:54 UTC (rev 269824)
@@ -903,12 +903,6 @@
 
 #if ENABLE(GPU_PROCESS)
 
-RemoteRenderingBackendProxy& WebChromeClient::ensureRemoteRenderingBackendProxy() const
-{
-    if (!m_remoteRenderingBackendProxy)
-        m_remoteRenderingBackendProxy = RemoteRenderingBackendProxy::create();
-    return *m_remoteRenderingBackendProxy;
-}
 
 RefPtr<ImageBuffer> WebChromeClient::createImageBuffer(const FloatSize& size, RenderingMode renderingMode, RenderingPurpose purpose, float resolutionScale, ColorSpace colorSpace, PixelFormat pixelFormat) const
 {
@@ -915,7 +909,7 @@
     if (!WebProcess::singleton().shouldUseRemoteRenderingFor(purpose))
         return nullptr;
 
-    return ensureRemoteRenderingBackendProxy().createImageBuffer(size, renderingMode, resolutionScale, colorSpace, pixelFormat);
+    return m_page.ensureRemoteRenderingBackendProxy().createImageBuffer(size, renderingMode, resolutionScale, colorSpace, pixelFormat);
 }
 
 #endif // ENABLE(GPU_PROCESS)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -37,7 +37,6 @@
 
 namespace WebKit {
 
-class RemoteRenderingBackendProxy;
 class WebFrame;
 class WebPage;
 
@@ -243,7 +242,6 @@
     RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) const final;
 
 #if ENABLE(GPU_PROCESS)
-    RemoteRenderingBackendProxy& ensureRemoteRenderingBackendProxy() const;
     RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, WebCore::RenderingPurpose, float resolutionScale, WebCore::ColorSpace, WebCore::PixelFormat) const final;
 #endif
 
@@ -405,9 +403,6 @@
 
     mutable bool m_cachedMainFrameHasHorizontalScrollbar { false };
     mutable bool m_cachedMainFrameHasVerticalScrollbar { false };
-#if ENABLE(GPU_PROCESS)
-    mutable std::unique_ptr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy;
-#endif
     WebPage& m_page;
 };
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -37,6 +37,7 @@
 
 class GraphicsLayerCARemote;
 class PlatformCALayerRemote;
+class RemoteRenderingBackendProxy;
 class WebPage;
 
 // FIXME: This class doesn't do much now. Roll into RemoteLayerTreeDrawingArea?
@@ -77,6 +78,8 @@
     bool nextRenderingUpdateRequiresSynchronousImageDecoding() const { return m_nextRenderingUpdateRequiresSynchronousImageDecoding; }
 
     void adoptLayersFromContext(RemoteLayerTreeContext&);
+
+    RemoteRenderingBackendProxy& ensureRemoteRenderingBackendProxy();
     
 #if PLATFORM(IOS_FAMILY)
     bool canShowWhileLocked() const;

Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeContext.mm	2020-11-15 09:30:54 UTC (rev 269824)
@@ -188,4 +188,9 @@
         it->value->animationEnded(key);
 }
 
+RemoteRenderingBackendProxy& RemoteLayerTreeContext::ensureRemoteRenderingBackendProxy()
+{
+    return m_webPage.ensureRemoteRenderingBackendProxy();
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -39,6 +39,7 @@
 
 namespace WebCore {
 class PlatformCALayer;
+class ThreadSafeImageBufferFlusher;
 }
 
 namespace WebKit {
@@ -125,17 +126,17 @@
 
     class BackingStoreFlusher : public ThreadSafeRefCounted<BackingStoreFlusher> {
     public:
-        static Ref<BackingStoreFlusher> create(IPC::Connection*, std::unique_ptr<IPC::Encoder>, Vector<RetainPtr<CGContextRef>>);
+        static Ref<BackingStoreFlusher> create(IPC::Connection*, std::unique_ptr<IPC::Encoder>, Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>>);
 
         void flush();
         bool hasFlushed() const { return m_hasFlushed; }
 
     private:
-        BackingStoreFlusher(IPC::Connection*, std::unique_ptr<IPC::Encoder>, Vector<RetainPtr<CGContextRef>>);
+        BackingStoreFlusher(IPC::Connection*, std::unique_ptr<IPC::Encoder>, Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>>);
 
         RefPtr<IPC::Connection> m_connection;
         std::unique_ptr<IPC::Encoder> m_commitEncoder;
-        Vector<RetainPtr<CGContextRef>> m_contextsToFlush;
+        Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>> m_flushers;
 
         std::atomic<bool> m_hasFlushed;
     };

Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteLayerTreeDrawingArea.mm	2020-11-15 09:30:54 UTC (rev 269824)
@@ -384,13 +384,13 @@
 
     // FIXME: Move all backing store flushing management to RemoteLayerBackingStoreCollection.
     bool hadAnyChangedBackingStore = false;
-    Vector<RetainPtr<CGContextRef>> contextsToFlush;
+    Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>> flushers;
     for (auto& layer : layerTransaction.changedLayers()) {
         if (layer->properties().changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
             hadAnyChangedBackingStore = true;
             if (layer->properties().backingStore) {
-                if (auto contextPendingFlush = layer->properties().backingStore->takeFrontContextPendingFlush())
-                    contextsToFlush.append(contextPendingFlush);
+                if (auto pendingFlusher = layer->properties().backingStore->takePendingFlusher())
+                    flushers.append(WTFMove(pendingFlusher));
             }
         }
 
@@ -402,7 +402,7 @@
     if (hadAnyChangedBackingStore)
         backingStoreCollection.scheduleVolatilityTimer();
 
-    RefPtr<BackingStoreFlusher> backingStoreFlusher = BackingStoreFlusher::create(WebProcess::singleton().parentProcessConnection(), WTFMove(commitEncoder), WTFMove(contextsToFlush));
+    RefPtr<BackingStoreFlusher> backingStoreFlusher = BackingStoreFlusher::create(WebProcess::singleton().parentProcessConnection(), WTFMove(commitEncoder), WTFMove(flushers));
     m_pendingBackingStoreFlusher = backingStoreFlusher;
 
     auto pageID = m_webPage.identifier();
@@ -451,15 +451,15 @@
     return m_remoteLayerTreeContext->backingStoreCollection().markAllBackingStoreVolatileImmediatelyIfPossible();
 }
 
-Ref<RemoteLayerTreeDrawingArea::BackingStoreFlusher> RemoteLayerTreeDrawingArea::BackingStoreFlusher::create(IPC::Connection* connection, std::unique_ptr<IPC::Encoder> encoder, Vector<RetainPtr<CGContextRef>> contextsToFlush)
+Ref<RemoteLayerTreeDrawingArea::BackingStoreFlusher> RemoteLayerTreeDrawingArea::BackingStoreFlusher::create(IPC::Connection* connection, std::unique_ptr<IPC::Encoder> encoder, Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>> flushers)
 {
-    return adoptRef(*new RemoteLayerTreeDrawingArea::BackingStoreFlusher(connection, WTFMove(encoder), WTFMove(contextsToFlush)));
+    return adoptRef(*new RemoteLayerTreeDrawingArea::BackingStoreFlusher(connection, WTFMove(encoder), WTFMove(flushers)));
 }
 
-RemoteLayerTreeDrawingArea::BackingStoreFlusher::BackingStoreFlusher(IPC::Connection* connection, std::unique_ptr<IPC::Encoder> encoder, Vector<RetainPtr<CGContextRef>> contextsToFlush)
+RemoteLayerTreeDrawingArea::BackingStoreFlusher::BackingStoreFlusher(IPC::Connection* connection, std::unique_ptr<IPC::Encoder> encoder, Vector<std::unique_ptr<WebCore::ThreadSafeImageBufferFlusher>> flushers)
     : m_connection(connection)
     , m_commitEncoder(WTFMove(encoder))
-    , m_contextsToFlush(WTFMove(contextsToFlush))
+    , m_flushers(WTFMove(flushers))
     , m_hasFlushed(false)
 {
 }
@@ -470,8 +470,8 @@
 
     TraceScope tracingScope(BackingStoreFlushStart, BackingStoreFlushEnd);
     
-    for (auto& context : m_contextsToFlush)
-        CGContextFlush(context.get());
+    for (auto& flusher : m_flushers)
+        flusher->flush();
     m_hasFlushed = true;
 
     m_connection->sendMessage(WTFMove(m_commitEncoder), { });

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-11-15 09:30:54 UTC (rev 269824)
@@ -57,6 +57,7 @@
 #include "PluginProxy.h"
 #include "PluginView.h"
 #include "PrintInfo.h"
+#include "RemoteRenderingBackendProxy.h"
 #include "RemoteWebInspectorUI.h"
 #include "RemoteWebInspectorUIMessages.h"
 #include "SessionState.h"
@@ -7041,6 +7042,15 @@
 }
 #endif
 
+#if ENABLE(GPU_PROCESS)
+RemoteRenderingBackendProxy& WebPage::ensureRemoteRenderingBackendProxy()
+{
+    if (!m_remoteRenderingBackendProxy)
+        m_remoteRenderingBackendProxy = RemoteRenderingBackendProxy::create();
+    return *m_remoteRenderingBackendProxy;
+}
+#endif
+
 } // namespace WebKit
 
 #undef RELEASE_LOG_IF_ALLOWED

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (269823 => 269824)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2020-11-15 08:56:23 UTC (rev 269823)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2020-11-15 09:30:54 UTC (rev 269824)
@@ -245,6 +245,7 @@
 class PDFPlugin;
 class PageBanner;
 class PluginView;
+class RemoteRenderingBackendProxy;
 class RemoteWebInspectorUI;
 class TextCheckingControllerProxy;
 class UserMediaPermissionRequestManager;
@@ -1361,6 +1362,10 @@
 
     void synchronizeCORSDisablingPatternsWithNetworkProcess();
 
+#if ENABLE(GPU_PROCESS)
+    RemoteRenderingBackendProxy& ensureRemoteRenderingBackendProxy();
+#endif
+
 private:
     WebPage(WebCore::PageIdentifier, WebPageCreationParameters&&);
 
@@ -2163,6 +2168,10 @@
     bool m_ipcTestingAPIEnabled { false };
     uint64_t m_visitedLinkTableID;
 #endif
+
+#if ENABLE(GPU_PROCESS)
+    std::unique_ptr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy;
+#endif
 };
 
 #if !PLATFORM(IOS_FAMILY)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to