From 96df6c373c8e65edfdaadd03e7b730bd7004818c Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 25 Aug 2015 13:33:54 -0700 Subject: [PATCH] Use sky.SceneBuilder to upload Layer tree to C++ We still use SkPicture as our rasterization backend, but now we're uploading our layer tree to C++. A future patch will push the layer tree deeper into the system and we'll eventually switch backends. --- sky/engine/core/compositing/Scene.cpp | 24 ++++ sky/engine/core/compositing/Scene.h | 33 ++++++ sky/engine/core/compositing/Scene.idl | 7 ++ sky/engine/core/compositing/SceneBuilder.cpp | 100 ++++++++++++++++ sky/engine/core/compositing/SceneBuilder.h | 57 +++++++++ sky/engine/core/compositing/SceneBuilder.idl | 19 +++ sky/engine/core/core.gni | 8 ++ sky/engine/core/painting/Canvas.cpp | 31 +---- sky/engine/core/painting/CanvasPath.cpp | 6 + sky/engine/core/painting/CanvasPath.h | 3 + sky/engine/core/painting/Matrix.cpp | 39 +++++++ sky/engine/core/painting/Matrix.h | 19 +++ sky/engine/core/painting/Path.idl | 2 + sky/engine/core/painting/RRect.cpp | 9 +- sky/engine/core/painting/RRect.h | 3 + sky/engine/core/painting/RRect.idl | 2 + sky/engine/core/view/View.h | 5 + sky/engine/core/view/View.idl | 1 + sky/engine/public/sky/sky_view.cc | 2 + sky/packages/sky/lib/rendering/layer.dart | 115 ++++++------------- sky/packages/sky/lib/rendering/view.dart | 11 +- 21 files changed, 380 insertions(+), 116 deletions(-) create mode 100644 sky/engine/core/compositing/Scene.cpp create mode 100644 sky/engine/core/compositing/Scene.h create mode 100644 sky/engine/core/compositing/Scene.idl create mode 100644 sky/engine/core/compositing/SceneBuilder.cpp create mode 100644 sky/engine/core/compositing/SceneBuilder.h create mode 100644 sky/engine/core/compositing/SceneBuilder.idl create mode 100644 sky/engine/core/painting/Matrix.cpp create mode 100644 sky/engine/core/painting/Matrix.h diff --git a/sky/engine/core/compositing/Scene.cpp b/sky/engine/core/compositing/Scene.cpp new file mode 100644 index 00000000000..08458676c71 --- /dev/null +++ b/sky/engine/core/compositing/Scene.cpp @@ -0,0 +1,24 @@ +// 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/core/compositing/Scene.h" + +namespace blink { + +PassRefPtr Scene::create(PassRefPtr picture) +{ + ASSERT(picture); + return adoptRef(new Scene(picture)); +} + +Scene::Scene(PassRefPtr picture) + : m_picture(picture) +{ +} + +Scene::~Scene() +{ +} + +} // namespace blink diff --git a/sky/engine/core/compositing/Scene.h b/sky/engine/core/compositing/Scene.h new file mode 100644 index 00000000000..8d3a5ac8c79 --- /dev/null +++ b/sky/engine/core/compositing/Scene.h @@ -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. + +#ifndef SKY_ENGINE_CORE_COMPOSITING_SCENE_H_ +#define SKY_ENGINE_CORE_COMPOSITING_SCENE_H_ + +#include "sky/engine/tonic/dart_wrappable.h" +#include "sky/engine/wtf/PassRefPtr.h" +#include "sky/engine/wtf/RefCounted.h" +#include "third_party/skia/include/core/SkPicture.h" + +namespace blink { + +class Scene : public RefCounted, public DartWrappable { + DEFINE_WRAPPERTYPEINFO(); +public: + ~Scene() override; + static PassRefPtr create(PassRefPtr skPicture); + + SkPicture* toSkia() const { return m_picture.get(); } + +private: + explicit Scene(PassRefPtr skPicture); + + // While bootstraping the compositing system, we use an SkPicture instead + // of a layer tree to back the scene. + RefPtr m_picture; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_COMPOSITING_SCENE_H_ diff --git a/sky/engine/core/compositing/Scene.idl b/sky/engine/core/compositing/Scene.idl new file mode 100644 index 00000000000..359eed344ad --- /dev/null +++ b/sky/engine/core/compositing/Scene.idl @@ -0,0 +1,7 @@ +// 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. + +// An opaque handle to a composited scene. +interface Scene { +}; diff --git a/sky/engine/core/compositing/SceneBuilder.cpp b/sky/engine/core/compositing/SceneBuilder.cpp new file mode 100644 index 00000000000..7e10ca3d10b --- /dev/null +++ b/sky/engine/core/compositing/SceneBuilder.cpp @@ -0,0 +1,100 @@ +// 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/core/compositing/SceneBuilder.h" + +#include "sky/engine/core/painting/Matrix.h" +#include "third_party/skia/include/core/SkColorFilter.h" + +namespace blink { + +SceneBuilder::SceneBuilder(const Rect& bounds) +{ + m_canvas = m_pictureRecorder.beginRecording(bounds.sk_rect, + &m_rtreeFactory, SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag); +} + +SceneBuilder::~SceneBuilder() +{ +} + +void SceneBuilder::pushTransform(const Float32List& matrix4, ExceptionState& es) +{ + SkMatrix sk_matrix = toSkMatrix(matrix4, es); + if (es.had_exception()) + return; + m_canvas->save(); + m_canvas->concat(sk_matrix); +} + +void SceneBuilder::pushClipRect(const Rect& rect) +{ + if (!m_canvas) + return; + m_canvas->save(); + m_canvas->clipRect(rect.sk_rect); +} + +void SceneBuilder::pushClipRRect(const RRect* rrect, const Rect& bounds) +{ + if (!m_canvas) + return; + m_canvas->saveLayer(&bounds.sk_rect, nullptr); + m_canvas->clipRRect(rrect->rrect()); +} + +void SceneBuilder::pushClipPath(const CanvasPath* path, const Rect& bounds) +{ + if (!m_canvas) + return; + m_canvas->saveLayer(&bounds.sk_rect, nullptr); + m_canvas->clipPath(path->path()); +} + +void SceneBuilder::pushOpacity(int alpha, const Rect& bounds) +{ + if (!m_canvas) + return; + SkColor color = SkColorSetARGB(alpha, 0, 0, 0); + RefPtr colorFilter = adoptRef(SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode)); + SkPaint paint; + paint.setColorFilter(colorFilter.get()); + m_canvas->saveLayer(&bounds.sk_rect, &paint); +} + +void SceneBuilder::pushColorFilter(SkColor color, SkXfermode::Mode transferMode, const Rect& bounds) +{ + if (!m_canvas) + return; + RefPtr colorFilter = adoptRef(SkColorFilter::CreateModeFilter(color, transferMode)); + SkPaint paint; + paint.setColorFilter(colorFilter.get()); + m_canvas->saveLayer(&bounds.sk_rect, &paint); +} + +void SceneBuilder::pop() +{ + if (!m_canvas) + return; + m_canvas->restore(); +} + +void SceneBuilder::addPicture(const Offset& offset, Picture* picture, const Rect& paintBounds) +{ + if (!m_canvas) + return; + m_canvas->save(); + m_canvas->translate(offset.sk_size.width(), offset.sk_size.height()); + m_canvas->drawPicture(picture->toSkia()); + m_canvas->restore(); +} + +PassRefPtr SceneBuilder::build() +{ + RefPtr scene = Scene::create(adoptRef(m_pictureRecorder.endRecording())); + m_canvas = nullptr; + return scene.release(); +} + +} // namespace blink diff --git a/sky/engine/core/compositing/SceneBuilder.h b/sky/engine/core/compositing/SceneBuilder.h new file mode 100644 index 00000000000..d8facf6036e --- /dev/null +++ b/sky/engine/core/compositing/SceneBuilder.h @@ -0,0 +1,57 @@ +// 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_COMPOSITING_SCENEBUILDER_H_ +#define SKY_ENGINE_CORE_COMPOSITING_SCENEBUILDER_H_ + +#include "sky/engine/bindings/exception_state.h" +#include "sky/engine/core/compositing/Scene.h" +#include "sky/engine/core/painting/CanvasPath.h" +#include "sky/engine/core/painting/Offset.h" +#include "sky/engine/core/painting/Paint.h" +#include "sky/engine/core/painting/Picture.h" +#include "sky/engine/core/painting/Point.h" +#include "sky/engine/core/painting/Rect.h" +#include "sky/engine/core/painting/RRect.h" +#include "sky/engine/core/painting/Size.h" +#include "sky/engine/tonic/dart_wrappable.h" +#include "sky/engine/tonic/float32_list.h" +#include "sky/engine/wtf/PassRefPtr.h" +#include "sky/engine/wtf/RefCounted.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkPictureRecorder.h" + +namespace blink { + +class SceneBuilder : public RefCounted, public DartWrappable { + DEFINE_WRAPPERTYPEINFO(); +public: + static PassRefPtr create(const Rect& bounds) { + return adoptRef(new SceneBuilder(bounds)); + } + + ~SceneBuilder() override; + + void pushTransform(const Float32List& matrix4, ExceptionState&); + void pushClipRect(const Rect& rect); + void pushClipRRect(const RRect* rrect, const Rect& bounds); + void pushClipPath(const CanvasPath* path, const Rect& bounds); + void pushOpacity(int alpha, const Rect& bounds); + void pushColorFilter(SkColor color, SkXfermode::Mode transferMode, const Rect& bounds); + void pop(); + void addPicture(const Offset& offset, Picture* picture, const Rect& bounds); + + PassRefPtr build(); + +private: + explicit SceneBuilder(const Rect& bounds); + + SkRTreeFactory m_rtreeFactory; + SkPictureRecorder m_pictureRecorder; + SkCanvas* m_canvas; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_COMPOSITING_SCENEBUILDER_H_ diff --git a/sky/engine/core/compositing/SceneBuilder.idl b/sky/engine/core/compositing/SceneBuilder.idl new file mode 100644 index 00000000000..17182c6e4f5 --- /dev/null +++ b/sky/engine/core/compositing/SceneBuilder.idl @@ -0,0 +1,19 @@ +// 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(Rect bounds), +] interface SceneBuilder { + [RaisesException] void pushTransform(Float32List matrix4); + void pushClipRect(Rect rect); + void pushClipRRect(RRect rrect, Rect bounds); + void pushClipPath(Path path, Rect bounds); + void pushOpacity(long alpha, Rect bounds); + void pushColorFilter(Color color, TransferMode transferMode, Rect bounds); + void pop(); + + void addPicture(Offset offset, Picture picture, Rect bounds); + + Scene build(); +}; diff --git a/sky/engine/core/core.gni b/sky/engine/core/core.gni index 94821df344e..52ed9b3353d 100644 --- a/sky/engine/core/core.gni +++ b/sky/engine/core/core.gni @@ -7,6 +7,10 @@ sky_core_output_dir = "$root_gen_dir/sky/core" sky_core_files = [ "Init.cpp", "Init.h", + "compositing/Scene.cpp", + "compositing/Scene.h", + "compositing/SceneBuilder.cpp", + "compositing/SceneBuilder.h", "css/BasicShapeFunctions.cpp", "css/BasicShapeFunctions.h", "css/BinaryDataFontFaceSource.cpp", @@ -434,6 +438,8 @@ sky_core_files = [ "painting/LayoutRoot.h", "painting/MaskFilter.cpp", "painting/MaskFilter.h", + "painting/Matrix.cpp", + "painting/Matrix.h", "painting/Offset.cpp", "painting/Offset.h", "painting/Paint.cpp", @@ -626,6 +632,8 @@ sky_core_files = [ ] core_idl_files = get_path_info([ + "compositing/Scene.idl", + "compositing/SceneBuilder.idl", "css/CSS.idl", "css/CSSStyleDeclaration.idl", "css/MediaQueryList.idl", diff --git a/sky/engine/core/painting/Canvas.cpp b/sky/engine/core/painting/Canvas.cpp index b373cb02110..29ea72c5d3a 100644 --- a/sky/engine/core/painting/Canvas.cpp +++ b/sky/engine/core/painting/Canvas.cpp @@ -9,6 +9,7 @@ #include "sky/engine/core/dom/Document.h" #include "sky/engine/core/dom/Element.h" #include "sky/engine/core/painting/CanvasImage.h" +#include "sky/engine/core/painting/Matrix.h" #include "sky/engine/core/painting/PaintingTasks.h" #include "sky/engine/platform/geometry/IntRect.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -82,36 +83,6 @@ void Canvas::skew(float sx, float sy) m_canvas->skew(sx, sy); } -// Mappings from SkMatrix-index to input-index. -static const int kSkMatrixIndexToMatrix4Index[] = { - 0, 4, 12, - 1, 5, 13, - 3, 7, 15, -}; - -SkMatrix toSkMatrix(const Float32List& matrix4, ExceptionState& es) -{ - ASSERT(matrix4.data()); - SkMatrix sk_matrix; - if (matrix4.num_elements() != 16) { - es.ThrowTypeError("Incorrect number of elements in matrix."); - return sk_matrix; - } - - for (intptr_t i = 0; i < 9; ++i) - sk_matrix[i] = matrix4[kSkMatrixIndexToMatrix4Index[i]]; - return sk_matrix; -} - -Float32List toMatrix4(const SkMatrix& sk_matrix) -{ - Float32List matrix4(Dart_NewTypedData(Dart_TypedData_kFloat32, 16)); - for (intptr_t i = 0; i < 9; ++i) - matrix4[kSkMatrixIndexToMatrix4Index[i]] = sk_matrix[i]; - matrix4[10] = 1.0; // Identity along the z axis. - return matrix4; -} - void Canvas::concat(const Float32List& matrix4, ExceptionState& es) { if (!m_canvas) diff --git a/sky/engine/core/painting/CanvasPath.cpp b/sky/engine/core/painting/CanvasPath.cpp index 3420b5df568..51f740037de 100644 --- a/sky/engine/core/painting/CanvasPath.cpp +++ b/sky/engine/core/painting/CanvasPath.cpp @@ -14,4 +14,10 @@ CanvasPath::~CanvasPath() { } +PassRefPtr CanvasPath::shift(const Offset& offset) { + RefPtr path = CanvasPath::create(); + m_path.offset(offset.sk_size.width(), offset.sk_size.height(), &path->m_path); + return path.release(); +} + } // namespace blink diff --git a/sky/engine/core/painting/CanvasPath.h b/sky/engine/core/painting/CanvasPath.h index 29520617d5e..0a1b9b30b9b 100644 --- a/sky/engine/core/painting/CanvasPath.h +++ b/sky/engine/core/painting/CanvasPath.h @@ -7,6 +7,7 @@ #include "math.h" +#include "sky/engine/core/painting/Offset.h" #include "sky/engine/core/painting/Rect.h" #include "sky/engine/tonic/dart_wrappable.h" #include "sky/engine/wtf/PassRefPtr.h" @@ -55,6 +56,8 @@ public: const SkPath& path() const { return m_path; } + PassRefPtr shift(const Offset& offset); + private: CanvasPath(); diff --git a/sky/engine/core/painting/Matrix.cpp b/sky/engine/core/painting/Matrix.cpp new file mode 100644 index 00000000000..8c390c6d08b --- /dev/null +++ b/sky/engine/core/painting/Matrix.cpp @@ -0,0 +1,39 @@ +// 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/core/painting/Matrix.h" + +namespace blink { + +// Mappings from SkMatrix-index to input-index. +static const int kSkMatrixIndexToMatrix4Index[] = { + 0, 4, 12, + 1, 5, 13, + 3, 7, 15, +}; + +SkMatrix toSkMatrix(const Float32List& matrix4, ExceptionState& es) +{ + ASSERT(matrix4.data()); + SkMatrix sk_matrix; + if (matrix4.num_elements() != 16) { + es.ThrowTypeError("Incorrect number of elements in matrix."); + return sk_matrix; + } + + for (intptr_t i = 0; i < 9; ++i) + sk_matrix[i] = matrix4[kSkMatrixIndexToMatrix4Index[i]]; + return sk_matrix; +} + +Float32List toMatrix4(const SkMatrix& sk_matrix) +{ + Float32List matrix4(Dart_NewTypedData(Dart_TypedData_kFloat32, 16)); + for (intptr_t i = 0; i < 9; ++i) + matrix4[kSkMatrixIndexToMatrix4Index[i]] = sk_matrix[i]; + matrix4[10] = 1.0; // Identity along the z axis. + return matrix4; +} + +} // namespace blink diff --git a/sky/engine/core/painting/Matrix.h b/sky/engine/core/painting/Matrix.h new file mode 100644 index 00000000000..6c395d48e27 --- /dev/null +++ b/sky/engine/core/painting/Matrix.h @@ -0,0 +1,19 @@ +// 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_MATRIX_H_ +#define SKY_ENGINE_CORE_PAINTING_MATRIX_H_ + +#include "sky/engine/bindings/exception_state.h" +#include "sky/engine/tonic/float32_list.h" +#include "third_party/skia/include/core/SkMatrix.h" + +namespace blink { + +SkMatrix toSkMatrix(const Float32List& matrix4, ExceptionState& es); +Float32List toMatrix4(const SkMatrix& sk_matrix); + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_MATRIX_H_ diff --git a/sky/engine/core/painting/Path.idl b/sky/engine/core/painting/Path.idl index 086392827c7..b172ee00bb4 100644 --- a/sky/engine/core/painting/Path.idl +++ b/sky/engine/core/painting/Path.idl @@ -11,4 +11,6 @@ void arcTo(Rect rect, float startAngle, float sweepAngle, boolean forceMoveTo); // angles in radians void addOval(Rect oval); void close(); + + Path shift(Offset offset); }; diff --git a/sky/engine/core/painting/RRect.cpp b/sky/engine/core/painting/RRect.cpp index 254bd510f1b..7aa2f47bc26 100644 --- a/sky/engine/core/painting/RRect.cpp +++ b/sky/engine/core/painting/RRect.cpp @@ -16,7 +16,14 @@ RRect::~RRect() void RRect::setRectXY(const Rect& rect, float xRad, float yRad) { - m_rrect.setRectXY(rect.sk_rect, xRad, yRad); + m_rrect.setRectXY(rect.sk_rect, xRad, yRad); +} + +PassRefPtr RRect::shift(const Offset& offset) { + RefPtr rrect = RRect::create(); + rrect->m_rrect = m_rrect; + rrect->m_rrect.offset(offset.sk_size.width(), offset.sk_size.height()); + return rrect.release(); } } // namespace blink diff --git a/sky/engine/core/painting/RRect.h b/sky/engine/core/painting/RRect.h index 4cfdc6bc52c..7d46dceb7a1 100644 --- a/sky/engine/core/painting/RRect.h +++ b/sky/engine/core/painting/RRect.h @@ -5,6 +5,7 @@ #ifndef SKY_ENGINE_CORE_PAINTING_RRECT_H_ #define SKY_ENGINE_CORE_PAINTING_RRECT_H_ +#include "sky/engine/core/painting/Offset.h" #include "sky/engine/core/painting/Rect.h" #include "sky/engine/tonic/dart_wrappable.h" #include "sky/engine/wtf/PassRefPtr.h" @@ -27,6 +28,8 @@ public: const SkRRect& rrect() const { return m_rrect; } void setRRect(const SkRRect& rrect) { m_rrect = rrect; } + PassRefPtr shift(const Offset& offset); + private: RRect(); diff --git a/sky/engine/core/painting/RRect.idl b/sky/engine/core/painting/RRect.idl index 16d83c73282..f57d13a1e6c 100644 --- a/sky/engine/core/painting/RRect.idl +++ b/sky/engine/core/painting/RRect.idl @@ -6,4 +6,6 @@ Constructor(), ] interface RRect { void setRectXY(Rect rect, float xRad, float yRad); + + RRect shift(Offset offset); }; diff --git a/sky/engine/core/view/View.h b/sky/engine/core/view/View.h index 71147f4b968..d8e7757fc03 100644 --- a/sky/engine/core/view/View.h +++ b/sky/engine/core/view/View.h @@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/time/time.h" +#include "sky/engine/core/compositing/Scene.h" #include "sky/engine/core/html/VoidCallback.h" #include "sky/engine/core/painting/Picture.h" #include "sky/engine/core/view/EventCallback.h" @@ -37,6 +38,9 @@ public: Picture* picture() const { return m_picture.get(); } void setPicture(Picture* picture) { m_picture = picture; } + Scene* scene() const { return m_scene.get(); } + void setScene(Scene* scene) { m_scene = scene; } + void setEventCallback(PassOwnPtr callback); void setMetricsChangedCallback(PassOwnPtr callback); @@ -57,6 +61,7 @@ private: OwnPtr m_metricsChangedCallback; OwnPtr m_frameCallback; RefPtr m_picture; + RefPtr m_scene; }; } // namespace blink diff --git a/sky/engine/core/view/View.idl b/sky/engine/core/view/View.idl index 2fb0301a335..569ed212eab 100644 --- a/sky/engine/core/view/View.idl +++ b/sky/engine/core/view/View.idl @@ -15,6 +15,7 @@ interface View { readonly attribute double height; attribute Picture picture; + attribute Scene scene; void setEventCallback(EventCallback callback); void setMetricsChangedCallback(VoidCallback callback); diff --git a/sky/engine/public/sky/sky_view.cc b/sky/engine/public/sky/sky_view.cc index f674fb95cd9..b290115117d 100644 --- a/sky/engine/public/sky/sky_view.cc +++ b/sky/engine/public/sky/sky_view.cc @@ -53,6 +53,8 @@ void SkyView::BeginFrame(base::TimeTicks frame_time) { } PassRefPtr SkyView::Paint() { + if (Scene* scene = view_->scene()) + return scene->toSkia(); if (Picture* picture = view_->picture()) return picture->toSkia(); return nullptr; diff --git a/sky/packages/sky/lib/rendering/layer.dart b/sky/packages/sky/lib/rendering/layer.dart index 9c6837376f2..adcbe8c44c4 100644 --- a/sky/packages/sky/lib/rendering/layer.dart +++ b/sky/packages/sky/lib/rendering/layer.dart @@ -5,7 +5,6 @@ import 'dart:sky' as sky; import 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; -import 'package:sky/base/debug.dart'; import 'package:vector_math/vector_math.dart'; abstract class Layer { @@ -47,12 +46,7 @@ abstract class Layer { _parent = null; } - // The paint() methods are temporary. Eventually, Layers won't have - // a paint() method, the entire Layer hierarchy will be handed over - // to the C++ side for processing. Until we implement that, though, - // we instead have the layers paint themselves into a canvas at - // paint time. - void paint(sky.Canvas canvas); + void addToScene(sky.SceneBuilder builder, Offset layerOffset); } class PictureLayer extends Layer { @@ -62,24 +56,10 @@ class PictureLayer extends Layer { Rect paintBounds; sky.Picture picture; - bool _debugPaintLayerBorder(sky.Canvas canvas) { - if (debugPaintLayerBordersEnabled) { - Paint border = new Paint() - ..color = debugPaintLayerBordersColor - ..strokeWidth = 2.0 - ..setStyle(sky.PaintingStyle.stroke); - canvas.drawRect(paintBounds, border); - } - return true; + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + builder.addPicture(offset + layerOffset, picture, paintBounds); } - void paint(sky.Canvas canvas) { - assert(picture != null); - canvas.translate(offset.dx, offset.dy); - canvas.drawPicture(picture); - assert(_debugPaintLayerBorder(canvas)); - canvas.translate(-offset.dx, -offset.dy); - } } class ContainerLayer extends Layer { @@ -182,19 +162,18 @@ class ContainerLayer extends Layer { _lastChild = null; } - void paint(sky.Canvas canvas) { - canvas.translate(offset.dx, offset.dy); - paintChildren(canvas); - canvas.translate(-offset.dx, -offset.dy); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + addChildrenToScene(builder, offset + layerOffset); } - void paintChildren(sky.Canvas canvas) { + void addChildrenToScene(sky.SceneBuilder builder, Offset layerOffset) { Layer child = firstChild; while (child != null) { - child.paint(canvas); + child.addToScene(builder, layerOffset); child = child.nextSibling; } } + } class ClipRectLayer extends ContainerLayer { @@ -203,16 +182,13 @@ class ClipRectLayer extends ContainerLayer { // clipRect is _not_ affected by given offset Rect clipRect; - void paint(sky.Canvas canvas) { - canvas.save(); - canvas.clipRect(clipRect); - canvas.translate(offset.dx, offset.dy); - paintChildren(canvas); - canvas.restore(); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + builder.pushClipRect(clipRect.shift(layerOffset)); + addChildrenToScene(builder, offset + layerOffset); + builder.pop(); } -} -final Paint _disableAntialias = new Paint()..isAntiAlias = false; +} class ClipRRectLayer extends ContainerLayer { ClipRRectLayer({ Offset offset: Offset.zero, this.bounds, this.clipRRect }) : super(offset: offset); @@ -221,13 +197,12 @@ class ClipRRectLayer extends ContainerLayer { Rect bounds; sky.RRect clipRRect; - void paint(sky.Canvas canvas) { - canvas.saveLayer(bounds, _disableAntialias); - canvas.clipRRect(clipRRect); - canvas.translate(offset.dx, offset.dy); - paintChildren(canvas); - canvas.restore(); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + builder.pushClipRRect(clipRRect.shift(layerOffset), bounds.shift(layerOffset)); + addChildrenToScene(builder, offset + layerOffset); + builder.pop(); } + } class ClipPathLayer extends ContainerLayer { @@ -237,13 +212,12 @@ class ClipPathLayer extends ContainerLayer { Rect bounds; Path clipPath; - void paint(sky.Canvas canvas) { - canvas.saveLayer(bounds, _disableAntialias); - canvas.clipPath(clipPath); - canvas.translate(offset.dx, offset.dy); - paintChildren(canvas); - canvas.restore(); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + builder.pushClipPath(clipPath.shift(layerOffset), bounds.shift(layerOffset)); + addChildrenToScene(builder, offset + layerOffset); + builder.pop(); } + } class TransformLayer extends ContainerLayer { @@ -251,12 +225,12 @@ class TransformLayer extends ContainerLayer { Matrix4 transform; - void paint(sky.Canvas canvas) { - canvas.save(); - canvas.translate(offset.dx, offset.dy); - canvas.concat(transform.storage); - paintChildren(canvas); - canvas.restore(); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + Matrix4 offsetTransform = new Matrix4.identity(); + offsetTransform.translate(offset.dx + layerOffset.dx, offset.dy + layerOffset.dy); + builder.pushTransform((offsetTransform * transform).storage); + addChildrenToScene(builder, Offset.zero); + builder.pop(); } } @@ -267,18 +241,10 @@ class OpacityLayer extends ContainerLayer { Rect bounds; int alpha; - static Paint paintForAlpha(int alpha) { - return new Paint() - ..color = new Color.fromARGB(alpha, 0, 0, 0) - ..setTransferMode(sky.TransferMode.srcOver) - ..isAntiAlias = false; - } - - void paint(sky.Canvas canvas) { - canvas.saveLayer(bounds, paintForAlpha(alpha)); - canvas.translate(offset.dx, offset.dy); - paintChildren(canvas); - canvas.restore(); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + builder.pushOpacity(alpha, bounds == null ? null : bounds.shift(layerOffset)); + addChildrenToScene(builder, offset + layerOffset); + builder.pop(); } } @@ -295,16 +261,9 @@ class ColorFilterLayer extends ContainerLayer { Color color; sky.TransferMode transferMode; - static paintForColorFilter(Color color, sky.TransferMode transferMode) { - new Paint() - ..setColorFilter(new sky.ColorFilter.mode(color, transferMode)) - ..isAntiAlias = false; - } - - void paint(sky.Canvas canvas) { - canvas.saveLayer(bounds, paintForColorFilter(color, transferMode)); - canvas.translate(offset.dx, offset.dy); - paintChildren(canvas); - canvas.restore(); + void addToScene(sky.SceneBuilder builder, Offset layerOffset) { + builder.pushColorFilter(color, transferMode, bounds.shift(offset)); + addChildrenToScene(builder, offset + layerOffset); + builder.pop(); } } diff --git a/sky/packages/sky/lib/rendering/view.dart b/sky/packages/sky/lib/rendering/view.dart index 09ad7ec1a52..b1ede698fff 100644 --- a/sky/packages/sky/lib/rendering/view.dart +++ b/sky/packages/sky/lib/rendering/view.dart @@ -98,13 +98,10 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin void compositeFrame() { sky.tracing.begin('RenderView.compositeFrame'); try { - // Eventually we will want to pass the entire layer tree to the C++ side. - // For now, however, we take the layer tree and paint it into a Canvas, - // which we then hand to the C++ side. - sky.PictureRecorder recorder = new sky.PictureRecorder(); - sky.Canvas canvas = new sky.Canvas(recorder, Point.origin & (size * sky.view.devicePixelRatio)); - layer.paint(canvas); - sky.view.picture = recorder.endRecording(); + Rect bounds = Point.origin & (size * sky.view.devicePixelRatio); + sky.SceneBuilder builder = new sky.SceneBuilder(bounds); + layer.addToScene(builder, Offset.zero); + sky.view.scene = builder.build(); } finally { sky.tracing.end('RenderView.compositeFrame'); }