Changeset 289495 in webkit


Ignore:
Timestamp:
Feb 9, 2022 12:20:04 PM (5 months ago)
Author:
graouts@webkit.org
Message:

[model] improve sizing on macOS
https://bugs.webkit.org/show_bug.cgi?id=236233
<rdar://problem/88569881>

Reviewed by Simon Fraser.

Source/WebCore:

We detect when the <model> layer size changes under RenderLayerBacking::updateGeometry()
and inform the associated HTMLModelElement through the new parentLayerSizeMayHaveChanged()
method that the size has changed. We then inform the backing player that sizeDidChange().

  • Modules/model-element/HTMLModelElement.cpp:

(WebCore::HTMLModelElement::createModelPlayer):
(WebCore::HTMLModelElement::parentLayerSizeMayHaveChanged):
(WebCore::HTMLModelElement::platformLayerSize const):

  • Modules/model-element/HTMLModelElement.h:
  • Modules/model-element/ModelPlayer.h:
  • Modules/model-element/dummy/DummyModelPlayer.cpp:

(WebCore::DummyModelPlayer::sizeDidChange):

  • Modules/model-element/dummy/DummyModelPlayer.h:
  • Modules/model-element/scenekit/SceneKitModelPlayer.h:
  • Modules/model-element/scenekit/SceneKitModelPlayer.mm:

(WebCore::SceneKitModelPlayer::sizeDidChange):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::RenderLayerBacking::updateGeometry):

Source/WebCore/PAL:

Add newly-used CAFenceHandle and ASVInlinePreview SPIs.

  • pal/spi/cocoa/QuartzCoreSPI.h:
  • pal/spi/mac/SystemPreviewSPI.h:

Source/WebKit:

We override the new ModelPlayer::sizeDidChange() virtual method on ARKitInlinePreviewModelPlayerMac
to be notified when the <model> layer's has changed size. We then send the new ModelElementSizeDidChange
message to the UI process which will yield a call to ModelElementController::modelElementSizeDidChange().

In that new method, we call -[ASVInlinePreview updateFrame:completionHandler:] which provides us with a
CAFenceHandle which we copy to create a MachSendRight to send back to the Web process in the IPC callback.

Back in the Web process, we install this fence on the drawing area and finally call -[ASVInlinePreview
setFrameWithinFencedTransaction:] to complete the sizing update on both the ASVInlinePreview instances.

  • UIProcess/Cocoa/ModelElementControllerCocoa.mm:

(WebKit::ModelElementController::modelElementSizeDidChange):

  • UIProcess/ModelElementController.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::modelElementSizeDidChange):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • WebProcess/Model/ARKitInlinePreviewModelPlayer.h:
  • WebProcess/Model/ARKitInlinePreviewModelPlayer.mm:

(WebKit::ARKitInlinePreviewModelPlayer::sizeDidChange):

  • WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.h:
  • WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.mm:

(WebKit::ARKitInlinePreviewModelPlayerMac::load):
(WebKit::ARKitInlinePreviewModelPlayerMac::sizeDidChange):

Location:
trunk/Source
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r289494 r289495  
     12022-02-09  Antoine Quint  <graouts@webkit.org>
     2
     3        [model] improve sizing on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=236233
     5        <rdar://problem/88569881>
     6
     7        Reviewed by Simon Fraser.
     8
     9        We detect when the <model> layer size changes under RenderLayerBacking::updateGeometry()
     10        and inform the associated HTMLModelElement through the new parentLayerSizeMayHaveChanged()
     11        method that the size has changed. We then inform the backing player that sizeDidChange().
     12
     13        * Modules/model-element/HTMLModelElement.cpp:
     14        (WebCore::HTMLModelElement::createModelPlayer):
     15        (WebCore::HTMLModelElement::parentLayerSizeMayHaveChanged):
     16        (WebCore::HTMLModelElement::platformLayerSize const):
     17        * Modules/model-element/HTMLModelElement.h:
     18        * Modules/model-element/ModelPlayer.h:
     19        * Modules/model-element/dummy/DummyModelPlayer.cpp:
     20        (WebCore::DummyModelPlayer::sizeDidChange):
     21        * Modules/model-element/dummy/DummyModelPlayer.h:
     22        * Modules/model-element/scenekit/SceneKitModelPlayer.h:
     23        * Modules/model-element/scenekit/SceneKitModelPlayer.mm:
     24        (WebCore::SceneKitModelPlayer::sizeDidChange):
     25        * rendering/RenderLayerBacking.cpp:
     26        (WebCore::RenderLayerBacking::updateConfiguration):
     27        (WebCore::RenderLayerBacking::updateGeometry):
     28
    1292022-02-09  Alex Christensen  <achristensen@webkit.org>
    230
  • trunk/Source/WebCore/Modules/model-element/HTMLModelElement.cpp

    r288728 r289495  
    4646#include "JSHTMLModelElement.h"
    4747#include "JSHTMLModelElementCamera.h"
     48#include "LayoutRect.h"
     49#include "LayoutSize.h"
    4850#include "Model.h"
    4951#include "ModelPlayer.h"
     
    5658#include "RenderLayerModelObject.h"
    5759#include "RenderModel.h"
     60#include "RenderReplaced.h"
    5861#include <wtf/IsoMallocInlines.h>
    5962#include <wtf/Seconds.h>
     
    262265    // FIXME: We need to tell the player if the size changes as well, so passing this
    263266    // in with load probably doesn't make sense.
    264     ASSERT(renderer());
    265     auto size = renderer()->absoluteBoundingBoxRect(false).size();
    266     m_modelPlayer->load(*m_model, size);
     267    m_modelPlayer->load(*m_model, contentSize());
    267268}
    268269
     
    275276{
    276277    return m_modelPlayer->layer();
     278}
     279
     280void HTMLModelElement::sizeMayHaveChanged()
     281{
     282    m_modelPlayer->sizeDidChange(contentSize());
    277283}
    278284
     
    639645#endif
    640646
     647LayoutSize HTMLModelElement::contentSize() const
     648{
     649    ASSERT(renderer());
     650    return downcast<RenderReplaced>(*renderer()).replacedContentRect().size();
     651}
     652
    641653}
    642654
  • trunk/Source/WebCore/Modules/model-element/HTMLModelElement.h

    r288728 r289495  
    4444
    4545class Event;
     46class LayoutSize;
    4647class Model;
    4748class ModelPlayer;
     
    104105    Vector<RetainPtr<id>> accessibilityChildren();
    105106#endif
    106    
     107
     108    void sizeMayHaveChanged();
     109
    107110private:
    108111    HTMLModelElement(const QualifiedName&, Document&);
     
    146149    bool isInteractive() const;
    147150
     151    LayoutSize contentSize() const;
     152
    148153    URL m_sourceURL;
    149154    CachedResourceHandle<CachedRawResource> m_resource;
  • trunk/Source/WebCore/Modules/model-element/ModelPlayer.h

    r288728 r289495  
    4545
    4646    virtual void load(Model&, LayoutSize) = 0;
     47    virtual void sizeDidChange(LayoutSize) = 0;
    4748    virtual PlatformLayer* layer() = 0;
    4849    virtual void enterFullscreen() = 0;
  • trunk/Source/WebCore/Modules/model-element/dummy/DummyModelPlayer.cpp

    r286406 r289495  
    5353{
    5454    return nullptr;
     55}
     56
     57void DummyModelPlayer::sizeDidChange(LayoutSize)
     58{
    5559}
    5660
  • trunk/Source/WebCore/Modules/model-element/dummy/DummyModelPlayer.h

    r286406 r289495  
    4343    // ModelPlayer overrides.
    4444    void load(Model&, LayoutSize) override;
     45    void sizeDidChange(LayoutSize) override;
    4546    PlatformLayer* layer() override;
    4647    void enterFullscreen() override;
  • trunk/Source/WebCore/Modules/model-element/scenekit/SceneKitModelPlayer.h

    r286406 r289495  
    5757    // ModelPlayer overrides.
    5858    void load(Model&, LayoutSize) override;
     59    void sizeDidChange(LayoutSize) override;
    5960    CALayer *layer() override;
    6061    void enterFullscreen() override;
  • trunk/Source/WebCore/Modules/model-element/scenekit/SceneKitModelPlayer.mm

    r286406 r289495  
    7272
    7373    m_loader = loadSceneKitModel(modelSource, *this);
     74}
     75
     76void SceneKitModelPlayer::sizeDidChange(LayoutSize)
     77{
    7478}
    7579
  • trunk/Source/WebCore/PAL/ChangeLog

    r289235 r289495  
     12022-02-09  Antoine Quint  <graouts@webkit.org>
     2
     3        [model] improve sizing on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=236233
     5        <rdar://problem/88569881>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Add newly-used CAFenceHandle and ASVInlinePreview SPIs.
     10
     11        * pal/spi/cocoa/QuartzCoreSPI.h:
     12        * pal/spi/mac/SystemPreviewSPI.h:
     13
    1142022-02-07  Antoine Quint  <graouts@webkit.org>
    215
  • trunk/Source/WebCore/PAL/pal/spi/cocoa/QuartzCoreSPI.h

    r286877 r289495  
    5353#endif
    5454
     55#if ENABLE(ARKIT_INLINE_PREVIEW)
     56#import <QuartzCore/CAFenceHandle.h>
     57#endif
     58
    5559#endif // __OBJC__
    5660
     
    6670#endif
    6771
    68 #if ENABLE(ARKIT_INLINE_PREVIEW_IOS)
    69 @class CAFenceHandle;
     72#if ENABLE(ARKIT_INLINE_PREVIEW)
     73@interface CAFenceHandle : NSObject
     74@end
     75
     76@interface CAFenceHandle ()
     77- (mach_port_t)copyPort;
     78- (void)invalidate;
     79@end
    7080#endif
    7181
  • trunk/Source/WebCore/PAL/pal/spi/mac/SystemPreviewSPI.h

    r286317 r289495  
    5151- (void)setRemoteContext:(uint32_t)contextId;
    5252
     53- (void)updateFrame:(CGRect)newFrame completionHandler:(void (^)(CAFenceHandle * _Nullable fenceHandle, NSError * _Nullable error))handler;
     54- (void)setFrameWithinFencedTransaction:(CGRect)frame;
     55
    5356- (void)mouseDownAtLocation:(CGPoint)location timestamp:(NSTimeInterval)timestamp;
    5457- (void)mouseDraggedAtLocation:(CGPoint)location timestamp:(NSTimeInterval)timestamp;
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r289225 r289495  
    11211121        // Some ModelPlayers use a platformLayer() and some pass the Model to the layer as contents,
    11221122        // but this is a runtime decision.
    1123         if (element->usesPlatformLayer()) {
     1123        if (element->usesPlatformLayer())
    11241124            m_graphicsLayer->setContentsToPlatformLayer(element->platformLayer(), GraphicsLayer::ContentsLayerPurpose::Model);
    1125         } else if (auto model = element->model())
     1125        else if (auto model = element->model())
    11261126            m_graphicsLayer->setContentsToModel(WTFMove(model));
    11271127
     
    15321532    if (subpixelOffsetFromRendererChanged(oldSubpixelOffsetFromRenderer, m_subpixelOffsetFromRenderer, deviceScaleFactor) && canIssueSetNeedsDisplay())
    15331533        setContentsNeedDisplay();
     1534
     1535#if ENABLE(MODEL_ELEMENT)
     1536    if (is<RenderModel>(renderer())) {
     1537        auto* element = downcast<HTMLModelElement>(renderer().element());
     1538        if (element->usesPlatformLayer())
     1539            element->sizeMayHaveChanged();
     1540    }
     1541#endif
    15341542}
    15351543
  • trunk/Source/WebKit/ChangeLog

    r289492 r289495  
     12022-02-09  Antoine Quint  <graouts@webkit.org>
     2
     3        [model] improve sizing on macOS
     4        https://bugs.webkit.org/show_bug.cgi?id=236233
     5        <rdar://problem/88569881>
     6
     7        Reviewed by Simon Fraser.
     8
     9        We override the new ModelPlayer::sizeDidChange() virtual method on ARKitInlinePreviewModelPlayerMac
     10        to be notified when the <model> layer's has changed size. We then send the new ModelElementSizeDidChange
     11        message to the UI process which will yield a call to ModelElementController::modelElementSizeDidChange().
     12
     13        In that new method, we call -[ASVInlinePreview updateFrame:completionHandler:] which provides us with a
     14        CAFenceHandle which we copy to create a MachSendRight to send back to the Web process in the IPC callback.
     15
     16        Back in the Web process, we install this fence on the drawing area and finally call -[ASVInlinePreview
     17        setFrameWithinFencedTransaction:] to complete the sizing update on both the ASVInlinePreview instances.
     18
     19        * UIProcess/Cocoa/ModelElementControllerCocoa.mm:
     20        (WebKit::ModelElementController::modelElementSizeDidChange):
     21        * UIProcess/ModelElementController.h:
     22        * UIProcess/WebPageProxy.cpp:
     23        (WebKit::WebPageProxy::modelElementSizeDidChange):
     24        * UIProcess/WebPageProxy.h:
     25        * UIProcess/WebPageProxy.messages.in:
     26        * WebProcess/Model/ARKitInlinePreviewModelPlayer.h:
     27        * WebProcess/Model/ARKitInlinePreviewModelPlayer.mm:
     28        (WebKit::ARKitInlinePreviewModelPlayer::sizeDidChange):
     29        * WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.h:
     30        * WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.mm:
     31        (WebKit::ARKitInlinePreviewModelPlayerMac::load):
     32        (WebKit::ARKitInlinePreviewModelPlayerMac::sizeDidChange):
     33
    1342022-02-09  Kimmo Kinnunen  <kkinnunen@apple.com>
    235
  • trunk/Source/WebKit/UIProcess/Cocoa/ModelElementControllerCocoa.mm

    r288728 r289495  
    3434#import <WebCore/LayoutUnit.h>
    3535#import <WebCore/ResourceError.h>
     36#import <pal/spi/cocoa/QuartzCoreSPI.h>
    3637#import <simd/simd.h>
     38#import <wtf/MachSendRight.h>
    3739#import <wtf/MainThread.h>
    3840#import <wtf/MonotonicTime.h>
     
    4446#import "RemoteLayerTreeViews.h"
    4547#import "WKModelView.h"
    46 #import <pal/spi/cocoa/QuartzCoreSPI.h>
    4748#import <pal/spi/ios/SystemPreviewSPI.h>
    4849#endif
     
    240241}
    241242
     243void ModelElementController::modelElementSizeDidChange(const String& uuid, WebCore::FloatSize size, CompletionHandler<void(Expected<MachSendRight, WebCore::ResourceError>)>&& completionHandler)
     244{
     245    auto preview = previewForUUID(uuid);
     246    if (!preview) {
     247        completionHandler(makeUnexpected(WebCore::ResourceError { WebCore::errorDomainWebKitInternal, 0, { }, "Could not find model"_s }));
     248        return;
     249    }
     250
     251    auto handler = CompletionHandlerWithFinalizer<void(Expected<MachSendRight, WebCore::ResourceError>)>(WTFMove(completionHandler), [] (Function<void(Expected<MachSendRight, WebCore::ResourceError>)>& completionHandler) {
     252        completionHandler(makeUnexpected(WebCore::ResourceError { WebCore::ResourceError::Type::General }));
     253    });
     254
     255    [preview updateFrame:CGRectMake(0, 0, size.width(), size.height()) completionHandler:makeBlockPtr([weakThis = WeakPtr { *this }, handler = WTFMove(handler), uuid] (CAFenceHandle *fenceHandle, NSError *error) mutable {
     256        if (error) {
     257            LOG(ModelElement, "Unable to update frame: %@.", error.localizedDescription);
     258            callOnMainRunLoop([weakThis = WTFMove(weakThis), handler = WTFMove(handler), error = WebCore::ResourceError { error }] () mutable {
     259                if (!weakThis)
     260                    return;
     261                handler(makeUnexpected(error));
     262            });
     263            [fenceHandle invalidate];
     264            return;
     265        }
     266
     267        RetainPtr strongFenceHandle = fenceHandle;
     268        callOnMainRunLoop([weakThis = WTFMove(weakThis), handler = WTFMove(handler), uuid, strongFenceHandle = WTFMove(strongFenceHandle)] () mutable {
     269            if (!weakThis)
     270                return;
     271
     272            auto fenceSendRight = MachSendRight::adopt([strongFenceHandle copyPort]);
     273            [strongFenceHandle invalidate];
     274            handler(fenceSendRight);
     275        });
     276    }).get()];
     277}
     278
    242279#endif
    243280
  • trunk/Source/WebKit/UIProcess/ModelElementController.h

    r288728 r289495  
    7272#if ENABLE(ARKIT_INLINE_PREVIEW_MAC)
    7373    void modelElementDidCreatePreview(URL, String, WebCore::FloatSize, CompletionHandler<void(Expected<std::pair<String, uint32_t>, WebCore::ResourceError>)>&&);
     74    void modelElementSizeDidChange(const String& uuid, WebCore::FloatSize, CompletionHandler<void(Expected<MachSendRight, WebCore::ResourceError>)>&&);
    7475    void handleMouseDownForModelElement(const String&, const WebCore::LayoutPoint&, MonotonicTime);
    7576    void handleMouseMoveForModelElement(const String&, const WebCore::LayoutPoint&, MonotonicTime);
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r289463 r289495  
    1109811098}
    1109911099
     11100void WebPageProxy::modelElementSizeDidChange(const String& uuid, WebCore::FloatSize size, CompletionHandler<void(Expected<MachSendRight, WebCore::ResourceError>)>&& completionHandler)
     11101{
     11102    modelElementController()->modelElementSizeDidChange(uuid, size, WTFMove(completionHandler));
     11103}
     11104
    1110011105void WebPageProxy::handleMouseDownForModelElement(const String& uuid, const WebCore::LayoutPoint& flippedLocationInElement, MonotonicTime timestamp)
    1110111106{
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r289463 r289495  
    613613#if ENABLE(ARKIT_INLINE_PREVIEW_MAC)
    614614    void modelElementDidCreatePreview(const URL&, const String&, const WebCore::FloatSize&, CompletionHandler<void(Expected<std::pair<String, uint32_t>, WebCore::ResourceError>)>&&);
     615    void modelElementSizeDidChange(const String&, WebCore::FloatSize, CompletionHandler<void(Expected<MachSendRight, WebCore::ResourceError>)>&&);
    615616    void handleMouseDownForModelElement(const String&, const WebCore::LayoutPoint&, MonotonicTime);
    616617    void handleMouseMoveForModelElement(const String&, const WebCore::LayoutPoint&, MonotonicTime);
  • trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r288728 r289495  
    590590#if ENABLE(ARKIT_INLINE_PREVIEW_MAC)
    591591    ModelElementDidCreatePreview(URL url, String uuid, WebCore::FloatSize size) -> (Expected<std::pair<String, uint32_t>, WebCore::ResourceError> result) Async
     592    ModelElementSizeDidChange(String uuid, WebCore::FloatSize size) -> (Expected<MachSendRight, WebCore::ResourceError> result) Async
    592593    HandleMouseDownForModelElement(String uuid, WebCore::LayoutPoint flippedLocationInElement, MonotonicTime timestamp)
    593594    HandleMouseMoveForModelElement(String uuid, WebCore::LayoutPoint flippedLocationInElement, MonotonicTime timestamp)
  • trunk/Source/WebKit/WebProcess/Model/ARKitInlinePreviewModelPlayer.h

    r286406 r289495  
    5252    // WebCore::ModelPlayer overrides.
    5353    void load(WebCore::Model&, WebCore::LayoutSize) override;
     54    void sizeDidChange(WebCore::LayoutSize) override;
    5455    PlatformLayer* layer() override;
    5556    void enterFullscreen() override;
  • trunk/Source/WebKit/WebProcess/Model/ARKitInlinePreviewModelPlayer.mm

    r286406 r289495  
    4747}
    4848
     49void ARKitInlinePreviewModelPlayer::sizeDidChange(LayoutSize)
     50{
     51}
     52
    4953PlatformLayer* ARKitInlinePreviewModelPlayer::layer()
    5054{
  • trunk/Source/WebKit/WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.h

    r288723 r289495  
    5252    // WebCore::ModelPlayer overrides.
    5353    void load(WebCore::Model&, WebCore::LayoutSize) override;
     54    void sizeDidChange(WebCore::LayoutSize) override;
    5455    PlatformLayer* layer() override;
    5556    bool supportsMouseInteraction() override;
     
    6263    void clearFile();
    6364
     65    WebCore::LayoutSize m_size;
    6466    String m_filePath;
    6567    RetainPtr<ASVInlinePreview> m_inlinePreview;
  • trunk/Source/WebKit/WebProcess/Model/mac/ARKitInlinePreviewModelPlayerMac.mm

    r288950 r289495  
    2929#if ENABLE(ARKIT_INLINE_PREVIEW_MAC)
    3030
     31#import "DrawingArea.h"
    3132#import "WebPage.h"
    3233#import "WebPageProxyMessages.h"
    3334#import <WebCore/Model.h>
     35#import <pal/spi/cocoa/QuartzCoreSPI.h>
    3436#import <pal/spi/mac/SystemPreviewSPI.h>
     37#import <wtf/MachSendRight.h>
    3538#import <wtf/SoftLinking.h>
    3639#import <wtf/UUID.h>
     
    125128void ARKitInlinePreviewModelPlayerMac::load(WebCore::Model& modelSource, WebCore::LayoutSize size)
    126129{
     130    m_size = size;
     131
    127132    auto strongClient = client();
    128133    if (!strongClient)
     
    173178}
    174179
     180void ARKitInlinePreviewModelPlayerMac::sizeDidChange(WebCore::LayoutSize size)
     181{
     182    if (m_size == size)
     183        return;
     184
     185    m_size = size;
     186
     187    RefPtr strongPage = page();
     188    if (!strongPage)
     189        return;
     190
     191    String uuid = [m_inlinePreview uuid].UUIDString;
     192    CompletionHandler<void(Expected<MachSendRight, WebCore::ResourceError>)> completionHandler = [weakSelf = WeakPtr { *this }, strongPage, size] (Expected<MachSendRight, WebCore::ResourceError> result) mutable {
     193        if (!result)
     194            return;
     195
     196        RefPtr strongSelf = weakSelf.get();
     197        if (!strongSelf)
     198            return;
     199
     200        auto* drawingArea = strongPage->drawingArea();
     201        if (!drawingArea)
     202            return;
     203
     204        auto fenceSendRight = *result;
     205        drawingArea->addFence(fenceSendRight);
     206
     207        [strongSelf->m_inlinePreview setFrameWithinFencedTransaction:CGRectMake(0, 0, size.width(), size.height())];
     208    };
     209
     210    strongPage->sendWithAsyncReply(Messages::WebPageProxy::ModelElementSizeDidChange(uuid, size), WTFMove(completionHandler));
     211}
     212
    175213PlatformLayer* ARKitInlinePreviewModelPlayerMac::layer()
    176214{
Note: See TracChangeset for help on using the changeset viewer.