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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 pixel_refs_(pixel_refs), | 185 pixel_refs_(pixel_refs), |
186 cell_size_(layer_rect.size()) { | 186 cell_size_(layer_rect.size()) { |
187 } | 187 } |
188 | 188 |
189 Picture::~Picture() { | 189 Picture::~Picture() { |
190 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 190 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
191 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::Picture", this); | 191 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::Picture", this); |
192 } | 192 } |
193 | 193 |
194 Picture* Picture::GetCloneForDrawingOnThread(unsigned thread_index) { | 194 Picture* Picture::GetCloneForDrawingOnThread(unsigned thread_index) { |
| 195 // We don't need clones to draw from multiple threads with SkRecord. |
| 196 if (playback_) { |
| 197 return this; |
| 198 } |
| 199 |
195 // SkPicture is not thread-safe to rasterize with, this returns a clone | 200 // SkPicture is not thread-safe to rasterize with, this returns a clone |
196 // to rasterize with on a specific thread. | 201 // to rasterize with on a specific thread. |
197 CHECK_GE(clones_.size(), thread_index); | 202 CHECK_GE(clones_.size(), thread_index); |
198 return thread_index == clones_.size() ? this : clones_[thread_index].get(); | 203 return thread_index == clones_.size() ? this : clones_[thread_index].get(); |
199 } | 204 } |
200 | 205 |
201 bool Picture::IsSuitableForGpuRasterization() const { | 206 bool Picture::IsSuitableForGpuRasterization() const { |
202 DCHECK(picture_); | 207 DCHECK(picture_); |
203 | 208 |
204 // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. | 209 // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext. |
205 // Ideally this GrContext should be the same as that for rasterizing this | 210 // Ideally this GrContext should be the same as that for rasterizing this |
206 // picture. But we are on the main thread while the rasterization context | 211 // picture. But we are on the main thread while the rasterization context |
207 // may be on the compositor or raster thread. | 212 // may be on the compositor or raster thread. |
208 // SkPicture::suitableForGpuRasterization is not implemented yet. | 213 // SkPicture::suitableForGpuRasterization is not implemented yet. |
209 // Pass a NULL context for now and discuss with skia folks if the context | 214 // Pass a NULL context for now and discuss with skia folks if the context |
210 // is really needed. | 215 // is really needed. |
211 return picture_->suitableForGpuRasterization(NULL); | 216 return picture_->suitableForGpuRasterization(NULL); |
212 } | 217 } |
213 | 218 |
214 void Picture::CloneForDrawing(int num_threads) { | 219 void Picture::CloneForDrawing(int num_threads) { |
215 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); | 220 TRACE_EVENT1("cc", "Picture::CloneForDrawing", "num_threads", num_threads); |
216 | 221 |
| 222 // We don't need clones to draw from multiple threads with SkRecord. |
| 223 if (playback_) { |
| 224 return; |
| 225 } |
| 226 |
217 DCHECK(picture_); | 227 DCHECK(picture_); |
218 DCHECK(clones_.empty()); | 228 DCHECK(clones_.empty()); |
219 | 229 |
220 // We can re-use this picture for one raster worker thread. | 230 // We can re-use this picture for one raster worker thread. |
221 raster_thread_checker_.DetachFromThread(); | 231 raster_thread_checker_.DetachFromThread(); |
222 | 232 |
223 if (num_threads > 1) { | 233 if (num_threads > 1) { |
224 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads - 1]); | 234 scoped_ptr<SkPicture[]> clones(new SkPicture[num_threads - 1]); |
225 picture_->clone(&clones[0], num_threads - 1); | 235 picture_->clone(&clones[0], num_threads - 1); |
226 | 236 |
(...skipping 20 matching lines...) Expand all Loading... |
247 AsTraceableRecordData(), | 257 AsTraceableRecordData(), |
248 "recording_mode", | 258 "recording_mode", |
249 recording_mode); | 259 recording_mode); |
250 | 260 |
251 DCHECK(!picture_); | 261 DCHECK(!picture_); |
252 DCHECK(!tile_grid_info.fTileInterval.isEmpty()); | 262 DCHECK(!tile_grid_info.fTileInterval.isEmpty()); |
253 | 263 |
254 SkTileGridFactory factory(tile_grid_info); | 264 SkTileGridFactory factory(tile_grid_info); |
255 SkPictureRecorder recorder; | 265 SkPictureRecorder recorder; |
256 | 266 |
| 267 scoped_ptr<EXPERIMENTAL::SkRecording> recording; |
| 268 |
257 skia::RefPtr<SkCanvas> canvas; | 269 skia::RefPtr<SkCanvas> canvas; |
258 canvas = skia::SharePtr( | 270 canvas = skia::SharePtr( |
259 recorder.beginRecording(layer_rect_.width(), | 271 recorder.beginRecording(layer_rect_.width(), |
260 layer_rect_.height(), | 272 layer_rect_.height(), |
261 &factory, | 273 &factory, |
262 SkPicture::kUsePathBoundsForClip_RecordingFlag)); | 274 SkPicture::kUsePathBoundsForClip_RecordingFlag)); |
263 | 275 |
264 switch (recording_mode) { | 276 switch (recording_mode) { |
265 case RECORD_NORMALLY: | 277 case RECORD_NORMALLY: |
266 // Already setup for normal recording | 278 // Already setup for normal recording |
267 break; | 279 break; |
268 case RECORD_WITH_SK_NULL_CANVAS: | 280 case RECORD_WITH_SK_NULL_CANVAS: |
269 canvas = skia::AdoptRef(SkCreateNullCanvas()); | 281 canvas = skia::AdoptRef(SkCreateNullCanvas()); |
270 break; | 282 break; |
271 case RECORD_WITH_PAINTING_DISABLED: | 283 case RECORD_WITH_PAINTING_DISABLED: |
272 // Blink's GraphicsContext will disable painting when given a NULL | 284 // Blink's GraphicsContext will disable painting when given a NULL |
273 // canvas. | 285 // canvas. |
274 canvas.clear(); | 286 canvas.clear(); |
275 break; | 287 break; |
| 288 case RECORD_WITH_SKRECORD: |
| 289 recording.reset(new EXPERIMENTAL::SkRecording(layer_rect_.width(), |
| 290 layer_rect_.height())); |
| 291 canvas = skia::SharePtr(recording->canvas()); |
| 292 break; |
276 default: | 293 default: |
277 NOTREACHED(); | 294 NOTREACHED(); |
278 } | 295 } |
279 | 296 |
280 if (canvas) { | 297 if (canvas) { |
281 canvas->save(); | 298 canvas->save(); |
282 canvas->translate(SkFloatToScalar(-layer_rect_.x()), | 299 canvas->translate(SkFloatToScalar(-layer_rect_.x()), |
283 SkFloatToScalar(-layer_rect_.y())); | 300 SkFloatToScalar(-layer_rect_.y())); |
284 | 301 |
285 SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(), | 302 SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(), |
286 layer_rect_.y(), | 303 layer_rect_.y(), |
287 layer_rect_.width(), | 304 layer_rect_.width(), |
288 layer_rect_.height()); | 305 layer_rect_.height()); |
289 canvas->clipRect(layer_skrect); | 306 canvas->clipRect(layer_skrect); |
290 } | 307 } |
291 | 308 |
292 gfx::RectF opaque_layer_rect; | 309 gfx::RectF opaque_layer_rect; |
293 painter->PaintContents(canvas.get(), layer_rect_, &opaque_layer_rect); | 310 painter->PaintContents(canvas.get(), layer_rect_, &opaque_layer_rect); |
294 | 311 |
295 if (canvas) | 312 if (canvas) |
296 canvas->restore(); | 313 canvas->restore(); |
297 picture_ = skia::AdoptRef(recorder.endRecording()); | 314 picture_ = skia::AdoptRef(recorder.endRecording()); |
298 DCHECK(picture_); | 315 DCHECK(picture_); |
299 | 316 |
| 317 if (recording) { |
| 318 // SkRecording requires it's the only one holding onto canvas before we |
| 319 // may call releasePlayback(). (This helps enforce thread-safety.) |
| 320 canvas.clear(); |
| 321 playback_.reset(recording->releasePlayback()); |
| 322 } |
| 323 |
300 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); | 324 opaque_rect_ = gfx::ToEnclosedRect(opaque_layer_rect); |
301 | 325 |
302 EmitTraceSnapshot(); | 326 EmitTraceSnapshot(); |
303 } | 327 } |
304 | 328 |
305 void Picture::GatherPixelRefs( | 329 void Picture::GatherPixelRefs( |
306 const SkTileGridFactory::TileGridInfo& tile_grid_info) { | 330 const SkTileGridFactory::TileGridInfo& tile_grid_info) { |
307 TRACE_EVENT2("cc", "Picture::GatherPixelRefs", | 331 TRACE_EVENT2("cc", "Picture::GatherPixelRefs", |
308 "width", layer_rect_.width(), | 332 "width", layer_rect_.width(), |
309 "height", layer_rect_.height()); | 333 "height", layer_rect_.height()); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 396 |
373 DCHECK(picture_); | 397 DCHECK(picture_); |
374 | 398 |
375 canvas->save(); | 399 canvas->save(); |
376 | 400 |
377 for (Region::Iterator it(negated_content_region); it.has_rect(); it.next()) | 401 for (Region::Iterator it(negated_content_region); it.has_rect(); it.next()) |
378 canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); | 402 canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op); |
379 | 403 |
380 canvas->scale(contents_scale, contents_scale); | 404 canvas->scale(contents_scale, contents_scale); |
381 canvas->translate(layer_rect_.x(), layer_rect_.y()); | 405 canvas->translate(layer_rect_.x(), layer_rect_.y()); |
382 picture_->draw(canvas, callback); | 406 if (playback_) { |
| 407 playback_->draw(canvas); |
| 408 } else { |
| 409 picture_->draw(canvas, callback); |
| 410 } |
383 SkIRect bounds; | 411 SkIRect bounds; |
384 canvas->getClipDeviceBounds(&bounds); | 412 canvas->getClipDeviceBounds(&bounds); |
385 canvas->restore(); | 413 canvas->restore(); |
386 TRACE_EVENT_END1( | 414 TRACE_EVENT_END1( |
387 "cc", "Picture::Raster", | 415 "cc", "Picture::Raster", |
388 "num_pixels_rasterized", bounds.width() * bounds.height()); | 416 "num_pixels_rasterized", bounds.width() * bounds.height()); |
389 return bounds.width() * bounds.height(); | 417 return bounds.width() * bounds.height(); |
390 } | 418 } |
391 | 419 |
392 void Picture::Replay(SkCanvas* canvas) { | 420 void Picture::Replay(SkCanvas* canvas) { |
393 DCHECK(raster_thread_checker_.CalledOnValidThread()); | 421 DCHECK(raster_thread_checker_.CalledOnValidThread()); |
394 TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); | 422 TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); |
395 DCHECK(picture_); | 423 DCHECK(picture_); |
396 | 424 |
397 picture_->draw(canvas); | 425 if (playback_) { |
| 426 playback_->draw(canvas); |
| 427 } else { |
| 428 picture_->draw(canvas); |
| 429 } |
398 SkIRect bounds; | 430 SkIRect bounds; |
399 canvas->getClipDeviceBounds(&bounds); | 431 canvas->getClipDeviceBounds(&bounds); |
400 TRACE_EVENT_END1("cc", "Picture::Replay", | 432 TRACE_EVENT_END1("cc", "Picture::Replay", |
401 "num_pixels_replayed", bounds.width() * bounds.height()); | 433 "num_pixels_replayed", bounds.width() * bounds.height()); |
402 } | 434 } |
403 | 435 |
404 scoped_ptr<base::Value> Picture::AsValue() const { | 436 scoped_ptr<base::Value> Picture::AsValue() const { |
405 SkDynamicMemoryWStream stream; | 437 SkDynamicMemoryWStream stream; |
406 | 438 |
407 // Serialize the picture. | 439 // Serialize the picture. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 | 577 |
546 scoped_refptr<base::debug::ConvertableToTraceFormat> | 578 scoped_refptr<base::debug::ConvertableToTraceFormat> |
547 Picture::AsTraceableRecordData() const { | 579 Picture::AsTraceableRecordData() const { |
548 scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue()); | 580 scoped_ptr<base::DictionaryValue> record_data(new base::DictionaryValue()); |
549 record_data->Set("picture_id", TracedValue::CreateIDRef(this).release()); | 581 record_data->Set("picture_id", TracedValue::CreateIDRef(this).release()); |
550 record_data->Set("layer_rect", MathUtil::AsValue(layer_rect_).release()); | 582 record_data->Set("layer_rect", MathUtil::AsValue(layer_rect_).release()); |
551 return TracedValue::FromValue(record_data.release()); | 583 return TracedValue::FromValue(record_data.release()); |
552 } | 584 } |
553 | 585 |
554 } // namespace cc | 586 } // namespace cc |
OLD | NEW |