1 //
2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer
8 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
9 
10 #ifndef LIBANGLE_FRAMEBUFFER_H_
11 #define LIBANGLE_FRAMEBUFFER_H_
12 
13 #include <vector>
14 
15 #include "common/Optional.h"
16 #include "common/angleutils.h"
17 #include "libANGLE/Constants.h"
18 #include "libANGLE/Debug.h"
19 #include "libANGLE/Error.h"
20 #include "libANGLE/FramebufferAttachment.h"
21 #include "libANGLE/RefCountObject.h"
22 #include "libANGLE/signal_utils.h"
23 
24 namespace rx
25 {
26 class ContextImpl;
27 class GLImplFactory;
28 class FramebufferImpl;
29 class RenderbufferImpl;
30 class SurfaceImpl;
31 }
32 
33 namespace egl
34 {
35 class Surface;
36 }
37 
38 namespace gl
39 {
40 class Context;
41 class Framebuffer;
42 class Renderbuffer;
43 class State;
44 class Texture;
45 class TextureCapsMap;
46 struct Caps;
47 class ContextState;
48 struct Extensions;
49 struct ImageIndex;
50 struct Rectangle;
51 
52 class FramebufferState final : angle::NonCopyable
53 {
54   public:
55     FramebufferState();
56     explicit FramebufferState(const Caps &caps);
57     ~FramebufferState();
58 
59     const std::string &getLabel();
60 
61     const FramebufferAttachment *getAttachment(GLenum attachment) const;
62     const FramebufferAttachment *getReadAttachment() const;
63     const FramebufferAttachment *getFirstColorAttachment() const;
64     const FramebufferAttachment *getDepthOrStencilAttachment() const;
65     const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
66     const FramebufferAttachment *getDepthAttachment() const;
67     const FramebufferAttachment *getStencilAttachment() const;
68     const FramebufferAttachment *getDepthStencilAttachment() const;
69 
getDrawBufferStates()70     const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
getReadBufferState()71     GLenum getReadBufferState() const { return mReadBufferState; }
getColorAttachments()72     const std::vector<FramebufferAttachment> &getColorAttachments() const
73     {
74         return mColorAttachments;
75     }
76 
77     bool attachmentsHaveSameDimensions() const;
78     bool colorAttachmentsAreUniqueImages() const;
79 
80     const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const;
81     size_t getDrawBufferCount() const;
82 
83   private:
84     friend class Framebuffer;
85 
86     std::string mLabel;
87 
88     std::vector<FramebufferAttachment> mColorAttachments;
89     FramebufferAttachment mDepthAttachment;
90     FramebufferAttachment mStencilAttachment;
91 
92     std::vector<GLenum> mDrawBufferStates;
93     GLenum mReadBufferState;
94 };
95 
96 class Framebuffer final : public LabeledObject, public angle::SignalReceiver
97 {
98   public:
99     Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id);
100     Framebuffer(rx::SurfaceImpl *surface);
101     virtual ~Framebuffer();
102 
103     void setLabel(const std::string &label) override;
104     const std::string &getLabel() const override;
105 
getImplementation()106     rx::FramebufferImpl *getImplementation() const { return mImpl; }
107 
id()108     GLuint id() const { return mId; }
109 
110     void setAttachment(GLenum type,
111                        GLenum binding,
112                        const ImageIndex &textureIndex,
113                        FramebufferAttachmentObject *resource);
114     void resetAttachment(GLenum binding);
115 
116     void detachTexture(GLuint texture);
117     void detachRenderbuffer(GLuint renderbuffer);
118 
119     const FramebufferAttachment *getColorbuffer(size_t colorAttachment) const;
120     const FramebufferAttachment *getDepthbuffer() const;
121     const FramebufferAttachment *getStencilbuffer() const;
122     const FramebufferAttachment *getDepthStencilBuffer() const;
123     const FramebufferAttachment *getDepthOrStencilbuffer() const;
124     const FramebufferAttachment *getReadColorbuffer() const;
125     GLenum getReadColorbufferType() const;
126     const FramebufferAttachment *getFirstColorbuffer() const;
127 
128     const FramebufferAttachment *getAttachment(GLenum attachment) const;
129 
130     size_t getDrawbufferStateCount() const;
131     GLenum getDrawBufferState(size_t drawBuffer) const;
132     const std::vector<GLenum> &getDrawBufferStates() const;
133     void setDrawBuffers(size_t count, const GLenum *buffers);
134     const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
135     bool hasEnabledDrawBuffer() const;
136 
137     GLenum getReadBufferState() const;
138     void setReadBuffer(GLenum buffer);
139 
140     size_t getNumColorBuffers() const;
141     bool hasDepth() const;
142     bool hasStencil() const;
143 
144     bool usingExtendedDrawBuffers() const;
145 
146     // This method calls checkStatus.
147     int getSamples(const ContextState &state);
148     GLenum checkStatus(const ContextState &state);
149 
150     // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
151     bool complete(const ContextState &state);
152 
153     bool hasValidDepthStencil() const;
154 
155     Error discard(size_t count, const GLenum *attachments);
156     Error invalidate(size_t count, const GLenum *attachments);
157     Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
158 
159     Error clear(rx::ContextImpl *context, GLbitfield mask);
160     Error clearBufferfv(rx::ContextImpl *context,
161                         GLenum buffer,
162                         GLint drawbuffer,
163                         const GLfloat *values);
164     Error clearBufferuiv(rx::ContextImpl *context,
165                          GLenum buffer,
166                          GLint drawbuffer,
167                          const GLuint *values);
168     Error clearBufferiv(rx::ContextImpl *context,
169                         GLenum buffer,
170                         GLint drawbuffer,
171                         const GLint *values);
172     Error clearBufferfi(rx::ContextImpl *context,
173                         GLenum buffer,
174                         GLint drawbuffer,
175                         GLfloat depth,
176                         GLint stencil);
177 
178     GLenum getImplementationColorReadFormat() const;
179     GLenum getImplementationColorReadType() const;
180     Error readPixels(rx::ContextImpl *context,
181                      const gl::Rectangle &area,
182                      GLenum format,
183                      GLenum type,
184                      GLvoid *pixels) const;
185 
186     Error blit(rx::ContextImpl *context,
187                const Rectangle &sourceArea,
188                const Rectangle &destArea,
189                GLbitfield mask,
190                GLenum filter);
191 
192     enum DirtyBitType
193     {
194         DIRTY_BIT_COLOR_ATTACHMENT_0,
195         DIRTY_BIT_COLOR_ATTACHMENT_MAX =
196             DIRTY_BIT_COLOR_ATTACHMENT_0 + gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS,
197         DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX,
198         DIRTY_BIT_STENCIL_ATTACHMENT,
199         DIRTY_BIT_DRAW_BUFFERS,
200         DIRTY_BIT_READ_BUFFER,
201         DIRTY_BIT_UNKNOWN,
202         DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN,
203     };
204 
205     typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
hasAnyDirtyBit()206     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
207 
208     void syncState();
209 
210     // angle::SignalReceiver implementation
211     void signal(angle::SignalToken token) override;
212 
213   private:
214     void detachResourceById(GLenum resourceType, GLuint resourceId);
215     void detachMatchingAttachment(FramebufferAttachment *attachment,
216                                   GLenum matchType,
217                                   GLuint matchId,
218                                   size_t dirtyBit);
219     GLenum checkStatusImpl(const ContextState &state);
220 
221     FramebufferState mState;
222     rx::FramebufferImpl *mImpl;
223     GLuint mId;
224 
225     Optional<GLenum> mCachedStatus;
226     std::vector<angle::ChannelBinding> mDirtyColorAttachmentBindings;
227     angle::ChannelBinding mDirtyDepthAttachmentBinding;
228     angle::ChannelBinding mDirtyStencilAttachmentBinding;
229 
230     DirtyBits mDirtyBits;
231 };
232 
233 }  // namespace gl
234 
235 #endif   // LIBANGLE_FRAMEBUFFER_H_
236