OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 private: | 179 private: |
180 Vector<OverlapMapContainer> m_overlapStack; | 180 Vector<OverlapMapContainer> m_overlapStack; |
181 HashSet<const RenderLayer*> m_layers; | 181 HashSet<const RenderLayer*> m_layers; |
182 RenderGeometryMap m_geometryMap; | 182 RenderGeometryMap m_geometryMap; |
183 }; | 183 }; |
184 | 184 |
185 struct CompositingRecursionData { | 185 struct CompositingRecursionData { |
186 CompositingRecursionData(RenderLayer* compAncestor, bool testOverlap) | 186 CompositingRecursionData(RenderLayer* compAncestor, bool testOverlap) |
187 : m_compositingAncestor(compAncestor) | 187 : m_compositingAncestor(compAncestor) |
188 , m_subtreeIsCompositing(false) | 188 , m_subtreeIsCompositing(false) |
| 189 , m_hasCompositedBlendingDescendants(false) |
189 , m_testingOverlap(testOverlap) | 190 , m_testingOverlap(testOverlap) |
190 #ifndef NDEBUG | 191 #ifndef NDEBUG |
191 , m_depth(0) | 192 , m_depth(0) |
192 #endif | 193 #endif |
193 { | 194 { |
194 } | 195 } |
195 | 196 |
196 CompositingRecursionData(const CompositingRecursionData& other) | 197 CompositingRecursionData(const CompositingRecursionData& other) |
197 : m_compositingAncestor(other.m_compositingAncestor) | 198 : m_compositingAncestor(other.m_compositingAncestor) |
198 , m_subtreeIsCompositing(other.m_subtreeIsCompositing) | 199 , m_subtreeIsCompositing(other.m_subtreeIsCompositing) |
| 200 , m_hasCompositedBlendingDescendants(other.m_hasCompositedBlendingDescen
dants) |
199 , m_testingOverlap(other.m_testingOverlap) | 201 , m_testingOverlap(other.m_testingOverlap) |
200 #ifndef NDEBUG | 202 #ifndef NDEBUG |
201 , m_depth(other.m_depth + 1) | 203 , m_depth(other.m_depth + 1) |
202 #endif | 204 #endif |
203 { | 205 { |
204 } | 206 } |
205 | 207 |
206 RenderLayer* m_compositingAncestor; | 208 RenderLayer* m_compositingAncestor; |
207 bool m_subtreeIsCompositing; | 209 bool m_subtreeIsCompositing; |
| 210 bool m_hasCompositedBlendingDescendants; |
208 bool m_testingOverlap; | 211 bool m_testingOverlap; |
209 #ifndef NDEBUG | 212 #ifndef NDEBUG |
210 int m_depth; | 213 int m_depth; |
211 #endif | 214 #endif |
212 }; | 215 }; |
213 | 216 |
214 | 217 |
215 static inline bool compositingLogEnabled() | 218 static inline bool compositingLogEnabled() |
216 { | 219 { |
217 #if !LOG_DISABLED | 220 #if !LOG_DISABLED |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 if (inCompositingMode() && m_hasAcceleratedCompositing) | 945 if (inCompositingMode() && m_hasAcceleratedCompositing) |
943 willBeComposited = true; | 946 willBeComposited = true; |
944 } | 947 } |
945 | 948 |
946 // All layers (even ones that aren't being composited) need to get added to | 949 // All layers (even ones that aren't being composited) need to get added to |
947 // the overlap map. Layers that are not separately composited will paint int
o their | 950 // the overlap map. Layers that are not separately composited will paint int
o their |
948 // compositing ancestor's backing, and so are still considered for overlap. | 951 // compositing ancestor's backing, and so are still considered for overlap. |
949 if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursio
nData.m_compositingAncestor->isRootLayer()) | 952 if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursio
nData.m_compositingAncestor->isRootLayer()) |
950 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); | 953 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); |
951 | 954 |
| 955 // According to http://dev.w3.org/fxtf/compositing-1/#csscompositingrules_CS
S, |
| 956 // an element that has blending applied must blend with all the underlying |
| 957 // content of the stacking context [CSS21] that element belongs to. |
| 958 // We should isolate the stacking contexts containing accelerated blending d
escendants |
| 959 layer->setHasCompositedBlendingDescendants(childRecursionData.m_hasComposite
dBlendingDescendants); |
| 960 |
| 961 if (layer->hasCompositedBlendingDescendants() && !layer->stackingNode()->isS
tackingContext()) |
| 962 currentRecursionData.m_hasCompositedBlendingDescendants = true; |
| 963 |
952 // Now check for reasons to become composited that depend on the state of de
scendant layers. | 964 // Now check for reasons to become composited that depend on the state of de
scendant layers. |
953 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(
layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3D
Transform); | 965 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(
layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3D
Transform); |
954 reasonsToComposite |= subtreeCompositingReasons; | 966 reasonsToComposite |= subtreeCompositingReasons; |
955 if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtr
eeCompositingReasons)) { | 967 if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtr
eeCompositingReasons)) { |
956 childRecursionData.m_compositingAncestor = layer; | 968 childRecursionData.m_compositingAncestor = layer; |
957 if (overlapMap) { | 969 if (overlapMap) { |
958 // FIXME: this context push is effectively a no-op but needs to exis
t for | 970 // FIXME: this context push is effectively a no-op but needs to exis
t for |
959 // now, because the code is designed to push overlap information to
the | 971 // now, because the code is designed to push overlap information to
the |
960 // second-from-top context of the stack. | 972 // second-from-top context of the stack. |
961 overlapMap->beginNewOverlapTestingContext(); | 973 overlapMap->beginNewOverlapTestingContext(); |
962 addToOverlapMapRecursive(*overlapMap, layer); | 974 addToOverlapMapRecursive(*overlapMap, layer); |
963 } | 975 } |
964 willBeComposited = true; | 976 willBeComposited = true; |
965 } | 977 } |
966 | 978 |
967 // If the original layer is composited, the reflection needs to be, too. | 979 // If the original layer is composited, the reflection needs to be, too. |
968 if (layer->reflectionInfo()) { | 980 if (layer->reflectionInfo()) { |
969 // FIXME: Shouldn't we call computeCompositingRequirements to handle a r
eflection overlapping with another renderer? | 981 // FIXME: Shouldn't we call computeCompositingRequirements to handle a r
eflection overlapping with another renderer? |
970 CompositingReasons reflectionCompositingReason = willBeComposited ? Comp
ositingReasonReflectionOfCompositedParent : CompositingReasonNone; | 982 CompositingReasons reflectionCompositingReason = willBeComposited ? Comp
ositingReasonReflectionOfCompositedParent : CompositingReasonNone; |
971 layer->reflectionInfo()->reflectionLayer()->setCompositingReasons(layer-
>reflectionInfo()->reflectionLayer()->compositingReasons() | reflectionCompositi
ngReason); | 983 layer->reflectionInfo()->reflectionLayer()->setCompositingReasons(layer-
>reflectionInfo()->reflectionLayer()->compositingReasons() | reflectionCompositi
ngReason); |
972 } | 984 } |
973 | 985 |
974 // Subsequent layers in the parent's stacking context may also need to compo
site. | 986 // Subsequent layers in the parent's stacking context may also need to compo
site. |
975 if (childRecursionData.m_subtreeIsCompositing) | 987 if (childRecursionData.m_subtreeIsCompositing) |
976 currentRecursionData.m_subtreeIsCompositing = true; | 988 currentRecursionData.m_subtreeIsCompositing = true; |
977 | 989 |
| 990 if (willBeComposited && layer->hasBlendMode()) |
| 991 currentRecursionData.m_hasCompositedBlendingDescendants = true; |
| 992 |
978 // Set the flag to say that this SC has compositing children. | 993 // Set the flag to say that this SC has compositing children. |
979 layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing
); | 994 layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing
); |
980 | 995 |
981 // Turn overlap testing off for later layers if it's already off, or if we h
ave an animating transform. | 996 // Turn overlap testing off for later layers if it's already off, or if we h
ave an animating transform. |
982 // Note that if the layer clips its descendants, there's no reason to propag
ate the child animation to the parent layers. That's because | 997 // Note that if the layer clips its descendants, there's no reason to propag
ate the child animation to the parent layers. That's because |
983 // we know for sure the animation is contained inside the clipping rectangle
, which is already added to the overlap map. | 998 // we know for sure the animation is contained inside the clipping rectangle
, which is already added to the overlap map. |
984 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposi
te & CompositingReasonClipsCompositingDescendants); | 999 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposi
te & CompositingReasonClipsCompositingDescendants); |
985 if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) ||
isRunningAcceleratedTransformAnimation(layer->renderer())) | 1000 if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) ||
isRunningAcceleratedTransformAnimation(layer->renderer())) |
986 currentRecursionData.m_testingOverlap = false; | 1001 currentRecursionData.m_testingOverlap = false; |
987 | 1002 |
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 return true; | 1562 return true; |
1548 | 1563 |
1549 CompositingReasons indirectReasonsThatNeedBacking = CompositingReasonOverlap | 1564 CompositingReasons indirectReasonsThatNeedBacking = CompositingReasonOverlap |
1550 | CompositingReasonAssumedOverlap | 1565 | CompositingReasonAssumedOverlap |
1551 | CompositingReasonNegativeZIndexChildren | 1566 | CompositingReasonNegativeZIndexChildren |
1552 | CompositingReasonTransformWithCompositedDescendants | 1567 | CompositingReasonTransformWithCompositedDescendants |
1553 | CompositingReasonOpacityWithCompositedDescendants | 1568 | CompositingReasonOpacityWithCompositedDescendants |
1554 | CompositingReasonMaskWithCompositedDescendants | 1569 | CompositingReasonMaskWithCompositedDescendants |
1555 | CompositingReasonFilterWithCompositedDescendants | 1570 | CompositingReasonFilterWithCompositedDescendants |
1556 | CompositingReasonBlendingWithCompositedDescendants | 1571 | CompositingReasonBlendingWithCompositedDescendants |
| 1572 | CompositingReasonIsolateCompositedDescendants |
1557 | CompositingReasonPreserve3D; // preserve-3d has to create backing stor
e to ensure that 3d-transformed elements intersect. | 1573 | CompositingReasonPreserve3D; // preserve-3d has to create backing stor
e to ensure that 3d-transformed elements intersect. |
1558 return layer->compositingReasons() & indirectReasonsThatNeedBacking; | 1574 return layer->compositingReasons() & indirectReasonsThatNeedBacking; |
1559 } | 1575 } |
1560 | 1576 |
1561 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const Rend
erLayer* layer) const | 1577 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const Rend
erLayer* layer) const |
1562 { | 1578 { |
1563 RenderObject* renderer = layer->renderer(); | 1579 RenderObject* renderer = layer->renderer(); |
1564 CompositingReasons directReasons = CompositingReasonNone; | 1580 CompositingReasons directReasons = CompositingReasonNone; |
1565 | 1581 |
1566 if (requiresCompositingForTransform(renderer)) | 1582 if (requiresCompositingForTransform(renderer)) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 | 1696 |
1681 if (reasons & CompositingReasonPerspective) | 1697 if (reasons & CompositingReasonPerspective) |
1682 return "perspective"; | 1698 return "perspective"; |
1683 | 1699 |
1684 if (reasons & CompositingReasonPreserve3D) | 1700 if (reasons & CompositingReasonPreserve3D) |
1685 return "preserve-3d"; | 1701 return "preserve-3d"; |
1686 | 1702 |
1687 if (reasons & CompositingReasonRoot) | 1703 if (reasons & CompositingReasonRoot) |
1688 return "root"; | 1704 return "root"; |
1689 | 1705 |
| 1706 if (reasons & CompositingReasonIsolateCompositedDescendants) |
| 1707 return "isolate composited descendants"; |
| 1708 |
1690 return ""; | 1709 return ""; |
1691 } | 1710 } |
1692 #endif | 1711 #endif |
1693 | 1712 |
1694 // Return true if the given layer has some ancestor in the RenderLayer hierarchy
that clips, | 1713 // Return true if the given layer has some ancestor in the RenderLayer hierarchy
that clips, |
1695 // up to the enclosing compositing ancestor. This is required because compositin
g layers are parented | 1714 // up to the enclosing compositing ancestor. This is required because compositin
g layers are parented |
1696 // according to the z-order hierarchy, yet clipping goes down the renderer hiera
rchy. | 1715 // according to the z-order hierarchy, yet clipping goes down the renderer hiera
rchy. |
1697 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in th
e renderer hierarchy, | 1716 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in th
e renderer hierarchy, |
1698 // but a sibling in the z-order hierarchy. | 1717 // but a sibling in the z-order hierarchy. |
1699 bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const | 1718 bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 CompositingReasons subtreeReasons = CompositingReasonNone; | 1893 CompositingReasons subtreeReasons = CompositingReasonNone; |
1875 | 1894 |
1876 // FIXME: this seems to be a potentially different layer than the layer for
which this was called. May not be an error, but is very confusing. | 1895 // FIXME: this seems to be a potentially different layer than the layer for
which this was called. May not be an error, but is very confusing. |
1877 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); | 1896 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); |
1878 | 1897 |
1879 // When a layer has composited descendants, some effects, like 2d transforms
, filters, masks etc must be implemented | 1898 // When a layer has composited descendants, some effects, like 2d transforms
, filters, masks etc must be implemented |
1880 // via compositing so that they also apply to those composited descdendants. | 1899 // via compositing so that they also apply to those composited descdendants. |
1881 if (hasCompositedDescendants) { | 1900 if (hasCompositedDescendants) { |
1882 if (layer->transform()) | 1901 if (layer->transform()) |
1883 subtreeReasons |= CompositingReasonTransformWithCompositedDescendant
s; | 1902 subtreeReasons |= CompositingReasonTransformWithCompositedDescendant
s; |
| 1903 if (layer->hasCompositedBlendingDescendants() && layer->stackingNode()->
isStackingContext()) |
| 1904 subtreeReasons |= CompositingReasonIsolateCompositedDescendants; |
1884 | 1905 |
1885 // If the implementation of createsGroup changes, we need to be aware of
that in this part of code. | 1906 // If the implementation of createsGroup changes, we need to be aware of
that in this part of code. |
1886 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->ha
sFilter() || renderer->hasBlendMode()) == renderer->createsGroup()); | 1907 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->ha
sFilter() || renderer->hasBlendMode()) == renderer->createsGroup()); |
1887 if (renderer->isTransparent()) | 1908 if (renderer->isTransparent()) |
1888 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants; | 1909 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants; |
1889 if (renderer->hasMask()) | 1910 if (renderer->hasMask()) |
1890 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants; | 1911 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants; |
1891 if (renderer->hasFilter()) | 1912 if (renderer->hasFilter()) |
1892 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants; | 1913 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants; |
1893 if (renderer->hasBlendMode()) | 1914 if (renderer->hasBlendMode()) |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 } else if (graphicsLayer == m_scrollLayer.get()) { | 2633 } else if (graphicsLayer == m_scrollLayer.get()) { |
2613 name = "Frame Scrolling Layer"; | 2634 name = "Frame Scrolling Layer"; |
2614 } else { | 2635 } else { |
2615 ASSERT_NOT_REACHED(); | 2636 ASSERT_NOT_REACHED(); |
2616 } | 2637 } |
2617 | 2638 |
2618 return name; | 2639 return name; |
2619 } | 2640 } |
2620 | 2641 |
2621 } // namespace WebCore | 2642 } // namespace WebCore |
OLD | NEW |