| 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <limits> | 6 #include <limits> |
| 7 | 7 |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "cc/base/region.h" | 9 #include "cc/base/region.h" |
| 10 #include "cc/debug/debug_colors.h" | 10 #include "cc/debug/debug_colors.h" |
| 11 #include "cc/resources/picture_pile_impl.h" | 11 #include "cc/resources/picture_pile_impl.h" |
| 12 #include "cc/resources/raster_worker_pool.h" | |
| 13 #include "skia/ext/analysis_canvas.h" | 12 #include "skia/ext/analysis_canvas.h" |
| 14 #include "third_party/skia/include/core/SkCanvas.h" | 13 #include "third_party/skia/include/core/SkCanvas.h" |
| 15 #include "third_party/skia/include/core/SkPictureRecorder.h" | 14 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 16 #include "third_party/skia/include/core/SkSize.h" | 15 #include "third_party/skia/include/core/SkSize.h" |
| 17 #include "ui/gfx/rect_conversions.h" | 16 #include "ui/gfx/rect_conversions.h" |
| 18 #include "ui/gfx/size_conversions.h" | 17 #include "ui/gfx/size_conversions.h" |
| 19 #include "ui/gfx/skia_util.h" | 18 #include "ui/gfx/skia_util.h" |
| 20 | 19 |
| 21 namespace cc { | 20 namespace cc { |
| 22 | 21 |
| 23 PicturePileImpl::ClonesForDrawing::ClonesForDrawing( | |
| 24 const PicturePileImpl* pile, int num_threads) { | |
| 25 for (int i = 0; i < num_threads; i++) { | |
| 26 scoped_refptr<PicturePileImpl> clone = | |
| 27 PicturePileImpl::CreateCloneForDrawing(pile, i); | |
| 28 clones_.push_back(clone); | |
| 29 } | |
| 30 } | |
| 31 | |
| 32 PicturePileImpl::ClonesForDrawing::~ClonesForDrawing() { | |
| 33 } | |
| 34 | |
| 35 scoped_refptr<PicturePileImpl> PicturePileImpl::Create() { | 22 scoped_refptr<PicturePileImpl> PicturePileImpl::Create() { |
| 36 return make_scoped_refptr(new PicturePileImpl); | 23 return make_scoped_refptr(new PicturePileImpl); |
| 37 } | 24 } |
| 38 | 25 |
| 39 scoped_refptr<PicturePileImpl> PicturePileImpl::CreateFromOther( | 26 scoped_refptr<PicturePileImpl> PicturePileImpl::CreateFromOther( |
| 40 const PicturePileBase* other) { | 27 const PicturePileBase* other) { |
| 41 return make_scoped_refptr(new PicturePileImpl(other)); | 28 return make_scoped_refptr(new PicturePileImpl(other)); |
| 42 } | 29 } |
| 43 | 30 |
| 44 scoped_refptr<PicturePileImpl> PicturePileImpl::CreateCloneForDrawing( | 31 PicturePileImpl::PicturePileImpl() { |
| 45 const PicturePileImpl* other, unsigned thread_index) { | |
| 46 return make_scoped_refptr(new PicturePileImpl(other, thread_index)); | |
| 47 } | |
| 48 | |
| 49 PicturePileImpl::PicturePileImpl() | |
| 50 : clones_for_drawing_(ClonesForDrawing(this, 0)) { | |
| 51 } | 32 } |
| 52 | 33 |
| 53 PicturePileImpl::PicturePileImpl(const PicturePileBase* other) | 34 PicturePileImpl::PicturePileImpl(const PicturePileBase* other) |
| 54 : PicturePileBase(other), | 35 : PicturePileBase(other) { |
| 55 clones_for_drawing_(ClonesForDrawing( | |
| 56 this, RasterWorkerPool::GetNumRasterThreads())) { | |
| 57 } | |
| 58 | |
| 59 PicturePileImpl::PicturePileImpl( | |
| 60 const PicturePileImpl* other, unsigned thread_index) | |
| 61 : PicturePileBase(other, thread_index), | |
| 62 clones_for_drawing_(ClonesForDrawing(this, 0)) { | |
| 63 } | 36 } |
| 64 | 37 |
| 65 PicturePileImpl::~PicturePileImpl() { | 38 PicturePileImpl::~PicturePileImpl() { |
| 66 } | 39 } |
| 67 | 40 |
| 68 PicturePileImpl* PicturePileImpl::GetCloneForDrawingOnThread( | |
| 69 unsigned thread_index) const { | |
| 70 CHECK_GT(clones_for_drawing_.clones_.size(), thread_index); | |
| 71 return clones_for_drawing_.clones_[thread_index].get(); | |
| 72 } | |
| 73 | |
| 74 void PicturePileImpl::RasterDirect( | 41 void PicturePileImpl::RasterDirect( |
| 75 SkCanvas* canvas, | 42 SkCanvas* canvas, |
| 76 const gfx::Rect& canvas_rect, | 43 const gfx::Rect& canvas_rect, |
| 77 float contents_scale, | 44 float contents_scale, |
| 78 RenderingStatsInstrumentation* rendering_stats_instrumentation) { | 45 RenderingStatsInstrumentation* rendering_stats_instrumentation) { |
| 79 RasterCommon(canvas, | 46 RasterCommon(canvas, |
| 80 NULL, | 47 NULL, |
| 81 canvas_rect, | 48 canvas_rect, |
| 82 contents_scale, | 49 contents_scale, |
| 83 rendering_stats_instrumentation, | 50 rendering_stats_instrumentation, |
| 84 false); | 51 false); |
| 85 } | 52 } |
| 86 | 53 |
| 87 void PicturePileImpl::RasterForAnalysis( | 54 void PicturePileImpl::RasterForAnalysis( |
| 88 skia::AnalysisCanvas* canvas, | 55 skia::AnalysisCanvas* canvas, |
| 89 const gfx::Rect& canvas_rect, | 56 const gfx::Rect& canvas_rect, |
| 90 float contents_scale, | 57 float contents_scale, |
| 91 RenderingStatsInstrumentation* stats_instrumentation) { | 58 RenderingStatsInstrumentation* stats_instrumentation) const { |
| 92 RasterCommon( | 59 RasterCommon( |
| 93 canvas, canvas, canvas_rect, contents_scale, stats_instrumentation, true); | 60 canvas, canvas, canvas_rect, contents_scale, stats_instrumentation, true); |
| 94 } | 61 } |
| 95 | 62 |
| 96 void PicturePileImpl::RasterToBitmap( | 63 void PicturePileImpl::RasterToBitmap( |
| 97 SkCanvas* canvas, | 64 SkCanvas* canvas, |
| 98 const gfx::Rect& canvas_rect, | 65 const gfx::Rect& canvas_rect, |
| 99 float contents_scale, | 66 float contents_scale, |
| 100 RenderingStatsInstrumentation* rendering_stats_instrumentation) { | 67 RenderingStatsInstrumentation* rendering_stats_instrumentation) const { |
| 101 canvas->discard(); | 68 canvas->discard(); |
| 102 if (clear_canvas_with_debug_color_) { | 69 if (clear_canvas_with_debug_color_) { |
| 103 // Any non-painted areas in the content bounds will be left in this color. | 70 // Any non-painted areas in the content bounds will be left in this color. |
| 104 canvas->clear(DebugColors::NonPaintedFillColor()); | 71 canvas->clear(DebugColors::NonPaintedFillColor()); |
| 105 } | 72 } |
| 106 | 73 |
| 107 // If this picture has opaque contents, it is guaranteeing that it will | 74 // If this picture has opaque contents, it is guaranteeing that it will |
| 108 // draw an opaque rect the size of the layer. If it is not, then we must | 75 // draw an opaque rect the size of the layer. If it is not, then we must |
| 109 // clear this canvas ourselves. | 76 // clear this canvas ourselves. |
| 110 if (contents_opaque_ || contents_fill_bounds_completely_) { | 77 if (contents_opaque_ || contents_fill_bounds_completely_) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 NULL, | 126 NULL, |
| 160 canvas_rect, | 127 canvas_rect, |
| 161 contents_scale, | 128 contents_scale, |
| 162 rendering_stats_instrumentation, | 129 rendering_stats_instrumentation, |
| 163 false); | 130 false); |
| 164 } | 131 } |
| 165 | 132 |
| 166 void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect, | 133 void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect, |
| 167 const gfx::Rect& content_rect, | 134 const gfx::Rect& content_rect, |
| 168 float contents_scale, | 135 float contents_scale, |
| 169 PictureRegionMap* results) { | 136 PictureRegionMap* results) const { |
| 170 DCHECK(results); | 137 DCHECK(results); |
| 171 // Rasterize the collection of relevant picture piles. | 138 // Rasterize the collection of relevant picture piles. |
| 172 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( | 139 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( |
| 173 content_rect, 1.f / contents_scale); | 140 content_rect, 1.f / contents_scale); |
| 174 | 141 |
| 175 // Make sure pictures don't overlap by keeping track of previous right/bottom. | 142 // Make sure pictures don't overlap by keeping track of previous right/bottom. |
| 176 int min_content_left = -1; | 143 int min_content_left = -1; |
| 177 int min_content_top = -1; | 144 int min_content_top = -1; |
| 178 int last_row_index = -1; | 145 int last_row_index = -1; |
| 179 int last_col_index = -1; | 146 int last_col_index = -1; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 190 // ignores the transform). Intersect then can be written as subtracting the | 157 // ignores the transform). Intersect then can be written as subtracting the |
| 191 // negation of the region we're trying to intersect. Luckily, we know that all | 158 // negation of the region we're trying to intersect. Luckily, we know that all |
| 192 // of the rects will have to fit into |content_rect|, so we can start with | 159 // of the rects will have to fit into |content_rect|, so we can start with |
| 193 // that and subtract chunk rects to get the region that we need to subtract | 160 // that and subtract chunk rects to get the region that we need to subtract |
| 194 // from the canvas. Then, we can use clipRect with difference op to subtract | 161 // from the canvas. Then, we can use clipRect with difference op to subtract |
| 195 // each rect in the region. | 162 // each rect in the region. |
| 196 bool include_borders = true; | 163 bool include_borders = true; |
| 197 for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders); | 164 for (TilingData::Iterator tile_iter(&tiling_, layer_rect, include_borders); |
| 198 tile_iter; | 165 tile_iter; |
| 199 ++tile_iter) { | 166 ++tile_iter) { |
| 200 PictureMap::iterator map_iter = picture_map_.find(tile_iter.index()); | 167 PictureMap::const_iterator map_iter = picture_map_.find(tile_iter.index()); |
| 201 if (map_iter == picture_map_.end()) | 168 if (map_iter == picture_map_.end()) |
| 202 continue; | 169 continue; |
| 203 PictureInfo& info = map_iter->second; | 170 const PictureInfo& info = map_iter->second; |
| 204 Picture* picture = info.GetPicture(); | 171 const Picture* picture = info.GetPicture(); |
| 205 if (!picture) | 172 if (!picture) |
| 206 continue; | 173 continue; |
| 207 | 174 |
| 208 // This is intentionally *enclosed* rect, so that the clip is aligned on | 175 // This is intentionally *enclosed* rect, so that the clip is aligned on |
| 209 // integral post-scale content pixels and does not extend past the edges | 176 // integral post-scale content pixels and does not extend past the edges |
| 210 // of the picture chunk's layer rect. The min_contents_scale enforces that | 177 // of the picture chunk's layer rect. The min_contents_scale enforces that |
| 211 // enough buffer pixels have been added such that the enclosed rect | 178 // enough buffer pixels have been added such that the enclosed rect |
| 212 // encompasses all invalidated pixels at any larger scale level. | 179 // encompasses all invalidated pixels at any larger scale level. |
| 213 gfx::Rect chunk_rect = PaddedRect(tile_iter.index()); | 180 gfx::Rect chunk_rect = PaddedRect(tile_iter.index()); |
| 214 gfx::Rect content_clip = | 181 gfx::Rect content_clip = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 last_content_rect = content_clip; | 224 last_content_rect = content_clip; |
| 258 } | 225 } |
| 259 } | 226 } |
| 260 | 227 |
| 261 void PicturePileImpl::RasterCommon( | 228 void PicturePileImpl::RasterCommon( |
| 262 SkCanvas* canvas, | 229 SkCanvas* canvas, |
| 263 SkDrawPictureCallback* callback, | 230 SkDrawPictureCallback* callback, |
| 264 const gfx::Rect& canvas_rect, | 231 const gfx::Rect& canvas_rect, |
| 265 float contents_scale, | 232 float contents_scale, |
| 266 RenderingStatsInstrumentation* rendering_stats_instrumentation, | 233 RenderingStatsInstrumentation* rendering_stats_instrumentation, |
| 267 bool is_analysis) { | 234 bool is_analysis) const { |
| 268 DCHECK(contents_scale >= min_contents_scale_); | 235 DCHECK(contents_scale >= min_contents_scale_); |
| 269 | 236 |
| 270 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); | 237 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); |
| 271 gfx::Rect content_tiling_rect = gfx::ToEnclosingRect( | 238 gfx::Rect content_tiling_rect = gfx::ToEnclosingRect( |
| 272 gfx::ScaleRect(gfx::Rect(tiling_.tiling_size()), contents_scale)); | 239 gfx::ScaleRect(gfx::Rect(tiling_.tiling_size()), contents_scale)); |
| 273 content_tiling_rect.Intersect(canvas_rect); | 240 content_tiling_rect.Intersect(canvas_rect); |
| 274 | 241 |
| 275 canvas->clipRect(gfx::RectToSkRect(content_tiling_rect), | 242 canvas->clipRect(gfx::RectToSkRect(content_tiling_rect), |
| 276 SkRegion::kIntersect_Op); | 243 SkRegion::kIntersect_Op); |
| 277 | 244 |
| 278 PictureRegionMap picture_region_map; | 245 PictureRegionMap picture_region_map; |
| 279 CoalesceRasters( | 246 CoalesceRasters( |
| 280 canvas_rect, content_tiling_rect, contents_scale, &picture_region_map); | 247 canvas_rect, content_tiling_rect, contents_scale, &picture_region_map); |
| 281 | 248 |
| 282 #ifndef NDEBUG | 249 #ifndef NDEBUG |
| 283 Region total_clip; | 250 Region total_clip; |
| 284 #endif // NDEBUG | 251 #endif // NDEBUG |
| 285 | 252 |
| 286 // Iterate the coalesced map and use each picture's region | 253 // Iterate the coalesced map and use each picture's region |
| 287 // to clip the canvas. | 254 // to clip the canvas. |
| 288 for (PictureRegionMap::iterator it = picture_region_map.begin(); | 255 for (PictureRegionMap::iterator it = picture_region_map.begin(); |
| 289 it != picture_region_map.end(); | 256 it != picture_region_map.end(); |
| 290 ++it) { | 257 ++it) { |
| 291 Picture* picture = it->first; | 258 const Picture* picture = it->first; |
| 292 Region negated_clip_region = it->second; | 259 Region negated_clip_region = it->second; |
| 293 | 260 |
| 294 #ifndef NDEBUG | 261 #ifndef NDEBUG |
| 295 Region positive_clip = content_tiling_rect; | 262 Region positive_clip = content_tiling_rect; |
| 296 positive_clip.Subtract(negated_clip_region); | 263 positive_clip.Subtract(negated_clip_region); |
| 297 // Make sure we never rasterize the same region twice. | 264 // Make sure we never rasterize the same region twice. |
| 298 DCHECK(!total_clip.Intersects(positive_clip)); | 265 DCHECK(!total_clip.Intersects(positive_clip)); |
| 299 total_clip.Union(positive_clip); | 266 total_clip.Union(positive_clip); |
| 300 #endif // NDEBUG | 267 #endif // NDEBUG |
| 301 | 268 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 SkPictureRecorder recorder; | 316 SkPictureRecorder recorder; |
| 350 SkCanvas* canvas = | 317 SkCanvas* canvas = |
| 351 recorder.beginRecording(tiling_rect.width(), tiling_rect.height()); | 318 recorder.beginRecording(tiling_rect.width(), tiling_rect.height()); |
| 352 if (!tiling_rect.IsEmpty()) | 319 if (!tiling_rect.IsEmpty()) |
| 353 RasterToBitmap(canvas, tiling_rect, 1.0, NULL); | 320 RasterToBitmap(canvas, tiling_rect, 1.0, NULL); |
| 354 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); | 321 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); |
| 355 | 322 |
| 356 return picture; | 323 return picture; |
| 357 } | 324 } |
| 358 | 325 |
| 359 void PicturePileImpl::AnalyzeInRect( | 326 void PicturePileImpl::AnalyzeInRect(const gfx::Rect& content_rect, |
| 360 const gfx::Rect& content_rect, | 327 float contents_scale, |
| 361 float contents_scale, | 328 PicturePileImpl::Analysis* analysis) const { |
| 362 PicturePileImpl::Analysis* analysis) { | |
| 363 AnalyzeInRect(content_rect, contents_scale, analysis, NULL); | 329 AnalyzeInRect(content_rect, contents_scale, analysis, NULL); |
| 364 } | 330 } |
| 365 | 331 |
| 366 void PicturePileImpl::AnalyzeInRect( | 332 void PicturePileImpl::AnalyzeInRect( |
| 367 const gfx::Rect& content_rect, | 333 const gfx::Rect& content_rect, |
| 368 float contents_scale, | 334 float contents_scale, |
| 369 PicturePileImpl::Analysis* analysis, | 335 PicturePileImpl::Analysis* analysis, |
| 370 RenderingStatsInstrumentation* stats_instrumentation) { | 336 RenderingStatsInstrumentation* stats_instrumentation) const { |
| 371 DCHECK(analysis); | 337 DCHECK(analysis); |
| 372 TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect"); | 338 TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect"); |
| 373 | 339 |
| 374 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( | 340 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( |
| 375 content_rect, 1.0f / contents_scale); | 341 content_rect, 1.0f / contents_scale); |
| 376 | 342 |
| 377 layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); | 343 layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); |
| 378 | 344 |
| 379 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); | 345 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); |
| 380 | 346 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 continue; | 403 continue; |
| 438 | 404 |
| 439 processed_pictures_.insert(picture); | 405 processed_pictures_.insert(picture); |
| 440 pixel_ref_iterator_ = Picture::PixelRefIterator(layer_rect_, picture); | 406 pixel_ref_iterator_ = Picture::PixelRefIterator(layer_rect_, picture); |
| 441 if (pixel_ref_iterator_) | 407 if (pixel_ref_iterator_) |
| 442 break; | 408 break; |
| 443 } | 409 } |
| 444 } | 410 } |
| 445 | 411 |
| 446 void PicturePileImpl::DidBeginTracing() { | 412 void PicturePileImpl::DidBeginTracing() { |
| 447 std::set<void*> processed_pictures; | 413 std::set<const void*> processed_pictures; |
| 448 for (PictureMap::iterator it = picture_map_.begin(); | 414 for (PictureMap::iterator it = picture_map_.begin(); |
| 449 it != picture_map_.end(); | 415 it != picture_map_.end(); |
| 450 ++it) { | 416 ++it) { |
| 451 Picture* picture = it->second.GetPicture(); | 417 const Picture* picture = it->second.GetPicture(); |
| 452 if (picture && (processed_pictures.count(picture) == 0)) { | 418 if (picture && (processed_pictures.count(picture) == 0)) { |
| 453 picture->EmitTraceSnapshot(); | 419 picture->EmitTraceSnapshot(); |
| 454 processed_pictures.insert(picture); | 420 processed_pictures.insert(picture); |
| 455 } | 421 } |
| 456 } | 422 } |
| 457 } | 423 } |
| 458 | 424 |
| 459 } // namespace cc | 425 } // namespace cc |
| OLD | NEW |