Index: skia/public/interfaces/bitmap_skbitmap_struct_traits.cc |
diff --git a/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc b/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc |
index 35f18be16bce02aed0f2ae89599bcf7901599e83..1bea044a8cde0eee8887ee6432ec21351d4e1d35 100644 |
--- a/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc |
+++ b/skia/public/interfaces/bitmap_skbitmap_struct_traits.cc |
@@ -4,10 +4,18 @@ |
#include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h" |
+#include <string.h> |
msw
2017/03/25 00:59:52
q: is this needed?
|
+ |
+#include <utility> |
+ |
namespace mojo { |
namespace { |
+void ReleaseScopedSharedBufferMapping(void* addr, void* context) { |
+ delete static_cast<mojo::ScopedSharedBufferMapping*>(context); |
+} |
+ |
SkColorType MojoColorTypeToSk(skia::mojom::ColorType type) { |
switch (type) { |
case skia::mojom::ColorType::UNKNOWN: |
@@ -156,9 +164,12 @@ uint64_t StructTraits<skia::mojom::BitmapDataView, SkBitmap>::row_bytes( |
} |
// static |
-BitmapBuffer StructTraits<skia::mojom::BitmapDataView, SkBitmap>::pixel_data( |
- const SkBitmap& b) { |
- return {b.getSize(), b.getSize(), static_cast<uint8_t*>(b.getPixels())}; |
+mojo::ScopedSharedBufferHandle |
+StructTraits<skia::mojom::BitmapDataView, SkBitmap>::pixel_data_buffer_handle( |
+ const SkBitmap& b, |
+ void* context) { |
+ return (*(static_cast<mojo::ScopedSharedBufferHandle*>(context))) |
+ ->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY); |
} |
// static |
@@ -167,51 +178,67 @@ bool StructTraits<skia::mojom::BitmapDataView, SkBitmap>::Read( |
SkBitmap* b) { |
// TODO: Ensure width and height are reasonable, eg. <= kMaxBitmapSize? |
*b = SkBitmap(); |
- if (!b->tryAllocPixels( |
- SkImageInfo::Make(data.width(), data.height(), |
- MojoColorTypeToSk(data.color_type()), |
- MojoAlphaTypeToSk(data.alpha_type()), |
- MojoProfileTypeToSk(data.profile_type())), |
- data.row_bytes())) { |
- return false; |
- } |
+ |
+ const SkImageInfo info = SkImageInfo::Make( |
+ data.width(), data.height(), MojoColorTypeToSk(data.color_type()), |
+ MojoAlphaTypeToSk(data.alpha_type()), |
+ MojoProfileTypeToSk(data.profile_type())); |
// If the image is empty, return success after setting the image info. |
- if (data.width() == 0 || data.height() == 0) |
- return true; |
+ if (data.width() == 0 || data.height() == 0) { |
msw
2017/03/25 00:59:52
nit: curlies not needed
|
+ return b->setInfo(info, data.row_bytes()); |
+ } |
+ |
+ mojo::ScopedSharedBufferHandle pixel_data_buffer_handle = |
+ data.TakePixelDataBufferHandle(); |
+ if (!pixel_data_buffer_handle.is_valid()) |
+ return false; |
+ |
+ const size_t data_byte_size = data.height() * data.row_bytes(); |
+ auto mapping = pixel_data_buffer_handle->Map(data_byte_size); |
+ if (!mapping) |
+ return false; |
+ |
+ 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.
|
+ &ReleaseScopedSharedBufferMapping, |
+ new ScopedSharedBufferMapping(std::move(mapping)))) { |
+ return false; |
+ } |
- SkAutoPixmapUnlock pixmap; |
- mojo::ArrayDataView<uint8_t> data_view; |
- data.GetPixelDataDataView(&data_view); |
if (static_cast<uint32_t>(b->width()) != data.width() || |
static_cast<uint32_t>(b->height()) != data.height() || |
static_cast<uint64_t>(b->rowBytes()) != data.row_bytes() || |
- b->getSize() != data_view.size() || !b->requestLock(&pixmap) || |
- !b->readyToDraw()) { |
+ b->getSize() != data_byte_size) { |
return false; |
} |
- BitmapBuffer bitmap_buffer = {0, b->getSize(), |
- static_cast<uint8_t*>(b->getPixels())}; |
- if (!data.ReadPixelData(&bitmap_buffer) || bitmap_buffer.size != b->getSize()) |
- return false; |
- |
b->notifyPixelsChanged(); |
+ b->setImmutable(); // Pixels are on a read-only shared buffer. |
return true; |
} |
// static |
void* StructTraits<skia::mojom::BitmapDataView, SkBitmap>::SetUpContext( |
const SkBitmap& b) { |
- b.lockPixels(); |
- return nullptr; |
+ // Shared buffer is not a good way for huge images. Consider alternatives. |
+ DCHECK_LT(b.width() * b.height(), 4000 * 4000); |
+ |
+ // Use a context to create a shared buffer for pixels only once. |
+ SkAutoLockPixels lock_pixels(b); |
+ const size_t buffer_size = b.getSize(); |
+ auto* pixel_data_buffer_handle = new mojo::ScopedSharedBufferHandle( |
+ mojo::SharedBufferHandle::Create(buffer_size)); |
+ mojo::ScopedSharedBufferMapping mapping = |
+ (*pixel_data_buffer_handle)->Map(b.getSize()); |
msw
2017/03/25 00:59:52
nit: use |buffer_size|
|
+ 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
|
+ return pixel_data_buffer_handle; |
} |
// static |
void StructTraits<skia::mojom::BitmapDataView, SkBitmap>::TearDownContext( |
const SkBitmap& b, |
void* context) { |
- b.unlockPixels(); |
+ delete static_cast<mojo::ScopedSharedBufferHandle*>(context); |
} |
} // namespace mojo |