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 "cc/resources/picture.h" | 5 #include "cc/resources/picture.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 return false; | 82 return false; |
83 } | 83 } |
84 | 84 |
85 } // namespace | 85 } // namespace |
86 | 86 |
87 scoped_refptr<Picture> Picture::Create( | 87 scoped_refptr<Picture> Picture::Create( |
88 const gfx::Rect& layer_rect, | 88 const gfx::Rect& layer_rect, |
89 ContentLayerClient* client, | 89 ContentLayerClient* client, |
90 const SkTileGridFactory::TileGridInfo& tile_grid_info, | 90 const SkTileGridFactory::TileGridInfo& tile_grid_info, |
91 bool gather_pixel_refs, | 91 bool gather_pixel_refs, |
92 int num_raster_threads, | |
93 RecordingMode recording_mode) { | 92 RecordingMode recording_mode) { |
94 scoped_refptr<Picture> picture = make_scoped_refptr(new Picture(layer_rect)); | 93 scoped_refptr<Picture> picture = make_scoped_refptr(new Picture(layer_rect)); |
95 | 94 |
96 picture->Record(client, tile_grid_info, recording_mode); | 95 picture->Record(client, tile_grid_info, recording_mode); |
97 if (gather_pixel_refs) | 96 if (gather_pixel_refs) |
98 picture->GatherPixelRefs(tile_grid_info); | 97 picture->GatherPixelRefs(tile_grid_info); |
99 picture->CloneForDrawing(num_raster_threads); | |
100 | 98 |
101 return picture; | 99 return picture; |
102 } | 100 } |
103 | 101 |
104 Picture::Picture(const gfx::Rect& layer_rect) | 102 Picture::Picture(const gfx::Rect& layer_rect) |
105 : layer_rect_(layer_rect), | 103 : layer_rect_(layer_rect), |
106 cell_size_(layer_rect.size()) { | 104 cell_size_(layer_rect.size()) { |
107 // Instead of recording a trace event for object creation here, we wait for | 105 // Instead of recording a trace event for object creation here, we wait for |
108 // the picture to be recorded in Picture::Record. | 106 // the picture to be recorded in Picture::Record. |
109 } | 107 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 picture_(picture), | 183 picture_(picture), |
186 pixel_refs_(pixel_refs), | 184 pixel_refs_(pixel_refs), |
187 cell_size_(layer_rect.size()) { | 185 cell_size_(layer_rect.size()) { |
188 } | 186 } |
189 | 187 |
190 Picture::~Picture() { | 188 Picture::~Picture() { |
191 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 189 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
192 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::Picture", this); | 190 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::Picture", this); |
193 } | 191 } |
194 | 192 |
195 Picture* Picture::GetCloneForDrawingOnThread(unsigned thread_index) { | |
196 // We don't need clones to draw from multiple threads with SkRecord. | |
197 if (playback_) { | |
198 return this; | |
199 } | |
200 | |
201 // SkPicture is not thread-safe to rasterize with, this returns a clone | |
202 // to rasterize with on a specific thread. | |
203 CHECK_GE(clones_.size(), thread_index); | |
204 return thread_index == clones_.size() ? this : clones_[thread_index].get(); | |
205 } | |
206 | |
207 bool Picture::IsSuitableForGpuRasterization() const { | 193 bool Picture::IsSuitableForGpuRasterization() const { |
208 DCHECK(picture_); | 194 DCHECK(picture_); |
209 | 195 |
210 // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. | 196 // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. |
211 // Ideally this GrContext should be the same as that for rasterizing this | 197 // Ideally this GrContext should be the same as that for rasterizing this |
212 // picture. But we are on the main thread while the rasterization context | 198 // picture. But we are on the main thread while the rasterization context |
213 // may be on the compositor or raster thread. | 199 // may be on the compositor or raster thread. |
214 // SkPicture::suitableForGpuRasterization is not implemented yet. | 200 // SkPicture::suitableForGpuRasterization is not implemented yet. |
215 // Pass a NULL context for now and discuss with skia folks if the context | 201 // Pass a NULL context for now and discuss with skia folks if the context |
216 // is really needed. | 202 // is really needed. |
217 return picture_->suitableForGpuRasterization(NULL); | 203 return picture_->suitableForGpuRasterization(NULL); |
218 } | 204 } |
219 | 205 |
220 bool Picture::HasText() const { | 206 bool Picture::HasText() const { |
221 DCHECK(picture_); | 207 DCHECK(picture_); |
222 return picture_->hasText(); | 208 return picture_->hasText(); |
223 } | 209 } |
224 | 210 |
225 void Picture::CloneForDrawing(int num_threads) { | |
226 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | |
227 | |
228 // We don't need clones to draw from multiple threads with SkRecord. | |
229 if (playback_) { | |
230 return; | |
231 } | |
232 | |
233 DCHECK(picture_); | |
234 DCHECK(clones_.empty()); | |
235 | |
236 // We can re-use this picture for one raster worker thread. | |
237 raster_thread_checker_.DetachFromThread(); | |
238 | |
239 if (num_threads > 1) { | |
240 for (int i = 0; i < num_threads - 1; i++) { | |
241 scoped_refptr<Picture> clone = | |
242 new Picture(skia::AdoptRef(picture_->clone()), | |
243 layer_rect_, | |
244 opaque_rect_, | |
245 pixel_refs_); | |
246 clones_.push_back(clone); | |
247 | |
248 clone->EmitTraceSnapshotAlias(this); | |
249 clone->raster_thread_checker_.DetachFromThread(); | |
250 } | |
251 } | |
252 } | |
253 | |
254 void Picture::Record(ContentLayerClient* painter, | 211 void Picture::Record(ContentLayerClient* painter, |
255 const SkTileGridFactory::TileGridInfo& tile_grid_info, | 212 const SkTileGridFactory::TileGridInfo& tile_grid_info, |
256 RecordingMode recording_mode) { | 213 RecordingMode recording_mode) { |
257 TRACE_EVENT2("cc", | 214 TRACE_EVENT2("cc", |
258 "Picture::Record", | 215 "Picture::Record", |
259 "data", | 216 "data", |
260 AsTraceableRecordData(), | 217 AsTraceableRecordData(), |
261 "recording_mode", | 218 "recording_mode", |
262 recording_mode); | 219 recording_mode); |
263 | 220 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 min_x = std::min(min_x, min.x()); | 336 min_x = std::min(min_x, min.x()); |
380 min_y = std::min(min_y, min.y()); | 337 min_y = std::min(min_y, min.y()); |
381 max_x = std::max(max_x, max.x()); | 338 max_x = std::max(max_x, max.x()); |
382 max_y = std::max(max_y, max.y()); | 339 max_y = std::max(max_y, max.y()); |
383 } | 340 } |
384 | 341 |
385 min_pixel_cell_ = gfx::Point(min_x, min_y); | 342 min_pixel_cell_ = gfx::Point(min_x, min_y); |
386 max_pixel_cell_ = gfx::Point(max_x, max_y); | 343 max_pixel_cell_ = gfx::Point(max_x, max_y); |
387 } | 344 } |
388 | 345 |
389 int Picture::Raster( | 346 int Picture::Raster(SkCanvas* canvas, |
390 SkCanvas* canvas, | 347 SkDrawPictureCallback* callback, |
391 SkDrawPictureCallback* callback, | 348 const Region& negated_content_region, |
392 const Region& negated_content_region, | 349 float contents_scale) const { |
393 float contents_scale) { | |
394 if (!playback_) | |
395 DCHECK(raster_thread_checker_.CalledOnValidThread()); | |
396 TRACE_EVENT_BEGIN1( | 350 TRACE_EVENT_BEGIN1( |
397 "cc", | 351 "cc", |
398 "Picture::Raster", | 352 "Picture::Raster", |
399 "data", | 353 "data", |
400 AsTraceableRasterData(contents_scale)); | 354 AsTraceableRasterData(contents_scale)); |
401 | 355 |
402 DCHECK(picture_); | 356 DCHECK(picture_); |
403 | 357 |
404 canvas->save(); | 358 canvas->save(); |
405 | 359 |
(...skipping 10 matching lines...) Expand all Loading... |
416 SkIRect bounds; | 370 SkIRect bounds; |
417 canvas->getClipDeviceBounds(&bounds); | 371 canvas->getClipDeviceBounds(&bounds); |
418 canvas->restore(); | 372 canvas->restore(); |
419 TRACE_EVENT_END1( | 373 TRACE_EVENT_END1( |
420 "cc", "Picture::Raster", | 374 "cc", "Picture::Raster", |
421 "num_pixels_rasterized", bounds.width() * bounds.height()); | 375 "num_pixels_rasterized", bounds.width() * bounds.height()); |
422 return bounds.width() * bounds.height(); | 376 return bounds.width() * bounds.height(); |
423 } | 377 } |
424 | 378 |
425 void Picture::Replay(SkCanvas* canvas) { | 379 void Picture::Replay(SkCanvas* canvas) { |
426 if (!playback_) | |
427 DCHECK(raster_thread_checker_.CalledOnValidThread()); | |
428 TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); | 380 TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); |
429 DCHECK(picture_); | 381 DCHECK(picture_); |
430 | 382 |
431 if (playback_) { | 383 if (playback_) { |
432 playback_->draw(canvas); | 384 playback_->draw(canvas); |
433 } else { | 385 } else { |
434 picture_->draw(canvas); | 386 picture_->draw(canvas); |
435 } | 387 } |
436 SkIRect bounds; | 388 SkIRect bounds; |
437 canvas->getClipDeviceBounds(&bounds); | 389 canvas->getClipDeviceBounds(&bounds); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 scoped_refptr<base::debug::TracedValue> record_data = | 556 scoped_refptr<base::debug::TracedValue> record_data = |
605 new base::debug::TracedValue(); | 557 new base::debug::TracedValue(); |
606 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); | 558 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); |
607 record_data->BeginArray("layer_rect"); | 559 record_data->BeginArray("layer_rect"); |
608 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); | 560 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); |
609 record_data->EndArray(); | 561 record_data->EndArray(); |
610 return record_data; | 562 return record_data; |
611 } | 563 } |
612 | 564 |
613 } // namespace cc | 565 } // namespace cc |
OLD | NEW |