Commit 05dd77e4 authored by Fredrik Söderqvist's avatar Fredrik Söderqvist Committed by Commit Bot

Make SVGFilterPainter::PrepareEffect return FilterData

This makes it possible to discern "no valid filter" from "contents does
not need recording". In turn this makes it possible to skip the
corresponding FinishEffect() call when there's no valid filter.
This allows simplifying FinishEffect() and drop the Abort() method on
SVGFilterRecordingContext.

The call to SVGFilterRecordingContext::BeginContent() is sunk out of
PrepareEffect() and likewise the clearing of the invalidation mask is
hoisted.

Bug: 109224
Change-Id: I440a0d85f93ec0bd0d043a4f3545d793364b9f1c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2105374Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#750892}
parent 129460b8
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
namespace blink { namespace blink {
ScopedSVGPaintState::~ScopedSVGPaintState() { ScopedSVGPaintState::~ScopedSVGPaintState() {
if (filter_) { if (filter_data_) {
DCHECK(filter_);
DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_)); DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_));
DCHECK( DCHECK(
SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter() == SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter() ==
...@@ -158,23 +159,24 @@ static bool HasReferenceFilterOnly(const ComputedStyle& style) { ...@@ -158,23 +159,24 @@ static bool HasReferenceFilterOnly(const ComputedStyle& style) {
bool ScopedSVGPaintState::ApplyFilterIfNecessary(SVGResources* resources) { bool ScopedSVGPaintState::ApplyFilterIfNecessary(SVGResources* resources) {
if (!resources) if (!resources)
return !HasReferenceFilterOnly(object_.StyleRef()); return !HasReferenceFilterOnly(object_.StyleRef());
LayoutSVGResourceFilter* filter = resources->Filter(); LayoutSVGResourceFilter* filter = resources->Filter();
if (!filter) if (!filter)
return true; return true;
filter->ClearInvalidationMask();
filter_recording_context_ = filter_recording_context_ =
std::make_unique<SVGFilterRecordingContext>(GetPaintInfo().context); std::make_unique<SVGFilterRecordingContext>(GetPaintInfo().context);
filter_ = filter; filter_ = filter;
GraphicsContext* filter_context = SVGFilterPainter(*filter).PrepareEffect( filter_data_ = SVGFilterPainter(*filter).PrepareEffect(object_);
object_, *filter_recording_context_); // If we have no filter data (== the filter was invalid) or if we
if (!filter_context) // don't need to update the source graphics, we can short-circuit
// here.
if (!filter_data_ || !filter_data_->ContentNeedsUpdate())
return false; return false;
// Because the filter needs to cache its contents we replace the context // Because the filter needs to cache its contents we replace the context
// during filtering with the filter's context. // during filtering with the filter's context.
GraphicsContext* filter_context = filter_recording_context_->BeginContent();
filter_paint_info_ = filter_paint_info_ =
std::make_unique<PaintInfo>(*filter_context, paint_info_); std::make_unique<PaintInfo>(*filter_context, paint_info_);
// Because we cache the filter contents and do not invalidate on paint // Because we cache the filter contents and do not invalidate on paint
// invalidation rect changes, we need to paint the entire filter region // invalidation rect changes, we need to paint the entire filter region
// so elements outside the initial paint (due to scrolling, etc) paint. // so elements outside the initial paint (due to scrolling, etc) paint.
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
namespace blink { namespace blink {
class FilterData;
class LayoutObject; class LayoutObject;
class LayoutSVGResourceFilter; class LayoutSVGResourceFilter;
class LayoutSVGResourceMasker; class LayoutSVGResourceMasker;
...@@ -90,6 +91,7 @@ class ScopedSVGPaintState { ...@@ -90,6 +91,7 @@ class ScopedSVGPaintState {
paint_info_(paint_info), paint_info_(paint_info),
display_item_client_(display_item_client), display_item_client_(display_item_client),
filter_(nullptr), filter_(nullptr),
filter_data_(nullptr),
masker_(nullptr) {} masker_(nullptr) {}
~ScopedSVGPaintState(); ~ScopedSVGPaintState();
...@@ -119,6 +121,7 @@ class ScopedSVGPaintState { ...@@ -119,6 +121,7 @@ class ScopedSVGPaintState {
const DisplayItemClient& display_item_client_; const DisplayItemClient& display_item_client_;
std::unique_ptr<PaintInfo> filter_paint_info_; std::unique_ptr<PaintInfo> filter_paint_info_;
LayoutSVGResourceFilter* filter_; LayoutSVGResourceFilter* filter_;
FilterData* filter_data_;
LayoutSVGResourceMasker* masker_; LayoutSVGResourceMasker* masker_;
base::Optional<ClipPathClipper> clip_path_clipper_; base::Optional<ClipPathClipper> clip_path_clipper_;
std::unique_ptr<SVGFilterRecordingContext> filter_recording_context_; std::unique_ptr<SVGFilterRecordingContext> filter_recording_context_;
......
...@@ -46,12 +46,6 @@ sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent() { ...@@ -46,12 +46,6 @@ sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent() {
return content; return content;
} }
void SVGFilterRecordingContext::Abort() {
if (!paint_controller_)
return;
EndContent();
}
static void PaintFilteredContent(GraphicsContext& context, static void PaintFilteredContent(GraphicsContext& context,
const LayoutObject& object, const LayoutObject& object,
const DisplayItemClient& display_item_client, const DisplayItemClient& display_item_client,
...@@ -78,18 +72,14 @@ static void PaintFilteredContent(GraphicsContext& context, ...@@ -78,18 +72,14 @@ static void PaintFilteredContent(GraphicsContext& context,
context.Restore(); context.Restore();
} }
GraphicsContext* SVGFilterPainter::PrepareEffect( FilterData* SVGFilterPainter::PrepareEffect(const LayoutObject& object) {
const LayoutObject& object,
SVGFilterRecordingContext& recording_context) {
filter_.ClearInvalidationMask();
SVGElementResourceClient* client = SVGResources::GetClient(object); SVGElementResourceClient* client = SVGResources::GetClient(object);
if (FilterData* filter_data = client->GetFilterData()) { if (FilterData* filter_data = client->GetFilterData()) {
// If the filterData already exists we do not need to record the content // If the filterData already exists we do not need to record the content
// to be filtered. This can occur if the content was previously recorded // to be filtered. This can occur if the content was previously recorded
// or we are in a cycle. // or we are in a cycle.
filter_data->UpdateStateOnPrepare(); filter_data->UpdateStateOnPrepare();
return nullptr; return filter_data;
} }
auto* node_map = MakeGarbageCollected<SVGFilterGraphNodeMap>(); auto* node_map = MakeGarbageCollected<SVGFilterGraphNodeMap>();
...@@ -106,24 +96,15 @@ GraphicsContext* SVGFilterPainter::PrepareEffect( ...@@ -106,24 +96,15 @@ GraphicsContext* SVGFilterPainter::PrepareEffect(
MakeGarbageCollected<FilterData>(filter->LastEffect(), node_map); MakeGarbageCollected<FilterData>(filter->LastEffect(), node_map);
// TODO(pdr): Can this be moved out of painter? // TODO(pdr): Can this be moved out of painter?
client->SetFilterData(filter_data); client->SetFilterData(filter_data);
return recording_context.BeginContent(); return filter_data;
} }
void SVGFilterPainter::FinishEffect( void SVGFilterPainter::FinishEffect(
const LayoutObject& object, const LayoutObject& object,
const DisplayItemClient& display_item_client, const DisplayItemClient& display_item_client,
SVGFilterRecordingContext& recording_context) { SVGFilterRecordingContext& recording_context) {
SVGElementResourceClient* client = SVGResources::GetClient(object); FilterData* filter_data = SVGResources::GetClient(object)->GetFilterData();
FilterData* filter_data = client->GetFilterData(); DCHECK(filter_data);
if (!filter_data) {
// Our state was torn down while we were being painted (selection style for
// <text> can have this effect), or it was never created (invalid filter.)
// In the former case we may have been in the process of recording content,
// so make sure we put recording state into a consistent state.
recording_context.Abort();
return;
}
if (!filter_data->UpdateStateOnFinish()) if (!filter_data->UpdateStateOnFinish())
return; return;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
namespace blink { namespace blink {
class DisplayItemClient; class DisplayItemClient;
class FilterData;
class LayoutObject; class LayoutObject;
class LayoutSVGResourceFilter; class LayoutSVGResourceFilter;
...@@ -26,7 +27,6 @@ class SVGFilterRecordingContext { ...@@ -26,7 +27,6 @@ class SVGFilterRecordingContext {
GraphicsContext* BeginContent(); GraphicsContext* BeginContent();
sk_sp<PaintRecord> EndContent(); sk_sp<PaintRecord> EndContent();
void Abort();
GraphicsContext& PaintingContext() const { return initial_context_; } GraphicsContext& PaintingContext() const { return initial_context_; }
...@@ -43,10 +43,9 @@ class SVGFilterPainter { ...@@ -43,10 +43,9 @@ class SVGFilterPainter {
public: public:
SVGFilterPainter(LayoutSVGResourceFilter& filter) : filter_(filter) {} SVGFilterPainter(LayoutSVGResourceFilter& filter) : filter_(filter) {}
// Returns the context that should be used to paint the filter contents, or // Returns the FilterData for the filter effect, or null if the
// null if the content should not be recorded. // filter is invalid.
GraphicsContext* PrepareEffect(const LayoutObject&, FilterData* PrepareEffect(const LayoutObject&);
SVGFilterRecordingContext&);
void FinishEffect(const LayoutObject&, void FinishEffect(const LayoutObject&,
const DisplayItemClient&, const DisplayItemClient&,
SVGFilterRecordingContext&); SVGFilterRecordingContext&);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment