1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/messaging/blink_transferable_message_struct_traits.h"
#include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace mojo {
namespace {
scoped_refptr<blink::StaticBitmapImage> ToStaticBitmapImage(
const SkBitmap& sk_bitmap) {
auto handle = WTF::ArrayBufferContents::CreateDataHandle(
sk_bitmap.computeByteSize(), WTF::ArrayBufferContents::kZeroInitialize);
if (!handle)
return nullptr;
WTF::ArrayBufferContents array_buffer_contents(
std::move(handle), WTF::ArrayBufferContents::kNotShared);
if (!array_buffer_contents.Data())
return nullptr;
SkImageInfo info = sk_bitmap.info();
if (!sk_bitmap.readPixels(info, array_buffer_contents.Data(),
info.minRowBytes(), 0, 0))
return nullptr;
return blink::StaticBitmapImage::Create(array_buffer_contents, info);
}
bool ToSkBitmap(
const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image,
SkBitmap& dest) {
const sk_sp<SkImage> image =
static_bitmap_image->PaintImageForCurrentFrame().GetSkImage();
return image && image->asLegacyBitmap(
&dest, SkImage::LegacyBitmapMode::kRO_LegacyBitmapMode);
}
} // namespace
Vector<SkBitmap>
StructTraits<blink::mojom::blink::TransferableMessage::DataView,
blink::BlinkTransferableMessage>::
image_bitmap_contents_array(const blink::BlinkCloneableMessage& input) {
Vector<SkBitmap> out;
out.ReserveInitialCapacity(
input.message->GetImageBitmapContentsArray().size());
for (auto& bitmap_contents : input.message->GetImageBitmapContentsArray()) {
SkBitmap bitmap;
if (!ToSkBitmap(bitmap_contents, bitmap)) {
return Vector<SkBitmap>();
}
out.push_back(std::move(bitmap));
}
return out;
}
bool StructTraits<blink::mojom::blink::TransferableMessage::DataView,
blink::BlinkTransferableMessage>::
Read(blink::mojom::blink::TransferableMessage::DataView data,
blink::BlinkTransferableMessage* out) {
Vector<mojo::ScopedMessagePipeHandle> ports;
blink::SerializedScriptValue::ArrayBufferContentsArray
array_buffer_contents_array;
Vector<SkBitmap> sk_bitmaps;
if (!data.ReadMessage(static_cast<blink::BlinkCloneableMessage*>(out)) ||
!data.ReadArrayBufferContentsArray(&array_buffer_contents_array) ||
!data.ReadImageBitmapContentsArray(&sk_bitmaps) ||
!data.ReadPorts(&ports)) {
return false;
}
out->ports.ReserveInitialCapacity(ports.size());
out->ports.AppendRange(std::make_move_iterator(ports.begin()),
std::make_move_iterator(ports.end()));
out->has_user_gesture = data.has_user_gesture();
out->message->SetArrayBufferContentsArray(
std::move(array_buffer_contents_array));
array_buffer_contents_array.clear();
// Bitmaps are serialized in mojo as SkBitmaps to leverage existing
// serialization logic, but SerializedScriptValue uses StaticBitmapImage, so
// the SkBitmaps need to be converted to StaticBitmapImages.
blink::SerializedScriptValue::ImageBitmapContentsArray
image_bitmap_contents_array;
for (auto& sk_bitmap : sk_bitmaps) {
const scoped_refptr<blink::StaticBitmapImage> bitmap_contents =
ToStaticBitmapImage(sk_bitmap);
if (!bitmap_contents) {
return false;
}
image_bitmap_contents_array.push_back(bitmap_contents);
}
out->message->SetImageBitmapContentsArray(image_bitmap_contents_array);
return true;
}
bool StructTraits<blink::mojom::blink::SerializedArrayBufferContents::DataView,
WTF::ArrayBufferContents>::
Read(blink::mojom::blink::SerializedArrayBufferContents::DataView data,
WTF::ArrayBufferContents* out) {
mojo_base::BigBufferView contents_view;
if (!data.ReadContents(&contents_view))
return false;
auto contents_data = contents_view.data();
auto handle = WTF::ArrayBufferContents::CreateDataHandle(
contents_data.size(), WTF::ArrayBufferContents::kZeroInitialize);
if (!handle)
return false;
WTF::ArrayBufferContents array_buffer_contents(
std::move(handle), WTF::ArrayBufferContents::kNotShared);
memcpy(array_buffer_contents.Data(), contents_data.data(),
contents_data.size());
*out = std::move(array_buffer_contents);
return true;
}
} // namespace mojo
|