1/*
2    Copyright 2011 Google Inc.
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8         http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 */
16
17
18#ifndef GrRenderTarget_DEFINED
19#define GrRenderTarget_DEFINED
20
21#include "GrRect.h"
22#include "GrResource.h"
23
24class GrStencilBuffer;
25class GrTexture;
26
27/**
28 * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
29 * A context's render target is set by setRenderTarget(). Render targets are
30 * created by a createTexture with the kRenderTarget_TextureFlag flag.
31 * Additionally, GrContext provides methods for creating GrRenderTargets
32 * that wrap externally created render targets.
33 */
34class GrRenderTarget : public GrResource {
35public:
36
37    /**
38     * @return the width of the rendertarget
39     */
40    int width() const { return fWidth; }
41    /**
42     * @return the height of the rendertarget
43     */
44    int height() const { return fHeight; }
45
46    /**
47     * @return the pixel config. Can be kUnknown_GrPixelConfig
48     * if client asked us to render to a target that has a pixel
49     * config that isn't equivalent with one of our configs.
50     */
51    GrPixelConfig config() const { return fConfig; }
52
53    /**
54     * @return the texture associated with the rendertarget, may be NULL.
55     */
56    GrTexture* asTexture() {return fTexture;}
57
58    /**
59     * If this RT is multisampled, this is the multisample buffer
60     * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
61     */
62    virtual intptr_t getRenderTargetHandle() const = 0;
63
64    /**
65     * If this RT is multisampled, this is the buffer it is resolved to.
66     * Otherwise, same as getRenderTargetHandle().
67     * (In GL a separate FBO ID is used for the msaa and resolved buffers)
68     * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
69     */
70    virtual intptr_t getRenderTargetResolvedHandle() const = 0;
71
72    /**
73     * @return true if the render target is multisampled, false otherwise
74     */
75    bool isMultisampled() const { return 0 != fSampleCnt; }
76
77    /**
78     * @return the number of samples-per-pixel or zero if non-MSAA.
79     */
80    int numSamples() const { return fSampleCnt; }
81
82    /**
83     * Call to indicate the multisample contents were modified such that the
84     * render target needs to be resolved before it can be used as texture. Gr
85     * tracks this for its own drawing and thus this only needs to be called
86     * when the render target has been modified outside of Gr. Only meaningful
87     * for Gr-created RT/Textures and Platform RT/Textures created with the
88     * kGrCanResolve flag.
89     * @param rect  a rect bounding the area needing resolve. NULL indicates
90     *              the whole RT needs resolving.
91     */
92    void flagAsNeedingResolve(const GrIRect* rect = NULL);
93
94    /**
95     * Call to override the region that needs to be resolved.
96     */
97    void overrideResolveRect(const GrIRect rect);
98
99    /**
100     * Call to indicate that GrRenderTarget was externally resolved. This may
101     * allow Gr to skip a redundant resolve step.
102     */
103    void flagAsResolved() { fResolveRect.setLargestInverted(); }
104
105    /**
106     * @return true if the GrRenderTarget requires MSAA resolving
107     */
108    bool needsResolve() const { return !fResolveRect.isEmpty(); }
109
110    /**
111     * Returns a rect bounding the region needing resolving.
112     */
113    const GrIRect& getResolveRect() const { return fResolveRect; }
114
115    /**
116     * If the render target is multisampled this will perform a multisample
117     * resolve. Any pending draws to the target are first flushed. This only
118     * applies to render targets that are associated with GrTextures. After the
119     * function returns the GrTexture will contain the resolved pixels.
120     */
121    void resolve();
122
123    // GrResource overrides
124    virtual size_t sizeInBytes() const;
125
126    /**
127     * Reads a rectangle of pixels from the render target.
128     * @param left          left edge of the rectangle to read (inclusive)
129     * @param top           top edge of the rectangle to read (inclusive)
130     * @param width         width of rectangle to read in pixels.
131     * @param height        height of rectangle to read in pixels.
132     * @param config        the pixel config of the destination buffer
133     * @param buffer        memory to read the rectangle into.
134     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
135     *                      means rows are tightly packed.
136     *
137     * @return true if the read succeeded, false if not. The read can fail
138     *              because of an unsupported pixel config.
139     */
140    bool readPixels(int left, int top, int width, int height,
141                    GrPixelConfig config, void* buffer, size_t rowBytes);
142
143    /**
144     * Copy the src pixels [buffer, rowbytes, pixelconfig] into the render
145     * target at the specified rectangle.
146     * @param left          left edge of the rectangle to write (inclusive)
147     * @param top           top edge of the rectangle to write (inclusive)
148     * @param width         width of rectangle to write in pixels.
149     * @param height        height of rectangle to write in pixels.
150     * @param config        the pixel config of the source buffer
151     * @param buffer        memory to read the rectangle from.
152     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
153     *                      means rows are tightly packed.
154     */
155    void writePixels(int left, int top, int width, int height,
156                     GrPixelConfig config, const void* buffer, size_t rowBytes);
157
158    // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
159    // 0 in GL), or be unresolvable because the client didn't give us the
160    // resolve destination.
161    enum ResolveType {
162        kCanResolve_ResolveType,
163        kAutoResolves_ResolveType,
164        kCantResolve_ResolveType,
165    };
166    virtual ResolveType getResolveType() const = 0;
167
168    /**
169     * GrStencilBuffer is not part of the public API.
170     */
171    GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
172    void setStencilBuffer(GrStencilBuffer* stencilBuffer);
173
174protected:
175    GrRenderTarget(GrGpu* gpu,
176                   GrTexture* texture,
177                   int width,
178                   int height,
179                   GrPixelConfig config,
180                   int sampleCnt)
181        : INHERITED(gpu)
182        , fStencilBuffer(NULL)
183        , fTexture(texture)
184        , fWidth(width)
185        , fHeight(height)
186        , fConfig(config)
187        , fSampleCnt(sampleCnt) {
188        fResolveRect.setLargestInverted();
189    }
190
191    friend class GrTexture;
192    // When a texture unrefs an owned rendertarget this func
193    // removes the back pointer. This could be done called from
194    // texture's destructor but would have to be done in derived
195    // class. By the time of texture base destructor it has already
196    // lost its pointer to the rt.
197    void onTextureReleaseRenderTarget() {
198        GrAssert(NULL != fTexture);
199        fTexture = NULL;
200    }
201
202private:
203    GrStencilBuffer*  fStencilBuffer;
204    GrTexture*        fTexture; // not ref'ed
205    int               fWidth;
206    int               fHeight;
207    GrPixelConfig     fConfig;
208    int               fSampleCnt;
209    GrIRect           fResolveRect;
210
211    typedef GrResource INHERITED;
212};
213
214#endif
215