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

Compute paint bounds from cull rects

Rather than relying upon the rects passed in from Dart, the compositor
should compute the paint bounds of layers from the cull rects of the
underlying SkPictures. This approach is better because it will handle
effects like shadows that paint outside the incorrect paint bounds we
use today (as well as shrinking around empty space).
上级 ad8b3de9
...@@ -13,13 +13,18 @@ ColorFilterLayer::ColorFilterLayer() { ...@@ -13,13 +13,18 @@ ColorFilterLayer::ColorFilterLayer() {
ColorFilterLayer::~ColorFilterLayer() { ColorFilterLayer::~ColorFilterLayer() {
} }
void ColorFilterLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
ContainerLayer::Preroll(context, matrix);
set_paint_bounds(context->child_paint_bounds);
}
void ColorFilterLayer::Paint(PaintContext::ScopedFrame& frame) { void ColorFilterLayer::Paint(PaintContext::ScopedFrame& frame) {
RefPtr<SkColorFilter> color_filter = RefPtr<SkColorFilter> color_filter =
adoptRef(SkColorFilter::CreateModeFilter(color_, transfer_mode_)); adoptRef(SkColorFilter::CreateModeFilter(color_, transfer_mode_));
SkPaint paint; SkPaint paint;
paint.setColorFilter(color_filter.get()); paint.setColorFilter(color_filter.get());
SkCanvas& canvas = frame.canvas(); SkCanvas& canvas = frame.canvas();
canvas.saveLayer(has_paint_bounds() ? &paint_bounds() : nullptr, &paint); canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(frame); PaintChildren(frame);
canvas.restore(); canvas.restore();
} }
......
...@@ -21,6 +21,8 @@ class ColorFilterLayer : public ContainerLayer { ...@@ -21,6 +21,8 @@ class ColorFilterLayer : public ContainerLayer {
transfer_mode_ = transfer_mode; transfer_mode_ = transfer_mode;
} }
protected:
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override; void Paint(PaintContext::ScopedFrame& frame) override;
private: private:
......
...@@ -18,15 +18,19 @@ void ContainerLayer::Add(std::unique_ptr<Layer> layer) { ...@@ -18,15 +18,19 @@ void ContainerLayer::Add(std::unique_ptr<Layer> layer) {
layers_.push_back(std::move(layer)); layers_.push_back(std::move(layer));
} }
void ContainerLayer::Preroll(PaintContext::ScopedFrame& frame, void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
const SkMatrix& matrix) { PrerollChildren(context, matrix);
PrerollChildren(frame, matrix);
} }
void ContainerLayer::PrerollChildren(PaintContext::ScopedFrame& frame, void ContainerLayer::PrerollChildren(PrerollContext* context,
const SkMatrix& matrix) { const SkMatrix& matrix) {
for (auto& layer : layers_) SkRect child_paint_bounds;
layer->Preroll(frame, matrix); for (auto& layer : layers_) {
PrerollContext child_context = *context;
layer->Preroll(&child_context, matrix);
child_paint_bounds.join(child_context.child_paint_bounds);
}
context->child_paint_bounds = child_paint_bounds;
} }
void ContainerLayer::PaintChildren(PaintContext::ScopedFrame& frame) const { void ContainerLayer::PaintChildren(PaintContext::ScopedFrame& frame) const {
......
...@@ -18,10 +18,9 @@ class ContainerLayer : public Layer { ...@@ -18,10 +18,9 @@ class ContainerLayer : public Layer {
void Add(std::unique_ptr<Layer> layer); void Add(std::unique_ptr<Layer> layer);
void Preroll(PaintContext::ScopedFrame& frame, void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
const SkMatrix& matrix) override; void PrerollChildren(PrerollContext* context, const SkMatrix& matrix);
void PrerollChildren(PaintContext::ScopedFrame& frame, const SkMatrix& matrix);
void PaintChildren(PaintContext::ScopedFrame& frame) const; void PaintChildren(PaintContext::ScopedFrame& frame) const;
const std::vector<std::unique_ptr<Layer>>& layers() const { return layers_; } const std::vector<std::unique_ptr<Layer>>& layers() const { return layers_; }
......
...@@ -18,7 +18,7 @@ Layer::Layer() ...@@ -18,7 +18,7 @@ Layer::Layer()
Layer::~Layer() { Layer::~Layer() {
} }
void Layer::Preroll(PaintContext::ScopedFrame& frame, const SkMatrix& matrix) { void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
} }
} // namespace compositor } // namespace compositor
......
...@@ -31,8 +31,12 @@ class Layer { ...@@ -31,8 +31,12 @@ class Layer {
Layer(); Layer();
virtual ~Layer(); virtual ~Layer();
virtual void Preroll(PaintContext::ScopedFrame& frame, struct PrerollContext {
const SkMatrix& matrix); PaintContext::ScopedFrame& frame;
SkRect child_paint_bounds;
};
virtual void Preroll(PrerollContext* context, const SkMatrix& matrix);
virtual void Paint(PaintContext::ScopedFrame& frame) = 0; virtual void Paint(PaintContext::ScopedFrame& frame) = 0;
ContainerLayer* parent() const { return parent_; } ContainerLayer* parent() const { return parent_; }
......
...@@ -16,7 +16,8 @@ LayerTree::~LayerTree() { ...@@ -16,7 +16,8 @@ LayerTree::~LayerTree() {
} }
void LayerTree::Raster(PaintContext::ScopedFrame& frame) { void LayerTree::Raster(PaintContext::ScopedFrame& frame) {
root_layer_->Preroll(frame, SkMatrix()); Layer::PrerollContext context = { frame, SkRect::MakeEmpty() };
root_layer_->Preroll(&context, SkMatrix());
root_layer_->Paint(frame); root_layer_->Paint(frame);
} }
......
...@@ -13,12 +13,17 @@ OpacityLayer::OpacityLayer() { ...@@ -13,12 +13,17 @@ OpacityLayer::OpacityLayer() {
OpacityLayer::~OpacityLayer() { OpacityLayer::~OpacityLayer() {
} }
void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
ContainerLayer::Preroll(context, matrix);
set_paint_bounds(context->child_paint_bounds);
}
void OpacityLayer::Paint(PaintContext::ScopedFrame& frame) { void OpacityLayer::Paint(PaintContext::ScopedFrame& frame) {
SkPaint paint; SkPaint paint;
paint.setColor(SkColorSetARGB(alpha_, 0, 0, 0)); paint.setColor(SkColorSetARGB(alpha_, 0, 0, 0));
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
SkCanvas& canvas = frame.canvas(); SkCanvas& canvas = frame.canvas();
canvas.saveLayer(has_paint_bounds() ? &paint_bounds() : nullptr, &paint); canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(frame); PaintChildren(frame);
canvas.restore(); canvas.restore();
} }
......
...@@ -18,6 +18,7 @@ class OpacityLayer : public ContainerLayer { ...@@ -18,6 +18,7 @@ class OpacityLayer : public ContainerLayer {
void set_alpha(int alpha) { alpha_ = alpha; } void set_alpha(int alpha) { alpha_ = alpha; }
protected: protected:
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override; void Paint(PaintContext::ScopedFrame& frame) override;
private: private:
......
...@@ -20,10 +20,11 @@ PictureLayer::PictureLayer() { ...@@ -20,10 +20,11 @@ PictureLayer::PictureLayer() {
PictureLayer::~PictureLayer() { PictureLayer::~PictureLayer() {
} }
void PictureLayer::Preroll(PaintContext::ScopedFrame& frame, void PictureLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) { const SkMatrix& matrix) {
image_ = frame.context().raster_cache().GetPrerolledImage( image_ = context->frame.context().raster_cache().GetPrerolledImage(
frame.gr_context(), picture_.get(), matrix); context->frame.gr_context(), picture_.get(), matrix);
context->child_paint_bounds = picture_->cullRect();
} }
void PictureLayer::Paint(PaintContext::ScopedFrame& frame) { void PictureLayer::Paint(PaintContext::ScopedFrame& frame) {
...@@ -44,10 +45,9 @@ void PictureLayer::Paint(PaintContext::ScopedFrame& frame) { ...@@ -44,10 +45,9 @@ void PictureLayer::Paint(PaintContext::ScopedFrame& frame) {
canvas.drawImage(image_.get(), dx, dy); canvas.drawImage(image_.get(), dx, dy);
canvas.restore(); canvas.restore();
if (kDebugCheckerboardRasterizedLayers) { if (kDebugCheckerboardRasterizedLayers)
SkRect rect = paint_bounds().makeOffset(offset_.x(), offset_.y()); DrawCheckerboard(&canvas, rect.makeOffset(offset_.x(), offset_.y()));
DrawCheckerboard(&canvas, rect);
}
} else { } else {
canvas.save(); canvas.save();
canvas.translate(offset_.x(), offset_.y()); canvas.translate(offset_.x(), offset_.y());
......
...@@ -21,8 +21,7 @@ class PictureLayer : public Layer { ...@@ -21,8 +21,7 @@ class PictureLayer : public Layer {
SkPicture* picture() const { return picture_.get(); } SkPicture* picture() const { return picture_.get(); }
void Preroll(PaintContext::ScopedFrame& frame, void Preroll(PrerollContext* frame, const SkMatrix& matrix) override;
const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override; void Paint(PaintContext::ScopedFrame& frame) override;
private: private:
......
...@@ -13,11 +13,11 @@ TransformLayer::TransformLayer() { ...@@ -13,11 +13,11 @@ TransformLayer::TransformLayer() {
TransformLayer::~TransformLayer() { TransformLayer::~TransformLayer() {
} }
void TransformLayer::Preroll(PaintContext::ScopedFrame& frame, void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
const SkMatrix& matrix) {
SkMatrix childMatrix; SkMatrix childMatrix;
childMatrix.setConcat(matrix, transform_); childMatrix.setConcat(matrix, transform_);
PrerollChildren(frame, childMatrix); PrerollChildren(context, childMatrix);
transform_.mapRect(&context->child_paint_bounds);
} }
void TransformLayer::Paint(PaintContext::ScopedFrame& frame) { void TransformLayer::Paint(PaintContext::ScopedFrame& frame) {
......
...@@ -17,8 +17,7 @@ class TransformLayer : public ContainerLayer { ...@@ -17,8 +17,7 @@ class TransformLayer : public ContainerLayer {
void set_transform(const SkMatrix& transform) { transform_ = transform; } void set_transform(const SkMatrix& transform) { transform_ = transform; }
void Preroll(PaintContext::ScopedFrame& frame, void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override; void Paint(PaintContext::ScopedFrame& frame) override;
private: private:
......
...@@ -62,8 +62,7 @@ FOR_EACH_BINDING(DART_REGISTER_NATIVE) ...@@ -62,8 +62,7 @@ FOR_EACH_BINDING(DART_REGISTER_NATIVE)
} }
SceneBuilder::SceneBuilder(const Rect& bounds) SceneBuilder::SceneBuilder(const Rect& bounds)
: m_rootPaintBounds(bounds.sk_rect) : m_currentLayer(nullptr)
, m_currentLayer(nullptr)
, m_currentRasterizerTracingThreshold(0) , m_currentRasterizerTracingThreshold(0)
{ {
} }
...@@ -106,8 +105,6 @@ void SceneBuilder::pushClipPath(const CanvasPath* path, const Rect& bounds) ...@@ -106,8 +105,6 @@ void SceneBuilder::pushClipPath(const CanvasPath* path, const Rect& bounds)
void SceneBuilder::pushOpacity(int alpha, const Rect& bounds) void SceneBuilder::pushOpacity(int alpha, const Rect& bounds)
{ {
std::unique_ptr<sky::compositor::OpacityLayer> layer(new sky::compositor::OpacityLayer()); std::unique_ptr<sky::compositor::OpacityLayer> layer(new sky::compositor::OpacityLayer());
if (!bounds.is_null)
layer->set_paint_bounds(bounds.sk_rect);
layer->set_alpha(alpha); layer->set_alpha(alpha);
addLayer(std::move(layer)); addLayer(std::move(layer));
} }
...@@ -115,8 +112,6 @@ void SceneBuilder::pushOpacity(int alpha, const Rect& bounds) ...@@ -115,8 +112,6 @@ void SceneBuilder::pushOpacity(int alpha, const Rect& bounds)
void SceneBuilder::pushColorFilter(CanvasColor color, TransferMode transferMode, const Rect& bounds) void SceneBuilder::pushColorFilter(CanvasColor color, TransferMode transferMode, const Rect& bounds)
{ {
std::unique_ptr<sky::compositor::ColorFilterLayer> layer(new sky::compositor::ColorFilterLayer()); std::unique_ptr<sky::compositor::ColorFilterLayer> layer(new sky::compositor::ColorFilterLayer());
if (!bounds.is_null)
layer->set_paint_bounds(bounds.sk_rect);
layer->set_color(color); layer->set_color(color);
layer->set_transfer_mode(transferMode); layer->set_transfer_mode(transferMode);
addLayer(std::move(layer)); addLayer(std::move(layer));
...@@ -128,7 +123,6 @@ void SceneBuilder::addLayer(std::unique_ptr<sky::compositor::ContainerLayer> lay ...@@ -128,7 +123,6 @@ void SceneBuilder::addLayer(std::unique_ptr<sky::compositor::ContainerLayer> lay
if (!m_rootLayer) { if (!m_rootLayer) {
DCHECK(!m_currentLayer); DCHECK(!m_currentLayer);
m_rootLayer = std::move(layer); m_rootLayer = std::move(layer);
m_rootLayer->set_paint_bounds(m_rootPaintBounds);
m_currentLayer = m_rootLayer.get(); m_currentLayer = m_rootLayer.get();
return; return;
} }
...@@ -153,8 +147,6 @@ void SceneBuilder::addPicture(const Offset& offset, Picture* picture, const Rect ...@@ -153,8 +147,6 @@ void SceneBuilder::addPicture(const Offset& offset, Picture* picture, const Rect
std::unique_ptr<sky::compositor::PictureLayer> layer(new sky::compositor::PictureLayer()); std::unique_ptr<sky::compositor::PictureLayer> layer(new sky::compositor::PictureLayer());
layer->set_offset(SkPoint::Make(offset.sk_size.width(), offset.sk_size.height())); layer->set_offset(SkPoint::Make(offset.sk_size.width(), offset.sk_size.height()));
layer->set_picture(picture->toSkia()); layer->set_picture(picture->toSkia());
if (!paintBounds.is_null)
layer->set_paint_bounds(paintBounds.sk_rect);
m_currentLayer->Add(std::move(layer)); m_currentLayer->Add(std::move(layer));
} }
......
...@@ -57,7 +57,6 @@ private: ...@@ -57,7 +57,6 @@ private:
void addLayer(std::unique_ptr<sky::compositor::ContainerLayer> layer); void addLayer(std::unique_ptr<sky::compositor::ContainerLayer> layer);
SkRect m_rootPaintBounds;
std::unique_ptr<sky::compositor::ContainerLayer> m_rootLayer; std::unique_ptr<sky::compositor::ContainerLayer> m_rootLayer;
sky::compositor::ContainerLayer* m_currentLayer; sky::compositor::ContainerLayer* m_currentLayer;
int32_t m_currentRasterizerTracingThreshold; int32_t m_currentRasterizerTracingThreshold;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册