[WP] Avoid calling IOSurfaceAlignProperty
https://bugs.webkit.org/show_bug.cgi?id=235659

Reviewed by Simon Fraser.

Source/WebCore:

Add information about alignment of bytes per row to IOSurface class.

* platform/graphics/cocoa/IOSurface.h:
* platform/graphics/cocoa/IOSurface.mm:
(WebCore::surfaceBytesPerRowAlignment):
(WebCore::IOSurface::bytesPerRowAlignment):
(WebCore::IOSurface::setBytesPerRowAlignment):

Source/WebKit:

Avoid calling IOSurfaceAlignProperty in the WebContent process, since it requires IOKit access.
Information about the alignment of bytes per row of IOSurface will be retrieved in the UI process,
and sent to the WebContent process, where it will be stored.

* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):
* Shared/WebProcessCreationParameters.h:
* Shared/cg/ShareableBitmapCG.cpp:
(WebKit::ShareableBitmap::calculateBytesPerRow):
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformInitializeWebProcess):
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformInitializeWebProcess):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288662 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6db727f..7dd4ce3 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,18 @@
+2022-01-26  Per Arne Vollan  <pvollan@apple.com>
+
+        [WP] Avoid calling IOSurfaceAlignProperty
+        https://bugs.webkit.org/show_bug.cgi?id=235659
+
+        Reviewed by Simon Fraser.
+
+        Add information about alignment of bytes per row to IOSurface class.
+
+        * platform/graphics/cocoa/IOSurface.h:
+        * platform/graphics/cocoa/IOSurface.mm:
+        (WebCore::surfaceBytesPerRowAlignment):
+        (WebCore::IOSurface::bytesPerRowAlignment):
+        (WebCore::IOSurface::setBytesPerRowAlignment):
+
 2022-01-26  Alexey Shvayka  <ashvayka@apple.com>
 
         Remove the now-unused JSGlobalObjectTask class
diff --git a/Source/WebCore/platform/graphics/cocoa/IOSurface.h b/Source/WebCore/platform/graphics/cocoa/IOSurface.h
index 1e9c7328..3a92e3d 100644
--- a/Source/WebCore/platform/graphics/cocoa/IOSurface.h
+++ b/Source/WebCore/platform/graphics/cocoa/IOSurface.h
@@ -117,6 +117,9 @@
     WEBCORE_EXPORT static IntSize maximumSize();
     WEBCORE_EXPORT static void setMaximumSize(IntSize);
 
+    WEBCORE_EXPORT static size_t bytesPerRowAlignment();
+    WEBCORE_EXPORT static void setBytesPerRowAlignment(size_t);
+
     WEBCORE_EXPORT WTF::MachSendRight createSendRight() const;
 
     // Any images created from a surface need to be released before releasing
diff --git a/Source/WebCore/platform/graphics/cocoa/IOSurface.mm b/Source/WebCore/platform/graphics/cocoa/IOSurface.mm
index ac0871f..c8eaa89 100644
--- a/Source/WebCore/platform/graphics/cocoa/IOSurface.mm
+++ b/Source/WebCore/platform/graphics/cocoa/IOSurface.mm
@@ -277,6 +277,32 @@
     return size;
 }
 
+static WTF::Atomic<size_t>& surfaceBytesPerRowAlignment()
+{
+    static WTF::Atomic<size_t> alignment = 0;
+    return alignment;
+}
+
+size_t IOSurface::bytesPerRowAlignment()
+{
+    auto alignment = surfaceBytesPerRowAlignment().load();
+    if (!alignment) {
+        surfaceBytesPerRowAlignment().store(IOSurfaceGetPropertyAlignment(kIOSurfaceBytesPerRow));
+        alignment = surfaceBytesPerRowAlignment().load();
+        // A return value for IOSurfaceGetPropertyAlignment(kIOSurfaceBytesPerRow) of 1 is invalid.
+        // See https://developer.apple.com/documentation/iosurface/1419453-iosurfacegetpropertyalignment?language=objc
+        // This likely means that the sandbox is blocking access to the IOSurface IOKit class,
+        // and that IOSurface::bytesPerRowAlignment() has been called before IOSurface::setBytesPerRowAlignment.
+        RELEASE_ASSERT(alignment > 1);
+    }
+    return alignment;
+}
+
+void IOSurface::setBytesPerRowAlignment(size_t bytesPerRowAlignment)
+{
+    surfaceBytesPerRowAlignment().store(bytesPerRowAlignment);
+}
+
 MachSendRight IOSurface::createSendRight() const
 {
     return MachSendRight::adopt(IOSurfaceCreateMachPort(m_surface.get()));
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index a20e0e9..f9fefa0 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,25 @@
+2022-01-26  Per Arne Vollan  <pvollan@apple.com>
+
+        [WP] Avoid calling IOSurfaceAlignProperty
+        https://bugs.webkit.org/show_bug.cgi?id=235659
+
+        Reviewed by Simon Fraser.
+
+        Avoid calling IOSurfaceAlignProperty in the WebContent process, since it requires IOKit access.
+        Information about the alignment of bytes per row of IOSurface will be retrieved in the UI process,
+        and sent to the WebContent process, where it will be stored.
+
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode const):
+        (WebKit::WebProcessCreationParameters::decode):
+        * Shared/WebProcessCreationParameters.h:
+        * Shared/cg/ShareableBitmapCG.cpp:
+        (WebKit::ShareableBitmap::calculateBytesPerRow):
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformInitializeWebProcess):
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+
 2022-01-26  Chris Dumez  <cdumez@apple.com>
 
         Symbols not always properly hidden when using WebKitAdditions to introduce new API
diff --git a/Source/WebKit/Shared/WebProcessCreationParameters.cpp b/Source/WebKit/Shared/WebProcessCreationParameters.cpp
index b9c9b7a..90914bb 100644
--- a/Source/WebKit/Shared/WebProcessCreationParameters.cpp
+++ b/Source/WebKit/Shared/WebProcessCreationParameters.cpp
@@ -203,6 +203,7 @@
 
 #if HAVE(IOSURFACE)
     encoder << maximumIOSurfaceSize;
+    encoder << bytesPerRowIOSurfaceAlignment;
 #endif
 
     encoder << accessibilityPreferences;
@@ -553,6 +554,8 @@
 #if HAVE(IOSURFACE)
     if (!decoder.decode(parameters.maximumIOSurfaceSize))
         return false;
+    if (!decoder.decode(parameters.bytesPerRowIOSurfaceAlignment))
+        return false;
 #endif
 
     std::optional<AccessibilityPreferences> accessibilityPreferences;
diff --git a/Source/WebKit/Shared/WebProcessCreationParameters.h b/Source/WebKit/Shared/WebProcessCreationParameters.h
index f5cd874..ff437a7 100644
--- a/Source/WebKit/Shared/WebProcessCreationParameters.h
+++ b/Source/WebKit/Shared/WebProcessCreationParameters.h
@@ -241,6 +241,7 @@
 
 #if HAVE(IOSURFACE)
     WebCore::IntSize maximumIOSurfaceSize;
+    size_t bytesPerRowIOSurfaceAlignment;
 #endif
     
     AccessibilityPreferences accessibilityPreferences;
diff --git a/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp b/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp
index 4275e1a..f017171 100644
--- a/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp
+++ b/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp
@@ -28,6 +28,7 @@
 
 #include <WebCore/BitmapImage.h>
 #include <WebCore/GraphicsContextCG.h>
+#include <WebCore/IOSurface.h>
 #include <WebCore/ImageBufferUtilitiesCG.h>
 #include <WebCore/NativeImage.h>
 #include <WebCore/PlatformScreen.h>
@@ -92,7 +93,8 @@
 #if HAVE(IOSURFACE)
     if (bytesPerRow.hasOverflowed())
         return bytesPerRow;
-    return IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, bytesPerRow);
+    size_t alignmentMask = WebCore::IOSurface::bytesPerRowAlignment() - 1;
+    return (bytesPerRow + alignmentMask) & ~alignmentMask;
 #else
     return bytesPerRow;
 #endif
diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
index 1103ae0..fc71cb3 100644
--- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
+++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm
@@ -473,6 +473,8 @@
     if (m_defaultPageGroup->preferences().useGPUProcessForDOMRenderingEnabled())
         parameters.maximumIOSurfaceSize = WebCore::IOSurface::maximumSize();
 
+    parameters.bytesPerRowIOSurfaceAlignment = WebCore::IOSurface::bytesPerRowAlignment();
+
     parameters.accessibilityPreferences = accessibilityPreferences();
 }
 
diff --git a/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm b/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
index 7dbd391..d95a4ce 100644
--- a/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
+++ b/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
@@ -458,6 +458,8 @@
     if (!parameters.maximumIOSurfaceSize.isEmpty())
         WebCore::IOSurface::setMaximumSize(parameters.maximumIOSurfaceSize);
 
+    WebCore::IOSurface::setBytesPerRowAlignment(parameters.bytesPerRowIOSurfaceAlignment);
+
     accessibilityPreferencesDidChange(parameters.accessibilityPreferences);
 }