1 /*
2  * Copyright 2011 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 #ifndef GrRenderTarget_DEFINED
9 #define GrRenderTarget_DEFINED
10 
11 #include "GrSurface.h"
12 #include "SkRect.h"
13 
14 class GrCaps;
15 class GrRenderTargetOpList;
16 class GrRenderTargetPriv;
17 class GrStencilAttachment;
18 
19 /**
20  * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
21  * A context's render target is set by setRenderTarget(). Render targets are
22  * created by a createTexture with the kRenderTarget_SurfaceFlag flag.
23  * Additionally, GrContext provides methods for creating GrRenderTargets
24  * that wrap externally created render targets.
25  */
26 class GrRenderTarget : virtual public GrSurface {
27 public:
28     // GrSurface overrides
asRenderTarget()29     GrRenderTarget* asRenderTarget() override { return this; }
asRenderTarget()30     const GrRenderTarget* asRenderTarget() const  override { return this; }
31 
32     // GrRenderTarget
isStencilBufferMultisampled()33     bool isStencilBufferMultisampled() const { return fDesc.fSampleCnt > 0; }
34 
35     /**
36      * For our purposes, "Mixed Sampled" means the stencil buffer is multisampled but the color
37      * buffer is not.
38      */
isMixedSampled()39     bool isMixedSampled() const { return fFlags & Flags::kMixedSampled; }
40 
41     /**
42      * "Unified Sampled" means the stencil and color buffers are both multisampled.
43      */
isUnifiedMultisampled()44     bool isUnifiedMultisampled() const { return fDesc.fSampleCnt > 0 && !this->isMixedSampled(); }
45 
46     /**
47      * Returns the number of samples/pixel in the stencil buffer (Zero if non-MSAA).
48      */
numStencilSamples()49     int numStencilSamples() const { return fDesc.fSampleCnt; }
50 
51     /**
52      * Returns the number of samples/pixel in the color buffer (Zero if non-MSAA or mixed sampled).
53      */
numColorSamples()54     int numColorSamples() const { return this->isMixedSampled() ? 0 : fDesc.fSampleCnt; }
55 
56     /**
57      * Call to indicate the multisample contents were modified such that the
58      * render target needs to be resolved before it can be used as texture. Gr
59      * tracks this for its own drawing and thus this only needs to be called
60      * when the render target has been modified outside of Gr. This has no
61      * effect on wrapped backend render targets.
62      *
63      * @param rect  a rect bounding the area needing resolve. NULL indicates
64      *              the whole RT needs resolving.
65      */
66     void flagAsNeedingResolve(const SkIRect* rect = NULL);
67 
68     /**
69      * Call to override the region that needs to be resolved.
70      */
71     void overrideResolveRect(const SkIRect rect);
72 
73     /**
74      * Call to indicate that GrRenderTarget was externally resolved. This may
75      * allow Gr to skip a redundant resolve step.
76      */
flagAsResolved()77     void flagAsResolved() { fResolveRect.setLargestInverted(); }
78 
79     /**
80      * @return true if the GrRenderTarget requires MSAA resolving
81      */
needsResolve()82     bool needsResolve() const { return !fResolveRect.isEmpty(); }
83 
84     /**
85      * Returns a rect bounding the region needing resolving.
86      */
getResolveRect()87     const SkIRect& getResolveRect() const { return fResolveRect; }
88 
89     /**
90      * Provide a performance hint that the render target's contents are allowed
91      * to become undefined.
92      */
93     void discard();
94 
95     // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
96     // 0 in GL), or be unresolvable because the client didn't give us the
97     // resolve destination.
98     enum ResolveType {
99         kCanResolve_ResolveType,
100         kAutoResolves_ResolveType,
101         kCantResolve_ResolveType,
102     };
103     virtual ResolveType getResolveType() const = 0;
104 
105     /**
106      *  Return the native ID or handle to the rendertarget, depending on the
107      *  platform. e.g. on OpenGL, return the FBO ID.
108      */
109     virtual GrBackendObject getRenderTargetHandle() const = 0;
110 
111     // Checked when this object is asked to attach a stencil buffer.
112     virtual bool canAttemptStencilAttachment() const = 0;
113 
114     // Provides access to functions that aren't part of the public API.
115     GrRenderTargetPriv renderTargetPriv();
116     const GrRenderTargetPriv renderTargetPriv() const;
117 
118 protected:
119     enum class Flags {
120         kNone                = 0,
121         kMixedSampled        = 1 << 0,
122         kWindowRectsSupport  = 1 << 1
123     };
124 
125     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
126 
127     GrRenderTarget(GrGpu*, const GrSurfaceDesc&, Flags = Flags::kNone,
128                    GrStencilAttachment* = nullptr);
129 
130     // override of GrResource
131     void onAbandon() override;
132     void onRelease() override;
133 
134 private:
135     // Allows the backends to perform any additional work that is required for attaching a
136     // GrStencilAttachment. When this is called, the GrStencilAttachment has already been put onto
137     // the GrRenderTarget. This function must return false if any failures occur when completing the
138     // stencil attachment.
139     virtual bool completeStencilAttachment() = 0;
140 
141     friend class GrRenderTargetPriv;
142     friend class GrRenderTargetProxy; // for Flags
143 
144     GrStencilAttachment*  fStencilAttachment;
145     uint8_t               fMultisampleSpecsID;
146     Flags                 fFlags;
147 
148     SkIRect               fResolveRect;
149 
150     typedef GrSurface INHERITED;
151 };
152 
153 GR_MAKE_BITFIELD_CLASS_OPS(GrRenderTarget::Flags);
154 
155 #endif
156