1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// Copyright 2012 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 <algorithm>
#include "cc/picture_pile.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace cc {
PicturePile::PicturePile() {
}
PicturePile::~PicturePile() {
}
void PicturePile::Invalidate(gfx::Rect rect) {
invalidation_.Union(rect);
}
class OutOfBoundsPredicate {
public:
OutOfBoundsPredicate(gfx::Size size) : layer_rect_(gfx::Point(), size) { }
bool operator()(const scoped_refptr<Picture>& picture) {
return !picture->LayerRect().Intersects(layer_rect_);
}
gfx::Rect layer_rect_;
};
void PicturePile::Resize(gfx::Size size) {
if (size.width() > size_.width()) {
gfx::Rect invalid(
size_.width(),
0,
size.width() - size_.width(),
size.height());
Invalidate(invalid);
}
if (size.height() > size_.height()) {
gfx::Rect invalid(
0,
size_.height(),
size.width(),
size.height() - size_.height());
Invalidate(invalid);
}
// Remove pictures that aren't in bounds anymore.
if (size.width() < size_.width() || size.height() < size_.height()) {
OutOfBoundsPredicate oob(size);
pile_.erase(std::remove_if(pile_.begin(), pile_.end(), oob), pile_.end());
}
size_ = size;
}
void PicturePile::Update(ContentLayerClient* painter, RenderingStats& stats) {
// WebKit paints (i.e. recording) can cause invalidations, so record previous.
invalidation_.Swap(prev_invalidation_);
invalidation_.Clear();
// TODO(enne): Add things to the pile, consolidate if needed, etc...
if (pile_.size() == 0)
pile_.push_back(Picture::Create());
pile_[0]->Record(painter, gfx::Rect(gfx::Point(), size_), stats);
}
void PicturePile::CopyAllButPile(PicturePile& from, PicturePile& to) {
to.size_ = from.size_;
to.invalidation_ = from.invalidation_;
to.prev_invalidation_ = from.prev_invalidation_;
}
void PicturePile::PushPropertiesTo(PicturePile& other) {
CopyAllButPile(*this, other);
other.pile_.resize(pile_.size());
for (size_t i = 0; i < pile_.size(); ++i)
other.pile_[i] = pile_[i];
}
scoped_ptr<PicturePile> PicturePile::CloneForDrawing() {
scoped_ptr<PicturePile> clone = make_scoped_ptr(new PicturePile);
CopyAllButPile(*this, *clone);
clone->pile_.resize(pile_.size());
for (size_t i = 0; i < pile_.size(); ++i)
clone->pile_[i] = pile_[i]->Clone();
return clone.Pass();
}
void PicturePile::Raster(SkCanvas* canvas, gfx::Rect rect) {
// TODO(enne): do this more efficiently, i.e. top down with Skia clips
canvas->save();
SkRect layer_skrect = SkRect::MakeXYWH(rect.x(), rect.y(),
rect.width(), rect.height());
canvas->clipRect(layer_skrect);
for (size_t i = 0; i < pile_.size(); ++i) {
if (!pile_[i]->LayerRect().Intersects(rect))
continue;
pile_[i]->Raster(canvas);
}
canvas->restore();
}
} // namespace cc
|