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

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: git merge origin/master for good measure 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
« blimp/common/blob_cache/id_util.cc ('K') | « blimp/engine/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/id_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.SerializeWithCachedSizesToArray(serialized.data());
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 // Encode all images regardless of their format, including WebP images.
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> encoded_data;
64 picture.custom_ptr = &data; 103 picture.custom_ptr = &encoded_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 113
75 // TODO(nyquist): Move image encoding to a different thread when 114 // TODO(nyquist): Move image encoding to a different thread when
76 // asynchronous loading of images is possible. The encode work currently 115 // asynchronous loading of images is possible. The encode work currently
77 // blocks the render thread so we are dropping the method down to 0. 116 // blocks the render thread so we are dropping the method down to 0.
78 // crbug.com/603643. 117 // crbug.com/603643.
79 config.method = 0; // quality/speed trade-off (0=fast, 6=slower-better). 118 config.method = 0; // quality/speed trade-off (0=fast, 6=slower-better).
80 119
81 // Encode the picture using the given configuration. 120 // Encode the picture using the given configuration.
82 bool success = WebPEncode(&config, &picture); 121 bool success = WebPEncode(&config, &picture);
83 122
84 // Release the memory allocated by WebPPictureImport*(). This does not free 123 // Release the memory allocated by WebPPictureImport*(). This does not free
85 // the memory used by the picture object itself. 124 // the memory used by the picture object itself.
86 WebPPictureFree(&picture); 125 WebPPictureFree(&picture);
87 126
88 if (!success) 127 if (!success)
89 return nullptr; 128 return nullptr;
90 129
91 // Copy WebP data into SkData. |data| is allocated only on the stack, so 130 // Did not find item in cache, so add it to client cache representation
92 // it is automatically deleted after this. 131 // and send full item.
93 return SkData::NewWithCopy(&data.front(), data.size()); 132 g_client_cache_contents.Get().insert(blob_id);
133 proto.set_payload(&encoded_data.front(), encoded_data.size());
134
135 // Copy proto into SkData.
136 SkData* sk_data = BlobCacheImageMetadataProtoAsSkData(proto);
137 DVLOG(2) << "Sending image: " << blob_id_hex
138 << " size = " << sk_data->size();
139 return sk_data;
94 } 140 }
95 141
96 private: 142 private:
97 // WebPWriterFunction implementation. 143 // WebPWriterFunction implementation.
98 static int WriteOutput(const uint8_t* data, 144 static int WriteOutput(const uint8_t* data,
99 size_t size, 145 size_t size,
100 const WebPPicture* const picture) { 146 const WebPPicture* const picture) {
101 std::vector<unsigned char>* dest = 147 std::vector<unsigned char>* dest =
102 static_cast<std::vector<unsigned char>*>(picture->custom_ptr); 148 static_cast<std::vector<unsigned char>*>(picture->custom_ptr);
103 dest->insert(dest->end(), data, data + size); 149 dest->insert(dest->end(), data, data + size);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 193 }
148 194
149 if (SK_B32_SHIFT) // Android 195 if (SK_B32_SHIFT) // Android
150 return WebPPictureImportRGBA(picture, pixels, row_stride); 196 return WebPPictureImportRGBA(picture, pixels, row_stride);
151 return WebPPictureImportBGRA(picture, pixels, row_stride); 197 return WebPPictureImportBGRA(picture, pixels, row_stride);
152 } 198 }
153 }; 199 };
154 200
155 } // namespace 201 } // namespace
156 202
157 namespace blimp {
158 namespace engine { 203 namespace engine {
159 204
160 EngineImageSerializationProcessor::EngineImageSerializationProcessor( 205 EngineImageSerializationProcessor::EngineImageSerializationProcessor(
161 mojom::BlobChannelPtr blob_channel) 206 mojom::BlobChannelPtr blob_channel)
162 : blob_channel_(std::move(blob_channel)) { 207 : blob_channel_(std::move(blob_channel)) {
163 DCHECK(blob_channel_); 208 DCHECK(blob_channel_);
164 209
165 pixel_serializer_.reset(new WebPImageEncoder); 210 pixel_serializer_.reset(new WebPImageEncoder);
166 211
167 // Dummy BlobChannel command. 212 // Dummy BlobChannel command.
168 // TODO(nyquist): Remove this after integrating BlobChannel. 213 // TODO(nyquist): Remove this after integrating BlobChannel.
169 blob_channel_->Push("foo"); 214 blob_channel_->Push("foo");
170 } 215 }
171 216
172 EngineImageSerializationProcessor::~EngineImageSerializationProcessor() {} 217 EngineImageSerializationProcessor::~EngineImageSerializationProcessor() {}
173 218
174 SkPixelSerializer* EngineImageSerializationProcessor::GetPixelSerializer() { 219 SkPixelSerializer* EngineImageSerializationProcessor::GetPixelSerializer() {
175 return pixel_serializer_.get(); 220 return pixel_serializer_.get();
176 } 221 }
177 222
178 SkPicture::InstallPixelRefProc 223 SkPicture::InstallPixelRefProc
179 EngineImageSerializationProcessor::GetPixelDeserializer() { 224 EngineImageSerializationProcessor::GetPixelDeserializer() {
180 return nullptr; 225 return nullptr;
181 } 226 }
182 227
183 } // namespace engine 228 } // namespace engine
184 } // namespace blimp 229 } // namespace blimp
OLDNEW
« blimp/common/blob_cache/id_util.cc ('K') | « blimp/engine/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698