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 19 matching lines...) Expand all Loading... |
30 } | 30 } |
31 | 31 |
32 PicturePileImpl::PicturePileImpl(const PicturePileBase* other) | 32 PicturePileImpl::PicturePileImpl(const PicturePileBase* other) |
33 : PicturePileBase(other), | 33 : PicturePileBase(other), |
34 likely_to_be_used_for_transform_animation_(false) { | 34 likely_to_be_used_for_transform_animation_(false) { |
35 } | 35 } |
36 | 36 |
37 PicturePileImpl::~PicturePileImpl() { | 37 PicturePileImpl::~PicturePileImpl() { |
38 } | 38 } |
39 | 39 |
40 void PicturePileImpl::RasterDirect( | 40 void PicturePileImpl::RasterDirect(SkCanvas* canvas, |
41 SkCanvas* canvas, | 41 const gfx::Rect& canvas_rect, |
42 const gfx::Rect& canvas_rect, | 42 float contents_scale) const { |
43 float contents_scale, | |
44 RenderingStatsInstrumentation* rendering_stats_instrumentation) const { | |
45 RasterCommon(canvas, | 43 RasterCommon(canvas, |
46 NULL, | 44 NULL, |
47 canvas_rect, | 45 canvas_rect, |
48 contents_scale, | 46 contents_scale, |
49 rendering_stats_instrumentation, | |
50 false); | 47 false); |
51 } | 48 } |
52 | 49 |
53 void PicturePileImpl::RasterForAnalysis( | 50 void PicturePileImpl::RasterForAnalysis(skia::AnalysisCanvas* canvas, |
54 skia::AnalysisCanvas* canvas, | 51 const gfx::Rect& canvas_rect, |
55 const gfx::Rect& canvas_rect, | 52 float contents_scale) const { |
56 float contents_scale, | 53 RasterCommon(canvas, canvas, canvas_rect, contents_scale, true); |
57 RenderingStatsInstrumentation* stats_instrumentation) const { | |
58 RasterCommon( | |
59 canvas, canvas, canvas_rect, contents_scale, stats_instrumentation, true); | |
60 } | 54 } |
61 | 55 |
62 void PicturePileImpl::PlaybackToCanvas( | 56 void PicturePileImpl::PlaybackToCanvas(SkCanvas* canvas, |
63 SkCanvas* canvas, | 57 const gfx::Rect& canvas_rect, |
64 const gfx::Rect& canvas_rect, | 58 float contents_scale) const { |
65 float contents_scale, | |
66 RenderingStatsInstrumentation* rendering_stats_instrumentation) const { | |
67 canvas->discard(); | 59 canvas->discard(); |
68 if (clear_canvas_with_debug_color_) { | 60 if (clear_canvas_with_debug_color_) { |
69 // Any non-painted areas in the content bounds will be left in this color. | 61 // Any non-painted areas in the content bounds will be left in this color. |
70 canvas->clear(DebugColors::NonPaintedFillColor()); | 62 canvas->clear(DebugColors::NonPaintedFillColor()); |
71 } | 63 } |
72 | 64 |
73 // If this picture has opaque contents, it is guaranteeing that it will | 65 // If this picture has opaque contents, it is guaranteeing that it will |
74 // draw an opaque rect the size of the layer. If it is not, then we must | 66 // draw an opaque rect the size of the layer. If it is not, then we must |
75 // clear this canvas ourselves. | 67 // clear this canvas ourselves. |
76 if (contents_opaque_ || contents_fill_bounds_completely_) { | 68 if (contents_opaque_ || contents_fill_bounds_completely_) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD); | 110 TRACE_EVENT_INSTANT0("cc", "SkCanvas::clear", TRACE_EVENT_SCOPE_THREAD); |
119 // Clearing is about ~4x faster than drawing a rect even if the content | 111 // Clearing is about ~4x faster than drawing a rect even if the content |
120 // isn't covering a majority of the canvas. | 112 // isn't covering a majority of the canvas. |
121 canvas->clear(SK_ColorTRANSPARENT); | 113 canvas->clear(SK_ColorTRANSPARENT); |
122 } | 114 } |
123 | 115 |
124 RasterCommon(canvas, | 116 RasterCommon(canvas, |
125 NULL, | 117 NULL, |
126 canvas_rect, | 118 canvas_rect, |
127 contents_scale, | 119 contents_scale, |
128 rendering_stats_instrumentation, | |
129 false); | 120 false); |
130 } | 121 } |
131 | 122 |
132 void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect, | 123 void PicturePileImpl::CoalesceRasters(const gfx::Rect& canvas_rect, |
133 const gfx::Rect& content_rect, | 124 const gfx::Rect& content_rect, |
134 float contents_scale, | 125 float contents_scale, |
135 PictureRegionMap* results) const { | 126 PictureRegionMap* results) const { |
136 DCHECK(results); | 127 DCHECK(results); |
137 // Rasterize the collection of relevant picture piles. | 128 // Rasterize the collection of relevant picture piles. |
138 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( | 129 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 clip_region->Subtract(content_clip); | 213 clip_region->Subtract(content_clip); |
223 last_content_rect = content_clip; | 214 last_content_rect = content_clip; |
224 } | 215 } |
225 } | 216 } |
226 | 217 |
227 void PicturePileImpl::RasterCommon( | 218 void PicturePileImpl::RasterCommon( |
228 SkCanvas* canvas, | 219 SkCanvas* canvas, |
229 SkDrawPictureCallback* callback, | 220 SkDrawPictureCallback* callback, |
230 const gfx::Rect& canvas_rect, | 221 const gfx::Rect& canvas_rect, |
231 float contents_scale, | 222 float contents_scale, |
232 RenderingStatsInstrumentation* rendering_stats_instrumentation, | |
233 bool is_analysis) const { | 223 bool is_analysis) const { |
234 DCHECK(contents_scale >= min_contents_scale_); | 224 DCHECK(contents_scale >= min_contents_scale_); |
235 | 225 |
236 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); | 226 canvas->translate(-canvas_rect.x(), -canvas_rect.y()); |
237 gfx::Rect content_tiling_rect = gfx::ToEnclosingRect( | 227 gfx::Rect content_tiling_rect = gfx::ToEnclosingRect( |
238 gfx::ScaleRect(gfx::Rect(tiling_.tiling_size()), contents_scale)); | 228 gfx::ScaleRect(gfx::Rect(tiling_.tiling_size()), contents_scale)); |
239 content_tiling_rect.Intersect(canvas_rect); | 229 content_tiling_rect.Intersect(canvas_rect); |
240 | 230 |
241 canvas->clipRect(gfx::RectToSkRect(content_tiling_rect), | 231 canvas->clipRect(gfx::RectToSkRect(content_tiling_rect), |
242 SkRegion::kIntersect_Op); | 232 SkRegion::kIntersect_Op); |
(...skipping 15 matching lines...) Expand all Loading... |
258 Region negated_clip_region = it->second; | 248 Region negated_clip_region = it->second; |
259 | 249 |
260 #ifndef NDEBUG | 250 #ifndef NDEBUG |
261 Region positive_clip = content_tiling_rect; | 251 Region positive_clip = content_tiling_rect; |
262 positive_clip.Subtract(negated_clip_region); | 252 positive_clip.Subtract(negated_clip_region); |
263 // Make sure we never rasterize the same region twice. | 253 // Make sure we never rasterize the same region twice. |
264 DCHECK(!total_clip.Intersects(positive_clip)); | 254 DCHECK(!total_clip.Intersects(positive_clip)); |
265 total_clip.Union(positive_clip); | 255 total_clip.Union(positive_clip); |
266 #endif // NDEBUG | 256 #endif // NDEBUG |
267 | 257 |
268 base::TimeDelta best_duration = base::TimeDelta::Max(); | |
269 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); | 258 int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_); |
270 int rasterized_pixel_count = 0; | |
271 | 259 |
272 for (int j = 0; j < repeat_count; ++j) { | 260 for (int j = 0; j < repeat_count; ++j) |
273 base::TimeTicks start_time; | 261 picture->Raster(canvas, callback, negated_clip_region, contents_scale); |
274 if (rendering_stats_instrumentation) | |
275 start_time = rendering_stats_instrumentation->StartRecording(); | |
276 | |
277 rasterized_pixel_count = picture->Raster( | |
278 canvas, callback, negated_clip_region, contents_scale); | |
279 | |
280 if (rendering_stats_instrumentation) { | |
281 base::TimeDelta duration = | |
282 rendering_stats_instrumentation->EndRecording(start_time); | |
283 best_duration = std::min(best_duration, duration); | |
284 } | |
285 } | |
286 | |
287 if (rendering_stats_instrumentation) { | |
288 if (is_analysis) { | |
289 rendering_stats_instrumentation->AddAnalysis(best_duration, | |
290 rasterized_pixel_count); | |
291 } else { | |
292 rendering_stats_instrumentation->AddRaster(best_duration, | |
293 rasterized_pixel_count); | |
294 } | |
295 } | |
296 } | 262 } |
297 | 263 |
298 #ifndef NDEBUG | 264 #ifndef NDEBUG |
299 // Fill the clip with debug color. This allows us to | 265 // Fill the clip with debug color. This allows us to |
300 // distinguish between non painted areas and problems with missing | 266 // distinguish between non painted areas and problems with missing |
301 // pictures. | 267 // pictures. |
302 SkPaint paint; | 268 SkPaint paint; |
303 for (Region::Iterator it(total_clip); it.has_rect(); it.next()) | 269 for (Region::Iterator it(total_clip); it.has_rect(); it.next()) |
304 canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); | 270 canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); |
305 paint.setColor(DebugColors::MissingPictureFillColor()); | 271 paint.setColor(DebugColors::MissingPictureFillColor()); |
306 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 272 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
307 canvas->drawPaint(paint); | 273 canvas->drawPaint(paint); |
308 #endif // NDEBUG | 274 #endif // NDEBUG |
309 } | 275 } |
310 | 276 |
311 skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() { | 277 skia::RefPtr<SkPicture> PicturePileImpl::GetFlattenedPicture() { |
312 TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture"); | 278 TRACE_EVENT0("cc", "PicturePileImpl::GetFlattenedPicture"); |
313 | 279 |
314 gfx::Rect tiling_rect(tiling_.tiling_size()); | 280 gfx::Rect tiling_rect(tiling_.tiling_size()); |
315 SkPictureRecorder recorder; | 281 SkPictureRecorder recorder; |
316 SkCanvas* canvas = | 282 SkCanvas* canvas = |
317 recorder.beginRecording(tiling_rect.width(), tiling_rect.height()); | 283 recorder.beginRecording(tiling_rect.width(), tiling_rect.height()); |
318 if (!tiling_rect.IsEmpty()) | 284 if (!tiling_rect.IsEmpty()) |
319 PlaybackToCanvas(canvas, tiling_rect, 1.0, NULL); | 285 PlaybackToCanvas(canvas, tiling_rect, 1.0); |
320 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); | 286 skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); |
321 | 287 |
322 return picture; | 288 return picture; |
323 } | 289 } |
324 | 290 |
325 void PicturePileImpl::PerformSolidColorAnalysis( | 291 void PicturePileImpl::PerformSolidColorAnalysis( |
326 const gfx::Rect& content_rect, | 292 const gfx::Rect& content_rect, |
327 float contents_scale, | 293 float contents_scale, |
328 RasterSource::SolidColorAnalysis* analysis, | 294 RasterSource::SolidColorAnalysis* analysis) const { |
329 RenderingStatsInstrumentation* stats_instrumentation) const { | |
330 DCHECK(analysis); | 295 DCHECK(analysis); |
331 TRACE_EVENT0("cc", "PicturePileImpl::PerformSolidColorAnalysis"); | 296 TRACE_EVENT0("cc", "PicturePileImpl::PerformSolidColorAnalysis"); |
332 | 297 |
333 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( | 298 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( |
334 content_rect, 1.0f / contents_scale); | 299 content_rect, 1.0f / contents_scale); |
335 | 300 |
336 layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); | 301 layer_rect.Intersect(gfx::Rect(tiling_.tiling_size())); |
337 | 302 |
338 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); | 303 skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); |
339 | 304 |
340 RasterForAnalysis(&canvas, layer_rect, 1.0f, stats_instrumentation); | 305 RasterForAnalysis(&canvas, layer_rect, 1.0f); |
341 | 306 |
342 analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color); | 307 analysis->is_solid_color = canvas.GetColorIfSolid(&analysis->solid_color); |
343 } | 308 } |
344 | 309 |
345 void PicturePileImpl::GatherPixelRefs( | 310 void PicturePileImpl::GatherPixelRefs( |
346 const gfx::Rect& content_rect, | 311 const gfx::Rect& content_rect, |
347 float contents_scale, | 312 float contents_scale, |
348 std::vector<SkPixelRef*>* pixel_refs) const { | 313 std::vector<SkPixelRef*>* pixel_refs) const { |
349 DCHECK_EQ(0u, pixel_refs->size()); | 314 DCHECK_EQ(0u, pixel_refs->size()); |
350 for (PixelRefIterator iter(content_rect, contents_scale, this); iter; | 315 for (PixelRefIterator iter(content_rect, contents_scale, this); iter; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 ++it) { | 384 ++it) { |
420 const Picture* picture = it->second.GetPicture(); | 385 const Picture* picture = it->second.GetPicture(); |
421 if (picture && (processed_pictures.count(picture) == 0)) { | 386 if (picture && (processed_pictures.count(picture) == 0)) { |
422 picture->EmitTraceSnapshot(); | 387 picture->EmitTraceSnapshot(); |
423 processed_pictures.insert(picture); | 388 processed_pictures.insert(picture); |
424 } | 389 } |
425 } | 390 } |
426 } | 391 } |
427 | 392 |
428 } // namespace cc | 393 } // namespace cc |
OLD | NEW |