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

Side by Side Diff: third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp

Issue 2851753002: Refactor FilterData::state_ handling in SVGFilterPainter (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « third_party/WebKit/Source/core/paint/SVGFilterPainter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "core/paint/SVGFilterPainter.h" 5 #include "core/paint/SVGFilterPainter.h"
6 6
7 #include "core/layout/svg/LayoutSVGResourceFilter.h" 7 #include "core/layout/svg/LayoutSVGResourceFilter.h"
8 #include "core/paint/FilterEffectBuilder.h" 8 #include "core/paint/FilterEffectBuilder.h"
9 #include "core/paint/LayoutObjectDrawingRecorder.h" 9 #include "core/paint/LayoutObjectDrawingRecorder.h"
10 #include "core/svg/SVGFilterElement.h" 10 #include "core/svg/SVGFilterElement.h"
11 #include "core/svg/graphics/filters/SVGFilterBuilder.h" 11 #include "core/svg/graphics/filters/SVGFilterBuilder.h"
12 #include "platform/graphics/filters/Filter.h" 12 #include "platform/graphics/filters/Filter.h"
13 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" 13 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
14 #include "platform/graphics/filters/SourceGraphic.h" 14 #include "platform/graphics/filters/SourceGraphic.h"
15 #include "platform/wtf/PtrUtil.h" 15 #include "platform/wtf/PtrUtil.h"
16 16
17 namespace blink { 17 namespace blink {
18 18
19 GraphicsContext* SVGFilterRecordingContext::BeginContent( 19 GraphicsContext* SVGFilterRecordingContext::BeginContent() {
20 FilterData* filter_data) {
21 DCHECK_EQ(filter_data->state_, FilterData::kInitial);
22
23 // Create a new context so the contents of the filter can be drawn and cached. 20 // Create a new context so the contents of the filter can be drawn and cached.
24 paint_controller_ = PaintController::Create(); 21 paint_controller_ = PaintController::Create();
25 context_ = WTF::WrapUnique(new GraphicsContext(*paint_controller_)); 22 context_ = WTF::WrapUnique(new GraphicsContext(*paint_controller_));
26 23
27 // Content painted into a new PaintRecord in SPv2 will have an 24 // Content painted into a new PaintRecord in SPv2 will have an
28 // independent property tree set. 25 // independent property tree set.
29 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 26 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
30 paint_controller_->UpdateCurrentPaintChunkProperties( 27 paint_controller_->UpdateCurrentPaintChunkProperties(
31 nullptr, PropertyTreeState::Root()); 28 nullptr, PropertyTreeState::Root());
32 } 29 }
33
34 filter_data->state_ = FilterData::kRecordingContent;
35 return context_.get(); 30 return context_.get();
36 } 31 }
37 32
38 void SVGFilterRecordingContext::EndContent(FilterData* filter_data) { 33 sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent(
39 DCHECK_EQ(filter_data->state_, FilterData::kRecordingContent); 34 const FloatRect& bounds) {
40
41 Filter* filter = filter_data->last_effect->GetFilter();
42 SourceGraphic* source_graphic = filter->GetSourceGraphic();
43 DCHECK(source_graphic);
44
45 // Use the context that contains the filtered content. 35 // Use the context that contains the filtered content.
46 DCHECK(paint_controller_); 36 DCHECK(paint_controller_);
47 DCHECK(context_); 37 DCHECK(context_);
48 context_->BeginRecording(filter->FilterRegion()); 38 context_->BeginRecording(bounds);
49 paint_controller_->CommitNewDisplayItems(); 39 paint_controller_->CommitNewDisplayItems();
50 40
51 paint_controller_->GetPaintArtifact().Replay(filter->FilterRegion(), 41 paint_controller_->GetPaintArtifact().Replay(bounds, *context_);
52 *context_);
53 42
54 SkiaImageFilterBuilder::BuildSourceGraphic(source_graphic, 43 sk_sp<PaintRecord> content = context_->EndRecording();
55 context_->EndRecording());
56
57 // Content is cached by the source graphic so temporaries can be freed. 44 // Content is cached by the source graphic so temporaries can be freed.
58 paint_controller_ = nullptr; 45 paint_controller_ = nullptr;
59 context_ = nullptr; 46 context_ = nullptr;
60 47 return content;
61 filter_data->state_ = FilterData::kReadyToPaint;
62 } 48 }
63 49
64 static void PaintFilteredContent(GraphicsContext& context, 50 static void PaintFilteredContent(GraphicsContext& context,
65 const LayoutObject& object, 51 const LayoutObject& object,
66 FilterData* filter_data) { 52 const FloatRect& bounds,
53 FilterEffect* effect) {
67 if (LayoutObjectDrawingRecorder::UseCachedDrawingIfPossible( 54 if (LayoutObjectDrawingRecorder::UseCachedDrawingIfPossible(
68 context, object, DisplayItem::kSVGFilter)) 55 context, object, DisplayItem::kSVGFilter))
69 return; 56 return;
70 57
71 FloatRect filter_bounds =
72 filter_data ? filter_data->last_effect->GetFilter()->FilterRegion()
73 : FloatRect();
74 LayoutObjectDrawingRecorder recorder(context, object, DisplayItem::kSVGFilter, 58 LayoutObjectDrawingRecorder recorder(context, object, DisplayItem::kSVGFilter,
75 filter_bounds); 59 bounds);
76 if (!filter_data || filter_data->state_ != FilterData::kReadyToPaint)
77 return;
78 DCHECK(filter_data->last_effect->GetFilter()->GetSourceGraphic());
79
80 filter_data->state_ = FilterData::kPaintingFilter;
81
82 FilterEffect* last_effect = filter_data->last_effect;
83 sk_sp<SkImageFilter> image_filter = 60 sk_sp<SkImageFilter> image_filter =
84 SkiaImageFilterBuilder::Build(last_effect, kColorSpaceDeviceRGB); 61 SkiaImageFilterBuilder::Build(effect, kColorSpaceDeviceRGB);
85 context.Save(); 62 context.Save();
86 63
87 // Clip drawing of filtered image to the minimum required paint rect. 64 // Clip drawing of filtered image to the minimum required paint rect.
88 context.ClipRect(last_effect->MapRect(object.StrokeBoundingBox())); 65 context.ClipRect(effect->MapRect(object.StrokeBoundingBox()));
89 66
90 context.BeginLayer(1, SkBlendMode::kSrcOver, &filter_bounds, kColorFilterNone, 67 context.BeginLayer(1, SkBlendMode::kSrcOver, &bounds, kColorFilterNone,
91 std::move(image_filter)); 68 std::move(image_filter));
92 context.EndLayer(); 69 context.EndLayer();
93 context.Restore(); 70 context.Restore();
94
95 filter_data->state_ = FilterData::kReadyToPaint;
96 } 71 }
97 72
98 GraphicsContext* SVGFilterPainter::PrepareEffect( 73 GraphicsContext* SVGFilterPainter::PrepareEffect(
99 const LayoutObject& object, 74 const LayoutObject& object,
100 SVGFilterRecordingContext& recording_context) { 75 SVGFilterRecordingContext& recording_context) {
101 filter_.ClearInvalidationMask(); 76 filter_.ClearInvalidationMask();
102 77
103 if (FilterData* filter_data = filter_.GetFilterDataForLayoutObject(&object)) { 78 if (FilterData* filter_data = filter_.GetFilterDataForLayoutObject(&object)) {
104 // If the filterData already exists we do not need to record the content 79 // If the filterData already exists we do not need to record the content
105 // to be filtered. This can occur if the content was previously recorded 80 // to be filtered. This can occur if the content was previously recorded
(...skipping 14 matching lines...) Expand all
120 if (!filter || !filter->LastEffect()) 95 if (!filter || !filter->LastEffect())
121 return nullptr; 96 return nullptr;
122 97
123 IntRect source_region = EnclosingIntRect( 98 IntRect source_region = EnclosingIntRect(
124 Intersection(filter->FilterRegion(), object.StrokeBoundingBox())); 99 Intersection(filter->FilterRegion(), object.StrokeBoundingBox()));
125 filter->GetSourceGraphic()->SetSourceRect(source_region); 100 filter->GetSourceGraphic()->SetSourceRect(source_region);
126 101
127 FilterData* filter_data = FilterData::Create(); 102 FilterData* filter_data = FilterData::Create();
128 filter_data->last_effect = filter->LastEffect(); 103 filter_data->last_effect = filter->LastEffect();
129 filter_data->node_map = node_map; 104 filter_data->node_map = node_map;
105 DCHECK_EQ(filter_data->state_, FilterData::kInitial);
130 106
131 // TODO(pdr): Can this be moved out of painter? 107 // TODO(pdr): Can this be moved out of painter?
132 filter_.SetFilterDataForLayoutObject(const_cast<LayoutObject*>(&object), 108 filter_.SetFilterDataForLayoutObject(const_cast<LayoutObject*>(&object),
133 filter_data); 109 filter_data);
134 return recording_context.BeginContent(filter_data); 110 filter_data->state_ = FilterData::kRecordingContent;
111 return recording_context.BeginContent();
135 } 112 }
136 113
137 void SVGFilterPainter::FinishEffect( 114 void SVGFilterPainter::FinishEffect(
138 const LayoutObject& object, 115 const LayoutObject& object,
139 SVGFilterRecordingContext& recording_context) { 116 SVGFilterRecordingContext& recording_context) {
140 FilterData* filter_data = filter_.GetFilterDataForLayoutObject(&object); 117 FilterData* filter_data = filter_.GetFilterDataForLayoutObject(&object);
141 if (filter_data) { 118 if (!filter_data)
142 // A painting cycle can occur when an FeImage references a source that 119 return;
143 // makes use of the FeImage itself. This is the first place we would hit
144 // the cycle so we reset the state and continue.
145 if (filter_data->state_ == FilterData::kPaintingFilterCycleDetected)
146 filter_data->state_ = FilterData::kPaintingFilter;
147 120
148 // Check for RecordingContent here because we may can be re-painting 121 // A painting cycle can occur when an FeImage references a source that
149 // without re-recording the contents to be filtered. 122 // makes use of the FeImage itself. This is the first place we would hit
150 if (filter_data->state_ == FilterData::kRecordingContent) 123 // the cycle so we reset the state and continue.
151 recording_context.EndContent(filter_data); 124 if (filter_data->state_ == FilterData::kPaintingFilterCycleDetected) {
125 filter_data->state_ = FilterData::kPaintingFilter;
126 return;
127 }
128 if (filter_data->state_ == FilterData::kRecordingContentCycleDetected) {
129 filter_data->state_ = FilterData::kRecordingContent;
130 return;
131 }
152 132
153 if (filter_data->state_ == FilterData::kRecordingContentCycleDetected) 133 // Check for RecordingContent here because we may can be re-painting
154 filter_data->state_ = FilterData::kRecordingContent; 134 // without re-recording the contents to be filtered.
135 Filter* filter = filter_data->last_effect->GetFilter();
136 FloatRect bounds = filter->FilterRegion();
137 if (filter_data->state_ == FilterData::kRecordingContent) {
138 DCHECK(filter->GetSourceGraphic());
139 sk_sp<PaintRecord> content = recording_context.EndContent(bounds);
140 SkiaImageFilterBuilder::BuildSourceGraphic(filter->GetSourceGraphic(),
141 std::move(content));
142 filter_data->state_ = FilterData::kReadyToPaint;
155 } 143 }
156 PaintFilteredContent(recording_context.PaintingContext(), object, 144
chrishtr 2017/04/28 18:20:56 The old code would have executed this line in the
fs 2017/04/28 18:40:52 Previously it would've early-outed in PaintFiltere
chrishtr 2017/04/28 18:45:49 Ok great.
157 filter_data); 145 DCHECK_EQ(filter_data->state_, FilterData::kReadyToPaint);
146 filter_data->state_ = FilterData::kPaintingFilter;
147 PaintFilteredContent(recording_context.PaintingContext(), object, bounds,
148 filter_data->last_effect);
149 filter_data->state_ = FilterData::kReadyToPaint;
158 } 150 }
159 151
160 } // namespace blink 152 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/SVGFilterPainter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698