Merge pull request #1031 from abarth/sky_scene_compositor

SceneBuilder should build a tree of layers
This commit is contained in:
Adam Barth
2015-09-02 18:27:32 -07:00
9 changed files with 406 additions and 56 deletions
+16
View File
@@ -0,0 +1,16 @@
# 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.
source_set("compositor") {
sources = [
"layer.cc",
"layer.h",
]
deps = [
"//base",
"//skia",
"//sky/engine/wtf",
]
}
+130
View File
@@ -0,0 +1,130 @@
// 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/compositor/layer.h"
#include "third_party/skia/include/core/SkColorFilter.h"
namespace sky {
Layer::Layer() {
}
Layer::~Layer() {
}
PictureLayer::PictureLayer() {
}
PictureLayer::~PictureLayer() {
}
void PictureLayer::Paint(SkCanvas* canvas) {
canvas->save();
canvas->translate(offset_.x(), offset_.y());
canvas->drawPicture(picture_.get());
canvas->restore();
}
ContainerLayer::ContainerLayer() {
}
ContainerLayer::~ContainerLayer() {
}
void ContainerLayer::Add(std::unique_ptr<Layer> layer) {
layer->set_parent(this);
layers_.push_back(std::move(layer));
}
void ContainerLayer::PaintChildren(SkCanvas* canvas) {
for (auto& layer : layers_)
layer->Paint(canvas);
}
TransformLayer::TransformLayer() {
}
TransformLayer::~TransformLayer() {
}
void TransformLayer::Paint(SkCanvas* canvas) {
canvas->save();
canvas->concat(transform_);
PaintChildren(canvas);
canvas->restore();
}
ClipRectLayer::ClipRectLayer() {
}
ClipRectLayer::~ClipRectLayer() {
}
void ClipRectLayer::Paint(SkCanvas* canvas) {
canvas->save();
canvas->clipRect(clip_rect_);
PaintChildren(canvas);
canvas->restore();
}
ClipRRectLayer::ClipRRectLayer() {
}
ClipRRectLayer::~ClipRRectLayer() {
}
void ClipRRectLayer::Paint(SkCanvas* canvas) {
canvas->saveLayer(&clip_rrect_.getBounds(), nullptr);
canvas->clipRRect(clip_rrect_);
PaintChildren(canvas);
canvas->restore();
}
ClipPathLayer::ClipPathLayer() {
}
ClipPathLayer::~ClipPathLayer() {
}
void ClipPathLayer::Paint(SkCanvas* canvas) {
canvas->saveLayer(&clip_path_.getBounds(), nullptr);
canvas->clipPath(clip_path_);
PaintChildren(canvas);
canvas->restore();
}
OpacityLayer::OpacityLayer() {
}
OpacityLayer::~OpacityLayer() {
}
void OpacityLayer::Paint(SkCanvas* canvas) {
SkColor color = SkColorSetARGB(alpha_, 0, 0, 0);
RefPtr<SkColorFilter> colorFilter = adoptRef(SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode));
SkPaint paint;
paint.setColorFilter(colorFilter.get());
canvas->saveLayer(&paint_bounds(), &paint);
PaintChildren(canvas);
canvas->restore();
}
ColorFilterLayer::ColorFilterLayer() {
}
ColorFilterLayer::~ColorFilterLayer() {
}
void ColorFilterLayer::Paint(SkCanvas* canvas) {
RefPtr<SkColorFilter> color_filter =
adoptRef(SkColorFilter::CreateModeFilter(color_, transfer_mode_));
SkPaint paint;
paint.setColorFilter(color_filter.get());
canvas->saveLayer(&paint_bounds(), &paint);
PaintChildren(canvas);
canvas->restore();
}
} // namespace sky
+173
View File
@@ -0,0 +1,173 @@
// 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_COMPOSITOR_H_
#define SKY_COMPOSITOR_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "sky/engine/wtf/RefPtr.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkXfermode.h"
namespace sky {
class ContainerLayer;
class Layer {
public:
Layer();
virtual ~Layer();
virtual void Paint(SkCanvas* canvas) = 0;
ContainerLayer* parent() const { return parent_; }
void set_parent(ContainerLayer* parent) { parent_ = parent; }
const SkRect& paint_bounds() const { return paint_bounds_; }
void set_paint_bounds(const SkRect& paint_bounds) { paint_bounds_ = paint_bounds; }
private:
ContainerLayer* parent_;
SkRect paint_bounds_;
DISALLOW_COPY_AND_ASSIGN(Layer);
};
class PictureLayer : public Layer {
public:
PictureLayer();
~PictureLayer() override;
void Paint(SkCanvas* canvas) override;
void set_offset(const SkPoint& offset) { offset_ = offset; }
void set_picture(PassRefPtr<SkPicture> picture) { picture_ = picture; }
private:
SkPoint offset_;
RefPtr<SkPicture> picture_;
DISALLOW_COPY_AND_ASSIGN(PictureLayer);
};
class ContainerLayer : public Layer {
public:
ContainerLayer();
~ContainerLayer() override;
void Add(std::unique_ptr<Layer> layer);
void PaintChildren(SkCanvas* canvas);
private:
std::vector<std::unique_ptr<Layer>> layers_;
DISALLOW_COPY_AND_ASSIGN(ContainerLayer);
};
class TransformLayer : public ContainerLayer {
public:
TransformLayer();
~TransformLayer() override;
void Paint(SkCanvas* canvas) override;
void set_transform(const SkMatrix& transform) { transform_ = transform; }
private:
SkMatrix transform_;
DISALLOW_COPY_AND_ASSIGN(TransformLayer);
};
class ClipRectLayer : public ContainerLayer {
public:
ClipRectLayer();
~ClipRectLayer() override;
void Paint(SkCanvas* canvas) override;
void set_clip_rect(const SkRect& clip_rect) { clip_rect_ = clip_rect; }
private:
SkRect clip_rect_;
DISALLOW_COPY_AND_ASSIGN(ClipRectLayer);
};
class ClipRRectLayer : public ContainerLayer {
public:
ClipRRectLayer();
~ClipRRectLayer() override;
void Paint(SkCanvas* canvas) override;
void set_clip_rrect(const SkRRect& clip_rrect) { clip_rrect_ = clip_rrect; }
private:
SkRRect clip_rrect_;
DISALLOW_COPY_AND_ASSIGN(ClipRRectLayer);
};
class ClipPathLayer : public ContainerLayer {
public:
ClipPathLayer();
~ClipPathLayer() override;
void Paint(SkCanvas* canvas) override;
void set_clip_path(const SkPath& clip_path) { clip_path_ = clip_path; }
private:
SkPath clip_path_;
DISALLOW_COPY_AND_ASSIGN(ClipPathLayer);
};
class OpacityLayer : public ContainerLayer {
public:
OpacityLayer();
~OpacityLayer() override;
void Paint(SkCanvas* canvas) override;
void set_alpha(int alpha) { alpha_ = alpha; }
private:
int alpha_;
DISALLOW_COPY_AND_ASSIGN(OpacityLayer);
};
class ColorFilterLayer : public ContainerLayer {
public:
ColorFilterLayer();
~ColorFilterLayer() override;
void Paint(SkCanvas* canvas) override;
void set_color(SkColor color) { color_ = color; }
void set_transfer_mode(SkXfermode::Mode transfer_mode) { transfer_mode_ = transfer_mode; }
private:
SkColor color_;
SkXfermode::Mode transfer_mode_;
DISALLOW_COPY_AND_ASSIGN(ColorFilterLayer);
};
} // namespace sky
#endif // SKY_COMPOSITOR_H_
+1
View File
@@ -21,6 +21,7 @@ source_set("libraries") {
"//mojo/public/cpp/utility",
"//mojo/public/interfaces/application",
"//skia",
"//sky/compositor",
"//sky/engine/tonic:tonic",
"//sky/engine/wtf",
"//third_party/iccjpeg",
+18 -5
View File
@@ -4,16 +4,19 @@
#include "sky/engine/core/compositing/Scene.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
namespace blink {
PassRefPtr<Scene> Scene::create(PassRefPtr<SkPicture> picture)
PassRefPtr<Scene> Scene::create(std::unique_ptr<sky::Layer> rootLayer)
{
ASSERT(picture);
return adoptRef(new Scene(picture));
ASSERT(rootLayer);
return adoptRef(new Scene(std::move(rootLayer)));
}
Scene::Scene(PassRefPtr<SkPicture> picture)
: m_picture(picture)
Scene::Scene(std::unique_ptr<sky::Layer> rootLayer)
: m_rootLayer(std::move(rootLayer))
{
}
@@ -21,4 +24,14 @@ Scene::~Scene()
{
}
PassRefPtr<SkPicture> Scene::createPicture() const
{
SkRTreeFactory rtreeFactory;
SkPictureRecorder pictureRecorder;
SkCanvas* canvas = pictureRecorder.beginRecording(m_rootLayer->paint_bounds(),
&rtreeFactory, SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag);
m_rootLayer->Paint(canvas);
return adoptRef(pictureRecorder.endRecording());
}
} // namespace blink
+10 -7
View File
@@ -5,6 +5,9 @@
#ifndef SKY_ENGINE_CORE_COMPOSITING_SCENE_H_
#define SKY_ENGINE_CORE_COMPOSITING_SCENE_H_
#include <memory>
#include "sky/compositor/layer.h"
#include "sky/engine/tonic/dart_wrappable.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "sky/engine/wtf/RefCounted.h"
@@ -16,16 +19,16 @@ 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);
static PassRefPtr<Scene> create(std::unique_ptr<sky::Layer> rootLayer);
// While bootstraping the compositing system, we use an SkPicture instead
// of a layer tree to back the scene.
RefPtr<SkPicture> m_picture;
PassRefPtr<SkPicture> createPicture() const;
private:
explicit Scene(std::unique_ptr<sky::Layer> rootLayer);
std::unique_ptr<sky::Layer> m_rootLayer;
};
} // namespace blink
+49 -38
View File
@@ -10,9 +10,9 @@
namespace blink {
SceneBuilder::SceneBuilder(const Rect& bounds)
: m_rootPaintBounds(bounds.sk_rect)
, m_currentLayer(nullptr)
{
m_canvas = m_pictureRecorder.beginRecording(bounds.sk_rect,
&m_rtreeFactory, SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag);
}
SceneBuilder::~SceneBuilder()
@@ -24,77 +24,88 @@ 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);
std::unique_ptr<sky::TransformLayer> layer(new sky::TransformLayer());
layer->set_transform(sk_matrix);
addLayer(std::move(layer));
}
void SceneBuilder::pushClipRect(const Rect& rect)
{
if (!m_canvas)
return;
m_canvas->save();
m_canvas->clipRect(rect.sk_rect);
std::unique_ptr<sky::ClipRectLayer> layer(new sky::ClipRectLayer());
layer->set_clip_rect(rect.sk_rect);
addLayer(std::move(layer));
}
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());
std::unique_ptr<sky::ClipRRectLayer> layer(new sky::ClipRRectLayer());
layer->set_clip_rrect(rrect->rrect());
addLayer(std::move(layer));
}
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());
std::unique_ptr<sky::ClipPathLayer> layer(new sky::ClipPathLayer());
layer->set_clip_path(path->path());
addLayer(std::move(layer));
}
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);
std::unique_ptr<sky::OpacityLayer> layer(new sky::OpacityLayer());
layer->set_paint_bounds(bounds.sk_rect);
layer->set_alpha(alpha);
addLayer(std::move(layer));
}
void SceneBuilder::pushColorFilter(SkColor color, SkXfermode::Mode transferMode, const Rect& bounds)
{
if (!m_canvas)
std::unique_ptr<sky::ColorFilterLayer> layer(new sky::ColorFilterLayer());
layer->set_paint_bounds(bounds.sk_rect);
layer->set_color(color);
layer->set_transfer_mode(transferMode);
addLayer(std::move(layer));
}
void SceneBuilder::addLayer(std::unique_ptr<sky::ContainerLayer> layer)
{
DCHECK(layer);
if (!m_rootLayer) {
DCHECK(!m_currentLayer);
m_rootLayer = std::move(layer);
m_rootLayer->set_paint_bounds(m_rootPaintBounds);
m_currentLayer = m_rootLayer.get();
return;
RefPtr<SkColorFilter> colorFilter = adoptRef(SkColorFilter::CreateModeFilter(color, transferMode));
SkPaint paint;
paint.setColorFilter(colorFilter.get());
m_canvas->saveLayer(&bounds.sk_rect, &paint);
}
if (!m_currentLayer)
return;
sky::ContainerLayer* newLayer = layer.get();
m_currentLayer->Add(std::move(layer));
m_currentLayer = newLayer;
}
void SceneBuilder::pop()
{
if (!m_canvas)
if (!m_currentLayer)
return;
m_canvas->restore();
m_currentLayer = m_currentLayer->parent();
}
void SceneBuilder::addPicture(const Offset& offset, Picture* picture, const Rect& paintBounds)
{
if (!m_canvas)
if (!m_currentLayer)
return;
m_canvas->save();
m_canvas->translate(offset.sk_size.width(), offset.sk_size.height());
m_canvas->drawPicture(picture->toSkia());
m_canvas->restore();
std::unique_ptr<sky::PictureLayer> layer(new sky::PictureLayer());
layer->set_offset(SkPoint::Make(offset.sk_size.width(), offset.sk_size.height()));
layer->set_picture(picture->toSkia());
layer->set_paint_bounds(paintBounds.sk_rect);
m_currentLayer->Add(std::move(layer));
}
PassRefPtr<Scene> SceneBuilder::build()
{
RefPtr<Scene> scene = Scene::create(adoptRef(m_pictureRecorder.endRecording()));
m_canvas = nullptr;
return scene.release();
m_currentLayer = nullptr;
return Scene::create(std::move(m_rootLayer));
}
} // namespace blink
+8 -5
View File
@@ -5,6 +5,9 @@
#ifndef SKY_ENGINE_CORE_COMPOSITING_SCENEBUILDER_H_
#define SKY_ENGINE_CORE_COMPOSITING_SCENEBUILDER_H_
#include <memory>
#include "sky/compositor/layer.h"
#include "sky/engine/bindings/exception_state.h"
#include "sky/engine/core/compositing/Scene.h"
#include "sky/engine/core/painting/CanvasPath.h"
@@ -19,8 +22,6 @@
#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 {
@@ -47,9 +48,11 @@ public:
private:
explicit SceneBuilder(const Rect& bounds);
SkRTreeFactory m_rtreeFactory;
SkPictureRecorder m_pictureRecorder;
SkCanvas* m_canvas;
void addLayer(std::unique_ptr<sky::ContainerLayer> layer);
SkRect m_rootPaintBounds;
std::unique_ptr<sky::ContainerLayer> m_rootLayer;
sky::ContainerLayer* m_currentLayer;
};
} // namespace blink
+1 -1
View File
@@ -72,7 +72,7 @@ void SkyView::BeginFrame(base::TimeTicks frame_time) {
PassRefPtr<SkPicture> SkyView::Paint() {
if (Scene* scene = view_->scene())
return scene->toSkia();
return scene->createPicture();
if (Picture* picture = view_->picture())
return picture->toSkia();
return nullptr;