Merge pull request #1119 from chinmaygarde/master

Allow compositor options to be modified at runtime
This commit is contained in:
Chinmay Garde 2015-09-10 23:51:33 -07:00
commit 244de91699
27 changed files with 220 additions and 99 deletions

View File

@ -14,7 +14,8 @@ source_set("compositor") {
"clip_rrect_layer.h",
"color_filter_layer.cc",
"color_filter_layer.h",
"compositor_config.h",
"compositor_options.cc",
"compositor_options.h",
"container_layer.cc",
"container_layer.h",
"layer.cc",

View File

@ -13,12 +13,12 @@ ClipPathLayer::ClipPathLayer() {
ClipPathLayer::~ClipPathLayer() {
}
void ClipPathLayer::Paint(PaintContext& context) {
SkCanvas* canvas = context.canvas();
canvas->saveLayer(&clip_path_.getBounds(), nullptr);
canvas->clipPath(clip_path_);
PaintChildren(context);
canvas->restore();
void ClipPathLayer::Paint(PaintContext::ScopedFrame& frame) {
SkCanvas& canvas = frame.canvas();
canvas.saveLayer(&clip_path_.getBounds(), nullptr);
canvas.clipPath(clip_path_);
PaintChildren(frame);
canvas.restore();
}
} // namespace compositor

View File

@ -17,7 +17,8 @@ class ClipPathLayer : public ContainerLayer {
void set_clip_path(const SkPath& clip_path) { clip_path_ = clip_path; }
void Paint(PaintContext& context) override;
protected:
void Paint(PaintContext::ScopedFrame& frame) override;
private:
SkPath clip_path_;

View File

@ -13,12 +13,12 @@ ClipRectLayer::ClipRectLayer() {
ClipRectLayer::~ClipRectLayer() {
}
void ClipRectLayer::Paint(PaintContext& context) {
SkCanvas* canvas = context.canvas();
canvas->save();
canvas->clipRect(clip_rect_);
PaintChildren(context);
canvas->restore();
void ClipRectLayer::Paint(PaintContext::ScopedFrame& frame) {
SkCanvas& canvas = frame.canvas();
canvas.save();
canvas.clipRect(clip_rect_);
PaintChildren(frame);
canvas.restore();
}
} // namespace compositor

View File

@ -17,7 +17,8 @@ class ClipRectLayer : public ContainerLayer {
void set_clip_rect(const SkRect& clip_rect) { clip_rect_ = clip_rect; }
void Paint(PaintContext& context) override;
protected:
void Paint(PaintContext::ScopedFrame& frame) override;
private:
SkRect clip_rect_;

View File

@ -13,12 +13,12 @@ ClipRRectLayer::ClipRRectLayer() {
ClipRRectLayer::~ClipRRectLayer() {
}
void ClipRRectLayer::Paint(PaintContext& context) {
SkCanvas* canvas = context.canvas();
canvas->saveLayer(&clip_rrect_.getBounds(), nullptr);
canvas->clipRRect(clip_rrect_);
PaintChildren(context);
canvas->restore();
void ClipRRectLayer::Paint(PaintContext::ScopedFrame& frame) {
SkCanvas& canvas = frame.canvas();
canvas.saveLayer(&clip_rrect_.getBounds(), nullptr);
canvas.clipRRect(clip_rrect_);
PaintChildren(frame);
canvas.restore();
}
} // namespace compositor

View File

@ -17,7 +17,7 @@ class ClipRRectLayer : public ContainerLayer {
void set_clip_rrect(const SkRRect& clip_rrect) { clip_rrect_ = clip_rrect; }
void Paint(PaintContext& context) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
SkRRect clip_rrect_;

View File

@ -13,15 +13,15 @@ ColorFilterLayer::ColorFilterLayer() {
ColorFilterLayer::~ColorFilterLayer() {
}
void ColorFilterLayer::Paint(PaintContext& context) {
void ColorFilterLayer::Paint(PaintContext::ScopedFrame& frame) {
RefPtr<SkColorFilter> color_filter =
adoptRef(SkColorFilter::CreateModeFilter(color_, transfer_mode_));
SkPaint paint;
paint.setColorFilter(color_filter.get());
SkCanvas* canvas = context.canvas();
canvas->saveLayer(&paint_bounds(), &paint);
PaintChildren(context);
canvas->restore();
SkCanvas& canvas = frame.canvas();
canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(frame);
canvas.restore();
}
} // namespace compositor

View File

@ -21,7 +21,7 @@ class ColorFilterLayer : public ContainerLayer {
transfer_mode_ = transfer_mode;
}
void Paint(PaintContext& context) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
SkColor color_;

View File

@ -1,13 +0,0 @@
// 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_COMPOSITOR_CONFIG_H_
#define SKY_COMPOSITOR_COMPOSITOR_CONFIG_H_
// SkPictures that dont mutate from frame to frame are rasterized by the picture
// rasterizer. This guard enables highlighting the rasterized images. Useful
// when debugging caching
#define COMPOSITOR_HIGHLIGHT_RASTERIZED_PICTURES 0
#endif // SKY_COMPOSITOR_COMPOSITOR_CONFIG_H_

View File

@ -0,0 +1,34 @@
// 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/compositor_options.h"
namespace sky {
namespace compositor {
CompositorOptions::CompositorOptions() {
static_assert(std::is_unsigned<OptionType>::value,
"OptionType must be unsigned");
options_.resize(static_cast<OptionType>(Option::TerminationSentinel), false);
}
bool CompositorOptions::isEnabled(Option option) const {
if (option >= Option::TerminationSentinel) {
return false;
}
return options_[static_cast<OptionType>(option)];
}
void CompositorOptions::setEnabled(Option option, bool enabled) {
if (option < Option::TerminationSentinel) {
options_[static_cast<OptionType>(option)] = enabled;
}
}
CompositorOptions::~CompositorOptions() {
}
} // namespace compositor
} // namespace sky

View File

@ -0,0 +1,42 @@
// 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_COMPOSITOR_OPTIONS_H_
#define SKY_COMPOSITOR_COMPOSITOR_OPTIONS_H_
#include "base/macros.h"
#include <vector>
namespace sky {
namespace compositor {
class CompositorOptions {
public:
using OptionType = unsigned int;
enum class Option : OptionType {
// SkPictures that dont mutate from frame to frame are rasterized by the
// picture rasterizer. This guard enables highlighting the rasterized
// images. Useful when debugging caching.
HightlightRasterizedImages,
TerminationSentinel,
};
CompositorOptions();
~CompositorOptions();
bool isEnabled(Option option) const;
void setEnabled(Option option, bool enabled);
private:
std::vector<bool> options_;
DISALLOW_COPY_AND_ASSIGN(CompositorOptions);
};
} // namespace compositor
} // namespace sky
#endif // SKY_COMPOSITOR_COMPOSITOR_OPTIONS_H_

View File

@ -18,9 +18,9 @@ void ContainerLayer::Add(std::unique_ptr<Layer> layer) {
layers_.push_back(std::move(layer));
}
void ContainerLayer::PaintChildren(PaintContext& context) const {
void ContainerLayer::PaintChildren(PaintContext::ScopedFrame& frame) const {
for (auto& layer : layers_)
layer->Paint(context);
layer->Paint(frame);
}
} // namespace compositor

View File

@ -17,7 +17,7 @@ class ContainerLayer : public Layer {
void Add(std::unique_ptr<Layer> layer);
void PaintChildren(PaintContext& context) const;
void PaintChildren(PaintContext::ScopedFrame& frame) const;
const std::vector<std::unique_ptr<Layer>>& layers() const { return layers_; }

View File

@ -32,7 +32,7 @@ class Layer {
Layer();
virtual ~Layer();
virtual void Paint(PaintContext& context) = 0;
virtual void Paint(PaintContext::ScopedFrame& frame) = 0;
virtual SkMatrix model_view_matrix(const SkMatrix& model_matrix) const;

View File

@ -13,16 +13,16 @@ OpacityLayer::OpacityLayer() {
OpacityLayer::~OpacityLayer() {
}
void OpacityLayer::Paint(PaintContext& context) {
void OpacityLayer::Paint(PaintContext::ScopedFrame& frame) {
SkColor color = SkColorSetARGB(alpha_, 0, 0, 0);
RefPtr<SkColorFilter> colorFilter = adoptRef(
SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode));
SkPaint paint;
paint.setColorFilter(colorFilter.get());
SkCanvas* canvas = context.canvas();
canvas->saveLayer(&paint_bounds(), &paint);
PaintChildren(context);
canvas->restore();
SkCanvas& canvas = frame.canvas();
canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(frame);
canvas.restore();
}
} // namespace compositor

View File

@ -17,7 +17,8 @@ class OpacityLayer : public ContainerLayer {
void set_alpha(int alpha) { alpha_ = alpha; }
void Paint(PaintContext& context) override;
protected:
void Paint(PaintContext::ScopedFrame& frame) override;
private:
int alpha_;

View File

@ -3,14 +3,24 @@
// found in the LICENSE file.
#include "sky/compositor/paint_context.h"
#include "base/logging.h"
namespace sky {
namespace compositor {
PaintContext::PaintContext(PictureRasterzier& rasterizer,
GrContext* gr_context,
SkCanvas* canvas)
: rasterizer_(rasterizer), gr_context_(gr_context), canvas_(canvas) {
PaintContext::PaintContext() {
}
void PaintContext::beginFrame() {
}
void PaintContext::endFrame() {
rasterizer_.PurgeCache();
}
PaintContext::ScopedFrame PaintContext::AcquireFrame(SkCanvas& canvas,
GrContext* gr_context) {
return ScopedFrame(*this, canvas, gr_context);
}
PaintContext::~PaintContext() {

View File

@ -6,6 +6,8 @@
#define SKY_COMPOSITOR_PAINT_CONTEXT_CC_
#include "base/macros.h"
#include "base/logging.h"
#include "sky/compositor/compositor_options.h"
#include "sky/compositor/picture_rasterizer.h"
namespace sky {
@ -13,21 +15,52 @@ namespace compositor {
class PaintContext {
public:
PaintContext(PictureRasterzier& rasterizer,
GrContext* gr_context,
SkCanvas* canvas);
class ScopedFrame {
public:
PaintContext& paint_context() { return context_; };
GrContext* gr_context() { return gr_context_; }
SkCanvas& canvas() { return canvas_; }
ScopedFrame(ScopedFrame&& frame) = default;
~ScopedFrame() { context_.endFrame(); }
private:
PaintContext& context_;
SkCanvas& canvas_;
GrContext* gr_context_;
ScopedFrame() = delete;
ScopedFrame(PaintContext& context, SkCanvas& canvas, GrContext* gr_context)
: context_(context), canvas_(canvas), gr_context_(gr_context) {
DCHECK(&canvas) << "The frame requries a valid canvas";
context_.beginFrame();
};
friend class PaintContext;
DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
};
PaintContext();
~PaintContext();
PictureRasterzier& rasterizer() { return rasterizer_; }
GrContext* gr_context() { return gr_context_; }
CompositorOptions& options() { return options_; };
SkCanvas* canvas() { return canvas_; }
ScopedFrame AcquireFrame(SkCanvas& canvas, GrContext* gr_context);
private:
PictureRasterzier& rasterizer_;
GrContext* gr_context_;
SkCanvas* canvas_;
PictureRasterzier rasterizer_;
CompositorOptions options_;
void beginFrame();
void endFrame();
DISALLOW_COPY_AND_ASSIGN(PaintContext);
};

View File

@ -20,23 +20,24 @@ SkMatrix PictureLayer::model_view_matrix(const SkMatrix& model_matrix) const {
return modelView;
}
void PictureLayer::Paint(PaintContext& context) {
void PictureLayer::Paint(PaintContext::ScopedFrame& frame) {
DCHECK(picture_);
const SkRect& bounds = paint_bounds();
SkISize size = SkISize::Make(bounds.width(), bounds.height());
RefPtr<SkImage> image = context.rasterizer().GetCachedImageIfPresent(
context.gr_context(), picture_.get(), size);
SkCanvas* canvas = context.canvas();
RefPtr<SkImage> image =
frame.paint_context().rasterizer().GetCachedImageIfPresent(
frame.paint_context(), frame.gr_context(), picture_.get(), size);
SkCanvas& canvas = frame.canvas();
if (image) {
canvas->drawImage(image.get(), offset_.x(), offset_.y());
canvas.drawImage(image.get(), offset_.x(), offset_.y());
} else {
canvas->save();
canvas->translate(offset_.x(), offset_.y());
canvas->drawPicture(picture_.get());
canvas->restore();
canvas.save();
canvas.translate(offset_.x(), offset_.y());
canvas.drawPicture(picture_.get());
canvas.restore();
}
}

View File

@ -21,10 +21,10 @@ class PictureLayer : public Layer {
SkMatrix model_view_matrix(const SkMatrix& model_matrix) const override;
void Paint(PaintContext& context) override;
SkPicture* picture() const { return picture_.get(); }
void Paint(PaintContext::ScopedFrame& frame) override;
private:
SkPoint offset_;
RefPtr<SkPicture> picture_;

View File

@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sky/compositor/compositor_config.h"
#include "sky/compositor/compositor_options.h"
#include "sky/compositor/checkerboard.h"
#include "sky/compositor/picture_rasterizer.h"
#include "sky/compositor/paint_context.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/gpu/GrContext.h"
@ -37,7 +38,8 @@ PictureRasterzier::Value::Value()
PictureRasterzier::Value::~Value() {
}
static RefPtr<SkImage> ImageFromPicture(GrContext* context,
static RefPtr<SkImage> ImageFromPicture(PaintContext& context,
GrContext* gr_context,
SkPicture* picture,
const SkISize& size) {
// Step 1: Create a texture from the context's texture provider
@ -48,7 +50,7 @@ static RefPtr<SkImage> ImageFromPicture(GrContext* context,
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = kRGBA_8888_GrPixelConfig;
GrTexture* texture = context->textureProvider()->createTexture(desc, true);
GrTexture* texture = gr_context->textureProvider()->createTexture(desc, true);
if (!texture) {
// The texture provider could not allocate a texture backing. Render
@ -82,21 +84,25 @@ static RefPtr<SkImage> ImageFromPicture(GrContext* context,
canvas->drawPicture(picture);
#if COMPOSITOR_HIGHLIGHT_RASTERIZED_PICTURES
DrawCheckerboard(canvas, desc.fWidth, desc.fHeight);
#endif
if (context.options().isEnabled(
CompositorOptions::Option::HightlightRasterizedImages)) {
DrawCheckerboard(canvas, desc.fWidth, desc.fHeight);
}
// Step 4: Create an image representation from the texture
RefPtr<SkImage> image = adoptRef(SkImage::NewFromTexture(
context, backendDesc, kPremul_SkAlphaType, &ImageReleaseProc, texture));
RefPtr<SkImage> image = adoptRef(
SkImage::NewFromTexture(gr_context, backendDesc, kPremul_SkAlphaType,
&ImageReleaseProc, texture));
return image;
}
RefPtr<SkImage> PictureRasterzier::GetCachedImageIfPresent(GrContext* context,
SkPicture* picture,
SkISize size) {
if (size.isEmpty() || picture == nullptr || context == nullptr) {
RefPtr<SkImage> PictureRasterzier::GetCachedImageIfPresent(
PaintContext& context,
GrContext* gr_context,
SkPicture* picture,
SkISize size) {
if (size.isEmpty() || picture == nullptr || gr_context == nullptr) {
return nullptr;
}
@ -114,7 +120,7 @@ RefPtr<SkImage> PictureRasterzier::GetCachedImageIfPresent(GrContext* context,
<< "Did you forget to call purge_cache between frames?";
if (!value.image) {
value.image = ImageFromPicture(context, picture, size);
value.image = ImageFromPicture(context, gr_context, picture, size);
}
return value.image;

View File

@ -18,12 +18,14 @@
namespace sky {
namespace compositor {
class PaintContext;
class PictureRasterzier {
public:
PictureRasterzier();
~PictureRasterzier();
RefPtr<SkImage> GetCachedImageIfPresent(GrContext* context,
RefPtr<SkImage> GetCachedImageIfPresent(PaintContext& context,
GrContext* gr_context,
SkPicture* picture,
SkISize size);

View File

@ -19,12 +19,12 @@ SkMatrix TransformLayer::model_view_matrix(const SkMatrix& model_matrix) const {
return modelView;
}
void TransformLayer::Paint(PaintContext& context) {
SkCanvas* canvas = context.canvas();
canvas->save();
canvas->concat(transform_);
PaintChildren(context);
canvas->restore();
void TransformLayer::Paint(PaintContext::ScopedFrame& frame) {
SkCanvas& canvas = frame.canvas();
canvas.save();
canvas.concat(transform_);
PaintChildren(frame);
canvas.restore();
}
} // namespace compositor

View File

@ -19,7 +19,7 @@ class TransformLayer : public ContainerLayer {
SkMatrix model_view_matrix(const SkMatrix& model_matrix) const override;
void Paint(PaintContext& context) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
SkMatrix transform_;

View File

@ -78,8 +78,10 @@ void Rasterizer::Draw(scoped_ptr<compositor::LayerTree> layer_tree) {
SkCanvas* canvas = ganesh_surface_->canvas();
canvas->clear(SK_ColorBLACK);
compositor::PaintContext context(rasterizer_, ganesh_context_->gr(), canvas);
layer_tree->root_layer()->Paint(context);
{
auto frame = paint_context_.AcquireFrame(*canvas, ganesh_context_->gr());
layer_tree->root_layer()->Paint(frame);
}
canvas->flush();
surface_->SwapBuffers();

View File

@ -11,7 +11,7 @@
#include "sky/shell/gpu_delegate.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_widget_types.h"
#include "sky/compositor/picture_rasterizer.h"
#include "sky/compositor/paint_context.h"
class SkPicture;
@ -48,7 +48,7 @@ class Rasterizer : public GPUDelegate {
scoped_ptr<GaneshContext> ganesh_context_;
scoped_ptr<GaneshSurface> ganesh_surface_;
compositor::PictureRasterzier rasterizer_;
compositor::PaintContext paint_context_;
base::WeakPtrFactory<Rasterizer> weak_factory_;