Commit 770c6456 authored by fmalita@chromium.org's avatar fmalita@chromium.org

[SVG] DisplayList-based patterns.

Instead of building an ImageBuffer tile (with all the ills of record
time rasterization), build a DisplayList tile and use Skia's
new SkPictureShader mechanism to fill/stroke the shape.

To facilitate this, Pattern is extended to support both bitmap and
picture shaders (the latter only in repeatXY mode -- the only mode
currently used by SVG).

Patterns (and their SkShaders) are cached per RenderSVGResourcePattern
per client. Internally, SkPictureShader also caches its rasterized tile
so there should be no performance degradation.

A handful of tests (about 9) require minor rebaselining (and a couple
have been updated for incorrect patternUnits).

R=pdr@chromium.org,schenney@chromium.org,fs@opera.com,ed@opera.com
BUG=401814,425278

Review URL: https://codereview.chromium.org/453653003

git-svn-id: svn://svn.chromium.org/blink/trunk@184271 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 2be03bf8
...@@ -826,6 +826,15 @@ crbug.com/350829 [ Win Debug ] virtual/threaded/animations/missing-keyframe-prop ...@@ -826,6 +826,15 @@ crbug.com/350829 [ Win Debug ] virtual/threaded/animations/missing-keyframe-prop
crbug.com/350829 [ Win Debug ] virtual/threaded/animations/duplicated-keyframes-name-unprefixed-03.html [ Timeout Pass ] crbug.com/350829 [ Win Debug ] virtual/threaded/animations/duplicated-keyframes-name-unprefixed-03.html [ Timeout Pass ]
crbug.com/350829 [ Win Debug ] virtual/threaded/animations/keyframes-unprefixed-03.html [ Timeout Pass ] crbug.com/350829 [ Win Debug ] virtual/threaded/animations/keyframes-unprefixed-03.html [ Timeout Pass ]
crbug.com/401814 svg/W3C-SVG-1.1/pservers-grad-06-b.svg [ NeedsRebaseline ]
crbug.com/401814 svg/custom/nested-pattern-boundingBoxModeContent.svg [ NeedsRebaseline ]
crbug.com/401814 svg/custom/non-scaling-stroke.svg [ NeedsRebaseline ]
crbug.com/401814 svg/custom/pattern-scaled-pattern-space.svg [ NeedsRebaseline ]
crbug.com/401814 svg/custom/pattern-skew-transformed.svg [ NeedsRebaseline ]
crbug.com/401814 svg/custom/pattern-with-transformation.svg [ NeedsRebaseline ]
crbug.com/401814 svg/transforms/text-with-pattern-inside-transformed-html.xhtml [ NeedsRebaseline ]
crbug.com/401814 svg/transforms/text-with-pattern-with-svg-transform.svg [ NeedsRebaseline ]
crbug.com/352377 svg/animations/repeatn-event-1c.svg [ ImageOnlyFailure Pass ] crbug.com/352377 svg/animations/repeatn-event-1c.svg [ ImageOnlyFailure Pass ]
crbug.com/352385 [ Debug ] virtual/threaded/animations/3d/transform-perspective.html [ Timeout Pass ] crbug.com/352385 [ Debug ] virtual/threaded/animations/3d/transform-perspective.html [ Timeout Pass ]
crbug.com/352705 [ Win Debug ] virtual/threaded/animations/sample-on-last-keyframe.html [ Timeout Pass ] crbug.com/352705 [ Win Debug ] virtual/threaded/animations/sample-on-last-keyframe.html [ Timeout Pass ]
......
/* /*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved. * Copyright (C) Research In Motion Limited 2010. All rights reserved.
* Copyright 2014 The Chromium Authors. All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
...@@ -23,24 +24,18 @@ ...@@ -23,24 +24,18 @@
#include "core/rendering/svg/RenderSVGResourceContainer.h" #include "core/rendering/svg/RenderSVGResourceContainer.h"
#include "core/svg/PatternAttributes.h" #include "core/svg/PatternAttributes.h"
#include "core/svg/SVGPatternElement.h"
#include "core/svg/SVGUnitTypes.h"
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/Pattern.h"
#include "platform/transforms/AffineTransform.h"
#include "wtf/HashMap.h" #include "wtf/HashMap.h"
#include "wtf/OwnPtr.h" #include "wtf/OwnPtr.h"
#include "wtf/RefPtr.h"
namespace blink { namespace blink {
struct PatternData { class AffineTransform;
WTF_MAKE_FAST_ALLOCATED; class DisplayList;
public: class FloatRect;
RefPtr<Pattern> pattern; class SVGPatternElement;
AffineTransform transform; struct PatternData;
};
class RenderSVGResourcePattern final : public RenderSVGResourceContainer { class RenderSVGResourcePattern final : public RenderSVGResourceContainer {
public: public:
...@@ -57,15 +52,19 @@ public: ...@@ -57,15 +52,19 @@ public:
static const RenderSVGResourceType s_resourceType; static const RenderSVGResourceType s_resourceType;
private: private:
bool buildTileImageTransform(const RenderObject&, const PatternAttributes&, const SVGPatternElement*, FloatRect& patternBoundaries, AffineTransform& tileImageTransform) const; PassOwnPtr<PatternData> buildPatternData(const RenderObject&);
PassRefPtr<DisplayList> asDisplayList(const FloatRect& tileBounds, const AffineTransform&) const;
PassOwnPtr<ImageBuffer> createTileImage(const PatternAttributes&, const FloatRect& tileBoundaries, PatternData* patternForRenderer(const RenderObject&);
const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform) const;
PatternData* buildPattern(const RenderObject&, const SVGPatternElement*);
bool m_shouldCollectPatternAttributes : 1; bool m_shouldCollectPatternAttributes : 1;
PatternAttributes m_attributes; PatternAttributes m_attributes;
// FIXME: we can almost do away with this per-object map, but not quite: the tile size can be
// relative to the client bounding box, and it gets captured in the cached Pattern shader.
// Hence, we need one Pattern shader per client. The display list OTOH is the same => we
// should be able to cache a single display list per RenderSVGResourcePattern + one
// Pattern(shader) for each client -- this would avoid re-recording when multiple clients
// share the same pattern.
HashMap<const RenderObject*, OwnPtr<PatternData> > m_patternMap; HashMap<const RenderObject*, OwnPtr<PatternData> > m_patternMap;
}; };
......
...@@ -37,8 +37,6 @@ ...@@ -37,8 +37,6 @@
#include "core/rendering/svg/SVGResourcesCache.h" #include "core/rendering/svg/SVGResourcesCache.h"
#include "platform/FloatConversion.h" #include "platform/FloatConversion.h"
static int kMaxImageBufferSize = 4096;
namespace blink { namespace blink {
SVGRenderingContext::~SVGRenderingContext() SVGRenderingContext::~SVGRenderingContext()
...@@ -254,20 +252,6 @@ void SVGRenderingContext::renderSubtree(GraphicsContext* context, RenderObject* ...@@ -254,20 +252,6 @@ void SVGRenderingContext::renderSubtree(GraphicsContext* context, RenderObject*
item->paint(info, IntPoint()); item->paint(info, IntPoint());
} }
FloatRect SVGRenderingContext::clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect)
{
const FloatSize maxImageBufferSize(kMaxImageBufferSize, kMaxImageBufferSize);
return FloatRect(absoluteTargetRect.location(), absoluteTargetRect.size().shrunkTo(maxImageBufferSize));
}
void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
{
AffineTransform::DecomposedType decomposition;
transform.decompose(decomposition);
decomposition.angle = 0;
transform.recompose(decomposition);
}
bool SVGRenderingContext::bufferForeground(OwnPtr<ImageBuffer>& imageBuffer) bool SVGRenderingContext::bufferForeground(OwnPtr<ImageBuffer>& imageBuffer)
{ {
ASSERT(m_paintInfo); ASSERT(m_paintInfo);
......
...@@ -86,8 +86,6 @@ public: ...@@ -86,8 +86,6 @@ public:
static float calculateScreenFontSizeScalingFactor(const RenderObject*); static float calculateScreenFontSizeScalingFactor(const RenderObject*);
static void calculateDeviceSpaceTransformation(const RenderObject*, AffineTransform& absoluteTransform); static void calculateDeviceSpaceTransformation(const RenderObject*, AffineTransform& absoluteTransform);
static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
static void clear2DRotation(AffineTransform&);
// Support for the buffered-rendering hint. // Support for the buffered-rendering hint.
bool bufferForeground(OwnPtr<ImageBuffer>&); bool bufferForeground(OwnPtr<ImageBuffer>&);
......
...@@ -559,6 +559,8 @@ ...@@ -559,6 +559,8 @@
'graphics/DeferredImageDecoder.cpp', 'graphics/DeferredImageDecoder.cpp',
'graphics/DeferredImageDecoder.h', 'graphics/DeferredImageDecoder.h',
'graphics/DisplayList.h', 'graphics/DisplayList.h',
'graphics/DisplayListPattern.cpp',
'graphics/DisplayListPattern.h',
'graphics/DrawLooperBuilder.cpp', 'graphics/DrawLooperBuilder.cpp',
'graphics/DrawLooperBuilder.h', 'graphics/DrawLooperBuilder.h',
'graphics/FirstPaintInvalidationTracking.cpp', 'graphics/FirstPaintInvalidationTracking.cpp',
......
...@@ -18,9 +18,9 @@ public: ...@@ -18,9 +18,9 @@ public:
virtual ~BitmapPattern() { } virtual ~BitmapPattern() { }
protected:
virtual PassRefPtr<SkShader> createShader() override; virtual PassRefPtr<SkShader> createShader() override;
protected:
virtual SkImageInfo getBitmapInfo() override; virtual SkImageInfo getBitmapInfo() override;
virtual void drawBitmapToCanvas(SkCanvas&, SkPaint&) override; virtual void drawBitmapToCanvas(SkCanvas&, SkPaint&) override;
......
...@@ -14,9 +14,9 @@ public: ...@@ -14,9 +14,9 @@ public:
BitmapPatternBase(RepeatMode, int64_t externalMemoryAllocated = 0); BitmapPatternBase(RepeatMode, int64_t externalMemoryAllocated = 0);
virtual ~BitmapPatternBase(); virtual ~BitmapPatternBase();
protected:
virtual PassRefPtr<SkShader> createShader() override; virtual PassRefPtr<SkShader> createShader() override;
protected:
virtual SkImageInfo getBitmapInfo() = 0; virtual SkImageInfo getBitmapInfo() = 0;
virtual void drawBitmapToCanvas(SkCanvas&, SkPaint&) = 0; virtual void drawBitmapToCanvas(SkCanvas&, SkPaint&) = 0;
}; };
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "platform/graphics/DisplayListPattern.h"
#include "platform/graphics/DisplayList.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "third_party/skia/include/core/SkShader.h"
namespace blink {
DisplayListPattern::DisplayListPattern(PassRefPtr<DisplayList> displayList, RepeatMode mode)
: Pattern(mode)
, m_tileDisplayList(displayList)
{
// All current clients use RepeatModeXY, so we only support this mode for now.
ASSERT(isRepeatXY());
// FIXME: we don't have a good way to account for DL memory utilization.
}
DisplayListPattern::~DisplayListPattern()
{
}
PassRefPtr<SkShader> DisplayListPattern::createShader()
{
SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation);
SkRect tileBounds = SkRect::MakeWH(m_tileDisplayList->bounds().width(),
m_tileDisplayList->bounds().height());
return adoptRef(SkShader::CreatePictureShader(m_tileDisplayList->picture(),
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix, &tileBounds));
}
} // namespace
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DisplayListPattern_h
#define DisplayListPattern_h
#include "platform/graphics/Pattern.h"
namespace blink {
class DisplayList;
class PLATFORM_EXPORT DisplayListPattern : public Pattern {
public:
static PassRefPtr<DisplayListPattern> create(PassRefPtr<DisplayList> displayList,
RepeatMode repeatMode)
{
return adoptRef(new DisplayListPattern(displayList, repeatMode));
}
virtual ~DisplayListPattern();
protected:
virtual PassRefPtr<SkShader> createShader() override;
private:
DisplayListPattern(PassRefPtr<DisplayList>, RepeatMode);
RefPtr<DisplayList> m_tileDisplayList;
};
} // namespace
#endif
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include "platform/graphics/Pattern.h" #include "platform/graphics/Pattern.h"
#include "platform/graphics/BitmapPattern.h" #include "platform/graphics/BitmapPattern.h"
#include "platform/graphics/DisplayList.h"
#include "platform/graphics/DisplayListPattern.h"
#include "platform/graphics/StaticBitmapPattern.h" #include "platform/graphics/StaticBitmapPattern.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/core/SkShader.h"
...@@ -44,6 +46,12 @@ PassRefPtr<Pattern> Pattern::createBitmapPattern(PassRefPtr<Image> tileImage, Re ...@@ -44,6 +46,12 @@ PassRefPtr<Pattern> Pattern::createBitmapPattern(PassRefPtr<Image> tileImage, Re
return BitmapPattern::create(tileImage, repeatMode); return BitmapPattern::create(tileImage, repeatMode);
} }
PassRefPtr<Pattern> Pattern::createDisplayListPattern(PassRefPtr<DisplayList> displayList,
RepeatMode repeatMode)
{
return DisplayListPattern::create(displayList, repeatMode);
}
Pattern::Pattern(RepeatMode repeatMode, int64_t externalMemoryAllocated) Pattern::Pattern(RepeatMode repeatMode, int64_t externalMemoryAllocated)
: m_repeatMode(repeatMode) : m_repeatMode(repeatMode)
, m_externalMemoryAllocated(0) , m_externalMemoryAllocated(0)
......
...@@ -41,6 +41,8 @@ class SkShader; ...@@ -41,6 +41,8 @@ class SkShader;
namespace blink { namespace blink {
class DisplayList;
class PLATFORM_EXPORT Pattern : public RefCounted<Pattern> { class PLATFORM_EXPORT Pattern : public RefCounted<Pattern> {
public: public:
enum RepeatMode { enum RepeatMode {
...@@ -53,6 +55,8 @@ public: ...@@ -53,6 +55,8 @@ public:
static PassRefPtr<Pattern> createBitmapPattern(PassRefPtr<Image> tileImage, static PassRefPtr<Pattern> createBitmapPattern(PassRefPtr<Image> tileImage,
RepeatMode = RepeatModeXY); RepeatMode = RepeatModeXY);
static PassRefPtr<Pattern> createDisplayListPattern(PassRefPtr<DisplayList>,
RepeatMode = RepeatModeXY);
virtual ~Pattern(); virtual ~Pattern();
SkShader* shader(); SkShader* shader();
......
...@@ -15,9 +15,9 @@ public: ...@@ -15,9 +15,9 @@ public:
virtual ~StaticBitmapPattern(); virtual ~StaticBitmapPattern();
protected:
virtual PassRefPtr<SkShader> createShader() override; virtual PassRefPtr<SkShader> createShader() override;
protected:
virtual SkImageInfo getBitmapInfo() override; virtual SkImageInfo getBitmapInfo() override;
virtual void drawBitmapToCanvas(SkCanvas&, SkPaint&) override; virtual void drawBitmapToCanvas(SkCanvas&, SkPaint&) override;
......
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