Index: cc/picture_pile_impl.cc |
diff --git a/cc/picture_pile_impl.cc b/cc/picture_pile_impl.cc |
index 4bb01a397dad325a0cfb138827b7fd0e70aea991..b6b22e49a434151b8142ee5d32ac8bce85e5a71c 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,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; |
+ } |
+ |
+ 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 |