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() {
DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_));
DCHECK(
SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter());
DCHECK(filter_recording_context_);
if (filter_data_->ContentNeedsUpdate())
filter_data_->UpdateContent(filter_recording_context_->EndContent());
if (filter_recording_context_) {
filter_data_->UpdateContent(
filter_recording_context_->GetPaintRecord(paint_info_));
filter_recording_context_ = nullptr;
}
PaintFilteredContent(paint_info_.context, object_, display_item_client_,
filter_data_);
// Reset the paint info after the filter effect has been completed.
filter_paint_info_ = nullptr;
filter_data_ = nullptr;
}
}
......@@ -172,8 +170,6 @@ bool ScopedSVGPaintState::ApplyFilterIfNecessary() {
if (!filter)
return true;
filter->ClearInvalidationMask();
filter_recording_context_ =
std::make_unique<SVGFilterRecordingContext>(GetPaintInfo().context);
filter_data_ = SVGFilterPainter(*filter).PrepareEffect(object_);
// 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
......@@ -182,13 +178,8 @@ bool ScopedSVGPaintState::ApplyFilterIfNecessary() {
return false;
// Because the filter needs to cache its contents we replace the context
// during filtering with the filter's context.
GraphicsContext* filter_context = filter_recording_context_->BeginContent();
filter_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();
filter_recording_context_ =
std::make_unique<SVGFilterRecordingContext>(paint_info_);
return true;
}
......
......@@ -93,7 +93,8 @@ class ScopedSVGPaintState {
~ScopedSVGPaintState();
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
......@@ -112,7 +113,6 @@ class ScopedSVGPaintState {
const LayoutObject& object_;
PaintInfo paint_info_;
const DisplayItemClient& display_item_client_;
std::unique_ptr<PaintInfo> filter_paint_info_;
FilterData* filter_data_;
base::Optional<ClipPathClipper> clip_path_clipper_;
std::unique_ptr<SVGFilterRecordingContext> filter_recording_context_;
......
......@@ -13,36 +13,37 @@
#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/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 {
GraphicsContext* SVGFilterRecordingContext::BeginContent() {
// Create a new context so the contents of the filter can be drawn and cached.
paint_controller_ = std::make_unique<PaintController>();
context_ = std::make_unique<GraphicsContext>(*paint_controller_);
// Use initial_context_'s current paint chunk properties so that any new
SVGFilterRecordingContext::SVGFilterRecordingContext(
const PaintInfo& initial_paint_info)
// Create a new context so the contents of the filter can be drawn and
// cached.
: paint_controller_(std::make_unique<PaintController>()),
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.
paint_controller_->UpdateCurrentPaintChunkProperties(
nullptr,
initial_context_.GetPaintController().CurrentPaintChunkProperties());
return context_.get();
nullptr, initial_paint_info.context.GetPaintController()
.CurrentPaintChunkProperties());
// 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.
paint_info_.ApplyInfiniteCullRect();
}
sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent() {
// 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());
SVGFilterRecordingContext::~SVGFilterRecordingContext() = default;
// Content is cached by the source graphic so temporaries can be freed.
paint_controller_ = nullptr;
context_ = nullptr;
return content;
sk_sp<PaintRecord> SVGFilterRecordingContext::GetPaintRecord(
const PaintInfo& initial_paint_info) {
paint_controller_->CommitNewDisplayItems();
return paint_controller_->GetPaintArtifact().GetPaintRecord(
initial_paint_info.context.GetPaintController()
.CurrentPaintChunkProperties());
}
FilterData* SVGFilterPainter::PrepareEffect(const LayoutObject& object) {
......
......@@ -7,30 +7,31 @@
#include <memory>
#include "base/macros.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class FilterData;
class GraphicsContext;
class LayoutObject;
class LayoutSVGResourceFilter;
class PaintController;
class SVGFilterRecordingContext {
USING_FAST_MALLOC(SVGFilterRecordingContext);
public:
explicit SVGFilterRecordingContext(GraphicsContext& initial_context)
: initial_context_(initial_context) {}
explicit SVGFilterRecordingContext(const PaintInfo&);
~SVGFilterRecordingContext();
GraphicsContext* BeginContent();
sk_sp<PaintRecord> EndContent();
const PaintInfo& GetPaintInfo() const { return paint_info_; }
sk_sp<PaintRecord> GetPaintRecord(const PaintInfo&);
private:
std::unique_ptr<PaintController> paint_controller_;
std::unique_ptr<GraphicsContext> context_;
GraphicsContext& initial_context_;
PaintInfo paint_info_;
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