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 |
11 #include "base/base64.h" | 11 #include "base/base64.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/debug/trace_event_argument.h" | 13 #include "base/debug/trace_event_argument.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "cc/base/math_util.h" | 15 #include "cc/base/math_util.h" |
16 #include "cc/base/util.h" | 16 #include "cc/base/util.h" |
| 17 #include "cc/debug/picture_debug_util.h" |
17 #include "cc/debug/traced_picture.h" | 18 #include "cc/debug/traced_picture.h" |
18 #include "cc/debug/traced_value.h" | 19 #include "cc/debug/traced_value.h" |
19 #include "cc/layers/content_layer_client.h" | 20 #include "cc/layers/content_layer_client.h" |
20 #include "skia/ext/pixel_ref_utils.h" | 21 #include "skia/ext/pixel_ref_utils.h" |
21 #include "third_party/skia/include/core/SkBBHFactory.h" | 22 #include "third_party/skia/include/core/SkBBHFactory.h" |
22 #include "third_party/skia/include/core/SkCanvas.h" | 23 #include "third_party/skia/include/core/SkCanvas.h" |
23 #include "third_party/skia/include/core/SkData.h" | |
24 #include "third_party/skia/include/core/SkDrawPictureCallback.h" | 24 #include "third_party/skia/include/core/SkDrawPictureCallback.h" |
25 #include "third_party/skia/include/core/SkPaint.h" | 25 #include "third_party/skia/include/core/SkPaint.h" |
26 #include "third_party/skia/include/core/SkPictureRecorder.h" | 26 #include "third_party/skia/include/core/SkPictureRecorder.h" |
27 #include "third_party/skia/include/core/SkPixelSerializer.h" | |
28 #include "third_party/skia/include/core/SkStream.h" | 27 #include "third_party/skia/include/core/SkStream.h" |
29 #include "third_party/skia/include/utils/SkNullCanvas.h" | 28 #include "third_party/skia/include/utils/SkNullCanvas.h" |
30 #include "third_party/skia/include/utils/SkPictureUtils.h" | 29 #include "third_party/skia/include/utils/SkPictureUtils.h" |
31 #include "ui/gfx/codec/jpeg_codec.h" | 30 #include "ui/gfx/codec/jpeg_codec.h" |
32 #include "ui/gfx/codec/png_codec.h" | 31 #include "ui/gfx/codec/png_codec.h" |
33 #include "ui/gfx/geometry/rect_conversions.h" | 32 #include "ui/gfx/geometry/rect_conversions.h" |
34 #include "ui/gfx/skia_util.h" | 33 #include "ui/gfx/skia_util.h" |
35 | 34 |
36 namespace cc { | 35 namespace cc { |
37 | 36 |
38 namespace { | 37 namespace { |
39 | 38 |
40 class BitmapSerializer : public SkPixelSerializer { | |
41 protected: | |
42 bool onUseEncodedData(const void* data, size_t len) override { return true; } | |
43 | |
44 SkData* onEncodePixels(const SkImageInfo& info, | |
45 const void* pixels, | |
46 size_t row_bytes) override { | |
47 const int kJpegQuality = 80; | |
48 std::vector<unsigned char> data; | |
49 | |
50 // If bitmap is opaque, encode as JPEG. | |
51 // Otherwise encode as PNG. | |
52 bool encoding_succeeded = false; | |
53 if (info.isOpaque()) { | |
54 encoding_succeeded = | |
55 gfx::JPEGCodec::Encode(reinterpret_cast<const unsigned char*>(pixels), | |
56 gfx::JPEGCodec::FORMAT_SkBitmap, info.width(), | |
57 info.height(), row_bytes, kJpegQuality, &data); | |
58 } else { | |
59 SkBitmap bm; | |
60 // The cast is ok, since we only read the bm. | |
61 if (!bm.installPixels(info, const_cast<void*>(pixels), row_bytes)) { | |
62 return nullptr; | |
63 } | |
64 encoding_succeeded = gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &data); | |
65 } | |
66 | |
67 if (encoding_succeeded) { | |
68 return SkData::NewWithCopy(&data.front(), data.size()); | |
69 } | |
70 return nullptr; | |
71 } | |
72 }; | |
73 | |
74 bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { | 39 bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { |
75 const unsigned char* data = static_cast<const unsigned char *>(buffer); | 40 const unsigned char* data = static_cast<const unsigned char *>(buffer); |
76 | 41 |
77 // Try PNG first. | 42 // Try PNG first. |
78 if (gfx::PNGCodec::Decode(data, size, bm)) | 43 if (gfx::PNGCodec::Decode(data, size, bm)) |
79 return true; | 44 return true; |
80 | 45 |
81 // Try JPEG. | 46 // Try JPEG. |
82 scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size)); | 47 scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size)); |
83 if (decoded_jpeg) { | 48 if (decoded_jpeg) { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 const gfx::Rect& layer_rect, | 135 const gfx::Rect& layer_rect, |
171 const PixelRefMap& pixel_refs) : | 136 const PixelRefMap& pixel_refs) : |
172 layer_rect_(layer_rect), | 137 layer_rect_(layer_rect), |
173 picture_(picture), | 138 picture_(picture), |
174 pixel_refs_(pixel_refs), | 139 pixel_refs_(pixel_refs), |
175 cell_size_(layer_rect.size()) { | 140 cell_size_(layer_rect.size()) { |
176 } | 141 } |
177 | 142 |
178 Picture::~Picture() { | 143 Picture::~Picture() { |
179 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 144 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
180 TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::Picture", this); | 145 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture"), "cc::Picture", this); |
181 } | 146 } |
182 | 147 |
183 bool Picture::IsSuitableForGpuRasterization(const char** reason) const { | 148 bool Picture::IsSuitableForGpuRasterization(const char** reason) const { |
184 DCHECK(picture_); | 149 DCHECK(picture_); |
185 | 150 |
186 // TODO(hendrikw): SkPicture::suitableForGpuRasterization takes a GrContext. | 151 // TODO(hendrikw): SkPicture::suitableForGpuRasterization takes a GrContext. |
187 // Currently the GrContext isn't used, and should probably be removed from | 152 // Currently the GrContext isn't used, and should probably be removed from |
188 // skia. | 153 // skia. |
189 return picture_->suitableForGpuRasterization(nullptr, reason); | 154 return picture_->suitableForGpuRasterization(nullptr, reason); |
190 } | 155 } |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); | 329 TRACE_EVENT_BEGIN0("cc", "Picture::Replay"); |
365 DCHECK(picture_); | 330 DCHECK(picture_); |
366 picture_->playback(canvas); | 331 picture_->playback(canvas); |
367 SkIRect bounds; | 332 SkIRect bounds; |
368 canvas->getClipDeviceBounds(&bounds); | 333 canvas->getClipDeviceBounds(&bounds); |
369 TRACE_EVENT_END1("cc", "Picture::Replay", | 334 TRACE_EVENT_END1("cc", "Picture::Replay", |
370 "num_pixels_replayed", bounds.width() * bounds.height()); | 335 "num_pixels_replayed", bounds.width() * bounds.height()); |
371 } | 336 } |
372 | 337 |
373 scoped_ptr<base::Value> Picture::AsValue() const { | 338 scoped_ptr<base::Value> Picture::AsValue() const { |
374 SkDynamicMemoryWStream stream; | |
375 BitmapSerializer serializer; | |
376 picture_->serialize(&stream, &serializer); | |
377 | |
378 // Encode the picture as base64. | 339 // Encode the picture as base64. |
379 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 340 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
380 res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release()); | 341 res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release()); |
381 | |
382 size_t serialized_size = stream.bytesWritten(); | |
383 scoped_ptr<char[]> serialized_picture(new char[serialized_size]); | |
384 stream.copyTo(serialized_picture.get()); | |
385 std::string b64_picture; | 342 std::string b64_picture; |
386 base::Base64Encode(std::string(serialized_picture.get(), serialized_size), | 343 PictureDebugUtil::SerializeAsBase64(picture_.get(), &b64_picture); |
387 &b64_picture); | |
388 res->SetString("skp64", b64_picture); | 344 res->SetString("skp64", b64_picture); |
389 return res.Pass(); | 345 return res.Pass(); |
390 } | 346 } |
391 | 347 |
392 void Picture::EmitTraceSnapshot() const { | 348 void Picture::EmitTraceSnapshot() const { |
393 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 349 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
394 TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT( | 350 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
395 "devtools.timeline.picture"), | 351 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
396 "cc::Picture", | 352 "cc::Picture", |
397 this, | 353 this, |
398 TracedPicture::AsTraceablePicture(this)); | 354 TracedPicture::AsTraceablePicture(this)); |
399 } | 355 } |
400 | 356 |
401 void Picture::EmitTraceSnapshotAlias(Picture* original) const { | 357 void Picture::EmitTraceSnapshotAlias(Picture* original) const { |
402 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 358 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
403 TRACE_DISABLED_BY_DEFAULT("cc.debug") "," TRACE_DISABLED_BY_DEFAULT( | 359 TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") "," |
404 "devtools.timeline.picture"), | 360 TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"), |
405 "cc::Picture", | 361 "cc::Picture", |
406 this, | 362 this, |
407 TracedPicture::AsTraceablePictureAlias(original)); | 363 TracedPicture::AsTraceablePictureAlias(original)); |
408 } | 364 } |
409 | 365 |
410 base::LazyInstance<Picture::PixelRefs> | 366 base::LazyInstance<Picture::PixelRefs> |
411 Picture::PixelRefIterator::empty_pixel_refs_; | 367 Picture::PixelRefIterator::empty_pixel_refs_; |
412 | 368 |
413 Picture::PixelRefIterator::PixelRefIterator() | 369 Picture::PixelRefIterator::PixelRefIterator() |
414 : picture_(NULL), | 370 : picture_(NULL), |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 scoped_refptr<base::debug::TracedValue> record_data = | 477 scoped_refptr<base::debug::TracedValue> record_data = |
522 new base::debug::TracedValue(); | 478 new base::debug::TracedValue(); |
523 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); | 479 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); |
524 record_data->BeginArray("layer_rect"); | 480 record_data->BeginArray("layer_rect"); |
525 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); | 481 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); |
526 record_data->EndArray(); | 482 record_data->EndArray(); |
527 return record_data; | 483 return record_data; |
528 } | 484 } |
529 | 485 |
530 } // namespace cc | 486 } // namespace cc |
OLD | NEW |