1 /*
2  * Copyright 2012 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 
9 #ifndef GrSurface_DEFINED
10 #define GrSurface_DEFINED
11 
12 #include "GrTypes.h"
13 #include "GrGpuResource.h"
14 #include "SkImageInfo.h"
15 #include "SkRect.h"
16 
17 class GrOpList;
18 class GrRenderTarget;
19 class GrSurfacePriv;
20 class GrTexture;
21 
22 class SK_API GrSurface : public GrGpuResource {
23 public:
24     /**
25      * Retrieves the width of the surface.
26      */
width()27     int width() const { return fDesc.fWidth; }
28 
29     /**
30      * Retrieves the height of the surface.
31      */
height()32     int height() const { return fDesc.fHeight; }
33 
34     /**
35      * Helper that gets the width and height of the surface as a bounding rectangle.
36      */
getBoundsRect()37     SkRect getBoundsRect() const { return SkRect::MakeIWH(this->width(), this->height()); }
38 
origin()39     GrSurfaceOrigin origin() const {
40         SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin || kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
41         return fDesc.fOrigin;
42     }
43 
44     /**
45      * Retrieves the pixel config specified when the surface was created.
46      * For render targets this can be kUnknown_GrPixelConfig
47      * if client asked us to render to a target that has a pixel
48      * config that isn't equivalent with one of our configs.
49      */
config()50     GrPixelConfig config() const { return fDesc.fConfig; }
51 
52     /**
53      * Return the descriptor describing the surface
54      */
desc()55     const GrSurfaceDesc& desc() const { return fDesc; }
56 
57     /**
58      * @return the texture associated with the surface, may be NULL.
59      */
asTexture()60     virtual GrTexture* asTexture() { return NULL; }
asTexture()61     virtual const GrTexture* asTexture() const { return NULL; }
62 
63     /**
64      * @return the render target underlying this surface, may be NULL.
65      */
asRenderTarget()66     virtual GrRenderTarget* asRenderTarget() { return NULL; }
asRenderTarget()67     virtual const GrRenderTarget* asRenderTarget() const { return NULL; }
68 
69     /**
70      * Reads a rectangle of pixels from the surface, possibly performing color space conversion.
71      * @param srcColorSpace color space of the source data (this surface)
72      * @param left          left edge of the rectangle to read (inclusive)
73      * @param top           top edge of the rectangle to read (inclusive)
74      * @param width         width of rectangle to read in pixels.
75      * @param height        height of rectangle to read in pixels.
76      * @param config        the pixel config of the destination buffer
77      * @param dstColorSpace color space of the destination buffer
78      * @param buffer        memory to read the rectangle into.
79      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
80      *                      packed.
81      * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
82      *
83      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
84      *              pixel config.
85      */
86     bool readPixels(SkColorSpace* srcColorSpace,
87                     int left, int top, int width, int height,
88                     GrPixelConfig config,
89                     SkColorSpace* dstColorSpace,
90                     void* buffer,
91                     size_t rowBytes = 0,
92                     uint32_t pixelOpsFlags = 0);
93 
94     /**
95      * Reads a rectangle of pixels from the surface. Does not perform any color space conversion.
96      * @param left          left edge of the rectangle to read (inclusive)
97      * @param top           top edge of the rectangle to read (inclusive)
98      * @param width         width of rectangle to read in pixels.
99      * @param height        height of rectangle to read in pixels.
100      * @param config        the pixel config of the destination buffer
101      * @param buffer        memory to read the rectangle into.
102      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
103      *                      packed.
104      * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
105      *
106      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
107      *              pixel config.
108      */
109     bool readPixels(int left, int top, int width, int height,
110                     GrPixelConfig config,
111                     void* buffer,
112                     size_t rowBytes = 0,
113                     uint32_t pixelOpsFlags = 0) {
114         return this->readPixels(nullptr, left, top, width, height, config, nullptr, buffer,
115                                 rowBytes, pixelOpsFlags);
116     }
117 
118     /**
119      * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
120      * rectangle, possibly performing color space conversion.
121      * @param dstColorSpace color space of the destination (this surface)
122      * @param left          left edge of the rectangle to write (inclusive)
123      * @param top           top edge of the rectangle to write (inclusive)
124      * @param width         width of rectangle to write in pixels.
125      * @param height        height of rectangle to write in pixels.
126      * @param config        the pixel config of the source buffer
127      * @param srcColorSpace color space of the source buffer
128      * @param buffer        memory to read the rectangle from.
129      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
130      *                      packed.
131      * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
132      *
133      * @return true if the write succeeded, false if not. The write can fail because of an
134      *              unsupported pixel config.
135      */
136     bool writePixels(SkColorSpace* dstColorSpace,
137                      int left, int top, int width, int height,
138                      GrPixelConfig config,
139                      SkColorSpace* srcColorSpace,
140                      const void* buffer,
141                      size_t rowBytes = 0,
142                      uint32_t pixelOpsFlags = 0);
143 
144     /**
145      * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
146      * rectangle. Does not perform any color space conversion.
147      * @param left          left edge of the rectangle to write (inclusive)
148      * @param top           top edge of the rectangle to write (inclusive)
149      * @param width         width of rectangle to write in pixels.
150      * @param height        height of rectangle to write in pixels.
151      * @param config        the pixel config of the source buffer
152      * @param buffer        memory to read the rectangle from.
153      * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
154      *                      packed.
155      * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
156      *
157      * @return true if the write succeeded, false if not. The write can fail because of an
158      *              unsupported pixel config.
159      */
160     bool writePixels(int left, int top, int width, int height,
161                      GrPixelConfig config,
162                      const void* buffer,
163                      size_t rowBytes = 0,
164                      uint32_t pixelOpsFlags = 0) {
165         return this->writePixels(nullptr, left, top, width, height, config, nullptr, buffer,
166                                  rowBytes, pixelOpsFlags);
167     }
168 
169     /**
170      * After this returns any pending writes to the surface will be issued to the backend 3D API.
171      */
172     void flushWrites();
173 
174     /** Access methods that are only to be used within Skia code. */
175     inline GrSurfacePriv surfacePriv();
176     inline const GrSurfacePriv surfacePriv() const;
177 
178     typedef void* ReleaseCtx;
179     typedef void (*ReleaseProc)(ReleaseCtx);
180 
setRelease(ReleaseProc proc,ReleaseCtx ctx)181     void setRelease(ReleaseProc proc, ReleaseCtx ctx) {
182         fReleaseProc = proc;
183         fReleaseCtx = ctx;
184     }
185 
186     void setLastOpList(GrOpList* opList);
getLastOpList()187     GrOpList* getLastOpList() { return fLastOpList; }
188 
189     static size_t WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2 = false);
190     static size_t ComputeSize(const GrSurfaceDesc& desc, int colorSamplesPerPixel,
191                               bool hasMIPMaps, bool useNextPow2 = false);
192 
193 protected:
194     // Methods made available via GrSurfacePriv
195     bool hasPendingRead() const;
196     bool hasPendingWrite() const;
197     bool hasPendingIO() const;
198 
199     // Provides access to methods that should be public within Skia code.
200     friend class GrSurfacePriv;
201 
GrSurface(GrGpu * gpu,const GrSurfaceDesc & desc)202     GrSurface(GrGpu* gpu, const GrSurfaceDesc& desc)
203         : INHERITED(gpu)
204         , fDesc(desc)
205         , fReleaseProc(NULL)
206         , fReleaseCtx(NULL)
207         , fLastOpList(nullptr) {
208     }
209     ~GrSurface() override;
210 
211     GrSurfaceDesc fDesc;
212 
213     void onRelease() override;
214     void onAbandon() override;
215 
216 private:
invokeReleaseProc()217     void invokeReleaseProc() {
218         if (fReleaseProc) {
219             fReleaseProc(fReleaseCtx);
220             fReleaseProc = NULL;
221         }
222     }
223 
224     ReleaseProc fReleaseProc;
225     ReleaseCtx  fReleaseCtx;
226 
227     // The last opList that wrote to or is currently going to write to this surface
228     // The opList can be closed (e.g., no render target or texture context is currently bound
229     // to this renderTarget or texture).
230     // This back-pointer is required so that we can add a dependancy between
231     // the opList used to create the current contents of this surface
232     // and the opList of a destination surface to which this one is being drawn or copied.
233     GrOpList* fLastOpList;
234 
235     typedef GrGpuResource INHERITED;
236 };
237 
238 #endif
239