15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_GFX_IMAGE_IMAGE_SKIA_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_GFX_IMAGE_IMAGE_SKIA_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/gfx_export.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_rep.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageSkiaSource; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Size; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageSkiaStorage; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestOnThread; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Container for the same image at different densities, similar to NSImage. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Image height and width are in DIP (Density Indepent Pixel) coordinates. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageSkia should be used whenever possible instead of SkBitmap. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Functions that mutate the image should operate on the gfx::ImageSkiaRep 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returned from ImageSkia::GetRepresentation, not on ImageSkia. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageSkia is cheap to copy and intentionally supports copy semantics. 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class GFX_EXPORT ImageSkia { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<ImageSkiaRep> ImageSkiaReps; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an instance with no bitmaps. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an instance that will use the |source| to get the image 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for scale factors. |size| specifes the size of the image in DIP. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ImageSkia owns |source|. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia(ImageSkiaSource* source, const gfx::Size& size); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an instance that uses the |source|. The constructor loads the image 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // at |scale| and uses its dimensions to calculate the size in DIP. ImageSkia 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // owns |source|. 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ImageSkia(ImageSkiaSource* source, float scale); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ImageSkia(const gfx::ImageSkiaRep& image_rep); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copies a reference to |other|'s storage. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia(const ImageSkia& other); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copies a reference to |other|'s storage. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageSkia& operator=(const ImageSkia& other); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ImageSkia(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Changes the value of GetSupportedScales() to |scales|. 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) static void SetSupportedScales(const std::vector<float>& scales); 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Returns a vector with the scale factors which are supported by this 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // platform, in ascending order. 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) static const std::vector<float>& GetSupportedScales(); 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Returns the maximum scale supported by this platform. 7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) static float GetMaxSupportedScale(); 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates an image from the passed in bitmap. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DIP width and height are based on scale factor of 1x. 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Adds ref to passed in bitmap. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WARNING: The resulting image will be pixelated when painted on a high 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // density display. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static ImageSkia CreateFrom1xBitmap(const SkBitmap& bitmap); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Returns true when ImageSkia looks up the resource pack with the closest 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // scale factor and rescale the fetched image. 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static bool IsDSFScalingInImageSkiaEnabled(); 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a deep copy of this ImageSkia which has its own storage with 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the ImageSkiaRep instances that this ImageSkia currently has. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be safely passed to and manipulated by another thread. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this does NOT generate ImageSkiaReps from its source. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If you want to create a deep copy with ImageSkiaReps for supported 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scale factors, you need to explicitly call 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |EnsureRepsForSupportedScales()| first. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ImageSkia> DeepCopy() const; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this object is backed by the same ImageSkiaStorage as 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |other|. Will also return true if both images are isNull(). 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool BackedBySameObjectAs(const gfx::ImageSkia& other) const; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds |image_rep| to the image reps contained by this object. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRepresentation(const gfx::ImageSkiaRep& image_rep); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Removes the image rep of |scale| if present. 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void RemoveRepresentation(float scale); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the object owns an image rep whose density matches 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |scale| exactly. 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool HasRepresentation(float scale) const; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Returns the image rep whose density best matches |scale|. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a null image rep if the object contains no image reps. 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const gfx::ImageSkiaRep& GetRepresentation(float scale) const; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make the ImageSkia instance read-only. Note that this only prevent 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // modification from client code, and the storage may still be 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // modified by the source if any (thus, it's not thread safe). This 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detaches the storage from currently accessing thread, so its safe 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to pass it to other thread as long as it is accessed only by that 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. If this ImageSkia's storage will be accessed by multiple 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // threads, use |MakeThreadSafe()| method. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetReadOnly(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make the image thread safe by making the storage read only and remove 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its source if any. All ImageSkia that shares the same storage will also 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // become thread safe. Note that in order to make it 100% thread safe, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this must be called before it's been passed to anther thread. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MakeThreadSafe(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsThreadSafe() const; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this is a null object. 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool isNull() const { return storage_.get() == NULL; } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Width and height of image in DIP coordinate system. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width() const; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height() const; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size() const; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns pointer to 1x bitmap contained by this object. If there is no 1x 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bitmap, the bitmap whose scale factor is closest to 1x is returned. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function should only be used in unittests and on platforms which do 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not support scale factors other than 1x. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkotwicz): Return null SkBitmap when the object has no 1x bitmap. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap* bitmap() const { return &GetBitmap(); } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a vector with the image reps contained in this object. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no guarantee that this will return all images rep for 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // supported scale factors. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<gfx::ImageSkiaRep> image_reps() const; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the source is available, generates all ImageReps for 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // supported scale factors. This method is defined as const as 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the state change in the storage is agnostic to the caller. 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void EnsureRepsForSupportedScales() const; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class test::TestOnThread; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, EmptyOnThreadTest); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, StaticOnThreadTest); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ImageSkiaTest, SourceOnThreadTest); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize ImageSkiaStorage with passed in parameters. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the image rep's bitmap is empty, ImageStorage is set to NULL. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Init(const gfx::ImageSkiaRep& image_rep); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap& GetBitmap() const; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if the current thread can read/modify the ImageSkia. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanRead() const; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanModify() const; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Detach the storage from the currently assinged thread 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that other thread can access the storage. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DetachStorageFromThread(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A refptr so that ImageRepSkia can be copied cheaply. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<internal::ImageSkiaStorage> storage_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UI_GFX_IMAGE_IMAGE_SKIA_H_ 180