| 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" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 } | 103 } |
| 104 | 104 |
| 105 // If this picture has opaque contents, it is guaranteeing that it will | 105 // If this picture has opaque contents, it is guaranteeing that it will |
| 106 // draw an opaque rect the size of the layer. If it is not, then we must | 106 // draw an opaque rect the size of the layer. If it is not, then we must |
| 107 // clear this canvas ourselves. | 107 // clear this canvas ourselves. |
| 108 if (contents_opaque_) { | 108 if (contents_opaque_) { |
| 109 // Even if it is opaque, on any rasterizations that touch the edge of the | 109 // Even if it is opaque, on any rasterizations that touch the edge of the |
| 110 // layer, we also need to raster the background color underneath the last | 110 // layer, we also need to raster the background color underneath the last |
| 111 // texel (since the recording won't cover it) and outside the last texel | 111 // texel (since the recording won't cover it) and outside the last texel |
| 112 // (due to linear filtering when using this texture). | 112 // (due to linear filtering when using this texture). |
| 113 gfx::SizeF total_content_size = | 113 gfx::Rect content_tiling_rect = |
| 114 gfx::ScaleSize(tiling_.total_size(), contents_scale); | 114 gfx::ToEnclosingRect(gfx::ScaleRect(tiling_.tiling_rect(), |
| 115 gfx::Rect content_rect(gfx::ToCeiledSize(total_content_size)); | 115 contents_scale)); |
| 116 | 116 |
| 117 // The final texel of content may only be partially covered by a | 117 // The final texel of content may only be partially covered by a |
| 118 // rasterization; this rect represents the content rect that is fully | 118 // rasterization; this rect represents the content rect that is fully |
| 119 // covered by content. | 119 // covered by content. |
| 120 gfx::Rect deflated_content_rect = content_rect; | 120 gfx::Rect deflated_content_tiling_rect = content_tiling_rect; |
| 121 deflated_content_rect.Inset(0, 0, 1, 1); | 121 deflated_content_tiling_rect.Inset(0, 0, 1, 1); |
| 122 if (!deflated_content_rect.Contains(canvas_rect)) { | 122 if (!deflated_content_tiling_rect.Contains(canvas_rect)) { |
| 123 // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X | 123 // Drawing at most 2 x 2 x (canvas width + canvas height) texels is 2-3X |
| 124 // faster than clearing, so special case this. | 124 // faster than clearing, so special case this. |
| 125 canvas->save(); | 125 canvas->save(); |
| 126 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); | 126 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); |
| 127 gfx::Rect inflated_content_rect = content_rect; | 127 gfx::Rect inflated_content_tiling_rect = content_tiling_rect; |
| 128 inflated_content_rect.Inset(0, 0, -1, -1); | 128 inflated_content_tiling_rect.Inset(0, 0, -1, -1); |
| 129 canvas->clipRect(gfx::RectToSkRect(inflated_content_rect), | 129 canvas->clipRect(gfx::RectToSkRect(inflated_content_tiling_rect), |
| 130 SkRegion::kReplace_Op); | 130 SkRegion::kReplace_Op); |
| 131 canvas->clipRect(gfx::RectToSkRect(deflated_content_rect), | 131 canvas->clipRect(gfx::RectToSkRect(deflated_content_tiling_rect), |
| 132 SkRegion::kDifference_Op); | 132 SkRegion::kDifference_Op); |
| 133 canvas->drawColor(background_color_, SkXfermode::kSrc_Mode); | 133 canvas->drawColor(background_color_, SkXfermode::kSrc_Mode); |
| 134 canvas->restore(); | 134 canvas->restore(); |
| 135 } | 135 } |
| 136 } else if (!contents_fill_bounds_completely_) { | 136 } else if (!contents_fill_bounds_completely_) { |
| 137 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD); | 137 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD); |
| 138 // Clearing is about ~4x faster than drawing a rect even if the content | 138 // Clearing is about ~4x faster than drawing a rect even if the content |
| 139 // isn't covering a majority of the canvas. | 139 // isn't covering a majority of the canvas. |
| 140 canvas->clear(SK_ColorTRANSPARENT); | 140 canvas->clear(SK_ColorTRANSPARENT); |
| 141 } | 141 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 void PicturePileImpl::RasterCommon( | 246 void PicturePileImpl::RasterCommon( |
| 247 SkCanvas* canvas, | 247 SkCanvas* canvas, |
| 248 SkDrawPictureCallback* callback, | 248 SkDrawPictureCallback* callback, |
| 249 const gfx::Rect& canvas_rect, | 249 const gfx::Rect& canvas_rect, |
| 250 float contents_scale, | 250 float contents_scale, |
| 251 RenderingStatsInstrumentation* rendering_stats_instrumentation, | 251 RenderingStatsInstrumentation* rendering_stats_instrumentation, |
| 252 bool is_analysis) { | 252 bool is_analysis) { |
| 253 DCHECK(contents_scale >= min_contents_scale_); | 253 DCHECK(contents_scale >= min_contents_scale_); |
| 254 | 254 |
| 255 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); | 255 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); |
| 256 gfx::SizeF total_content_size = gfx::ScaleSize(tiling_.total_size(), | 256 gfx::Rect content_tiling_rect = |
| 257 contents_scale); | 257 gfx::ToEnclosingRect(gfx::ScaleRect(tiling_.tiling_rect(), |
| 258 gfx::Rect total_content_rect(gfx::ToCeiledSize(total_content_size)); | 258 contents_scale)); |
| 259 gfx::Rect content_rect = total_content_rect; | 259 content_tiling_rect.Intersect(canvas_rect); |
| 260 content_rect.Intersect(canvas_rect); | |
| 261 | 260 |
| 262 canvas->clipRect(gfx::RectToSkRect(content_rect), | 261 canvas->clipRect(gfx::RectToSkRect(content_tiling_rect), |
| 263 SkRegion::kIntersect_Op); | 262 SkRegion::kIntersect_Op); |
| 264 | 263 |
| 265 PictureRegionMap picture_region_map; | 264 PictureRegionMap picture_region_map; |
| 266 CoalesceRasters( | 265 CoalesceRasters( |
| 267 canvas_rect, content_rect, contents_scale, &picture_region_map); | 266 canvas_rect, content_tiling_rect, contents_scale, &picture_region_map); |
| 268 | 267 |
| 269 #ifndef NDEBUG | 268 #ifndef NDEBUG |
| 270 Region total_clip; | 269 Region total_clip; |
| 271 #endif // NDEBUG | 270 #endif // NDEBUG |
| 272 | 271 |
| 273 // Iterate the coalesced map and use each picture's region | 272 // Iterate the coalesced map and use each picture's region |
| 274 // to clip the canvas. | 273 // to clip the canvas. |
| 275 for (PictureRegionMap::iterator it = picture_region_map.begin(); | 274 for (PictureRegionMap::iterator it = picture_region_map.begin(); |
| 276 it != picture_region_map.end(); | 275 it != picture_region_map.end(); |
| 277 ++it) { | 276 ++it) { |
| 278 Picture* picture = it->first; | 277 Picture* picture = it->first; |
| 279 Region negated_clip_region = it->second; | 278 Region negated_clip_region = it->second; |
| 280 | 279 |
| 281 #ifndef NDEBUG | 280 #ifndef NDEBUG |
| 282 Region positive_clip = content_rect; | 281 Region positive_clip = content_tiling_rect; |
| 283 positive_clip.Subtract(negated_clip_region); | 282 positive_clip.Subtract(negated_clip_region); |
| 284 // Make sure we never rasterize the same region twice. | 283 // Make sure we never rasterize the same region twice. |
| 285 DCHECK(!total_clip.Intersects(positive_clip)); | 284 DCHECK(!total_clip.Intersects(positive_clip)); |
| 286 total_clip.Union(positive_clip); | 285 total_clip.Union(positive_clip); |
| 287 #endif // NDEBUG | 286 #endif // NDEBUG |
| 288 | 287 |
| 289 base::TimeDelta best_duration = base::TimeDelta::Max(); | 288 base::TimeDelta best_duration = base::TimeDelta::Max(); |
| 290 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); | 289 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); |
| 291 int rasterized_pixel_count = 0; | 290 int rasterized_pixel_count = 0; |
| 292 | 291 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); | 324 canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); |
| 326 paint.setColor(DebugColors::MissingPictureFillColor()); | 325 paint.setColor(DebugColors::MissingPictureFillColor()); |
| 327 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 326 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 328 canvas->drawPaint(paint); | 327 canvas->drawPaint(paint); |
| 329 #endif // NDEBUG | 328 #endif // NDEBUG |
| 330 } | 329 } |
| 331 | 330 |
| 332 skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() { | 331 skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() { |
| 333 TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture"); | 332 TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture"); |
| 334 | 333 |
| 335 gfx::Rect layer_rect(tiling_.total_size()); | 334 gfx::Rect tiling_rect(tiling_.tiling_rect()); |
| 336 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); | 335 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); |
| 337 if (layer_rect.IsEmpty()) | 336 if (tiling_rect.IsEmpty()) |
| 338 return picture; | 337 return picture; |
| 339 | 338 |
| 340 SkCanvas* canvas = picture->beginRecording( | 339 SkCanvas* canvas = picture->beginRecording( |
| 341 layer_rect.width(), | 340 tiling_rect.width(), |
| 342 layer_rect.height(), | 341 tiling_rect.height(), |
| 343 SkPicture::kUsePathBoundsForClip_RecordingFlag); | 342 SkPicture::kUsePathBoundsForClip_RecordingFlag); |
| 344 | 343 |
| 345 RasterToBitmap(canvas, layer_rect, 1.0, NULL); | 344 RasterToBitmap(canvas, tiling_rect, 1.0, NULL); |
| 346 picture->endRecording(); | 345 picture->endRecording(); |
| 347 | 346 |
| 348 return picture; | 347 return picture; |
| 349 } | 348 } |
| 350 | 349 |
| 351 void PicturePileImpl::AnalyzeInRect( | 350 void PicturePileImpl::AnalyzeInRect( |
| 352 const gfx::Rect& content_rect, | 351 const gfx::Rect& content_rect, |
| 353 float contents_scale, | 352 float contents_scale, |
| 354 PicturePileImpl::Analysis* analysis) { | 353 PicturePileImpl::Analysis* analysis) { |
| 355 AnalyzeInRect(content_rect, contents_scale, analysis, NULL); | 354 AnalyzeInRect(content_rect, contents_scale, analysis, NULL); |
| 356 } | 355 } |
| 357 | 356 |
| 358 void PicturePileImpl::AnalyzeInRect( | 357 void PicturePileImpl::AnalyzeInRect( |
| 359 const gfx::Rect& content_rect, | 358 const gfx::Rect& content_rect, |
| 360 float contents_scale, | 359 float contents_scale, |
| 361 PicturePileImpl::Analysis* analysis, | 360 PicturePileImpl::Analysis* analysis, |
| 362 RenderingStatsInstrumentation* stats_instrumentation) { | 361 RenderingStatsInstrumentation* stats_instrumentation) { |
| 363 DCHECK(analysis); | 362 DCHECK(analysis); |
| 364 TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect"); | 363 TRACE_EVENT0("cc", "PicturePileImpl::AnalyzeInRect"); |
| 365 | 364 |
| 366 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( | 365 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( |
| 367 content_rect, 1.0f / contents_scale); | 366 content_rect, 1.0f / contents_scale); |
| 368 | 367 |
| 369 layer_rect.Intersect(gfx::Rect(tiling_.total_size())); | 368 layer_rect.Intersect(tiling_.tiling_rect()); |
| 370 | 369 |
| 371 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); | 370 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); |
| 372 | 371 |
| 373 RasterForAnalysis(&canvas, layer_rect, 1.0f, stats_instrumentation); | 372 RasterForAnalysis(&canvas, layer_rect, 1.0f, stats_instrumentation); |
| 374 | 373 |
| 375 analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color); | 374 analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color); |
| 376 analysis->has_text = canvas.HasText(); | 375 analysis->has_text = canvas.HasText(); |
| 377 } | 376 } |
| 378 | 377 |
| 379 PicturePileImpl::Analysis::Analysis() | 378 PicturePileImpl::Analysis::Analysis() |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 continue; | 427 continue; |
| 429 | 428 |
| 430 processed_pictures_.insert(picture); | 429 processed_pictures_.insert(picture); |
| 431 pixel_ref_iterator_ = Picture::PixelRefIterator(layer_rect_, picture); | 430 pixel_ref_iterator_ = Picture::PixelRefIterator(layer_rect_, picture); |
| 432 if (pixel_ref_iterator_) | 431 if (pixel_ref_iterator_) |
| 433 break; | 432 break; |
| 434 } | 433 } |
| 435 } | 434 } |
| 436 | 435 |
| 437 void PicturePileImpl::DidBeginTracing() { | 436 void PicturePileImpl::DidBeginTracing() { |
| 438 gfx::Rect layer_rect(tiling_.total_size()); | |
| 439 std::set<void*> processed_pictures; | 437 std::set<void*> processed_pictures; |
| 440 for (PictureMap::iterator it = picture_map_.begin(); | 438 for (PictureMap::iterator it = picture_map_.begin(); |
| 441 it != picture_map_.end(); | 439 it != picture_map_.end(); |
| 442 ++it) { | 440 ++it) { |
| 443 Picture* picture = it->second.GetPicture(); | 441 Picture* picture = it->second.GetPicture(); |
| 444 if (picture && (processed_pictures.count(picture) == 0)) { | 442 if (picture && (processed_pictures.count(picture) == 0)) { |
| 445 picture->EmitTraceSnapshot(); | 443 picture->EmitTraceSnapshot(); |
| 446 processed_pictures.insert(picture); | 444 processed_pictures.insert(picture); |
| 447 } | 445 } |
| 448 } | 446 } |
| 449 } | 447 } |
| 450 | 448 |
| 451 } // namespace cc | 449 } // namespace cc |
| OLD | NEW |