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 |