| 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 |