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

Side by Side Diff: ui/base/resource/resource_bundle.cc

Issue 2699323002: Restrict cross-thread access to gfx::Image and gfx::Font in ResourceBundle (Closed)
Patch Set: rebase Created 3 years, 10 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 "ui/base/resource/resource_bundle.h" 5 #include "ui/base/resource/resource_bundle.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <utility> 10 #include <utility>
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 UnloadLocaleResources(); 400 UnloadLocaleResources();
401 return LoadLocaleResources(pref_locale); 401 return LoadLocaleResources(pref_locale);
402 } 402 }
403 403
404 gfx::ImageSkia* ResourceBundle::GetImageSkiaNamed(int resource_id) { 404 gfx::ImageSkia* ResourceBundle::GetImageSkiaNamed(int resource_id) {
405 const gfx::ImageSkia* image = GetImageNamed(resource_id).ToImageSkia(); 405 const gfx::ImageSkia* image = GetImageNamed(resource_id).ToImageSkia();
406 return const_cast<gfx::ImageSkia*>(image); 406 return const_cast<gfx::ImageSkia*>(image);
407 } 407 }
408 408
409 gfx::Image& ResourceBundle::GetImageNamed(int resource_id) { 409 gfx::Image& ResourceBundle::GetImageNamed(int resource_id) {
410 DCHECK(sequence_checker_.CalledOnValidSequence());
411
410 // Check to see if the image is already in the cache. 412 // Check to see if the image is already in the cache.
411 { 413 if (images_.count(resource_id))
412 base::AutoLock lock_scope(*images_and_fonts_lock_); 414 return images_[resource_id];
413 if (images_.count(resource_id))
414 return images_[resource_id];
415 }
416 415
417 gfx::Image image; 416 gfx::Image image;
418 if (delegate_) 417 if (delegate_)
419 image = delegate_->GetImageNamed(resource_id); 418 image = delegate_->GetImageNamed(resource_id);
420 419
421 if (image.IsEmpty()) { 420 if (image.IsEmpty()) {
422 DCHECK(!data_packs_.empty()) << 421 DCHECK(!data_packs_.empty()) <<
423 "Missing call to SetResourcesDataDLL?"; 422 "Missing call to SetResourcesDataDLL?";
424 423
425 #if defined(OS_CHROMEOS) 424 #if defined(OS_CHROMEOS)
(...skipping 17 matching lines...) Expand all
443 LOG(WARNING) << "Unable to load image with id " << resource_id; 442 LOG(WARNING) << "Unable to load image with id " << resource_id;
444 NOTREACHED(); // Want to assert in debug mode. 443 NOTREACHED(); // Want to assert in debug mode.
445 // The load failed to retrieve the image; show a debugging red square. 444 // The load failed to retrieve the image; show a debugging red square.
446 return GetEmptyImage(); 445 return GetEmptyImage();
447 } 446 }
448 image_skia.SetReadOnly(); 447 image_skia.SetReadOnly();
449 image = gfx::Image(image_skia); 448 image = gfx::Image(image_skia);
450 } 449 }
451 450
452 // The load was successful, so cache the image. 451 // The load was successful, so cache the image.
453 base::AutoLock lock_scope(*images_and_fonts_lock_);
454
455 // Another thread raced the load and has already cached the image.
456 if (images_.count(resource_id))
457 return images_[resource_id];
458
459 images_[resource_id] = image; 452 images_[resource_id] = image;
460 return images_[resource_id]; 453 return images_[resource_id];
461 } 454 }
462 455
463 base::RefCountedMemory* ResourceBundle::LoadDataResourceBytes( 456 base::RefCountedMemory* ResourceBundle::LoadDataResourceBytes(
464 int resource_id) const { 457 int resource_id) const {
465 return LoadDataResourceBytesForScale(resource_id, ui::SCALE_FACTOR_NONE); 458 return LoadDataResourceBytesForScale(resource_id, ui::SCALE_FACTOR_NONE);
466 } 459 }
467 460
468 base::RefCountedMemory* ResourceBundle::LoadDataResourceBytesForScale( 461 base::RefCountedMemory* ResourceBundle::LoadDataResourceBytesForScale(
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 } 572 }
580 } 573 }
581 // Release lock_scope and fall back to main data pack. 574 // Release lock_scope and fall back to main data pack.
582 return LoadDataResourceBytes(resource_id); 575 return LoadDataResourceBytes(resource_id);
583 } 576 }
584 577
585 const gfx::FontList& ResourceBundle::GetFontListWithDelta( 578 const gfx::FontList& ResourceBundle::GetFontListWithDelta(
586 int size_delta, 579 int size_delta,
587 gfx::Font::FontStyle style, 580 gfx::Font::FontStyle style,
588 gfx::Font::Weight weight) { 581 gfx::Font::Weight weight) {
589 base::AutoLock lock_scope(*images_and_fonts_lock_); 582 DCHECK(sequence_checker_.CalledOnValidSequence());
590 583
591 const FontKey styled_key(size_delta, style, weight); 584 const FontKey styled_key(size_delta, style, weight);
592 585
593 auto found = font_cache_.find(styled_key); 586 auto found = font_cache_.find(styled_key);
594 if (found != font_cache_.end()) 587 if (found != font_cache_.end())
595 return found->second; 588 return found->second;
596 589
597 const FontKey base_key(0, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL); 590 const FontKey base_key(0, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL);
598 gfx::FontList& base = font_cache_[base_key]; 591 gfx::FontList& base = font_cache_[base_key];
599 if (styled_key == base_key) 592 if (styled_key == base_key)
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 641 }
649 642
650 return GetFontListWithDelta(size_delta, gfx::Font::NORMAL, font_weight); 643 return GetFontListWithDelta(size_delta, gfx::Font::NORMAL, font_weight);
651 } 644 }
652 645
653 const gfx::Font& ResourceBundle::GetFont(FontStyle style) { 646 const gfx::Font& ResourceBundle::GetFont(FontStyle style) {
654 return GetFontList(style).GetPrimaryFont(); 647 return GetFontList(style).GetPrimaryFont();
655 } 648 }
656 649
657 void ResourceBundle::ReloadFonts() { 650 void ResourceBundle::ReloadFonts() {
658 base::AutoLock lock_scope(*images_and_fonts_lock_); 651 DCHECK(sequence_checker_.CalledOnValidSequence());
659 InitDefaultFontList(); 652 InitDefaultFontList();
660 font_cache_.clear(); 653 font_cache_.clear();
661 } 654 }
662 655
663 ScaleFactor ResourceBundle::GetMaxScaleFactor() const { 656 ScaleFactor ResourceBundle::GetMaxScaleFactor() const {
664 #if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_LINUX) 657 #if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_LINUX)
665 return max_scale_factor_; 658 return max_scale_factor_;
666 #else 659 #else
667 return GetSupportedScaleFactors().back(); 660 return GetSupportedScaleFactors().back();
668 #endif 661 #endif
669 } 662 }
670 663
671 bool ResourceBundle::IsScaleFactorSupported(ScaleFactor scale_factor) { 664 bool ResourceBundle::IsScaleFactorSupported(ScaleFactor scale_factor) {
672 const std::vector<ScaleFactor>& supported_scale_factors = 665 const std::vector<ScaleFactor>& supported_scale_factors =
673 ui::GetSupportedScaleFactors(); 666 ui::GetSupportedScaleFactors();
674 return std::find(supported_scale_factors.begin(), 667 return std::find(supported_scale_factors.begin(),
675 supported_scale_factors.end(), 668 supported_scale_factors.end(),
676 scale_factor) != supported_scale_factors.end(); 669 scale_factor) != supported_scale_factors.end();
677 } 670 }
678 671
679 ResourceBundle::ResourceBundle(Delegate* delegate) 672 ResourceBundle::ResourceBundle(Delegate* delegate)
680 : delegate_(delegate), 673 : delegate_(delegate),
681 images_and_fonts_lock_(new base::Lock),
682 locale_resources_data_lock_(new base::Lock), 674 locale_resources_data_lock_(new base::Lock),
683 max_scale_factor_(SCALE_FACTOR_100P) { 675 max_scale_factor_(SCALE_FACTOR_100P) {
684 } 676 }
685 677
686 ResourceBundle::~ResourceBundle() { 678 ResourceBundle::~ResourceBundle() {
687 FreeImages(); 679 FreeImages();
688 UnloadLocaleResources(); 680 UnloadLocaleResources();
689 } 681 }
690 682
691 // static 683 // static
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 data_pack->CheckForDuplicateResources(data_packs_); 767 data_pack->CheckForDuplicateResources(data_packs_);
776 #endif 768 #endif
777 769
778 if (GetScaleForScaleFactor(data_pack->GetScaleFactor()) > 770 if (GetScaleForScaleFactor(data_pack->GetScaleFactor()) >
779 GetScaleForScaleFactor(max_scale_factor_)) 771 GetScaleForScaleFactor(max_scale_factor_))
780 max_scale_factor_ = data_pack->GetScaleFactor(); 772 max_scale_factor_ = data_pack->GetScaleFactor();
781 773
782 data_packs_.push_back(std::move(data_pack)); 774 data_packs_.push_back(std::move(data_pack));
783 } 775 }
784 776
785 void ResourceBundle::InitDefaultFontList() { 777 void ResourceBundle::InitDefaultFontList() {
Yuki 2017/02/21 06:23:54 You may want to add DCHECK here, too.
tzik 2017/02/22 07:19:21 Done.
786 #if defined(OS_CHROMEOS) 778 #if defined(OS_CHROMEOS)
787 std::string font_family = base::UTF16ToUTF8( 779 std::string font_family = base::UTF16ToUTF8(
788 GetLocalizedString(IDS_UI_FONT_FAMILY_CROS)); 780 GetLocalizedString(IDS_UI_FONT_FAMILY_CROS));
789 gfx::FontList::SetDefaultFontDescription(font_family); 781 gfx::FontList::SetDefaultFontDescription(font_family);
790 782
791 // TODO(yukishiino): Remove SetDefaultFontDescription() once the migration to 783 // TODO(yukishiino): Remove SetDefaultFontDescription() once the migration to
792 // the font list is done. We will no longer need SetDefaultFontDescription() 784 // the font list is done. We will no longer need SetDefaultFontDescription()
793 // after every client gets started using a FontList instead of a Font. 785 // after every client gets started using a FontList instead of a Font.
794 gfx::PlatformFontLinux::SetDefaultFontDescription(font_family); 786 gfx::PlatformFontLinux::SetDefaultFontDescription(font_family);
795 #else 787 #else
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 *fell_back_to_1x = true; 847 *fell_back_to_1x = true;
856 return true; 848 return true;
857 } 849 }
858 } 850 }
859 } 851 }
860 852
861 return false; 853 return false;
862 } 854 }
863 855
864 gfx::Image& ResourceBundle::GetEmptyImage() { 856 gfx::Image& ResourceBundle::GetEmptyImage() {
865 base::AutoLock lock(*images_and_fonts_lock_); 857 DCHECK(sequence_checker_.CalledOnValidSequence());
866 858
867 if (empty_image_.IsEmpty()) { 859 if (empty_image_.IsEmpty()) {
868 // The placeholder bitmap is bright red so people notice the problem. 860 // The placeholder bitmap is bright red so people notice the problem.
869 SkBitmap bitmap = CreateEmptyBitmap(); 861 SkBitmap bitmap = CreateEmptyBitmap();
870 empty_image_ = gfx::Image::CreateFrom1xBitmap(bitmap); 862 empty_image_ = gfx::Image::CreateFrom1xBitmap(bitmap);
871 } 863 }
872 return empty_image_; 864 return empty_image_;
873 } 865 }
874 866
875 // static 867 // static
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 // static 902 // static
911 bool ResourceBundle::DecodePNG(const unsigned char* buf, 903 bool ResourceBundle::DecodePNG(const unsigned char* buf,
912 size_t size, 904 size_t size,
913 SkBitmap* bitmap, 905 SkBitmap* bitmap,
914 bool* fell_back_to_1x) { 906 bool* fell_back_to_1x) {
915 *fell_back_to_1x = PNGContainsFallbackMarker(buf, size); 907 *fell_back_to_1x = PNGContainsFallbackMarker(buf, size);
916 return gfx::PNGCodec::Decode(buf, size, bitmap); 908 return gfx::PNGCodec::Decode(buf, size, bitmap);
917 } 909 }
918 910
919 } // namespace ui 911 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698