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