Chromium Code Reviews| Index: chrome/browser/ui/app_list/fast_show_pickler.cc |
| diff --git a/chrome/browser/ui/app_list/fast_show_pickler.cc b/chrome/browser/ui/app_list/fast_show_pickler.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0bed9134ed12c93d08f4e1d7d76d8bb732d92636 |
| --- /dev/null |
| +++ b/chrome/browser/ui/app_list/fast_show_pickler.cc |
| @@ -0,0 +1,161 @@ |
| +// Copyright 2013 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 "chrome/browser/ui/app_list/fast_show_pickler.h" |
| + |
| + |
| +namespace { |
| + |
| +using app_list::AppListItemModel; |
| +using app_list::AppListModel; |
| + |
| +gfx::ImageSkia UnpickleImage(PickleIterator* it) { |
| + int rep_count = 0; |
| + if (!it->ReadInt(&rep_count)) |
| + return gfx::ImageSkia(); |
| + |
| + gfx::ImageSkia result; |
| + for (int i = 0; i < rep_count; ++i) { |
| + int scale_factor = 0; |
| + if (!it->ReadInt(&scale_factor)) |
| + return gfx::ImageSkia(); |
| + |
| + int width = 0; |
| + if (!it->ReadInt(&width)) |
| + return gfx::ImageSkia(); |
| + |
| + int height = 0; |
| + if (!it->ReadInt(&height)) |
| + return gfx::ImageSkia(); |
| + |
| + int config = 0; |
| + if (!it->ReadInt(&config)) |
| + return gfx::ImageSkia(); |
| + |
| + int size = 0; |
| + if (!it->ReadInt(&size)) |
| + return gfx::ImageSkia(); |
| + |
| + const char* pixels = NULL; |
| + if (!it->ReadBytes(&pixels, size)) |
|
xiyuan
2013/08/28 17:00:39
Can we ReadBytes into SkBitmap's pixel buffer to s
koz (OOO until 15th September)
2013/08/29 03:19:01
ReadBytes() has the effect of pointing |pixels| in
xiyuan
2013/08/29 16:52:11
You are right. Apparently, I have never used Pickl
|
| + return gfx::ImageSkia(); |
| + |
| + SkBitmap bitmap; |
| + bitmap.setConfig(static_cast<SkBitmap::Config>(config), width, height); |
| + if (!bitmap.allocPixels()) |
| + return gfx::ImageSkia(); |
| + { |
| + SkAutoLockPixels lock(bitmap); |
| + memcpy(bitmap.getPixels(), pixels, bitmap.getSize()); |
| + } |
| + result.AddRepresentation( |
| + gfx::ImageSkiaRep(bitmap, static_cast<ui::ScaleFactor>(scale_factor))); |
| + } |
| + |
| + return result; |
| +} |
| + |
| +scoped_ptr<AppListItemModel> UnpickleAppListItemModel(PickleIterator* it) { |
| + scoped_ptr<AppListItemModel> result(new AppListItemModel); |
| + std::string id; |
| + if (!it->ReadString(&id)) |
| + return scoped_ptr<AppListItemModel>(); |
| + result->set_app_id(id); |
| + std::string title; |
| + if (!it->ReadString(&title)) |
| + return scoped_ptr<AppListItemModel>(); |
| + result->SetTitle(title); |
| + bool has_shadow = false; |
| + if (!it->ReadBool(&has_shadow)) |
| + return scoped_ptr<AppListItemModel>(); |
| + gfx::ImageSkia icon = UnpickleImage(it); |
| + result->SetIcon(icon, has_shadow); |
| + return result.Pass(); |
| +} |
| + |
| +void PickleImage(Pickle* pickle, const gfx::ImageSkia& image) { |
| + std::vector<gfx::ImageSkiaRep> reps(image.image_reps()); |
| + pickle->WriteInt(static_cast<int>(reps.size())); |
| + for (std::vector<gfx::ImageSkiaRep>::const_iterator it = reps.begin(); |
| + it != reps.end(); ++it) { |
| + pickle->WriteInt(static_cast<int>(it->scale_factor())); |
| + pickle->WriteInt(it->pixel_width()); |
| + pickle->WriteInt(it->pixel_height()); |
| + pickle->WriteInt(it->sk_bitmap().getConfig()); |
|
xiyuan
2013/08/28 17:00:39
I might be a paranoid so not feel comfortable use
koz (OOO until 15th September)
2013/08/29 03:19:01
Done.
|
| + int size = static_cast<int>(it->sk_bitmap().getSize()); |
|
xiyuan
2013/08/28 17:00:39
getSafeSize() might be better for the usage here.
koz (OOO until 15th September)
2013/08/29 03:19:01
Done.
|
| + pickle->WriteInt(size); |
| + SkBitmap bitmap = it->sk_bitmap(); |
| + SkAutoLockPixels lock(bitmap); |
| + pickle->WriteBytes(bitmap.getPixels(), size); |
| + } |
| +} |
| + |
| +void PickleAppListItemModel(Pickle* pickle, AppListItemModel* item) { |
| + pickle->WriteString(item->app_id()); |
| + pickle->WriteString(item->title()); |
| + pickle->WriteBool(item->has_shadow()); |
| + PickleImage(pickle, item->icon()); |
| +} |
| + |
| +void CopyOverItem(AppListItemModel* src_item, AppListItemModel* dest_item) { |
| + dest_item->set_app_id(src_item->app_id()); |
| + dest_item->SetTitle(src_item->title()); |
| + dest_item->SetIcon(src_item->icon(), src_item->has_shadow()); |
| +} |
| + |
| +} // namespace |
| + |
| +// The version of the pickle format defined here. This needs to be incremented |
| +// whenever this format is changed so new clients can invalidate old versions. |
| +const int FastShowPickler::kVersion = 1; |
| + |
| +scoped_ptr<Pickle> FastShowPickler::PickleAppListModelForFastShow( |
| + AppListModel* model) { |
| + scoped_ptr<Pickle> result(new Pickle); |
| + if (!result->WriteInt(kVersion)) |
| + return scoped_ptr<Pickle>(); |
| + if (!result->WriteInt((int) model->apps()->item_count())) |
| + return scoped_ptr<Pickle>(); |
| + if (!result->WriteBool(model->signed_in())) |
| + return scoped_ptr<Pickle>(); |
| + for (size_t i = 0; i < model->apps()->item_count(); ++i) |
| + PickleAppListItemModel(result.get(), model->apps()->GetItemAt(i)); |
| + return result.Pass(); |
| +} |
| + |
| +void FastShowPickler::CopyOver(AppListModel* src, AppListModel* dest) { |
| + dest->apps()->DeleteAll(); |
| + for (size_t i = 0; i < src->apps()->item_count(); i++) { |
| + AppListItemModel* src_item = src->apps()->GetItemAt(i); |
| + AppListItemModel* dest_item = new AppListItemModel; |
| + CopyOverItem(src_item, dest_item); |
| + dest->apps()->Add(dest_item); |
| + } |
| +} |
| + |
| +scoped_ptr<AppListModel> |
| +FastShowPickler::UnpickleAppListModelForFastShow(Pickle* pickle) { |
| + PickleIterator it(*pickle); |
| + int read_version = 0; |
| + if (!it.ReadInt(&read_version)) |
| + return scoped_ptr<AppListModel>(); |
| + if (read_version != kVersion) |
| + return scoped_ptr<AppListModel>(); |
| + int app_count = 0; |
| + if (!it.ReadInt(&app_count)) |
| + return scoped_ptr<AppListModel>(); |
| + bool signed_in = false; |
| + if (!it.ReadBool(&signed_in)) |
| + return scoped_ptr<AppListModel>(); |
| + |
| + scoped_ptr<AppListModel> model(new AppListModel); |
| + for (int i = 0; i < app_count; ++i) { |
| + scoped_ptr<AppListItemModel> item(UnpickleAppListItemModel(&it).Pass()); |
| + if (!item) |
| + return scoped_ptr<AppListModel>(); |
| + model->apps()->Add(item.release()); |
| + } |
| + |
| + return model.Pass(); |
| +} |