提交 ec232fff 编写于 作者: A Adam Barth

Merge pull request #809 from abarth/scene_builder

Use sky.SceneBuilder to upload Layer tree to C++
// 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> Scene::create(PassRefPtr<SkPicture> picture)
{
ASSERT(picture);
return adoptRef(new Scene(picture));
}
Scene::Scene(PassRefPtr<SkPicture> picture)
: m_picture(picture)
{
}
Scene::~Scene()
{
}
} // namespace blink
// 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<Scene>, public DartWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
~Scene() override;
static PassRefPtr<Scene> create(PassRefPtr<SkPicture> skPicture);
SkPicture* toSkia() const { return m_picture.get(); }
private:
explicit Scene(PassRefPtr<SkPicture> skPicture);
// While bootstraping the compositing system, we use an SkPicture instead
// of a layer tree to back the scene.
RefPtr<SkPicture> m_picture;
};
} // namespace blink
#endif // SKY_ENGINE_CORE_COMPOSITING_SCENE_H_
// 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 {
};
// 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<SkColorFilter> 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<SkColorFilter> 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<Scene> SceneBuilder::build()
{
RefPtr<Scene> scene = Scene::create(adoptRef(m_pictureRecorder.endRecording()));
m_canvas = nullptr;
return scene.release();
}
} // namespace blink
// 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<SceneBuilder>, public DartWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
static PassRefPtr<SceneBuilder> 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<Scene> 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_
// 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();
};
......@@ -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",
......
......@@ -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)
......
......@@ -14,4 +14,10 @@ CanvasPath::~CanvasPath()
{
}
PassRefPtr<CanvasPath> CanvasPath::shift(const Offset& offset) {
RefPtr<CanvasPath> path = CanvasPath::create();
m_path.offset(offset.sk_size.width(), offset.sk_size.height(), &path->m_path);
return path.release();
}
} // namespace blink
......@@ -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<CanvasPath> shift(const Offset& offset);
private:
CanvasPath();
......
// 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
// 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_
......@@ -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);
};
......@@ -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> RRect::shift(const Offset& offset) {
RefPtr<RRect> 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
......@@ -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<RRect> shift(const Offset& offset);
private:
RRect();
......
......@@ -6,4 +6,6 @@
Constructor(),
] interface RRect {
void setRectXY(Rect rect, float xRad, float yRad);
RRect shift(Offset offset);
};
......@@ -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<EventCallback> callback);
void setMetricsChangedCallback(PassOwnPtr<VoidCallback> callback);
......@@ -57,6 +61,7 @@ private:
OwnPtr<VoidCallback> m_metricsChangedCallback;
OwnPtr<FrameCallback> m_frameCallback;
RefPtr<Picture> m_picture;
RefPtr<Scene> m_scene;
};
} // namespace blink
......
......@@ -15,6 +15,7 @@ interface View {
readonly attribute double height;
attribute Picture picture;
attribute Scene scene;
void setEventCallback(EventCallback callback);
void setMetricsChangedCallback(VoidCallback callback);
......
......@@ -53,6 +53,8 @@ void SkyView::BeginFrame(base::TimeTicks frame_time) {
}
PassRefPtr<SkPicture> SkyView::Paint() {
if (Scene* scene = view_->scene())
return scene->toSkia();
if (Picture* picture = view_->picture())
return picture->toSkia();
return nullptr;
......
......@@ -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();
}
}
......@@ -98,13 +98,10 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
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');
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册