| Index: ui/gfx/image/image_skia.cc
|
| diff --git a/ui/gfx/image/image_skia.cc b/ui/gfx/image/image_skia.cc
|
| index 65f2d48741233911458e18986c57f6ea12c4d56c..1816921a38814b8859a5708daedf6ba368903f0a 100644
|
| --- a/ui/gfx/image/image_skia.cc
|
| +++ b/ui/gfx/image/image_skia.cc
|
| @@ -10,6 +10,7 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/threading/non_thread_safe.h"
|
| #include "ui/gfx/image/image_skia_operations.h"
|
| #include "ui/gfx/image/image_skia_source.h"
|
| #include "ui/gfx/rect.h"
|
| @@ -48,11 +49,15 @@ class Matcher {
|
| // A helper class such that ImageSkia can be cheaply copied. ImageSkia holds a
|
| // refptr instance of ImageSkiaStorage, which in turn holds all of ImageSkia's
|
| // information.
|
| -class ImageSkiaStorage : public base::RefCounted<ImageSkiaStorage> {
|
| +class ImageSkiaStorage : public base::RefCounted<ImageSkiaStorage>,
|
| + public base::NonThreadSafe {
|
| public:
|
| ImageSkiaStorage(ImageSkiaSource* source, const gfx::Size& size)
|
| : source_(source),
|
| size_(size) {
|
| + // We only care if the storage is modified by the same thread.
|
| + // Don't blow up even if someone else created/deleted the ImageSkia.
|
| + base::NonThreadSafe::DetachFromThread();
|
| }
|
|
|
| bool has_source() const { return source_.get() != NULL; }
|
| @@ -61,6 +66,17 @@ class ImageSkiaStorage : public base::RefCounted<ImageSkiaStorage> {
|
|
|
| const gfx::Size& size() const { return size_; }
|
|
|
| + // A public method to call base::NonThreadSafeImpl::DetachFromThread
|
| + // which is protected. See base/threading/non_thread_safe_impl.h
|
| + // for more details.
|
| + void DetachFromThread() {
|
| + base::NonThreadSafe::DetachFromThread();
|
| + }
|
| +
|
| + void DeleteSource() {
|
| + source_.reset();
|
| + }
|
| +
|
| // Returns the iterator of the image rep whose density best matches
|
| // |scale_factor|. If the image for the |scale_factor| doesn't exist
|
| // in the storage and |storage| is set, it fetches new image by calling
|
| @@ -96,6 +112,10 @@ class ImageSkiaStorage : public base::RefCounted<ImageSkiaStorage> {
|
| }
|
|
|
| if (fetch_new_image && source_.get()) {
|
| + DCHECK(CalledOnValidThread()) <<
|
| + "More than one thread is tring to access ImageSkia which has "
|
| + "ImageSkiaSource. This is thread unsafe operation and not allowed";
|
| +
|
| ImageSkiaRep image = source_->GetImageForScale(scale_factor);
|
|
|
| // If the source returned the new image, store it.
|
| @@ -120,7 +140,8 @@ class ImageSkiaStorage : public base::RefCounted<ImageSkiaStorage> {
|
| }
|
|
|
| private:
|
| - ~ImageSkiaStorage() {
|
| + virtual ~ImageSkiaStorage() {
|
| + DetachFromThread();
|
| }
|
|
|
| // Vector of bitmaps and their associated scale factor.
|
| @@ -223,14 +244,7 @@ std::vector<ImageSkiaRep> ImageSkia::GetRepresentations() const {
|
| if (!storage_->has_source())
|
| return image_reps();
|
|
|
| - // Attempt to generate image reps for as many scale factors supported by
|
| - // this platform as possible.
|
| - // Do not build return array here because the mapping from scale factor to
|
| - // image rep is one to many in some cases.
|
| - std::vector<ui::ScaleFactor> supported_scale_factors =
|
| - ui::GetSupportedScaleFactors();
|
| - for (size_t i = 0; i < supported_scale_factors.size(); ++i)
|
| - storage_->FindRepresentation(supported_scale_factors[i], true);
|
| + EnsureRepsForSupportedScaleFactors();
|
|
|
| return image_reps();
|
| }
|
| @@ -266,6 +280,20 @@ std::vector<ImageSkiaRep> ImageSkia::image_reps() const {
|
| return image_reps;
|
| }
|
|
|
| +void ImageSkia::DeleteSource() {
|
| + if (storage_)
|
| + storage_->DeleteSource();
|
| +}
|
| +
|
| +void ImageSkia::EnsureRepsForSupportedScaleFactors() const {
|
| + if (storage_ && storage_->has_source()) {
|
| + std::vector<ui::ScaleFactor> supported_scale_factors =
|
| + ui::GetSupportedScaleFactors();
|
| + for (size_t i = 0; i < supported_scale_factors.size(); ++i)
|
| + storage_->FindRepresentation(supported_scale_factors[i], true);
|
| + }
|
| +}
|
| +
|
| void ImageSkia::Init(const ImageSkiaRep& image_rep) {
|
| // TODO(pkotwicz): The image should be null whenever image rep is null.
|
| if (image_rep.sk_bitmap().empty()) {
|
|
|