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 "GrGpuObject.h"
14#include "SkRect.h"
15
16class GrTexture;
17class GrRenderTarget;
18struct SkImageInfo;
19
20class GrSurface : public GrGpuObject {
21public:
22    SK_DECLARE_INST_COUNT(GrSurface);
23
24    /**
25     * Retrieves the width of the surface.
26     *
27     * @return the width in texels
28     */
29    int width() const { return fDesc.fWidth; }
30
31    /**
32     * Retrieves the height of the surface.
33     *
34     * @return the height in texels
35     */
36    int height() const { return fDesc.fHeight; }
37
38    /**
39     * Helper that gets the width and height of the surface as a bounding rectangle.
40     */
41    void getBoundsRect(SkRect* rect) const { rect->setWH(SkIntToScalar(this->width()),
42                                                         SkIntToScalar(this->height())); }
43
44    GrSurfaceOrigin origin() const {
45        SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin || kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
46        return fDesc.fOrigin;
47    }
48
49    /**
50     * Retrieves the pixel config specified when the surface was created.
51     * For render targets this can be kUnknown_GrPixelConfig
52     * if client asked us to render to a target that has a pixel
53     * config that isn't equivalent with one of our configs.
54     */
55    GrPixelConfig config() const { return fDesc.fConfig; }
56
57    /**
58     * Return the descriptor describing the surface
59     */
60    const GrTextureDesc& desc() const { return fDesc; }
61
62    SkImageInfo info() const;
63
64    /**
65     * @return the texture associated with the surface, may be NULL.
66     */
67    virtual GrTexture* asTexture() = 0;
68    virtual const GrTexture* asTexture() const = 0;
69
70    /**
71     * @return the render target underlying this surface, may be NULL.
72     */
73    virtual GrRenderTarget* asRenderTarget() = 0;
74    virtual const GrRenderTarget* asRenderTarget() const = 0;
75
76    /**
77     * Checks whether this GrSurface refers to the same GPU object as other. This
78     * catches the case where a GrTexture and GrRenderTarget refer to the same
79     * GPU memory.
80     */
81    bool isSameAs(const GrSurface* other) const {
82        const GrRenderTarget* thisRT = this->asRenderTarget();
83        if (NULL != thisRT) {
84            return thisRT == other->asRenderTarget();
85        } else {
86            const GrTexture* thisTex = this->asTexture();
87            SkASSERT(NULL != thisTex); // We must be one or the other
88            return thisTex == other->asTexture();
89        }
90    }
91
92    /**
93     * Reads a rectangle of pixels from the surface.
94     * @param left          left edge of the rectangle to read (inclusive)
95     * @param top           top edge of the rectangle to read (inclusive)
96     * @param width         width of rectangle to read in pixels.
97     * @param height        height of rectangle to read in pixels.
98     * @param config        the pixel config of the destination buffer
99     * @param buffer        memory to read the rectangle into.
100     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
101     *                      packed.
102     * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
103     *
104     * @return true if the read succeeded, false if not. The read can fail because of an unsupported
105     *              pixel config.
106     */
107    virtual bool readPixels(int left, int top, int width, int height,
108                            GrPixelConfig config,
109                            void* buffer,
110                            size_t rowBytes = 0,
111                            uint32_t pixelOpsFlags = 0) = 0;
112
113    /**
114     * Copy the src pixels [buffer, rowbytes, pixelconfig] into the surface at the specified
115     * rectangle.
116     * @param left          left edge of the rectangle to write (inclusive)
117     * @param top           top edge of the rectangle to write (inclusive)
118     * @param width         width of rectangle to write in pixels.
119     * @param height        height of rectangle to write in pixels.
120     * @param config        the pixel config of the source buffer
121     * @param buffer        memory to read the rectangle from.
122     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
123     *                      packed.
124     * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
125     */
126    virtual void writePixels(int left, int top, int width, int height,
127                             GrPixelConfig config,
128                             const void* buffer,
129                             size_t rowBytes = 0,
130                             uint32_t pixelOpsFlags = 0) = 0;
131
132    /**
133     * Write the contents of the surface to a PNG. Returns true if successful.
134     * @param filename      Full path to desired file
135     */
136    bool savePixels(const char* filename);
137
138protected:
139    GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
140    : INHERITED(gpu, isWrapped)
141    , fDesc(desc) {
142    }
143
144    GrTextureDesc fDesc;
145
146private:
147    typedef GrGpuObject INHERITED;
148};
149
150#endif // GrSurface_DEFINED
151