Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: chrome/browser/themes/browser_theme_pack.cc

Issue 10783015: Add ability to store hidpi theme images in data pack (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/themes/browser_theme_pack.h ('k') | chrome/browser/themes/browser_theme_pack_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/themes/browser_theme_pack.cc
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index cb7aba49a21e199e9fd0022c8283dcee01e47e03..41c69fcc3ca225b9e8e6516295f4a84dedcef097 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -24,9 +24,11 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/skbitmap_operations.h"
+#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/gfx/screen.h"
using content::BrowserThread;
using extensions::Extension;
@@ -49,6 +51,7 @@ const int kTintsID = kMaxID - 2;
const int kColorsID = kMaxID - 3;
const int kDisplayPropertiesID = kMaxID - 4;
const int kSourceImagesID = kMaxID - 5;
+const int kScaleFactorsID = kMaxID - 6;
// Static size of the tint/color/display property arrays that are mmapped.
const int kTintArraySize = 6;
@@ -157,9 +160,10 @@ PersistingImagesTable kPersistingImages[] = {
{ 44, IDR_THROBBER_WAITING, NULL },
{ 45, IDR_THROBBER_LIGHT, NULL },
};
+size_t kPersistingImagesLength = arraysize(kPersistingImages);
int GetPersistentIDByName(const std::string& key) {
- for (size_t i = 0; i < arraysize(kPersistingImages); ++i) {
+ for (size_t i = 0; i < kPersistingImagesLength; ++i) {
if (kPersistingImages[i].key != NULL &&
base::strcasecmp(key.c_str(), kPersistingImages[i].key) == 0) {
return kPersistingImages[i].persistent_id;
@@ -170,13 +174,47 @@ int GetPersistentIDByName(const std::string& key) {
}
int GetPersistentIDByIDR(int idr) {
- for (size_t i = 0; i < arraysize(kPersistingImages); ++i) {
- if (kPersistingImages[i].idr_id == idr) {
- return kPersistingImages[i].persistent_id;
+ static std::map<int,int>* lookup_table = new std::map<int,int>();
+ if (lookup_table->empty()) {
+ for (size_t i = 0; i < kPersistingImagesLength; ++i) {
+ int idr = kPersistingImages[i].idr_id;
+ int prs_id = kPersistingImages[i].persistent_id;
+ (*lookup_table)[idr] = prs_id;
}
}
+ std::map<int,int>::iterator it = lookup_table->find(idr);
+ return (it == lookup_table->end()) ? -1 : it->second;
+}
- return -1;
+// Returns true if the scales in |input| match those in |expected|.
+// The order must match as the index is used in determining the raw id.
+bool InputScalesValid(const char* input,
+ const std::vector<ui::ScaleFactor>& expected) {
+ const float* scales = reinterpret_cast<const float*>(input);
+ size_t index = 0;
+ for (const float* end = scales; *end != -1.0f; ++end) {
+ if (index >= expected.size())
+ return false;
+ if (*end != ui::GetScaleFactorScale(expected[index]))
+ return false;
+ index++;
+ }
+ return (index == expected.size());
+}
+
+// Returns |scale_factors| as a string to be written to disk.
+base::StringPiece GetScaleFactorsAsString(
+ const std::vector<ui::ScaleFactor>& scale_factors) {
+ size_t scales_size = scale_factors.size() + 1;
+ float* scales = new float[scales_size];
+ for (size_t i = 0; i < scale_factors.size(); ++i)
+ scales[i] = ui::GetScaleFactorScale(scale_factors[i]);
+ scales[scales_size - 1] = -1.0f;
+ base::StringPiece out_string = base::StringPiece(
+ reinterpret_cast<const char*>(&scales),
+ scales_size * sizeof(float));
+ delete[] scales;
+ return out_string;
}
struct StringToIntTable {
@@ -308,23 +346,55 @@ base::RefCountedMemory* ReadFileData(const FilePath& path) {
return NULL;
}
-// Shifts a bitmap's HSL values. The caller is responsible for deleting
+// Shifts an image's HSL values. The caller is responsible for deleting
// the returned image.
gfx::Image* CreateHSLShiftedImage(const gfx::Image& image,
const color_utils::HSL& hsl_shift) {
const gfx::ImageSkia* src_image = image.ToImageSkia();
- std::vector<gfx::ImageSkiaRep> src_image_reps = src_image->image_reps();
- gfx::ImageSkia dst_image;
- for (size_t i = 0; i < src_image_reps.size(); ++i) {
- const gfx::ImageSkiaRep& image_rep = src_image_reps[i];
- SkBitmap dst_bitmap = SkBitmapOperations::CreateHSLShiftedBitmap(
- image_rep.sk_bitmap(), hsl_shift);
- dst_image.AddRepresentation(gfx::ImageSkiaRep(dst_bitmap,
- image_rep.scale_factor()));
- }
- return new gfx::Image(dst_image);
+ return new gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage(
+ *src_image, hsl_shift));
}
+class TabBackgroundImageSource: public gfx::CanvasImageSource {
+ public:
+ TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint,
+ const gfx::ImageSkia& overlay,
+ const color_utils::HSL& hsl_shift,
+ int vertical_offset)
+ : gfx::CanvasImageSource(image_to_tint.size(), false),
+ image_to_tint_(image_to_tint),
+ overlay_(overlay),
+ hsl_shift_(hsl_shift),
+ vertical_offset_(vertical_offset) {
+ }
+
+ virtual ~TabBackgroundImageSource() {
+ }
+
+ // Overridden from CanvasImageSource:
+ virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
+ gfx::ImageSkia bg_tint =
+ gfx::ImageSkiaOperations::CreateHSLShiftedImage(image_to_tint_,
+ hsl_shift_);
+ canvas->TileImageInt(bg_tint, 0, vertical_offset_, 0, 0,
+ size().width(), size().height());
+
+ // If they've provided a custom image, overlay it.
+ if (!overlay_.isNull()) {
+ canvas->TileImageInt(overlay_, 0, 0, size().width(),
+ overlay_.height());
+ }
+ }
+
+ private:
+ const gfx::ImageSkia image_to_tint_;
+ const gfx::ImageSkia overlay_;
+ const color_utils::HSL hsl_shift_;
+ const int vertical_offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabBackgroundImageSource);
+};
+
} // namespace
BrowserThemePack::~BrowserThemePack() {
@@ -336,8 +406,8 @@ BrowserThemePack::~BrowserThemePack() {
delete [] source_images_;
}
- STLDeleteValues(&prepared_images_);
- STLDeleteValues(&loaded_images_);
+ STLDeleteValues(&images_on_ui_thread_);
+ STLDeleteValues(&images_on_file_thread_);
}
// static
@@ -360,16 +430,19 @@ scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension(
&file_paths);
pack->BuildSourceImagesArray(file_paths);
- if (!pack->LoadRawBitmapsTo(file_paths, &pack->prepared_images_))
+ if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_))
return NULL;
- pack->GenerateFrameImages(&pack->prepared_images_);
+ pack->CopyImagesTo(pack->images_on_ui_thread_, &pack->images_on_file_thread_);
- pack->GenerateTintedButtons(
- pack->GetTintInternal(ThemeService::TINT_BUTTONS),
- &pack->prepared_images_);
+ pack->CreateImages(&pack->images_on_ui_thread_);
+ pack->CreateImages(&pack->images_on_file_thread_);
- pack->GenerateTabBackgroundImages(&pack->prepared_images_);
+ // For M22, as it is not possible to easily determine which scale factors are
+ // in use, assume that the 1x scale factor is in use.
+ std::vector<ui::ScaleFactor> scale_factors_in_use;
+ scale_factors_in_use.push_back(ui::SCALE_FACTOR_100P);
+ pack->GenerateImageReps(scale_factors_in_use);
// The BrowserThemePack is now in a consistent state.
return pack;
@@ -383,8 +456,10 @@ scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack(
// (see http://crbug.com/80206)
base::ThreadRestrictions::ScopedAllowIO allow_io;
scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
+ // Scale factor parameter is moot as data pack has image resources for all
+ // supported scale factors.
pack->data_pack_.reset(
- new ui::DataPack(ui::SCALE_FACTOR_100P));
+ new ui::DataPack(ui::SCALE_FACTOR_NONE));
if (!pack->data_pack_->LoadFromPath(path)) {
LOG(ERROR) << "Failed to load theme data pack.";
@@ -430,6 +505,15 @@ scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack(
pack->source_images_ = reinterpret_cast<int*>(
const_cast<char*>(pointer.data()));
+ if (!pack->data_pack_->GetStringPiece(kScaleFactorsID, &pointer))
+ return NULL;
+
+ if (!InputScalesValid(const_cast<char*>(pointer.data()),
+ pack->scale_factors_)) {
+ DLOG(ERROR) << "BuildFromDataPack failure! The pack scale factors differ "
+ << "from those supported by platform.";
+ }
+
return pack;
}
@@ -456,10 +540,12 @@ bool BrowserThemePack::WriteToDisk(const FilePath& path) const {
reinterpret_cast<const char*>(source_images_),
source_count * sizeof(*source_images_));
+ resources[kScaleFactorsID] = GetScaleFactorsAsString(scale_factors_);
+
AddRawImagesTo(image_memory_, &resources);
RawImages reencoded_images;
- RepackImages(prepared_images_, &reencoded_images);
+ RepackImages(images_on_file_thread_, &reencoded_images);
AddRawImagesTo(reencoded_images, &resources);
return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY);
@@ -522,54 +608,53 @@ const gfx::Image* BrowserThemePack::GetImageNamed(int idr_id) const {
if (prs_id == -1)
return NULL;
- // Check our cache of prepared images, first.
- ImageCache::const_iterator image_iter = prepared_images_.find(prs_id);
- if (image_iter != prepared_images_.end())
+ // Check if the image is cached.
+ ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
+ if (image_iter != images_on_ui_thread_.end())
return image_iter->second;
- // Check if we've already loaded this image.
- image_iter = loaded_images_.find(prs_id);
- if (image_iter != loaded_images_.end())
- return image_iter->second;
+ // TODO(pkotwicz): Do something better than loading the bitmaps
+ // for all the scale factors associated with |idr_id|.
+ gfx::ImageSkia image_skia;
+ for (size_t i = 0; i < scale_factors_.size(); ++i) {
+ scoped_refptr<base::RefCountedMemory> memory =
+ GetRawData(idr_id, scale_factors_[i]);
- scoped_refptr<base::RefCountedMemory> memory;
- if (data_pack_.get()) {
- memory = data_pack_->GetStaticMemory(prs_id);
- } else {
- RawImages::const_iterator it = image_memory_.find(prs_id);
- if (it != image_memory_.end()) {
- memory = it->second;
+ if (memory.get()) {
+ // Decode the PNG.
+ SkBitmap bitmap;
+ if (!gfx::PNGCodec::Decode(memory->front(), memory->size(),
+ &bitmap)) {
+ NOTREACHED() << "Unable to decode theme image resource " << idr_id
+ << " from saved DataPack.";
+ return NULL;
+ }
+ image_skia.AddRepresentation(
+ gfx::ImageSkiaRep(bitmap, scale_factors_[i]));
}
}
- if (memory.get()) {
- // Decode the PNG.
- SkBitmap bitmap;
- if (!gfx::PNGCodec::Decode(memory->front(), memory->size(),
- &bitmap)) {
- NOTREACHED() << "Unable to decode theme image resource " << idr_id
- << " from saved DataPack.";
- return NULL;
- }
-
- gfx::Image* ret = new gfx::Image(bitmap);
- loaded_images_[prs_id] = ret;
-
+ if (!image_skia.isNull()) {
+ gfx::Image* ret = new gfx::Image(image_skia);
+ images_on_ui_thread_[prs_id] = ret;
return ret;
}
return NULL;
}
-base::RefCountedMemory* BrowserThemePack::GetRawData(int idr_id) const {
+base::RefCountedMemory* BrowserThemePack::GetRawData(
+ int idr_id,
+ ui::ScaleFactor scale_factor) const {
base::RefCountedMemory* memory = NULL;
int prs_id = GetPersistentIDByIDR(idr_id);
+ int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
- if (prs_id != -1) {
+ if (raw_id != -1) {
if (data_pack_.get()) {
- memory = data_pack_->GetStaticMemory(prs_id);
+ memory = data_pack_->GetStaticMemory(raw_id);
} else {
- RawImages::const_iterator it = image_memory_.find(prs_id);
+ RawImages::const_iterator it = image_memory_.find(raw_id);
if (it != image_memory_.end()) {
memory = it->second;
}
@@ -601,6 +686,11 @@ BrowserThemePack::BrowserThemePack()
colors_(NULL),
display_properties_(NULL),
source_images_(NULL) {
+#if defined(OS_MACOSX)
+ scale_factors_ = ui::GetSupportedScaleFactors();
+#else
+ scale_factors_.push_back(ui::SCALE_FACTOR_100P);
+#endif
}
void BrowserThemePack::BuildHeader(const Extension* extension) {
@@ -867,7 +957,7 @@ void BrowserThemePack::BuildSourceImagesArray(const FilePathMap& file_paths) {
bool BrowserThemePack::LoadRawBitmapsTo(
const FilePathMap& file_paths,
- ImageCache* raw_bitmaps) {
+ ImageCache* image_cache) {
// Themes should be loaded on the file thread, not the UI thread.
// http://crbug.com/61838
base::ThreadRestrictions::ScopedAllowIO allow_io;
@@ -880,26 +970,27 @@ bool BrowserThemePack::LoadRawBitmapsTo(
return false;
}
- int id = it->first;
+ int prs_id = it->first;
// Some images need to go directly into |image_memory_|. No modification is
// necessary or desirable.
bool is_copyable = false;
for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) {
- if (kPreloadIDs[i] == id) {
+ if (kPreloadIDs[i] == prs_id) {
is_copyable = true;
break;
}
}
if (is_copyable) {
- image_memory_[id] = raw_data;
+ int raw_id = GetRawIDByPersistentID(prs_id, ui::SCALE_FACTOR_100P);
+ image_memory_[raw_id] = raw_data;
} else if (raw_data.get() && raw_data->size()) {
// Decode the PNG.
SkBitmap bitmap;
if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(),
&bitmap)) {
- (*raw_bitmaps)[it->first] = new gfx::Image(bitmap);
+ (*image_cache)[prs_id] = new gfx::Image(bitmap);
} else {
NOTREACHED() << "Unable to decode theme image resource " << it->first;
}
@@ -909,11 +1000,17 @@ bool BrowserThemePack::LoadRawBitmapsTo(
return true;
}
-void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const {
+void BrowserThemePack::CreateImages(ImageCache* images) const {
+ CreateFrameImages(images);
+ CreateTintedButtons(GetTintInternal(ThemeService::TINT_BUTTONS), images);
+ CreateTabBackgroundImages(images);
+}
+
+void BrowserThemePack::CreateFrameImages(ImageCache* images) const {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- // Create all the output bitmaps in a separate cache and move them back into
- // the input bitmaps because there can be name collisions.
+ // Create all the output images in a separate cache and move them back into
+ // the input images because there can be name collisions.
ImageCache temp_output;
for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) {
@@ -925,25 +1022,25 @@ void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const {
int prs_base_id;
if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) {
- prs_base_id = bitmaps->count(PRS_THEME_FRAME_INCOGNITO) ?
+ prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ?
PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME;
} else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) {
prs_base_id = PRS_THEME_FRAME_OVERLAY;
} else if (prs_id == PRS_THEME_FRAME_INACTIVE) {
prs_base_id = PRS_THEME_FRAME;
} else if (prs_id == PRS_THEME_FRAME_INCOGNITO &&
- !bitmaps->count(PRS_THEME_FRAME_INCOGNITO)) {
+ !images->count(PRS_THEME_FRAME_INCOGNITO)) {
prs_base_id = PRS_THEME_FRAME;
} else {
prs_base_id = prs_id;
}
- if (bitmaps->count(prs_id)) {
- frame = (*bitmaps)[prs_id];
- } else if (prs_base_id != prs_id && bitmaps->count(prs_base_id)) {
- frame = (*bitmaps)[prs_base_id];
+ if (images->count(prs_id)) {
+ frame = (*images)[prs_id];
+ } else if (prs_base_id != prs_id && images->count(prs_base_id)) {
+ frame = (*images)[prs_base_id];
} else if (prs_base_id == PRS_THEME_FRAME_OVERLAY &&
- bitmaps->count(PRS_THEME_FRAME)) {
+ images->count(PRS_THEME_FRAME)) {
// If there is no theme overlay, don't tint the default frame,
// because it will overwrite the custom frame image when we cache and
// reload from disk.
@@ -959,13 +1056,12 @@ void BrowserThemePack::GenerateFrameImages(ImageCache* bitmaps) const {
*frame, GetTintInternal(kFrameTintMap[i].value));
}
}
-
- MergeImageCaches(temp_output, bitmaps);
+ MergeImageCaches(temp_output, images);
}
-void BrowserThemePack::GenerateTintedButtons(
+void BrowserThemePack::CreateTintedButtons(
const color_utils::HSL& button_tint,
- ImageCache* processed_bitmaps) const {
+ ImageCache* processed_images) const {
if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
const std::set<int>& idr_ids =
@@ -979,13 +1075,13 @@ void BrowserThemePack::GenerateTintedButtons(
gfx::Image& button = rb.GetImageNamed(*it);
// but save a version with the persistent ID.
- (*processed_bitmaps)[prs_id] =
+ (*processed_images)[prs_id] =
CreateHSLShiftedImage(button, button_tint);
}
}
}
-void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const {
+void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const {
ImageCache temp_output;
for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) {
int prs_id = kTabBackgroundMap[i].key;
@@ -993,57 +1089,91 @@ void BrowserThemePack::GenerateTabBackgroundImages(ImageCache* bitmaps) const {
// We only need to generate the background tab images if we were provided
// with a PRS_THEME_FRAME.
- ImageCache::const_iterator it = bitmaps->find(prs_base_id);
- if (it != bitmaps->end()) {
+ ImageCache::const_iterator it = images->find(prs_base_id);
+ if (it != images->end()) {
const gfx::ImageSkia* image_to_tint = (it->second)->ToImageSkia();
- const std::vector<gfx::ImageSkiaRep> image_reps_to_tint =
- image_to_tint->image_reps();
- gfx::ImageSkia tinted_image;
- for (size_t j = 0; j < image_reps_to_tint.size(); ++j) {
- gfx::ImageSkiaRep image_rep_to_tint = image_reps_to_tint[j];
- SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap(
- image_rep_to_tint.sk_bitmap(), GetTintInternal(
- ThemeService::TINT_BACKGROUND_TAB));
- gfx::Size bg_tint_dip_size(image_rep_to_tint.GetWidth(),
- image_rep_to_tint.GetHeight());
- int vertical_offset = bitmaps->count(prs_id)
- ? kRestoredTabVerticalOffset : 0;
- gfx::Canvas canvas(gfx::Size(bg_tint.width(), bg_tint.height()),
- image_rep_to_tint.scale_factor(),
- false);
- canvas.TileImageInt(bg_tint, 0, vertical_offset, 0, 0,
- bg_tint_dip_size.width(), bg_tint_dip_size.height());
-
- // If they've provided a custom image, overlay it.
- ImageCache::const_iterator overlay_it = bitmaps->find(prs_id);
- if (overlay_it != bitmaps->end()) {
- const gfx::ImageSkia* overlay = overlay_it->second->ToImageSkia();
- canvas.TileImageInt(*overlay, 0, 0, bg_tint_dip_size.width(),
- overlay->height());
- }
- tinted_image.AddRepresentation(canvas.ExtractImageRep());
- }
-
- temp_output[prs_id] = new gfx::Image(tinted_image);
+ color_utils::HSL hsl_shift = GetTintInternal(
+ ThemeService::TINT_BACKGROUND_TAB);
+ int vertical_offset = images->count(prs_id)
+ ? kRestoredTabVerticalOffset : 0;
+
+ gfx::ImageSkia overlay;
+ ImageCache::const_iterator overlay_it = images->find(prs_id);
+ if (overlay_it != images->end())
+ overlay = *overlay_it->second->ToImageSkia();
+
+ gfx::ImageSkiaSource* source = new TabBackgroundImageSource(
+ *image_to_tint, overlay, hsl_shift, vertical_offset);
+ // ImageSkia takes ownership of |source|.
+ temp_output[prs_id] = new gfx::Image(gfx::ImageSkia(source,
+ image_to_tint->size()));
}
}
-
- MergeImageCaches(temp_output, bitmaps);
+ MergeImageCaches(temp_output, images);
}
void BrowserThemePack::RepackImages(const ImageCache& images,
RawImages* reencoded_images) const {
+
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ typedef std::vector<ui::ScaleFactor> ScaleFactors;
for (ImageCache::const_iterator it = images.begin();
it != images.end(); ++it) {
- std::vector<unsigned char> image_data;
- if (!gfx::PNGCodec::EncodeBGRASkBitmap(*it->second->ToSkBitmap(), false,
- &image_data)) {
- NOTREACHED() << "Image file for resource " << it->first
- << " could not be encoded.";
- } else {
- (*reencoded_images)[it->first] =
- base::RefCountedBytes::TakeVector(&image_data);
+ gfx::ImageSkia image_skia = *it->second->ToImageSkia();
+
+ // Attempt to generate image reps for all supported scale factors.
+ for (ScaleFactors::const_iterator factor_it = scale_factors_.begin();
+ factor_it != scale_factors_.end(); ++factor_it) {
+ // Ask for representation to force the representation to be generated
+ // if it wasn't already.
+ image_skia.GetRepresentation(*factor_it);
+ }
+
+ typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps;
+ ImageSkiaReps image_reps = image_skia.image_reps();
+ if (image_reps.empty()) {
+ NOTREACHED() << "No image reps for resource " << it->first << ".";
+ }
+ for (ImageSkiaReps::iterator rep_it = image_reps.begin();
+ rep_it != image_reps.end(); ++rep_it) {
+ std::vector<unsigned char> bitmap_data;
+ if (!gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false,
+ &bitmap_data)) {
+ NOTREACHED() << "Image file for resource " << it->first
+ << " could not be encoded.";
+ }
+ int raw_id = GetRawIDByPersistentID(it->first, rep_it->scale_factor());
+ (*reencoded_images)[raw_id] =
+ base::RefCountedBytes::TakeVector(&bitmap_data);
+ }
+ }
+}
+
+void BrowserThemePack::GenerateImageReps(
+ const std::vector<ui::ScaleFactor>& scale_factors) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ for (ImageCache::const_iterator it = images_on_ui_thread_.begin();
+ it != images_on_ui_thread_.end();
+ ++it) {
+ const gfx::ImageSkia* image1 = it->second->ToImageSkia();
+ const gfx::ImageSkia* image2 =
+ images_on_file_thread_[it->first]->ToImageSkia();
+
+ // Ensure that image reps are generated and cached in |image1| by
+ // calling GetRepresentation().
+ for (size_t i = 0; i < scale_factors.size(); ++i)
+ image1->GetRepresentation(scale_factors[i]);
+
+ // |image1| and |image2| have ImageSkiaSources which produce pixel
+ // equivalent output. Instead of regenerating again, copy the image reps
+ // which were generated for |image1| into |image2|.
+ // Don't do a deep copy of the SkBitmaps as SkBitmap is thread safe.
+ std::vector<gfx::ImageSkiaRep> image1_reps = image1->image_reps();
+ for (size_t i = 0; i < image1_reps.size(); ++i) {
+ gfx::ImageSkiaRep image1_rep = image1_reps[i];
+ const_cast<gfx::ImageSkia*>(image2)->AddRepresentation(gfx::ImageSkiaRep(
+ image1_rep.sk_bitmap(), image1_rep.scale_factor()));
}
}
}
@@ -1052,14 +1182,22 @@ void BrowserThemePack::MergeImageCaches(
const ImageCache& source, ImageCache* destination) const {
for (ImageCache::const_iterator it = source.begin(); it != source.end();
++it) {
- ImageCache::const_iterator bitmap_it = destination->find(it->first);
- if (bitmap_it != destination->end())
- delete bitmap_it->second;
+ ImageCache::const_iterator image_it = destination->find(it->first);
+ if (image_it != destination->end())
+ delete image_it->second;
(*destination)[it->first] = it->second;
}
}
+void BrowserThemePack::CopyImagesTo(const ImageCache& source,
+ ImageCache* destination) const {
+ for (ImageCache::const_iterator it = source.begin(); it != source.end();
+ ++it) {
+ (*destination)[it->first] = new gfx::Image(*it->second);
+ }
+}
+
void BrowserThemePack::AddRawImagesTo(const RawImages& images,
RawDataForWriting* out) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
@@ -1085,3 +1223,16 @@ color_utils::HSL BrowserThemePack::GetTintInternal(int id) const {
return ThemeService::GetDefaultTint(id);
}
+
+int BrowserThemePack::GetRawIDByPersistentID(
+ int prs_id,
+ ui::ScaleFactor scale_factor) const {
+ if (prs_id < 0)
+ return -1;
+
+ for (size_t i = 0; i < scale_factors_.size(); ++i) {
+ if (scale_factors_[i] == scale_factor)
+ return static_cast<int>(kPersistingImagesLength * i) + prs_id;
+ }
+ return -1;
+}
« no previous file with comments | « chrome/browser/themes/browser_theme_pack.h ('k') | chrome/browser/themes/browser_theme_pack_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698