Chromium Code Reviews| 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 23 matching lines...) Expand all Loading... | |
| 34 } | 34 } |
| 35 | 35 |
| 36 std::vector<float>* g_supported_scales = NULL; | 36 std::vector<float>* g_supported_scales = NULL; |
| 37 | 37 |
| 38 // The difference to fall back to the smaller scale factor rather than the | 38 // The difference to fall back to the smaller scale factor rather than the |
| 39 // larger one. For example, assume 1.20 is requested but only 1.0 and 2.0 are | 39 // larger one. For example, assume 1.20 is requested but only 1.0 and 2.0 are |
| 40 // supported. In that case, not fall back to 2.0 but 1.0, and then expand | 40 // supported. In that case, not fall back to 2.0 but 1.0, and then expand |
| 41 // the image to 1.25. | 41 // the image to 1.25. |
| 42 const float kFallbackToSmallerScaleDiff = 0.20f; | 42 const float kFallbackToSmallerScaleDiff = 0.20f; |
| 43 | 43 |
| 44 // Maps to the closest supported scale. Returns an exact match, a smaller | |
| 45 // scale within 0.2 units, the nearest larger scale, or the min/max | |
| 46 // supported scale. | |
| 47 float MapToSupportedScale(float scale) { | |
| 48 for (float supported_scale : *g_supported_scales) { | |
| 49 if (supported_scale + kFallbackToSmallerScaleDiff >= scale) | |
| 50 return supported_scale; | |
| 51 } | |
| 52 return g_supported_scales->back(); | |
| 53 } | |
| 54 | |
| 44 } // namespace | 55 } // namespace |
| 45 | 56 |
| 46 namespace internal { | 57 namespace internal { |
| 47 namespace { | 58 namespace { |
| 48 | 59 |
| 49 ImageSkiaRep ScaleImageSkiaRep(const ImageSkiaRep& rep, float target_scale) { | 60 ImageSkiaRep ScaleImageSkiaRep(const ImageSkiaRep& rep, float target_scale) { |
| 50 if (rep.is_null() || rep.scale() == target_scale) | 61 if (rep.is_null() || rep.scale() == target_scale) |
| 51 return rep; | 62 return rep; |
| 52 | 63 |
| 53 gfx::Size scaled_size = | 64 gfx::Size scaled_size = |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 smallest_diff = diff; | 223 smallest_diff = diff; |
| 213 } | 224 } |
| 214 } | 225 } |
| 215 | 226 |
| 216 if (fetch_new_image && source_.get()) { | 227 if (fetch_new_image && source_.get()) { |
| 217 DCHECK(CalledOnValidThread()) | 228 DCHECK(CalledOnValidThread()) |
| 218 << "An ImageSkia with the source must be accessed by the same thread."; | 229 << "An ImageSkia with the source must be accessed by the same thread."; |
| 219 | 230 |
| 220 ImageSkiaRep image; | 231 ImageSkiaRep image; |
| 221 float resource_scale = scale; | 232 float resource_scale = scale; |
| 222 if (!HasRepresentationAtAllScales() && g_supported_scales) { | 233 if (!HasRepresentationAtAllScales() && g_supported_scales) |
| 223 if (g_supported_scales->back() <= scale) { | 234 resource_scale = MapToSupportedScale(scale); |
| 224 resource_scale = g_supported_scales->back(); | |
| 225 } else { | |
| 226 for (size_t i = 0; i < g_supported_scales->size(); ++i) { | |
| 227 if ((*g_supported_scales)[i] + kFallbackToSmallerScaleDiff >= scale) { | |
| 228 resource_scale = (*g_supported_scales)[i]; | |
| 229 break; | |
| 230 } | |
| 231 } | |
| 232 } | |
| 233 } | |
| 234 if (scale != resource_scale) { | 235 if (scale != resource_scale) { |
| 235 std::vector<ImageSkiaRep>::iterator iter = | 236 std::vector<ImageSkiaRep>::iterator iter = |
| 236 FindRepresentation(resource_scale, fetch_new_image); | 237 FindRepresentation(resource_scale, fetch_new_image); |
| 237 CHECK(iter != image_reps_.end()); | 238 CHECK(iter != image_reps_.end()); |
| 238 image = iter->unscaled() ? (*iter) : ScaleImageSkiaRep(*iter, scale); | 239 image = iter->unscaled() ? (*iter) : ScaleImageSkiaRep(*iter, scale); |
| 239 } else { | 240 } else { |
| 240 image = source_->GetImageForScale(scale); | 241 image = source_->GetImageForScale(scale); |
| 241 // Image may be missing for the specified scale in some cases, such like | 242 // Image may be missing for the specified scale in some cases, such like |
| 242 // looking up 2x resources but the 2x resource pack is missing. Fall back | 243 // looking up 2x resources but the 2x resource pack is missing. Fall back |
| 243 // to 1x and re-scale it. | 244 // to 1x and re-scale it. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 // Don't check ReadOnly because the source may generate images | 475 // Don't check ReadOnly because the source may generate images |
| 475 // even for read only ImageSkia. Concurrent access will be protected | 476 // even for read only ImageSkia. Concurrent access will be protected |
| 476 // by |DCHECK(CalledOnValidThread())| in FindRepresentation. | 477 // by |DCHECK(CalledOnValidThread())| in FindRepresentation. |
| 477 if (storage_.get() && storage_->has_source()) { | 478 if (storage_.get() && storage_->has_source()) { |
| 478 for (std::vector<float>::const_iterator it = g_supported_scales->begin(); | 479 for (std::vector<float>::const_iterator it = g_supported_scales->begin(); |
| 479 it != g_supported_scales->end(); ++it) | 480 it != g_supported_scales->end(); ++it) |
| 480 storage_->FindRepresentation(*it, true); | 481 storage_->FindRepresentation(*it, true); |
| 481 } | 482 } |
| 482 } | 483 } |
| 483 | 484 |
| 485 void ImageSkia::RemoveUnsupportedRepresentationsForScale(float scale) { | |
| 486 std::vector<float> scales_to_remove; | |
|
oshima
2017/05/26 20:01:05
image reps returns the vector by value, so you can
khmel
2017/05/26 20:13:55
Good point, done.
| |
| 487 for (const ImageSkiaRep& image_rep_to_test : image_reps()) { | |
| 488 const float test_scale = image_rep_to_test.scale(); | |
| 489 if (test_scale != scale && MapToSupportedScale(test_scale) == scale) | |
| 490 scales_to_remove.push_back(test_scale); | |
| 491 } | |
| 492 | |
| 493 for (float scale_to_remove : scales_to_remove) | |
| 494 RemoveRepresentation(scale_to_remove); | |
| 495 } | |
| 496 | |
| 484 void ImageSkia::Init(const ImageSkiaRep& image_rep) { | 497 void ImageSkia::Init(const ImageSkiaRep& image_rep) { |
| 485 // TODO(pkotwicz): The image should be null whenever image rep is null. | 498 // TODO(pkotwicz): The image should be null whenever image rep is null. |
| 486 if (image_rep.sk_bitmap().empty()) { | 499 if (image_rep.sk_bitmap().empty()) { |
| 487 storage_ = NULL; | 500 storage_ = NULL; |
| 488 return; | 501 return; |
| 489 } | 502 } |
| 490 storage_ = new internal::ImageSkiaStorage( | 503 storage_ = new internal::ImageSkiaStorage( |
| 491 NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight())); | 504 NULL, gfx::Size(image_rep.GetWidth(), image_rep.GetHeight())); |
| 492 storage_->image_reps().push_back(image_rep); | 505 storage_->image_reps().push_back(image_rep); |
| 493 } | 506 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 518 bool ImageSkia::CanModify() const { | 531 bool ImageSkia::CanModify() const { |
| 519 return !storage_.get() || storage_->CanModify(); | 532 return !storage_.get() || storage_->CanModify(); |
| 520 } | 533 } |
| 521 | 534 |
| 522 void ImageSkia::DetachStorageFromThread() { | 535 void ImageSkia::DetachStorageFromThread() { |
| 523 if (storage_.get()) | 536 if (storage_.get()) |
| 524 storage_->DetachFromThread(); | 537 storage_->DetachFromThread(); |
| 525 } | 538 } |
| 526 | 539 |
| 527 } // namespace gfx | 540 } // namespace gfx |
| OLD | NEW |