OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/debug/trace_event.h" | 5 #include "base/debug/trace_event.h" |
6 #include "cc/debug_colors.h" | 6 #include "cc/debug_colors.h" |
7 #include "cc/picture_pile_impl.h" | 7 #include "cc/picture_pile_impl.h" |
8 #include "cc/region.h" | 8 #include "cc/region.h" |
9 #include "cc/rendering_stats.h" | 9 #include "cc/rendering_stats.h" |
| 10 #include "skia/ext/analysis_canvas.h" |
10 #include "third_party/skia/include/core/SkCanvas.h" | 11 #include "third_party/skia/include/core/SkCanvas.h" |
11 #include "third_party/skia/include/core/SkSize.h" | 12 #include "third_party/skia/include/core/SkSize.h" |
12 #include "ui/gfx/rect_conversions.h" | 13 #include "ui/gfx/rect_conversions.h" |
13 #include "ui/gfx/skia_util.h" | 14 #include "ui/gfx/skia_util.h" |
14 | 15 |
15 namespace cc { | 16 namespace cc { |
16 | 17 |
17 scoped_refptr<PicturePileImpl> PicturePileImpl::Create() { | 18 scoped_refptr<PicturePileImpl> PicturePileImpl::Create() { |
18 return make_scoped_refptr(new PicturePileImpl()); | 19 return make_scoped_refptr(new PicturePileImpl()); |
19 } | 20 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 layer_rect.height(), | 182 layer_rect.height(), |
182 SkPicture::kUsePathBoundsForClip_RecordingFlag); | 183 SkPicture::kUsePathBoundsForClip_RecordingFlag); |
183 | 184 |
184 int64 total_pixels_rasterized = 0; | 185 int64 total_pixels_rasterized = 0; |
185 Raster(canvas, layer_rect, 1.0, &total_pixels_rasterized); | 186 Raster(canvas, layer_rect, 1.0, &total_pixels_rasterized); |
186 picture->endRecording(); | 187 picture->endRecording(); |
187 | 188 |
188 return picture; | 189 return picture; |
189 } | 190 } |
190 | 191 |
191 bool PicturePileImpl::IsCheapInRect( | 192 void PicturePileImpl::AnalyzeInRect(const gfx::Rect& content_rect, |
192 gfx::Rect content_rect, float contents_scale) const { | 193 float contents_scale) { |
| 194 TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect"); |
| 195 |
| 196 if (analysis_.is_analyzed_ && |
| 197 content_rect == analysis_.analyzed_content_rect_ && |
| 198 contents_scale == analysis_.analyzed_contents_scale_) { |
| 199 return; |
| 200 } |
| 201 |
193 gfx::Rect layer_rect = gfx::ToEnclosingRect( | 202 gfx::Rect layer_rect = gfx::ToEnclosingRect( |
194 gfx::ScaleRect(content_rect, 1.f / contents_scale)); | 203 gfx::ScaleRect(content_rect, 1.f / contents_scale)); |
195 | 204 |
| 205 SkBitmap emptyBitmap; |
| 206 emptyBitmap.setConfig(SkBitmap::kNo_Config, content_rect.width(), |
| 207 content_rect.height()); |
| 208 skia::AnalysisDevice device(emptyBitmap); |
| 209 skia::AnalysisCanvas canvas(&device); |
| 210 |
| 211 canvas.translate(-content_rect.x(), -content_rect.y()); |
| 212 canvas.clipRect(gfx::RectToSkRect(content_rect)); |
| 213 |
| 214 Region unclipped(content_rect); |
| 215 analysis_.is_solid_color_ = false; |
| 216 bool determined_if_transparent = false; |
| 217 bool is_transparent_guess = false; |
| 218 bool cheap = true; |
196 for (TilingData::Iterator tile_iter(&tiling_, layer_rect); | 219 for (TilingData::Iterator tile_iter(&tiling_, layer_rect); |
197 tile_iter; ++tile_iter) { | 220 tile_iter; ++tile_iter) { |
198 PictureListMap::const_iterator map_iter = | 221 PictureListMap::iterator map_iter = |
199 picture_list_map_.find(tile_iter.index()); | 222 picture_list_map_.find(tile_iter.index()); |
200 if (map_iter == picture_list_map_.end()) | 223 if (map_iter == picture_list_map_.end()) |
201 continue; | 224 continue; |
| 225 PictureList& pic_list= map_iter->second; |
| 226 if (pic_list.empty()) |
| 227 continue; |
202 | 228 |
203 const PictureList& pic_list = map_iter->second; | 229 for (PictureList::reverse_iterator i = pic_list.rbegin(); |
204 for (PictureList::const_iterator i = pic_list.begin(); | 230 i != pic_list.rend(); ++i) { |
205 i != pic_list.end(); ++i) { | 231 gfx::Rect content_clip = gfx::ToEnclosedRect( |
206 if (!(*i)->LayerRect().Intersects(layer_rect) || !(*i)->HasRecording()) | 232 gfx::ScaleRect((*i)->LayerRect(), contents_scale)); |
| 233 if (!unclipped.Intersects(content_clip)) |
207 continue; | 234 continue; |
208 if (!(*i)->IsCheapInRect(layer_rect)) | 235 |
209 return false; | 236 Picture::Analysis picture_analysis; |
| 237 (*i)->AnalyzeInRect(&canvas, |
| 238 content_clip, |
| 239 contents_scale, |
| 240 &picture_analysis); |
| 241 |
| 242 // Since the iteration happens bottom-up, take the solid information |
| 243 // from the last picture that is analyzed. |
| 244 analysis_.is_solid_color_ = picture_analysis.is_solid_color_; |
| 245 analysis_.solid_color_ = picture_analysis.solid_color_; |
| 246 |
| 247 // If the current picture is transparent, then the best we can do |
| 248 // is guess that the whole tile will be transparent (since that |
| 249 // might change in later iterations) |
| 250 if (picture_analysis.is_transparent_) |
| 251 is_transparent_guess = true; |
| 252 else { |
| 253 analysis_.is_transparent_ = false; |
| 254 determined_if_transparent = true; |
| 255 } |
| 256 |
| 257 // Cheap can turn into not cheap, but not cheap |
| 258 // can't be updated to be cheap |
| 259 if (cheap) |
| 260 cheap = picture_analysis.is_cheap_; |
| 261 |
| 262 // Don't allow pictures underneath to draw where this picture did. |
| 263 canvas.clipRect( |
| 264 gfx::RectToSkRect(content_clip), |
| 265 SkRegion::kDifference_Op); |
| 266 unclipped.Subtract(content_clip); |
210 } | 267 } |
211 } | 268 } |
212 return true; | 269 |
| 270 if (!determined_if_transparent) |
| 271 analysis_.is_transparent_ = is_transparent_guess; |
| 272 analysis_.is_cheap_ = cheap; |
| 273 analysis_.is_analyzed_ = true; |
| 274 analysis_.analyzed_content_rect_ = content_rect; |
| 275 analysis_.analyzed_contents_scale_ = contents_scale; |
213 } | 276 } |
214 | 277 |
| 278 bool PicturePileImpl::GetColorIfSolidInRect(const gfx::Rect& content_rect, |
| 279 float contents_scale, |
| 280 SkColor* color) { |
| 281 AnalyzeInRect(content_rect, contents_scale); |
| 282 DCHECK(analysis_.is_analyzed_); |
| 283 *color = analysis_.solid_color_; |
| 284 return analysis_.is_solid_color_; |
| 285 } |
| 286 |
| 287 bool PicturePileImpl::IsCheapInRect(const gfx::Rect& content_rect, |
| 288 float contents_scale) { |
| 289 AnalyzeInRect(content_rect, contents_scale); |
| 290 DCHECK(analysis_.is_analyzed_); |
| 291 return analysis_.is_cheap_; |
| 292 } |
| 293 |
| 294 bool PicturePileImpl::IsTransparentInRect(const gfx::Rect& content_rect, |
| 295 float contents_scale) { |
| 296 AnalyzeInRect(content_rect, contents_scale); |
| 297 DCHECK(analysis_.is_analyzed_); |
| 298 return analysis_.is_transparent_; |
| 299 } |
| 300 |
| 301 PicturePileImpl::Analysis::Analysis() |
| 302 : is_analyzed_(false) {} |
| 303 |
215 } // namespace cc | 304 } // namespace cc |
OLD | NEW |