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

Side by Side Diff: Source/core/layout/svg/LayoutSVGResourceMasker.cpp

Issue 947893002: Implement SVG masking with slimming paint (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add a mask debug print string Created 5 years, 10 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) Research In Motion Limited 2009-2010. All rights reserved. 2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details. 12 * Library General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU Library General Public License 14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to 15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA. 17 * Boston, MA 02110-1301, USA.
18 */ 18 */
19 19
20 #include "config.h" 20 #include "config.h"
21 #include "core/layout/svg/LayoutSVGResourceMasker.h" 21 #include "core/layout/svg/LayoutSVGResourceMasker.h"
22 22
23 #include "core/dom/ElementTraversal.h" 23 #include "core/dom/ElementTraversal.h"
24 #include "core/layout/svg/SVGLayoutSupport.h" 24 #include "core/layout/svg/SVGLayoutSupport.h"
25 #include "core/paint/CompositingRecorder.h"
25 #include "core/paint/SVGPaintContext.h" 26 #include "core/paint/SVGPaintContext.h"
27 #include "core/paint/TransformRecorder.h"
26 #include "core/svg/SVGElement.h" 28 #include "core/svg/SVGElement.h"
27 #include "platform/graphics/GraphicsContextStateSaver.h" 29 #include "platform/graphics/GraphicsContextStateSaver.h"
30 #include "platform/graphics/paint/CompositingDisplayItem.h"
31 #include "platform/graphics/paint/DisplayItemList.h"
32 #include "platform/graphics/paint/DrawingDisplayItem.h"
28 #include "platform/transforms/AffineTransform.h" 33 #include "platform/transforms/AffineTransform.h"
29 #include "third_party/skia/include/core/SkPicture.h" 34 #include "third_party/skia/include/core/SkPicture.h"
30 35
31 namespace blink { 36 namespace blink {
32 37
33 LayoutSVGResourceMasker::LayoutSVGResourceMasker(SVGMaskElement* node) 38 LayoutSVGResourceMasker::LayoutSVGResourceMasker(SVGMaskElement* node)
34 : LayoutSVGResourceContainer(node) 39 : LayoutSVGResourceContainer(node)
35 { 40 {
36 } 41 }
37 42
(...skipping 20 matching lines...) Expand all
58 ASSERT(context); 63 ASSERT(context);
59 ASSERT(style()); 64 ASSERT(style());
60 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout()); 65 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
61 66
62 clearInvalidationMask(); 67 clearInvalidationMask();
63 68
64 FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordi nates(); 69 FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordi nates();
65 if (paintInvalidationRect.isEmpty() || !element()->hasChildren()) 70 if (paintInvalidationRect.isEmpty() || !element()->hasChildren())
66 return false; 71 return false;
67 72
68 // Content layer start. 73 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
69 context->beginTransparencyLayer(1, &paintInvalidationRect); 74 ASSERT(context->displayItemList());
75 context->displayItemList()->add(BeginCompositingDisplayItem::create(obje ct->displayItemClient(), WebCoreCompositeToSkiaComposite(context->compositeOpera tionDeprecated(), WebBlendModeNormal), 1, &paintInvalidationRect));
76 } else {
77 BeginCompositingDisplayItem beginCompositingContent(object->displayItemC lient(), WebCoreCompositeToSkiaComposite(context->compositeOperationDeprecated() , WebBlendModeNormal), 1, &paintInvalidationRect);
78 beginCompositingContent.replay(context);
79 }
70 80
71 return true; 81 return true;
72 } 82 }
73 83
74 void LayoutSVGResourceMasker::finishEffect(LayoutObject* object, GraphicsContext * context) 84 void LayoutSVGResourceMasker::finishEffect(LayoutObject* object, GraphicsContext * context)
75 { 85 {
76 ASSERT(object); 86 ASSERT(object);
77 ASSERT(context); 87 ASSERT(context);
78 ASSERT(style()); 88 ASSERT(style());
79 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout()); 89 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
80 90
81 FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordi nates(); 91 FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordi nates();
82
83 const SVGLayoutStyle& svgStyle = style()->svgStyle();
84 ColorFilter maskLayerFilter = svgStyle.maskType() == MT_LUMINANCE
85 ? ColorFilterLuminanceToAlpha : ColorFilterNone;
86 ColorFilter maskContentFilter = svgStyle.colorInterpolation() == CI_LINEARRG B
87 ? ColorFilterSRGBToLinearRGB : ColorFilterNone;
88
89 // Mask layer start.
90 context->beginLayer(1, SkXfermode::kDstIn_Mode, &paintInvalidationRect, mask LayerFilter);
91 { 92 {
92 // Draw the mask with color conversion (when needed). 93 ColorFilter maskLayerFilter = style()->svgStyle().maskType() == MT_LUMIN ANCE
93 GraphicsContextStateSaver maskContentSaver(*context); 94 ? ColorFilterLuminanceToAlpha : ColorFilterNone;
94 context->setColorFilter(maskContentFilter); 95 CompositingRecorder maskCompositing(context, object->displayItemClient() , SkXfermode::kDstIn_Mode, 1, &paintInvalidationRect, maskLayerFilter);
95 96 drawMaskForRenderer(context, object->displayItemClient(), object->object BoundingBox());
96 drawMaskForRenderer(context, object->objectBoundingBox());
97 } 97 }
98 98
99 // Transfer mask layer -> content layer (DstIn) 99 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
100 context->endLayer(); 100 ASSERT(context->displayItemList());
101 // Transfer content layer -> backdrop (SrcOver) 101 context->displayItemList()->add(EndCompositingDisplayItem::create(object ->displayItemClient()));
102 context->endLayer(); 102 } else {
103 EndCompositingDisplayItem endCompositingContent(object->displayItemClien t());
104 endCompositingContent.replay(context);
105 }
103 } 106 }
104 107
105 void LayoutSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, cons t FloatRect& targetBoundingBox) 108 void LayoutSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, Disp layItemClient client, const FloatRect& targetBoundingBox)
106 { 109 {
107 ASSERT(context); 110 ASSERT(context);
108 111
109 AffineTransform contentTransformation; 112 AffineTransform contentTransformation;
110 SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskCo ntentUnits()->currentValue()->enumValue(); 113 SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskCo ntentUnits()->currentValue()->enumValue();
111 if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { 114 if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
112 contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox .y()); 115 contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox .y());
113 contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetB oundingBox.height()); 116 contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetB oundingBox.height());
114 context->concatCTM(contentTransformation);
115 } 117 }
116 118
117 if (!m_maskContentPicture) { 119 if (!m_maskContentPicture) {
118 SubtreeContentTransformScope contentTransformScope(contentTransformation ); 120 SubtreeContentTransformScope contentTransformScope(contentTransformation );
119 createPicture(context); 121 m_maskContentPicture = createContentPicture();
120 } 122 }
121 123
122 context->drawPicture(m_maskContentPicture.get()); 124 TransformRecorder recorder(*context, client, contentTransformation);
125
126 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
127 ASSERT(context->displayItemList());
128 context->displayItemList()->add(DrawingDisplayItem::create(client, Displ ayItem::SVGMask, m_maskContentPicture));
129 } else {
130 DrawingDisplayItem maskPicture(client, DisplayItem::SVGMask, m_maskConte ntPicture);
131 maskPicture.replay(context);
132 }
123 } 133 }
124 134
125 void LayoutSVGResourceMasker::createPicture(GraphicsContext* context) 135 PassRefPtr<const SkPicture> LayoutSVGResourceMasker::createContentPicture()
126 { 136 {
127 ASSERT(context);
128
129 // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinat es) to avoid the intersection 137 // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinat es) to avoid the intersection
130 // with local clips/mask, which may yield incorrect results when mixing obje ctBoundingBox and 138 // with local clips/mask, which may yield incorrect results when mixing obje ctBoundingBox and
131 // userSpaceOnUse units (http://crbug.com/294900). 139 // userSpaceOnUse units (http://crbug.com/294900).
132 FloatRect bounds = strokeBoundingBox(); 140 FloatRect bounds = strokeBoundingBox();
133 context->beginRecording(bounds); 141
142 OwnPtr<DisplayItemList> displayItemList;
143 if (RuntimeEnabledFeatures::slimmingPaintEnabled())
144 displayItemList = DisplayItemList::create();
145 GraphicsContext context(nullptr, displayItemList.get());
146 context.beginRecording(bounds);
147
148 ColorFilter maskContentFilter = style()->svgStyle().colorInterpolation() == CI_LINEARRGB
149 ? ColorFilterSRGBToLinearRGB : ColorFilterNone;
150 context.setColorFilter(maskContentFilter);
151
134 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) { 152 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
135 LayoutObject* renderer = childElement->renderer(); 153 LayoutObject* renderer = childElement->renderer();
136 if (!renderer) 154 if (!renderer)
137 continue; 155 continue;
138 const LayoutStyle* style = renderer->style(); 156 const LayoutStyle* style = renderer->style();
139 if (!style || style->display() == NONE || style->visibility() != VISIBLE ) 157 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
140 continue; 158 continue;
141 159
142 SVGPaintContext::paintSubtree(context, renderer); 160 SVGPaintContext::paintSubtree(&context, renderer);
143 } 161 }
144 m_maskContentPicture = context->endRecording(); 162
163 if (displayItemList)
164 displayItemList->replay(&context);
165 return context.endRecording();
145 } 166 }
146 167
147 void LayoutSVGResourceMasker::calculateMaskContentPaintInvalidationRect() 168 void LayoutSVGResourceMasker::calculateMaskContentPaintInvalidationRect()
148 { 169 {
149 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) { 170 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
150 LayoutObject* renderer = childElement->renderer(); 171 LayoutObject* renderer = childElement->renderer();
151 if (!renderer) 172 if (!renderer)
152 continue; 173 continue;
153 const LayoutStyle* style = renderer->style(); 174 const LayoutStyle* style = renderer->style();
154 if (!style || style->display() == NONE || style->visibility() != VISIBLE ) 175 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
(...skipping 23 matching lines...) Expand all
178 transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); 199 transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
179 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h eight()); 200 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h eight());
180 maskRect = transform.mapRect(maskRect); 201 maskRect = transform.mapRect(maskRect);
181 } 202 }
182 203
183 maskRect.intersect(maskBoundaries); 204 maskRect.intersect(maskBoundaries);
184 return maskRect; 205 return maskRect;
185 } 206 }
186 207
187 } 208 }
OLDNEW
« no previous file with comments | « Source/core/layout/svg/LayoutSVGResourceMasker.h ('k') | Source/core/paint/CompositingRecorder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698