GrRenderTarget.h revision fbfcd5602128ec010c82cb733c9cdc0a3254f9f3
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 "GrSurface.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 GrSurface {
35public:
36    SK_DECLARE_INST_COUNT(GrRenderTarget)
37
38    // GrResource overrides
39    virtual size_t sizeInBytes() const SK_OVERRIDE;
40
41    // GrSurface overrides
42    /**
43     * @return the texture associated with the rendertarget, may be NULL.
44     */
45    virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; }
46    virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; }
47
48    /**
49     * @return this render target.
50     */
51    virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return this; }
52    virtual const GrRenderTarget* asRenderTarget() const  SK_OVERRIDE {
53        return this;
54    }
55
56    virtual bool readPixels(int left, int top, int width, int height,
57                            GrPixelConfig config,
58                            void* buffer,
59                            size_t rowBytes = 0,
60                            uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
61
62    virtual void writePixels(int left, int top, int width, int height,
63                             GrPixelConfig config,
64                             const void* buffer,
65                             size_t rowBytes = 0,
66                             uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
67
68    // GrRenderTarget
69    /**
70     * If this RT is multisampled, this is the multisample buffer
71     * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
72     */
73    virtual intptr_t getRenderTargetHandle() const = 0;
74
75    /**
76     * If this RT is multisampled, this is the buffer it is resolved to.
77     * Otherwise, same as getRenderTargetHandle().
78     * (In GL a separate FBO ID is used for the msaa and resolved buffers)
79     * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
80     */
81    virtual intptr_t getRenderTargetResolvedHandle() const = 0;
82
83    /**
84     * @return true if the surface is multisampled, false otherwise
85     */
86    bool isMultisampled() const { return 0 != fDesc.fSampleCnt; }
87
88    /**
89     * @return the number of samples-per-pixel or zero if non-MSAA.
90     */
91    int numSamples() const { return fDesc.fSampleCnt; }
92
93    /**
94     * Call to indicate the multisample contents were modified such that the
95     * render target needs to be resolved before it can be used as texture. Gr
96     * tracks this for its own drawing and thus this only needs to be called
97     * when the render target has been modified outside of Gr. Only meaningful
98     * for Gr-created RT/Textures and Platform RT/Textures created with the
99     * kGrCanResolve flag.
100     * @param rect  a rect bounding the area needing resolve. NULL indicates
101     *              the whole RT needs resolving.
102     */
103    void flagAsNeedingResolve(const GrIRect* rect = NULL);
104
105    /**
106     * Call to override the region that needs to be resolved.
107     */
108    void overrideResolveRect(const GrIRect rect);
109
110    /**
111     * Call to indicate that GrRenderTarget was externally resolved. This may
112     * allow Gr to skip a redundant resolve step.
113     */
114    void flagAsResolved() { fResolveRect.setLargestInverted(); }
115
116    /**
117     * @return true if the GrRenderTarget requires MSAA resolving
118     */
119    bool needsResolve() const { return !fResolveRect.isEmpty(); }
120
121    /**
122     * Returns a rect bounding the region needing resolving.
123     */
124    const GrIRect& getResolveRect() const { return fResolveRect; }
125
126    /**
127     * If the render target is multisampled this will perform a multisample
128     * resolve. Any pending draws to the target are first flushed. This only
129     * applies to render targets that are associated with GrTextures. After the
130     * function returns the GrTexture will contain the resolved pixels.
131     */
132    void resolve();
133
134    // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
135    // 0 in GL), or be unresolvable because the client didn't give us the
136    // resolve destination.
137    enum ResolveType {
138        kCanResolve_ResolveType,
139        kAutoResolves_ResolveType,
140        kCantResolve_ResolveType,
141    };
142    virtual ResolveType getResolveType() const = 0;
143
144    /**
145     * GrStencilBuffer is not part of the public API.
146     */
147    GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
148    void setStencilBuffer(GrStencilBuffer* stencilBuffer);
149
150protected:
151    GrRenderTarget(GrGpu* gpu,
152                   GrTexture* texture,
153                   const GrTextureDesc& desc)
154        : INHERITED(gpu, desc)
155        , fStencilBuffer(NULL)
156        , fTexture(texture) {
157        fResolveRect.setLargestInverted();
158    }
159
160    friend class GrTexture;
161    // When a texture unrefs an owned rendertarget this func
162    // removes the back pointer. This could be called from
163    // texture's destructor but would have to be done in derived
164    // classes. By the time of texture base destructor it has already
165    // lost its pointer to the rt.
166    void onTextureReleaseRenderTarget() {
167        GrAssert(NULL != fTexture);
168        fTexture = NULL;
169    }
170
171private:
172    GrStencilBuffer*  fStencilBuffer;
173    GrTexture*        fTexture; // not ref'ed
174
175    GrIRect           fResolveRect;
176
177    typedef GrSurface INHERITED;
178};
179
180#endif
181