| // Copyright 2016 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 "ui/gfx/ipc/skia/gfx_skia_param_traits.h" |
| |
| #include <string> |
| |
| #include "base/pickle.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| #include "third_party/skia/include/core/SkImageInfo.h" |
| #include "ui/gfx/transform.h" |
| |
| namespace { |
| |
| struct SkBitmap_Data { |
| // The color type for the bitmap (bits per pixel, etc). |
| SkColorType color_type; |
| |
| // The alpha type for the bitmap (opaque, premul, unpremul). |
| SkAlphaType alpha_type; |
| |
| // The width of the bitmap in pixels. |
| uint32_t width; |
| |
| // The height of the bitmap in pixels. |
| uint32_t height; |
| |
| void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) { |
| const SkImageInfo& info = bitmap.info(); |
| color_type = info.colorType(); |
| alpha_type = info.alphaType(); |
| width = info.width(); |
| height = info.height(); |
| } |
| |
| // Returns whether |bitmap| successfully initialized. |
| bool InitSkBitmapFromData(SkBitmap* bitmap, |
| const char* pixels, |
| size_t pixels_size) const { |
| if (!bitmap->tryAllocPixels( |
| SkImageInfo::Make(width, height, color_type, alpha_type))) |
| return false; |
| if (pixels_size != bitmap->getSize()) |
| return false; |
| memcpy(bitmap->getPixels(), pixels, pixels_size); |
| return true; |
| } |
| }; |
| |
| } // namespace |
| |
| namespace IPC { |
| |
| void ParamTraits<SkBitmap>::GetSize(base::PickleSizer* s, const param_type& p) { |
| s->AddData(sizeof(SkBitmap_Data)); |
| s->AddData(static_cast<int>(p.getSize())); |
| } |
| |
| void ParamTraits<SkBitmap>::Write(base::Pickle* m, const SkBitmap& p) { |
| size_t fixed_size = sizeof(SkBitmap_Data); |
| SkBitmap_Data bmp_data; |
| bmp_data.InitSkBitmapDataForTransfer(p); |
| m->WriteData(reinterpret_cast<const char*>(&bmp_data), |
| static_cast<int>(fixed_size)); |
| size_t pixel_size = p.getSize(); |
| SkAutoLockPixels p_lock(p); |
| m->WriteData(reinterpret_cast<const char*>(p.getPixels()), |
| static_cast<int>(pixel_size)); |
| } |
| |
| bool ParamTraits<SkBitmap>::Read(const base::Pickle* m, |
| base::PickleIterator* iter, |
| SkBitmap* r) { |
| const char* fixed_data; |
| int fixed_data_size = 0; |
| if (!iter->ReadData(&fixed_data, &fixed_data_size) || |
| (fixed_data_size <= 0)) { |
| return false; |
| } |
| if (fixed_data_size != sizeof(SkBitmap_Data)) |
| return false; // Message is malformed. |
| |
| const char* variable_data; |
| int variable_data_size = 0; |
| if (!iter->ReadData(&variable_data, &variable_data_size) || |
| (variable_data_size < 0)) { |
| return false; |
| } |
| const SkBitmap_Data* bmp_data = |
| reinterpret_cast<const SkBitmap_Data*>(fixed_data); |
| return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size); |
| } |
| |
| void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) { |
| l->append("<SkBitmap>"); |
| } |
| |
| void ParamTraits<gfx::Transform>::GetSize(base::PickleSizer* s, |
| const param_type& p) { |
| s->AddBytes(sizeof(SkMScalar) * 16); |
| } |
| |
| void ParamTraits<gfx::Transform>::Write(base::Pickle* m, const param_type& p) { |
| #ifdef SK_MSCALAR_IS_FLOAT |
| float column_major_data[16]; |
| p.matrix().asColMajorf(column_major_data); |
| #else |
| double column_major_data[16]; |
| p.matrix().asColMajord(column_major_data); |
| #endif |
| // We do this in a single write for performance reasons. |
| m->WriteBytes(&column_major_data, sizeof(SkMScalar) * 16); |
| } |
| |
| bool ParamTraits<gfx::Transform>::Read(const base::Pickle* m, |
| base::PickleIterator* iter, |
| param_type* r) { |
| const char* column_major_data; |
| if (!iter->ReadBytes(&column_major_data, sizeof(SkMScalar) * 16)) |
| return false; |
| r->matrix().setColMajor( |
| reinterpret_cast<const SkMScalar*>(column_major_data)); |
| return true; |
| } |
| |
| void ParamTraits<gfx::Transform>::Log( |
| const param_type& p, std::string* l) { |
| #ifdef SK_MSCALAR_IS_FLOAT |
| float row_major_data[16]; |
| p.matrix().asRowMajorf(row_major_data); |
| #else |
| double row_major_data[16]; |
| p.matrix().asRowMajord(row_major_data); |
| #endif |
| l->append("("); |
| for (int i = 0; i < 16; ++i) { |
| if (i > 0) |
| l->append(", "); |
| LogParam(row_major_data[i], l); |
| } |
| l->append(") "); |
| } |
| |
| } // namespace IPC |