mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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:
parent
ccf1ee8661
commit
08da55706c
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -21,6 +21,7 @@ class ColorFilterLayer : public ContainerLayer {
|
||||
transfer_mode_ = transfer_mode;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Paint(PaintContext& context) override;
|
||||
|
||||
private:
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -17,6 +17,7 @@ class OpacityLayer : public ContainerLayer {
|
||||
|
||||
void set_alpha(int alpha) { alpha_ = alpha; }
|
||||
|
||||
protected:
|
||||
void Paint(PaintContext& context) override;
|
||||
|
||||
private:
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user