1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file
6  */
7 
8 #ifndef SkSpecialImage_DEFINED
9 #define SkSpecialImage_DEFINED
10 
11 #include "SkNextID.h"
12 #include "SkRefCnt.h"
13 
14 // remove this when internal_getProxy goes away (see skbug.com/4965)
15 #include "SkImageFilter.h"
16 
17 class GrTexture;
18 class SkBitmap;
19 class SkCanvas;
20 class SkImage;
21 struct SkImageInfo;
22 class SkPaint;
23 class SkSpecialSurface;
24 
25 enum {
26     kNeedNewImageUniqueID_SpecialImage = 0
27 };
28 
29 /**
30  * This is a restricted form of SkImage solely intended for internal use. It
31  * differs from SkImage in that:
32  *      - it can only be backed by raster or gpu (no generators)
33  *      - it can be backed by a GrTexture larger than its nominal bounds
34  *      - it can't be drawn tiled
35  *      - it can't be drawn with MIPMAPs
36  * It is similar to SkImage in that it abstracts how the pixels are stored/represented.
37  *
38  * Note: the contents of the backing storage outside of the subset rect are undefined.
39  */
40 class SkSpecialImage : public SkRefCnt {
41 public:
width()42     int width() const { return fSubset.width(); }
height()43     int height() const { return fSubset.height(); }
subset()44     const SkIRect& subset() const { return fSubset; }
45 
uniqueID()46     uint32_t uniqueID() const { return fUniqueID; }
isOpaque()47     virtual bool isOpaque() const { return false; }
48     virtual size_t getSize() const = 0;
49 
50     /**
51      *  Draw this SpecialImage into the canvas.
52      */
53     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
54 
55     static SkSpecialImage* NewFromImage(const SkIRect& subset, const SkImage*);
56     static SkSpecialImage* NewFromRaster(SkImageFilter::Proxy*,
57                                          const SkIRect& subset,
58                                          const SkBitmap&);
59     static SkSpecialImage* NewFromGpu(SkImageFilter::Proxy*,
60                                       const SkIRect& subset,
61                                       uint32_t uniqueID,
62                                       GrTexture*,
63                                       SkAlphaType at = kPremul_SkAlphaType);
64 
65     /**
66      *  Create a new surface with a backend that is compatible with this image.
67      */
68     SkSpecialSurface* newSurface(const SkImageInfo&) const;
69 
70     // These three internal methods will go away (see skbug.com/4965)
71     bool internal_getBM(SkBitmap* result);
72     static SkSpecialImage* internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&);
73     SkImageFilter::Proxy* internal_getProxy();
74 
75 protected:
SkSpecialImage(SkImageFilter::Proxy * proxy,const SkIRect & subset,uint32_t uniqueID)76     SkSpecialImage(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
77         : fSubset(subset)
78         , fUniqueID(kNeedNewImageUniqueID_SpecialImage == uniqueID ? SkNextID::ImageID()
79                                                                    : uniqueID)
80         , fProxy(proxy) {
81     }
82 
83     // The following 2 are for testing and shouldn't be used.
84     friend class TestingSpecialImageAccess;
85     friend class TestingSpecialSurfaceAccess;
86 
87     /**
88      *  If the SpecialImage is backed by cpu pixels, return the const address
89      *  of those pixels and, if not null, return the ImageInfo and rowBytes.
90      *  The returned address is only valid while the image object is in scope.
91      *
92      *  The returned ImageInfo represents the backing memory. Use 'subset'
93      *  to get the active portion's dimensions.
94      *
95      *  On failure, return false and ignore the pixmap parameter.
96      */
97     bool peekPixels(SkPixmap*) const;
98 
99     /**
100      *  If the SpecialImage is backed by a gpu texture, return that texture.
101      *  The active portion of the texture can be retrieved via 'subset'.
102      */
103     GrTexture* peekTexture() const;
104 
105     // TODO: remove this ASAP (see skbug.com/4965)
proxy()106     SkImageFilter::Proxy* proxy() const { return fProxy; }
107 
108 private:
109     const SkIRect   fSubset;
110     const uint32_t  fUniqueID;
111 
112     // TODO: remove this ASAP (see skbug.com/4965)
113     SkImageFilter::Proxy* fProxy;
114 
115     typedef SkRefCnt INHERITED;
116 };
117 
118 #endif
119 
120