OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/paint/SVGFilterPainter.h" | 6 #include "core/paint/SVGFilterPainter.h" |
7 | 7 |
8 #include "core/layout/PaintInfo.h" | 8 #include "core/layout/PaintInfo.h" |
9 #include "core/layout/svg/LayoutSVGResourceFilter.h" | 9 #include "core/layout/svg/LayoutSVGResourceFilter.h" |
10 #include "core/paint/CompositingRecorder.h" | 10 #include "core/paint/CompositingRecorder.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 { | 22 { |
23 ASSERT(filterData->m_state == FilterData::Initial); | 23 ASSERT(filterData->m_state == FilterData::Initial); |
24 | 24 |
25 // For slimming paint we need to create a new context so the contents of the | 25 // For slimming paint we need to create a new context so the contents of the |
26 // filter can be drawn and cached. | 26 // filter can be drawn and cached. |
27 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { | 27 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
28 filterData->m_displayItemList = DisplayItemList::create(); | 28 filterData->m_displayItemList = DisplayItemList::create(); |
29 filterData->m_context = adoptPtr(new GraphicsContext(filterData->m_displ
ayItemList.get())); | 29 filterData->m_context = adoptPtr(new GraphicsContext(filterData->m_displ
ayItemList.get())); |
30 context = filterData->m_context.get(); | 30 context = filterData->m_context.get(); |
31 } else { | 31 } else { |
32 context->beginRecording(filterData->boundaries); | 32 context->beginRecording(filterData->filter->filterRegion()); |
33 } | 33 } |
34 | 34 |
35 filterData->m_state = FilterData::RecordingContent; | 35 filterData->m_state = FilterData::RecordingContent; |
36 return context; | 36 return context; |
37 } | 37 } |
38 | 38 |
39 static void endRecordingContent(GraphicsContext* context, FilterData* filterData
) | 39 static void endRecordingContent(GraphicsContext* context, FilterData* filterData
) |
40 { | 40 { |
41 ASSERT(filterData->m_state == FilterData::RecordingContent); | 41 ASSERT(filterData->m_state == FilterData::RecordingContent); |
42 | 42 |
43 // FIXME: maybe filterData should just hold onto SourceGraphic after creatio
n? | 43 // FIXME: maybe filterData should just hold onto SourceGraphic after creatio
n? |
44 SourceGraphic* sourceGraphic = static_cast<SourceGraphic*>(filterData->build
er->getEffectById(SourceGraphic::effectName())); | 44 SourceGraphic* sourceGraphic = static_cast<SourceGraphic*>(filterData->build
er->getEffectById(SourceGraphic::effectName())); |
45 ASSERT(sourceGraphic); | 45 ASSERT(sourceGraphic); |
46 | 46 |
47 // For slimming paint we need to use the context that contains the filtered | 47 // For slimming paint we need to use the context that contains the filtered |
48 // content. | 48 // content. |
49 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { | 49 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
50 ASSERT(filterData->m_displayItemList); | 50 ASSERT(filterData->m_displayItemList); |
51 ASSERT(filterData->m_context); | 51 ASSERT(filterData->m_context); |
52 context = filterData->m_context.get(); | 52 context = filterData->m_context.get(); |
53 context->beginRecording(filterData->boundaries); | 53 context->beginRecording(filterData->filter->filterRegion()); |
54 filterData->m_displayItemList->commitNewDisplayItemsAndReplay(*context); | 54 filterData->m_displayItemList->commitNewDisplayItemsAndReplay(*context); |
55 } | 55 } |
56 | 56 |
57 sourceGraphic->setPicture(context->endRecording()); | 57 sourceGraphic->setPicture(context->endRecording()); |
58 | 58 |
59 // Content is cached by the source graphic so temporaries can be freed. | 59 // Content is cached by the source graphic so temporaries can be freed. |
60 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { | 60 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { |
61 filterData->m_displayItemList = nullptr; | 61 filterData->m_displayItemList = nullptr; |
62 filterData->m_context = nullptr; | 62 filterData->m_context = nullptr; |
63 } | 63 } |
64 | 64 |
65 filterData->m_state = FilterData::ReadyToPaint; | 65 filterData->m_state = FilterData::ReadyToPaint; |
66 } | 66 } |
67 | 67 |
68 static void paintFilteredContent(GraphicsContext* context, FilterData* filterDat
a, SVGFilterElement* filterElement) | 68 static void paintFilteredContent(GraphicsContext* context, FilterData* filterDat
a, SVGFilterElement* filterElement) |
69 { | 69 { |
70 ASSERT(filterData->m_state == FilterData::ReadyToPaint); | 70 ASSERT(filterData->m_state == FilterData::ReadyToPaint); |
71 filterData->m_state = FilterData::PaintingFilter; | 71 filterData->m_state = FilterData::PaintingFilter; |
72 | 72 |
73 SkiaImageFilterBuilder builder(context); | 73 SkiaImageFilterBuilder builder(context); |
74 SourceGraphic* sourceGraphic = static_cast<SourceGraphic*>(filterData->build
er->getEffectById(SourceGraphic::effectName())); | 74 SourceGraphic* sourceGraphic = static_cast<SourceGraphic*>(filterData->build
er->getEffectById(SourceGraphic::effectName())); |
75 ASSERT(sourceGraphic); | 75 ASSERT(sourceGraphic); |
76 builder.setSourceGraphic(sourceGraphic); | 76 builder.setSourceGraphic(sourceGraphic); |
77 RefPtr<SkImageFilter> imageFilter = builder.build(filterData->builder->lastE
ffect(), ColorSpaceDeviceRGB); | 77 RefPtr<SkImageFilter> imageFilter = builder.build(filterData->builder->lastE
ffect(), ColorSpaceDeviceRGB); |
78 FloatRect boundaries = filterData->boundaries; | 78 FloatRect boundaries = filterData->filter->filterRegion(); |
79 context->save(); | 79 context->save(); |
80 | 80 |
81 // Clip drawing of filtered image to the minimum required paint rect. | 81 // Clip drawing of filtered image to the minimum required paint rect. |
82 FilterEffect* lastEffect = filterData->builder->lastEffect(); | 82 FilterEffect* lastEffect = filterData->builder->lastEffect(); |
83 context->clipRect(lastEffect->determineAbsolutePaintRect(lastEffect->maxEffe
ctRect())); | 83 context->clipRect(lastEffect->determineAbsolutePaintRect(lastEffect->maxEffe
ctRect())); |
84 if (filterElement->hasAttribute(SVGNames::filterResAttr)) { | 84 if (filterElement->hasAttribute(SVGNames::filterResAttr)) { |
85 // Get boundaries in device coords. | 85 // Get boundaries in device coords. |
86 // FIXME: See crbug.com/382491. Is the use of getCTM OK here, given it d
oes not include device | 86 // FIXME: See crbug.com/382491. Is the use of getCTM OK here, given it d
oes not include device |
87 // zoom or High DPI adjustments? | 87 // zoom or High DPI adjustments? |
88 FloatSize size = context->getCTM().mapSize(boundaries.size()); | 88 FloatSize size = context->getCTM().mapSize(boundaries.size()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 if (filterData->m_state == FilterData::RecordingContent) | 137 if (filterData->m_state == FilterData::RecordingContent) |
138 filterData->m_state = FilterData::RecordingContentCycleDetected; | 138 filterData->m_state = FilterData::RecordingContentCycleDetected; |
139 | 139 |
140 return nullptr; | 140 return nullptr; |
141 } | 141 } |
142 | 142 |
143 OwnPtrWillBeRawPtr<FilterData> filterData = FilterData::create(); | 143 OwnPtrWillBeRawPtr<FilterData> filterData = FilterData::create(); |
144 FloatRect targetBoundingBox = object.objectBoundingBox(); | 144 FloatRect targetBoundingBox = object.objectBoundingBox(); |
145 | 145 |
146 SVGFilterElement* filterElement = toSVGFilterElement(m_filter.element()); | 146 SVGFilterElement* filterElement = toSVGFilterElement(m_filter.element()); |
147 filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement
>(filterElement, filterElement->filterUnits()->currentValue()->enumValue(), targ
etBoundingBox); | 147 FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement
>(filterElement, filterElement->filterUnits()->currentValue()->enumValue(), targ
etBoundingBox); |
148 if (filterData->boundaries.isEmpty()) | 148 if (filterRegion.isEmpty()) |
149 return nullptr; | 149 return nullptr; |
150 | 150 |
151 // Create the SVGFilter object. | 151 // Create the SVGFilter object. |
152 FloatRect drawingRegion = object.strokeBoundingBox(); | 152 FloatRect drawingRegion = object.strokeBoundingBox(); |
153 drawingRegion.intersect(filterData->boundaries); | 153 drawingRegion.intersect(filterRegion); |
154 bool primitiveBoundingBoxMode = filterElement->primitiveUnits()->currentValu
e()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; | 154 bool primitiveBoundingBoxMode = filterElement->primitiveUnits()->currentValu
e()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; |
155 filterData->filter = SVGFilter::create(enclosingIntRect(drawingRegion), targ
etBoundingBox, filterData->boundaries, primitiveBoundingBoxMode); | 155 filterData->filter = SVGFilter::create(enclosingIntRect(drawingRegion), targ
etBoundingBox, filterRegion, primitiveBoundingBoxMode); |
156 | 156 |
157 // Create all relevant filter primitives. | 157 // Create all relevant filter primitives. |
158 filterData->builder = m_filter.buildPrimitives(filterData->filter.get()); | 158 filterData->builder = m_filter.buildPrimitives(filterData->filter.get()); |
159 if (!filterData->builder) | 159 if (!filterData->builder) |
160 return nullptr; | 160 return nullptr; |
161 | 161 |
162 FilterEffect* lastEffect = filterData->builder->lastEffect(); | 162 FilterEffect* lastEffect = filterData->builder->lastEffect(); |
163 if (!lastEffect) | 163 if (!lastEffect) |
164 return nullptr; | 164 return nullptr; |
165 | 165 |
(...skipping 24 matching lines...) Expand all Loading... |
190 | 190 |
191 LayoutObjectDrawingRecorder recorder(*context, object, DisplayItem::SVGFilte
r, LayoutRect::infiniteIntRect()); | 191 LayoutObjectDrawingRecorder recorder(*context, object, DisplayItem::SVGFilte
r, LayoutRect::infiniteIntRect()); |
192 if (recorder.canUseCachedDrawing()) | 192 if (recorder.canUseCachedDrawing()) |
193 return; | 193 return; |
194 | 194 |
195 if (filterData && filterData->m_state == FilterData::ReadyToPaint) | 195 if (filterData && filterData->m_state == FilterData::ReadyToPaint) |
196 paintFilteredContent(context, filterData, toSVGFilterElement(m_filter.el
ement())); | 196 paintFilteredContent(context, filterData, toSVGFilterElement(m_filter.el
ement())); |
197 } | 197 } |
198 | 198 |
199 } | 199 } |
OLD | NEW |