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/traced_picture.h" | 17 #include "cc/debug/traced_picture.h" |
18 #include "cc/debug/traced_value.h" | 18 #include "cc/debug/traced_value.h" |
19 #include "cc/layers/content_layer_client.h" | 19 #include "cc/layers/content_layer_client.h" |
20 #include "skia/ext/pixel_ref_utils.h" | 20 #include "skia/ext/pixel_ref_utils.h" |
21 #include "third_party/skia/include/core/SkBBHFactory.h" | 21 #include "third_party/skia/include/core/SkBBHFactory.h" |
22 #include "third_party/skia/include/core/SkCanvas.h" | 22 #include "third_party/skia/include/core/SkCanvas.h" |
23 #include "third_party/skia/include/core/SkData.h" | 23 #include "third_party/skia/include/core/SkData.h" |
24 #include "third_party/skia/include/core/SkPaint.h" | 24 #include "third_party/skia/include/core/SkPaint.h" |
25 #include "third_party/skia/include/core/SkPictureRecorder.h" | 25 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 26 #include "third_party/skia/include/core/SkPixelSerializer.h" |
26 #include "third_party/skia/include/core/SkStream.h" | 27 #include "third_party/skia/include/core/SkStream.h" |
27 #include "third_party/skia/include/utils/SkNullCanvas.h" | 28 #include "third_party/skia/include/utils/SkNullCanvas.h" |
28 #include "third_party/skia/include/utils/SkPictureUtils.h" | 29 #include "third_party/skia/include/utils/SkPictureUtils.h" |
29 #include "ui/gfx/codec/jpeg_codec.h" | 30 #include "ui/gfx/codec/jpeg_codec.h" |
30 #include "ui/gfx/codec/png_codec.h" | 31 #include "ui/gfx/codec/png_codec.h" |
31 #include "ui/gfx/geometry/rect_conversions.h" | 32 #include "ui/gfx/geometry/rect_conversions.h" |
32 #include "ui/gfx/skia_util.h" | 33 #include "ui/gfx/skia_util.h" |
33 | 34 |
34 namespace cc { | 35 namespace cc { |
35 | 36 |
36 namespace { | 37 namespace { |
37 | 38 |
38 SkData* EncodeBitmap(size_t* offset, const SkBitmap& bm) { | 39 class BitmapSerializer : public SkPixelSerializer { |
39 const int kJpegQuality = 80; | 40 protected: |
40 std::vector<unsigned char> data; | 41 bool onUseEncodedData(const void* data, size_t len) override { return true; } |
41 | 42 |
42 // If bitmap is opaque, encode as JPEG. | 43 SkData* onEncodePixels(const SkImageInfo& info, |
43 // Otherwise encode as PNG. | 44 const void* pixels, |
44 bool encoding_succeeded = false; | 45 size_t row_bytes) override { |
45 if (bm.isOpaque()) { | 46 const int kJpegQuality = 80; |
46 SkAutoLockPixels lock_bitmap(bm); | 47 std::vector<unsigned char> data; |
47 if (bm.empty()) | |
48 return NULL; | |
49 | 48 |
50 encoding_succeeded = gfx::JPEGCodec::Encode( | 49 // If bitmap is opaque, encode as JPEG. |
51 reinterpret_cast<unsigned char*>(bm.getAddr32(0, 0)), | 50 // Otherwise encode as PNG. |
52 gfx::JPEGCodec::FORMAT_SkBitmap, | 51 bool encoding_succeeded = false; |
53 bm.width(), | 52 if (info.isOpaque()) { |
54 bm.height(), | 53 encoding_succeeded = |
55 bm.rowBytes(), | 54 gfx::JPEGCodec::Encode(reinterpret_cast<const unsigned char*>(pixels), |
56 kJpegQuality, | 55 gfx::JPEGCodec::FORMAT_SkBitmap, info.width(), |
57 &data); | 56 info.height(), row_bytes, kJpegQuality, &data); |
58 } else { | 57 } else { |
59 encoding_succeeded = gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &data); | 58 SkBitmap bm; |
| 59 // The cast is ok, since we only read the bm. |
| 60 if (!bm.installPixels(info, const_cast<void*>(pixels), row_bytes)) { |
| 61 return nullptr; |
| 62 } |
| 63 encoding_succeeded = gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &data); |
| 64 } |
| 65 |
| 66 if (encoding_succeeded) { |
| 67 return SkData::NewWithCopy(&data.front(), data.size()); |
| 68 } |
| 69 return nullptr; |
60 } | 70 } |
61 | 71 }; |
62 if (encoding_succeeded) { | |
63 *offset = 0; | |
64 return SkData::NewWithCopy(&data.front(), data.size()); | |
65 } | |
66 return NULL; | |
67 } | |
68 | 72 |
69 bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { | 73 bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) { |
70 const unsigned char* data = static_cast<const unsigned char *>(buffer); | 74 const unsigned char* data = static_cast<const unsigned char *>(buffer); |
71 | 75 |
72 // Try PNG first. | 76 // Try PNG first. |
73 if (gfx::PNGCodec::Decode(data, size, bm)) | 77 if (gfx::PNGCodec::Decode(data, size, bm)) |
74 return true; | 78 return true; |
75 | 79 |
76 // Try JPEG. | 80 // Try JPEG. |
77 scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size)); | 81 scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size)); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 DCHECK(picture_); | 364 DCHECK(picture_); |
361 picture_->playback(canvas); | 365 picture_->playback(canvas); |
362 SkIRect bounds; | 366 SkIRect bounds; |
363 canvas->getClipDeviceBounds(&bounds); | 367 canvas->getClipDeviceBounds(&bounds); |
364 TRACE_EVENT_END1("cc", "Picture::Replay", | 368 TRACE_EVENT_END1("cc", "Picture::Replay", |
365 "num_pixels_replayed", bounds.width() * bounds.height()); | 369 "num_pixels_replayed", bounds.width() * bounds.height()); |
366 } | 370 } |
367 | 371 |
368 scoped_ptr<base::Value> Picture::AsValue() const { | 372 scoped_ptr<base::Value> Picture::AsValue() const { |
369 SkDynamicMemoryWStream stream; | 373 SkDynamicMemoryWStream stream; |
370 picture_->serialize(&stream, &EncodeBitmap); | 374 BitmapSerializer serializer; |
| 375 picture_->serialize(&stream, &serializer); |
371 | 376 |
372 // Encode the picture as base64. | 377 // Encode the picture as base64. |
373 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 378 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
374 res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release()); | 379 res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release()); |
375 | 380 |
376 size_t serialized_size = stream.bytesWritten(); | 381 size_t serialized_size = stream.bytesWritten(); |
377 scoped_ptr<char[]> serialized_picture(new char[serialized_size]); | 382 scoped_ptr<char[]> serialized_picture(new char[serialized_size]); |
378 stream.copyTo(serialized_picture.get()); | 383 stream.copyTo(serialized_picture.get()); |
379 std::string b64_picture; | 384 std::string b64_picture; |
380 base::Base64Encode(std::string(serialized_picture.get(), serialized_size), | 385 base::Base64Encode(std::string(serialized_picture.get(), serialized_size), |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 scoped_refptr<base::debug::TracedValue> record_data = | 520 scoped_refptr<base::debug::TracedValue> record_data = |
516 new base::debug::TracedValue(); | 521 new base::debug::TracedValue(); |
517 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); | 522 TracedValue::SetIDRef(this, record_data.get(), "picture_id"); |
518 record_data->BeginArray("layer_rect"); | 523 record_data->BeginArray("layer_rect"); |
519 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); | 524 MathUtil::AddToTracedValue(layer_rect_, record_data.get()); |
520 record_data->EndArray(); | 525 record_data->EndArray(); |
521 return record_data; | 526 return record_data; |
522 } | 527 } |
523 | 528 |
524 } // namespace cc | 529 } // namespace cc |
OLD | NEW |