Commit 12c97dea authored by schenney@chromium.org's avatar schenney@chromium.org

Modifications to DisplayList for better Slimming Paint

Add clipping.
Add transform.
Change recording to be driven by GraphicsContext.
Update dependent code.
Move a method used only by SVGFEImage from AffineTransform to SVGFEImage

R=pdr,senorblanco
BUG=410019

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

git-svn-id: svn://svn.chromium.org/blink/trunk@181502 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent bc325ac0
...@@ -245,13 +245,13 @@ void RenderSVGResourceClipper::drawClipMaskContent(GraphicsContext* context, con ...@@ -245,13 +245,13 @@ void RenderSVGResourceClipper::drawClipMaskContent(GraphicsContext* context, con
} }
if (!m_clipContentDisplayList) if (!m_clipContentDisplayList)
m_clipContentDisplayList = asDisplayList(context, contentTransformation); createDisplayList(context, contentTransformation);
ASSERT(m_clipContentDisplayList); ASSERT(m_clipContentDisplayList);
context->drawDisplayList(m_clipContentDisplayList.get()); context->drawDisplayList(m_clipContentDisplayList.get());
} }
PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext* context, void RenderSVGResourceClipper::createDisplayList(GraphicsContext* context,
const AffineTransform& contentTransformation) const AffineTransform& contentTransformation)
{ {
ASSERT(context); ASSERT(context);
...@@ -260,7 +260,8 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext* ...@@ -260,7 +260,8 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
// Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection
// with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and
// userSpaceOnUse units (http://crbug.com/294900). // userSpaceOnUse units (http://crbug.com/294900).
context->beginRecording(strokeBoundingBox()); FloatRect bounds = strokeBoundingBox();
context->beginRecording(bounds);
// Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints: // Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints:
// - fill-opacity/stroke-opacity/opacity set to 1 // - fill-opacity/stroke-opacity/opacity set to 1
...@@ -304,7 +305,7 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext* ...@@ -304,7 +305,7 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
frame()->view()->setPaintBehavior(oldBehavior); frame()->view()->setPaintBehavior(oldBehavior);
return context->endRecording(); m_clipContentDisplayList = context->endRecording();
} }
void RenderSVGResourceClipper::calculateClipContentPaintInvalidationRect() void RenderSVGResourceClipper::calculateClipContentPaintInvalidationRect()
......
...@@ -76,7 +76,7 @@ public: ...@@ -76,7 +76,7 @@ public:
private: private:
bool tryPathOnlyClipping(GraphicsContext*, const AffineTransform&, const FloatRect&); bool tryPathOnlyClipping(GraphicsContext*, const AffineTransform&, const FloatRect&);
void drawClipMaskContent(GraphicsContext*, const FloatRect& targetBoundingBox); void drawClipMaskContent(GraphicsContext*, const FloatRect& targetBoundingBox);
PassRefPtr<DisplayList> asDisplayList(GraphicsContext*, const AffineTransform&); void createDisplayList(GraphicsContext*, const AffineTransform&);
void calculateClipContentPaintInvalidationRect(); void calculateClipContentPaintInvalidationRect();
RefPtr<DisplayList> m_clipContentDisplayList; RefPtr<DisplayList> m_clipContentDisplayList;
......
...@@ -144,6 +144,7 @@ static bool createImageBuffer(const Filter* filter, OwnPtr<ImageBuffer>& imageBu ...@@ -144,6 +144,7 @@ static bool createImageBuffer(const Filter* filter, OwnPtr<ImageBuffer>& imageBu
static void beginDeferredFilter(GraphicsContext* context, FilterData* filterData) static void beginDeferredFilter(GraphicsContext* context, FilterData* filterData)
{ {
context->beginRecording(filterData->boundaries); context->beginRecording(filterData->boundaries);
// We pass the boundaries to SkPictureImageFilter so it knows the // We pass the boundaries to SkPictureImageFilter so it knows the
// world-space position of the filter primitives. It gets them // world-space position of the filter primitives. It gets them
// from the DisplayList, which also applies the inverse translate // from the DisplayList, which also applies the inverse translate
......
...@@ -122,12 +122,12 @@ void RenderSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, cons ...@@ -122,12 +122,12 @@ void RenderSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, cons
} }
if (!m_maskContentDisplayList) if (!m_maskContentDisplayList)
m_maskContentDisplayList = asDisplayList(context, contentTransformation); createDisplayList(context, contentTransformation);
ASSERT(m_maskContentDisplayList); ASSERT(m_maskContentDisplayList);
context->drawDisplayList(m_maskContentDisplayList.get()); context->drawDisplayList(m_maskContentDisplayList.get());
} }
PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext* context, void RenderSVGResourceMasker::createDisplayList(GraphicsContext* context,
const AffineTransform& contentTransform) const AffineTransform& contentTransform)
{ {
ASSERT(context); ASSERT(context);
...@@ -135,7 +135,8 @@ PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext* ...@@ -135,7 +135,8 @@ PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext*
// Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection
// with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and
// userSpaceOnUse units (http://crbug.com/294900). // userSpaceOnUse units (http://crbug.com/294900).
context->beginRecording(strokeBoundingBox()); FloatRect bounds = strokeBoundingBox();
context->beginRecording(bounds);
for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) { for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
RenderObject* renderer = childElement->renderer(); RenderObject* renderer = childElement->renderer();
if (!renderer) if (!renderer)
...@@ -146,8 +147,7 @@ PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext* ...@@ -146,8 +147,7 @@ PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext*
SVGRenderingContext::renderSubtree(context, renderer, contentTransform); SVGRenderingContext::renderSubtree(context, renderer, contentTransform);
} }
m_maskContentDisplayList = context->endRecording();
return context->endRecording();
} }
void RenderSVGResourceMasker::calculateMaskContentPaintInvalidationRect() void RenderSVGResourceMasker::calculateMaskContentPaintInvalidationRect()
......
...@@ -57,7 +57,7 @@ public: ...@@ -57,7 +57,7 @@ public:
private: private:
void calculateMaskContentPaintInvalidationRect(); void calculateMaskContentPaintInvalidationRect();
void drawMaskForRenderer(GraphicsContext*, const FloatRect& targetBoundingBox); void drawMaskForRenderer(GraphicsContext*, const FloatRect& targetBoundingBox);
PassRefPtr<DisplayList> asDisplayList(GraphicsContext*, const AffineTransform&); void createDisplayList(GraphicsContext*, const AffineTransform&);
RefPtr<DisplayList> m_maskContentDisplayList; RefPtr<DisplayList> m_maskContentDisplayList;
FloatRect m_maskContentBoundaries; FloatRect m_maskContentBoundaries;
......
...@@ -72,6 +72,14 @@ static FloatRect getRendererRepaintRect(RenderObject* renderer) ...@@ -72,6 +72,14 @@ static FloatRect getRendererRepaintRect(RenderObject* renderer)
renderer->paintInvalidationRectInLocalCoordinates()); renderer->paintInvalidationRectInLocalCoordinates());
} }
AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest)
{
AffineTransform transform;
transform.translate(dest.x() - source.x(), dest.y() - source.y());
transform.scale(dest.width() / source.width(), dest.height() / source.height());
return transform;
}
FloatRect FEImage::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) FloatRect FEImage::determineAbsolutePaintRect(const FloatRect& originalRequestedRect)
{ {
RenderObject* renderer = referencedRenderer(); RenderObject* renderer = referencedRenderer();
...@@ -203,8 +211,9 @@ PassRefPtr<SkImageFilter> FEImage::createImageFilterForRenderer(RenderObject* re ...@@ -203,8 +211,9 @@ PassRefPtr<SkImageFilter> FEImage::createImageFilterForRenderer(RenderObject* re
if (!context) if (!context)
return adoptRef(SkBitmapSource::Create(SkBitmap())); return adoptRef(SkBitmapSource::Create(SkBitmap()));
AffineTransform contentTransformation; AffineTransform contentTransformation;
FloatRect bounds(FloatPoint(), dstRect.size());
context->save(); context->save();
context->beginRecording(FloatRect(FloatPoint(), dstRect.size())); context->beginRecording(bounds);
context->concatCTM(transform); context->concatCTM(transform);
SVGRenderingContext::renderSubtree(context, renderer, contentTransformation); SVGRenderingContext::renderSubtree(context, renderer, contentTransformation);
RefPtr<DisplayList> displayList = context->endRecording(); RefPtr<DisplayList> displayList = context->endRecording();
......
...@@ -567,7 +567,6 @@ ...@@ -567,7 +567,6 @@
'graphics/DecodingImageGenerator.h', 'graphics/DecodingImageGenerator.h',
'graphics/DeferredImageDecoder.cpp', 'graphics/DeferredImageDecoder.cpp',
'graphics/DeferredImageDecoder.h', 'graphics/DeferredImageDecoder.h',
'graphics/DisplayList.cpp',
'graphics/DisplayList.h', 'graphics/DisplayList.h',
'graphics/DrawLooperBuilder.cpp', 'graphics/DrawLooperBuilder.cpp',
'graphics/DrawLooperBuilder.h', 'graphics/DrawLooperBuilder.h',
......
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "platform/graphics/DisplayList.h"
#include "platform/geometry/IntSize.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "wtf/PassOwnPtr.h"
namespace blink {
DisplayList::DisplayList(const FloatRect& bounds)
: m_bounds(bounds)
{
}
DisplayList::~DisplayList()
{
}
const FloatRect& DisplayList::bounds() const
{
return m_bounds;
}
SkPicture* DisplayList::picture() const
{
return m_picture.get();
}
SkCanvas* DisplayList::beginRecording(const IntSize& size, uint32_t recordFlags)
{
m_picture.clear();
if (!m_recorder)
m_recorder = adoptPtr(new SkPictureRecorder);
return m_recorder->beginRecording(size.width(), size.height(), 0, recordFlags);
}
void DisplayList::endRecording()
{
if (m_recorder) {
m_picture = adoptRef(m_recorder->endRecording());
m_recorder.clear();
}
}
} // namespace blink
...@@ -32,15 +32,13 @@ ...@@ -32,15 +32,13 @@
#define DisplayList_h #define DisplayList_h
#include "platform/geometry/FloatRect.h" #include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntRect.h"
#include "platform/geometry/LayoutPoint.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "wtf/FastAllocBase.h" #include "wtf/FastAllocBase.h"
#include "wtf/RefCounted.h" #include "wtf/RefCounted.h"
#include "wtf/RefPtr.h" #include "wtf/RefPtr.h"
class SkCanvas;
class SkPicture;
class SkPictureRecorder;
namespace blink { namespace blink {
class IntSize; class IntSize;
...@@ -49,25 +47,50 @@ class PLATFORM_EXPORT DisplayList FINAL : public WTF::RefCounted<DisplayList> { ...@@ -49,25 +47,50 @@ class PLATFORM_EXPORT DisplayList FINAL : public WTF::RefCounted<DisplayList> {
WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(DisplayList); WTF_MAKE_NONCOPYABLE(DisplayList);
public: public:
DisplayList(const FloatRect&); static PassRefPtr<DisplayList> create(const FloatRect& bounds)
~DisplayList(); {
return adoptRef(new DisplayList(bounds));
}
virtual ~DisplayList() { }
const FloatRect& bounds() const; const FloatRect& bounds() const { return m_bounds; }
// This entry point will return 0 when the DisplayList is in the // This entry point will return 0 when the DisplayList is in the
// midst of recording (i.e., between a beginRecording/endRecording pair) // midst of recording (i.e., between a beginRecording/endRecording pair)
// and if no recording has ever been completed. Otherwise it will return // and if no recording has ever been completed. Otherwise it will return
// the picture created by the last endRecording call. // the picture created by the last endRecording call.
SkPicture* picture() const; SkPicture* picture() const { return m_picture.get(); }
void setPicture(SkPicture* picture) { m_picture = adoptRef(picture); }
SkCanvas* beginRecording(const IntSize&, uint32_t recordFlags = 0); // FIXME: Need unit testing of these methods and their effect
bool isRecording() const { return m_recorder; } const SkMatrix& transform() const { return m_transform; }
void endRecording(); void setTransform(const SkMatrix& transform) { m_transform = transform; }
void setTransformFromPaintOffset(const LayoutPoint& paintOffset)
{
SkMatrix m;
m.setTranslate(paintOffset.x().toFloat(), paintOffset.y().toFloat());
setTransform(m);
}
void clearTransform() { m_transform.reset(); }
// FIXME: Need unit testing of these methods and their effect
const SkRect& clip() const { return m_clip; }
void setClip(const IntRect& rect) { m_clip = rect; }
void setClip(const FloatRect& rect) { m_clip = rect; }
void clearClip() { m_clip.setEmpty(); }
private: private:
DisplayList(const FloatRect& bounds) : m_bounds(bounds)
{
clearTransform();
clearClip();
}
FloatRect m_bounds; FloatRect m_bounds;
SkMatrix m_transform;
SkRect m_clip; // TODO: Do we need to support other types of clips here?
RefPtr<SkPicture> m_picture; RefPtr<SkPicture> m_picture;
OwnPtr<SkPictureRecorder> m_recorder;
}; };
} // namespace blink } // namespace blink
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkDevice.h"
#include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkRRect.h" #include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
...@@ -99,15 +100,17 @@ struct GraphicsContext::CanvasSaveState { ...@@ -99,15 +100,17 @@ struct GraphicsContext::CanvasSaveState {
}; };
struct GraphicsContext::RecordingState { struct GraphicsContext::RecordingState {
RecordingState(SkCanvas* currentCanvas, const SkMatrix& currentMatrix, PassRefPtr<DisplayList> displayList) RecordingState(SkPictureRecorder* recorder, SkCanvas* currentCanvas, const SkMatrix& currentMatrix, PassRefPtr<DisplayList> displayList)
: m_savedCanvas(currentCanvas) : m_displayList(displayList)
, m_displayList(displayList) , m_recorder(recorder)
, m_savedMatrix(currentMatrix) , m_savedCanvas(currentCanvas)
{ , m_savedMatrix(currentMatrix) { }
}
~RecordingState() { }
SkCanvas* m_savedCanvas;
RefPtr<DisplayList> m_displayList; RefPtr<DisplayList> m_displayList;
SkPictureRecorder* m_recorder;
SkCanvas* m_savedCanvas;
const SkMatrix m_savedMatrix; const SkMatrix m_savedMatrix;
}; };
...@@ -492,16 +495,20 @@ void GraphicsContext::endLayer() ...@@ -492,16 +495,20 @@ void GraphicsContext::endLayer()
#endif #endif
} }
void GraphicsContext::beginRecording(const FloatRect& bounds) void GraphicsContext::beginRecording(const FloatRect& bounds, uint32_t recordFlags)
{ {
RefPtr<DisplayList> displayList = adoptRef(new DisplayList(bounds)); RefPtr<DisplayList> displayList = DisplayList::create(bounds);
SkPictureRecorder* recorder = 0;
SkCanvas* savedCanvas = m_canvas; SkCanvas* savedCanvas = m_canvas;
SkMatrix savedMatrix = getTotalMatrix(); SkMatrix savedMatrix = getTotalMatrix();
if (!contextDisabled()) { if (!contextDisabled()) {
IntRect recordingRect = enclosingIntRect(bounds); FloatRect bounds = displayList->bounds();
m_canvas = displayList->beginRecording(recordingRect.size()); IntSize recordingSize = enclosingIntRect(bounds).size();
recorder = new SkPictureRecorder;
m_canvas = recorder->beginRecording(recordingSize.width(), recordingSize.height(), 0, recordFlags);
// We want the bounds offset mapped to (0, 0), such that the display list content // We want the bounds offset mapped to (0, 0), such that the display list content
// is fully contained within the SkPictureRecord's bounds. // is fully contained within the SkPictureRecord's bounds.
...@@ -512,7 +519,7 @@ void GraphicsContext::beginRecording(const FloatRect& bounds) ...@@ -512,7 +519,7 @@ void GraphicsContext::beginRecording(const FloatRect& bounds)
} }
} }
m_recordingStateStack.append(RecordingState(savedCanvas, savedMatrix, displayList)); m_recordingStateStack.append(RecordingState(recorder, savedCanvas, savedMatrix, displayList));
} }
PassRefPtr<DisplayList> GraphicsContext::endRecording() PassRefPtr<DisplayList> GraphicsContext::endRecording()
...@@ -520,15 +527,14 @@ PassRefPtr<DisplayList> GraphicsContext::endRecording() ...@@ -520,15 +527,14 @@ PassRefPtr<DisplayList> GraphicsContext::endRecording()
ASSERT(!m_recordingStateStack.isEmpty()); ASSERT(!m_recordingStateStack.isEmpty());
RecordingState recording = m_recordingStateStack.last(); RecordingState recording = m_recordingStateStack.last();
if (!contextDisabled()) { if (!contextDisabled())
ASSERT(recording.m_displayList->isRecording()); recording.m_displayList->setPicture(recording.m_recorder->endRecording());
recording.m_displayList->endRecording();
}
m_recordingStateStack.removeLast();
m_canvas = recording.m_savedCanvas; m_canvas = recording.m_savedCanvas;
delete recording.m_recorder;
m_recordingStateStack.removeLast();
return recording.m_displayList.release(); return recording.m_displayList;
} }
bool GraphicsContext::isRecording() const bool GraphicsContext::isRecording() const
...@@ -539,21 +545,33 @@ bool GraphicsContext::isRecording() const ...@@ -539,21 +545,33 @@ bool GraphicsContext::isRecording() const
void GraphicsContext::drawDisplayList(DisplayList* displayList) void GraphicsContext::drawDisplayList(DisplayList* displayList)
{ {
ASSERT(displayList); ASSERT(displayList);
ASSERT(!displayList->isRecording());
if (contextDisabled() || displayList->bounds().isEmpty()) if (contextDisabled() || displayList->bounds().isEmpty())
return; return;
bool performClip = !displayList->clip().isEmpty();
bool performTransform = !displayList->transform().isIdentity();
if (performClip || performTransform) {
save();
if (performTransform)
concat(displayList->transform());
if (performClip)
clipRect(displayList->clip());
}
realizeCanvasSave(); realizeCanvasSave();
const FloatRect& bounds = displayList->bounds(); const FloatPoint& location = displayList->bounds().location();
if (bounds.x() || bounds.y()) { if (location.x() || location.y()) {
SkMatrix m; SkMatrix m;
m.setTranslate(bounds.x(), bounds.y()); m.setTranslate(location.x(), location.y());
m_canvas->drawPicture(displayList->picture(), &m, 0); m_canvas->drawPicture(displayList->picture(), &m, 0);
} else { } else {
m_canvas->drawPicture(displayList->picture()); m_canvas->drawPicture(displayList->picture());
} }
if (performClip || performTransform)
restore();
} }
void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias) void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
......
...@@ -310,10 +310,15 @@ public: ...@@ -310,10 +310,15 @@ public:
void clip(const FloatRect& rect) { clipRect(rect); } void clip(const FloatRect& rect) { clipRect(rect); }
void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op); void clipRoundedRect(const RoundedRect&, SkRegion::Op = SkRegion::kIntersect_Op);
void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); } void clipOut(const IntRect& rect) { clipRect(rect, NotAntiAliased, SkRegion::kDifference_Op); }
void clipOut(const Path&);
void clipOutRoundedRect(const RoundedRect&); void clipOutRoundedRect(const RoundedRect&);
void clipPath(const Path&, WindRule = RULE_EVENODD); void clipPath(const Path&, WindRule = RULE_EVENODD);
void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true); void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true);
void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op); void clipRect(const SkRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
// This clip function is used only by <canvas> code. It allows
// implementations to handle clipping on the canvas differently since
// the discipline is different.
void canvasClip(const Path&, WindRule = RULE_EVENODD);
void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&); void drawText(const Font&, const TextRunPaintInfo&, const FloatPoint&);
void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&); void drawEmphasisMarks(const Font&, const TextRunPaintInfo&, const AtomicString& mark, const FloatPoint&);
...@@ -335,8 +340,9 @@ public: ...@@ -335,8 +340,9 @@ public:
void endCull(); void endCull();
// Instead of being dispatched to the active canvas, draw commands following beginRecording() // Instead of being dispatched to the active canvas, draw commands following beginRecording()
// are stored in a display list that can be replayed at a later time. // are stored in a display list that can be replayed at a later time. Pass in the bounding
void beginRecording(const FloatRect& bounds); // rectangle for the content in the list.
void beginRecording(const FloatRect&, uint32_t = 0);
PassRefPtr<DisplayList> endRecording(); PassRefPtr<DisplayList> endRecording();
bool hasShadow() const; bool hasShadow() const;
...@@ -364,12 +370,6 @@ public: ...@@ -364,12 +370,6 @@ public:
typedef unsigned Edges; typedef unsigned Edges;
void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge); void drawInnerShadow(const RoundedRect&, const Color& shadowColor, const IntSize shadowOffset, int shadowBlur, int shadowSpread, Edges clippedEdges = NoEdge);
// This clip function is used only by <canvas> code. It allows
// implementations to handle clipping on the canvas differently since
// the discipline is different.
void canvasClip(const Path&, WindRule = RULE_EVENODD);
void clipOut(const Path&);
// ---------- Transformation methods ----------------- // ---------- Transformation methods -----------------
// Note that the getCTM method returns only the current transform from Blink's perspective, // Note that the getCTM method returns only the current transform from Blink's perspective,
// which is not the final transform used to place content on screen. It cannot be relied upon // which is not the final transform used to place content on screen. It cannot be relied upon
...@@ -448,7 +448,6 @@ private: ...@@ -448,7 +448,6 @@ private:
void drawFocusRingPath(const SkPath&, const Color&, int width); void drawFocusRingPath(const SkPath&, const Color&, int width);
void drawFocusRingRect(const SkRect&, const Color&, int width); void drawFocusRingRect(const SkRect&, const Color&, int width);
// SkCanvas wrappers. // SkCanvas wrappers.
void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op); void clipPath(const SkPath&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op); void clipRRect(const SkRRect&, AntiAliasingMode = NotAntiAliased, SkRegion::Op = SkRegion::kIntersect_Op);
......
...@@ -1154,45 +1154,36 @@ TEST(GraphicsContextTest, RecordingTotalMatrix) ...@@ -1154,45 +1154,36 @@ TEST(GraphicsContextTest, RecordingTotalMatrix)
EXPECT_EQ(context.getCTM(), controlContext.getCTM()); EXPECT_EQ(context.getCTM(), controlContext.getCTM());
} }
TEST(GraphicsContextTest, DisplayList) TEST(GraphicsContextTest, RecordingCanvas)
{ {
FloatRect rect(0, 0, 1, 1); SkBitmap bitmap;
RefPtr<DisplayList> dl = adoptRef(new DisplayList(rect)); bitmap.allocN32Pixels(1, 1);
bitmap.eraseColor(0);
// picture() returns 0 initially SkCanvas canvas(bitmap);
SkPicture* pic = dl->picture(); GraphicsContext context(&canvas);
EXPECT_FALSE(pic);
// endRecording without a beginRecording does nothing FloatRect rect(0, 0, 1, 1);
dl->endRecording();
pic = dl->picture();
EXPECT_FALSE(pic);
// Two beginRecordings in a row generate two canvases. // Two beginRecordings in a row generate two canvases.
// Unfortunately the new one could be allocated in the same // Unfortunately the new one could be allocated in the same
// spot as the old one so ref the first one to prolong its life. // spot as the old one so ref the first one to prolong its life.
IntSize size(1, 1); context.beginRecording(rect);
SkCanvas* canvas1 = dl->beginRecording(size); SkCanvas* canvas1 = context.canvas();
EXPECT_TRUE(canvas1); EXPECT_TRUE(canvas1);
canvas1->ref(); context.beginRecording(rect);
SkCanvas* canvas2 = dl->beginRecording(size); SkCanvas* canvas2 = context.canvas();
EXPECT_TRUE(canvas2); EXPECT_TRUE(canvas2);
EXPECT_NE(canvas1, canvas2); EXPECT_NE(canvas1, canvas2);
EXPECT_EQ(1, canvas1->getRefCnt()); EXPECT_EQ(1, canvas1->getRefCnt());
canvas1->unref();
EXPECT_TRUE(dl->isRecording());
// picture() returns 0 during recording
pic = dl->picture();
EXPECT_FALSE(pic);
// endRecording finally makes the picture accessible // endRecording finally makes the picture accessible
dl->endRecording(); RefPtr<DisplayList> dl = context.endRecording();
pic = dl->picture(); SkPicture* pic = dl->picture();
EXPECT_TRUE(pic); EXPECT_TRUE(pic);
EXPECT_EQ(1, pic->getRefCnt()); EXPECT_EQ(1, pic->getRefCnt());
context.endRecording();
} }
} // namespace } // namespace
...@@ -223,14 +223,6 @@ AffineTransform& AffineTransform::skewY(double angle) ...@@ -223,14 +223,6 @@ AffineTransform& AffineTransform::skewY(double angle)
return shear(0, tan(deg2rad(angle))); return shear(0, tan(deg2rad(angle)));
} }
AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest)
{
AffineTransform transform;
transform.translate(dest.x() - source.x(), dest.y() - source.y());
transform.scale(dest.width() / source.width(), dest.height() / source.height());
return transform;
}
void AffineTransform::map(double x, double y, double& x2, double& y2) const void AffineTransform::map(double x, double y, double& x2, double& y2) const
{ {
x2 = (m_transform[0] * x + m_transform[2] * y + m_transform[4]); x2 = (m_transform[0] * x + m_transform[2] * y + m_transform[4]);
......
...@@ -177,8 +177,6 @@ private: ...@@ -177,8 +177,6 @@ private:
Transform m_transform; Transform m_transform;
}; };
PLATFORM_EXPORT AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest);
} }
#endif #endif
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