Chromium Code Reviews| Index: cc/picture_pile_impl.cc |
| diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc |
| index b29459bf9bbcef645d7e42d7840d065d39d742bb..b16e59d9debb24bf5176ccc5e0c04489004e6442 100644 |
| --- a/cc/picture_pile_impl.cc |
| +++ b/cc/picture_pile_impl.cc |
| @@ -7,6 +7,7 @@ |
| #include "cc/picture_pile_impl.h" |
| #include "cc/region.h" |
| #include "cc/rendering_stats.h" |
| +#include "skia/ext/analysis_canvas.h" |
| #include "third_party/skia/include/core/SkCanvas.h" |
| #include "third_party/skia/include/core/SkSize.h" |
| #include "ui/gfx/rect_conversions.h" |
| @@ -187,28 +188,122 @@ skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() { |
| return picture; |
| } |
| -bool PicturePileImpl::IsCheapInRect( |
| - gfx::Rect content_rect, float contents_scale) const { |
| +void PicturePileImpl::AnalyzeInRect(const gfx::Rect& content_rect, |
| + float contents_scale) { |
| + TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect"); |
| + |
| + if (analysis_.is_analyzed_ && |
| + content_rect == analysis_.analyzed_content_rect_ && |
| + contents_scale == analysis_.analyzed_contents_scale_) { |
| + return; |
| + } |
| + |
| gfx::Rect layer_rect = gfx::ToEnclosingRect( |
| gfx::ScaleRect(content_rect, 1.f / contents_scale)); |
| + SkBitmap emptyBitmap; |
| + emptyBitmap.setConfig(SkBitmap::kNo_Config, content_rect.width(), |
| + content_rect.height()); |
| + skia::AnalysisDevice device(emptyBitmap); |
| + skia::AnalysisCanvas canvas(&device); |
| + |
| + canvas.translate(-content_rect.x(), -content_rect.y()); |
| + canvas.clipRect(gfx::RectToSkRect(content_rect)); |
| + |
| + Region unclipped(content_rect); |
| + bool determined_if_solid = false; |
| + bool determined_if_transparent = false; |
| + bool is_transparent_guess = false; |
| + bool cheap = true; |
| for (TilingData::Iterator tile_iter(&tiling_, layer_rect); |
| tile_iter; ++tile_iter) { |
| - PictureListMap::const_iterator map_iter = |
| + PictureListMap::iterator map_iter = |
| picture_list_map_.find(tile_iter.index()); |
| if (map_iter == picture_list_map_.end()) |
| continue; |
| + PictureList& pic_list= map_iter->second; |
| + if (pic_list.empty()) |
| + continue; |
| - const PictureList& pic_list = map_iter->second; |
| - for (PictureList::const_iterator i = pic_list.begin(); |
| - i != pic_list.end(); ++i) { |
| - if (!(*i)->LayerRect().Intersects(layer_rect) || !(*i)->HasRecording()) |
| + for (PictureList::reverse_iterator i = pic_list.rbegin(); |
| + i != pic_list.rend(); ++i) { |
| + gfx::Rect content_clip = gfx::ToEnclosedRect( |
| + gfx::ScaleRect((*i)->LayerRect(), contents_scale)); |
| + if (!unclipped.Intersects(content_clip)) |
| continue; |
| - if (!(*i)->IsCheapInRect(layer_rect)) |
| - return false; |
| + |
| + bool is_picture_solid; |
| + SkColor solid_color; |
| + bool is_picture_transparent; |
| + bool is_picture_cheap; |
| + (*i)->AnalyzeInRect(&canvas, |
| + content_clip, |
| + contents_scale, |
| + &is_picture_solid, |
| + &solid_color, |
| + &is_picture_transparent, |
| + &is_picture_cheap); |
| + if (!determined_if_solid) { |
| + determined_if_solid = true; |
| + analysis_.is_solid_color_ = is_picture_solid; |
| + analysis_.solid_color_ = solid_color; |
| + } |
| + else { |
| + analysis_.is_solid_color_ = false; |
|
Tom Hudson
2013/02/27 14:49:36
Does this mean that if there's more than one pictu
|
| + } |
| + |
| + if (is_picture_transparent) |
| + is_transparent_guess = true; |
| + else { |
| + analysis_.is_transparent_ = false; |
| + determined_if_transparent = true; |
| + } |
| + |
| + if (cheap) |
| + cheap = is_picture_cheap; |
| + |
| + // Don't allow pictures underneath to draw where this picture did. |
| + canvas.clipRect( |
| + gfx::RectToSkRect(content_clip), |
| + SkRegion::kDifference_Op); |
| + unclipped.Subtract(content_clip); |
| } |
| } |
| - return true; |
| + |
| + if (!determined_if_solid) |
| + analysis_.is_solid_color_ = false; |
| + if (!determined_if_transparent) |
| + analysis_.is_transparent_ = is_transparent_guess; |
| + analysis_.is_cheap_ = cheap; |
| + analysis_.is_analyzed_ = true; |
| + analysis_.analyzed_content_rect_ = content_rect; |
| + analysis_.analyzed_contents_scale_ = contents_scale; |
| } |
| +bool PicturePileImpl::GetColorIfSolidInRect(const gfx::Rect& content_rect, |
| + float contents_scale, |
| + SkColor* color) { |
| + AnalyzeInRect(content_rect, contents_scale); |
| + DCHECK(analysis_.is_analyzed_); |
| + *color = analysis_.solid_color_; |
| + return analysis_.is_solid_color_; |
| +} |
| + |
| +bool PicturePileImpl::IsCheapInRect(const gfx::Rect& content_rect, |
| + float contents_scale) { |
| + AnalyzeInRect(content_rect, contents_scale); |
| + DCHECK(analysis_.is_analyzed_); |
| + return analysis_.is_cheap_; |
| +} |
| + |
| +bool PicturePileImpl::IsTransparentInRect(const gfx::Rect& content_rect, |
| + float contents_scale) { |
| + AnalyzeInRect(content_rect, contents_scale); |
| + DCHECK(analysis_.is_analyzed_); |
| + return analysis_.is_transparent_; |
| +} |
| + |
| +PicturePileImpl::Analysis::Analysis() |
| + : is_analyzed_(false) {} |
| + |
| } // namespace cc |