 Chromium Code Reviews
 Chromium Code Reviews Issue 2772113004:
  Make skia.mojom.Bitmap use shared buffer  (Closed)
    
  
    Issue 2772113004:
  Make skia.mojom.Bitmap use shared buffer  (Closed) 
  | 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 |