diff --git a/engine/core/core.gni b/engine/core/core.gni index 2a78c74f4d9997c3d6039bbd9b448c1a763eab6f..51547c81d7be7eae48791fbe420c86db6a35c20a 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -833,6 +833,8 @@ sky_core_files = [ "page/PageVisibilityState.cpp", "page/PageVisibilityState.h", "page/SpellCheckerClient.h", + "painting/Canvas.cpp", + "painting/Canvas.h", "painting/Paint.cpp", "painting/Paint.h", "painting/PaintingCallback.cpp", @@ -841,6 +843,10 @@ sky_core_files = [ "painting/PaintingContext.h", "painting/PaintingTasks.cpp", "painting/PaintingTasks.h", + "painting/Picture.cpp", + "painting/Picture.h", + "painting/PictureRecorder.cpp", + "painting/PictureRecorder.h", "rendering/BidiRun.h", "rendering/BidiRunForLine.cpp", "rendering/BidiRunForLine.h", @@ -1095,9 +1101,12 @@ core_idl_files = get_path_info([ "html/TextMetrics.idl", "html/VoidCallback.idl", "layout/LayoutCallback.idl", + "painting/Canvas.idl", "painting/Paint.idl", "painting/PaintingCallback.idl", "painting/PaintingContext.idl", + "painting/Picture.idl", + "painting/PictureRecorder.idl", ], "abspath") diff --git a/engine/core/dom/Document.cpp b/engine/core/dom/Document.cpp index 38bb75179d003ba9db25ba590e98f101d7748d2d..2b37f28f7ecafc4db297bfb9f6979456130dc959 100644 --- a/engine/core/dom/Document.cpp +++ b/engine/core/dom/Document.cpp @@ -104,6 +104,8 @@ #include "sky/engine/core/page/EventHandler.h" #include "sky/engine/core/page/FocusController.h" #include "sky/engine/core/page/Page.h" +#include "sky/engine/core/painting/PaintingTasks.h" +#include "sky/engine/core/painting/Picture.h" #include "sky/engine/core/rendering/HitTestResult.h" #include "sky/engine/core/rendering/RenderView.h" #include "sky/engine/platform/DateComponents.h" @@ -2204,6 +2206,19 @@ bool Document::hasFocus() const return focusedFrame && focusedFrame == frame(); } +Picture* Document::rootPicture() const +{ + return m_picture.get(); +} + +void Document::setRootPicture(PassRefPtr picture) +{ + m_picture = picture; + if (m_picture) + PaintingTasks::enqueueCommit(this, m_picture->displayList()); + scheduleVisualUpdate(); +} + } // namespace blink #ifndef NDEBUG diff --git a/engine/core/dom/Document.h b/engine/core/dom/Document.h index 408763005fdbf7e0cc41a72321c96232eaa7958c..8116b3bc6ef87ff0a6b691296f55f7e2170065df 100644 --- a/engine/core/dom/Document.h +++ b/engine/core/dom/Document.h @@ -63,10 +63,11 @@ namespace blink { class AbstractModule; class AnimationTimeline; class Attr; -class CSSStyleDeclaration; -class CSSStyleSheet; class Comment; class ConsoleMessage; +class CSSStyleDeclaration; +class CSSStyleSheet; +class CustomElementRegistry; class DocumentFragment; class DocumentLifecycleNotifier; class DocumentLoadTiming; @@ -82,28 +83,28 @@ class FloatRect; class Frame; class FrameHost; class FrameView; +class HitTestRequest; class HTMLDocumentParser; class HTMLElement; class HTMLImport; class HTMLImportLoader; class HTMLImportsController; class HTMLScriptElement; -class HitTestRequest; class LayoutPoint; class LocalDOMWindow; class LocalFrame; class Location; class MediaQueryListListener; class MediaQueryMatcher; -class CustomElementRegistry; class Page; +class Picture; class QualifiedName; class Range; class RenderView; class RequestAnimationFrameCallback; class ResourceFetcher; -class ScriptRunner; class ScriptedAnimationController; +class ScriptRunner; class SegmentedString; class SelectorQueryCache; class Settings; @@ -494,6 +495,9 @@ public: void didRecalculateStyleForElement() { ++m_styleRecalcElementCounter; } + Picture* rootPicture() const; + void setRootPicture(PassRefPtr picture); + protected: explicit Document(const DocumentInit&); @@ -678,6 +682,8 @@ private: int m_styleRecalcElementCounter; mutable DocumentLoadTiming m_documentLoadTiming; + + RefPtr m_picture; }; inline void Document::scheduleRenderTreeUpdateIfNeeded() diff --git a/engine/core/dom/Document.idl b/engine/core/dom/Document.idl index e52d6ddd8d93c5a25878d5c52344356590dca2aa..957b764cdbd8b0fc9dba7205ddf197ec7be61abd 100644 --- a/engine/core/dom/Document.idl +++ b/engine/core/dom/Document.idl @@ -69,4 +69,6 @@ callback CustomElementConstructor = Element (); readonly attribute boolean hidden; readonly attribute HTMLScriptElement currentScript; + + attribute Picture rootPicture; }; diff --git a/engine/core/painting/Canvas.cpp b/engine/core/painting/Canvas.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e25baf4893daf35302066caabb6bb74ca24b369 --- /dev/null +++ b/engine/core/painting/Canvas.cpp @@ -0,0 +1,45 @@ +// Copyright 2015 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 "sky/engine/config.h" +#include "sky/engine/core/painting/PictureRecorder.h" + +#include "sky/engine/core/dom/Document.h" +#include "sky/engine/core/dom/Element.h" +#include "sky/engine/core/painting/PaintingTasks.h" +#include "sky/engine/platform/geometry/IntRect.h" +#include "third_party/skia/include/core/SkCanvas.h" + +namespace blink { + +Canvas::Canvas(const FloatSize& size) + : m_size(size) +{ + m_displayList = adoptRef(new DisplayList); + m_canvas = m_displayList->beginRecording(expandedIntSize(m_size)); +} + +Canvas::~Canvas() +{ +} + +void Canvas::drawCircle(double x, double y, double radius, Paint* paint) +{ + if (!m_canvas) + return; + ASSERT(paint); + ASSERT(m_displayList->isRecording()); + m_canvas->drawCircle(x, y, radius, paint->paint()); +} + +PassRefPtr Canvas::finishRecording() +{ + if (!isRecording()) + return nullptr; + m_canvas = nullptr; + m_displayList->endRecording(); + return m_displayList.release(); +} + +} // namespace blink diff --git a/engine/core/painting/Canvas.h b/engine/core/painting/Canvas.h new file mode 100644 index 0000000000000000000000000000000000000000..8cb0b21ba530138306c792e5f647e223f0ca4e04 --- /dev/null +++ b/engine/core/painting/Canvas.h @@ -0,0 +1,43 @@ +// Copyright 2015 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 SKY_ENGINE_CORE_PAINTING_CANVAS_H_ +#define SKY_ENGINE_CORE_PAINTING_CANVAS_H_ + +#include "sky/engine/core/painting/Paint.h" +#include "sky/engine/platform/graphics/DisplayList.h" +#include "sky/engine/tonic/dart_wrappable.h" +#include "sky/engine/wtf/PassRefPtr.h" +#include "sky/engine/wtf/RefCounted.h" + +namespace blink { +class Element; + +class Canvas : public RefCounted, public DartWrappable { + DEFINE_WRAPPERTYPEINFO(); +public: + Canvas(const FloatSize& size); + ~Canvas() override; + + // Width/Height define a culling rect which Skia may use for optimizing + // out draw calls issued outside the rect. + double width() const { return m_size.width(); } + double height() const { return m_size.height(); } + + void drawCircle(double x, double y, double radius, Paint* paint); + +protected: + PassRefPtr finishRecording(); + + bool isRecording() const { return m_canvas; } + +private: + FloatSize m_size; + RefPtr m_displayList; + SkCanvas* m_canvas; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_CANVAS_H_ diff --git a/engine/core/painting/Canvas.idl b/engine/core/painting/Canvas.idl new file mode 100644 index 0000000000000000000000000000000000000000..36fc06318df17e5002b04ca37245356e7bbf8a46 --- /dev/null +++ b/engine/core/painting/Canvas.idl @@ -0,0 +1,11 @@ +// Copyright 2015 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. +interface Canvas { + // Height and width are used for culling optimizations and do not necessarily + // imply that the Canvas is backed by a buffer with any specific bounds. + readonly attribute double height; + readonly attribute double width; + + void drawCircle(double x, double y, double radius, Paint paint); +}; diff --git a/engine/core/painting/PaintingContext.cpp b/engine/core/painting/PaintingContext.cpp index 0bac4898e52ba248bbd421c8bbed01ef0073a218..1ab9198e5dca7eb9f0cd9a176c947ea8c9ea0132 100644 --- a/engine/core/painting/PaintingContext.cpp +++ b/engine/core/painting/PaintingContext.cpp @@ -9,7 +9,6 @@ #include "sky/engine/core/dom/Element.h" #include "sky/engine/core/painting/PaintingTasks.h" #include "sky/engine/platform/geometry/IntRect.h" -#include "third_party/skia/include/core/SkCanvas.h" namespace blink { @@ -19,33 +18,20 @@ PassRefPtr PaintingContext::create(PassRefPtr element, } PaintingContext::PaintingContext(PassRefPtr element, const FloatSize& size) - : m_element(element) - , m_size(size) + : Canvas(size) + , m_element(element) { - m_displayList = adoptRef(new DisplayList); - m_canvas = m_displayList->beginRecording(expandedIntSize(m_size)); } PaintingContext::~PaintingContext() { } -void PaintingContext::drawCircle(double x, double y, double radius, Paint* paint) -{ - if (!m_canvas) - return; - ASSERT(paint); - ASSERT(m_displayList->isRecording()); - m_canvas->drawCircle(x, y, radius, paint->paint()); -} - void PaintingContext::commit() { - if (!m_canvas) + if (!isRecording()) return; - m_displayList->endRecording(); - m_canvas = nullptr; - PaintingTasks::enqueueCommit(m_element, m_displayList.release()); + PaintingTasks::enqueueCommit(m_element, finishRecording()); m_element->document().scheduleVisualUpdate(); } diff --git a/engine/core/painting/PaintingContext.h b/engine/core/painting/PaintingContext.h index 2c082522213f507a79707e6c1bb73e0b4388426c..8d51be47c88df0c31fe24b0e92d4f17831a8a69e 100644 --- a/engine/core/painting/PaintingContext.h +++ b/engine/core/painting/PaintingContext.h @@ -5,34 +5,23 @@ #ifndef SKY_ENGINE_CORE_PAINTING_PAINTINGCONTEXT_H_ #define SKY_ENGINE_CORE_PAINTING_PAINTINGCONTEXT_H_ -#include "sky/engine/core/painting/Paint.h" -#include "sky/engine/platform/graphics/DisplayList.h" -#include "sky/engine/tonic/dart_wrappable.h" -#include "sky/engine/wtf/PassRefPtr.h" -#include "sky/engine/wtf/RefCounted.h" +#include "sky/engine/core/painting/Canvas.h" namespace blink { class Element; -class PaintingContext : public RefCounted, public DartWrappable { +class PaintingContext : public Canvas { DEFINE_WRAPPERTYPEINFO(); public: ~PaintingContext() override; static PassRefPtr create(PassRefPtr element, const FloatSize& size); - double height() const { return m_size.height(); } - double width() const { return m_size.width(); } - - void drawCircle(double x, double y, double radius, Paint* paint); void commit(); private: PaintingContext(PassRefPtr element, const FloatSize& size); RefPtr m_element; - FloatSize m_size; - RefPtr m_displayList; - SkCanvas* m_canvas; }; } // namespace blink diff --git a/engine/core/painting/PaintingContext.idl b/engine/core/painting/PaintingContext.idl index 8eec203b5b9fbde6570dc4004f7244c640b03275..3f87cb8e80ecbdb38e3fb51f6b8c54c15281a276 100644 --- a/engine/core/painting/PaintingContext.idl +++ b/engine/core/painting/PaintingContext.idl @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -interface PaintingContext { - readonly attribute double height; - readonly attribute double width; - - void drawCircle(double x, double y, double radius, Paint paint); +interface PaintingContext : Canvas { void commit(); }; diff --git a/engine/core/painting/PaintingTasks.cpp b/engine/core/painting/PaintingTasks.cpp index e266eafc5b20d830a3193efcc59102dcfeed0c60..994ff11611affebeecd73bc53af723c861e5a33b 100644 --- a/engine/core/painting/PaintingTasks.cpp +++ b/engine/core/painting/PaintingTasks.cpp @@ -29,10 +29,10 @@ struct RequestTask { }; struct CommitTask { - CommitTask(PassRefPtr e, PassRefPtr d) - : element(e), displayList(d) { } + CommitTask(PassRefPtr n, PassRefPtr d) + : node(n), displayList(d) { } - RefPtr element; + RefPtr node; RefPtr displayList; }; @@ -55,9 +55,9 @@ void PaintingTasks::enqueueRequest(PassRefPtr element, PassOwnPtr element, PassRefPtr displayList) +void PaintingTasks::enqueueCommit(PassRefPtr node, PassRefPtr displayList) { - commits().append(CommitTask(element, displayList)); + commits().append(CommitTask(node, displayList)); } bool PaintingTasks::serviceRequests() @@ -86,7 +86,7 @@ bool PaintingTasks::serviceRequests() void PaintingTasks::drainCommits() { for (auto& commit : commits()) { - RenderObject* renderer = commit.element->renderer(); + RenderObject* renderer = commit.node->renderer(); if (!renderer || !renderer->isBox()) return; toRenderBox(renderer)->setCustomPainting(commit.displayList.release()); diff --git a/engine/core/painting/PaintingTasks.h b/engine/core/painting/PaintingTasks.h index 792477c05b086170d18f7c8e70fbecb7905b2a29..bd9a20e8d4b494b50275693b568ef0004c48e75f 100644 --- a/engine/core/painting/PaintingTasks.h +++ b/engine/core/painting/PaintingTasks.h @@ -11,12 +11,13 @@ namespace blink { class DisplayList; class Element; +class Node; class PaintingCallback; class PaintingTasks { public: static void enqueueRequest(PassRefPtr, PassOwnPtr); - static void enqueueCommit(PassRefPtr, PassRefPtr); + static void enqueueCommit(PassRefPtr, PassRefPtr); static bool serviceRequests(); static void drainCommits(); diff --git a/engine/core/painting/Picture.cpp b/engine/core/painting/Picture.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d96aa3a0e9deb84be32b591922f3070a7db6a80 --- /dev/null +++ b/engine/core/painting/Picture.cpp @@ -0,0 +1,27 @@ +// Copyright 2015 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 "sky/engine/config.h" +#include "sky/engine/core/painting/Picture.h" + +#include "base/logging.h" + +namespace blink { + +PassRefPtr Picture::create(PassRefPtr list) +{ + ASSERT(list); + return adoptRef(new Picture(list)); +} + +Picture::Picture(PassRefPtr list) + : m_displayList(list) +{ +} + +Picture::~Picture() +{ +} + +} // namespace blink diff --git a/engine/core/painting/Picture.h b/engine/core/painting/Picture.h new file mode 100644 index 0000000000000000000000000000000000000000..adfc908563c7716c7deeb4ffa75c4e9709c117d1 --- /dev/null +++ b/engine/core/painting/Picture.h @@ -0,0 +1,31 @@ +// Copyright 2015 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 SKY_ENGINE_CORE_PAINTING_PICTURE_H_ +#define SKY_ENGINE_CORE_PAINTING_PICTURE_H_ + +#include "sky/engine/platform/graphics/DisplayList.h" +#include "sky/engine/tonic/dart_wrappable.h" +#include "sky/engine/wtf/PassRefPtr.h" +#include "sky/engine/wtf/RefCounted.h" + +namespace blink { + +class Picture : public RefCounted, public DartWrappable { + DEFINE_WRAPPERTYPEINFO(); +public: + ~Picture() override; + static PassRefPtr create(PassRefPtr); + + DisplayList* displayList() const { return m_displayList.get(); } + +private: + Picture(PassRefPtr); + + RefPtr m_displayList; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_PICTURE_H_ diff --git a/engine/core/painting/Picture.idl b/engine/core/painting/Picture.idl new file mode 100644 index 0000000000000000000000000000000000000000..0f618fdef72cafeff11960cb00f1fb24a959a6b0 --- /dev/null +++ b/engine/core/painting/Picture.idl @@ -0,0 +1,5 @@ +// Copyright 2015 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. +interface Picture { +}; diff --git a/engine/core/painting/PictureRecorder.cpp b/engine/core/painting/PictureRecorder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4896215210088f05beabeffd410676e47a4f8b2b --- /dev/null +++ b/engine/core/painting/PictureRecorder.cpp @@ -0,0 +1,33 @@ +// Copyright 2015 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 "sky/engine/config.h" +#include "sky/engine/core/painting/PictureRecorder.h" + +#include "sky/engine/core/painting/Picture.h" + +namespace blink { + +PassRefPtr PictureRecorder::create(double width, double height) +{ + return adoptRef(new PictureRecorder(FloatSize(width, height))); +} + +PictureRecorder::PictureRecorder(const FloatSize& size) + : Canvas(size) +{ +} + +PictureRecorder::~PictureRecorder() +{ +} + +PassRefPtr PictureRecorder::endRecording() +{ + if (!isRecording()) + return nullptr; + return Picture::create(finishRecording()); +} + +} // namespace blink diff --git a/engine/core/painting/PictureRecorder.h b/engine/core/painting/PictureRecorder.h new file mode 100644 index 0000000000000000000000000000000000000000..485edd50499bb006a22784d5d68a202816dbd5b6 --- /dev/null +++ b/engine/core/painting/PictureRecorder.h @@ -0,0 +1,28 @@ +// Copyright 2015 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 SKY_ENGINE_CORE_PAINTING_PICTURERECORDER_H_ +#define SKY_ENGINE_CORE_PAINTING_PICTURERECORDER_H_ + +#include "sky/engine/core/painting/Canvas.h" + +namespace blink { + +class Picture; + +class PictureRecorder : public Canvas { + DEFINE_WRAPPERTYPEINFO(); +public: + ~PictureRecorder() override; + static PassRefPtr create(double width, double height); + + PassRefPtr endRecording(); + +private: + PictureRecorder(const FloatSize& size); +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_PICTURERECORDER_H_ diff --git a/engine/core/painting/PictureRecorder.idl b/engine/core/painting/PictureRecorder.idl new file mode 100644 index 0000000000000000000000000000000000000000..b1ea18510b980135bc66694d42e9bd76c926f779 --- /dev/null +++ b/engine/core/painting/PictureRecorder.idl @@ -0,0 +1,8 @@ +// Copyright 2015 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. +[ + Constructor(double width, double height) +] interface PictureRecorder : Canvas { + Picture endRecording(); +}; diff --git a/engine/core/rendering/RenderBox.cpp b/engine/core/rendering/RenderBox.cpp index 59acacea1dcec48cc0d953072615bd69f7344d5b..c7d70da18919727a3a876f49f452242438096332 100644 --- a/engine/core/rendering/RenderBox.cpp +++ b/engine/core/rendering/RenderBox.cpp @@ -994,19 +994,24 @@ BackgroundBleedAvoidance RenderBox::determineBackgroundBleedAvoidance(GraphicsCo return BackgroundBleedClipBackground; } -void RenderBox::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset) +void RenderBox::paintCustomPainting(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { LayoutRect paintRect = borderBoxRect(); paintRect.moveBy(paintOffset); - paintBoxDecorationBackgroundWithRect(paintInfo, paintOffset, paintRect); // TODO(abarth): Currently we only draw m_customPainting if we happen to - // have a box decoration or a background. Instead, we should probably have - // another function like paintBoxDecorationBackground that subclasses can - // call to draw m_customPainting. + // have a box decoration or a background. if (m_customPainting) paintInfo.context->drawDisplayList(m_customPainting.get(), paintRect.location()); } +void RenderBox::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset) +{ + LayoutRect paintRect = borderBoxRect(); + paintRect.moveBy(paintOffset); + paintBoxDecorationBackgroundWithRect(paintInfo, paintOffset, paintRect); + paintCustomPainting(paintInfo, paintOffset); +} + void RenderBox::paintBoxDecorationBackgroundWithRect(PaintInfo& paintInfo, const LayoutPoint& paintOffset, const LayoutRect& paintRect) { RenderStyle* style = this->style(); diff --git a/engine/core/rendering/RenderBox.h b/engine/core/rendering/RenderBox.h index bbf8283a8eabb5436b7a526fb5b3cc782ffaaf1f..cbb0194cf956c5589fd1c277c9a081462df70095 100644 --- a/engine/core/rendering/RenderBox.h +++ b/engine/core/rendering/RenderBox.h @@ -491,6 +491,8 @@ protected: void updateIntrinsicContentLogicalHeight(LayoutUnit intrinsicContentLogicalHeight) const { m_intrinsicContentLogicalHeight = intrinsicContentLogicalHeight; } + void paintCustomPainting(PaintInfo& paintInfo, const LayoutPoint& paintOffset); + private: void updateTransformationMatrix(); void updateTransform(const RenderStyle* oldStyle); diff --git a/engine/core/rendering/RenderView.cpp b/engine/core/rendering/RenderView.cpp index f7e5bd5c001f34399f54e0c28302c7dae9c8a7e3..7013d70afb1329ccdd373078c477d3358b38ca7d 100644 --- a/engine/core/rendering/RenderView.cpp +++ b/engine/core/rendering/RenderView.cpp @@ -196,7 +196,7 @@ void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, Vec paintObject(paintInfo, paintOffset, layers); } -void RenderView::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint&) +void RenderView::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (!view()) return; @@ -216,6 +216,7 @@ void RenderView::paintBoxDecorationBackground(PaintInfo& paintInfo, const Layout paintInfo.context->clearRect(paintInfo.rect); } } + paintCustomPainting(paintInfo, paintOffset); } void RenderView::absoluteQuads(Vector& quads) const diff --git a/examples/raw/custom_paint_without_element.sky b/examples/raw/custom_paint_without_element.sky new file mode 100644 index 0000000000000000000000000000000000000000..d18611070edd8ae6786ce8919c4b65ef14ef5627 --- /dev/null +++ b/examples/raw/custom_paint_without_element.sky @@ -0,0 +1,18 @@ +