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

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: store png in source 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 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 } 436 }
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
pkotwicz 2013/06/19 16:20:32 Nit: Add a comment for this method
sschmitz 2013/06/19 21:56:52 Done.
447 SkBitmap CreateLowQualityResizedBitmap(const SkBitmap& available_bitmap,
pkotwicz 2013/06/19 16:20:32 Nit: Name this |source_bitmap|
sschmitz 2013/06/19 21:56:52 Done.
448 ui::ScaleFactor available_scale_factor,
449 ui::ScaleFactor desired_scale_factor) {
450 gfx::Size scaled_size = gfx::ToCeiledSize(
451 gfx::ScaleSize(gfx::Size(available_bitmap.width(),
452 available_bitmap.height()),
453 ui::GetScaleFactorScale(desired_scale_factor) /
454 ui::GetScaleFactorScale(available_scale_factor)));
455 SkBitmap scaled_bitmap;
456 scaled_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
457 scaled_size.width(),
458 scaled_size.height());
459 if (!scaled_bitmap.allocPixels())
460 SK_CRASH();
461 scaled_bitmap.eraseARGB(0, 0, 0, 0);
462 SkCanvas canvas(scaled_bitmap);
463 SkRect scaled_bounds = RectToSkRect(gfx::Rect(scaled_size));
464 canvas.drawBitmapRect(available_bitmap, NULL, scaled_bounds);
465 return scaled_bitmap;
466 }
467
447 // A ImageSkiaSource that scales 100P image to the target scale factor 468 // A ImageSkiaSource that scales 100P image to the target scale factor
448 // if the ImageSkiaRep for the target scale factor isn't available. 469 // if the ImageSkiaRep for the target scale factor isn't available.
449 class ThemeImageSource: public gfx::ImageSkiaSource { 470 class ThemeImageSource: public gfx::ImageSkiaSource {
450 public: 471 public:
451 explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) { 472 explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) {
452 } 473 }
453 virtual ~ThemeImageSource() {} 474 virtual ~ThemeImageSource() {}
454 475
455 virtual gfx::ImageSkiaRep GetImageForScale( 476 virtual gfx::ImageSkiaRep GetImageForScale(
456 ui::ScaleFactor scale_factor) OVERRIDE { 477 ui::ScaleFactor scale_factor) OVERRIDE {
457 if (source_.HasRepresentation(scale_factor)) 478 if (source_.HasRepresentation(scale_factor))
458 return source_.GetRepresentation(scale_factor); 479 return source_.GetRepresentation(scale_factor);
459 const gfx::ImageSkiaRep& rep_100p = 480 const gfx::ImageSkiaRep& rep_100p =
460 source_.GetRepresentation(ui::SCALE_FACTOR_100P); 481 source_.GetRepresentation(ui::SCALE_FACTOR_100P);
461 float scale = ui::GetScaleFactorScale(scale_factor); 482 float scale = ui::GetScaleFactorScale(scale_factor);
462 gfx::Size size(rep_100p.GetWidth() * scale, rep_100p.GetHeight() * scale); 483 gfx::Size size(rep_100p.GetWidth() * scale, rep_100p.GetHeight() * scale);
463 SkBitmap resized_bitmap; 484 SkBitmap resized_bitmap;
464 resized_bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), 485 resized_bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(),
pkotwicz 2013/06/19 16:20:32 You should be able to invoke CreateLowQualityResiz
sschmitz 2013/06/19 21:56:52 Done.
465 size.height()); 486 size.height());
466 if (!resized_bitmap.allocPixels()) 487 if (!resized_bitmap.allocPixels())
467 SK_CRASH(); 488 SK_CRASH();
468 resized_bitmap.eraseARGB(0, 0, 0, 0); 489 resized_bitmap.eraseARGB(0, 0, 0, 0);
469 SkCanvas canvas(resized_bitmap); 490 SkCanvas canvas(resized_bitmap);
470 SkRect resized_bounds = RectToSkRect(gfx::Rect(size)); 491 SkRect resized_bounds = RectToSkRect(gfx::Rect(size));
471 // Note(oshima): The following scaling code doesn't work with 492 // Note(oshima): The following scaling code doesn't work with
472 // a mask image. 493 // a mask image.
473 canvas.drawBitmapRect(rep_100p.sk_bitmap(), NULL, resized_bounds); 494 canvas.drawBitmapRect(rep_100p.sk_bitmap(), NULL, resized_bounds);
474 return gfx::ImageSkiaRep(resized_bitmap, scale_factor); 495 return gfx::ImageSkiaRep(resized_bitmap, scale_factor);
475 } 496 }
476 497
477 private: 498 private:
478 const gfx::ImageSkia source_; 499 const gfx::ImageSkia source_;
479 500
480 DISALLOW_COPY_AND_ASSIGN(ThemeImageSource); 501 DISALLOW_COPY_AND_ASSIGN(ThemeImageSource);
481 }; 502 };
482 503
504 // An ImageSkiaSource that delays decoding PNG data into bitmaps until
505 // needed. Missing data for a scale factor is computed by scaling data for an
506 // available scale factor. Computed bitmaps are stored for future look up.
507 class ThemeImagePngSource : public gfx::ImageSkiaSource {
508 public:
509 ThemeImagePngSource() {}
pkotwicz 2013/06/19 16:20:32 Nit: Could you pass std::map<ui::ScaleFactor, base
sschmitz 2013/06/19 21:56:52 Done.
510
511 virtual ~ThemeImagePngSource() {}
512
513 void AddPng(scoped_refptr<base::RefCountedMemory> png_memory,
514 ui::ScaleFactor scale_factor) {
515 png_map_[scale_factor] = png_memory;
516 }
517
518 private:
519 virtual gfx::ImageSkiaRep GetImageForScale(
520 ui::ScaleFactor scale_factor) OVERRIDE {
521 // Look up the bitmap for |scale factor| in the bitmap map. If found
522 // return it.
523 BitmapMap::const_iterator exact_bitmap_it = bitmap_map_.find(scale_factor);
pkotwicz 2013/06/19 16:20:32 Technically, this check here is unnecessary becaus
sschmitz 2013/06/19 21:56:52 It feel safer to keep it. Then we're less coupled
524 if (exact_bitmap_it != bitmap_map_.end())
525 return gfx::ImageSkiaRep(exact_bitmap_it->second, scale_factor);
526
527 // Look up the raw PNG data for |scale_factor| in the png map. If found,
528 // decode it, store the result in the bitmap map and return it.
529 PngMap::const_iterator exact_png_it = png_map_.find(scale_factor);
530 if (exact_png_it != png_map_.end()) {
531 SkBitmap bitmap;
532 if (!gfx::PNGCodec::Decode(exact_png_it->second->front(),
533 exact_png_it->second->size(),
534 &bitmap)) {
535 NOTREACHED();
536 return gfx::ImageSkiaRep();
537 }
538 bitmap_map_[scale_factor] = bitmap;
539 return gfx::ImageSkiaRep(bitmap, scale_factor);
540 }
541
542 // Find an available PNG for another scale factor. We want to use the
543 // highest available scale factor.
544 PngMap::const_iterator available_png_it = png_map_.end();
545 for (PngMap::const_iterator png_it = png_map_.begin();
546 png_it != png_map_.end(); ++png_it) {
547 if (available_png_it == png_map_.end() ||
548 ui::GetScaleFactorScale(png_it->first) >
549 ui::GetScaleFactorScale(available_png_it->first)) {
550 available_png_it = png_it;
551 }
552 }
553 if (available_png_it == png_map_.end())
554 return gfx::ImageSkiaRep();
555
pkotwicz 2013/06/19 16:23:28 Shouldn't you check if there is already a bitmap i
sschmitz 2013/06/19 21:56:52 Yes. Done.
556 // Decode the available png and store the result in the bitmap map.
557 SkBitmap available_bitmap;
558 if (!gfx::PNGCodec::Decode(available_png_it->second->front(),
559 available_png_it->second->size(),
560 &available_bitmap)) {
561 NOTREACHED();
562 return gfx::ImageSkiaRep();
563 }
564 ui::ScaleFactor available_scale_factor = available_png_it->first;
565 bitmap_map_[available_scale_factor] = available_bitmap;
566
567 // Scale the available bitmap to the desired scale factor, store the result
568 // in the bitmap map and return it.
569 SkBitmap scaled_bitmap = CreateLowQualityResizedBitmap(
570 available_bitmap,
571 available_scale_factor,
572 scale_factor);
573 bitmap_map_[scale_factor] = scaled_bitmap;
574 return gfx::ImageSkiaRep(scaled_bitmap, scale_factor);
575 }
576
577 typedef std::map<ui::ScaleFactor,
578 scoped_refptr<base::RefCountedMemory> > PngMap;
579 PngMap png_map_;
580
581 typedef std::map<ui::ScaleFactor, SkBitmap> BitmapMap;
582 BitmapMap bitmap_map_;
583
584 DISALLOW_COPY_AND_ASSIGN(ThemeImagePngSource);
585 };
586
483 class TabBackgroundImageSource: public gfx::CanvasImageSource { 587 class TabBackgroundImageSource: public gfx::CanvasImageSource {
484 public: 588 public:
485 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint, 589 TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint,
486 const gfx::ImageSkia& overlay, 590 const gfx::ImageSkia& overlay,
487 const color_utils::HSL& hsl_shift, 591 const color_utils::HSL& hsl_shift,
488 int vertical_offset) 592 int vertical_offset)
489 : gfx::CanvasImageSource(image_to_tint.size(), false), 593 : gfx::CanvasImageSource(image_to_tint.size(), false),
490 image_to_tint_(image_to_tint), 594 image_to_tint_(image_to_tint),
491 overlay_(overlay), 595 overlay_(overlay),
492 hsl_shift_(hsl_shift), 596 hsl_shift_(hsl_shift),
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) { 846 gfx::Image BrowserThemePack::GetImageNamed(int idr_id) {
743 int prs_id = GetPersistentIDByIDR(idr_id); 847 int prs_id = GetPersistentIDByIDR(idr_id);
744 if (prs_id == -1) 848 if (prs_id == -1)
745 return gfx::Image(); 849 return gfx::Image();
746 850
747 // Check if the image is cached. 851 // Check if the image is cached.
748 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id); 852 ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
749 if (image_iter != images_on_ui_thread_.end()) 853 if (image_iter != images_on_ui_thread_.end())
750 return image_iter->second; 854 return image_iter->second;
751 855
752 // TODO(pkotwicz): Do something better than loading the bitmaps 856 ThemeImagePngSource* png_source = NULL;
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) { 857 for (size_t i = 0; i < scale_factors_.size(); ++i) {
757 scoped_refptr<base::RefCountedMemory> memory = 858 scoped_refptr<base::RefCountedMemory> memory =
758 GetRawData(idr_id, scale_factors_[i]); 859 GetRawData(idr_id, scale_factors_[i]);
759 if (memory.get()) { 860 if (memory.get()) {
760 // Decode the PNG. 861 if (!png_source)
761 SkBitmap bitmap; 862 png_source = new ThemeImagePngSource;
762 if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), 863 png_source->AddPng(memory, scale_factors_[i]);
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 } 864 }
771 } 865 }
772 866 if (png_source) {
773 if (!source_image_skia.isNull()) { 867 // |image_skia| owns png_source.
774 ThemeImageSource* source = new ThemeImageSource(source_image_skia); 868 gfx::ImageSkia image_skia(png_source, ui::SCALE_FACTOR_100P);
775 gfx::ImageSkia image_skia(source, source_image_skia.size());
776 gfx::Image ret = gfx::Image(image_skia); 869 gfx::Image ret = gfx::Image(image_skia);
777 images_on_ui_thread_[prs_id] = ret; 870 images_on_ui_thread_[prs_id] = ret;
778 return ret; 871 return ret;
779 } 872 }
873
780 return gfx::Image(); 874 return gfx::Image();
781 } 875 }
782 876
783 base::RefCountedMemory* BrowserThemePack::GetRawData( 877 base::RefCountedMemory* BrowserThemePack::GetRawData(
784 int idr_id, 878 int idr_id,
785 ui::ScaleFactor scale_factor) const { 879 ui::ScaleFactor scale_factor) const {
786 base::RefCountedMemory* memory = NULL; 880 base::RefCountedMemory* memory = NULL;
787 int prs_id = GetPersistentIDByIDR(idr_id); 881 int prs_id = GetPersistentIDByIDR(idr_id);
788 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor); 882 int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
789 883
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]); 1562 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
1469 if (image_memory_.find(raw_id) == image_memory_.end()) { 1563 if (image_memory_.find(raw_id) == image_memory_.end()) {
1470 image_missing = true; 1564 image_missing = true;
1471 break; 1565 break;
1472 } 1566 }
1473 } 1567 }
1474 if (!image_missing) 1568 if (!image_missing)
1475 return; 1569 return;
1476 1570
1477 // Find available scale factor with highest scale. 1571 // Find available scale factor with highest scale.
1478 ui::ScaleFactor available = ui::SCALE_FACTOR_NONE; 1572 ui::ScaleFactor available_scale_factor = ui::SCALE_FACTOR_NONE;
1479 for (size_t i = 0; i < scale_factors_.size(); ++i) { 1573 for (size_t i = 0; i < scale_factors_.size(); ++i) {
1480 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]); 1574 int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
1481 if ((available == ui::SCALE_FACTOR_NONE || 1575 if ((available_scale_factor == ui::SCALE_FACTOR_NONE ||
1482 (ui::GetScaleFactorScale(scale_factors_[i]) > 1576 (ui::GetScaleFactorScale(scale_factors_[i]) >
1483 ui::GetScaleFactorScale(available))) && 1577 ui::GetScaleFactorScale(available_scale_factor))) &&
1484 image_memory_.find(raw_id) != image_memory_.end()) { 1578 image_memory_.find(raw_id) != image_memory_.end()) {
1485 available = scale_factors_[i]; 1579 available_scale_factor = scale_factors_[i];
1486 } 1580 }
1487 } 1581 }
1488 // If no scale factor is available, we're done. 1582 // If no scale factor is available, we're done.
1489 if (available == ui::SCALE_FACTOR_NONE) 1583 if (available_scale_factor == ui::SCALE_FACTOR_NONE)
1490 return; 1584 return;
1491 1585
1492 // Get bitmap for the available scale factor. 1586 // Get bitmap for the available scale factor.
1493 int available_raw_id = GetRawIDByPersistentID(prs_id, available); 1587 int available_raw_id = GetRawIDByPersistentID(prs_id, available_scale_factor);
1494 RawImages::const_iterator it = image_memory_.find(available_raw_id); 1588 RawImages::const_iterator it = image_memory_.find(available_raw_id);
1495 SkBitmap available_bitmap; 1589 SkBitmap available_bitmap;
1496 if (!gfx::PNGCodec::Decode(it->second->front(), 1590 if (!gfx::PNGCodec::Decode(it->second->front(),
1497 it->second->size(), 1591 it->second->size(),
1498 &available_bitmap)) { 1592 &available_bitmap)) {
1499 NOTREACHED() << "Unable to decode theme image for prs_id=" 1593 NOTREACHED() << "Unable to decode theme image for prs_id="
1500 << prs_id << " for scale_factor=" << available; 1594 << prs_id << " for scale_factor=" << available_scale_factor;
1501 return; 1595 return;
1502 } 1596 }
1503 1597
1504 // Fill in all missing scale factors by scaling the available bitmap. 1598 // Fill in all missing scale factors by scaling the available bitmap.
1505 for (size_t i = 0; i < scale_factors_.size(); ++i) { 1599 for (size_t i = 0; i < scale_factors_.size(); ++i) {
1506 int scaled_raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]); 1600 int scaled_raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
1507 if (image_memory_.find(scaled_raw_id) != image_memory_.end()) 1601 if (image_memory_.find(scaled_raw_id) != image_memory_.end())
1508 continue; 1602 continue;
1509 gfx::Size scaled_size = gfx::ToCeiledSize( 1603 SkBitmap scaled_bitmap =
1510 gfx::ScaleSize(gfx::Size(available_bitmap.width(), 1604 CreateLowQualityResizedBitmap(available_bitmap,
1511 available_bitmap.height()), 1605 available_scale_factor,
1512 ui::GetScaleFactorScale(scale_factors_[i]) / 1606 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; 1607 std::vector<unsigned char> bitmap_data;
1525 if (!gfx::PNGCodec::EncodeBGRASkBitmap(scaled_bitmap, 1608 if (!gfx::PNGCodec::EncodeBGRASkBitmap(scaled_bitmap,
1526 false, 1609 false,
1527 &bitmap_data)) { 1610 &bitmap_data)) {
1528 NOTREACHED() << "Unable to encode theme image for prs_id=" 1611 NOTREACHED() << "Unable to encode theme image for prs_id="
1529 << prs_id << " for scale_factor=" << scale_factors_[i]; 1612 << prs_id << " for scale_factor=" << scale_factors_[i];
1530 break; 1613 break;
1531 } 1614 }
1532 image_memory_[scaled_raw_id] = 1615 image_memory_[scaled_raw_id] =
1533 base::RefCountedBytes::TakeVector(&bitmap_data); 1616 base::RefCountedBytes::TakeVector(&bitmap_data);
1534 } 1617 }
1535 } 1618 }
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