| Index: cc/picture_pile_impl.cc
|
| diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc
|
| index 4bb01a397dad325a0cfb138827b7fd0e70aea991..ea7a2ba28682ddacbf14d242857e992e4a6b8188 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"
|
| @@ -188,28 +189,89 @@ 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,
|
| + PicturePileImpl::Analysis* analysis) {
|
| + DCHECK(analysis);
|
| +
|
| + TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect");
|
| +
|
| 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);
|
| + analysis->is_solid_color_ = 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;
|
| +
|
| + Picture::Analysis picture_analysis;
|
| + (*i)->AnalyzeInRect(&canvas,
|
| + content_clip,
|
| + contents_scale,
|
| + &picture_analysis);
|
| +
|
| + // Since the iteration happens bottom-up, take the solid information
|
| + // from the last picture that is analyzed.
|
| + analysis->is_solid_color_ = picture_analysis.is_solid_color_;
|
| + analysis->solid_color_ = picture_analysis.solid_color_;
|
| +
|
| + // If the current picture is transparent, then the best we can do
|
| + // is guess that the whole tile will be transparent (since that
|
| + // might change in later iterations)
|
| + if (picture_analysis.is_transparent_)
|
| + is_transparent_guess = true;
|
| + else {
|
| + analysis->is_transparent_ = false;
|
| + determined_if_transparent = true;
|
| + }
|
| +
|
| + // Cheap can turn into not cheap, but not cheap
|
| + // can't be updated to be cheap
|
| + if (cheap)
|
| + cheap = picture_analysis.is_cheap_to_raster_;
|
| +
|
| + // 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_transparent)
|
| + analysis->is_transparent_ = is_transparent_guess;
|
| + analysis->is_cheap_to_raster_ = cheap;
|
| + analysis->is_analyzed_ = true;
|
| +}
|
| +
|
| +PicturePileImpl::Analysis::Analysis()
|
| + : is_analyzed_(false) {
|
| }
|
|
|
| } // namespace cc
|
|
|