Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: blimp/engine/renderer/engine_image_serialization_processor.cc

Issue 1867653002: Initial version of Blimp BlobCache. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changed BlobId from 'const std::string' to 'std::string' Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "blimp/engine/renderer/engine_image_serialization_processor.h" 5 #include "blimp/engine/renderer/engine_image_serialization_processor.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <set>
9 #include <string>
8 #include <vector> 10 #include <vector>
9 11
12 #include "base/lazy_instance.h"
10 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/sha1.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "blimp/common/blob_cache/sha1_util.h"
11 #include "blimp/common/compositor/webp_decoder.h" 18 #include "blimp/common/compositor/webp_decoder.h"
19 #include "blimp/common/proto/blob_cache.pb.h"
12 #include "content/public/renderer/render_frame.h" 20 #include "content/public/renderer/render_frame.h"
13 #include "third_party/libwebp/webp/encode.h" 21 #include "third_party/libwebp/webp/encode.h"
14 #include "third_party/skia/include/core/SkData.h" 22 #include "third_party/skia/include/core/SkData.h"
15 #include "third_party/skia/include/core/SkPicture.h" 23 #include "third_party/skia/include/core/SkPicture.h"
16 #include "third_party/skia/include/core/SkPixelSerializer.h" 24 #include "third_party/skia/include/core/SkPixelSerializer.h"
17 #include "third_party/skia/include/core/SkUnPreMultiply.h" 25 #include "third_party/skia/include/core/SkUnPreMultiply.h"
18 26
27 namespace blimp {
19 namespace { 28 namespace {
29
30 // TODO(nyquist): Add support for changing this from the client.
31 static base::LazyInstance<std::set<BlobId>> g_client_cache_contents =
32 LAZY_INSTANCE_INITIALIZER;
33
34 SkData* BlobCacheImageMetadataProtoAsSkData(
35 const BlobCacheImageMetadata& proto) {
36 int signed_size = proto.ByteSize();
37 size_t unsigned_size = base::checked_cast<size_t>(signed_size);
38 std::vector<uint8_t> serialized(unsigned_size);
39 proto.SerializeToArray(serialized.data(), signed_size);
Kevin M 2016/04/18 18:13:14 optimization nit: SerializeWithCachedSizesToArray?
nyquist 2016/04/18 20:12:02 Done.
40 return SkData::NewWithCopy(serialized.data(), serialized.size());
41 }
42
20 // TODO(nyquist): Make sure encoder does not serialize images more than once. 43 // TODO(nyquist): Make sure encoder does not serialize images more than once.
21 // See crbug.com/548434. 44 // See crbug.com/548434.
22 class WebPImageEncoder : public SkPixelSerializer { 45 class WebPImageEncoder : public SkPixelSerializer {
23 public: 46 public:
24 WebPImageEncoder() {} 47 WebPImageEncoder() {}
25 ~WebPImageEncoder() override{}; 48 ~WebPImageEncoder() override{};
26 49
27 bool onUseEncodedData(const void* data, size_t len) override { 50 bool onUseEncodedData(const void* data, size_t len) override {
28 const unsigned char* cast_data = static_cast<const unsigned char*>(data); 51 // Always encode even WebP data, to enable caching.
Kevin M 2016/04/18 18:13:14 "even" ? "Encode all images regardless of their f
nyquist 2016/04/18 20:12:02 Done.
29 if (len < 14) 52 return false;
30 return false;
31 return !memcmp(cast_data, "RIFF", 4) && !memcmp(cast_data + 8, "WEBPVP", 6);
32 } 53 }
33 54
34 SkData* onEncode(const SkPixmap& pixmap) override { 55 SkData* onEncode(const SkPixmap& pixmap) override {
35 // Initialize an empty WebPConfig. 56 // Initialize an empty WebPConfig.
36 WebPConfig config; 57 WebPConfig config;
37 if (!WebPConfigInit(&config)) 58 if (!WebPConfigInit(&config))
38 return nullptr; 59 return nullptr;
39 60
40 // Initialize an empty WebPPicture. 61 // Initialize an empty WebPPicture.
41 WebPPicture picture; 62 WebPPicture picture;
42 if (!WebPPictureInit(&picture)) 63 if (!WebPPictureInit(&picture))
43 return nullptr; 64 return nullptr;
44 65
45 // Ensure width and height are valid dimensions. 66 // Ensure width and height are valid dimensions.
46 if (!pixmap.width() || pixmap.width() > WEBP_MAX_DIMENSION) 67 if (!pixmap.width() || pixmap.width() > WEBP_MAX_DIMENSION)
47 return nullptr; 68 return nullptr;
48 picture.width = pixmap.width(); 69 picture.width = pixmap.width();
49 if (!pixmap.height() || pixmap.height() > WEBP_MAX_DIMENSION) 70 if (!pixmap.height() || pixmap.height() > WEBP_MAX_DIMENSION)
50 return nullptr; 71 return nullptr;
51 picture.height = pixmap.height(); 72 picture.height = pixmap.height();
52 73
74 const BlobId blob_id = CalculateBlobId(pixmap.addr(), pixmap.getSafeSize());
75 std::string blob_id_hex = FormatBlobId(blob_id);
76
77 // Create proto with all requires information.
78 BlobCacheImageMetadata proto;
79 proto.set_id(blob_id);
80 proto.set_width(pixmap.width());
81 proto.set_height(pixmap.height());
82
83 if (g_client_cache_contents.Get().find(blob_id) !=
84 g_client_cache_contents.Get().end()) {
85 // Found image in client cache, so skip sending decoded payload.
86 SkData* sk_data = BlobCacheImageMetadataProtoAsSkData(proto);
87 DVLOG(2) << "Sending cached: " << blob_id_hex
88 << " size = " << sk_data->size();
89 return sk_data;
90 }
91
53 DVLOG(2) << "Encoding image color_type=" << pixmap.colorType() 92 DVLOG(2) << "Encoding image color_type=" << pixmap.colorType()
54 << ", alpha_type=" << pixmap.alphaType() << " " << pixmap.width() 93 << ", alpha_type=" << pixmap.alphaType() << " " << pixmap.width()
55 << "x" << pixmap.height(); 94 << "x" << pixmap.height();
56 95
57 // Import picture from raw pixels. 96 // Import picture from raw pixels.
58 auto pixel_chars = static_cast<const unsigned char*>(pixmap.addr()); 97 auto pixel_chars = static_cast<const unsigned char*>(pixmap.addr());
59 if (!PlatformPictureImport(pixel_chars, &picture, pixmap.alphaType())) 98 if (!PlatformPictureImport(pixel_chars, &picture, pixmap.alphaType()))
60 return nullptr; 99 return nullptr;
61 100
62 // Create a buffer for where to store the output data. 101 // Create a buffer for where to store the output data.
63 std::vector<unsigned char> data; 102 std::vector<unsigned char> data;
Kevin M 2016/04/18 18:13:14 Pick a more descriptive name?
nyquist 2016/04/18 20:12:02 Done.
64 picture.custom_ptr = &data; 103 picture.custom_ptr = &data;
65 104
66 // Use our own WebPWriterFunction implementation. 105 // Use our own WebPWriterFunction implementation.
67 picture.writer = &WebPImageEncoder::WriteOutput; 106 picture.writer = &WebPImageEncoder::WriteOutput;
68 107
69 // Setup the configuration for the output WebP picture. This is currently 108 // Setup the configuration for the output WebP picture. This is currently
70 // the same as the default configuration for WebP, but since any change in 109 // the same as the default configuration for WebP, but since any change in
71 // the WebP defaults would invalidate all caches they are hard coded. 110 // the WebP defaults would invalidate all caches they are hard coded.
72 config.lossless = 0; 111 config.lossless = 0;
73 config.quality = 75.0; // between 0 (smallest file) and 100 (biggest). 112 config.quality = 75.0; // between 0 (smallest file) and 100 (biggest).
74 config.method = 4; // quality/speed trade-off (0=fast, 6=slower-better). 113 config.method = 4; // quality/speed trade-off (0=fast, 6=slower-better).
75 114
76 // Encode the picture using the given configuration. 115 // Encode the picture using the given configuration.
77 bool success = WebPEncode(&config, &picture); 116 bool success = WebPEncode(&config, &picture);
78 117
79 // Release the memory allocated by WebPPictureImport*(). This does not free 118 // Release the memory allocated by WebPPictureImport*(). This does not free
80 // the memory used by the picture object itself. 119 // the memory used by the picture object itself.
81 WebPPictureFree(&picture); 120 WebPPictureFree(&picture);
82 121
83 if (!success) 122 if (!success)
84 return nullptr; 123 return nullptr;
85 124
86 // Copy WebP data into SkData. |data| is allocated only on the stack, so 125 // Did not find item in cache, so add it to client cache representation
87 // it is automatically deleted after this. 126 // and send full item.
88 return SkData::NewWithCopy(&data.front(), data.size()); 127 g_client_cache_contents.Get().insert(blob_id);
128 proto.set_payload(&data.front(), data.size());
129
130 // Copy proto into SkData.
131 SkData* sk_data = BlobCacheImageMetadataProtoAsSkData(proto);
132 DVLOG(2) << "Sending image: " << blob_id_hex
133 << " size = " << sk_data->size();
134 return sk_data;
89 } 135 }
90 136
91 private: 137 private:
92 // WebPWriterFunction implementation. 138 // WebPWriterFunction implementation.
93 static int WriteOutput(const uint8_t* data, 139 static int WriteOutput(const uint8_t* data,
94 size_t size, 140 size_t size,
95 const WebPPicture* const picture) { 141 const WebPPicture* const picture) {
96 std::vector<unsigned char>* dest = 142 std::vector<unsigned char>* dest =
97 static_cast<std::vector<unsigned char>*>(picture->custom_ptr); 143 static_cast<std::vector<unsigned char>*>(picture->custom_ptr);
98 dest->insert(dest->end(), data, data + size); 144 dest->insert(dest->end(), data, data + size);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 188 }
143 189
144 if (SK_B32_SHIFT) // Android 190 if (SK_B32_SHIFT) // Android
145 return WebPPictureImportRGBA(picture, pixels, row_stride); 191 return WebPPictureImportRGBA(picture, pixels, row_stride);
146 return WebPPictureImportBGRA(picture, pixels, row_stride); 192 return WebPPictureImportBGRA(picture, pixels, row_stride);
147 } 193 }
148 }; 194 };
149 195
150 } // namespace 196 } // namespace
151 197
152 namespace blimp {
153 namespace engine { 198 namespace engine {
154 199
155 EngineImageSerializationProcessor::EngineImageSerializationProcessor( 200 EngineImageSerializationProcessor::EngineImageSerializationProcessor(
156 mojom::BlobChannelPtr blob_channel) 201 mojom::BlobChannelPtr blob_channel)
157 : blob_channel_(std::move(blob_channel)) { 202 : blob_channel_(std::move(blob_channel)) {
158 DCHECK(blob_channel_); 203 DCHECK(blob_channel_);
159 204
160 pixel_serializer_.reset(new WebPImageEncoder); 205 pixel_serializer_.reset(new WebPImageEncoder);
161 206
162 // Dummy BlobChannel command. 207 // Dummy BlobChannel command.
163 // TODO(nyquist): Remove this after integrating BlobChannel. 208 // TODO(nyquist): Remove this after integrating BlobChannel.
164 blob_channel_->Push("foo"); 209 blob_channel_->Push("foo");
165 } 210 }
166 211
167 EngineImageSerializationProcessor::~EngineImageSerializationProcessor() {} 212 EngineImageSerializationProcessor::~EngineImageSerializationProcessor() {}
168 213
169 SkPixelSerializer* EngineImageSerializationProcessor::GetPixelSerializer() { 214 SkPixelSerializer* EngineImageSerializationProcessor::GetPixelSerializer() {
170 return pixel_serializer_.get(); 215 return pixel_serializer_.get();
171 } 216 }
172 217
173 SkPicture::InstallPixelRefProc 218 SkPicture::InstallPixelRefProc
174 EngineImageSerializationProcessor::GetPixelDeserializer() { 219 EngineImageSerializationProcessor::GetPixelDeserializer() {
175 return nullptr; 220 return nullptr;
176 } 221 }
177 222
178 } // namespace engine 223 } // namespace engine
179 } // namespace blimp 224 } // namespace blimp
OLDNEW
« blimp/common/compositor/webp_decoder.cc ('K') | « blimp/engine/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698