Commit 5b996fea authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Refactor LayoutSVGResourceGradient::PreparePaintServer

Split said method into two - one that does a cache lookup and one that
builds the GradientData.

Reorder the code a bit to eliminate the redundant check for an empty
object bounding box.

Bug: 109212
Change-Id: If9bdf1d771478d208debbdddf33188b5db28cf62
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2060956Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#742140}
parent aa56ee4b
...@@ -24,8 +24,18 @@ ...@@ -24,8 +24,18 @@
#include <memory> #include <memory>
#include "third_party/blink/renderer/platform/graphics/gradient.h"
namespace blink { namespace blink {
struct GradientData {
USING_FAST_MALLOC(GradientData);
public:
scoped_refptr<Gradient> gradient;
AffineTransform userspace_transform;
};
LayoutSVGResourceGradient::LayoutSVGResourceGradient(SVGGradientElement* node) LayoutSVGResourceGradient::LayoutSVGResourceGradient(SVGGradientElement* node)
: LayoutSVGResourcePaintServer(node), : LayoutSVGResourcePaintServer(node),
should_collect_gradient_attributes_(true), should_collect_gradient_attributes_(true),
...@@ -50,10 +60,10 @@ bool LayoutSVGResourceGradient::RemoveClientFromCache( ...@@ -50,10 +60,10 @@ bool LayoutSVGResourceGradient::RemoveClientFromCache(
return true; return true;
} }
SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer( std::unique_ptr<GradientData> LayoutSVGResourceGradient::BuildGradientData(
const SVGResourceClient& client,
const FloatRect& object_bounding_box) { const FloatRect& object_bounding_box) {
ClearInvalidationMask(); // Create gradient object
auto gradient_data = std::make_unique<GradientData>();
// Validate gradient DOM state before building the actual // Validate gradient DOM state before building the actual
// gradient. This should avoid tearing down the gradient we're // gradient. This should avoid tearing down the gradient we're
...@@ -61,39 +71,42 @@ SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer( ...@@ -61,39 +71,42 @@ SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer(
// no side-effects though. // no side-effects though.
if (should_collect_gradient_attributes_) { if (should_collect_gradient_attributes_) {
if (!CollectGradientAttributes()) if (!CollectGradientAttributes())
return SVGPaintServer::Invalid(); return gradient_data;
should_collect_gradient_attributes_ = false; should_collect_gradient_attributes_ = false;
} }
// Spec: When the geometry of the applicable element has no width or height // We want the text bounding box applied to the gradient space transform
// and objectBoundingBox is specified, then the given effect (e.g. a gradient // now, so the gradient shader can use it.
// or a filter) will be ignored. if (GradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox) {
if (GradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox && // Spec: When the geometry of the applicable element has no width or height
object_bounding_box.IsEmpty()) // and objectBoundingBox is specified, then the given effect (e.g. a
return SVGPaintServer::Invalid(); // gradient or a filter) will be ignored.
if (object_bounding_box.IsEmpty())
return gradient_data;
gradient_data->userspace_transform.Translate(object_bounding_box.X(),
object_bounding_box.Y());
gradient_data->userspace_transform.ScaleNonUniform(
object_bounding_box.Width(), object_bounding_box.Height());
}
// Create gradient object
gradient_data->gradient = BuildGradient();
AffineTransform gradient_transform = CalculateGradientTransform();
gradient_data->userspace_transform *= gradient_transform;
return gradient_data;
}
SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer(
const SVGResourceClient& client,
const FloatRect& object_bounding_box) {
ClearInvalidationMask();
std::unique_ptr<GradientData>& gradient_data = std::unique_ptr<GradientData>& gradient_data =
gradient_map_->insert(&client, nullptr).stored_value->value; gradient_map_->insert(&client, nullptr).stored_value->value;
if (!gradient_data) if (!gradient_data)
gradient_data = std::make_unique<GradientData>(); gradient_data = BuildGradientData(object_bounding_box);
// Create gradient object
if (!gradient_data->gradient) {
gradient_data->gradient = BuildGradient();
// We want the text bounding box applied to the gradient space transform
// now, so the gradient shader can use it.
if (GradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
!object_bounding_box.IsEmpty()) {
gradient_data->userspace_transform.Translate(object_bounding_box.X(),
object_bounding_box.Y());
gradient_data->userspace_transform.ScaleNonUniform(
object_bounding_box.Width(), object_bounding_box.Height());
}
AffineTransform gradient_transform = CalculateGradientTransform();
gradient_data->userspace_transform *= gradient_transform;
}
if (!gradient_data->gradient) if (!gradient_data->gradient)
return SVGPaintServer::Invalid(); return SVGPaintServer::Invalid();
......
...@@ -25,19 +25,12 @@ ...@@ -25,19 +25,12 @@
#include <memory> #include <memory>
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h"
#include "third_party/blink/renderer/core/svg/svg_gradient_element.h" #include "third_party/blink/renderer/core/svg/svg_gradient_element.h"
#include "third_party/blink/renderer/platform/graphics/gradient.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink { namespace blink {
struct GradientData { struct GradientData;
USING_FAST_MALLOC(GradientData);
public:
scoped_refptr<Gradient> gradient;
AffineTransform userspace_transform;
};
class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer { class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer {
public: public:
...@@ -61,6 +54,9 @@ class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer { ...@@ -61,6 +54,9 @@ class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer {
SVGSpreadMethodType); SVGSpreadMethodType);
private: private:
std::unique_ptr<GradientData> BuildGradientData(
const FloatRect& object_bounding_box);
bool should_collect_gradient_attributes_ : 1; bool should_collect_gradient_attributes_ : 1;
using GradientMap = HeapHashMap<Member<const SVGResourceClient>, using GradientMap = HeapHashMap<Member<const SVGResourceClient>,
std::unique_ptr<GradientData>>; std::unique_ptr<GradientData>>;
......
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