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

Side by Side Diff: ui/gfx/image/image_skia.cc

Issue 24175004: Remove dependency on ui::ScaleFactor from ui/gfx (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix new usage of scale in FastShowPickler Created 7 years, 2 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 | « ui/gfx/image/image_skia.h ('k') | ui/gfx/image/image_skia_operations.cc » ('j') | 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 "ui/gfx/image/image_skia.h" 5 #include "ui/gfx/image/image_skia.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/threading/non_thread_safe.h" 13 #include "base/threading/non_thread_safe.h"
14 #include "ui/gfx/image/image_skia_operations.h" 14 #include "ui/gfx/image/image_skia_operations.h"
15 #include "ui/gfx/image/image_skia_source.h" 15 #include "ui/gfx/image/image_skia_source.h"
16 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
17 #include "ui/gfx/size.h" 17 #include "ui/gfx/size.h"
18 #include "ui/gfx/skia_util.h" 18 #include "ui/gfx/skia_util.h"
19 19
20 namespace gfx { 20 namespace gfx {
21 namespace { 21 namespace {
22 22
23 // static 23 // static
24 gfx::ImageSkiaRep& NullImageRep() { 24 gfx::ImageSkiaRep& NullImageRep() {
25 CR_DEFINE_STATIC_LOCAL(ImageSkiaRep, null_image_rep, ()); 25 CR_DEFINE_STATIC_LOCAL(ImageSkiaRep, null_image_rep, ());
26 return null_image_rep; 26 return null_image_rep;
27 } 27 }
28 28
29 std::vector<float>* g_supported_scales = NULL;
29 } // namespace 30 } // namespace
30 31
31 namespace internal { 32 namespace internal {
32 namespace { 33 namespace {
33 34
34 class Matcher { 35 class Matcher {
35 public: 36 public:
36 explicit Matcher(ui::ScaleFactor scale_factor) : scale_factor_(scale_factor) { 37 explicit Matcher(float scale) : scale_(scale) {
37 } 38 }
38 39
39 bool operator()(const ImageSkiaRep& rep) const { 40 bool operator()(const ImageSkiaRep& rep) const {
40 return rep.scale_factor() == scale_factor_; 41 return rep.scale() == scale_;
41 } 42 }
42 43
43 private: 44 private:
44 ui::ScaleFactor scale_factor_; 45 float scale_;
45 }; 46 };
46 47
47 } // namespace 48 } // namespace
48 49
49 // A helper class such that ImageSkia can be cheaply copied. ImageSkia holds a 50 // A helper class such that ImageSkia can be cheaply copied. ImageSkia holds a
50 // refptr instance of ImageSkiaStorage, which in turn holds all of ImageSkia's 51 // refptr instance of ImageSkiaStorage, which in turn holds all of ImageSkia's
51 // information. Having both |base::RefCountedThreadSafe| and 52 // information. Having both |base::RefCountedThreadSafe| and
52 // |base::NonThreadSafe| may sounds strange but necessary to turn 53 // |base::NonThreadSafe| may sounds strange but necessary to turn
53 // the 'thread-non-safe modifiable ImageSkiaStorage' into 54 // the 'thread-non-safe modifiable ImageSkiaStorage' into
54 // the 'thread-safe read-only ImageSkiaStorage'. 55 // the 'thread-safe read-only ImageSkiaStorage'.
55 class ImageSkiaStorage : public base::RefCountedThreadSafe<ImageSkiaStorage>, 56 class ImageSkiaStorage : public base::RefCountedThreadSafe<ImageSkiaStorage>,
56 public base::NonThreadSafe { 57 public base::NonThreadSafe {
57 public: 58 public:
58 ImageSkiaStorage(ImageSkiaSource* source, const gfx::Size& size) 59 ImageSkiaStorage(ImageSkiaSource* source, const gfx::Size& size)
59 : source_(source), 60 : source_(source),
60 size_(size), 61 size_(size),
61 read_only_(false) { 62 read_only_(false) {
62 } 63 }
63 64
64 ImageSkiaStorage(ImageSkiaSource* source, ui::ScaleFactor scale_factor) 65 ImageSkiaStorage(ImageSkiaSource* source, float scale)
65 : source_(source), 66 : source_(source),
66 read_only_(false) { 67 read_only_(false) {
67 ImageSkia::ImageSkiaReps::iterator it = 68 ImageSkia::ImageSkiaReps::iterator it = FindRepresentation(scale, true);
68 FindRepresentation(scale_factor, true);
69 if (it == image_reps_.end() || it->is_null()) 69 if (it == image_reps_.end() || it->is_null())
70 source_.reset(); 70 source_.reset();
71 else 71 else
72 size_.SetSize(it->GetWidth(), it->GetHeight()); 72 size_.SetSize(it->GetWidth(), it->GetHeight());
73 } 73 }
74 74
75 bool has_source() const { return source_.get() != NULL; } 75 bool has_source() const { return source_.get() != NULL; }
76 76
77 std::vector<gfx::ImageSkiaRep>& image_reps() { return image_reps_; } 77 std::vector<gfx::ImageSkiaRep>& image_reps() { return image_reps_; }
78 78
(...skipping 17 matching lines...) Expand all
96 bool CanModify() const { 96 bool CanModify() const {
97 return !read_only_ && CalledOnValidThread(); 97 return !read_only_ && CalledOnValidThread();
98 } 98 }
99 99
100 // Checks if the current thread can safely read the storage. 100 // Checks if the current thread can safely read the storage.
101 bool CanRead() const { 101 bool CanRead() const {
102 return (read_only_ && !source_.get()) || CalledOnValidThread(); 102 return (read_only_ && !source_.get()) || CalledOnValidThread();
103 } 103 }
104 104
105 // Returns the iterator of the image rep whose density best matches 105 // Returns the iterator of the image rep whose density best matches
106 // |scale_factor|. If the image for the |scale_factor| doesn't exist 106 // |scale|. If the image for the |scale| doesn't exist in the storage and
107 // in the storage and |storage| is set, it fetches new image by calling 107 // |storage| is set, it fetches new image by calling
108 // |ImageSkiaSource::GetImageForScale|. If the source returns the 108 // |ImageSkiaSource::GetImageForScale|. If the source returns the image with
109 // image with different scale factor (if the image doesn't exist in 109 // different scale (if the image doesn't exist in resource, for example), it
110 // resource, for example), it will fallback to closest image rep. 110 // will fallback to closest image rep.
111 std::vector<ImageSkiaRep>::iterator FindRepresentation( 111 std::vector<ImageSkiaRep>::iterator FindRepresentation(
112 ui::ScaleFactor scale_factor, bool fetch_new_image) const { 112 float scale, bool fetch_new_image) const {
113 ImageSkiaStorage* non_const = const_cast<ImageSkiaStorage*>(this); 113 ImageSkiaStorage* non_const = const_cast<ImageSkiaStorage*>(this);
114 114
115 float scale = ui::GetScaleFactorScale(scale_factor);
116 ImageSkia::ImageSkiaReps::iterator closest_iter = 115 ImageSkia::ImageSkiaReps::iterator closest_iter =
117 non_const->image_reps().end(); 116 non_const->image_reps().end();
118 ImageSkia::ImageSkiaReps::iterator exact_iter = 117 ImageSkia::ImageSkiaReps::iterator exact_iter =
119 non_const->image_reps().end(); 118 non_const->image_reps().end();
120 float smallest_diff = std::numeric_limits<float>::max(); 119 float smallest_diff = std::numeric_limits<float>::max();
121 for (ImageSkia::ImageSkiaReps::iterator it = 120 for (ImageSkia::ImageSkiaReps::iterator it =
122 non_const->image_reps().begin(); 121 non_const->image_reps().begin();
123 it < image_reps_.end(); ++it) { 122 it < image_reps_.end(); ++it) {
124 if (it->GetScale() == scale) { 123 if (it->scale() == scale) {
125 // found exact match 124 // found exact match
126 fetch_new_image = false; 125 fetch_new_image = false;
127 if (it->is_null()) 126 if (it->is_null())
128 continue; 127 continue;
129 exact_iter = it; 128 exact_iter = it;
130 break; 129 break;
131 } 130 }
132 float diff = std::abs(it->GetScale() - scale); 131 float diff = std::abs(it->scale() - scale);
133 if (diff < smallest_diff && !it->is_null()) { 132 if (diff < smallest_diff && !it->is_null()) {
134 closest_iter = it; 133 closest_iter = it;
135 smallest_diff = diff; 134 smallest_diff = diff;
136 } 135 }
137 } 136 }
138 137
139 if (fetch_new_image && source_.get()) { 138 if (fetch_new_image && source_.get()) {
140 DCHECK(CalledOnValidThread()) << 139 DCHECK(CalledOnValidThread()) <<
141 "An ImageSkia with the source must be accessed by the same thread."; 140 "An ImageSkia with the source must be accessed by the same thread.";
142 141
143 ImageSkiaRep image = source_->GetImageForScale(scale_factor); 142 ImageSkiaRep image = source_->GetImageForScale(scale);
144 143
145 // If the source returned the new image, store it. 144 // If the source returned the new image, store it.
146 if (!image.is_null() && 145 if (!image.is_null() &&
147 std::find_if(image_reps_.begin(), image_reps_.end(), 146 std::find_if(image_reps_.begin(), image_reps_.end(),
148 Matcher(image.scale_factor())) == image_reps_.end()) { 147 Matcher(image.scale())) == image_reps_.end()) {
149 non_const->image_reps().push_back(image); 148 non_const->image_reps().push_back(image);
150 } 149 }
151 150
152 // If the result image's scale factor isn't same as the expected 151 // If the result image's scale isn't same as the expected scale, create
153 // scale factor, create null ImageSkiaRep with the |scale_factor| 152 // null ImageSkiaRep with the |scale| so that the next lookup will
154 // so that the next lookup will fallback to the closest scale. 153 // fallback to the closest scale.
155 if (image.is_null() || image.scale_factor() != scale_factor) { 154 if (image.is_null() || image.scale() != scale) {
156 non_const->image_reps().push_back( 155 non_const->image_reps().push_back(ImageSkiaRep(SkBitmap(), scale));
157 ImageSkiaRep(SkBitmap(), scale_factor));
158 } 156 }
159 157
160 // image_reps_ must have the exact much now, so find again. 158 // image_reps_ must have the exact much now, so find again.
161 return FindRepresentation(scale_factor, false); 159 return FindRepresentation(scale, false);
162 } 160 }
163 return exact_iter != image_reps_.end() ? exact_iter : closest_iter; 161 return exact_iter != image_reps_.end() ? exact_iter : closest_iter;
164 } 162 }
165 163
166 private: 164 private:
167 virtual ~ImageSkiaStorage() { 165 virtual ~ImageSkiaStorage() {
168 // We only care if the storage is modified by the same thread. 166 // We only care if the storage is modified by the same thread.
169 // Don't blow up even if someone else deleted the ImageSkia. 167 // Don't blow up even if someone else deleted the ImageSkia.
170 DetachFromThread(); 168 DetachFromThread();
171 } 169 }
172 170
173 // Vector of bitmaps and their associated scale factor. 171 // Vector of bitmaps and their associated scale.
174 std::vector<gfx::ImageSkiaRep> image_reps_; 172 std::vector<gfx::ImageSkiaRep> image_reps_;
175 173
176 scoped_ptr<ImageSkiaSource> source_; 174 scoped_ptr<ImageSkiaSource> source_;
177 175
178 // Size of the image in DIP. 176 // Size of the image in DIP.
179 gfx::Size size_; 177 gfx::Size size_;
180 178
181 bool read_only_; 179 bool read_only_;
182 180
183 friend class base::RefCountedThreadSafe<ImageSkiaStorage>; 181 friend class base::RefCountedThreadSafe<ImageSkiaStorage>;
184 }; 182 };
185 183
186 } // internal 184 } // internal
187 185
188 ImageSkia::ImageSkia() : storage_(NULL) { 186 ImageSkia::ImageSkia() : storage_(NULL) {
189 } 187 }
190 188
191 ImageSkia::ImageSkia(ImageSkiaSource* source, const gfx::Size& size) 189 ImageSkia::ImageSkia(ImageSkiaSource* source, const gfx::Size& size)
192 : storage_(new internal::ImageSkiaStorage(source, size)) { 190 : storage_(new internal::ImageSkiaStorage(source, size)) {
193 DCHECK(source); 191 DCHECK(source);
194 // No other thread has reference to this, so it's safe to detach the thread. 192 // No other thread has reference to this, so it's safe to detach the thread.
195 DetachStorageFromThread(); 193 DetachStorageFromThread();
196 } 194 }
197 195
198 ImageSkia::ImageSkia(ImageSkiaSource* source, ui::ScaleFactor scale_factor) 196 ImageSkia::ImageSkia(ImageSkiaSource* source, float scale)
199 : storage_(new internal::ImageSkiaStorage(source, scale_factor)) { 197 : storage_(new internal::ImageSkiaStorage(source, scale)) {
200 DCHECK(source); 198 DCHECK(source);
201 if (!storage_->has_source()) 199 if (!storage_->has_source())
202 storage_ = NULL; 200 storage_ = NULL;
203 // No other thread has reference to this, so it's safe to detach the thread. 201 // No other thread has reference to this, so it's safe to detach the thread.
204 DetachStorageFromThread(); 202 DetachStorageFromThread();
205 } 203 }
206 204
207 ImageSkia::ImageSkia(const ImageSkiaRep& image_rep) { 205 ImageSkia::ImageSkia(const ImageSkiaRep& image_rep) {
208 Init(image_rep); 206 Init(image_rep);
209 // No other thread has reference to this, so it's safe to detach the thread. 207 // No other thread has reference to this, so it's safe to detach the thread.
210 DetachStorageFromThread(); 208 DetachStorageFromThread();
211 } 209 }
212 210
213 ImageSkia::ImageSkia(const ImageSkia& other) : storage_(other.storage_) { 211 ImageSkia::ImageSkia(const ImageSkia& other) : storage_(other.storage_) {
214 } 212 }
215 213
216 ImageSkia& ImageSkia::operator=(const ImageSkia& other) { 214 ImageSkia& ImageSkia::operator=(const ImageSkia& other) {
217 storage_ = other.storage_; 215 storage_ = other.storage_;
218 return *this; 216 return *this;
219 } 217 }
220 218
221 ImageSkia::~ImageSkia() { 219 ImageSkia::~ImageSkia() {
222 } 220 }
223 221
224 // static 222 // static
223 void ImageSkia::SetSupportedScales(const std::vector<float>& supported_scales) {
224 if (g_supported_scales != NULL)
225 delete g_supported_scales;
226 g_supported_scales = new std::vector<float>(supported_scales);
227 std::sort(g_supported_scales->begin(), g_supported_scales->end());
228 }
229
230 // static
231 const std::vector<float>& ImageSkia::GetSupportedScales() {
232 DCHECK(g_supported_scales != NULL);
233 return *g_supported_scales;
234 }
235
236 // static
237 float ImageSkia::GetMaxSupportedScale() {
238 return g_supported_scales->back();
239 }
240
241 // static
225 ImageSkia ImageSkia::CreateFrom1xBitmap(const SkBitmap& bitmap) { 242 ImageSkia ImageSkia::CreateFrom1xBitmap(const SkBitmap& bitmap) {
226 return ImageSkia(ImageSkiaRep(bitmap, ui::SCALE_FACTOR_100P)); 243 return ImageSkia(ImageSkiaRep(bitmap, 1.0f));
227 } 244 }
228 245
229 scoped_ptr<ImageSkia> ImageSkia::DeepCopy() const { 246 scoped_ptr<ImageSkia> ImageSkia::DeepCopy() const {
230 ImageSkia* copy = new ImageSkia; 247 ImageSkia* copy = new ImageSkia;
231 if (isNull()) 248 if (isNull())
232 return scoped_ptr<ImageSkia>(copy); 249 return scoped_ptr<ImageSkia>(copy);
233 250
234 CHECK(CanRead()); 251 CHECK(CanRead());
235 252
236 std::vector<gfx::ImageSkiaRep>& reps = storage_->image_reps(); 253 std::vector<gfx::ImageSkiaRep>& reps = storage_->image_reps();
(...skipping 10 matching lines...) Expand all
247 264
248 bool ImageSkia::BackedBySameObjectAs(const gfx::ImageSkia& other) const { 265 bool ImageSkia::BackedBySameObjectAs(const gfx::ImageSkia& other) const {
249 return storage_.get() == other.storage_.get(); 266 return storage_.get() == other.storage_.get();
250 } 267 }
251 268
252 void ImageSkia::AddRepresentation(const ImageSkiaRep& image_rep) { 269 void ImageSkia::AddRepresentation(const ImageSkiaRep& image_rep) {
253 DCHECK(!image_rep.is_null()); 270 DCHECK(!image_rep.is_null());
254 271
255 // TODO(oshima): This method should be called |SetRepresentation| 272 // TODO(oshima): This method should be called |SetRepresentation|
256 // and replace the existing rep if there is already one with the 273 // and replace the existing rep if there is already one with the
257 // same scale factor so that we can guarantee that a ImageSkia 274 // same scale so that we can guarantee that a ImageSkia instance contains only
258 // instance contians only one image rep per scale factor. This is 275 // one image rep per scale. This is not possible now as ImageLoader currently
259 // not possible now as ImageLoader currently stores need 276 // stores need this feature, but this needs to be fixed.
260 // this feature, but this needs to be fixed.
261 if (isNull()) { 277 if (isNull()) {
262 Init(image_rep); 278 Init(image_rep);
263 } else { 279 } else {
264 CHECK(CanModify()); 280 CHECK(CanModify());
265 storage_->image_reps().push_back(image_rep); 281 storage_->image_reps().push_back(image_rep);
266 } 282 }
267 } 283 }
268 284
269 void ImageSkia::RemoveRepresentation(ui::ScaleFactor scale_factor) { 285 void ImageSkia::RemoveRepresentation(float scale) {
270 if (isNull()) 286 if (isNull())
271 return; 287 return;
272 CHECK(CanModify()); 288 CHECK(CanModify());
273 289
274 ImageSkiaReps& image_reps = storage_->image_reps(); 290 ImageSkiaReps& image_reps = storage_->image_reps();
275 ImageSkiaReps::iterator it = 291 ImageSkiaReps::iterator it =
276 storage_->FindRepresentation(scale_factor, false); 292 storage_->FindRepresentation(scale, false);
277 if (it != image_reps.end() && it->scale_factor() == scale_factor) 293 if (it != image_reps.end() && it->scale() == scale)
278 image_reps.erase(it); 294 image_reps.erase(it);
279 } 295 }
280 296
281 bool ImageSkia::HasRepresentation(ui::ScaleFactor scale_factor) const { 297 bool ImageSkia::HasRepresentation(float scale) const {
282 if (isNull()) 298 if (isNull())
283 return false; 299 return false;
284 CHECK(CanRead()); 300 CHECK(CanRead());
285 301
286 ImageSkiaReps::iterator it = 302 ImageSkiaReps::iterator it = storage_->FindRepresentation(scale, false);
287 storage_->FindRepresentation(scale_factor, false); 303 return (it != storage_->image_reps().end() && it->scale() == scale);
288 return (it != storage_->image_reps().end() &&
289 it->scale_factor() == scale_factor);
290 } 304 }
291 305
292 const ImageSkiaRep& ImageSkia::GetRepresentation( 306 const ImageSkiaRep& ImageSkia::GetRepresentation(float scale) const {
293 ui::ScaleFactor scale_factor) const {
294 if (isNull()) 307 if (isNull())
295 return NullImageRep(); 308 return NullImageRep();
296 309
297 CHECK(CanRead()); 310 CHECK(CanRead());
298 311
299 ImageSkiaReps::iterator it = storage_->FindRepresentation(scale_factor, true); 312 ImageSkiaReps::iterator it = storage_->FindRepresentation(scale, true);
300 if (it == storage_->image_reps().end()) 313 if (it == storage_->image_reps().end())
301 return NullImageRep(); 314 return NullImageRep();
302 315
303 return *it; 316 return *it;
304 } 317 }
305 318
306 void ImageSkia::SetReadOnly() { 319 void ImageSkia::SetReadOnly() {
307 CHECK(storage_.get()); 320 CHECK(storage_.get());
308 storage_->SetReadOnly(); 321 storage_->SetReadOnly();
309 DetachStorageFromThread(); 322 DetachStorageFromThread();
310 } 323 }
311 324
312 void ImageSkia::MakeThreadSafe() { 325 void ImageSkia::MakeThreadSafe() {
313 CHECK(storage_.get()); 326 CHECK(storage_.get());
314 EnsureRepsForSupportedScaleFactors(); 327 EnsureRepsForSupportedScales();
315 // Delete source as we no longer needs it. 328 // Delete source as we no longer needs it.
316 if (storage_.get()) 329 if (storage_.get())
317 storage_->DeleteSource(); 330 storage_->DeleteSource();
318 storage_->SetReadOnly(); 331 storage_->SetReadOnly();
319 CHECK(IsThreadSafe()); 332 CHECK(IsThreadSafe());
320 } 333 }
321 334
322 bool ImageSkia::IsThreadSafe() const { 335 bool ImageSkia::IsThreadSafe() const {
323 return !storage_.get() || (storage_->read_only() && !storage_->has_source()); 336 return !storage_.get() || (storage_->read_only() && !storage_->has_source());
324 } 337 }
(...skipping 22 matching lines...) Expand all
347 ImageSkiaReps image_reps; 360 ImageSkiaReps image_reps;
348 for (ImageSkiaReps::iterator it = internal_image_reps.begin(); 361 for (ImageSkiaReps::iterator it = internal_image_reps.begin();
349 it != internal_image_reps.end(); ++it) { 362 it != internal_image_reps.end(); ++it) {
350 if (!it->is_null()) 363 if (!it->is_null())
351 image_reps.push_back(*it); 364 image_reps.push_back(*it);
352 } 365 }
353 366
354 return image_reps; 367 return image_reps;
355 } 368 }
356 369
357 void ImageSkia::EnsureRepsForSupportedScaleFactors() const { 370 void ImageSkia::EnsureRepsForSupportedScales() const {
371 DCHECK(g_supported_scales != NULL);
358 // Don't check ReadOnly because the source may generate images 372 // Don't check ReadOnly because the source may generate images
359 // even for read only ImageSkia. Concurrent access will be protected 373 // even for read only ImageSkia. Concurrent access will be protected
360 // by |DCHECK(CalledOnValidThread())| in FindRepresentation. 374 // by |DCHECK(CalledOnValidThread())| in FindRepresentation.
361 if (storage_.get() && storage_->has_source()) { 375 if (storage_.get() && storage_->has_source()) {
362 std::vector<ui::ScaleFactor> supported_scale_factors = 376 for (std::vector<float>::const_iterator it = g_supported_scales->begin();
363 ui::GetSupportedScaleFactors(); 377 it != g_supported_scales->end(); ++it)
364 for (size_t i = 0; i < supported_scale_factors.size(); ++i) 378 storage_->FindRepresentation(*it, true);
365 storage_->FindRepresentation(supported_scale_factors[i], true);
366 } 379 }
367 } 380 }
368 381
369 void ImageSkia::Init(const ImageSkiaRep& image_rep) { 382 void ImageSkia::Init(const ImageSkiaRep& image_rep) {
370 // TODO(pkotwicz): The image should be null whenever image rep is null. 383 // TODO(pkotwicz): The image should be null whenever image rep is null.
371 if (image_rep.sk_bitmap().empty()) { 384 if (image_rep.sk_bitmap().empty()) {
372 storage_ = NULL; 385 storage_ = NULL;
373 return; 386 return;
374 } 387 }
375 storage_ = new internal::ImageSkiaStorage( 388 storage_ = new internal::ImageSkiaStorage(
376 NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight())); 389 NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight()));
377 storage_->image_reps().push_back(image_rep); 390 storage_->image_reps().push_back(image_rep);
378 } 391 }
379 392
380 SkBitmap& ImageSkia::GetBitmap() const { 393 SkBitmap& ImageSkia::GetBitmap() const {
381 if (isNull()) { 394 if (isNull()) {
382 // Callers expect a ImageSkiaRep even if it is |isNull()|. 395 // Callers expect a ImageSkiaRep even if it is |isNull()|.
383 // TODO(pkotwicz): Fix this. 396 // TODO(pkotwicz): Fix this.
384 return NullImageRep().mutable_sk_bitmap(); 397 return NullImageRep().mutable_sk_bitmap();
385 } 398 }
386 399
387 // TODO(oshima): This made a few tests flaky on Windows. 400 // TODO(oshima): This made a few tests flaky on Windows.
388 // Fix the root cause and re-enable this. crbug.com/145623. 401 // Fix the root cause and re-enable this. crbug.com/145623.
389 #if !defined(OS_WIN) 402 #if !defined(OS_WIN)
390 CHECK(CanRead()); 403 CHECK(CanRead());
391 #endif 404 #endif
392 405
393 ImageSkiaReps::iterator it = 406 ImageSkiaReps::iterator it = storage_->FindRepresentation(1.0f, true);
394 storage_->FindRepresentation(ui::SCALE_FACTOR_100P, true);
395 if (it != storage_->image_reps().end()) 407 if (it != storage_->image_reps().end())
396 return it->mutable_sk_bitmap(); 408 return it->mutable_sk_bitmap();
397 return NullImageRep().mutable_sk_bitmap(); 409 return NullImageRep().mutable_sk_bitmap();
398 } 410 }
399 411
400 bool ImageSkia::CanRead() const { 412 bool ImageSkia::CanRead() const {
401 return !storage_.get() || storage_->CanRead(); 413 return !storage_.get() || storage_->CanRead();
402 } 414 }
403 415
404 bool ImageSkia::CanModify() const { 416 bool ImageSkia::CanModify() const {
405 return !storage_.get() || storage_->CanModify(); 417 return !storage_.get() || storage_->CanModify();
406 } 418 }
407 419
408 void ImageSkia::DetachStorageFromThread() { 420 void ImageSkia::DetachStorageFromThread() {
409 if (storage_.get()) 421 if (storage_.get())
410 storage_->DetachFromThread(); 422 storage_->DetachFromThread();
411 } 423 }
412 424
413 } // namespace gfx 425 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/image/image_skia.h ('k') | ui/gfx/image/image_skia_operations.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698