Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(861)

Side by Side Diff: Source/core/rendering/RenderLayerCompositor.cpp

Issue 23511004: mix-blend-mode implementation for accelerated layers - blink part (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added layout test & addressed review comments Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 private: 173 private:
174 Vector<OverlapMapContainer> m_overlapStack; 174 Vector<OverlapMapContainer> m_overlapStack;
175 HashSet<const RenderLayer*> m_layers; 175 HashSet<const RenderLayer*> m_layers;
176 RenderGeometryMap m_geometryMap; 176 RenderGeometryMap m_geometryMap;
177 }; 177 };
178 178
179 struct CompositingState { 179 struct CompositingState {
180 CompositingState(RenderLayer* compAncestor, bool testOverlap) 180 CompositingState(RenderLayer* compAncestor, bool testOverlap)
181 : m_compositingAncestor(compAncestor) 181 : m_compositingAncestor(compAncestor)
182 , m_subtreeIsCompositing(false) 182 , m_subtreeIsCompositing(false)
183 , m_hasCompositedBlendingDescendents(false)
shawnsingh 2013/09/13 10:22:59 Let's spell it "Descendants" instead... that way t
rosca 2013/09/19 14:26:54 Done.
183 , m_testingOverlap(testOverlap) 184 , m_testingOverlap(testOverlap)
184 #ifndef NDEBUG 185 #ifndef NDEBUG
185 , m_depth(0) 186 , m_depth(0)
186 #endif 187 #endif
187 { 188 {
188 } 189 }
189 190
190 CompositingState(const CompositingState& other) 191 CompositingState(const CompositingState& other)
191 : m_compositingAncestor(other.m_compositingAncestor) 192 : m_compositingAncestor(other.m_compositingAncestor)
192 , m_subtreeIsCompositing(other.m_subtreeIsCompositing) 193 , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
194 , m_hasCompositedBlendingDescendents(other.m_hasCompositedBlendingDescen dents)
193 , m_testingOverlap(other.m_testingOverlap) 195 , m_testingOverlap(other.m_testingOverlap)
194 #ifndef NDEBUG 196 #ifndef NDEBUG
195 , m_depth(other.m_depth + 1) 197 , m_depth(other.m_depth + 1)
196 #endif 198 #endif
197 { 199 {
198 } 200 }
199 201
200 RenderLayer* m_compositingAncestor; 202 RenderLayer* m_compositingAncestor;
201 bool m_subtreeIsCompositing; 203 bool m_subtreeIsCompositing;
204 bool m_hasCompositedBlendingDescendents;
202 bool m_testingOverlap; 205 bool m_testingOverlap;
203 #ifndef NDEBUG 206 #ifndef NDEBUG
204 int m_depth; 207 int m_depth;
205 #endif 208 #endif
206 }; 209 };
207 210
208 211
209 static inline bool compositingLogEnabled() 212 static inline bool compositingLogEnabled()
210 { 213 {
211 #if !LOG_DISABLED 214 #if !LOG_DISABLED
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 // 780 //
778 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor Layer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositing State, bool& layersChanged, bool& descendantHas3DTransform, Vector<RenderLayer*> & unclippedDescendants) 781 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor Layer, RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositing State, bool& layersChanged, bool& descendantHas3DTransform, Vector<RenderLayer*> & unclippedDescendants)
779 { 782 {
780 layer->updateLayerListsIfNeeded(); 783 layer->updateLayerListsIfNeeded();
781 784
782 if (overlapMap) 785 if (overlapMap)
783 overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer); 786 overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
784 787
785 // Clear the flag 788 // Clear the flag
786 layer->setHasCompositingDescendant(false); 789 layer->setHasCompositingDescendant(false);
790 layer->setShouldIsolateCompositedBlendingDescendants(false);
787 791
788 // Start by assuming this layer will not need to composite. 792 // Start by assuming this layer will not need to composite.
789 CompositingReasons reasonsToComposite = CompositingReasonNone; 793 CompositingReasons reasonsToComposite = CompositingReasonNone;
790 794
791 // First accumulate the straightforward compositing reasons. 795 // First accumulate the straightforward compositing reasons.
792 CompositingReasons directReasons = directReasonsForCompositing(layer); 796 CompositingReasons directReasons = directReasonsForCompositing(layer);
793 797
794 // Video is special. It's the only RenderLayer type that can both have 798 // Video is special. It's the only RenderLayer type that can both have
795 // RenderLayer children and whose children can't use its backing to render 799 // RenderLayer children and whose children can't use its backing to render
796 // into. These children (the controls) always need to be promoted into their 800 // into. These children (the controls) always need to be promoted into their
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 if (inCompositingMode() && m_hasAcceleratedCompositing) 940 if (inCompositingMode() && m_hasAcceleratedCompositing)
937 willBeComposited = true; 941 willBeComposited = true;
938 } 942 }
939 943
940 // All layers (even ones that aren't being composited) need to get added to 944 // All layers (even ones that aren't being composited) need to get added to
941 // the overlap map. Layers that do not composite will draw into their 945 // the overlap map. Layers that do not composite will draw into their
942 // compositing ancestor's backing, and so are still considered for overlap. 946 // compositing ancestor's backing, and so are still considered for overlap.
943 if (overlapMap && childState.m_compositingAncestor && !childState.m_composit ingAncestor->isRootLayer()) 947 if (overlapMap && childState.m_compositingAncestor && !childState.m_composit ingAncestor->isRootLayer())
944 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 948 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
945 949
950 // According to http://dev.w3.org/fxtf/compositing-1/#csscompositingrules_CS S,
951 // an element that has blending applied, must blend with all the underlying
shawnsingh 2013/09/13 10:22:59 nit - remove the comma after "applied"
rosca 2013/09/19 14:26:54 Done.
952 // content of the stacking context [CSS21] that element belongs to.
953 // We should isolate and accelerate the stacking contexts containing
954 // accelerated blending descendants
955 if (layer->isStackingContext())
shawnsingh 2013/09/13 10:22:59 OK - please bear with me =) (1) This part of the
rosca 2013/09/19 14:26:54 This part of the code should make sure that a stac
956 layer->setShouldIsolateCompositedBlendingDescendants(childState.m_hasCom positedBlendingDescendents);
957 else
958 compositingState.m_hasCompositedBlendingDescendents = childState.m_hasCo mpositedBlendingDescendents;
959
946 // Now check for reasons to become composited that depend on the state of de scendant layers. 960 // Now check for reasons to become composited that depend on the state of de scendant layers.
947 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing( layer->renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransfor m); 961 CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing( layer->renderer(), childState.m_subtreeIsCompositing, anyDescendantHas3DTransfor m);
948 reasonsToComposite |= subtreeCompositingReasons; 962 reasonsToComposite |= subtreeCompositingReasons;
949 if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtr eeCompositingReasons)) { 963 if (!willBeComposited && canBeComposited(layer) && requiresCompositing(subtr eeCompositingReasons)) {
950 childState.m_compositingAncestor = layer; 964 childState.m_compositingAncestor = layer;
951 if (overlapMap) { 965 if (overlapMap) {
952 // FIXME: this context push is effectively a no-op but needs to exis t for 966 // FIXME: this context push is effectively a no-op but needs to exis t for
953 // now, because the code is designed to push overlap information to the 967 // now, because the code is designed to push overlap information to the
954 // second-from-top context of the stack. 968 // second-from-top context of the stack.
955 overlapMap->beginNewOverlapTestingContext(); 969 overlapMap->beginNewOverlapTestingContext();
956 addToOverlapMapRecursive(*overlapMap, layer); 970 addToOverlapMapRecursive(*overlapMap, layer);
957 } 971 }
958 willBeComposited = true; 972 willBeComposited = true;
959 } 973 }
960 974
961 // If the original layer is composited, the reflection needs to be, too. 975 // If the original layer is composited, the reflection needs to be, too.
962 if (layer->reflectionLayer()) { 976 if (layer->reflectionLayer()) {
963 // FIXME: Shouldn't we call computeCompositingRequirements to handle a r eflection overlapping with another renderer? 977 // FIXME: Shouldn't we call computeCompositingRequirements to handle a r eflection overlapping with another renderer?
964 CompositingReasons reflectionCompositingReason = willBeComposited ? Comp ositingReasonReflectionOfCompositedParent : CompositingReasonNone; 978 CompositingReasons reflectionCompositingReason = willBeComposited ? Comp ositingReasonReflectionOfCompositedParent : CompositingReasonNone;
965 layer->reflectionLayer()->setCompositingReasons(layer->reflectionLayer() ->compositingReasons() | reflectionCompositingReason); 979 layer->reflectionLayer()->setCompositingReasons(layer->reflectionLayer() ->compositingReasons() | reflectionCompositingReason);
966 } 980 }
967 981
968 // Subsequent layers in the parent's stacking context may also need to compo site. 982 // Subsequent layers in the parent's stacking context may also need to compo site.
969 if (childState.m_subtreeIsCompositing) 983 if (childState.m_subtreeIsCompositing)
970 compositingState.m_subtreeIsCompositing = true; 984 compositingState.m_subtreeIsCompositing = true;
985 if (willBeComposited && layer->hasBlendMode())
986 compositingState.m_hasCompositedBlendingDescendents = true;
971 987
972 // Set the flag to say that this SC has compositing children. 988 // Set the flag to say that this SC has compositing children.
973 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing); 989 layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
974 990
975 991
976 // Turn overlap testing off for later layers if it's already off, or if we h ave an animating transform. 992 // Turn overlap testing off for later layers if it's already off, or if we h ave an animating transform.
977 // 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 993 // 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
978 // we know for sure the animation is contained inside the clipping rectangle , which is already added to the overlap map. 994 // we know for sure the animation is contained inside the clipping rectangle , which is already added to the overlap map.
979 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposi te & CompositingReasonClipsCompositingDescendants); 995 bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposi te & CompositingReasonClipsCompositingDescendants);
980 if ((!childState.m_testingOverlap && !isCompositedClippingLayer) || isRunnin gAcceleratedTransformAnimation(layer->renderer())) 996 if ((!childState.m_testingOverlap && !isCompositedClippingLayer) || isRunnin gAcceleratedTransformAnimation(layer->renderer()))
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 return true; 1614 return true;
1599 1615
1600 CompositingReasons indirectReasonsThatNeedBacking = CompositingReasonOverlap 1616 CompositingReasons indirectReasonsThatNeedBacking = CompositingReasonOverlap
1601 | CompositingReasonAssumedOverlap 1617 | CompositingReasonAssumedOverlap
1602 | CompositingReasonNegativeZIndexChildren 1618 | CompositingReasonNegativeZIndexChildren
1603 | CompositingReasonTransformWithCompositedDescendants 1619 | CompositingReasonTransformWithCompositedDescendants
1604 | CompositingReasonOpacityWithCompositedDescendants 1620 | CompositingReasonOpacityWithCompositedDescendants
1605 | CompositingReasonMaskWithCompositedDescendants 1621 | CompositingReasonMaskWithCompositedDescendants
1606 | CompositingReasonFilterWithCompositedDescendants 1622 | CompositingReasonFilterWithCompositedDescendants
1607 | CompositingReasonBlendingWithCompositedDescendants 1623 | CompositingReasonBlendingWithCompositedDescendants
1624 | CompositingReasonIsolateCompositedDescendants
1608 | CompositingReasonPreserve3D; // preserve-3d has to create backing stor e to ensure that 3d-transformed elements intersect. 1625 | CompositingReasonPreserve3D; // preserve-3d has to create backing stor e to ensure that 3d-transformed elements intersect.
1609 return layer->compositingReasons() & indirectReasonsThatNeedBacking; 1626 return layer->compositingReasons() & indirectReasonsThatNeedBacking;
1610 } 1627 }
1611 1628
1612 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const Rend erLayer* layer) const 1629 CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const Rend erLayer* layer) const
1613 { 1630 {
1614 RenderObject* renderer = layer->renderer(); 1631 RenderObject* renderer = layer->renderer();
1615 CompositingReasons directReasons = CompositingReasonNone; 1632 CompositingReasons directReasons = CompositingReasonNone;
1616 1633
1617 if (requiresCompositingForTransform(renderer)) 1634 if (requiresCompositingForTransform(renderer))
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 1751
1735 if (reasons & CompositingReasonPerspective) 1752 if (reasons & CompositingReasonPerspective)
1736 return "perspective"; 1753 return "perspective";
1737 1754
1738 if (reasons & CompositingReasonPreserve3D) 1755 if (reasons & CompositingReasonPreserve3D)
1739 return "preserve-3d"; 1756 return "preserve-3d";
1740 1757
1741 if (reasons & CompositingReasonRoot) 1758 if (reasons & CompositingReasonRoot)
1742 return "root"; 1759 return "root";
1743 1760
1761 if (reasons & CompositingReasonIsolateCompositedDescendants)
1762 return "isolate composited descendants";
1763
1744 return ""; 1764 return "";
1745 } 1765 }
1746 #endif 1766 #endif
1747 1767
1748 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, 1768 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
1749 // up to the enclosing compositing ancestor. This is required because compositin g layers are parented 1769 // up to the enclosing compositing ancestor. This is required because compositin g layers are parented
1750 // according to the z-order hierarchy, yet clipping goes down the renderer hiera rchy. 1770 // according to the z-order hierarchy, yet clipping goes down the renderer hiera rchy.
1751 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in th e renderer hierarchy, 1771 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in th e renderer hierarchy,
1752 // but a sibling in the z-order hierarchy. 1772 // but a sibling in the z-order hierarchy.
1753 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const 1773 bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 CompositingReasons subtreeReasons = CompositingReasonNone; 1942 CompositingReasons subtreeReasons = CompositingReasonNone;
1923 1943
1924 // 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. 1944 // 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.
1925 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); 1945 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1926 1946
1927 // When a layer has composited descendants, some effects, like 2d transforms , filters, masks etc must be implemented 1947 // When a layer has composited descendants, some effects, like 2d transforms , filters, masks etc must be implemented
1928 // via compositing so that they also apply to those composited descdendants. 1948 // via compositing so that they also apply to those composited descdendants.
1929 if (hasCompositedDescendants) { 1949 if (hasCompositedDescendants) {
1930 if (layer->transform()) 1950 if (layer->transform())
1931 subtreeReasons |= CompositingReasonTransformWithCompositedDescendant s; 1951 subtreeReasons |= CompositingReasonTransformWithCompositedDescendant s;
1952 if (layer->shouldIsolateCompositedBlendingDescendants())
shawnsingh 2013/09/13 10:22:59 So it seems like this boolean value, shouldIsolate
rosca 2013/09/19 14:26:54 This property is used in RenderLayerBacking::updat
1953 subtreeReasons |= CompositingReasonIsolateCompositedDescendants;
1932 1954
1933 // If the implementation of createsGroup changes, we need to be aware of that in this part of code. 1955 // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
1934 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->ha sFilter() || renderer->hasBlendMode()) == renderer->createsGroup()); 1956 ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->ha sFilter() || renderer->hasBlendMode()) == renderer->createsGroup());
1935 if (renderer->isTransparent()) 1957 if (renderer->isTransparent())
1936 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants; 1958 subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants;
1937 if (renderer->hasMask()) 1959 if (renderer->hasMask())
1938 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants; 1960 subtreeReasons |= CompositingReasonMaskWithCompositedDescendants;
1939 if (renderer->hasFilter()) 1961 if (renderer->hasFilter())
1940 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants; 1962 subtreeReasons |= CompositingReasonFilterWithCompositedDescendants;
1941 if (renderer->hasBlendMode()) 1963 if (renderer->hasBlendMode())
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
2735 } else if (graphicsLayer == m_scrollLayer.get()) { 2757 } else if (graphicsLayer == m_scrollLayer.get()) {
2736 name = "Frame Scrolling Layer"; 2758 name = "Frame Scrolling Layer";
2737 } else { 2759 } else {
2738 ASSERT_NOT_REACHED(); 2760 ASSERT_NOT_REACHED();
2739 } 2761 }
2740 2762
2741 return name; 2763 return name;
2742 } 2764 }
2743 2765
2744 } // namespace WebCore 2766 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698