| Index: ui/gfx/image/image.cc
|
| diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc
|
| index 0a5564d8d6c023597386e0f2e614e6cca779b6e1..a072ab09328c51c304ba786203a05b7c91ed6490 100644
|
| --- a/ui/gfx/image/image.cc
|
| +++ b/ui/gfx/image/image.cc
|
| @@ -9,6 +9,7 @@
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/stl_util.h"
|
| +#include "base/synchronization/lock.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| #include "ui/gfx/image/image_png_rep.h"
|
| #include "ui/gfx/image/image_skia.h"
|
| @@ -30,6 +31,10 @@ namespace gfx {
|
|
|
| namespace internal {
|
|
|
| +class ImageRep;
|
| +
|
| +typedef std::map<Image::RepresentationType, ImageRep*> RepresentationMap;
|
| +
|
| #if defined(OS_IOS)
|
| scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage(
|
| UIImage* uiimage);
|
| @@ -301,7 +306,7 @@ class ImageRepCocoa : public ImageRep {
|
| // The Storage class acts similarly to the pixels in a SkBitmap: the Image
|
| // class holds a refptr instance of Storage, which in turn holds all the
|
| // ImageReps. This way, the Image can be cheaply copied.
|
| -class ImageStorage : public base::RefCounted<ImageStorage> {
|
| +class ImageStorage : public base::RefCountedThreadSafe<ImageStorage> {
|
| public:
|
| ImageStorage(gfx::Image::RepresentationType default_type)
|
| : default_representation_type_(default_type),
|
| @@ -312,22 +317,48 @@ class ImageStorage : public base::RefCounted<ImageStorage> {
|
| representations_deleter_(&representations_) {
|
| }
|
|
|
| - gfx::Image::RepresentationType default_representation_type() {
|
| + gfx::Image::RepresentationType default_representation_type() const {
|
| return default_representation_type_;
|
| }
|
| - gfx::Image::RepresentationMap& representations() { return representations_; }
|
| +
|
| + size_t representation_count() const {
|
| + base::AutoLock lock(mutex_);
|
| + return representations_.size();
|
| + }
|
| +
|
| + void add_representation(internal::ImageRep* rep) {
|
| + base::AutoLock lock(mutex_);
|
| + representations_.insert(std::make_pair(rep->type(), rep));
|
| + }
|
| +
|
| + bool has_representation(Image::RepresentationType type) const {
|
| + base::AutoLock lock(mutex_);
|
| + return representations_.count(type) != 0;
|
| + }
|
| +
|
| + internal::ImageRep* get_representation(
|
| + Image::RepresentationType rep_type) const {
|
| + base::AutoLock lock(mutex_);
|
| + internal::RepresentationMap::const_iterator it =
|
| + representations_.find(rep_type);
|
| + if (it == representations_.end())
|
| + return NULL;
|
| + return it->second;
|
| + }
|
|
|
| #if defined(OS_MACOSX) && !defined(OS_IOS)
|
| void set_default_representation_color_space(CGColorSpaceRef color_space) {
|
| + base::AutoLock lock(mutex_);
|
| default_representation_color_space_ = color_space;
|
| }
|
| - CGColorSpaceRef default_representation_color_space() {
|
| + CGColorSpaceRef default_representation_color_space() const {
|
| + base::AutoLock lock(mutex_);
|
| return default_representation_color_space_;
|
| }
|
| #endif // defined(OS_MACOSX) && !defined(OS_IOS)
|
|
|
| private:
|
| - friend class base::RefCounted<ImageStorage>;
|
| + friend class base::RefCountedThreadSafe<ImageStorage>;
|
|
|
| ~ImageStorage() {}
|
|
|
| @@ -340,14 +371,19 @@ class ImageStorage : public base::RefCounted<ImageStorage> {
|
| // NSImage. This field exists to compensate for PNGCodec not writing or
|
| // reading colorspace ancillary chunks. (sRGB, iCCP).
|
| // Not owned.
|
| + // Must hold |mutex_| when accessing.
|
| CGColorSpaceRef default_representation_color_space_;
|
| #endif // defined(OS_MACOSX) && !defined(OS_IOS)
|
|
|
| // All the representations of an Image. Size will always be at least one, with
|
| // more for any converted representations.
|
| - gfx::Image::RepresentationMap representations_;
|
| + // Must hold |mutex_| when accessing.
|
| + RepresentationMap representations_;
|
|
|
| - STLValueDeleter<Image::RepresentationMap> representations_deleter_;
|
| + STLValueDeleter<RepresentationMap> representations_deleter_;
|
| +
|
| + // Lock for mutable fields of this object.
|
| + mutable base::Lock mutex_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ImageStorage);
|
| };
|
| @@ -652,14 +688,14 @@ NSImage* Image::CopyNSImage() const {
|
| #endif
|
|
|
| bool Image::HasRepresentation(RepresentationType type) const {
|
| - return storage_.get() && storage_->representations().count(type) != 0;
|
| + return storage_.get() && storage_->has_representation(type);
|
| }
|
|
|
| size_t Image::RepresentationCount() const {
|
| if (!storage_.get())
|
| return 0;
|
|
|
| - return storage_->representations().size();
|
| + return storage_->representation_count();
|
| }
|
|
|
| bool Image::IsEmpty() const {
|
| @@ -707,17 +743,15 @@ Image::RepresentationType Image::DefaultRepresentationType() const {
|
| internal::ImageRep* Image::GetRepresentation(
|
| RepresentationType rep_type, bool must_exist) const {
|
| CHECK(storage_.get());
|
| - RepresentationMap::iterator it = storage_->representations().find(rep_type);
|
| - if (it == storage_->representations().end()) {
|
| - CHECK(!must_exist);
|
| - return NULL;
|
| - }
|
| - return it->second;
|
| + internal::ImageRep* representation = storage_->get_representation(rep_type);
|
| + if (must_exist)
|
| + CHECK(representation);
|
| + return representation;
|
| }
|
|
|
| void Image::AddRepresentation(internal::ImageRep* rep) const {
|
| CHECK(storage_.get());
|
| - storage_->representations().insert(std::make_pair(rep->type(), rep));
|
| + storage_->add_representation(rep);
|
| }
|
|
|
| } // namespace gfx
|
|
|