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