1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "cc/picture_pile.h"
8 #include "cc/picture_pile_impl.h"
11 // Maximum number of pictures that can overlap before we collapse them into
13 const int kMaxOverlapping
= 2;
14 // Maximum percentage area of the base picture another picture in the pile
15 // can be. If higher, we destroy the pile and recreate from scratch.
16 const float kResetThreshold
= 0.7f
;
21 PicturePile::PicturePile() {
24 PicturePile::~PicturePile() {
27 void PicturePile::Resize(gfx::Size size
) {
35 void PicturePile::Update(
36 ContentLayerClient
* painter
,
37 const Region
& invalidation
,
38 RenderingStats
& stats
) {
40 ResetPile(painter
, stats
);
44 for (Region::Iterator
i(invalidation
); i
.has_rect(); i
.next())
45 InvalidateRect(i
.rect());
47 for (Pile::iterator i
= pile_
.begin(); i
!= pile_
.end(); ++i
) {
48 if (!(*i
)->HasRecording())
49 (*i
)->Record(painter
, stats
);
53 class FullyContainedPredicate
{
55 FullyContainedPredicate(gfx::Rect rect
) : layer_rect_(rect
) { }
56 bool operator()(const scoped_refptr
<Picture
>& picture
) {
57 return layer_rect_
.Contains(picture
->LayerRect());
59 gfx::Rect layer_rect_
;
62 void PicturePile::InvalidateRect(gfx::Rect invalidation
) {
63 if (invalidation
.IsEmpty())
66 std::vector
<Pile::iterator
> overlaps
;
67 for (Pile::iterator i
= pile_
.begin(); i
!= pile_
.end(); ++i
) {
68 if ((*i
)->LayerRect().Contains(invalidation
) && !(*i
)->HasRecording())
70 if ((*i
)->LayerRect().Intersects(invalidation
) && i
!= pile_
.begin())
71 overlaps
.push_back(i
);
74 gfx::Rect picture_rect
= invalidation
;
75 if (overlaps
.size() >= kMaxOverlapping
) {
76 for (size_t j
= 0; j
< overlaps
.size(); j
++)
77 picture_rect
= gfx::UnionRects(picture_rect
, (*overlaps
[j
])->LayerRect());
79 if (picture_rect
.size().GetArea() / static_cast<float>(size_
.GetArea()) >
81 picture_rect
= gfx::Rect(size_
);
83 FullyContainedPredicate
pred(picture_rect
);
84 pile_
.erase(std::remove_if(pile_
.begin(), pile_
.end(), pred
), pile_
.end());
86 pile_
.push_back(Picture::Create(picture_rect
));
90 void PicturePile::ResetPile(ContentLayerClient
* painter
,
91 RenderingStats
& stats
) {
94 scoped_refptr
<Picture
> base_picture
= Picture::Create(gfx::Rect(size_
));
95 base_picture
->Record(painter
, stats
);
96 pile_
.push_back(base_picture
);
99 void PicturePile::PushPropertiesTo(PicturePileImpl
* other
) {
100 other
->pile_
= pile_
;
101 // Remove all old clones.
102 other
->clones_
.clear();