[webkit-changes] [WebKit/WebKit] 99b9a1: [Materials] Add rendering support for hosted mater...

Aditya Keerthi noreply at github.com
Wed Feb 12 10:44:51 PST 2025


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 99b9a154a6f7e44e8a17c81b12919b8bf76fa6ce
      https://github.com/WebKit/WebKit/commit/99b9a154a6f7e44e8a17c81b12919b8bf76fa6ce
  Author: Aditya Keerthi <akeerthi at apple.com>
  Date:   2025-02-12 (Wed, 12 Feb 2025)

  Changed paths:
    M Source/WebCore/platform/cocoa/AppleVisualEffect.cpp
    M Source/WebCore/platform/cocoa/AppleVisualEffect.h
    M Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
    M Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
    M Source/WebCore/platform/graphics/ca/PlatformCALayer.h
    M Source/WebCore/platform/graphics/ca/PlatformCALayer.mm
    M Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm
    M Source/WebCore/rendering/RenderLayerBacking.cpp
    M Source/WebKit/Configurations/WebKit.xcconfig
    M Source/WebKit/DerivedSources-input.xcfilelist
    M Source/WebKit/DerivedSources-output.xcfilelist
    M Source/WebKit/DerivedSources.make
    M Source/WebKit/Modules/Internal/WebKitInternal.h
    A Source/WebKit/Platform/cocoa/WKMaterialHostingSupport.h
    A Source/WebKit/Platform/cocoa/WKMaterialHostingSupport.swift
    M Source/WebKit/Shared/Cocoa/WebCoreArgumentCodersCocoa.serialization.in
    M Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm
    M Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.mm
    M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm
    M Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm
    M Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h
    M Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj

  Log Message:
  -----------
  [Materials] Add rendering support for hosted materials
https://bugs.webkit.org/show_bug.cgi?id=287421
rdar://144551395

Reviewed by Richard Robinson.

Support rendering materials implemented in SwiftUI. These materials can be used
via `-apple-visual-effect`.

When a "hosted material" is used, a structural layer is created to encapsulate
the content layer. In the UI process, the structural layer is realized using
SwiftUI. On iOS, a `_UIHostingView` is created, and on macOS a `_CALayerView`
is created. A `materialEffect` is then applied to their respective root views.
WebKit's own layers are parented underneath the SwiftUI-created views/layers.

* Source/WebCore/platform/cocoa/AppleVisualEffect.cpp:
(WebCore::appleVisualEffectIsHostedMaterial):
* Source/WebCore/platform/cocoa/AppleVisualEffect.h:

Introduce a `borderRect` property to `AppleVisualEffectData`. This is necessary
as the shape of the material needs to be applied to the structural layer via
the `materialEffect`, and cannot be set via traditional `CALayer` properties.

* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):

Ensure a structural layer is created for hosted materials, using `-apple-visual-effect.`

(WebCore::GraphicsLayerCA::updateNames):
(WebCore::GraphicsLayerCA::updateAppleVisualEffectData):
(WebCore::GraphicsLayerCA::ensureStructuralLayer):

Creating a structural layer for material hosting takes precedence over
preserves-3D and replica flattening. Those features are not supported with
hosted materials, due to a (current) lack of use case.

(WebCore::GraphicsLayerCA::structuralLayerPurpose const):
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h:
* Source/WebCore/platform/graphics/ca/PlatformCALayer.h:
* Source/WebCore/platform/graphics/ca/PlatformCALayer.mm:
(WebCore::operator<<):
* Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
(WebCore::PlatformCALayerCocoa::PlatformCALayerCocoa):

Specify a plain layer here, as the feature is unsupported when UI-side
compositing is disabled.

* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateAppleVisualEffect):

Specify the `borderRect` on the `AppleVisualEffectData` so that the
material effect can set a corner radius.

* Source/WebKit/Configurations/WebKit.xcconfig:
* Source/WebKit/DerivedSources-input.xcfilelist:
* Source/WebKit/DerivedSources-output.xcfilelist:
* Source/WebKit/DerivedSources.make:
* Source/WebKit/Modules/Internal/WebKitInternal.h:
* Source/WebKit/Platform/cocoa/WKMaterialHostingSupport.h: Added.

Expose utilities from Swift to Obj-C to work with material effects.

* Source/WebKit/Platform/cocoa/WKMaterialHostingSupport.swift: Added.
(MaterialHostingContentViewWrapper.makeUIView(_:)):

A `UIViewRepresentable` is necessary since WebKit's own views need to be
parented underneath the SwiftUI view with the material effect applied.

(MaterialHostingContentViewWrapper.updateUIView(_:context:)):
(MaterialHostingProvider.view(for:)):

Add `MaterialHostingProvider` as a protocol to vend layer-backed or
view-backed material effects.

(LayerBackedMaterialHostingProvider.view(for:)):

The layer-backed material provider uses a `_CALayerView`. WebKit's own layers
are parented underneath the created layer.

(ViewBackedMaterialHostingProvider.view(for:)):

The view-backed material uses a `UIViewRepresentable`. WebKit's own views are
parented underneath the `UIViewRepresentable`.

(MaterialHostingView.body):

Share code to either return a plain SwiftUI view (from the material hosting provider)
or one with the material effect applied. `MaterialHostingView` is specialized on
`MaterialHostingProvider` to allow for code reuse.

(CALayer.materialHostingContentLayer):

Add an extension to `CALayer` to make it easy to get/set the content layer that
will parent WebKit's own layers.

(WKMaterialHostingSupport.createHostingLayer):

Create two layers. A `CAHostingLayer` to encapsulate a SwiftUI view with a
material effect, and a regular `CALayer` which will parent WebKit's own layers.

The `contentLayer` is stored using a key on the `CAHostingLayer` so that it
may be retrieved later to parent WebKit's own layers.

(WKMaterialHostingSupport.updateHostingLayer(_:cornerRadius:)):

Apply the material effect. This involves recreating the `_CALayerView`, so the
content layer must be re-parented under the new view/layer.

(WKMaterialHostingSupport.contentLayer(forMaterialHostingLayer:)):

Expose the `contentLayer` in order to add WebKit's layers as sublayers.

(WKMaterialHostingSupport.createHostingView(_:)):

Create a `_UIHostingView` which encapsulates a content view specified by the
remote layer tree.

(WKMaterialHostingSupport.updateHostingView(_:contentView:cornerRadius:)):

Apply the material effect. This involves recreating the wrapper view,
and content view must be re-parented under the new view.

* Source/WebKit/Shared/Cocoa/WebCoreArgumentCodersCocoa.serialization.in:
* Source/WebKit/Shared/RemoteLayerTree/RemoteLayerBackingStore.mm:
(WebKit::RemoteLayerBackingStore::drawInContext):
* Source/WebKit/Shared/RemoteLayerTree/RemoteLayerTreePropertyApplier.mm:
(WebKit::updateAppleVisualEffect):

Refactor the `AppleVisualEffectChanged` update into a method.

Use the `MaterialHostingSupport` utilities to apply the new effects.

(WebKit::RemoteLayerTreePropertyApplier::applyPropertiesToLayer):
(WebKit::RemoteLayerTreePropertyApplier::applyHierarchyUpdates):

Access the content layer / content view on the structural layer / view so that
WebKit's own layers are parented underneath a view with material effects applied.

If this were not done, the material effect would be applied to an (empty) sibling
layer, which would be incorrect.

(WebKit::RemoteLayerTreePropertyApplier::applyPropertiesToUIView):

Since `WKMaterialHostingView` has a intermediate "hosting view", its size must
be updated along with the `WKMaterialHostingView` itself. Without this, the
`_UIHostingView` would have a zero frame, and SwiftUI would not size the `rootView`.

* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeHost.mm:
(WebKit::RemoteLayerTreeHost::makeNode):
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm:
(WebKit::RemoteLayerTreeHost::makeNode):
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(-[WKMaterialHostingView init]):

`WKMaterialHostingView` has a hosting view (which is the `_UIHostingView`) and
a content view (which is a subview of the hosting view and serves to parent
WebKit's own views).

`WKMaterialHostingView` is used rather than simply returning a `_UIHostingView`
when creating the structural node for two reasons:
1. To easily give access the content view.
2. To subclass `WKCompositingView`.

(-[WKMaterialHostingView contentView]):
(-[WKMaterialHostingView updateHostingSize:]):
(-[WKMaterialHostingView updateCornerRadius:]):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/290280@main



To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications


More information about the webkit-changes mailing list