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

Side by Side Diff: chrome/browser/themes/browser_theme_pack.cc

Issue 1869693002: Theme suppliers: Avoid all Image copying. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/themes/browser_theme_pack.h" 5 #include "chrome/browser/themes/browser_theme_pack.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <limits> 10 #include <limits>
11 #include <memory> 11 #include <memory>
12 #include <utility>
12 13
13 #include "base/files/file.h" 14 #include "base/files/file.h"
14 #include "base/macros.h" 15 #include "base/macros.h"
15 #include "base/memory/ref_counted_memory.h" 16 #include "base/memory/ref_counted_memory.h"
16 #include "base/stl_util.h" 17 #include "base/stl_util.h"
17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/sequenced_worker_pool.h" 21 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/threading/thread_restrictions.h" 22 #include "base/threading/thread_restrictions.h"
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 extensions::ThemeInfo::GetDisplayProperties(extension)); 614 extensions::ThemeInfo::GetDisplayProperties(extension));
614 615
615 // Builds the images. (Image building is dependent on tints). 616 // Builds the images. (Image building is dependent on tints).
616 FilePathMap file_paths; 617 FilePathMap file_paths;
617 pack->ParseImageNamesFromJSON( 618 pack->ParseImageNamesFromJSON(
618 extensions::ThemeInfo::GetImages(extension), 619 extensions::ThemeInfo::GetImages(extension),
619 extension->path(), 620 extension->path(),
620 &file_paths); 621 &file_paths);
621 pack->BuildSourceImagesArray(file_paths); 622 pack->BuildSourceImagesArray(file_paths);
622 623
623 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_)) 624 // Create images for use on the FILE thread (which is where these Image
625 // objects will live).
626 if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_file_thread_))
624 return NULL; 627 return NULL;
625 628
626 pack->CreateImages(&pack->images_on_ui_thread_); 629 pack->CreateImages(&pack->images_on_file_thread_);
627 630
628 // Make sure the |images_on_file_thread_| has bitmaps for supported 631 // Make sure the |images_on_file_thread_| has bitmaps for supported
629 // scale factors before passing to FILE thread. 632 // scale factors before passing to FILE thread.
630 pack->images_on_file_thread_ = pack->images_on_ui_thread_; 633 for (auto& item : pack->images_on_file_thread_) {
631 for (ImageCache::iterator it = pack->images_on_file_thread_.begin();
632 it != pack->images_on_file_thread_.end(); ++it) {
633 gfx::ImageSkia* image_skia = 634 gfx::ImageSkia* image_skia =
634 const_cast<gfx::ImageSkia*>(it->second.ToImageSkia()); 635 const_cast<gfx::ImageSkia*>(item.second.ToImageSkia());
635 image_skia->MakeThreadSafe(); 636 image_skia->MakeThreadSafe();
636 } 637 }
637 638
639 // Copy the images over for use on the UI thread. To avoid sharing
640 // thread-unsafe Image objects across threads, new Image objects are created.
641 //
638 // Set ThemeImageSource on |images_on_ui_thread_| to resample the source 642 // Set ThemeImageSource on |images_on_ui_thread_| to resample the source
639 // image if a caller of BrowserThemePack::GetImageNamed() requests an 643 // image if a caller of BrowserThemePack::GetImageNamed() requests an
640 // ImageSkiaRep for a scale factor not specified by the theme author. 644 // ImageSkiaRep for a scale factor not specified by the theme author.
641 // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve 645 // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve
642 // ImageSkiaReps for all supported scale factors. 646 // ImageSkiaReps for all supported scale factors.
643 for (ImageCache::iterator it = pack->images_on_ui_thread_.begin(); 647 for (auto& item : pack->images_on_file_thread_) {
644 it != pack->images_on_ui_thread_.end(); ++it) { 648 const gfx::ImageSkia source_image_skia = item.second.AsImageSkia();
645 const gfx::ImageSkia source_image_skia = it->second.AsImageSkia();
646 ThemeImageSource* source = new ThemeImageSource(source_image_skia); 649 ThemeImageSource* source = new ThemeImageSource(source_image_skia);
647 // image_skia takes ownership of source. 650 // image_skia takes ownership of source.
648 gfx::ImageSkia image_skia(source, source_image_skia.size()); 651 gfx::ImageSkia image_skia(source, source_image_skia.size());
649 it->second = gfx::Image(image_skia); 652 pack->images_on_ui_thread_.insert(
653 std::make_pair(item.first, gfx::Image(image_skia)));
650 } 654 }
651 655
652 // Generate raw images (for new-tab-page attribution and background) for 656 // Generate raw images (for new-tab-page attribution and background) for
653 // any missing scale from an available scale image. 657 // any missing scale from an available scale image.
654 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) { 658 for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) {
655 pack->GenerateRawImageForAllSupportedScales(kPreloadIDs[i]); 659 pack->GenerateRawImageForAllSupportedScales(kPreloadIDs[i]);
656 } 660 }
657 661
658 // The BrowserThemePack is now in a consistent state. 662 // The BrowserThemePack is now in a consistent state.
659 return pack; 663 return pack;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 if (display_properties_[i].id == id) { 811 if (display_properties_[i].id == id) {
808 *result = display_properties_[i].property; 812 *result = display_properties_[i].property;
809 return true; 813 return true;
810 } 814 }
811 } 815 }
812 } 816 }
813 817
814 return false; 818 return false;
815 } 819 }
816 820
817 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { 821 const gfx::Image& BrowserThemePack::GetImageNamed(int idr_id) {
818 int prs_id = GetPersistentIDByIDR(idr_id); 822 int prs_id = GetPersistentIDByIDR(idr_id);
819 if (prs_id == -1) 823 if (prs_id == -1)
820 return gfx::Image(); 824 return empty_image();
821 825
822 // Check if the image is cached. 826 // Check if the image is cached.
823 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); 827 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
824 if (image_iter != images_on_ui_thread_.end()) 828 if (image_iter != images_on_ui_thread_.end())
825 return image_iter->second; 829 return image_iter->second;
826 830
827 ThemeImagePngSource::PngMap png_map; 831 ThemeImagePngSource::PngMap png_map;
828 for (size_t i = 0; i < scale_factors_.size(); ++i) { 832 for (size_t i = 0; i < scale_factors_.size(); ++i) {
829 scoped_refptr<base::RefCountedMemory> memory = 833 scoped_refptr<base::RefCountedMemory> memory =
830 GetRawData(idr_id, scale_factors_[i]); 834 GetRawData(idr_id, scale_factors_[i]);
831 if (memory.get()) 835 if (memory.get())
832 png_map[scale_factors_[i]] = memory; 836 png_map[scale_factors_[i]] = memory;
833 } 837 }
834 if (!png_map.empty()) { 838 if (!png_map.empty()) {
835 gfx::ImageSkia image_skia(new ThemeImagePngSource(png_map), 1.0f); 839 gfx::ImageSkia image_skia(new ThemeImagePngSource(png_map), 1.0f);
836 // |image_skia| takes ownership of ThemeImagePngSource. 840 // |image_skia| takes ownership of ThemeImagePngSource.
837 gfx::Image ret = gfx::Image(image_skia); 841 auto result = images_on_ui_thread_.insert(
838 images_on_ui_thread_[prs_id] = ret; 842 std::make_pair(prs_id, gfx::Image(image_skia)));
839 return ret; 843 return result.first->second;
840 } 844 }
841 845
842 return gfx::Image(); 846 return empty_image();
843 } 847 }
844 848
845 base::RefCountedMemory* BrowserThemePack::GetRawData( 849 base::RefCountedMemory* BrowserThemePack::GetRawData(
846 int idr_id, 850 int idr_id,
847 ui::ScaleFactor scale_factor) const { 851 ui::ScaleFactor scale_factor) const {
848 base::RefCountedMemory* memory = NULL; 852 base::RefCountedMemory* memory = NULL;
849 int prs_id = GetPersistentIDByIDR(idr_id); 853 int prs_id = GetPersistentIDByIDR(idr_id);
850 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); 854 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
851 855
852 if (raw_id != -1) { 856 if (raw_id != -1) {
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 1286
1283 void BrowserThemePack::CreateFrameImages(ImageCache* images) const { 1287 void BrowserThemePack::CreateFrameImages(ImageCache* images) const {
1284 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1288 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1285 1289
1286 // Create all the output images in a separate cache and move them back into 1290 // Create all the output images in a separate cache and move them back into
1287 // the input images because there can be name collisions. 1291 // the input images because there can be name collisions.
1288 ImageCache temp_output; 1292 ImageCache temp_output;
1289 1293
1290 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) { 1294 for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) {
1291 int prs_id = kFrameTintMap[i].key; 1295 int prs_id = kFrameTintMap[i].key;
1292 gfx::Image frame; 1296 const gfx::Image* frame = &empty_image();
1293 // If there's no frame image provided for the specified id, then load 1297 // If there's no frame image provided for the specified id, then load
1294 // the default provided frame. If that's not provided, skip this whole 1298 // the default provided frame. If that's not provided, skip this whole
1295 // thing and just use the default images. 1299 // thing and just use the default images.
1296 int prs_base_id = 0; 1300 int prs_base_id = 0;
1297 1301
1298 if (!prs_base_id) { 1302 if (!prs_base_id) {
1299 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) { 1303 if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) {
1300 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ? 1304 prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ?
1301 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME; 1305 PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME;
1302 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) { 1306 } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) {
1303 prs_base_id = PRS_THEME_FRAME_OVERLAY; 1307 prs_base_id = PRS_THEME_FRAME_OVERLAY;
1304 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) { 1308 } else if (prs_id == PRS_THEME_FRAME_INACTIVE) {
1305 prs_base_id = PRS_THEME_FRAME; 1309 prs_base_id = PRS_THEME_FRAME;
1306 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO && 1310 } else if (prs_id == PRS_THEME_FRAME_INCOGNITO &&
1307 !images->count(PRS_THEME_FRAME_INCOGNITO)) { 1311 !images->count(PRS_THEME_FRAME_INCOGNITO)) {
1308 prs_base_id = PRS_THEME_FRAME; 1312 prs_base_id = PRS_THEME_FRAME;
1309 } else { 1313 } else {
1310 prs_base_id = prs_id; 1314 prs_base_id = prs_id;
1311 } 1315 }
1312 } 1316 }
1313 if (images->count(prs_id)) { 1317 if (images->count(prs_id)) {
1314 frame = (*images)[prs_id]; 1318 frame = &(*images)[prs_id];
1315 } else if (prs_base_id != prs_id && images->count(prs_base_id)) { 1319 } else if (prs_base_id != prs_id && images->count(prs_base_id)) {
1316 frame = (*images)[prs_base_id]; 1320 frame = &(*images)[prs_base_id];
1317 } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY) { 1321 } else if (prs_base_id != PRS_THEME_FRAME_OVERLAY) {
1318 if (images->count(PRS_THEME_FRAME)) { 1322 // If there is no theme overlay, don't tint the default frame,
1319 // If there is no theme overlay, don't tint the default frame, 1323 // because it will overwrite the custom frame image when we cache and
1320 // because it will overwrite the custom frame image when we cache and 1324 // reload from disk. If the theme doesn't specify an image, then apply the
1321 // reload from disk. 1325 // tint to the default frame.
1322 frame = gfx::Image(); 1326 frame = &rb.GetImageNamed(IDR_THEME_FRAME);
1323 }
1324 } else {
1325 // If the theme doesn't specify an image, then apply the tint to
1326 // the default frame.
1327 frame = rb.GetImageNamed(IDR_THEME_FRAME);
1328 } 1327 }
1329 if (!frame.IsEmpty()) { 1328 if (!frame->IsEmpty()) {
1330 temp_output[prs_id] = CreateHSLShiftedImage( 1329 temp_output[prs_id] = CreateHSLShiftedImage(
1331 frame, GetTintInternal(kFrameTintMap[i].value)); 1330 *frame, GetTintInternal(kFrameTintMap[i].value));
1332 } 1331 }
1333 } 1332 }
1334 MergeImageCaches(temp_output, images); 1333 MergeImageCaches(std::move(temp_output), images);
1335 } 1334 }
1336 1335
1337 void BrowserThemePack::CreateTintedButtons( 1336 void BrowserThemePack::CreateTintedButtons(
1338 const color_utils::HSL& button_tint, 1337 const color_utils::HSL& button_tint,
1339 ImageCache* processed_images) const { 1338 ImageCache* processed_images) const {
1340 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) { 1339 if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) {
1341 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 1340 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1342 const std::set<int>& idr_ids = 1341 const std::set<int>& idr_ids =
1343 ThemeProperties::GetTintableToolbarButtons(); 1342 ThemeProperties::GetTintableToolbarButtons();
1344 for (std::set<int>::const_iterator it = idr_ids.begin(); 1343 for (std::set<int>::const_iterator it = idr_ids.begin();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 if (overlay_it != images->end()) 1376 if (overlay_it != images->end())
1378 overlay = overlay_it->second.AsImageSkia(); 1377 overlay = overlay_it->second.AsImageSkia();
1379 1378
1380 gfx::ImageSkiaSource* source = new TabBackgroundImageSource( 1379 gfx::ImageSkiaSource* source = new TabBackgroundImageSource(
1381 image_to_tint, overlay, hsl_shift, vertical_offset); 1380 image_to_tint, overlay, hsl_shift, vertical_offset);
1382 // ImageSkia takes ownership of |source|. 1381 // ImageSkia takes ownership of |source|.
1383 temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source, 1382 temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source,
1384 image_to_tint.size())); 1383 image_to_tint.size()));
1385 } 1384 }
1386 } 1385 }
1387 MergeImageCaches(temp_output, images); 1386 MergeImageCaches(std::move(temp_output), images);
1388 } 1387 }
1389 1388
1390 void BrowserThemePack::RepackImages(const ImageCache& images, 1389 void BrowserThemePack::RepackImages(const ImageCache& images,
1391 RawImages* reencoded_images) const { 1390 RawImages* reencoded_images) const {
1392 for (ImageCache::const_iterator it = images.begin(); 1391 for (ImageCache::const_iterator it = images.begin();
1393 it != images.end(); ++it) { 1392 it != images.end(); ++it) {
1394 gfx::ImageSkia image_skia = *it->second.ToImageSkia(); 1393 gfx::ImageSkia image_skia = *it->second.ToImageSkia();
1395 1394
1396 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps; 1395 typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps;
1397 ImageSkiaReps image_reps = image_skia.image_reps(); 1396 ImageSkiaReps image_reps = image_skia.image_reps();
(...skipping 10 matching lines...) Expand all
1408 } 1407 }
1409 int raw_id = GetRawIDByPersistentID( 1408 int raw_id = GetRawIDByPersistentID(
1410 it->first, 1409 it->first,
1411 ui::GetSupportedScaleFactor(rep_it->scale())); 1410 ui::GetSupportedScaleFactor(rep_it->scale()));
1412 (*reencoded_images)[raw_id] = 1411 (*reencoded_images)[raw_id] =
1413 base::RefCountedBytes::TakeVector(&bitmap_data); 1412 base::RefCountedBytes::TakeVector(&bitmap_data);
1414 } 1413 }
1415 } 1414 }
1416 } 1415 }
1417 1416
1418 void BrowserThemePack::MergeImageCaches( 1417 void BrowserThemePack::MergeImageCaches(ImageCache source,
1419 const ImageCache& source, ImageCache* destination) const { 1418 ImageCache* destination) const {
1420 for (ImageCache::const_iterator it = source.begin(); it != source.end(); 1419 for (auto& item : source)
1421 ++it) { 1420 (*destination)[item.first] = std::move(item.second);
1422 (*destination)[it->first] = it->second;
1423 }
1424 } 1421 }
1425 1422
1426 void BrowserThemePack::AddRawImagesTo(const RawImages& images, 1423 void BrowserThemePack::AddRawImagesTo(const RawImages& images,
1427 RawDataForWriting* out) const { 1424 RawDataForWriting* out) const {
1428 for (RawImages::const_iterator it = images.begin(); it != images.end(); 1425 for (RawImages::const_iterator it = images.begin(); it != images.end();
1429 ++it) { 1426 ++it) {
1430 (*out)[it->first] = base::StringPiece( 1427 (*out)[it->first] = base::StringPiece(
1431 it->second->front_as<char>(), it->second->size()); 1428 it->second->front_as<char>(), it->second->size());
1432 } 1429 }
1433 } 1430 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 false, 1537 false,
1541 &bitmap_data)) { 1538 &bitmap_data)) {
1542 NOTREACHED() << "Unable to encode theme image for prs_id=" 1539 NOTREACHED() << "Unable to encode theme image for prs_id="
1543 << prs_id << " for scale_factor=" << scale_factors_[i]; 1540 << prs_id << " for scale_factor=" << scale_factors_[i];
1544 break; 1541 break;
1545 } 1542 }
1546 image_memory_[scaled_raw_id] = 1543 image_memory_[scaled_raw_id] =
1547 base::RefCountedBytes::TakeVector(&bitmap_data); 1544 base::RefCountedBytes::TakeVector(&bitmap_data);
1548 } 1545 }
1549 } 1546 }
OLDNEW
« no previous file with comments | « chrome/browser/themes/browser_theme_pack.h ('k') | chrome/browser/themes/custom_theme_supplier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698