Home | History | Annotate | Download | only in image
      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
      3 // found in the LICENSE file.
      4 
      5 #include "ui/gfx/image/image_skia.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/logging.h"
      9 #include "base/threading/simple_thread.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "third_party/skia/include/core/SkBitmap.h"
     12 #include "ui/gfx/image/image_skia_rep.h"
     13 #include "ui/gfx/image/image_skia_source.h"
     14 #include "ui/gfx/size.h"
     15 #include "ui/gfx/switches.h"
     16 
     17 // Duplicated from base/threading/non_thread_safe.h so that we can be
     18 // good citizens there and undef the macro.
     19 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
     20 #define ENABLE_NON_THREAD_SAFE 1
     21 #else
     22 #define ENABLE_NON_THREAD_SAFE 0
     23 #endif
     24 
     25 namespace gfx {
     26 
     27 namespace {
     28 
     29 class FixedSource : public ImageSkiaSource {
     30  public:
     31   FixedSource(const ImageSkiaRep& image) : image_(image) {}
     32 
     33   virtual ~FixedSource() {
     34   }
     35 
     36   virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
     37     return image_;
     38   }
     39 
     40  private:
     41   ImageSkiaRep image_;
     42 
     43   DISALLOW_COPY_AND_ASSIGN(FixedSource);
     44 };
     45 
     46 class DynamicSource : public ImageSkiaSource {
     47  public:
     48   DynamicSource(const gfx::Size& size)
     49       : size_(size),
     50         last_requested_scale_(0.0f) {}
     51 
     52   virtual ~DynamicSource() {
     53   }
     54 
     55   virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
     56     last_requested_scale_ = scale;
     57     return gfx::ImageSkiaRep(size_, scale);
     58   }
     59 
     60   float GetLastRequestedScaleAndReset() {
     61     float result = last_requested_scale_;
     62     last_requested_scale_ = 0.0f;
     63     return result;
     64   }
     65 
     66  private:
     67   gfx::Size size_;
     68   float last_requested_scale_;
     69 
     70   DISALLOW_COPY_AND_ASSIGN(DynamicSource);
     71 };
     72 
     73 class NullSource: public ImageSkiaSource {
     74  public:
     75   NullSource() {
     76   }
     77 
     78   virtual ~NullSource() {
     79   }
     80 
     81   virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
     82     return gfx::ImageSkiaRep();
     83   }
     84 
     85  private:
     86   DISALLOW_COPY_AND_ASSIGN(NullSource);
     87 };
     88 
     89 }  // namespace
     90 
     91 namespace test {
     92 class TestOnThread : public base::SimpleThread {
     93  public:
     94   explicit TestOnThread(ImageSkia* image_skia)
     95       : SimpleThread("image_skia_on_thread"),
     96         image_skia_(image_skia),
     97         can_read_(false),
     98         can_modify_(false) {
     99   }
    100 
    101   virtual void Run() OVERRIDE {
    102     can_read_ = image_skia_->CanRead();
    103     can_modify_ = image_skia_->CanModify();
    104     if (can_read_)
    105       image_skia_->image_reps();
    106   }
    107 
    108   void StartAndJoin() {
    109     Start();
    110     Join();
    111   }
    112 
    113   bool can_read() const { return can_read_; }
    114 
    115   bool can_modify() const { return can_modify_; }
    116 
    117  private:
    118   ImageSkia* image_skia_;
    119 
    120   bool can_read_;
    121   bool can_modify_;
    122 
    123   DISALLOW_COPY_AND_ASSIGN(TestOnThread);
    124 };
    125 
    126 }  // namespace test
    127 
    128 class ImageSkiaTest : public testing::Test {
    129  public:
    130   ImageSkiaTest() {
    131     // In the test, we assume that we support 1.0f and 2.0f DSFs.
    132     old_scales_ = ImageSkia::GetSupportedScales();
    133 
    134     // Sets the list of scale factors supported by resource bundle.
    135     std::vector<float> supported_scales;
    136     supported_scales.push_back(1.0f);
    137     supported_scales.push_back(2.0f);
    138     ImageSkia::SetSupportedScales(supported_scales);
    139   }
    140   virtual ~ImageSkiaTest() {
    141     ImageSkia::SetSupportedScales(old_scales_);
    142   }
    143 
    144  private:
    145   std::vector<float> old_scales_;
    146   DISALLOW_COPY_AND_ASSIGN(ImageSkiaTest);
    147 };
    148 
    149 TEST_F(ImageSkiaTest, FixedSource) {
    150   ImageSkiaRep image(Size(100, 200), 1.0f);
    151   ImageSkia image_skia(new FixedSource(image), Size(100, 200));
    152   EXPECT_EQ(0U, image_skia.image_reps().size());
    153 
    154   const ImageSkiaRep& result_100p = image_skia.GetRepresentation(1.0f);
    155   EXPECT_EQ(100, result_100p.GetWidth());
    156   EXPECT_EQ(200, result_100p.GetHeight());
    157   EXPECT_EQ(1.0f, result_100p.scale());
    158   EXPECT_EQ(1U, image_skia.image_reps().size());
    159 
    160   const ImageSkiaRep& result_200p = image_skia.GetRepresentation(2.0f);
    161 
    162   EXPECT_EQ(100, result_200p.GetWidth());
    163   EXPECT_EQ(200, result_200p.GetHeight());
    164   EXPECT_EQ(100, result_200p.pixel_width());
    165   EXPECT_EQ(200, result_200p.pixel_height());
    166   EXPECT_EQ(1.0f, result_200p.scale());
    167   EXPECT_EQ(1U, image_skia.image_reps().size());
    168 
    169   // Get the representation again and make sure it doesn't
    170   // generate new image skia rep.
    171   image_skia.GetRepresentation(1.0f);
    172   image_skia.GetRepresentation(2.0f);
    173   EXPECT_EQ(1U, image_skia.image_reps().size());
    174 }
    175 
    176 TEST_F(ImageSkiaTest, DynamicSource) {
    177   ImageSkia image_skia(new DynamicSource(Size(100, 200)), Size(100, 200));
    178   EXPECT_EQ(0U, image_skia.image_reps().size());
    179   const ImageSkiaRep& result_100p = image_skia.GetRepresentation(1.0f);
    180   EXPECT_EQ(100, result_100p.GetWidth());
    181   EXPECT_EQ(200, result_100p.GetHeight());
    182   EXPECT_EQ(1.0f, result_100p.scale());
    183   EXPECT_EQ(1U, image_skia.image_reps().size());
    184 
    185   const ImageSkiaRep& result_200p =
    186       image_skia.GetRepresentation(2.0f);
    187   EXPECT_EQ(100, result_200p.GetWidth());
    188   EXPECT_EQ(200, result_200p.GetHeight());
    189   EXPECT_EQ(200, result_200p.pixel_width());
    190   EXPECT_EQ(400, result_200p.pixel_height());
    191   EXPECT_EQ(2.0f, result_200p.scale());
    192   EXPECT_EQ(2U, image_skia.image_reps().size());
    193 
    194   // Get the representation again and make sure it doesn't
    195   // generate new image skia rep.
    196   image_skia.GetRepresentation(1.0f);
    197   EXPECT_EQ(2U, image_skia.image_reps().size());
    198   image_skia.GetRepresentation(2.0f);
    199   EXPECT_EQ(2U, image_skia.image_reps().size());
    200 }
    201 
    202 // Tests that image_reps returns all of the representations in the
    203 // image when there are multiple representations for a scale factor.
    204 // This currently is the case with ImageLoader::LoadImages.
    205 TEST_F(ImageSkiaTest, ManyRepsPerScaleFactor) {
    206   const int kSmallIcon1x = 16;
    207   const int kSmallIcon2x = 32;
    208   const int kLargeIcon1x = 32;
    209 
    210   ImageSkia image(new NullSource(), gfx::Size(kSmallIcon1x, kSmallIcon1x));
    211   // Simulate a source which loads images on a delay. Upon
    212   // GetImageForScaleFactor, it immediately returns null and starts loading
    213   // image reps slowly.
    214   image.GetRepresentation(1.0f);
    215   image.GetRepresentation(2.0f);
    216 
    217   // After a lengthy amount of simulated time, finally loaded image reps.
    218   image.AddRepresentation(ImageSkiaRep(
    219       gfx::Size(kSmallIcon1x, kSmallIcon1x), 1.0f));
    220   image.AddRepresentation(ImageSkiaRep(
    221       gfx::Size(kSmallIcon2x, kSmallIcon2x), 2.0f));
    222   image.AddRepresentation(ImageSkiaRep(
    223       gfx::Size(kLargeIcon1x, kLargeIcon1x), 1.0f));
    224 
    225   std::vector<ImageSkiaRep> image_reps = image.image_reps();
    226   EXPECT_EQ(3u, image_reps.size());
    227 
    228   int num_1x = 0;
    229   int num_2x = 0;
    230   for (size_t i = 0; i < image_reps.size(); ++i) {
    231     if (image_reps[i].scale() == 1.0f)
    232       num_1x++;
    233     else if (image_reps[i].scale() == 2.0f)
    234       num_2x++;
    235   }
    236   EXPECT_EQ(2, num_1x);
    237   EXPECT_EQ(1, num_2x);
    238 }
    239 
    240 TEST_F(ImageSkiaTest, GetBitmap) {
    241   ImageSkia image_skia(new DynamicSource(Size(100, 200)), Size(100, 200));
    242   const SkBitmap* bitmap = image_skia.bitmap();
    243   EXPECT_NE(static_cast<SkBitmap*>(NULL), bitmap);
    244   EXPECT_FALSE(bitmap->isNull());
    245 }
    246 
    247 TEST_F(ImageSkiaTest, GetBitmapFromEmpty) {
    248   // Create an image with 1 representation and remove it so the ImageSkiaStorage
    249   // is left with no representations.
    250   ImageSkia empty_image(ImageSkiaRep(Size(100, 200), 1.0f));
    251   ImageSkia empty_image_copy(empty_image);
    252   empty_image.RemoveRepresentation(1.0f);
    253 
    254   // Check that ImageSkia::bitmap() still returns a valid SkBitmap pointer for
    255   // the image and all its copies.
    256   const SkBitmap* bitmap = empty_image_copy.bitmap();
    257   ASSERT_NE(static_cast<SkBitmap*>(NULL), bitmap);
    258   EXPECT_TRUE(bitmap->isNull());
    259   EXPECT_TRUE(bitmap->empty());
    260 }
    261 
    262 TEST_F(ImageSkiaTest, BackedBySameObjectAs) {
    263   // Null images should all be backed by the same object (NULL).
    264   ImageSkia image;
    265   ImageSkia unrelated;
    266   EXPECT_TRUE(image.BackedBySameObjectAs(unrelated));
    267 
    268   image.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
    269                                             1.0f));
    270   ImageSkia copy = image;
    271   copy.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
    272                                            2.0f));
    273   unrelated.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
    274                                                 1.0f));
    275   EXPECT_TRUE(image.BackedBySameObjectAs(copy));
    276   EXPECT_FALSE(image.BackedBySameObjectAs(unrelated));
    277   EXPECT_FALSE(copy.BackedBySameObjectAs(unrelated));
    278 }
    279 
    280 #if ENABLE_NON_THREAD_SAFE
    281 TEST_F(ImageSkiaTest, EmptyOnThreadTest) {
    282   ImageSkia empty;
    283   test::TestOnThread empty_on_thread(&empty);
    284   empty_on_thread.Start();
    285   empty_on_thread.Join();
    286   EXPECT_TRUE(empty_on_thread.can_read());
    287   EXPECT_TRUE(empty_on_thread.can_modify());
    288 }
    289 
    290 TEST_F(ImageSkiaTest, StaticOnThreadTest) {
    291   ImageSkia image(ImageSkiaRep(Size(100, 200), 1.0f));
    292   EXPECT_FALSE(image.IsThreadSafe());
    293 
    294   test::TestOnThread image_on_thread(&image);
    295   // an image that was never accessed on this thread can be
    296   // read by other thread.
    297   image_on_thread.StartAndJoin();
    298   EXPECT_TRUE(image_on_thread.can_read());
    299   EXPECT_TRUE(image_on_thread.can_modify());
    300   EXPECT_FALSE(image.CanRead());
    301   EXPECT_FALSE(image.CanModify());
    302 
    303   image.DetachStorageFromThread();
    304   // An image is accessed by this thread,
    305   // so other thread cannot read/modify it.
    306   image.image_reps();
    307   test::TestOnThread image_on_thread2(&image);
    308   image_on_thread2.StartAndJoin();
    309   EXPECT_FALSE(image_on_thread2.can_read());
    310   EXPECT_FALSE(image_on_thread2.can_modify());
    311   EXPECT_TRUE(image.CanRead());
    312   EXPECT_TRUE(image.CanModify());
    313 
    314   image.DetachStorageFromThread();
    315   scoped_ptr<ImageSkia> deep_copy(image.DeepCopy());
    316   EXPECT_FALSE(deep_copy->IsThreadSafe());
    317   test::TestOnThread deepcopy_on_thread(deep_copy.get());
    318   deepcopy_on_thread.StartAndJoin();
    319   EXPECT_TRUE(deepcopy_on_thread.can_read());
    320   EXPECT_TRUE(deepcopy_on_thread.can_modify());
    321   EXPECT_FALSE(deep_copy->CanRead());
    322   EXPECT_FALSE(deep_copy->CanModify());
    323 
    324   scoped_ptr<ImageSkia> deep_copy2(image.DeepCopy());
    325   EXPECT_EQ(1U, deep_copy2->image_reps().size());
    326   // Access it from current thread so that it can't be
    327   // accessed from another thread.
    328   deep_copy2->image_reps();
    329   EXPECT_FALSE(deep_copy2->IsThreadSafe());
    330   test::TestOnThread deepcopy2_on_thread(deep_copy2.get());
    331   deepcopy2_on_thread.StartAndJoin();
    332   EXPECT_FALSE(deepcopy2_on_thread.can_read());
    333   EXPECT_FALSE(deepcopy2_on_thread.can_modify());
    334   EXPECT_TRUE(deep_copy2->CanRead());
    335   EXPECT_TRUE(deep_copy2->CanModify());
    336 
    337   image.DetachStorageFromThread();
    338   image.SetReadOnly();
    339   // A read-only ImageSkia with no source is thread safe.
    340   EXPECT_TRUE(image.IsThreadSafe());
    341   test::TestOnThread readonly_on_thread(&image);
    342   readonly_on_thread.StartAndJoin();
    343   EXPECT_TRUE(readonly_on_thread.can_read());
    344   EXPECT_FALSE(readonly_on_thread.can_modify());
    345   EXPECT_TRUE(image.CanRead());
    346   EXPECT_FALSE(image.CanModify());
    347 
    348   image.DetachStorageFromThread();
    349   image.MakeThreadSafe();
    350   EXPECT_TRUE(image.IsThreadSafe());
    351   test::TestOnThread threadsafe_on_thread(&image);
    352   threadsafe_on_thread.StartAndJoin();
    353   EXPECT_TRUE(threadsafe_on_thread.can_read());
    354   EXPECT_FALSE(threadsafe_on_thread.can_modify());
    355   EXPECT_TRUE(image.CanRead());
    356   EXPECT_FALSE(image.CanModify());
    357 }
    358 
    359 TEST_F(ImageSkiaTest, SourceOnThreadTest) {
    360   ImageSkia image(new DynamicSource(Size(100, 200)), Size(100, 200));
    361   EXPECT_FALSE(image.IsThreadSafe());
    362 
    363   test::TestOnThread image_on_thread(&image);
    364   image_on_thread.StartAndJoin();
    365   // an image that was never accessed on this thread can be
    366   // read by other thread.
    367   EXPECT_TRUE(image_on_thread.can_read());
    368   EXPECT_TRUE(image_on_thread.can_modify());
    369   EXPECT_FALSE(image.CanRead());
    370   EXPECT_FALSE(image.CanModify());
    371 
    372   image.DetachStorageFromThread();
    373   // An image is accessed by this thread,
    374   // so other thread cannot read/modify it.
    375   image.image_reps();
    376   test::TestOnThread image_on_thread2(&image);
    377   image_on_thread2.StartAndJoin();
    378   EXPECT_FALSE(image_on_thread2.can_read());
    379   EXPECT_FALSE(image_on_thread2.can_modify());
    380   EXPECT_TRUE(image.CanRead());
    381   EXPECT_TRUE(image.CanModify());
    382 
    383   image.DetachStorageFromThread();
    384   image.SetReadOnly();
    385   EXPECT_FALSE(image.IsThreadSafe());
    386   test::TestOnThread readonly_on_thread(&image);
    387   readonly_on_thread.StartAndJoin();
    388   EXPECT_TRUE(readonly_on_thread.can_read());
    389   EXPECT_FALSE(readonly_on_thread.can_modify());
    390   EXPECT_FALSE(image.CanRead());
    391   EXPECT_FALSE(image.CanModify());
    392 
    393   image.DetachStorageFromThread();
    394   image.MakeThreadSafe();
    395   EXPECT_TRUE(image.IsThreadSafe());
    396   // Check if image reps are generated for supported scale factors.
    397   EXPECT_EQ(ImageSkia::GetSupportedScales().size(),
    398            image.image_reps().size());
    399   test::TestOnThread threadsafe_on_thread(&image);
    400   threadsafe_on_thread.StartAndJoin();
    401   EXPECT_TRUE(threadsafe_on_thread.can_read());
    402   EXPECT_FALSE(threadsafe_on_thread.can_modify());
    403   EXPECT_TRUE(image.CanRead());
    404   EXPECT_FALSE(image.CanModify());
    405 }
    406 #endif  // ENABLE_NON_THREAD_SAFE
    407 
    408 // Just in case we ever get lumped together with other compilation units.
    409 #undef ENABLE_NON_THREAD_SAFE
    410 
    411 TEST_F(ImageSkiaTest, Unscaled) {
    412   SkBitmap bitmap;
    413 
    414   // An ImageSkia created with 1x bitmap is unscaled.
    415   ImageSkia image_skia = ImageSkia::CreateFrom1xBitmap(bitmap);
    416   EXPECT_TRUE(image_skia.GetRepresentation(1.0f).unscaled());
    417   ImageSkiaRep rep_2x(Size(100, 100), 2.0f);
    418 
    419   // When reps for other scales are added, the unscaled image
    420   // becomes scaled.
    421   image_skia.AddRepresentation(rep_2x);
    422   EXPECT_FALSE(image_skia.GetRepresentation(1.0f).unscaled());
    423   EXPECT_FALSE(image_skia.GetRepresentation(2.0f).unscaled());
    424 }
    425 
    426 namespace {
    427 
    428 std::vector<float> GetSortedScaleFactors(const gfx::ImageSkia& image) {
    429   const std::vector<ImageSkiaRep>& image_reps = image.image_reps();
    430   std::vector<float> scale_factors;
    431   for (size_t i = 0; i < image_reps.size(); ++i) {
    432     scale_factors.push_back(image_reps[i].scale());
    433   }
    434   std::sort(scale_factors.begin(), scale_factors.end());
    435   return scale_factors;
    436 }
    437 
    438 }  // namespace
    439 
    440 TEST_F(ImageSkiaTest, ArbitraryScaleFactor) {
    441   // Do not test if the ImageSkia doesn't support arbitrary scale factors.
    442   if (!ImageSkia::IsDSFScalingInImageSkiaEnabled())
    443     return;
    444 
    445   // source is owned by |image|
    446   DynamicSource* source = new DynamicSource(Size(100, 200));
    447   ImageSkia image(source, gfx::Size(100, 200));
    448 
    449   image.GetRepresentation(1.5f);
    450   EXPECT_EQ(2.0f, source->GetLastRequestedScaleAndReset());
    451   std::vector<ImageSkiaRep> image_reps = image.image_reps();
    452   EXPECT_EQ(2u, image_reps.size());
    453 
    454   std::vector<float> scale_factors = GetSortedScaleFactors(image);
    455   EXPECT_EQ(1.5f, scale_factors[0]);
    456   EXPECT_EQ(2.0f, scale_factors[1]);
    457 
    458   // Requesting 1.75 scale factor also falls back to 2.0f and rescale.
    459   // However, the image already has the 2.0f data, so it won't fetch again.
    460   image.GetRepresentation(1.75f);
    461   EXPECT_EQ(0.0f, source->GetLastRequestedScaleAndReset());
    462   image_reps = image.image_reps();
    463   EXPECT_EQ(3u, image_reps.size());
    464 
    465   scale_factors = GetSortedScaleFactors(image);
    466   EXPECT_EQ(1.5f, scale_factors[0]);
    467   EXPECT_EQ(1.75f, scale_factors[1]);
    468   EXPECT_EQ(2.0f, scale_factors[2]);
    469 
    470   // Requesting 1.25 scale factor also falls back to 2.0f and rescale.
    471   // However, the image already has the 2.0f data, so it won't fetch again.
    472   image.GetRepresentation(1.25f);
    473   EXPECT_EQ(0.0f, source->GetLastRequestedScaleAndReset());
    474   image_reps = image.image_reps();
    475   EXPECT_EQ(4u, image_reps.size());
    476   scale_factors = GetSortedScaleFactors(image);
    477   EXPECT_EQ(1.25f, scale_factors[0]);
    478   EXPECT_EQ(1.5f, scale_factors[1]);
    479   EXPECT_EQ(1.75f, scale_factors[2]);
    480   EXPECT_EQ(2.0f, scale_factors[3]);
    481 
    482   // 1.20 is falled back to 1.0.
    483   image.GetRepresentation(1.20f);
    484   EXPECT_EQ(1.0f, source->GetLastRequestedScaleAndReset());
    485   image_reps = image.image_reps();
    486   EXPECT_EQ(6u, image_reps.size());
    487   scale_factors = GetSortedScaleFactors(image);
    488   EXPECT_EQ(1.0f, scale_factors[0]);
    489   EXPECT_EQ(1.2f, scale_factors[1]);
    490   EXPECT_EQ(1.25f, scale_factors[2]);
    491   EXPECT_EQ(1.5f, scale_factors[3]);
    492   EXPECT_EQ(1.75f, scale_factors[4]);
    493   EXPECT_EQ(2.0f, scale_factors[5]);
    494 
    495   // Scale factor less than 1.0f will be falled back to 1.0f
    496   image.GetRepresentation(0.75f);
    497   EXPECT_EQ(0.0f, source->GetLastRequestedScaleAndReset());
    498   image_reps = image.image_reps();
    499   EXPECT_EQ(7u, image_reps.size());
    500 
    501   scale_factors = GetSortedScaleFactors(image);
    502   EXPECT_EQ(0.75f, scale_factors[0]);
    503   EXPECT_EQ(1.0f, scale_factors[1]);
    504   EXPECT_EQ(1.2f, scale_factors[2]);
    505   EXPECT_EQ(1.25f, scale_factors[3]);
    506   EXPECT_EQ(1.5f, scale_factors[4]);
    507   EXPECT_EQ(1.75f, scale_factors[5]);
    508   EXPECT_EQ(2.0f, scale_factors[6]);
    509 
    510   // Scale factor greater than 2.0f is falled back to 2.0f because it's not
    511   // supported.
    512   image.GetRepresentation(3.0f);
    513   EXPECT_EQ(0.0f, source->GetLastRequestedScaleAndReset());
    514   image_reps = image.image_reps();
    515   EXPECT_EQ(8u, image_reps.size());
    516 }
    517 
    518 TEST_F(ImageSkiaTest, ArbitraryScaleFactorWithMissingResource) {
    519   // Do not test if the ImageSkia doesn't support arbitrary scale factors.
    520   if (!ImageSkia::IsDSFScalingInImageSkiaEnabled())
    521     return;
    522 
    523   ImageSkia image(new FixedSource(
    524       ImageSkiaRep(Size(100, 200), 1.0f)), Size(100, 200));
    525 
    526   // Requesting 1.5f -- falls back to 2.0f, but couldn't find. It should
    527   // look up 1.0f and then rescale it.
    528   const ImageSkiaRep& rep = image.GetRepresentation(1.5f);
    529   EXPECT_EQ(1.5f, rep.scale());
    530   EXPECT_EQ(2U, image.image_reps().size());
    531   EXPECT_EQ(1.0f, image.image_reps()[0].scale());
    532   EXPECT_EQ(1.5f, image.image_reps()[1].scale());
    533 }
    534 
    535 TEST_F(ImageSkiaTest, UnscaledImageForArbitraryScaleFactor) {
    536   // Do not test if the ImageSkia doesn't support arbitrary scale factors.
    537   if (!ImageSkia::IsDSFScalingInImageSkiaEnabled())
    538     return;
    539 
    540   // 0.0f means unscaled.
    541   ImageSkia image(new FixedSource(
    542       ImageSkiaRep(Size(100, 200), 0.0f)), Size(100, 200));
    543 
    544   // Requesting 2.0f, which should return 1.0f unscaled image.
    545   const ImageSkiaRep& rep = image.GetRepresentation(2.0f);
    546   EXPECT_EQ(1.0f, rep.scale());
    547   EXPECT_EQ("100x200", rep.pixel_size().ToString());
    548   EXPECT_TRUE(rep.unscaled());
    549   EXPECT_EQ(1U, image.image_reps().size());
    550 
    551   // Same for any other scale factors.
    552   const ImageSkiaRep& rep15 = image.GetRepresentation(1.5f);
    553   EXPECT_EQ(1.0f, rep15.scale());
    554   EXPECT_EQ("100x200", rep15.pixel_size().ToString());
    555   EXPECT_TRUE(rep15.unscaled());
    556   EXPECT_EQ(1U, image.image_reps().size());
    557 
    558   const ImageSkiaRep& rep12 = image.GetRepresentation(1.2f);
    559   EXPECT_EQ(1.0f, rep12.scale());
    560   EXPECT_EQ("100x200", rep12.pixel_size().ToString());
    561   EXPECT_TRUE(rep12.unscaled());
    562   EXPECT_EQ(1U, image.image_reps().size());
    563 }
    564 
    565 }  // namespace gfx
    566