1 /* 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_H_ 28 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_H_ 29 30 #include "base/macros.h" 31 #include "base/memory/scoped_refptr.h" 32 #include "base/memory/weak_ptr.h" 33 #include "third_party/blink/renderer/platform/geometry/float_point.h" 34 #include "third_party/blink/renderer/platform/geometry/float_size.h" 35 #include "third_party/blink/renderer/platform/geometry/int_rect.h" 36 #include "third_party/blink/renderer/platform/graphics/graphics_types.h" 37 #include "third_party/blink/renderer/platform/graphics/image_animation_policy.h" 38 #include "third_party/blink/renderer/platform/graphics/image_observer.h" 39 #include "third_party/blink/renderer/platform/graphics/image_orientation.h" 40 #include "third_party/blink/renderer/platform/graphics/paint/paint_image.h" 41 #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" 42 #include "third_party/blink/renderer/platform/heap/persistent.h" 43 #include "third_party/blink/renderer/platform/platform_export.h" 44 #include "third_party/blink/renderer/platform/wtf/forward.h" 45 #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" 46 #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" 47 #include "third_party/skia/include/core/SkRefCnt.h" 48 #include "ui/base/resource/scale_factor.h" 49 50 class SkMatrix; 51 52 namespace cc { 53 class PaintCanvas; 54 class PaintFlags; 55 class ImageDecodeCache; 56 } // namespace cc 57 58 namespace blink { 59 60 class DarkModeImageClassifier; 61 class FloatRect; 62 class GraphicsContext; 63 class Image; 64 class KURL; 65 class WebGraphicsContext3DProvider; 66 class WebGraphicsContext3DProviderWrapper; 67 68 class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> { 69 friend class GeneratedImage; 70 friend class CrossfadeGeneratedImage; 71 friend class GradientGeneratedImage; 72 friend class GraphicsContext; 73 74 public: 75 virtual ~Image(); 76 77 static cc::ImageDecodeCache& SharedCCDecodeCache(SkColorType); 78 79 static scoped_refptr<Image> LoadPlatformResource( 80 int resource_id, 81 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P); 82 83 static PaintImage ResizeAndOrientImage( 84 const PaintImage&, 85 ImageOrientation, 86 FloatSize image_scale = FloatSize(1, 1), 87 float opacity = 1.0, 88 InterpolationQuality = kInterpolationNone); 89 IsSVGImage()90 virtual bool IsSVGImage() const { return false; } IsBitmapImage()91 virtual bool IsBitmapImage() const { return false; } IsStaticBitmapImage()92 virtual bool IsStaticBitmapImage() const { return false; } IsPlaceholderImage()93 virtual bool IsPlaceholderImage() const { return false; } 94 95 virtual bool CurrentFrameKnownToBeOpaque() = 0; 96 CurrentFrameIsComplete()97 virtual bool CurrentFrameIsComplete() { return false; } CurrentFrameIsLazyDecoded()98 virtual bool CurrentFrameIsLazyDecoded() { return false; } FrameCount()99 virtual size_t FrameCount() { return 0; } IsTextureBacked()100 virtual bool IsTextureBacked() const { return false; } 101 102 // Derived classes should override this if they can assure that the current 103 // image frame contains only resources from its own security origin. CurrentFrameHasSingleSecurityOrigin()104 virtual bool CurrentFrameHasSingleSecurityOrigin() const { return false; } 105 106 static Image* NullImage(); IsNull()107 bool IsNull() const { return Size().IsEmpty(); } 108 HasIntrinsicSize()109 virtual bool HasIntrinsicSize() const { return true; } 110 111 virtual IntSize Size() const = 0; 112 IntSize Size(RespectImageOrientationEnum) const; SizeRespectingOrientation()113 virtual IntSize SizeRespectingOrientation() const { return Size(); } SizeAsFloat(RespectImageOrientationEnum respect_orientation)114 virtual FloatSize SizeAsFloat( 115 RespectImageOrientationEnum respect_orientation) const { 116 return FloatSize(Size(respect_orientation)); 117 } Rect()118 IntRect Rect() const { return IntRect(IntPoint(), Size()); } width()119 int width() const { return Size().Width(); } height()120 int height() const { return Size().Height(); } 121 GetHotSpot(IntPoint &)122 virtual bool GetHotSpot(IntPoint&) const { return false; } 123 124 enum SizeAvailability { 125 kSizeUnavailable, 126 kSizeAvailableAndLoadingAsynchronously, 127 kSizeAvailable, 128 }; 129 130 // If SetData() returns |kSizeAvailableAndLoadingAsynchronously|: 131 // Image loading is continuing asynchronously 132 // (only when |this| is SVGImage and |all_data_received| is true), and 133 // ImageResourceObserver::AsyncLoadCompleted() is called when finished. 134 // Otherwise: 135 // Image loading is completed synchronously. 136 // ImageResourceObserver::AsyncLoadCompleted() is not called. 137 virtual SizeAvailability SetData(scoped_refptr<SharedBuffer> data, 138 bool all_data_received); DataChanged(bool)139 virtual SizeAvailability DataChanged(bool /*all_data_received*/) { 140 return kSizeUnavailable; 141 } 142 143 // null string if unknown 144 virtual String FilenameExtension() const; 145 146 virtual void DestroyDecodedData() = 0; 147 Data()148 virtual scoped_refptr<SharedBuffer> Data() { return encoded_image_data_; } 149 150 // Animation begins whenever someone draws the image, so startAnimation() is 151 // not normally called. It will automatically pause once all observers no 152 // longer want to render the image anywhere. StartAnimation()153 virtual void StartAnimation() {} ResetAnimation()154 virtual void ResetAnimation() {} 155 156 // True if this image can potentially animate. MaybeAnimated()157 virtual bool MaybeAnimated() { return false; } 158 159 // Set animationPolicy SetAnimationPolicy(ImageAnimationPolicy)160 virtual void SetAnimationPolicy(ImageAnimationPolicy) {} AnimationPolicy()161 virtual ImageAnimationPolicy AnimationPolicy() { 162 return kImageAnimationPolicyAllowed; 163 } 164 165 // Advances an animated image. For BitmapImage (e.g., animated gifs) this 166 // will advance to the next frame. For SVGImage, this will trigger an 167 // animation update for CSS and advance the SMIL timeline by one frame. AdvanceAnimationForTesting()168 virtual void AdvanceAnimationForTesting() {} 169 170 // Typically the ImageResourceContent that owns us. GetImageObserver()171 ImageObserver* GetImageObserver() const { 172 return image_observer_disabled_ ? nullptr : image_observer_; 173 } ClearImageObserver()174 void ClearImageObserver() { image_observer_ = nullptr; } 175 // To avoid interleaved accesses to |m_imageObserverDisabled|, do not call 176 // setImageObserverDisabled() other than from ImageObserverDisabler. SetImageObserverDisabled(bool disabled)177 void SetImageObserverDisabled(bool disabled) { 178 image_observer_disabled_ = disabled; 179 } 180 181 virtual scoped_refptr<Image> ImageForDefaultFrame(); 182 183 enum ImageDecodingMode { 184 // No preference specified. 185 kUnspecifiedDecode, 186 // Prefer to display the image synchronously with the rest of the content 187 // updates. 188 kSyncDecode, 189 // Prefer to display the image asynchronously with the rest of the content 190 // updates. 191 kAsyncDecode 192 }; 193 ToPaintImageDecodingMode(ImageDecodingMode mode)194 static PaintImage::DecodingMode ToPaintImageDecodingMode( 195 ImageDecodingMode mode) { 196 switch (mode) { 197 case kUnspecifiedDecode: 198 return PaintImage::DecodingMode::kUnspecified; 199 case kSyncDecode: 200 return PaintImage::DecodingMode::kSync; 201 case kAsyncDecode: 202 return PaintImage::DecodingMode::kAsync; 203 } 204 205 NOTREACHED(); 206 return PaintImage::DecodingMode::kUnspecified; 207 } 208 209 virtual PaintImage PaintImageForCurrentFrame() = 0; 210 HasDefaultOrientation()211 virtual bool HasDefaultOrientation() const { return true; } 212 213 // Most image types have the default orientation. Only bitmap derived image 214 // types need to override this method. CurrentFrameOrientation()215 virtual ImageOrientation CurrentFrameOrientation() const { 216 return kDefaultImageOrientation; 217 } 218 219 // Correct the src rect (rotate and maybe translate it) to account for a 220 // non-default image orientation. The image must have non-default orientation 221 // to call this method. The image_size is the oriented size of the image (i.e. 222 // after orientation has been applied). src_rect may be a subset of the image, 223 // also oriented. 224 FloatRect CorrectSrcRectForImageOrientation(FloatSize image_size, 225 FloatRect src_rect) const; 226 227 enum ImageClampingMode { 228 kClampImageToSourceRect, 229 kDoNotClampImageToSourceRect 230 }; 231 232 virtual void Draw(cc::PaintCanvas*, 233 const cc::PaintFlags&, 234 const FloatRect& dst_rect, 235 const FloatRect& src_rect, 236 RespectImageOrientationEnum, 237 ImageClampingMode, 238 ImageDecodingMode) = 0; 239 240 virtual bool ApplyShader(cc::PaintFlags&, const SkMatrix& local_matrix); 241 242 // Use ContextProvider() for immediate use only, use 243 // ContextProviderWrapper() to obtain a retainable reference. Note: 244 // Implemented only in sub-classes that use the GPU. ContextProvider()245 virtual WebGraphicsContext3DProvider* ContextProvider() const { 246 return nullptr; 247 } 248 virtual base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper()249 ContextProviderWrapper() const { 250 return nullptr; 251 } 252 PaintRecordForContainer(const KURL & url,const IntSize & container_size,const IntRect & draw_src_rect,const IntRect & draw_dst_rect,bool flip_y)253 virtual sk_sp<PaintRecord> PaintRecordForContainer( 254 const KURL& url, 255 const IntSize& container_size, 256 const IntRect& draw_src_rect, 257 const IntRect& draw_dst_rect, 258 bool flip_y) { 259 return nullptr; 260 } 261 262 // This function is implemented by the derived classes which might 263 // have certain conditions or default classification decisions which 264 // need to be checked before the classification algorithms are applied 265 // on the image. CheckTypeSpecificConditionsForDarkMode(const FloatRect & dest_rect,DarkModeImageClassifier * classifier)266 virtual DarkModeClassification CheckTypeSpecificConditionsForDarkMode( 267 const FloatRect& dest_rect, 268 DarkModeImageClassifier* classifier) { 269 return DarkModeClassification::kDoNotApplyFilter; 270 } 271 272 // This function returns true if it can create the bitmap of the 273 // image using |src_rect| for the location and dimensions of the image. 274 // For Bitmap and SVG (and any other type) images the implementation 275 // of this function differs when it comes to the implementation of 276 // PaintImageForCurrentFrame(). Once the PaintImage is available, 277 // the method used to extract the bitmap is the same for any image. 278 bool GetBitmap(const FloatRect& src_rect, SkBitmap* bitmap); 279 paint_image_id()280 PaintImage::Id paint_image_id() const { return stable_image_id_; } 281 282 // Returns an SkBitmap that is a copy of the image's current frame. 283 SkBitmap AsSkBitmapForCurrentFrame(RespectImageOrientationEnum); 284 285 DarkModeClassification GetDarkModeClassification(const FloatRect& src_rect); 286 287 // Dark mode classification result is cached to be consistent and have 288 // higher performance for future paints. 289 void AddDarkModeClassification( 290 const FloatRect& src_rect, 291 const DarkModeClassification dark_mode_classification); 292 293 protected: 294 Image(ImageObserver* = nullptr, bool is_multipart = false); 295 296 virtual void DrawPattern(GraphicsContext&, 297 const FloatRect&, 298 const FloatSize&, 299 const FloatPoint& phase, 300 SkBlendMode, 301 const FloatRect&, 302 const FloatSize& repeat_spacing, 303 RespectImageOrientationEnum); 304 305 // Creates and initializes a PaintImageBuilder with the metadata flags for the 306 // PaintImage. 307 PaintImageBuilder CreatePaintImageBuilder(); 308 309 // Whether or not size is available yet. IsSizeAvailable()310 virtual bool IsSizeAvailable() { return true; } 311 312 typedef FloatPoint ClassificationKey; 313 HashMap<ClassificationKey, DarkModeClassification> dark_mode_classifications_; 314 315 private: 316 bool image_observer_disabled_; 317 scoped_refptr<SharedBuffer> encoded_image_data_; 318 // TODO(Oilpan): consider having Image on the Oilpan heap and 319 // turn this into a Member<>. 320 // 321 // The observer (an ImageResourceContent) is responsible for clearing 322 // itself out when it switches to another Image. 323 // When the ImageResourceContent is garbage collected while Image is still 324 // alive, |image_observer_| is cleared by WeakPersistent mechanism. 325 WeakPersistent<ImageObserver> image_observer_; 326 PaintImage::Id stable_image_id_; 327 const bool is_multipart_; 328 DISALLOW_COPY_AND_ASSIGN(Image); 329 }; 330 331 } // namespace blink 332 333 #endif 334