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