Commit 5c4646ad authored by Fredrik Söderqvist's avatar Fredrik Söderqvist Committed by Commit Bot

Only create SVGFilterRecordingContext when actually recording

Even if we don't need to record (new) content for the filter, we still
create a SVGFilterRecordingContext. Make this conditional on actually
needing to record content instead. This makes it possible to simplify
the setup and interface of said helper class.

Also move the filter-content PaintInfo to SVGFilterRecordingContext
since they are pretty tightly coupled anyway and now have the same
lifetime.

Bug: 109224
Change-Id: I6507d6666e270499e19b7ed279f95546c99594f5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106192Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#751750}
parent 538f2fe2
...@@ -62,15 +62,13 @@ ScopedSVGPaintState::~ScopedSVGPaintState() { ...@@ -62,15 +62,13 @@ ScopedSVGPaintState::~ScopedSVGPaintState() {
DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_)); DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_));
DCHECK( DCHECK(
SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter()); SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter());
DCHECK(filter_recording_context_); if (filter_recording_context_) {
filter_data_->UpdateContent(
if (filter_data_->ContentNeedsUpdate()) filter_recording_context_->GetPaintRecord(paint_info_));
filter_data_->UpdateContent(filter_recording_context_->EndContent()); filter_recording_context_ = nullptr;
}
PaintFilteredContent(paint_info_.context, object_, display_item_client_, PaintFilteredContent(paint_info_.context, object_, display_item_client_,
filter_data_); filter_data_);
// Reset the paint info after the filter effect has been completed.
filter_paint_info_ = nullptr;
filter_data_ = nullptr; filter_data_ = nullptr;
} }
} }
...@@ -172,8 +170,6 @@ bool ScopedSVGPaintState::ApplyFilterIfNecessary() { ...@@ -172,8 +170,6 @@ bool ScopedSVGPaintState::ApplyFilterIfNecessary() {
if (!filter) if (!filter)
return true; return true;
filter->ClearInvalidationMask(); filter->ClearInvalidationMask();
filter_recording_context_ =
std::make_unique<SVGFilterRecordingContext>(GetPaintInfo().context);
filter_data_ = SVGFilterPainter(*filter).PrepareEffect(object_); filter_data_ = SVGFilterPainter(*filter).PrepareEffect(object_);
// If we have no filter data (== the filter was invalid) or if we // If we have no filter data (== the filter was invalid) or if we
// don't need to update the source graphics, we can short-circuit // don't need to update the source graphics, we can short-circuit
...@@ -182,13 +178,8 @@ bool ScopedSVGPaintState::ApplyFilterIfNecessary() { ...@@ -182,13 +178,8 @@ bool ScopedSVGPaintState::ApplyFilterIfNecessary() {
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_recording_context_ =
filter_paint_info_ = std::make_unique<SVGFilterRecordingContext>(paint_info_);
std::make_unique<PaintInfo>(*filter_context, paint_info_);
// Because we cache the filter contents and do not invalidate on paint
// invalidation rect changes, we need to paint the entire filter region
// so elements outside the initial paint (due to scrolling, etc) paint.
filter_paint_info_->ApplyInfiniteCullRect();
return true; return true;
} }
......
...@@ -93,7 +93,8 @@ class ScopedSVGPaintState { ...@@ -93,7 +93,8 @@ class ScopedSVGPaintState {
~ScopedSVGPaintState(); ~ScopedSVGPaintState();
const PaintInfo& GetPaintInfo() const { const PaintInfo& GetPaintInfo() const {
return filter_paint_info_ ? *filter_paint_info_ : paint_info_; return filter_recording_context_ ? filter_recording_context_->GetPaintInfo()
: paint_info_;
} }
// Return true if these operations aren't necessary or if they are // Return true if these operations aren't necessary or if they are
...@@ -112,7 +113,6 @@ class ScopedSVGPaintState { ...@@ -112,7 +113,6 @@ class ScopedSVGPaintState {
const LayoutObject& object_; const LayoutObject& object_;
PaintInfo paint_info_; PaintInfo paint_info_;
const DisplayItemClient& display_item_client_; const DisplayItemClient& display_item_client_;
std::unique_ptr<PaintInfo> filter_paint_info_;
FilterData* filter_data_; FilterData* filter_data_;
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_;
......
...@@ -13,36 +13,37 @@ ...@@ -13,36 +13,37 @@
#include "third_party/blink/renderer/core/svg/svg_filter_element.h" #include "third_party/blink/renderer/core/svg/svg_filter_element.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h"
#include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h" #include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
namespace blink { namespace blink {
GraphicsContext* SVGFilterRecordingContext::BeginContent() { SVGFilterRecordingContext::SVGFilterRecordingContext(
// Create a new context so the contents of the filter can be drawn and cached. const PaintInfo& initial_paint_info)
paint_controller_ = std::make_unique<PaintController>(); // Create a new context so the contents of the filter can be drawn and
context_ = std::make_unique<GraphicsContext>(*paint_controller_); // cached.
: paint_controller_(std::make_unique<PaintController>()),
// Use initial_context_'s current paint chunk properties so that any new context_(std::make_unique<GraphicsContext>(*paint_controller_)),
paint_info_(*context_, initial_paint_info) {
// Use initial_paint_info's current paint chunk properties so that any new
// chunk created during painting the content will be in the correct state. // chunk created during painting the content will be in the correct state.
paint_controller_->UpdateCurrentPaintChunkProperties( paint_controller_->UpdateCurrentPaintChunkProperties(
nullptr, nullptr, initial_paint_info.context.GetPaintController()
initial_context_.GetPaintController().CurrentPaintChunkProperties()); .CurrentPaintChunkProperties());
// Because we cache the filter contents and do not invalidate on paint
return context_.get(); // invalidation rect changes, we need to paint the entire filter region so
// elements outside the initial paint (due to scrolling, etc) paint.
paint_info_.ApplyInfiniteCullRect();
} }
sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent() { SVGFilterRecordingContext::~SVGFilterRecordingContext() = default;
// Use the context that contains the filtered content.
DCHECK(paint_controller_);
DCHECK(context_);
paint_controller_->CommitNewDisplayItems();
sk_sp<PaintRecord> content =
paint_controller_->GetPaintArtifact().GetPaintRecord(
initial_context_.GetPaintController().CurrentPaintChunkProperties());
// Content is cached by the source graphic so temporaries can be freed. sk_sp<PaintRecord> SVGFilterRecordingContext::GetPaintRecord(
paint_controller_ = nullptr; const PaintInfo& initial_paint_info) {
context_ = nullptr; paint_controller_->CommitNewDisplayItems();
return content; return paint_controller_->GetPaintArtifact().GetPaintRecord(
initial_paint_info.context.GetPaintController()
.CurrentPaintChunkProperties());
} }
FilterData* SVGFilterPainter::PrepareEffect(const LayoutObject& object) { FilterData* SVGFilterPainter::PrepareEffect(const LayoutObject& object) {
......
...@@ -7,30 +7,31 @@ ...@@ -7,30 +7,31 @@
#include <memory> #include <memory>
#include "base/macros.h" #include "base/macros.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink { namespace blink {
class FilterData; class FilterData;
class GraphicsContext;
class LayoutObject; class LayoutObject;
class LayoutSVGResourceFilter; class LayoutSVGResourceFilter;
class PaintController;
class SVGFilterRecordingContext { class SVGFilterRecordingContext {
USING_FAST_MALLOC(SVGFilterRecordingContext); USING_FAST_MALLOC(SVGFilterRecordingContext);
public: public:
explicit SVGFilterRecordingContext(GraphicsContext& initial_context) explicit SVGFilterRecordingContext(const PaintInfo&);
: initial_context_(initial_context) {} ~SVGFilterRecordingContext();
GraphicsContext* BeginContent(); const PaintInfo& GetPaintInfo() const { return paint_info_; }
sk_sp<PaintRecord> EndContent(); sk_sp<PaintRecord> GetPaintRecord(const PaintInfo&);
private: private:
std::unique_ptr<PaintController> paint_controller_; std::unique_ptr<PaintController> paint_controller_;
std::unique_ptr<GraphicsContext> context_; std::unique_ptr<GraphicsContext> context_;
GraphicsContext& initial_context_; PaintInfo paint_info_;
DISALLOW_COPY_AND_ASSIGN(SVGFilterRecordingContext); DISALLOW_COPY_AND_ASSIGN(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