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

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

Issue 16977007: Only load theme images for the scale factors that use them (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: revert unit test Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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> 7 #include <limits>
8 8
9 #include "base/memory/ref_counted_memory.h" 9 #include "base/memory/ref_counted_memory.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 437
438 // Shifts an image's HSL values. The caller is responsible for deleting 438 // Shifts an image's HSL values. The caller is responsible for deleting
439 // the returned image. 439 // the returned image.
440 gfx::Image CreateHSLShiftedImage(const gfx::Image& image, 440 gfx::Image CreateHSLShiftedImage(const gfx::Image& image,
441 const color_utils::HSL& hsl_shift) { 441 const color_utils::HSL& hsl_shift) {
442 const gfx::ImageSkia* src_image = image.ToImageSkia(); 442 const gfx::ImageSkia* src_image = image.ToImageSkia();
443 return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( 443 return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage(
444 *src_image, hsl_shift)); 444 *src_image, hsl_shift));
445 } 445 }
446 446
447 // Computes a bitmap at one scale from a bitmap at a different scale.
448 SkBitmap CreateLowQualityResizedBitmap(const SkBitmap& source_bitmap,
449 ui::ScaleFactor source_scale_factor,
450 ui::ScaleFactor desired_scale_factor) {
451 gfx::Size scaled_size = gfx::ToCeiledSize(
452 gfx::ScaleSize(gfx::Size(source_bitmap.width(),
453 source_bitmap.height()),
454 ui::GetScaleFactorScale(desired_scale_factor) /
455 ui::GetScaleFactorScale(source_scale_factor)));
456 SkBitmap scaled_bitmap;
457 scaled_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
458 scaled_size.width(),
459 scaled_size.height());
460 if (!scaled_bitmap.allocPixels())
461 SK_CRASH();
462 scaled_bitmap.eraseARGB(0, 0, 0, 0);
463 SkCanvas canvas(scaled_bitmap);
464 SkRect scaled_bounds = RectToSkRect(gfx::Rect(scaled_size));
465 // Note(oshima): The following scaling code doesn't work with
466 // a mask image.
467 canvas.drawBitmapRect(source_bitmap, NULL, scaled_bounds);
468 return scaled_bitmap;
469 }
470
447 // A ImageSkiaSource that scales 100P image to the target scale factor 471 // A ImageSkiaSource that scales 100P image to the target scale factor
448 // if the ImageSkiaRep for the target scale factor isn't available. 472 // if the ImageSkiaRep for the target scale factor isn't available.
449 class ThemeImageSource: public gfx::ImageSkiaSource { 473 class ThemeImageSource: public gfx::ImageSkiaSource {
450 public: 474 public:
451 explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) { 475 explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) {
452 } 476 }
453 virtual ~ThemeImageSource() {} 477 virtual ~ThemeImageSource() {}
454 478
455 virtual gfx::ImageSkiaRep GetImageForScale( 479 virtual gfx::ImageSkiaRep GetImageForScale(
456 ui::ScaleFactor scale_factor) OVERRIDE { 480 ui::ScaleFactor scale_factor) OVERRIDE {
457 if (source_.HasRepresentation(scale_factor)) 481 if (source_.HasRepresentation(scale_factor))
458 return source_.GetRepresentation(scale_factor); 482 return source_.GetRepresentation(scale_factor);
459 const gfx::ImageSkiaRep& rep_100p = 483 const gfx::ImageSkiaRep& rep_100p =
460 source_.GetRepresentation(ui::SCALE_FACTOR_100P); 484 source_.GetRepresentation(ui::SCALE_FACTOR_100P);
461 float scale = ui::GetScaleFactorScale(scale_factor); 485 SkBitmap scaled_bitmap = CreateLowQualityResizedBitmap(
462 gfx::Size size(rep_100p.GetWidth() * scale, rep_100p.GetHeight() * scale); 486 rep_100p.sk_bitmap(),
463 SkBitmap resized_bitmap; 487 ui::SCALE_FACTOR_100P,
464 resized_bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), 488 scale_factor);
465 size.height()); 489 return gfx::ImageSkiaRep(scaled_bitmap, scale_factor);
466 if (!resized_bitmap.allocPixels())
467 SK_CRASH();
468 resized_bitmap.eraseARGB(0, 0, 0, 0);
469 SkCanvas canvas(resized_bitmap);
470 SkRect resized_bounds = RectToSkRect(gfx::Rect(size));
471 // Note(oshima): The following scaling code doesn't work with
472 // a mask image.
473 canvas.drawBitmapRect(rep_100p.sk_bitmap(), NULL, resized_bounds);
474 return gfx::ImageSkiaRep(resized_bitmap, scale_factor);
475 } 490 }
476 491
477 private: 492 private:
478 const gfx::ImageSkia source_; 493 const gfx::ImageSkia source_;
479 494
480 DISALLOW_COPY_AND_ASSIGN(ThemeImageSource); 495 DISALLOW_COPY_AND_ASSIGN(ThemeImageSource);
481 }; 496 };
482 497
498 // An ImageSkiaSource that delays decoding PNG data into bitmaps until
499 // needed. Missing data for a scale factor is computed by scaling data for an
500 // available scale factor. Computed bitmaps are stored for future look up.
501 class ThemeImagePngSource : public gfx::ImageSkiaSource {
502 public:
503 typedef std::map<ui::ScaleFactor,
504 scoped_refptr<base::RefCountedMemory> > PngMap;
505
506 explicit ThemeImagePngSource(const PngMap& png_map) : png_map_(png_map) {}
507
508 virtual ~ThemeImagePngSource() {}
509
510 private:
511 virtual gfx::ImageSkiaRep GetImageForScale(
512 ui::ScaleFactor scale_factor) OVERRIDE {
513 // Look up the bitmap for |scale factor| in the bitmap map. If found
514 // return it.
515 BitmapMap::const_iterator exact_bitmap_it = bitmap_map_.find(scale_factor);
516 if (exact_bitmap_it != bitmap_map_.end())
517 return gfx::ImageSkiaRep(exact_bitmap_it->second, scale_factor);
518
519 // Look up the raw PNG data for |scale_factor| in the png map. If found,
520 // decode it, store the result in the bitmap map and return it.
521 PngMap::const_iterator exact_png_it = png_map_.find(scale_factor);
522 if (exact_png_it != png_map_.end()) {
523 SkBitmap bitmap;
524 if (!gfx::PNGCodec::Decode(exact_png_it->second->front(),
525 exact_png_it->second->size(),
526 &bitmap)) {
527 NOTREACHED();
528 return gfx::ImageSkiaRep();
529 }
530 bitmap_map_[scale_factor] = bitmap;
531 return gfx::ImageSkiaRep(bitmap, scale_factor);
532 }
533
534 // Find an available PNG for another scale factor. We want to use the
535 // highest available scale factor.
536 PngMap::const_iterator available_png_it = png_map_.end();
537 for (PngMap::const_iterator png_it = png_map_.begin();
538 png_it != png_map_.end(); ++png_it) {
539 if (available_png_it == png_map_.end() ||
540 ui::GetScaleFactorScale(png_it->first) >
541 ui::GetScaleFactorScale(available_png_it->first)) {
542 available_png_it = png_it;
543 }
544 }
545 if (available_png_it == png_map_.end())
546 return gfx::ImageSkiaRep();
547 ui::ScaleFactor available_scale_factor = available_png_it->first;
548
549 // Look up the bitmap for |available_scale_factor| in the bitmap map.
550 // If not found, decode the corresponging png data, store the result
551 // in the bitmap map.
552 BitmapMap::const_iterator available_bitmap_it =
553 bitmap_map_.find(available_scale_factor);
554 if (available_bitmap_it == bitmap_map_.end()) {
555 SkBitmap available_bitmap;
556 if (!gfx::PNGCodec::Decode(available_png_it->second->front(),
557 available_png_it->second->size(),
558 &available_bitmap)) {
559 NOTREACHED();
560 return gfx::ImageSkiaRep();
561 }
562 bitmap_map_[available_scale_factor] = available_bitmap;
563 available_bitmap_it = bitmap_map_.find(available_scale_factor);
564 }
565
566 // Scale the available bitmap to the desired scale factor, store the result
567 // in the bitmap map and return it.
568 SkBitmap scaled_bitmap = CreateLowQualityResizedBitmap(
569 available_bitmap_it->second,
570 available_scale_factor,
571 scale_factor);
572 bitmap_map_[scale_factor] = scaled_bitmap;
573 return gfx::ImageSkiaRep(scaled_bitmap, scale_factor);
574 }
575
576 PngMap png_map_;
577
578 typedef std::map<ui::ScaleFactor, SkBitmap> BitmapMap;
579 BitmapMap bitmap_map_;
580
581 DISALLOW_COPY_AND_ASSIGN(ThemeImagePngSource);
582 };
583
483 class TabBackgroundImageSource: public gfx::CanvasImageSource { 584 class TabBackgroundImageSource: public gfx::CanvasImageSource {
484 public: 585 public:
485 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint, 586 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint,
486 const gfx::ImageSkia& overlay, 587 const gfx::ImageSkia& overlay,
487 const color_utils::HSL& hsl_shift, 588 const color_utils::HSL& hsl_shift,
488 int vertical_offset) 589 int vertical_offset)
489 : gfx::CanvasImageSource(image_to_tint.size(), false), 590 : gfx::CanvasImageSource(image_to_tint.size(), false),
490 image_to_tint_(image_to_tint), 591 image_to_tint_(image_to_tint),
491 overlay_(overlay), 592 overlay_(overlay),
492 hsl_shift_(hsl_shift), 593 hsl_shift_(hsl_shift),
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { 843 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) {
743 int prs_id = GetPersistentIDByIDR(idr_id); 844 int prs_id = GetPersistentIDByIDR(idr_id);
744 if (prs_id == -1) 845 if (prs_id == -1)
745 return gfx::Image(); 846 return gfx::Image();
746 847
747 // Check if the image is cached. 848 // Check if the image is cached.
748 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); 849 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
749 if (image_iter != images_on_ui_thread_.end()) 850 if (image_iter != images_on_ui_thread_.end())
750 return image_iter->second; 851 return image_iter->second;
751 852
752 // TODO(pkotwicz): Do something better than loading the bitmaps 853 ThemeImagePngSource::PngMap png_map;
753 // for all the scale factors associated with |idr_id|.
754 // See crbug.com/243831.
755 gfx::ImageSkia source_image_skia;
756 for (size_t i = 0; i < scale_factors_.size(); ++i) { 854 for (size_t i = 0; i < scale_factors_.size(); ++i) {
757 scoped_refptr<base::RefCountedMemory> memory = 855 scoped_refptr<base::RefCountedMemory> memory =
758 GetRawData(idr_id, scale_factors_[i]); 856 GetRawData(idr_id, scale_factors_[i]);
759 if (memory.get()) { 857 if (memory.get())
760 // Decode the PNG. 858 png_map[scale_factors_[i]] = memory;
761 SkBitmap bitmap;
762 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(),
763 &bitmap)) {
764 NOTREACHED() << "Unable to decode theme image resource " << idr_id
765 << " from saved DataPack.";
766 continue;
767 }
768 source_image_skia.AddRepresentation(
769 gfx::ImageSkiaRep(bitmap, scale_factors_[i]));
770 }
771 } 859 }
772 860 if (!png_map.empty()) {
773 if (!source_image_skia.isNull()) { 861 gfx::ImageSkia image_skia(new ThemeImagePngSource(png_map),
774 ThemeImageSource* source = new ThemeImageSource(source_image_skia); 862 ui::SCALE_FACTOR_100P);
775 gfx::ImageSkia image_skia(source, source_image_skia.size()); 863 // |image_skia| takes ownership of ThemeImagePngSource.
776 gfx::Image ret = gfx::Image(image_skia); 864 gfx::Image ret = gfx::Image(image_skia);
777 images_on_ui_thread_[prs_id] = ret; 865 images_on_ui_thread_[prs_id] = ret;
778 return ret; 866 return ret;
779 } 867 }
868
780 return gfx::Image(); 869 return gfx::Image();
781 } 870 }
782 871
783 base::RefCountedMemory* BrowserThemePack::GetRawData( 872 base::RefCountedMemory* BrowserThemePack::GetRawData(
784 int idr_id, 873 int idr_id,
785 ui::ScaleFactor scale_factor) const { 874 ui::ScaleFactor scale_factor) const {
786 base::RefCountedMemory* memory = NULL; 875 base::RefCountedMemory* memory = NULL;
787 int prs_id = GetPersistentIDByIDR(idr_id); 876 int prs_id = GetPersistentIDByIDR(idr_id);
788 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); 877 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
789 878
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]); 1557 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
1469 if (image_memory_.find(raw_id) == image_memory_.end()) { 1558 if (image_memory_.find(raw_id) == image_memory_.end()) {
1470 image_missing = true; 1559 image_missing = true;
1471 break; 1560 break;
1472 } 1561 }
1473 } 1562 }
1474 if (!image_missing) 1563 if (!image_missing)
1475 return; 1564 return;
1476 1565
1477 // Find available scale factor with highest scale. 1566 // Find available scale factor with highest scale.
1478 ui::ScaleFactor available = ui::SCALE_FACTOR_NONE; 1567 ui::ScaleFactor available_scale_factor = ui::SCALE_FACTOR_NONE;
1479 for (size_t i = 0; i < scale_factors_.size(); ++i) { 1568 for (size_t i = 0; i < scale_factors_.size(); ++i) {
1480 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]); 1569 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
1481 if ((available == ui::SCALE_FACTOR_NONE || 1570 if ((available_scale_factor == ui::SCALE_FACTOR_NONE ||
1482 (ui::GetScaleFactorScale(scale_factors_[i]) > 1571 (ui::GetScaleFactorScale(scale_factors_[i]) >
1483 ui::GetScaleFactorScale(available))) && 1572 ui::GetScaleFactorScale(available_scale_factor))) &&
1484 image_memory_.find(raw_id) != image_memory_.end()) { 1573 image_memory_.find(raw_id) != image_memory_.end()) {
1485 available = scale_factors_[i]; 1574 available_scale_factor = scale_factors_[i];
1486 } 1575 }
1487 } 1576 }
1488 // If no scale factor is available, we're done. 1577 // If no scale factor is available, we're done.
1489 if (available == ui::SCALE_FACTOR_NONE) 1578 if (available_scale_factor == ui::SCALE_FACTOR_NONE)
1490 return; 1579 return;
1491 1580
1492 // Get bitmap for the available scale factor. 1581 // Get bitmap for the available scale factor.
1493 int available_raw_id = GetRawIDByPersistentID(prs_id, available); 1582 int available_raw_id = GetRawIDByPersistentID(prs_id, available_scale_factor);
1494 RawImages::const_iterator it = image_memory_.find(available_raw_id); 1583 RawImages::const_iterator it = image_memory_.find(available_raw_id);
1495 SkBitmap available_bitmap; 1584 SkBitmap available_bitmap;
1496 if (!gfx::PNGCodec::Decode(it->second->front(), 1585 if (!gfx::PNGCodec::Decode(it->second->front(),
1497 it->second->size(), 1586 it->second->size(),
1498 &available_bitmap)) { 1587 &available_bitmap)) {
1499 NOTREACHED() << "Unable to decode theme image for prs_id=" 1588 NOTREACHED() << "Unable to decode theme image for prs_id="
1500 << prs_id << " for scale_factor=" << available; 1589 << prs_id << " for scale_factor=" << available_scale_factor;
1501 return; 1590 return;
1502 } 1591 }
1503 1592
1504 // Fill in all missing scale factors by scaling the available bitmap. 1593 // Fill in all missing scale factors by scaling the available bitmap.
1505 for (size_t i = 0; i < scale_factors_.size(); ++i) { 1594 for (size_t i = 0; i < scale_factors_.size(); ++i) {
1506 int scaled_raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]); 1595 int scaled_raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
1507 if (image_memory_.find(scaled_raw_id) != image_memory_.end()) 1596 if (image_memory_.find(scaled_raw_id) != image_memory_.end())
1508 continue; 1597 continue;
1509 gfx::Size scaled_size = gfx::ToCeiledSize( 1598 SkBitmap scaled_bitmap =
1510 gfx::ScaleSize(gfx::Size(available_bitmap.width(), 1599 CreateLowQualityResizedBitmap(available_bitmap,
1511 available_bitmap.height()), 1600 available_scale_factor,
1512 ui::GetScaleFactorScale(scale_factors_[i]) / 1601 scale_factors_[i]);
1513 ui::GetScaleFactorScale(available)));
1514 SkBitmap scaled_bitmap;
1515 scaled_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
1516 scaled_size.width(),
1517 scaled_size.height());
1518 if (!scaled_bitmap.allocPixels())
1519 SK_CRASH();
1520 scaled_bitmap.eraseARGB(0, 0, 0, 0);
1521 SkCanvas canvas(scaled_bitmap);
1522 SkRect scaled_bounds = RectToSkRect(gfx::Rect(scaled_size));
1523 canvas.drawBitmapRect(available_bitmap, NULL, scaled_bounds);
1524 std::vector<unsigned char> bitmap_data; 1602 std::vector<unsigned char> bitmap_data;
1525 if (!gfx::PNGCodec::EncodeBGRASkBitmap(scaled_bitmap, 1603 if (!gfx::PNGCodec::EncodeBGRASkBitmap(scaled_bitmap,
1526 false, 1604 false,
1527 &bitmap_data)) { 1605 &bitmap_data)) {
1528 NOTREACHED() << "Unable to encode theme image for prs_id=" 1606 NOTREACHED() << "Unable to encode theme image for prs_id="
1529 << prs_id << " for scale_factor=" << scale_factors_[i]; 1607 << prs_id << " for scale_factor=" << scale_factors_[i];
1530 break; 1608 break;
1531 } 1609 }
1532 image_memory_[scaled_raw_id] = 1610 image_memory_[scaled_raw_id] =
1533 base::RefCountedBytes::TakeVector(&bitmap_data); 1611 base::RefCountedBytes::TakeVector(&bitmap_data);
1534 } 1612 }
1535 } 1613 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698