OLD | NEW |
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/gfx/image/image_skia.h" | 5 #include "ui/gfx/image/image_skia.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 bool CanModify() const; | 85 bool CanModify() const; |
86 | 86 |
87 // Checks if the current thread can safely read the storage. | 87 // Checks if the current thread can safely read the storage. |
88 bool CanRead() const; | 88 bool CanRead() const; |
89 | 89 |
90 // Add a new representation. This checks if the scale of the added image | 90 // Add a new representation. This checks if the scale of the added image |
91 // is not 1.0f, and mark the existing rep as scaled to make | 91 // is not 1.0f, and mark the existing rep as scaled to make |
92 // the image high DPI aware. | 92 // the image high DPI aware. |
93 void AddRepresentation(const ImageSkiaRep& image); | 93 void AddRepresentation(const ImageSkiaRep& image); |
94 | 94 |
| 95 // Returns whether the underlying image source can provide a representation at |
| 96 // any scale. In this case, the caller is guaranteed that |
| 97 // FindRepresentation(..., true) will always succeed. |
| 98 bool HasRepresentationAtAllScales() const; |
| 99 |
95 // Returns the iterator of the image rep whose density best matches | 100 // Returns the iterator of the image rep whose density best matches |
96 // |scale|. If the image for the |scale| doesn't exist in the storage and | 101 // |scale|. If the image for the |scale| doesn't exist in the storage and |
97 // |storage| is set, it fetches new image by calling | 102 // |storage| is set, it fetches new image by calling |
98 // |ImageSkiaSource::GetImageForScale|. There are two modes to deal with | 103 // |ImageSkiaSource::GetImageForScale|. There are two modes to deal with |
99 // arbitrary scale factors. | 104 // arbitrary scale factors. |
100 // 1: Invoke GetImageForScale with requested scale and if the source | 105 // 1: Invoke GetImageForScale with requested scale and if the source |
101 // returns the image with different scale (if the image doesn't exist in | 106 // returns the image with different scale (if the image doesn't exist in |
102 // resource, for example), it will fallback to closest image rep. | 107 // resource, for example), it will fallback to closest image rep. |
103 // 2: Invoke GetImageForScale with the closest known scale to the requested | 108 // 2: Invoke GetImageForScale with the closest known scale to the requested |
104 // one and rescale the image. | 109 // one and rescale the image. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 | 158 |
154 bool ImageSkiaStorage::CanModify() const { | 159 bool ImageSkiaStorage::CanModify() const { |
155 return !read_only_ && CalledOnValidThread(); | 160 return !read_only_ && CalledOnValidThread(); |
156 } | 161 } |
157 | 162 |
158 bool ImageSkiaStorage::CanRead() const { | 163 bool ImageSkiaStorage::CanRead() const { |
159 return (read_only_ && !source_) || CalledOnValidThread(); | 164 return (read_only_ && !source_) || CalledOnValidThread(); |
160 } | 165 } |
161 | 166 |
162 void ImageSkiaStorage::AddRepresentation(const ImageSkiaRep& image) { | 167 void ImageSkiaStorage::AddRepresentation(const ImageSkiaRep& image) { |
| 168 // Explicitly adding a representation makes no sense for images that |
| 169 // inherently have representations at all scales already. |
| 170 DCHECK(!HasRepresentationAtAllScales()); |
| 171 |
163 if (image.scale() != 1.0f) { | 172 if (image.scale() != 1.0f) { |
164 for (ImageSkia::ImageSkiaReps::iterator it = image_reps_.begin(); | 173 for (ImageSkia::ImageSkiaReps::iterator it = image_reps_.begin(); |
165 it < image_reps_.end(); ++it) { | 174 it < image_reps_.end(); ++it) { |
166 if (it->unscaled()) { | 175 if (it->unscaled()) { |
167 DCHECK_EQ(1.0f, it->scale()); | 176 DCHECK_EQ(1.0f, it->scale()); |
168 it->SetScaled(); | 177 it->SetScaled(); |
169 break; | 178 break; |
170 } | 179 } |
171 } | 180 } |
172 } | 181 } |
173 image_reps_.push_back(image); | 182 image_reps_.push_back(image); |
174 } | 183 } |
175 | 184 |
| 185 bool ImageSkiaStorage::HasRepresentationAtAllScales() const { |
| 186 return source_ && source_->HasRepresentationAtAllScales(); |
| 187 } |
| 188 |
176 std::vector<ImageSkiaRep>::iterator ImageSkiaStorage::FindRepresentation( | 189 std::vector<ImageSkiaRep>::iterator ImageSkiaStorage::FindRepresentation( |
177 float scale, | 190 float scale, |
178 bool fetch_new_image) const { | 191 bool fetch_new_image) const { |
179 ImageSkiaStorage* non_const = const_cast<ImageSkiaStorage*>(this); | 192 ImageSkiaStorage* non_const = const_cast<ImageSkiaStorage*>(this); |
180 | 193 |
181 ImageSkia::ImageSkiaReps::iterator closest_iter = | 194 ImageSkia::ImageSkiaReps::iterator closest_iter = |
182 non_const->image_reps().end(); | 195 non_const->image_reps().end(); |
183 ImageSkia::ImageSkiaReps::iterator exact_iter = non_const->image_reps().end(); | 196 ImageSkia::ImageSkiaReps::iterator exact_iter = non_const->image_reps().end(); |
184 float smallest_diff = std::numeric_limits<float>::max(); | 197 float smallest_diff = std::numeric_limits<float>::max(); |
185 for (ImageSkia::ImageSkiaReps::iterator it = non_const->image_reps().begin(); | 198 for (ImageSkia::ImageSkiaReps::iterator it = non_const->image_reps().begin(); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 storage_->FindRepresentation(scale, false); | 385 storage_->FindRepresentation(scale, false); |
373 if (it != image_reps.end() && it->scale() == scale) | 386 if (it != image_reps.end() && it->scale() == scale) |
374 image_reps.erase(it); | 387 image_reps.erase(it); |
375 } | 388 } |
376 | 389 |
377 bool ImageSkia::HasRepresentation(float scale) const { | 390 bool ImageSkia::HasRepresentation(float scale) const { |
378 if (isNull()) | 391 if (isNull()) |
379 return false; | 392 return false; |
380 CHECK(CanRead()); | 393 CHECK(CanRead()); |
381 | 394 |
| 395 // This check is not only faster than FindRepresentation(), it's important for |
| 396 // getting the right answer in cases of image types that are not based on |
| 397 // discrete preset underlying representations, which otherwise might report |
| 398 // "false" for this if GetRepresentation() has not yet been called for this |
| 399 // |scale|. |
| 400 if (storage_->HasRepresentationAtAllScales()) |
| 401 return true; |
| 402 |
382 ImageSkiaReps::iterator it = storage_->FindRepresentation(scale, false); | 403 ImageSkiaReps::iterator it = storage_->FindRepresentation(scale, false); |
383 return (it != storage_->image_reps().end() && it->scale() == scale); | 404 return (it != storage_->image_reps().end() && it->scale() == scale); |
384 } | 405 } |
385 | 406 |
386 const ImageSkiaRep& ImageSkia::GetRepresentation(float scale) const { | 407 const ImageSkiaRep& ImageSkia::GetRepresentation(float scale) const { |
387 if (isNull()) | 408 if (isNull()) |
388 return NullImageRep(); | 409 return NullImageRep(); |
389 | 410 |
390 CHECK(CanRead()); | 411 CHECK(CanRead()); |
391 | 412 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 bool ImageSkia::CanModify() const { | 517 bool ImageSkia::CanModify() const { |
497 return !storage_.get() || storage_->CanModify(); | 518 return !storage_.get() || storage_->CanModify(); |
498 } | 519 } |
499 | 520 |
500 void ImageSkia::DetachStorageFromThread() { | 521 void ImageSkia::DetachStorageFromThread() { |
501 if (storage_.get()) | 522 if (storage_.get()) |
502 storage_->DetachFromThread(); | 523 storage_->DetachFromThread(); |
503 } | 524 } |
504 | 525 |
505 } // namespace gfx | 526 } // namespace gfx |
OLD | NEW |