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

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: Addressed comments from kmarshall, except swap 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
19 namespace { 27 namespace {
28
29 // TODO(nyquist): Add support for changing this from the client.
30 static base::LazyInstance<std::set<std::vector<unsigned char>>>
31 g_client_cache_contents = LAZY_INSTANCE_INITIALIZER;
32
33 SkData* BlobCacheImageMetadataProtoAsSkData(
34 const blimp::BlobCacheImageMetadata& proto) {
35 int signed_size = proto.ByteSize();
36 size_t unsigned_size = base::checked_cast<size_t>(signed_size);
vmpstr 2016/04/15 18:18:54 This is super safe and all, but do you need this?
nyquist 2016/04/16 00:25:30 It returns an int, which could be negative, so we
37 std::vector<uint8_t> serialized(unsigned_size);
38 proto.SerializeToArray(serialized.data(), signed_size);
39 return SkData::NewWithCopy(serialized.data(), serialized.size());
40 }
41
20 // TODO(nyquist): Make sure encoder does not serialize images more than once. 42 // TODO(nyquist): Make sure encoder does not serialize images more than once.
21 // See crbug.com/548434. 43 // See crbug.com/548434.
22 class WebPImageEncoder : public SkPixelSerializer { 44 class WebPImageEncoder : public SkPixelSerializer {
23 public: 45 public:
24 WebPImageEncoder() {} 46 WebPImageEncoder() {}
25 ~WebPImageEncoder() override{}; 47 ~WebPImageEncoder() override{};
26 48
27 bool onUseEncodedData(const void* data, size_t len) override { 49 bool onUseEncodedData(const void* data, size_t len) override {
28 const unsigned char* cast_data = static_cast<const unsigned char*>(data); 50 // Always encode even WebP data, to enable caching.
29 if (len < 14) 51 return false;
30 return false;
31 return !memcmp(cast_data, "RIFF", 4) && !memcmp(cast_data + 8, "WEBPVP", 6);
32 } 52 }
33 53
34 SkData* onEncode(const SkPixmap& pixmap) override { 54 SkData* onEncode(const SkPixmap& pixmap) override {
35 // Initialize an empty WebPConfig. 55 // Initialize an empty WebPConfig.
36 WebPConfig config; 56 WebPConfig config;
37 if (!WebPConfigInit(&config)) 57 if (!WebPConfigInit(&config))
38 return nullptr; 58 return nullptr;
39 59
40 // Initialize an empty WebPPicture. 60 // Initialize an empty WebPPicture.
41 WebPPicture picture; 61 WebPPicture picture;
42 if (!WebPPictureInit(&picture)) 62 if (!WebPPictureInit(&picture))
43 return nullptr; 63 return nullptr;
44 64
45 // Ensure width and height are valid dimensions. 65 // Ensure width and height are valid dimensions.
46 if (!pixmap.width() || pixmap.width() > WEBP_MAX_DIMENSION) 66 if (!pixmap.width() || pixmap.width() > WEBP_MAX_DIMENSION)
47 return nullptr; 67 return nullptr;
48 picture.width = pixmap.width(); 68 picture.width = pixmap.width();
49 if (!pixmap.height() || pixmap.height() > WEBP_MAX_DIMENSION) 69 if (!pixmap.height() || pixmap.height() > WEBP_MAX_DIMENSION)
50 return nullptr; 70 return nullptr;
51 picture.height = pixmap.height(); 71 picture.height = pixmap.height();
52 72
73 // Each pixel is using 4 bytes (RGBA/BGRA), so hash over the whole input.
Kevin M 2016/04/15 17:28:51 Is there something we can check to validate the pi
vmpstr 2016/04/15 18:18:54 SkPixmap has a bunch of functions to tell you the
nyquist 2016/04/16 00:25:30 Doh... I thought they looked like row size :-/ th
74 size_t pixel_size = picture.width * picture.height * 4;
75 std::vector<unsigned char> sha1_bytes =
76 blimp::ToSHA1HashBytes(pixmap.addr(), pixel_size);
77 std::string sha1 = blimp::FormatSHA1Hash(sha1_bytes.data());
78
79 // Create proto with all requires information.
80 std::unique_ptr<blimp::BlobCacheImageMetadata> proto(
vmpstr 2016/04/15 18:18:54 Create this on the stack?
nyquist 2016/04/16 00:25:30 Done.
81 new blimp::BlobCacheImageMetadata);
82 proto->set_id(sha1_bytes.data(), sha1_bytes.size());
83 proto->set_width(pixmap.width());
84 proto->set_height(pixmap.height());
85
86 if (g_client_cache_contents.Get().find(sha1_bytes) !=
87 g_client_cache_contents.Get().end()) {
88 // Found image in client cache, so skip sending decoded payload.
89 SkData* sk_data = BlobCacheImageMetadataProtoAsSkData(*proto.get());
vmpstr 2016/04/15 18:18:54 If you create proto on the stack, then *proto.get(
nyquist 2016/04/16 00:25:30 Done.
90 DVLOG(2) << "Sending cached: " << sha1 << " size = " << sk_data->size();
91 return sk_data;
92 }
93
53 DVLOG(2) << "Encoding image color_type=" << pixmap.colorType() 94 DVLOG(2) << "Encoding image color_type=" << pixmap.colorType()
54 << ", alpha_type=" << pixmap.alphaType() << " " << pixmap.width() 95 << ", alpha_type=" << pixmap.alphaType() << " " << pixmap.width()
55 << "x" << pixmap.height(); 96 << "x" << pixmap.height();
56 97
57 // Import picture from raw pixels. 98 // Import picture from raw pixels.
58 auto pixel_chars = static_cast<const unsigned char*>(pixmap.addr()); 99 auto pixel_chars = static_cast<const unsigned char*>(pixmap.addr());
59 if (!PlatformPictureImport(pixel_chars, &picture, pixmap.alphaType())) 100 if (!PlatformPictureImport(pixel_chars, &picture, pixmap.alphaType()))
60 return nullptr; 101 return nullptr;
61 102
62 // Create a buffer for where to store the output data. 103 // Create a buffer for where to store the output data.
(...skipping 13 matching lines...) Expand all
76 // Encode the picture using the given configuration. 117 // Encode the picture using the given configuration.
77 bool success = WebPEncode(&config, &picture); 118 bool success = WebPEncode(&config, &picture);
78 119
79 // Release the memory allocated by WebPPictureImport*(). This does not free 120 // Release the memory allocated by WebPPictureImport*(). This does not free
80 // the memory used by the picture object itself. 121 // the memory used by the picture object itself.
81 WebPPictureFree(&picture); 122 WebPPictureFree(&picture);
82 123
83 if (!success) 124 if (!success)
84 return nullptr; 125 return nullptr;
85 126
86 // Copy WebP data into SkData. |data| is allocated only on the stack, so 127 // Did not find item in cache, so add it to client cache representation
87 // it is automatically deleted after this. 128 // and send full item.
88 return SkData::NewWithCopy(&data.front(), data.size()); 129 g_client_cache_contents.Get().insert(sha1_bytes);
130 proto->set_payload(&data.front(), data.size());
131
132 // Copy proto into SkData.
133 SkData* sk_data = BlobCacheImageMetadataProtoAsSkData(*proto.get());
134 DVLOG(2) << "Sending image: " << sha1 << " size = " << sk_data->size();
135 return sk_data;
89 } 136 }
90 137
91 private: 138 private:
92 // WebPWriterFunction implementation. 139 // WebPWriterFunction implementation.
93 static int WriteOutput(const uint8_t* data, 140 static int WriteOutput(const uint8_t* data,
94 size_t size, 141 size_t size,
95 const WebPPicture* const picture) { 142 const WebPPicture* const picture) {
96 std::vector<unsigned char>* dest = 143 std::vector<unsigned char>* dest =
97 static_cast<std::vector<unsigned char>*>(picture->custom_ptr); 144 static_cast<std::vector<unsigned char>*>(picture->custom_ptr);
98 dest->insert(dest->end(), data, data + size); 145 dest->insert(dest->end(), data, data + size);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 return pixel_serializer_.get(); 217 return pixel_serializer_.get();
171 } 218 }
172 219
173 SkPicture::InstallPixelRefProc 220 SkPicture::InstallPixelRefProc
174 EngineImageSerializationProcessor::GetPixelDeserializer() { 221 EngineImageSerializationProcessor::GetPixelDeserializer() {
175 return nullptr; 222 return nullptr;
176 } 223 }
177 224
178 } // namespace engine 225 } // namespace engine
179 } // namespace blimp 226 } // 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