Changeset 175716 in webkit


Ignore:
Timestamp:
Nov 6, 2014 2:23:16 PM (9 years ago)
Author:
dino@apple.com
Message:

[filters2] Support for backdrop-filter
https://bugs.webkit.org/show_bug.cgi?id=138384
<rdar://problem/18874494>

Reviewed by Simon Fraser.

Take 2!! Previous patch was rolled out.

Source/WebCore:

Add prototype support for backdrop-filter
http://dev.w3.org/fxtf/filters-2/#BackdropFilterProperty

This adds support for parsing the new CSS property, adding
the value to RenderStyle, noticing that on the layer tree,
and the platform code in GraphicsLayer to render a backdrop
and apply an effect to the result.

Some things are missing:

  • animation of the backdrop-filter is not yet supported
  • backdrops will not work in cloned layers yet (e.g. reflections)

Tests: css3/filters/backdrop/backdropfilter-property-computed-style.html

css3/filters/backdrop/backdropfilter-property-parsing-invalid.html
css3/filters/backdrop/backdropfilter-property-parsing.html
css3/filters/backdrop/backdropfilter-property.html
css3/filters/backdrop/effect-hw.html

  • WebCore.exp.in: Export the setBackdropFilters method so it can

be used from WebKit.

  • css/CSSComputedStyleDeclaration.cpp: New property name.

(WebCore::isLayoutDependent):
(WebCore::ComputedStyleExtractor::propertyValue): Use the existing valueForFilter method.

  • css/CSSParser.cpp:

(WebCore::CSSParser::parseValue): Piggyback on the filter parser.

  • css/CSSPropertyNames.in: Add -webkit-backdrop-filter.
  • css/StyleResolver.cpp:

(WebCore::StyleResolver::adjustRenderStyle): Add test for backdrop.
(WebCore::StyleResolver::applyProperty): Support new property.

  • platform/graphics/GraphicsLayer.h:

(WebCore::GraphicsLayer::needsBackdrop): New method to test for existence of values.
(WebCore::GraphicsLayer::backdropFilters): Keeps the list of filters.
(WebCore::GraphicsLayer::setBackdropFilters):
(WebCore::GraphicsLayer::clearBackdropFilters):

  • platform/graphics/ca/GraphicsLayerCA.cpp: This adds a new m_backdropLayer CALayer

that will sit behind the contents layer and provide the element's backdrop.
(WebCore::GraphicsLayerCA::willBeDestroyed):
(WebCore::GraphicsLayerCA::moveOrCopyAnimations):
(WebCore::GraphicsLayerCA::setBackdropFilters): Set a custom appearance so
remote layer hosts will notice the special layer. Also set the actual
layer properties.
(WebCore::GraphicsLayerCA::addAnimation): Remove whitespace.
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Update backdrop if necessary.
(WebCore::GraphicsLayerCA::updateLayerNames): Give the new layer a name.
(WebCore::GraphicsLayerCA::updateSublayerList):
(WebCore::GraphicsLayerCA::updateGeometry): Make the backdrop layer match the contents
layer geometry.
(WebCore::GraphicsLayerCA::updateBackdropFilters): Create the backdrop layer if necessary,
and copy the filter values to any clones.
(WebCore::GraphicsLayerCA::ensureStructuralLayer): We need a structural layer if we
have backdrop filters.
(WebCore::GraphicsLayerCA::structuralLayerPurpose):
(WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
(WebCore::GraphicsLayerCA::swapFromOrToTiledLayer):

  • platform/graphics/ca/GraphicsLayerCA.h: New StructuralLayerPurpose, new LayerChangeFlag.
  • platform/graphics/ca/PlatformCALayer.h: New LayerType.
  • platform/graphics/ca/mac/PlatformCALayerMac.mm: Define CABackdropLayer.

(PlatformCALayerMac::PlatformCALayerMac): Create the correct CALayer type.

  • rendering/RenderElement.h:

(WebCore::RenderElement::createsGroup):
(WebCore::RenderElement::hasBackdropFilter): This method is always around, but
only can return true when FILTERS_LEVEL_2 is enabled.

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::paintsWithFilters): Remove an unnecessary comment.
(WebCore::RenderLayer::calculateClipRects):

  • rendering/RenderLayer.h: Add hasBackdropFilter.
  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::RenderLayerBacking):
(WebCore::RenderLayerBacking::createPrimaryGraphicsLayer): Update the backdrop filters.
(WebCore::RenderLayerBacking::updateBackdropFilters): Set the filters on the GraphicsLayer.
(WebCore::RenderLayerBacking::updateGeometry):

  • rendering/RenderLayerBacking.h:
  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::requiresOwnBackingStore): Needs backingstore if it has a backdrop filter.
(WebCore::RenderLayerCompositor::reasonsForCompositing):
(WebCore::RenderLayerCompositor::requiresCompositingForFilters): Return early if we have
a backdrop filter, because currently we absolutely require compositing.

  • rendering/RenderLayerModelObject.cpp:

(WebCore::RenderLayerModelObject::styleWillChange): Add hasBackdropFilter().

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::changeRequiresLayout): Check backdrops for change.

  • rendering/style/RenderStyle.h: Add the backdropFilter style stuff.
  • rendering/style/StyleRareNonInheritedData.cpp:

(WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
(WebCore::StyleRareNonInheritedData::operator==):
(WebCore::StyleRareNonInheritedData::hasBackdropFilters):

  • rendering/style/StyleRareNonInheritedData.h:

Source/WebKit2:

  • Shared/mac/RemoteLayerBackingStore.mm:

(WebKit::RemoteLayerBackingStore::drawInContext): Handle LayerTypeBackdropLayer in the switch.

  • Shared/mac/RemoteLayerTreeTransaction.mm:

(WebKit::RemoteLayerTreeTransaction::description): Describe a backdrop layer.

  • UIProcess/ios/RemoteLayerTreeHostIOS.mm:

(+[WKBackdropView layerClass]): Define CABackdropLayer and use it as the class.
(WebKit::RemoteLayerTreeHost::createLayer):

  • UIProcess/mac/RemoteLayerTreeHost.mm: Ditto.

(WebKit::RemoteLayerTreeHost::createLayer):

LayoutTests:

Tests for backdrop-filter. These are skipped on non-Apple platforms.

  • platform/win/TestExpections: Skip these tests.
  • platform/efl/TestExpections:
  • platform/gtk/TestExpections:
  • platform/mac-mavericks/TestExpectations: Yosemite only.
  • css3/filters/backdrop/backdropfilter-property-computed-style-expected.txt: Added.
  • css3/filters/backdrop/backdropfilter-property-computed-style.html: Added.
  • css3/filters/backdrop/backdropfilter-property-expected.txt: Added.
  • css3/filters/backdrop/backdropfilter-property-parsing-expected.txt: Added.
  • css3/filters/backdrop/backdropfilter-property-parsing-invalid-expected.txt: Added.
  • css3/filters/backdrop/backdropfilter-property-parsing-invalid.html: Added.
  • css3/filters/backdrop/backdropfilter-property-parsing.html: Added.
  • css3/filters/backdrop/backdropfilter-property.html: Added.
  • css3/filters/backdrop/effect-hw-expected.html: Added.
  • css3/filters/backdrop/effect-hw.html: Added.
  • css3/filters/backdrop/script-tests/backdropfilter-property-computed-style.js: Added.

(testComputedFilterRule):

  • css3/filters/backdrop/script-tests/backdropfilter-property-parsing-invalid.js: Added.

(testInvalidFilterRule):

  • css3/filters/backdrop/script-tests/backdropfilter-property-parsing.js: Added.

(jsWrapperClass):
(shouldBeType):
(testFilterRule):

  • css3/filters/backdrop/script-tests/backdropfilter-property.js: Added.
Location:
trunk
Files:
16 added
34 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r175715 r175716  
     12014-11-06  Dean Jackson  <dino@apple.com>
     2
     3        [filters2] Support for backdrop-filter
     4        https://bugs.webkit.org/show_bug.cgi?id=138384
     5        <rdar://problem/18874494>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Take 2!! Previous patch was rolled out.
     10
     11        Tests for backdrop-filter. These are skipped on non-Apple platforms.
     12
     13        * platform/win/TestExpections: Skip these tests.
     14        * platform/efl/TestExpections:
     15        * platform/gtk/TestExpections:
     16        * platform/mac-mavericks/TestExpectations: Yosemite only.
     17
     18        * css3/filters/backdrop/backdropfilter-property-computed-style-expected.txt: Added.
     19        * css3/filters/backdrop/backdropfilter-property-computed-style.html: Added.
     20        * css3/filters/backdrop/backdropfilter-property-expected.txt: Added.
     21        * css3/filters/backdrop/backdropfilter-property-parsing-expected.txt: Added.
     22        * css3/filters/backdrop/backdropfilter-property-parsing-invalid-expected.txt: Added.
     23        * css3/filters/backdrop/backdropfilter-property-parsing-invalid.html: Added.
     24        * css3/filters/backdrop/backdropfilter-property-parsing.html: Added.
     25        * css3/filters/backdrop/backdropfilter-property.html: Added.
     26        * css3/filters/backdrop/effect-hw-expected.html: Added.
     27        * css3/filters/backdrop/effect-hw.html: Added.
     28        * css3/filters/backdrop/script-tests/backdropfilter-property-computed-style.js: Added.
     29        (testComputedFilterRule):
     30        * css3/filters/backdrop/script-tests/backdropfilter-property-parsing-invalid.js: Added.
     31        (testInvalidFilterRule):
     32        * css3/filters/backdrop/script-tests/backdropfilter-property-parsing.js: Added.
     33        (jsWrapperClass):
     34        (shouldBeType):
     35        (testFilterRule):
     36        * css3/filters/backdrop/script-tests/backdropfilter-property.js: Added.
     37
    1382014-11-06  Benjamin Poulain  <bpoulain@apple.com>
    239
  • trunk/LayoutTests/platform/efl/TestExpectations

    r175687 r175716  
    446446media/encrypted-media/encrypted-media-not-loaded.html [ WontFix ]
    447447media/encrypted-media/encrypted-media-syntax.html [ WontFix ]
     448
     449# No support for Filters Level 2 on EFL yet
     450Bug(EFL) css3/filters/backdrop [ Skip ]
    448451
    449452#////////////////////////////////////////////////////////////////////////////////////////
  • trunk/LayoutTests/platform/gtk/TestExpectations

    r175687 r175716  
    443443
    444444webkit.org/b/133806 svg/masking/mask-transformed-text-missing.svg [ ImageOnlyFailure ]
     445
     446# No support for Filters Level 2 on GTK yet
     447Bug(GTK) css3/filters/backdrop [ Skip ]
    445448
    446449#////////////////////////////////////////////////////////////////////////////////////////
  • trunk/LayoutTests/platform/mac-mavericks/TestExpectations

    r175687 r175716  
    11# This test should only be run on Yosemite or later.
    22platform/mac/editing/input/undo-grouping-on-text-insertion.html [ Skip ]
     3
     4# Backdrop filters are not supported on Mavericks
     5css3/filters/backdrop [ Skip ]
  • trunk/LayoutTests/platform/win/TestExpectations

    r175687 r175716  
    4545css3/filters/filter-is-on-subpixel-position.html
    4646css3/masking/clip-path-filter.html
     47css3/filters/backdrop
    4748
    4849# Remove from list after enabling CANVAS_PATH
  • trunk/Source/WebCore/ChangeLog

    r175715 r175716  
     12014-11-06  Dean Jackson  <dino@apple.com>
     2
     3        [filters2] Support for backdrop-filter
     4        https://bugs.webkit.org/show_bug.cgi?id=138384
     5        <rdar://problem/18874494>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Take 2!! Previous patch was rolled out.
     10
     11        Add prototype support for backdrop-filter
     12        http://dev.w3.org/fxtf/filters-2/#BackdropFilterProperty
     13
     14        This adds support for parsing the new CSS property, adding
     15        the value to RenderStyle, noticing that on the layer tree,
     16        and the platform code in GraphicsLayer to render a backdrop
     17        and apply an effect to the result.
     18
     19        Some things are missing:
     20        - animation of the backdrop-filter is not yet supported
     21        - backdrops will not work in cloned layers yet (e.g. reflections)
     22
     23        Tests: css3/filters/backdrop/backdropfilter-property-computed-style.html
     24               css3/filters/backdrop/backdropfilter-property-parsing-invalid.html
     25               css3/filters/backdrop/backdropfilter-property-parsing.html
     26               css3/filters/backdrop/backdropfilter-property.html
     27               css3/filters/backdrop/effect-hw.html
     28
     29        * WebCore.exp.in: Export the setBackdropFilters method so it can
     30        be used from WebKit.
     31
     32        * css/CSSComputedStyleDeclaration.cpp: New property name.
     33        (WebCore::isLayoutDependent):
     34        (WebCore::ComputedStyleExtractor::propertyValue): Use the existing valueForFilter method.
     35
     36        * css/CSSParser.cpp:
     37        (WebCore::CSSParser::parseValue): Piggyback on the filter parser.
     38
     39        * css/CSSPropertyNames.in: Add -webkit-backdrop-filter.
     40
     41        * css/StyleResolver.cpp:
     42        (WebCore::StyleResolver::adjustRenderStyle): Add test for backdrop.
     43        (WebCore::StyleResolver::applyProperty): Support new property.
     44
     45        * platform/graphics/GraphicsLayer.h:
     46        (WebCore::GraphicsLayer::needsBackdrop): New method to test for existence of values.
     47        (WebCore::GraphicsLayer::backdropFilters): Keeps the list of filters.
     48        (WebCore::GraphicsLayer::setBackdropFilters):
     49        (WebCore::GraphicsLayer::clearBackdropFilters):
     50
     51        * platform/graphics/ca/GraphicsLayerCA.cpp: This adds a new m_backdropLayer CALayer
     52        that will sit behind the contents layer and provide the element's backdrop.
     53        (WebCore::GraphicsLayerCA::willBeDestroyed):
     54        (WebCore::GraphicsLayerCA::moveOrCopyAnimations):
     55        (WebCore::GraphicsLayerCA::setBackdropFilters): Set a custom appearance so
     56        remote layer hosts will notice the special layer. Also set the actual
     57        layer properties.
     58        (WebCore::GraphicsLayerCA::addAnimation): Remove whitespace.
     59        (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Update backdrop if necessary.
     60        (WebCore::GraphicsLayerCA::updateLayerNames): Give the new layer a name.
     61        (WebCore::GraphicsLayerCA::updateSublayerList):
     62        (WebCore::GraphicsLayerCA::updateGeometry): Make the backdrop layer match the contents
     63        layer geometry.
     64        (WebCore::GraphicsLayerCA::updateBackdropFilters): Create the backdrop layer if necessary,
     65        and copy the filter values to any clones.
     66        (WebCore::GraphicsLayerCA::ensureStructuralLayer): We need a structural layer if we
     67        have backdrop filters.
     68        (WebCore::GraphicsLayerCA::structuralLayerPurpose):
     69        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
     70        (WebCore::GraphicsLayerCA::swapFromOrToTiledLayer):
     71        * platform/graphics/ca/GraphicsLayerCA.h: New StructuralLayerPurpose, new LayerChangeFlag.
     72
     73        * platform/graphics/ca/PlatformCALayer.h: New LayerType.
     74
     75        * platform/graphics/ca/mac/PlatformCALayerMac.mm: Define CABackdropLayer.
     76        (PlatformCALayerMac::PlatformCALayerMac): Create the correct CALayer type.
     77
     78        * rendering/RenderElement.h:
     79        (WebCore::RenderElement::createsGroup):
     80        (WebCore::RenderElement::hasBackdropFilter): This method is always around, but
     81        only can return true when FILTERS_LEVEL_2 is enabled.
     82
     83        * rendering/RenderLayer.cpp:
     84        (WebCore::RenderLayer::paintsWithFilters): Remove an unnecessary comment.
     85        (WebCore::RenderLayer::calculateClipRects):
     86
     87        * rendering/RenderLayer.h: Add hasBackdropFilter.
     88
     89        * rendering/RenderLayerBacking.cpp:
     90        (WebCore::RenderLayerBacking::RenderLayerBacking):
     91        (WebCore::RenderLayerBacking::createPrimaryGraphicsLayer): Update the backdrop filters.
     92        (WebCore::RenderLayerBacking::updateBackdropFilters): Set the filters on the GraphicsLayer.
     93        (WebCore::RenderLayerBacking::updateGeometry):
     94        * rendering/RenderLayerBacking.h:
     95
     96        * rendering/RenderLayerCompositor.cpp:
     97        (WebCore::RenderLayerCompositor::requiresOwnBackingStore): Needs backingstore if it has a backdrop filter.
     98        (WebCore::RenderLayerCompositor::reasonsForCompositing):
     99        (WebCore::RenderLayerCompositor::requiresCompositingForFilters): Return early if we have
     100        a backdrop filter, because currently we absolutely require compositing.
     101
     102        * rendering/RenderLayerModelObject.cpp:
     103        (WebCore::RenderLayerModelObject::styleWillChange): Add hasBackdropFilter().
     104
     105        * rendering/style/RenderStyle.cpp:
     106        (WebCore::RenderStyle::changeRequiresLayout): Check backdrops for change.
     107
     108        * rendering/style/RenderStyle.h: Add the backdropFilter style stuff.
     109        * rendering/style/StyleRareNonInheritedData.cpp:
     110        (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
     111        (WebCore::StyleRareNonInheritedData::operator==):
     112        (WebCore::StyleRareNonInheritedData::hasBackdropFilters):
     113        * rendering/style/StyleRareNonInheritedData.h:
     114
    11152014-11-06  Benjamin Poulain  <bpoulain@apple.com>
    2116
  • trunk/Source/WebCore/WebCore.exp.in

    r175710 r175716  
    550550__ZN7WebCore15GraphicsContextD1Ev
    551551__ZN7WebCore15GraphicsLayerCA10initializeEv
     552__ZN7WebCore15GraphicsLayerCA18setBackdropFiltersERKNS_16FilterOperationsE
    552553__ZN7WebCore15GraphicsLayerCA10setFiltersERKNS_16FilterOperationsE
    553554__ZN7WebCore15GraphicsLayerCA10setOpacityEf
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r175687 r175716  
    292292    CSSPropertyWebkitJustifySelf,
    293293    CSSPropertyWebkitFilter,
     294#if ENABLE(FILTERS_LEVEL_2)
     295    CSSPropertyWebkitBackdropFilter,
     296#endif
    294297    CSSPropertyWebkitFontKerning,
    295298    CSSPropertyWebkitFontSmoothing,
     
    16001603    case CSSPropertyWebkitTransform:
    16011604    case CSSPropertyWebkitFilter:
     1605#if ENABLE(FILTERS_LEVEL_2)
     1606    case CSSPropertyWebkitBackdropFilter:
     1607#endif
    16021608        return true;
    16031609    case CSSPropertyMargin: {
     
    28922898        case CSSPropertyWebkitFilter:
    28932899            return valueForFilter(style.get(), style->filter());
     2900#if ENABLE(FILTERS_LEVEL_2)
     2901        case CSSPropertyWebkitBackdropFilter:
     2902            return valueForFilter(style.get(), style->backdropFilter());
     2903#endif
    28942904#if ENABLE(CSS_COMPOSITING)
    28952905        case CSSPropertyMixBlendMode:
  • trunk/Source/WebCore/css/CSSParser.cpp

    r175687 r175716  
    24562456        break;
    24572457    case CSSPropertyWebkitFilter:
     2458#if ENABLE(FILTERS_LEVEL_2)
     2459    case CSSPropertyWebkitBackdropFilter:
     2460#endif
    24582461        if (id == CSSValueNone)
    24592462            validPrimitive = true;
  • trunk/Source/WebCore/css/CSSPropertyNames.in

    r175687 r175716  
    372372justify-content [NewStyleBuilder]
    373373-webkit-justify-content = justify-content
     374#if defined(ENABLE_FILTERS_LEVEL_2) && ENABLE_FILTERS_LEVEL_2
     375-webkit-backdrop-filter
     376#endif
    374377-webkit-justify-self
    375378-webkit-font-size-delta
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r175687 r175716  
    12601260        || style.boxReflect()
    12611261        || style.hasFilter()
     1262#if ENABLE(FILTERS_LEVEL_2)
     1263        || style.hasBackdropFilter()
     1264#endif
    12621265        || style.hasBlendMode()
    12631266        || style.hasIsolation()
     
    13531356        || style.overflowY() != OVISIBLE
    13541357        || style.hasFilter()
     1358#if ENABLE(FILTERS_LEVEL_2)
     1359        || style.hasBackdropFilter()
     1360#endif
    13551361        || style.hasBlendMode()))
    13561362        style.setTransformStyle3D(TransformStyle3DFlat);
     
    27022708        return;
    27032709    }
     2710
     2711#if ENABLE(FILTERS_LEVEL_2)
     2712    case CSSPropertyWebkitBackdropFilter: {
     2713        HANDLE_INHERIT_AND_INITIAL(backdropFilter, BackdropFilter);
     2714        FilterOperations operations;
     2715        if (createFilterOperations(value, operations))
     2716            state.style()->setBackdropFilter(operations);
     2717        return;
     2718    }
     2719#endif
    27042720
    27052721#if ENABLE(CSS_GRID_LAYOUT)
  • trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp

    r175687 r175716  
    363363    m_filterFunctionListsMatch = false;
    364364
     365#if ENABLE(FILTERS_LEVEL_2)
     366    if (m_keyframes.size() < 2 || (!m_keyframes.containsProperty(CSSPropertyWebkitFilter) && !m_keyframes.containsProperty(CSSPropertyWebkitBackdropFilter)))
     367#else
    365368    if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitFilter))
     369#endif
    366370        return;
    367371
  • trunk/Source/WebCore/platform/graphics/GraphicsLayer.h

    r175687 r175716  
    326326    virtual void setAcceleratesDrawing(bool b) { m_acceleratesDrawing = b; }
    327327
     328    bool needsBackdrop() const { return !m_backdropFilters.isEmpty(); }
     329
    328330    // The color used to paint the layer background. Pass an invalid color to remove it.
    329331    // Note that this covers the entire layer. Use setContentsToSolidColor() if the color should
     
    343345
    344346    const FilterOperations& filters() const { return m_filters; }
    345    
    346     // Returns true if filter can be rendered by the compositor
     347    // Returns true if filter can be rendered by the compositor.
    347348    virtual bool setFilters(const FilterOperations& filters) { m_filters = filters; return true; }
     349
     350    const FilterOperations& backdropFilters() const { return m_backdropFilters; }
     351    virtual bool setBackdropFilters(const FilterOperations& filters) { m_backdropFilters = filters; return true; }
    348352
    349353#if ENABLE(CSS_COMPOSITING)
     
    519523    // needs to notifiy the change to the platform layer as needed.
    520524    void clearFilters() { m_filters.clear(); }
     525    void clearBackdropFilters() { m_backdropFilters.clear(); }
    521526
    522527    // Given a KeyframeValueList containing filterOperations, return true if the operations are valid.
     
    565570   
    566571    FilterOperations m_filters;
     572    FilterOperations m_backdropFilters;
    567573
    568574#if ENABLE(CSS_COMPOSITING)
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

    r175687 r175716  
    303303#endif
    304304}
    305    
     305
    306306PassRefPtr<PlatformCALayer> GraphicsLayerCA::createPlatformCALayer(PlatformCALayer::LayerType layerType, PlatformCALayerClient* owner)
    307307{
     
    377377    if (m_structuralLayer)
    378378        m_structuralLayer->setOwner(nullptr);
    379    
     379
     380    if (m_backdropLayer)
     381        m_backdropLayer->setOwner(nullptr);
     382
    380383    removeCloneLayers();
    381384
     
    568571        for (size_t i = 0; i < numAnimations; ++i) {
    569572            const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
    570            
     573
    571574            if (currAnimation.m_property == AnimatedPropertyWebkitTransform || currAnimation.m_property == AnimatedPropertyOpacity
    572575                    || currAnimation.m_property == AnimatedPropertyBackgroundColor
     
    686689}
    687690
     691bool GraphicsLayerCA::setBackdropFilters(const FilterOperations& filterOperations)
     692{
     693    bool canCompositeFilters = filtersCanBeComposited(filterOperations);
     694
     695    if (m_backdropFilters == filterOperations)
     696        return canCompositeFilters;
     697
     698    // Filters cause flattening, so we should never have filters on a layer with preserves3D().
     699    ASSERT(!filterOperations.size() || !preserves3D());
     700
     701    if (canCompositeFilters)
     702        GraphicsLayer::setBackdropFilters(filterOperations);
     703    else {
     704        // FIXME: This would clear the backdrop filters if we had a software implementation.
     705        clearBackdropFilters();
     706    }
     707    noteLayerPropertyChanged(BackdropFiltersChanged);
     708    return canCompositeFilters;
     709}
     710
    688711#if ENABLE(CSS_COMPOSITING)
    689712void GraphicsLayerCA::setBlendMode(BlendMode blendMode)
     
    800823    if (createdAnimations)
    801824        noteLayerPropertyChanged(AnimationChanged);
    802        
     825
    803826    return createdAnimations;
    804827}
     
    12661289
    12671290    // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to
    1268     if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged))
     1291    if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged | BackdropFiltersChanged))
    12691292        updateStructuralLayer();
    12701293
     
    13141337    if (m_uncommittedChanges & FiltersChanged)
    13151338        updateFilters();
     1339
     1340    if (m_uncommittedChanges & BackdropFiltersChanged)
     1341        updateBackdropFilters();
    13161342
    13171343#if ENABLE(CSS_COMPOSITING)
     
    14011427        m_structuralLayer->setName("Replica flattening layer " + name());
    14021428        break;
     1429    case StructuralLayerForBackdrop:
     1430        m_structuralLayer->setName("Backdrop hosting layer " + name());
     1431        break;
    14031432    case NoStructuralLayer:
    14041433        break;
     
    14251454
    14261455    if (m_structuralLayer) {
     1456        if (m_backdropLayer)
     1457            structuralLayerChildren.append(m_backdropLayer);
     1458
    14271459        if (m_replicaLayer)
    14281460            structuralLayerChildren.append(downcast<GraphicsLayerCA>(*m_replicaLayer).primaryLayer());
     
    15101542    m_layer->setBounds(adjustedBounds);
    15111543    m_layer->setAnchorPoint(scaledAnchorPoint);
     1544
     1545    if (m_backdropLayer) {
     1546        m_backdropLayer->setPosition(adjustedPosition);
     1547        m_backdropLayer->setBounds(adjustedBounds);
     1548        m_backdropLayer->setAnchorPoint(scaledAnchorPoint);
     1549    }
    15121550
    15131551    if (LayerMap* layerCloneMap = m_layerClones.get()) {
     
    16411679}
    16421680
     1681void GraphicsLayerCA::updateBackdropFilters()
     1682{
     1683    if (m_backdropFilters.isEmpty()) {
     1684        if (m_backdropLayer) {
     1685            m_backdropLayer->removeFromSuperlayer();
     1686            m_backdropLayer->setOwner(nullptr);
     1687            m_backdropLayer = nullptr;
     1688        }
     1689        return;
     1690    }
     1691
     1692    if (!m_backdropLayer) {
     1693        m_backdropLayer = createPlatformCALayer(PlatformCALayer::LayerTypeBackdropLayer, this);
     1694        m_backdropLayer->setPosition(m_layer->position());
     1695        m_backdropLayer->setBounds(m_layer->bounds());
     1696        m_backdropLayer->setAnchorPoint(m_layer->anchorPoint());
     1697        m_backdropLayer->setMasksToBounds(true);
     1698    }
     1699    m_backdropLayer->setFilters(m_backdropFilters);
     1700}
     1701
    16431702#if ENABLE(CSS_COMPOSITING)
    16441703void GraphicsLayerCA::updateBlendMode()
     
    16711730        | BackfaceVisibilityChanged
    16721731        | FiltersChanged
     1732        | BackdropFiltersChanged
    16731733        | OpacityChanged;
    16741734
     
    16861746
    16871747            // Release the structural layer.
    1688             m_structuralLayer = 0;
     1748            m_structuralLayer = nullptr;
    16891749
    16901750            m_uncommittedChanges |= structuralLayerChangeFlags;
     
    17501810    if (isReplicated())
    17511811        return StructuralLayerForReplicaFlattening;
    1752    
     1812
     1813    if (needsBackdrop())
     1814        return StructuralLayerForBackdrop;
     1815
    17531816    return NoStructuralLayer;
    17541817}
     
    22632326{
    22642327    ASSERT(valueList.property() != AnimatedPropertyWebkitTransform && (!supportsAcceleratedFilterAnimations() || valueList.property() != AnimatedPropertyWebkitFilter));
    2265    
     2328
    22662329    bool isKeyframe = valueList.size() > 2;
    22672330    bool valuesOK;
     
    30003063        | AcceleratesDrawingChanged
    30013064        | FiltersChanged
     3065        | BackdropFiltersChanged
    30023066        | MaskLayerChanged
    30033067        | OpacityChanged
  • trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h

    r175687 r175716  
    106106    virtual bool filtersCanBeComposited(const FilterOperations&);
    107107
     108    WEBCORE_EXPORT virtual bool setBackdropFilters(const FilterOperations&) override;
     109
    108110#if ENABLE(CSS_COMPOSITING)
    109111    WEBCORE_EXPORT virtual void setBlendMode(BlendMode) override;
     
    203205    void updateOpacityOnLayer();
    204206    void updateFilters();
     207    void updateBackdropFilters();
    205208
    206209#if ENABLE(CSS_COMPOSITING)
     
    384387        NoStructuralLayer = 0,
    385388        StructuralLayerForPreserves3D,
    386         StructuralLayerForReplicaFlattening
     389        StructuralLayerForReplicaFlattening,
     390        StructuralLayerForBackdrop
    387391    };
    388392    void ensureStructuralLayer(StructuralLayerPurpose);
     
    428432        VisibleRectChanged = 1LLU << 25,
    429433        FiltersChanged = 1LLU << 26,
    430         TilingAreaChanged = 1LLU << 27,
    431         TilesAdded = 1LLU < 28,
    432         DebugIndicatorsChanged = 1LLU << 29,
    433         CustomAppearanceChanged = 1LLU << 30,
    434         CustomBehaviorChanged = 1LLU << 31,
    435         BlendModeChanged = 1LLU << 32
     434        BackdropFiltersChanged = 1LLU << 27,
     435        TilingAreaChanged = 1LLU << 28,
     436        TilesAdded = 1LLU < 29,
     437        DebugIndicatorsChanged = 1LLU << 30,
     438        CustomAppearanceChanged = 1LLU << 31,
     439        CustomBehaviorChanged = 1LLU << 32,
     440        BlendModeChanged = 1LLU << 33
    436441    };
    437442    typedef uint64_t LayerChangeFlags;
     
    447452    RefPtr<PlatformCALayer> m_contentsClippingLayer; // A layer used to clip inner content
    448453    RefPtr<PlatformCALayer> m_contentsLayer; // A layer used for inner content, like image and video
     454    RefPtr<PlatformCALayer> m_backdropLayer; // The layer used for backdrop rendering, if necessary.
    449455
    450456    // References to clones of our layers, for replicated layers.
  • trunk/Source/WebCore/platform/graphics/ca/PlatformCALayer.h

    r175687 r175716  
    7878        LayerTypeAVPlayerLayer,
    7979        LayerTypeWebGLLayer,
     80        LayerTypeBackdropLayer,
    8081        LayerTypeCustom
    8182    };
  • trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm

    r175687 r175716  
    6363#endif
    6464
     65#if ENABLE(FILTERS_LEVEL_2)
     66@interface CABackdropLayer : CALayer
     67@end
     68#endif
    6569
    6670SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
     
    233237    case LayerTypeTransformLayer:
    234238        layerClass = [CATransformLayer class];
     239        break;
     240    case LayerTypeBackdropLayer:
     241#if ENABLE(FILTERS_LEVEL_2)
     242        layerClass = [CABackdropLayer class];
     243#else
     244        ASSERT_NOT_REACHED();
     245        layerClass = [CALayer class];
     246#endif
    235247        break;
    236248    case LayerTypeWebTiledLayer:
  • trunk/Source/WebCore/rendering/RenderElement.h

    r175687 r175716  
    123123
    124124    // Returns true if this renderer requires a new stacking context.
    125     bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBlendMode(); }
     125    bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBackdropFilter() || hasBlendMode(); }
    126126
    127127    bool isTransparent() const { return style().opacity() < 1.0f; }
     
    138138
    139139    bool hasFilter() const { return style().hasFilter(); }
     140    bool hasBackdropFilter() const
     141    {
     142#if ENABLE(FILTERS_LEVEL_2)
     143        return style().hasBackdropFilter();
     144#else
     145        return false;
     146#endif
     147    }
    140148
    141149#if ENABLE(CSS_COMPOSITING)
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r175687 r175716  
    316316bool RenderLayer::paintsWithFilters() const
    317317{
    318     // FIXME: Eventually there will be cases where we paint with filters even without accelerated compositing,
    319     // and this whole function won't be inside the #if below.
    320 
    321318    if (!renderer().hasFilter())
    322319        return false;
     
    62196216        && !renderer().hasClipPath()
    62206217        && !renderer().hasFilter()
     6218        && !renderer().hasBackdropFilter()
    62216219#if PLATFORM(IOS)
    62226220        && !hasAcceleratedTouchScrolling()
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r175687 r175716  
    792792    void filterNeedsRepaint();
    793793    bool hasFilter() const { return renderer().hasFilter(); }
     794    bool hasBackdropFilter() const
     795    {
     796#if ENABLE(FILTERS_LEVEL_2)
     797        return renderer().hasBackdropFilter();
     798#else
     799        return false;
     800#endif
     801    }
    794802
    795803#if ENABLE(CSS_COMPOSITING)
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r175687 r175716  
    113113    , m_requiresOwnBackingStore(true)
    114114    , m_canCompositeFilters(false)
     115#if ENABLE(FILTERS_LEVEL_2)
     116    , m_canCompositeBackdropFilters(false)
     117#endif
    115118    , m_backgroundLayerPaintsFixedRootBackground(false)
    116119{
     
    312315    updateTransform(renderer().style());
    313316    updateFilters(renderer().style());
     317#if ENABLE(FILTERS_LEVEL_2)
     318    updateBackdropFilters(renderer().style());
     319#endif
    314320#if ENABLE(CSS_COMPOSITING)
    315321    updateBlendMode(renderer().style());
     
    375381    m_canCompositeFilters = m_graphicsLayer->setFilters(style.filter());
    376382}
     383
     384#if ENABLE(FILTERS_LEVEL_2)
     385void RenderLayerBacking::updateBackdropFilters(const RenderStyle& style)
     386{
     387    m_canCompositeBackdropFilters = m_graphicsLayer->setBackdropFilters(style.backdropFilter());
     388}
     389#endif
    377390
    378391#if ENABLE(CSS_COMPOSITING)
     
    653666
    654667    updateFilters(style);
    655 
     668#if ENABLE(FILTERS_LEVEL_2)
     669    updateBackdropFilters(style);
     670#endif
    656671#if ENABLE(CSS_COMPOSITING)
    657672    updateBlendMode(style);
  • trunk/Source/WebCore/rendering/RenderLayerBacking.h

    r175687 r175716  
    233233
    234234    bool canCompositeFilters() const { return m_canCompositeFilters; }
     235#if ENABLE(FILTERS_LEVEL_2)
     236    bool canCompositeBackdropFilters() const { return m_canCompositeBackdropFilters; }
     237#endif
    235238
    236239    // Return an estimate of the backing store area (in pixels) allocated by this object's GraphicsLayers.
     
    280283    void updateTransform(const RenderStyle&);
    281284    void updateFilters(const RenderStyle&);
     285#if ENABLE(FILTERS_LEVEL_2)
     286    void updateBackdropFilters(const RenderStyle&);
     287#endif
    282288#if ENABLE(CSS_COMPOSITING)
    283289    void updateBlendMode(const RenderStyle&);
     
    349355    bool m_requiresOwnBackingStore;
    350356    bool m_canCompositeFilters;
     357#if ENABLE(FILTERS_LEVEL_2)
     358    bool m_canCompositeBackdropFilters;
     359#endif
    351360    bool m_backgroundLayerPaintsFixedRootBackground;
    352361
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r175687 r175716  
    21812181        || renderer.hasReflection()
    21822182        || renderer.hasFilter()
     2183        || renderer.hasBackdropFilter()
    21832184#if PLATFORM(IOS)
    21842185        || requiresCompositingForScrolling(layer)
     
    21862187        )
    21872188        return true;
    2188        
    2189    
     2189
    21902190    if (layer.mustCompositeForIndirectReasons()) {
    21912191        RenderLayer::IndirectCompositingReason reason = layer.indirectCompositingReason();
     
    22742274            reasons |= CompositingReasonReflectionWithCompositedDescendants;
    22752275
    2276         if (renderer->hasFilter())
     2276        if (renderer->hasFilter() || renderer->hasBackdropFilter())
    22772277            reasons |= CompositingReasonFilterWithCompositedDescendants;
    22782278
     
    25952595bool RenderLayerCompositor::requiresCompositingForFilters(RenderLayerModelObject& renderer) const
    25962596{
     2597#if ENABLE(FILTERS_LEVEL_2)
     2598    if (renderer.hasBackdropFilter())
     2599        return true;
     2600#endif
     2601
    25972602    if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
    25982603        return false;
  • trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp

    r175687 r175716  
    115115                    )
    116116                layer()->repaintIncludingDescendants();
    117             } else if (newStyle.hasTransform() || newStyle.opacity() < 1 || newStyle.hasFilter()) {
     117            } else if (newStyle.hasTransform() || newStyle.opacity() < 1 || newStyle.hasFilter() || newStyle.hasBackdropFilter()) {
    118118                // If we don't have a layer yet, but we are going to get one because of transform or opacity,
    119119                //  then we need to repaint the old position of the object.
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r175687 r175716  
    639639        return true;
    640640
     641#if ENABLE(FILTERS_LEVEL_2)
     642    if (rareNonInheritedData->hasBackdropFilters() != other.rareNonInheritedData->hasBackdropFilters())
     643        return true;
     644#endif
     645
    641646    const QuotesData* quotesDataA = rareInheritedData->quotes.get();
    642647    const QuotesData* quotesDataB = other.rareInheritedData->quotes.get();
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r175687 r175716  
    11171117    const FilterOperations& filter() const { return rareNonInheritedData->m_filter->m_operations; }
    11181118    bool hasFilter() const { return !rareNonInheritedData->m_filter->m_operations.operations().isEmpty(); }
     1119
     1120#if ENABLE(FILTERS_LEVEL_2)
     1121    FilterOperations& mutableBackdropFilter() { return rareNonInheritedData.access()->m_backdropFilter.access()->m_operations; }
     1122    const FilterOperations& backdropFilter() const { return rareNonInheritedData->m_backdropFilter->m_operations; }
     1123    bool hasBackdropFilter() const { return !rareNonInheritedData->m_backdropFilter->m_operations.operations().isEmpty(); }
     1124#else
     1125    bool hasBackdropFilter() const { return false; }
     1126#endif
    11191127
    11201128#if ENABLE(CSS_COMPOSITING)
     
    15481556
    15491557    void setFilter(const FilterOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_filter, m_operations, ops); }
     1558#if ENABLE(FILTERS_LEVEL_2)
     1559    void setBackdropFilter(const FilterOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_backdropFilter, m_operations, ops); }
     1560#endif
    15501561
    15511562    void setTabSize(unsigned size) { SET_VAR(rareInheritedData, m_tabSize, size); }
     
    19962007#endif
    19972008    static const FilterOperations& initialFilter() { DEPRECATED_DEFINE_STATIC_LOCAL(FilterOperations, ops, ()); return ops; }
     2009#if ENABLE(FILTERS_LEVEL_2)
     2010    static const FilterOperations& initialBackdropFilter() { DEPRECATED_DEFINE_STATIC_LOCAL(FilterOperations, ops, ()); return ops; }
     2011#endif
    19982012#if ENABLE(CSS_COMPOSITING)
    19992013    static BlendMode initialBlendMode() { return BlendModeNormal; }
  • trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp

    r175687 r175716  
    5050    , m_transform(StyleTransformData::create())
    5151    , m_filter(StyleFilterData::create())
     52#if ENABLE(FILTERS_LEVEL_2)
     53    , m_backdropFilter(StyleFilterData::create())
     54#endif
    5255#if ENABLE(CSS_GRID_LAYOUT)
    5356    , m_grid(StyleGridData::create())
     
    120123    , m_transform(o.m_transform)
    121124    , m_filter(o.m_filter)
     125#if ENABLE(FILTERS_LEVEL_2)
     126    , m_backdropFilter(o.m_backdropFilter)
     127#endif
    122128#if ENABLE(CSS_GRID_LAYOUT)
    123129    , m_grid(o.m_grid)
     
    215221        && m_transform == o.m_transform
    216222        && m_filter == o.m_filter
     223#if ENABLE(FILTERS_LEVEL_2)
     224        && m_backdropFilter == o.m_backdropFilter
     225#endif
    217226#if ENABLE(CSS_GRID_LAYOUT)
    218227        && m_grid == o.m_grid
     
    347356}
    348357
     358#if ENABLE(FILTERS_LEVEL_2)
     359bool StyleRareNonInheritedData::hasBackdropFilters() const
     360{
     361    return m_backdropFilter.get() && !m_backdropFilter->m_operations.isEmpty();
     362}
     363#endif
     364
    349365} // namespace WebCore
  • trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.h

    r175687 r175716  
    9595    bool transitionDataEquivalent(const StyleRareNonInheritedData&) const;
    9696    bool hasFilters() const;
     97#if ENABLE(FILTERS_LEVEL_2)
     98    bool hasBackdropFilters() const;
     99#endif
    97100    bool hasOpacity() const { return opacity < 1; }
    98101
     
    120123    DataRef<StyleTransformData> m_transform; // Transform properties (rotate, scale, skew, etc.)
    121124    DataRef<StyleFilterData> m_filter; // Filter operations (url, sepia, blur, etc.)
     125#if ENABLE(FILTERS_LEVEL_2)
     126    DataRef<StyleFilterData> m_backdropFilter; // Filter operations (url, sepia, blur, etc.)
     127#endif
    122128
    123129#if ENABLE(CSS_GRID_LAYOUT)
  • trunk/Source/WebKit2/ChangeLog

    r175711 r175716  
     12014-11-06  Dean Jackson  <dino@apple.com>
     2
     3        [filters2] Support for backdrop-filter
     4        https://bugs.webkit.org/show_bug.cgi?id=138384
     5        <rdar://problem/18874494>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Take 2!! Previous patch was rolled out.
     10
     11        * Shared/mac/RemoteLayerBackingStore.mm:
     12        (WebKit::RemoteLayerBackingStore::drawInContext): Handle LayerTypeBackdropLayer in the switch.
     13        * Shared/mac/RemoteLayerTreeTransaction.mm:
     14        (WebKit::RemoteLayerTreeTransaction::description): Describe a backdrop layer.
     15        * UIProcess/ios/RemoteLayerTreeHostIOS.mm:
     16        (+[WKBackdropView layerClass]): Define CABackdropLayer and use it as the class.
     17        (WebKit::RemoteLayerTreeHost::createLayer):
     18        * UIProcess/mac/RemoteLayerTreeHost.mm: Ditto.
     19        (WebKit::RemoteLayerTreeHost::createLayer):
     20
    1212014-11-06  Tim Horton  <timothy_horton@apple.com>
    222
  • trunk/Source/WebKit2/Shared/mac/RemoteLayerBackingStore.mm

    r175687 r175716  
    349349    case PlatformCALayer::LayerTypeAVPlayerLayer:
    350350    case PlatformCALayer::LayerTypeWebGLLayer:
     351    case PlatformCALayer::LayerTypeBackdropLayer:
    351352    case PlatformCALayer::LayerTypeCustom:
    352353        ASSERT_NOT_REACHED();
  • trunk/Source/WebKit2/Shared/mac/RemoteLayerTreeTransaction.mm

    r175687 r175716  
    11811181                ts << "root-layer";
    11821182                break;
     1183            case PlatformCALayer::LayerTypeBackdropLayer:
     1184                ts << "backdrop-layer";
     1185                break;
    11831186            case PlatformCALayer::LayerTypeAVPlayerLayer:
    11841187                ts << "av-player-layer (context-id " << createdLayer.hostingContextID << ")";
  • trunk/Source/WebKit2/UIProcess/ios/RemoteLayerTreeHostIOS.mm

    r175687 r175716  
    3737@interface CALayer(WKLayerInternal)
    3838- (void)setContextId:(uint32_t)contextID;
     39@end
     40
     41@interface CABackdropLayer : CALayer
    3942@end
    4043
     
    105108@end
    106109
     110@interface WKBackdropView : WKCompositingView
     111@end
     112
     113@implementation WKBackdropView
     114+ (Class)layerClass
     115{
     116    return [CABackdropLayer self];
     117}
     118
     119@end
     120
    107121@interface WKRemoteView : WKCompositingView
    108122@end
     
    152166            view = adoptNS([[WKCompositingView alloc] init]);
    153167        break;
     168    case PlatformCALayer::LayerTypeBackdropLayer:
     169        view = adoptNS([[WKBackdropView alloc] init]);
     170        break;
    154171    case PlatformCALayer::LayerTypeTransformLayer:
    155172        view = adoptNS([[WKTransformView alloc] init]);
  • trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeHost.mm

    r175687 r175716  
    4242#endif
    4343
     44#if ENABLE(FILTERS_LEVEL_2)
     45@interface CABackdropLayer : CALayer
     46@end
     47#endif
     48
    4449using namespace WebCore;
    4550
     
    223228        layer = adoptNS([[CATransformLayer alloc] init]);
    224229        break;
     230    case PlatformCALayer::LayerTypeBackdropLayer:
     231#if ENABLE(FILTERS_LEVEL_2)
     232        layer = adoptNS([[CABackdropLayer alloc] init]);
     233#else
     234        ASSERT_NOT_REACHED();
     235        layer = adoptNS([[CALayer alloc] init]);
     236#endif
     237        break;
    225238    case PlatformCALayer::LayerTypeCustom:
    226239    case PlatformCALayer::LayerTypeAVPlayerLayer:
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h

    r175687 r175716  
    230230            ThreeDTransformTrigger |
    231231            VideoTrigger |
    232             PluginTrigger| 
     232            PluginTrigger|
    233233            CanvasTrigger |
    234234#if PLATFORM(IOS)
Note: See TracChangeset for help on using the changeset viewer.