提交 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() {
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) {
RefPtr<SkColorFilter> color_filter =
adoptRef(SkColorFilter::CreateModeFilter(color_, transfer_mode_));
SkPaint paint;
paint.setColorFilter(color_filter.get());
SkCanvas& canvas = frame.canvas();
canvas.saveLayer(has_paint_bounds() ? &paint_bounds() : nullptr, &paint);
canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(frame);
canvas.restore();
}
......
......@@ -21,6 +21,8 @@ class ColorFilterLayer : public ContainerLayer {
transfer_mode_ = transfer_mode;
}
protected:
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
......
......@@ -18,15 +18,19 @@ void ContainerLayer::Add(std::unique_ptr<Layer> layer) {
layers_.push_back(std::move(layer));
}
void ContainerLayer::Preroll(PaintContext::ScopedFrame& frame,
const SkMatrix& matrix) {
PrerollChildren(frame, matrix);
void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
PrerollChildren(context, matrix);
}
void ContainerLayer::PrerollChildren(PaintContext::ScopedFrame& frame,
void ContainerLayer::PrerollChildren(PrerollContext* context,
const SkMatrix& matrix) {
for (auto& layer : layers_)
layer->Preroll(frame, matrix);
SkRect child_paint_bounds;
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 {
......
......@@ -18,10 +18,9 @@ class ContainerLayer : public Layer {
void Add(std::unique_ptr<Layer> layer);
void Preroll(PaintContext::ScopedFrame& frame,
const SkMatrix& matrix) override;
void Preroll(PrerollContext* context, 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;
const std::vector<std::unique_ptr<Layer>>& layers() const { return layers_; }
......
......@@ -18,7 +18,7 @@ Layer::Layer()
Layer::~Layer() {
}
void Layer::Preroll(PaintContext::ScopedFrame& frame, const SkMatrix& matrix) {
void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
}
} // namespace compositor
......
......@@ -31,8 +31,12 @@ class Layer {
Layer();
virtual ~Layer();
virtual void Preroll(PaintContext::ScopedFrame& frame,
const SkMatrix& matrix);
struct PrerollContext {
PaintContext::ScopedFrame& frame;
SkRect child_paint_bounds;
};
virtual void Preroll(PrerollContext* context, const SkMatrix& matrix);
virtual void Paint(PaintContext::ScopedFrame& frame) = 0;
ContainerLayer* parent() const { return parent_; }
......
......@@ -16,7 +16,8 @@ LayerTree::~LayerTree() {
}
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);
}
......
......@@ -13,12 +13,17 @@ 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) {
SkPaint paint;
paint.setColor(SkColorSetARGB(alpha_, 0, 0, 0));
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
SkCanvas& canvas = frame.canvas();
canvas.saveLayer(has_paint_bounds() ? &paint_bounds() : nullptr, &paint);
canvas.saveLayer(&paint_bounds(), &paint);
PaintChildren(frame);
canvas.restore();
}
......
......@@ -18,6 +18,7 @@ class OpacityLayer : public ContainerLayer {
void set_alpha(int alpha) { alpha_ = alpha; }
protected:
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
......
......@@ -20,10 +20,11 @@ PictureLayer::PictureLayer() {
PictureLayer::~PictureLayer() {
}
void PictureLayer::Preroll(PaintContext::ScopedFrame& frame,
void PictureLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
image_ = frame.context().raster_cache().GetPrerolledImage(
frame.gr_context(), picture_.get(), matrix);
image_ = context->frame.context().raster_cache().GetPrerolledImage(
context->frame.gr_context(), picture_.get(), matrix);
context->child_paint_bounds = picture_->cullRect();
}
void PictureLayer::Paint(PaintContext::ScopedFrame& frame) {
......@@ -44,10 +45,9 @@ void PictureLayer::Paint(PaintContext::ScopedFrame& frame) {
canvas.drawImage(image_.get(), dx, dy);
canvas.restore();
if (kDebugCheckerboardRasterizedLayers) {
SkRect rect = paint_bounds().makeOffset(offset_.x(), offset_.y());
DrawCheckerboard(&canvas, rect);
}
if (kDebugCheckerboardRasterizedLayers)
DrawCheckerboard(&canvas, rect.makeOffset(offset_.x(), offset_.y()));
} else {
canvas.save();
canvas.translate(offset_.x(), offset_.y());
......
......@@ -21,8 +21,7 @@ class PictureLayer : public Layer {
SkPicture* picture() const { return picture_.get(); }
void Preroll(PaintContext::ScopedFrame& frame,
const SkMatrix& matrix) override;
void Preroll(PrerollContext* frame, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
......
......@@ -13,11 +13,11 @@ TransformLayer::TransformLayer() {
TransformLayer::~TransformLayer() {
}
void TransformLayer::Preroll(PaintContext::ScopedFrame& frame,
const SkMatrix& matrix) {
void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
SkMatrix childMatrix;
childMatrix.setConcat(matrix, transform_);
PrerollChildren(frame, childMatrix);
PrerollChildren(context, childMatrix);
transform_.mapRect(&context->child_paint_bounds);
}
void TransformLayer::Paint(PaintContext::ScopedFrame& frame) {
......
......@@ -17,8 +17,7 @@ class TransformLayer : public ContainerLayer {
void set_transform(const SkMatrix& transform) { transform_ = transform; }
void Preroll(PaintContext::ScopedFrame& frame,
const SkMatrix& matrix) override;
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext::ScopedFrame& frame) override;
private:
......
......@@ -62,8 +62,7 @@ FOR_EACH_BINDING(DART_REGISTER_NATIVE)
}
SceneBuilder::SceneBuilder(const Rect& bounds)
: m_rootPaintBounds(bounds.sk_rect)
, m_currentLayer(nullptr)
: m_currentLayer(nullptr)
, m_currentRasterizerTracingThreshold(0)
{
}
......@@ -106,8 +105,6 @@ void SceneBuilder::pushClipPath(const CanvasPath* path, const Rect& bounds)
void SceneBuilder::pushOpacity(int alpha, const Rect& bounds)
{
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);
addLayer(std::move(layer));
}
......@@ -115,8 +112,6 @@ void SceneBuilder::pushOpacity(int alpha, const Rect& bounds)
void SceneBuilder::pushColorFilter(CanvasColor color, TransferMode transferMode, const Rect& bounds)
{
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_transfer_mode(transferMode);
addLayer(std::move(layer));
......@@ -128,7 +123,6 @@ void SceneBuilder::addLayer(std::unique_ptr<sky::compositor::ContainerLayer> lay
if (!m_rootLayer) {
DCHECK(!m_currentLayer);
m_rootLayer = std::move(layer);
m_rootLayer->set_paint_bounds(m_rootPaintBounds);
m_currentLayer = m_rootLayer.get();
return;
}
......@@ -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());
layer->set_offset(SkPoint::Make(offset.sk_size.width(), offset.sk_size.height()));
layer->set_picture(picture->toSkia());
if (!paintBounds.is_null)
layer->set_paint_bounds(paintBounds.sk_rect);
m_currentLayer->Add(std::move(layer));
}
......
......@@ -57,7 +57,6 @@ private:
void addLayer(std::unique_ptr<sky::compositor::ContainerLayer> layer);
SkRect m_rootPaintBounds;
std::unique_ptr<sky::compositor::ContainerLayer> m_rootLayer;
sky::compositor::ContainerLayer* m_currentLayer;
int32_t m_currentRasterizerTracingThreshold;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册