OLD | NEW |
---|---|
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 "skia/public/interfaces/bitmap_skbitmap_struct_traits.h" | 5 #include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h" |
6 | 6 |
7 #include <string.h> | |
msw
2017/03/25 00:59:52
q: is this needed?
| |
8 | |
9 #include <utility> | |
10 | |
7 namespace mojo { | 11 namespace mojo { |
8 | 12 |
9 namespace { | 13 namespace { |
10 | 14 |
15 void ReleaseScopedSharedBufferMapping(void* addr, void* context) { | |
16 delete static_cast<mojo::ScopedSharedBufferMapping*>(context); | |
17 } | |
18 | |
11 SkColorType MojoColorTypeToSk(skia::mojom::ColorType type) { | 19 SkColorType MojoColorTypeToSk(skia::mojom::ColorType type) { |
12 switch (type) { | 20 switch (type) { |
13 case skia::mojom::ColorType::UNKNOWN: | 21 case skia::mojom::ColorType::UNKNOWN: |
14 return kUnknown_SkColorType; | 22 return kUnknown_SkColorType; |
15 case skia::mojom::ColorType::ALPHA_8: | 23 case skia::mojom::ColorType::ALPHA_8: |
16 return kAlpha_8_SkColorType; | 24 return kAlpha_8_SkColorType; |
17 case skia::mojom::ColorType::RGB_565: | 25 case skia::mojom::ColorType::RGB_565: |
18 return kRGB_565_SkColorType; | 26 return kRGB_565_SkColorType; |
19 case skia::mojom::ColorType::ARGB_4444: | 27 case skia::mojom::ColorType::ARGB_4444: |
20 return kARGB_4444_SkColorType; | 28 return kARGB_4444_SkColorType; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 return b.height() < 0 ? 0 : static_cast<uint32_t>(b.height()); | 157 return b.height() < 0 ? 0 : static_cast<uint32_t>(b.height()); |
150 } | 158 } |
151 | 159 |
152 // static | 160 // static |
153 uint64_t StructTraits<skia::mojom::BitmapDataView, SkBitmap>::row_bytes( | 161 uint64_t StructTraits<skia::mojom::BitmapDataView, SkBitmap>::row_bytes( |
154 const SkBitmap& b) { | 162 const SkBitmap& b) { |
155 return b.rowBytes(); | 163 return b.rowBytes(); |
156 } | 164 } |
157 | 165 |
158 // static | 166 // static |
159 BitmapBuffer StructTraits<skia::mojom::BitmapDataView, SkBitmap>::pixel_data( | 167 mojo::ScopedSharedBufferHandle |
160 const SkBitmap& b) { | 168 StructTraits<skia::mojom::BitmapDataView, SkBitmap>::pixel_data_buffer_handle( |
161 return {b.getSize(), b.getSize(), static_cast<uint8_t*>(b.getPixels())}; | 169 const SkBitmap& b, |
170 void* context) { | |
171 return (*(static_cast<mojo::ScopedSharedBufferHandle*>(context))) | |
172 ->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY); | |
162 } | 173 } |
163 | 174 |
164 // static | 175 // static |
165 bool StructTraits<skia::mojom::BitmapDataView, SkBitmap>::Read( | 176 bool StructTraits<skia::mojom::BitmapDataView, SkBitmap>::Read( |
166 skia::mojom::BitmapDataView data, | 177 skia::mojom::BitmapDataView data, |
167 SkBitmap* b) { | 178 SkBitmap* b) { |
168 // TODO: Ensure width and height are reasonable, eg. <= kMaxBitmapSize? | 179 // TODO: Ensure width and height are reasonable, eg. <= kMaxBitmapSize? |
169 *b = SkBitmap(); | 180 *b = SkBitmap(); |
170 if (!b->tryAllocPixels( | 181 |
171 SkImageInfo::Make(data.width(), data.height(), | 182 const SkImageInfo info = SkImageInfo::Make( |
172 MojoColorTypeToSk(data.color_type()), | 183 data.width(), data.height(), MojoColorTypeToSk(data.color_type()), |
173 MojoAlphaTypeToSk(data.alpha_type()), | 184 MojoAlphaTypeToSk(data.alpha_type()), |
174 MojoProfileTypeToSk(data.profile_type())), | 185 MojoProfileTypeToSk(data.profile_type())); |
175 data.row_bytes())) { | 186 |
187 // If the image is empty, return success after setting the image info. | |
188 if (data.width() == 0 || data.height() == 0) { | |
msw
2017/03/25 00:59:52
nit: curlies not needed
| |
189 return b->setInfo(info, data.row_bytes()); | |
190 } | |
191 | |
192 mojo::ScopedSharedBufferHandle pixel_data_buffer_handle = | |
193 data.TakePixelDataBufferHandle(); | |
194 if (!pixel_data_buffer_handle.is_valid()) | |
195 return false; | |
196 | |
197 const size_t data_byte_size = data.height() * data.row_bytes(); | |
198 auto mapping = pixel_data_buffer_handle->Map(data_byte_size); | |
199 if (!mapping) | |
200 return false; | |
201 | |
202 if (!b->installPixels(info, mapping.get(), data.row_bytes(), nullptr, | |
msw
2017/03/25 00:59:52
nit: cache a raw pointer for mapping.get() above.
| |
203 &ReleaseScopedSharedBufferMapping, | |
204 new ScopedSharedBufferMapping(std::move(mapping)))) { | |
176 return false; | 205 return false; |
177 } | 206 } |
178 | 207 |
179 // If the image is empty, return success after setting the image info. | |
180 if (data.width() == 0 || data.height() == 0) | |
181 return true; | |
182 | |
183 SkAutoPixmapUnlock pixmap; | |
184 mojo::ArrayDataView<uint8_t> data_view; | |
185 data.GetPixelDataDataView(&data_view); | |
186 if (static_cast<uint32_t>(b->width()) != data.width() || | 208 if (static_cast<uint32_t>(b->width()) != data.width() || |
187 static_cast<uint32_t>(b->height()) != data.height() || | 209 static_cast<uint32_t>(b->height()) != data.height() || |
188 static_cast<uint64_t>(b->rowBytes()) != data.row_bytes() || | 210 static_cast<uint64_t>(b->rowBytes()) != data.row_bytes() || |
189 b->getSize() != data_view.size() || !b->requestLock(&pixmap) || | 211 b->getSize() != data_byte_size) { |
190 !b->readyToDraw()) { | |
191 return false; | 212 return false; |
192 } | 213 } |
193 | 214 |
194 BitmapBuffer bitmap_buffer = {0, b->getSize(), | |
195 static_cast<uint8_t*>(b->getPixels())}; | |
196 if (!data.ReadPixelData(&bitmap_buffer) || bitmap_buffer.size != b->getSize()) | |
197 return false; | |
198 | |
199 b->notifyPixelsChanged(); | 215 b->notifyPixelsChanged(); |
216 b->setImmutable(); // Pixels are on a read-only shared buffer. | |
200 return true; | 217 return true; |
201 } | 218 } |
202 | 219 |
203 // static | 220 // static |
204 void* StructTraits<skia::mojom::BitmapDataView, SkBitmap>::SetUpContext( | 221 void* StructTraits<skia::mojom::BitmapDataView, SkBitmap>::SetUpContext( |
205 const SkBitmap& b) { | 222 const SkBitmap& b) { |
206 b.lockPixels(); | 223 // Shared buffer is not a good way for huge images. Consider alternatives. |
207 return nullptr; | 224 DCHECK_LT(b.width() * b.height(), 4000 * 4000); |
225 | |
226 // Use a context to create a shared buffer for pixels only once. | |
227 SkAutoLockPixels lock_pixels(b); | |
228 const size_t buffer_size = b.getSize(); | |
229 auto* pixel_data_buffer_handle = new mojo::ScopedSharedBufferHandle( | |
230 mojo::SharedBufferHandle::Create(buffer_size)); | |
231 mojo::ScopedSharedBufferMapping mapping = | |
232 (*pixel_data_buffer_handle)->Map(b.getSize()); | |
msw
2017/03/25 00:59:52
nit: use |buffer_size|
| |
233 memcpy(mapping.get(), b.getPixels(), buffer_size); | |
msw
2017/03/25 00:59:52
Do we need this copy? Can the buffer just point to
| |
234 return pixel_data_buffer_handle; | |
208 } | 235 } |
209 | 236 |
210 // static | 237 // static |
211 void StructTraits<skia::mojom::BitmapDataView, SkBitmap>::TearDownContext( | 238 void StructTraits<skia::mojom::BitmapDataView, SkBitmap>::TearDownContext( |
212 const SkBitmap& b, | 239 const SkBitmap& b, |
213 void* context) { | 240 void* context) { |
214 b.unlockPixels(); | 241 delete static_cast<mojo::ScopedSharedBufferHandle*>(context); |
215 } | 242 } |
216 | 243 |
217 } // namespace mojo | 244 } // namespace mojo |
OLD | NEW |