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
17class GrRenderTarget;
18class GrSurfacePriv;
19class GrTexture;
20
21class SK_API GrSurface : public GrGpuResource {
22public:
23    /**
24     * Retrieves the width of the surface.
25     */
26    int width() const { return fDesc.fWidth; }
27
28    /**
29     * Retrieves the height of the surface.
30     */
31    int height() const { return fDesc.fHeight; }
32
33    /**
34     * Helper that gets the width and height of the surface as a bounding rectangle.
35     */
36    void getBoundsRect(SkRect* rect) const { rect->setWH(SkIntToScalar(this->width()),
37                                                         SkIntToScalar(this->height())); }
38
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     */
50    GrPixelConfig config() const { return fDesc.fConfig; }
51
52    /**
53     * Return the descriptor describing the surface
54     */
55    const GrSurfaceDesc& desc() const { return fDesc; }
56
57    /**
58     * @return the texture associated with the surface, may be NULL.
59     */
60    virtual GrTexture* asTexture() { return NULL; }
61    virtual const GrTexture* asTexture() const { return NULL; }
62
63    /**
64     * @return the render target underlying this surface, may be NULL.
65     */
66    virtual GrRenderTarget* asRenderTarget() { return NULL; }
67    virtual const GrRenderTarget* asRenderTarget() const { return NULL; }
68
69    /**
70     * Reads a rectangle of pixels from the surface.
71     * @param left          left edge of the rectangle to read (inclusive)
72     * @param top           top edge of the rectangle to read (inclusive)
73     * @param width         width of rectangle to read in pixels.
74     * @param height        height of rectangle to read in pixels.
75     * @param config        the pixel config of the destination buffer
76     * @param buffer        memory to read the rectangle into.
77     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
78     *                      packed.
79     * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
80     *
81     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
82     *              pixel config.
83     */
84    bool readPixels(int left, int top, int width, int height,
85                    GrPixelConfig config,
86                    void* buffer,
87                    size_t rowBytes = 0,
88                    uint32_t pixelOpsFlags = 0);
89
90    /**
91     * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
92     * rectangle.
93     * @param left          left edge of the rectangle to write (inclusive)
94     * @param top           top edge of the rectangle to write (inclusive)
95     * @param width         width of rectangle to write in pixels.
96     * @param height        height of rectangle to write in pixels.
97     * @param config        the pixel config of the source buffer
98     * @param buffer        memory to read the rectangle from.
99     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
100     *                      packed.
101     * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
102     *
103     * @return true if the read succeeded, false if not. The read can fail because of an
104     *              unsupported pixel config.
105     */
106    bool writePixels(int left, int top, int width, int height,
107                     GrPixelConfig config,
108                     const void* buffer,
109                     size_t rowBytes = 0,
110                     uint32_t pixelOpsFlags = 0);
111
112    /**
113     * After this returns any pending writes to the surface will be issued to the backend 3D API.
114     */
115    void flushWrites();
116
117
118    /**
119     * After this returns any pending surface IO will be issued to the backend 3D API and
120     * if the surface has MSAA it will be resolved.
121     */
122    void prepareForExternalIO();
123
124    /** Access methods that are only to be used within Skia code. */
125    inline GrSurfacePriv surfacePriv();
126    inline const GrSurfacePriv surfacePriv() const;
127
128    typedef void* ReleaseCtx;
129    typedef void (*ReleaseProc)(ReleaseCtx);
130
131    void setRelease(ReleaseProc proc, ReleaseCtx ctx) {
132        fReleaseProc = proc;
133        fReleaseCtx = ctx;
134    }
135
136    static size_t WorseCaseSize(const GrSurfaceDesc& desc);
137
138protected:
139    // Methods made available via GrSurfacePriv
140    SkImageInfo info(SkAlphaType) const;
141    bool savePixels(const char* filename);
142    bool hasPendingRead() const;
143    bool hasPendingWrite() const;
144    bool hasPendingIO() const;
145
146    // Provides access to methods that should be public within Skia code.
147    friend class GrSurfacePriv;
148
149    GrSurface(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
150        : INHERITED(gpu, lifeCycle)
151        , fDesc(desc)
152        , fReleaseProc(NULL)
153        , fReleaseCtx(NULL)
154    {}
155
156    ~GrSurface() override {
157        // check that invokeReleaseProc has been called (if needed)
158        SkASSERT(NULL == fReleaseProc);
159    }
160
161    GrSurfaceDesc fDesc;
162
163    void onRelease() override;
164    void onAbandon() override;
165
166private:
167    void invokeReleaseProc() {
168        if (fReleaseProc) {
169            fReleaseProc(fReleaseCtx);
170            fReleaseProc = NULL;
171        }
172    }
173
174    ReleaseProc fReleaseProc;
175    ReleaseCtx  fReleaseCtx;
176
177    typedef GrGpuResource INHERITED;
178};
179
180#endif
181