Title: [158417] trunk/Source
Revision
158417
Author
[email protected]
Date
2013-10-31 18:16:33 -0700 (Thu, 31 Oct 2013)

Log Message

Remote Layer Tree: Vend layer contents via IOSurfaces
https://bugs.webkit.org/show_bug.cgi?id=123600

Reviewed by Anders Carlsson.

* Configurations/WebKit2.xcconfig:
Link WebKit2 against IOSurface.

* Shared/mac/RemoteLayerTreeTransaction.mm:
(WebKit::dumpChangedLayers):
Dump the size of the backing store instead of the pointer of its
SharedBitmap, because that's slightly more useful.

* UIProcess/mac/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::commit):
If a layer's backing store uses accelerated drawing, hand the IOSurface
to the CALayer for display.

* WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
(PlatformCALayerRemote::PlatformCALayerRemote):
Initialize contentsScale to 1 to match CA. Other properties will follow.

(PlatformCALayerRemote::ensureBackingStore):
Instead of replacing the RemoteLayerBackingStore when its properties
change, allow it to update them on the fly. Replacing them caused
us to throw away repaint rects when the accelerated drawing
flag was flipped.

(PlatformCALayerRemote::acceleratesDrawing):
(PlatformCALayerRemote::setAcceleratesDrawing):
Store the accelerated drawing flag and mark it dirty when it changes.

* WebProcess/WebPage/mac/PlatformCALayerRemote.h:
* WebProcess/WebPage/mac/RemoteLayerBackingStore.h:
(WebKit::RemoteLayerBackingStore::image):
Rename bitmap() to image() and have it create a CGImageRef from
the ShareableBitmap, ready for direct application to a CALayer.

(WebKit::RemoteLayerBackingStore::surface):
Return a IOSurface ready for direct application to a CALayer.

(WebKit::RemoteLayerBackingStore::acceleratesDrawing):
(WebKit::RemoteLayerBackingStore::hasFrontBuffer):
Return whether or not we have a front buffer/surface.

* WebProcess/WebPage/mac/RemoteLayerBackingStore.mm:
Forward-declare some CGIOSurface SPI.

(RemoteLayerBackingStore::RemoteLayerBackingStore):
(RemoteLayerBackingStore::ensureBackingStore):
Throw away our front image and reset flags if needed.

(RemoteLayerBackingStore::encode):
(RemoteLayerBackingStore::decode):
En/decode the front surface instead of the ShareableBitmap if needed,
using CoreIPC::MachPort. Destroy the port on receipt.

(createIOSurfaceContext):
Create a CGIOSurfaceContext from an IOSurface.

(createIOSurface):
Create an IOSurface of the given size.

(RemoteLayerBackingStore::image):
Return a CGImageRef, if we're not using accelerated drawing.
Moved from the header.

(RemoteLayerBackingStore::display):
(RemoteLayerBackingStore::drawInContext):
If using accelerated drawing, create and paint into an IOSurface.
Reorganize some code to make the copying-from-the-front-image code
work for both software and IOSurfaces.
Flush the context when completed, to ensure that any asynchronous
painting is complete before we vend the surface to the UI process.

* WebCore.exp.in:
Export sRGBColorSpaceRef.

* WebCore.xcodeproj/project.pbxproj:
Expose GraphicsContextCG.h.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (158416 => 158417)


--- trunk/Source/WebCore/ChangeLog	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebCore/ChangeLog	2013-11-01 01:16:33 UTC (rev 158417)
@@ -1,3 +1,16 @@
+2013-10-31  Tim Horton  <[email protected]>
+
+        Remote Layer Tree: Vend layer contents via IOSurfaces
+        https://bugs.webkit.org/show_bug.cgi?id=123600
+
+        Reviewed by Anders Carlsson.
+
+        * WebCore.exp.in:
+        Export sRGBColorSpaceRef.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Expose GraphicsContextCG.h.
+
 2013-10-31  Joseph Pecoraro  <[email protected]>
 
         Remove unused Page::setDebuggerForAllPages

Modified: trunk/Source/WebCore/WebCore.exp.in (158416 => 158417)


--- trunk/Source/WebCore/WebCore.exp.in	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebCore/WebCore.exp.in	2013-11-01 01:16:33 UTC (rev 158417)
@@ -695,6 +695,7 @@
 __ZN7WebCore17languageDidChangeEv
 __ZN7WebCore17openTemporaryFileERKN3WTF6StringERi
 __ZN7WebCore17setCookiesFromDOMERKNS_21NetworkStorageSessionERKNS_3URLES5_RKN3WTF6StringE
+__ZN7WebCore17sRGBColorSpaceRefEv
 __ZN7WebCore17userVisibleStringEP5NSURL
 __ZN7WebCore18DOMWindowExtensionC1EPNS_5FrameERNS_15DOMWrapperWorldE
 __ZN7WebCore18PlatformCALayerMac18setGeometryFlippedEb

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (158416 => 158417)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2013-11-01 01:16:33 UTC (rev 158417)
@@ -2990,7 +2990,7 @@
 		9343CB8212F25E510033C5EE /* TextCodecUTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = 9343CB8012F25E510033C5EE /* TextCodecUTF8.h */; };
 		93442C9E0D2B335C00338FF9 /* HTMLTableRowsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 93442C9D0D2B335C00338FF9 /* HTMLTableRowsCollection.h */; };
 		93442CA00D2B336000338FF9 /* HTMLTableRowsCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93442C9F0D2B336000338FF9 /* HTMLTableRowsCollection.cpp */; };
-		934907E4125BBBC8007F23A0 /* GraphicsContextCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 934907E3125BBBC8007F23A0 /* GraphicsContextCG.h */; };
+		934907E4125BBBC8007F23A0 /* GraphicsContextCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 934907E3125BBBC8007F23A0 /* GraphicsContextCG.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		934CC0E10ED39D6F00A658F2 /* ScriptValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 934CC0DF0ED39D6F00A658F2 /* ScriptValue.cpp */; };
 		934CC0E20ED39D6F00A658F2 /* ScriptValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 934CC0E00ED39D6F00A658F2 /* ScriptValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		934CC10A0EDB223900A658F2 /* ScriptSourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 934CC1090EDB223900A658F2 /* ScriptSourceCode.h */; };

Modified: trunk/Source/WebKit2/ChangeLog (158416 => 158417)


--- trunk/Source/WebKit2/ChangeLog	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/ChangeLog	2013-11-01 01:16:33 UTC (rev 158417)
@@ -1,3 +1,80 @@
+2013-10-31  Tim Horton  <[email protected]>
+
+        Remote Layer Tree: Vend layer contents via IOSurfaces
+        https://bugs.webkit.org/show_bug.cgi?id=123600
+
+        Reviewed by Anders Carlsson.
+
+        * Configurations/WebKit2.xcconfig:
+        Link WebKit2 against IOSurface.
+
+        * Shared/mac/RemoteLayerTreeTransaction.mm:
+        (WebKit::dumpChangedLayers):
+        Dump the size of the backing store instead of the pointer of its
+        SharedBitmap, because that's slightly more useful.
+
+        * UIProcess/mac/RemoteLayerTreeHost.mm:
+        (WebKit::RemoteLayerTreeHost::commit):
+        If a layer's backing store uses accelerated drawing, hand the IOSurface
+        to the CALayer for display.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.cpp:
+        (PlatformCALayerRemote::PlatformCALayerRemote):
+        Initialize contentsScale to 1 to match CA. Other properties will follow.
+
+        (PlatformCALayerRemote::ensureBackingStore):
+        Instead of replacing the RemoteLayerBackingStore when its properties
+        change, allow it to update them on the fly. Replacing them caused
+        us to throw away repaint rects when the accelerated drawing
+        flag was flipped.
+
+        (PlatformCALayerRemote::acceleratesDrawing):
+        (PlatformCALayerRemote::setAcceleratesDrawing):
+        Store the accelerated drawing flag and mark it dirty when it changes.
+
+        * WebProcess/WebPage/mac/PlatformCALayerRemote.h:
+        * WebProcess/WebPage/mac/RemoteLayerBackingStore.h:
+        (WebKit::RemoteLayerBackingStore::image):
+        Rename bitmap() to image() and have it create a CGImageRef from
+        the ShareableBitmap, ready for direct application to a CALayer.
+
+        (WebKit::RemoteLayerBackingStore::surface):
+        Return a IOSurface ready for direct application to a CALayer.
+
+        (WebKit::RemoteLayerBackingStore::acceleratesDrawing):
+        (WebKit::RemoteLayerBackingStore::hasFrontBuffer):
+        Return whether or not we have a front buffer/surface.
+
+        * WebProcess/WebPage/mac/RemoteLayerBackingStore.mm:
+        Forward-declare some CGIOSurface SPI.
+
+        (RemoteLayerBackingStore::RemoteLayerBackingStore):
+        (RemoteLayerBackingStore::ensureBackingStore):
+        Throw away our front image and reset flags if needed.
+
+        (RemoteLayerBackingStore::encode):
+        (RemoteLayerBackingStore::decode):
+        En/decode the front surface instead of the ShareableBitmap if needed,
+        using CoreIPC::MachPort. Destroy the port on receipt.
+
+        (createIOSurfaceContext):
+        Create a CGIOSurfaceContext from an IOSurface.
+
+        (createIOSurface):
+        Create an IOSurface of the given size.
+
+        (RemoteLayerBackingStore::image):
+        Return a CGImageRef, if we're not using accelerated drawing.
+        Moved from the header.
+
+        (RemoteLayerBackingStore::display):
+        (RemoteLayerBackingStore::drawInContext):
+        If using accelerated drawing, create and paint into an IOSurface.
+        Reorganize some code to make the copying-from-the-front-image code
+        work for both software and IOSurfaces.
+        Flush the context when completed, to ensure that any asynchronous
+        painting is complete before we vend the surface to the UI process.
+
 2013-10-31  Anders Carlsson  <[email protected]>
 
         Begin stubbing out the WKRemoteObjectCoder NSCoder subclass

Modified: trunk/Source/WebKit2/Configurations/WebKit2.xcconfig (158416 => 158417)


--- trunk/Source/WebKit2/Configurations/WebKit2.xcconfig	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/Configurations/WebKit2.xcconfig	2013-11-01 01:16:33 UTC (rev 158417)
@@ -29,7 +29,7 @@
 INSTALL_PATH = $(WEBKIT2_FRAMEWORKS_DIR);
 DYLIB_INSTALL_NAME_BASE = $(NORMAL_WEBKIT2_FRAMEWORKS_DIR);
 
-FRAMEWORK_AND_LIBRARY_LDFLAGS = -framework ApplicationServices -framework Carbon -framework Cocoa -framework CoreServices -framework IOKit -framework _javascript_Core -licucore -framework QuartzCore -framework Security -framework WebCore -framework CoreAudio;
+FRAMEWORK_AND_LIBRARY_LDFLAGS = -framework ApplicationServices -framework Carbon -framework Cocoa -framework CoreServices -framework IOKit -framework _javascript_Core -licucore -framework QuartzCore -framework Security -framework WebCore -framework CoreAudio -framework IOSurface;
 
 // Prevent C++ standard library operator new, delete and their related exception types from being exported as weak symbols.
 UNEXPORTED_SYMBOL_LDFLAGS = -Wl,-unexported_symbol -Wl,__ZTISt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTISt9exception -Wl,-unexported_symbol -Wl,__ZTSSt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTSSt9exception -Wl,-unexported_symbol -Wl,__ZdlPvS_ -Wl,-unexported_symbol -Wl,__ZnwmPv -Wl,-unexported_symbol -Wl,__Znwm -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC2EOS4_ -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC1EOS4_ -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEaSEDn -Wl,-unexported_symbol, -Wl,__ZNKSt3__18functionIFvN7WebCore12PolicyActionEEEclES2_ -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEE4swapERS4_ -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC1ERKS4_ -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEC2ERKS4_ -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEED1Ev -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEED2Ev -Wl,-unexported_symbol, -Wl,__ZNSt3__18functionIFvN7WebCore12PolicyActionEEEaSERKS4_;

Modified: trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm (158416 => 158417)


--- trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm	2013-11-01 01:16:33 UTC (rev 158417)
@@ -622,7 +622,7 @@
             dumpProperty<double>(ts, "timeOffset", layerProperties.timeOffset);
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged)
-            dumpProperty<ShareableBitmap*>(ts, "backingStore", layerProperties.backingStore.bitmap());
+            dumpProperty<IntSize>(ts, "backingStore", layerProperties.backingStore.size());
 
         if (layerProperties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)
             dumpProperty<FilterOperations>(ts, "filters", layerProperties.filters);

Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm (158416 => 158417)


--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm	2013-11-01 01:16:33 UTC (rev 158417)
@@ -200,9 +200,10 @@
             layer.timeOffset = properties.timeOffset;
 
         if (properties.changedProperties & RemoteLayerTreeTransaction::BackingStoreChanged) {
-            // FIXME: Do we need Copy?
-            RetainPtr<CGImageRef> image = properties.backingStore.bitmap()->makeCGImageCopy();
-            layer.contents = (id)image.get();
+            if (properties.backingStore.acceleratesDrawing())
+                layer.contents = (id)properties.backingStore.surface().get();
+            else
+                layer.contents = (id)properties.backingStore.image().get();
         }
 
         if (properties.changedProperties & RemoteLayerTreeTransaction::FiltersChanged)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp (158416 => 158417)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.cpp	2013-11-01 01:16:33 UTC (rev 158417)
@@ -69,8 +69,12 @@
     : PlatformCALayer(layerType, owner)
     , m_layerID(generateLayerID())
     , m_superlayer(nullptr)
+    , m_acceleratesDrawing(false)
     , m_context(context)
 {
+    // FIXME: match all default values from CA.
+    setContentsScale(1);
+
     m_context->layerWasCreated(this, layerType);
 }
 
@@ -115,12 +119,7 @@
 
 void PlatformCALayerRemote::ensureBackingStore()
 {
-    if (m_properties.backingStore.layer() == this
-        && m_properties.backingStore.size() == m_properties.size
-        && m_properties.backingStore.scale() == m_properties.contentsScale)
-        return;
-
-    m_properties.backingStore = RemoteLayerBackingStore(this, expandedIntSize(m_properties.size), m_properties.contentsScale);
+    m_properties.backingStore.ensureBackingStore(this, expandedIntSize(m_properties.size), m_properties.contentsScale, m_acceleratesDrawing);
 }
 
 void PlatformCALayerRemote::setNeedsDisplay(const FloatRect* rect)
@@ -352,11 +351,13 @@
 
 bool PlatformCALayerRemote::acceleratesDrawing() const
 {
-    return false;
+    return m_acceleratesDrawing;
 }
 
 void PlatformCALayerRemote::setAcceleratesDrawing(bool acceleratesDrawing)
 {
+    m_acceleratesDrawing = acceleratesDrawing;
+    ensureBackingStore();
 }
 
 CFTypeRef PlatformCALayerRemote::contents() const

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h (158416 => 158417)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemote.h	2013-11-01 01:16:33 UTC (rev 158417)
@@ -158,6 +158,7 @@
     RemoteLayerTreeTransaction::LayerProperties m_properties;
     WebCore::PlatformCALayerList m_children;
     PlatformCALayerRemote* m_superlayer;
+    bool m_acceleratesDrawing;
 
     RemoteLayerTreeContext* m_context;
 };

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerBackingStore.h (158416 => 158417)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerBackingStore.h	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerBackingStore.h	2013-11-01 01:16:33 UTC (rev 158417)
@@ -39,16 +39,19 @@
 class RemoteLayerBackingStore {
 public:
     RemoteLayerBackingStore();
-    RemoteLayerBackingStore(PlatformCALayerRemote*, WebCore::IntSize, float scale);
 
+    void ensureBackingStore(PlatformCALayerRemote*, WebCore::IntSize, float scale, bool acceleratesDrawing);
+
     void setNeedsDisplay(const WebCore::IntRect);
     void setNeedsDisplay();
 
     bool display();
 
-    ShareableBitmap* bitmap() const { return m_frontBuffer.get(); }
+    RetainPtr<CGImageRef> image() const;
+    RetainPtr<IOSurfaceRef> surface() const { return m_frontSurface.get(); }
     WebCore::IntSize size() const { return m_size; }
     float scale() const { return m_scale; }
+    bool acceleratesDrawing() const { return m_acceleratesDrawing; }
 
     PlatformCALayerRemote* layer() const { return m_layer; }
 
@@ -58,6 +61,11 @@
 private:
     WebCore::IntRect mapToContentCoordinates(const WebCore::IntRect) const;
 
+    bool hasFrontBuffer() { return m_acceleratesDrawing ? !!m_frontSurface : !!m_frontBuffer; }
+
+    std::unique_ptr<WebCore::GraphicsContext> createBackingStore();
+    void drawInContext(WebCore::GraphicsContext&);
+
     PlatformCALayerRemote* m_layer;
 
     WebCore::IntSize m_size;
@@ -66,7 +74,9 @@
     WebCore::Region m_dirtyRegion;
 
     RefPtr<ShareableBitmap> m_frontBuffer;
-    RefPtr<ShareableBitmap> m_backBuffer;
+    RetainPtr<IOSurfaceRef> m_frontSurface;
+
+    bool m_acceleratesDrawing;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerBackingStore.mm (158416 => 158417)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerBackingStore.mm	2013-11-01 01:11:54 UTC (rev 158416)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerBackingStore.mm	2013-11-01 01:16:33 UTC (rev 158417)
@@ -28,51 +28,90 @@
 
 #if USE(ACCELERATED_COMPOSITING)
 
+#import "ArgumentCoders.h"
+#import "MachPort.h"
 #import "PlatformCALayerRemote.h"
-#import "ArgumentCoders.h"
 #import "ShareableBitmap.h"
 #import "WebCoreArgumentCoders.h"
+#import <WebCore/GraphicsContextCG.h>
 #import <WebCore/WebLayer.h>
 
+#ifdef __has_include
+#if __has_include(<ApplicationServices/ApplicationServicesPriv.h>)
+#import <ApplicationServices/ApplicationServicesPriv.h>
+#endif
+#endif
+
+extern "C" {
+CGContextRef CGIOSurfaceContextCreate(IOSurfaceRef, size_t, size_t, size_t, size_t, CGColorSpaceRef, CGBitmapInfo);
+CGImageRef CGIOSurfaceContextCreateImage(CGContextRef);
+}
+
 using namespace WebCore;
 using namespace WebKit;
 
-RemoteLayerBackingStore::RemoteLayerBackingStore(PlatformCALayerRemote* layer, IntSize size, float scale)
-    : m_layer(layer)
-    , m_size(size)
-    , m_scale(scale)
+RemoteLayerBackingStore::RemoteLayerBackingStore()
+    : m_layer(nullptr)
 {
-    ASSERT(layer);
 }
 
-RemoteLayerBackingStore::RemoteLayerBackingStore()
-    : m_layer(nullptr)
+void RemoteLayerBackingStore::ensureBackingStore(PlatformCALayerRemote* layer, IntSize size, float scale, bool acceleratesDrawing)
 {
+    if (m_layer == layer
+        && m_size == size
+        && m_scale == scale
+        && m_acceleratesDrawing == acceleratesDrawing)
+        return;
+
+    m_layer = layer;
+    m_size = size;
+    m_scale = scale;
+    m_acceleratesDrawing = acceleratesDrawing;
+
+    m_frontSurface = nullptr;
+    m_frontBuffer = nullptr;
 }
 
 void RemoteLayerBackingStore::encode(CoreIPC::ArgumentEncoder& encoder) const
 {
-    ShareableBitmap::Handle handle;
-    m_frontBuffer->createHandle(handle);
-
-    encoder << handle;
     encoder << m_size;
     encoder << m_scale;
+    encoder << m_acceleratesDrawing;
+
+    if (m_acceleratesDrawing) {
+        mach_port_t port = IOSurfaceCreateMachPort(m_frontSurface.get());
+        encoder << CoreIPC::MachPort(port, MACH_MSG_TYPE_MOVE_SEND);
+    } else {
+        ShareableBitmap::Handle handle;
+        m_frontBuffer->createHandle(handle);
+        encoder << handle;
+    }
 }
 
 bool RemoteLayerBackingStore::decode(CoreIPC::ArgumentDecoder& decoder, RemoteLayerBackingStore& result)
 {
-    ShareableBitmap::Handle handle;
-    if (!decoder.decode(handle))
-        return false;
-    result.m_frontBuffer = ShareableBitmap::create(handle);
-
     if (!decoder.decode(result.m_size))
         return false;
 
     if (!decoder.decode(result.m_scale))
         return false;
 
+    if (!decoder.decode(result.m_acceleratesDrawing))
+        return false;
+
+    if (result.m_acceleratesDrawing) {
+        CoreIPC::MachPort machPort;
+        if (!decoder.decode(machPort))
+            return false;
+        result.m_frontSurface = adoptCF(IOSurfaceLookupFromMachPort(machPort.port()));
+        mach_port_deallocate(mach_task_self(), machPort.port());
+    } else {
+        ShareableBitmap::Handle handle;
+        if (!decoder.decode(handle))
+            return false;
+        result.m_frontBuffer = ShareableBitmap::create(handle);
+    }
+
     return true;
 }
 
@@ -95,6 +134,55 @@
     setNeedsDisplay(IntRect(IntPoint(), m_size));
 }
 
+static RetainPtr<CGContextRef> createIOSurfaceContext(IOSurfaceRef surface, IntSize size, CGColorSpaceRef colorSpace)
+{
+    if (!surface)
+        return nullptr;
+
+    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
+    size_t bitsPerComponent = 8;
+    size_t bitsPerPixel = 32;
+    RetainPtr<CGContextRef> ctx = adoptCF(CGIOSurfaceContextCreate(surface, size.width(), size.height(), bitsPerComponent, bitsPerPixel, colorSpace, bitmapInfo));
+    if (!ctx)
+        return nullptr;
+
+    return ctx;
+}
+
+static RetainPtr<IOSurfaceRef> createIOSurface(IntSize size)
+{
+    unsigned pixelFormat = 'BGRA';
+    unsigned bytesPerElement = 4;
+    int width = size.width();
+    int height = size.height();
+
+    unsigned long bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerElement);
+    ASSERT(bytesPerRow);
+
+    unsigned long allocSize = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow);
+    ASSERT(allocSize);
+
+    RetainPtr<NSDictionary> dict = @{
+        (id)kIOSurfaceWidth: @(width),
+        (id)kIOSurfaceHeight: @(height),
+        (id)kIOSurfacePixelFormat: @(pixelFormat),
+        (id)kIOSurfaceBytesPerElement: @(bytesPerElement),
+        (id)kIOSurfaceBytesPerRow: @(bytesPerRow),
+        (id)kIOSurfaceAllocSize: @(allocSize)
+    };
+
+    return adoptCF(IOSurfaceCreate((CFDictionaryRef)dict.get()));
+}
+
+RetainPtr<CGImageRef> RemoteLayerBackingStore::image() const
+{
+    if (!m_frontBuffer || m_acceleratesDrawing)
+        return nullptr;
+
+    // FIXME: Do we need Copy?
+    return m_frontBuffer->makeCGImageCopy();
+}
+
 bool RemoteLayerBackingStore::display()
 {
     if (!m_layer)
@@ -102,45 +190,85 @@
 
     // If we previously were drawsContent=YES, and now are not, we need
     // to note that our backing store has been cleared.
-    if (!m_layer->owner()->platformCALayerDrawsContent())
-        return m_frontBuffer;
+    if (!m_layer->owner() || !m_layer->owner()->platformCALayerDrawsContent()) {
+        bool previouslyDrewContents = hasFrontBuffer();
 
-    if (m_dirtyRegion.isEmpty())
-        return false;
+        m_frontBuffer = nullptr;
+        m_frontSurface = nullptr;
 
-    FloatSize scaledSize = m_size;
-    scaledSize.scale(m_scale);
+        return previouslyDrewContents;
+    }
 
-    IntRect layerBounds(IntPoint(), m_size);
+    if (!hasFrontBuffer())
+        m_dirtyRegion.unite(IntRect(IntPoint(), m_size));
 
-    m_backBuffer = ShareableBitmap::createShareable(expandedIntSize(scaledSize), ShareableBitmap::SupportsAlpha);
-    if (!m_frontBuffer)
-        m_dirtyRegion.unite(layerBounds);
+    if (m_dirtyRegion.isEmpty() || m_size.isEmpty())
+        return false;
 
     if (m_layer->owner()->platformCALayerShowRepaintCounter(m_layer)) {
         IntRect indicatorRect = mapToContentCoordinates(IntRect(0, 0, 52, 27));
         m_dirtyRegion.unite(indicatorRect);
     }
 
-    std::unique_ptr<GraphicsContext> context = m_backBuffer->createGraphicsContext();
+    std::unique_ptr<GraphicsContext> context;
 
+    FloatSize scaledSize = m_size;
+    scaledSize.scale(m_scale);
+    IntSize expandedScaledSize = expandedIntSize(scaledSize);
+
+    RefPtr<ShareableBitmap> backBuffer;
+    RetainPtr<IOSurfaceRef> backSurface;
+
+    if (m_acceleratesDrawing) {
+        backSurface = createIOSurface(expandedScaledSize);
+        RetainPtr<CGContextRef> cgContext = createIOSurfaceContext(backSurface.get(), expandedScaledSize, sRGBColorSpaceRef());
+        context = std::make_unique<GraphicsContext>(cgContext.get());
+        CGContextClearRect(cgContext.get(), CGRectMake(0, 0, expandedScaledSize.width(), expandedScaledSize.height()));
+        context->scale(FloatSize(1, -1));
+        context->translate(0, -expandedScaledSize.height());
+    } else {
+        backBuffer = ShareableBitmap::createShareable(expandedIntSize(scaledSize), ShareableBitmap::SupportsAlpha);
+        context = backBuffer->createGraphicsContext();
+    }
+
+    drawInContext(*context);
+
+    if (m_acceleratesDrawing)
+        m_frontSurface = backSurface;
+    else
+        m_frontBuffer = backBuffer;
+
+    return true;
+}
+
+void RemoteLayerBackingStore::drawInContext(GraphicsContext& context)
+{
+    RetainPtr<CGImageRef> frontImage;
+    RetainPtr<CGContextRef> frontContext;
+
+    if (m_acceleratesDrawing) {
+        frontContext = createIOSurfaceContext(m_frontSurface.get(), expandedIntSize(m_size * m_scale), sRGBColorSpaceRef());
+        frontImage = adoptCF(CGIOSurfaceContextCreateImage(frontContext.get()));
+    } else
+        frontImage = image();
+
     Vector<IntRect> dirtyRects = m_dirtyRegion.rects();
 
     // If we have less than webLayerMaxRectsToPaint rects to paint and they cover less
     // than webLayerWastedSpaceThreshold of the area, we'll do a partial repaint.
+
     Vector<FloatRect, webLayerMaxRectsToPaint> rectsToPaint;
-    if (dirtyRects.size() <= webLayerMaxRectsToPaint && m_dirtyRegion.totalArea() <= webLayerWastedSpaceThreshold * layerBounds.width() * layerBounds.height()) {
+    if (dirtyRects.size() <= webLayerMaxRectsToPaint && m_dirtyRegion.totalArea() <= webLayerWastedSpaceThreshold * m_size.width() * m_size.height()) {
         // Copy over the parts of the front buffer that we're not going to repaint.
-        if (m_frontBuffer) {
-            Region cleanRegion(layerBounds);
+        if (frontImage) {
+            Region cleanRegion(IntRect(IntPoint(), m_size));
             cleanRegion.subtract(m_dirtyRegion);
 
-            RetainPtr<CGImageRef> frontImage = m_frontBuffer->makeCGImage();
-
             for (const auto& rect : cleanRegion.rects()) {
                 FloatRect scaledRect = rect;
                 scaledRect.scale(m_scale);
-                context->drawNativeImage(frontImage.get(), m_frontBuffer->size(), ColorSpaceDeviceRGB, scaledRect, scaledRect);
+                FloatSize imageSize(CGImageGetWidth(frontImage.get()), CGImageGetHeight(frontImage.get()));
+                context.drawNativeImage(frontImage.get(), imageSize, ColorSpaceDeviceRGB, scaledRect, scaledRect);
             }
         }
 
@@ -148,18 +276,18 @@
             rectsToPaint.append(rect);
     }
 
-    context->scale(FloatSize(m_scale, m_scale));
+    context.scale(FloatSize(m_scale, m_scale));
 
-    switch (layer()->layerType()) {
+    switch (m_layer->layerType()) {
         case PlatformCALayer::LayerTypeSimpleLayer:
         case PlatformCALayer::LayerTypeTiledBackingTileLayer:
             if (rectsToPaint.isEmpty())
-                rectsToPaint.append(layerBounds);
+                rectsToPaint.append(IntRect(IntPoint(), m_size));
             for (const auto& rect : rectsToPaint)
-                m_layer->owner()->platformCALayerPaintContents(m_layer, *context, enclosingIntRect(rect));
+                m_layer->owner()->platformCALayerPaintContents(m_layer, context, enclosingIntRect(rect));
             break;
         case PlatformCALayer::LayerTypeWebLayer:
-            drawLayerContents(context->platformContext(), m_layer, rectsToPaint);
+            drawLayerContents(context.platformContext(), m_layer, rectsToPaint);
             break;
         case PlatformCALayer::LayerTypeLayer:
         case PlatformCALayer::LayerTypeTransformLayer:
@@ -169,16 +297,18 @@
         case PlatformCALayer::LayerTypeRootLayer:
         case PlatformCALayer::LayerTypeAVPlayerLayer:
         case PlatformCALayer::LayerTypeCustom:
-            ASSERT_NOT_REACHED();
             break;
     };
 
     m_dirtyRegion = Region();
 
-    m_frontBuffer = m_backBuffer;
-    m_backBuffer = nullptr;
+    CGContextFlush(context.platformContext());
 
-    return true;
+    // If our frontImage is derived from an IOSurface, we need to
+    // destroy the image before the CGContext it's derived from,
+    // so that the context doesn't make a CPU copy of the surface data.
+    frontImage = nullptr;
+    frontContext = nullptr;
 }
 
 #endif // USE(ACCELERATED_COMPOSITING)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to