Make the paint context own the rasterizer and options. Also give it the ability to vend frames to render into.

This commit is contained in:
Chinmay Garde 2015-09-10 16:41:54 -07:00
parent ccf1ee8661
commit 08da55706c
23 changed files with 132 additions and 66 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,13 +9,6 @@
namespace sky {
namespace compositor {
CompositorOptions& CompositorOptions::Shared() {
static std::once_flag once;
static CompositorOptions* options = nullptr;
std::call_once(once, []() { options = new CompositorOptions(); });
return *options;
}
CompositorOptions::CompositorOptions() {
static_assert(std::is_unsigned<OptionType>::value,
"OptionType must be unsigned");

View File

@ -23,7 +23,8 @@ class CompositorOptions {
TerminationSentinel,
};
static CompositorOptions& Shared();
CompositorOptions();
~CompositorOptions();
bool isEnabled(Option option) const;
@ -32,9 +33,6 @@ class CompositorOptions {
private:
std::vector<bool> options_;
CompositorOptions();
~CompositorOptions();
DISALLOW_COPY_AND_ASSIGN(CompositorOptions);
};

View File

@ -32,7 +32,7 @@ class Layer {
Layer();
virtual ~Layer();
virtual void Paint(PaintContext& context) = 0;
void Paint(PaintContext::ScopedFrame& frame) { Paint(frame.paint_context()); }
virtual SkMatrix model_view_matrix(const SkMatrix& model_matrix) const;
@ -46,10 +46,15 @@ class Layer {
paint_bounds_ = paint_bounds;
}
protected:
virtual void Paint(PaintContext& context) = 0;
private:
ContainerLayer* parent_;
SkRect paint_bounds_;
friend class ContainerLayer;
DISALLOW_COPY_AND_ASSIGN(Layer);
};

View File

@ -19,10 +19,10 @@ void OpacityLayer::Paint(PaintContext& context) {
SkColorFilter::CreateModeFilter(color, SkXfermode::kSrcOver_Mode));
SkPaint paint;
paint.setColorFilter(colorFilter.get());
SkCanvas* canvas = context.canvas();
canvas->saveLayer(&paint_bounds(), &paint);
SkCanvas& canvas = context.canvas();
canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(context);
canvas->restore();
canvas.restore();
}
} // namespace compositor

View File

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

View File

@ -3,14 +3,33 @@
// 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(SkCanvas& canvas, GrContext* gr_context) {
canvas_ = &canvas; // required
gr_context_ = gr_context; // optional
DCHECK(canvas_);
}
void PaintContext::endFrame() {
DCHECK(canvas_);
rasterizer_.PurgeCache();
canvas_ = nullptr;
gr_context_ = nullptr;
}
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,22 +15,57 @@ namespace compositor {
class PaintContext {
public:
PaintContext(PictureRasterzier& rasterizer,
GrContext* gr_context,
SkCanvas* canvas);
class ScopedFrame {
public:
PaintContext& paint_context() { return context_; };
ScopedFrame(ScopedFrame&& frame) = default;
~ScopedFrame() { context_.endFrame(); }
private:
PaintContext& context_;
ScopedFrame() = delete;
ScopedFrame(PaintContext& context, SkCanvas& canvas, GrContext* gr_context)
: context_(context) {
context_.beginFrame(canvas, gr_context);
};
friend class PaintContext;
DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
};
PaintContext();
~PaintContext();
PictureRasterzier& rasterizer() { return rasterizer_; }
CompositorOptions& options() { return options_; };
GrContext* gr_context() { return gr_context_; }
SkCanvas* canvas() { return canvas_; }
SkCanvas& canvas() {
DCHECK(canvas_) << "Tried to access the canvas of a context whose frame "
"was not initialized. Did you forget to "
"`AcquireFrame`?";
return *canvas_;
}
ScopedFrame AcquireFrame(SkCanvas& canvas, GrContext* gr_context);
private:
PictureRasterzier& rasterizer_;
PictureRasterzier rasterizer_;
CompositorOptions options_;
GrContext* gr_context_;
SkCanvas* canvas_;
void beginFrame(SkCanvas& canvas, GrContext* context);
void endFrame();
DISALLOW_COPY_AND_ASSIGN(PaintContext);
};

View File

@ -27,16 +27,16 @@ void PictureLayer::Paint(PaintContext& context) {
SkISize size = SkISize::Make(bounds.width(), bounds.height());
RefPtr<SkImage> image = context.rasterizer().GetCachedImageIfPresent(
context.gr_context(), picture_.get(), size);
SkCanvas* canvas = context.canvas();
context, picture_.get(), size);
SkCanvas& canvas = context.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,11 @@ 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(); }
protected:
void Paint(PaintContext& context) override;
private:
SkPoint offset_;
RefPtr<SkPicture> picture_;

View File

@ -5,6 +5,7 @@
#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,7 @@ PictureRasterzier::Value::Value()
PictureRasterzier::Value::~Value() {
}
static RefPtr<SkImage> ImageFromPicture(GrContext* context,
static RefPtr<SkImage> ImageFromPicture(PaintContext& context,
SkPicture* picture,
const SkISize& size) {
// Step 1: Create a texture from the context's texture provider
@ -48,7 +49,8 @@ static RefPtr<SkImage> ImageFromPicture(GrContext* context,
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = kRGBA_8888_GrPixelConfig;
GrTexture* texture = context->textureProvider()->createTexture(desc, true);
GrTexture* texture =
context.gr_context()->textureProvider()->createTexture(desc, true);
if (!texture) {
// The texture provider could not allocate a texture backing. Render
@ -82,22 +84,24 @@ static RefPtr<SkImage> ImageFromPicture(GrContext* context,
canvas->drawPicture(picture);
if (CompositorOptions::Shared().isEnabled(
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(context.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,
SkPicture* picture,
SkISize size) {
if (size.isEmpty() || picture == nullptr || context.gr_context() == nullptr) {
return nullptr;
}

View File

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

View File

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

View File

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

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_;