blob: e489536aa438d2a501bf207da6b1f36312b8d190 [file] [log] [blame]
rvargas@google.comdd255042012-03-05 20:14:171// Copyright (c) 2012 The Chromium Authors. All rights reserved.
gman@chromium.orga25fa872010-03-25 02:57:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
6#define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
7
avif15d60a2015-12-21 17:06:338#include <stddef.h>
9#include <stdint.h>
10
mostynb6682b1c42016-04-19 10:17:3011#include <memory>
reveman@chromium.org4aada5a92013-11-01 13:45:0012#include <vector>
13
brettw@chromium.org14c1c232013-06-11 17:52:4414#include "base/containers/hash_tables.h"
avif15d60a2015-12-21 17:06:3315#include "base/macros.h"
levin@chromium.org3b63f8f42011-03-28 01:54:1516#include "base/memory/ref_counted.h"
zmoa0ee95e2015-07-11 01:33:1117#include "gpu/command_buffer/service/context_group.h"
gman@chromium.orga25fa872010-03-25 02:57:5818#include "gpu/command_buffer/service/gl_utils.h"
zmoeaae3bb2016-07-15 19:23:1919#include "gpu/command_buffer/service/shader_manager.h"
rvargas@google.comdd255042012-03-05 20:14:1720#include "gpu/gpu_export.h"
gman@chromium.orga25fa872010-03-25 02:57:5821
22namespace gpu {
23namespace gles2 {
24
zmo59b6cc52016-01-30 02:35:5925class FeatureInfo;
tobiasjsfc199b472015-08-22 00:39:0626class FramebufferCompletenessCache;
gman@chromium.orged9f9cd2013-02-27 21:12:3527class FramebufferManager;
gman@chromium.org31494b82013-02-28 10:10:2628class Renderbuffer;
29class RenderbufferManager;
30class Texture;
piman@chromium.org370eaf12013-05-18 09:19:4931class TextureRef;
gman@chromium.org31494b82013-02-28 10:10:2632class TextureManager;
gman@chromium.orged9f9cd2013-02-27 21:12:3533
34// Info about a particular Framebuffer.
35class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
36 public:
37 class Attachment : public base::RefCounted<Attachment> {
38 public:
39 virtual GLsizei width() const = 0;
40 virtual GLsizei height() const = 0;
41 virtual GLenum internal_format() const = 0;
geofflang@chromium.org68586372013-12-11 01:27:5942 virtual GLenum texture_type() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3543 virtual GLsizei samples() const = 0;
piman@chromium.org62e65f02013-05-29 22:28:1044 virtual GLuint object_name() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3545 virtual bool cleared() const = 0;
46 virtual void SetCleared(
47 RenderbufferManager* renderbuffer_manager,
48 TextureManager* texture_manager,
49 bool cleared) = 0;
zmod252e3ea2016-02-23 00:38:1750 virtual bool IsPartiallyCleared() const = 0;
51 virtual bool IsTextureAttachment() const = 0;
52 virtual bool IsRenderbufferAttachment() const = 0;
piman@chromium.org370eaf12013-05-18 09:19:4953 virtual bool IsTexture(TextureRef* texture) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3554 virtual bool IsRenderbuffer(
55 Renderbuffer* renderbuffer) const = 0;
zmod252e3ea2016-02-23 00:38:1756 virtual bool Is3D() const = 0;
zmodda9c292016-05-31 19:04:1957
58 // If it's a 3D texture attachment, return true if
59 // FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is smaller than the number of
60 // layers in the texture.
61 virtual bool IsLayerValid() const = 0;
62
zmo59b6cc52016-01-30 02:35:5963 virtual bool CanRenderTo(const FeatureInfo* feature_info) const = 0;
reveman@chromium.org91c94eb2013-10-22 10:32:5464 virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0;
avif15d60a2015-12-21 17:06:3365 virtual bool ValidForAttachmentType(GLenum attachment_type,
zmo08c9d1e2016-02-09 20:15:5366 ContextType context_type,
avif15d60a2015-12-21 17:06:3367 uint32_t max_color_attachments) = 0;
dyencb017312014-09-29 18:16:2068 virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3569 virtual void AddToSignature(
70 TextureManager* texture_manager, std::string* signature) const = 0;
zmo383512cf2014-10-14 00:11:0071 virtual bool FormsFeedbackLoop(TextureRef* texture, GLint level) const = 0;
erikchen6e484562016-04-16 01:23:3972 virtual bool EmulatingRGB() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3573
74 protected:
75 friend class base::RefCounted<Attachment>;
76 virtual ~Attachment() {}
77 };
78
79 Framebuffer(FramebufferManager* manager, GLuint service_id);
80
81 GLuint service_id() const {
82 return service_id_;
83 }
84
85 bool HasUnclearedAttachment(GLenum attachment) const;
zmo@chromium.orgee757922014-06-06 05:21:4286 bool HasUnclearedColorAttachments() const;
gman@chromium.orged9f9cd2013-02-27 21:12:3587
zmo9d631972016-06-17 23:31:0488 bool HasSRGBAttachments() const;
89
zmod252e3ea2016-02-23 00:38:1790 void ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures(
91 GLES2Decoder* decoder,
92 TextureManager* texture_manager);
93
94 bool HasUnclearedIntRenderbufferAttachments() const;
95
96 void ClearUnclearedIntRenderbufferAttachments(
97 RenderbufferManager* renderbuffer_manager);
98
gman@chromium.orged9f9cd2013-02-27 21:12:3599 void MarkAttachmentAsCleared(
100 RenderbufferManager* renderbuffer_manager,
101 TextureManager* texture_manager,
102 GLenum attachment,
103 bool cleared);
104
vmiura7d08fee52015-02-18 18:39:34105 // Unbinds all attachments from this framebuffer for workaround
106 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
107 // bound when calling this.
108 void DoUnbindGLAttachmentsForWorkaround(GLenum target);
109
gman@chromium.orged9f9cd2013-02-27 21:12:35110 // Attaches a renderbuffer to a particlar attachment.
111 // Pass null to detach.
112 void AttachRenderbuffer(
113 GLenum attachment, Renderbuffer* renderbuffer);
114
115 // Attaches a texture to a particlar attachment. Pass null to detach.
116 void AttachTexture(
piman@chromium.org370eaf12013-05-18 09:19:49117 GLenum attachment, TextureRef* texture_ref, GLenum target,
bsalomon@google.com7d3c36e2013-07-12 14:13:16118 GLint level, GLsizei samples);
qiankun.miao3071b532015-10-30 09:30:32119 void AttachTextureLayer(
120 GLenum attachment, TextureRef* texture_ref, GLenum target,
121 GLint level, GLint layer);
gman@chromium.orged9f9cd2013-02-27 21:12:35122
123 // Unbinds the given renderbuffer if it is bound.
124 void UnbindRenderbuffer(
125 GLenum target, Renderbuffer* renderbuffer);
126
127 // Unbinds the given texture if it is bound.
128 void UnbindTexture(
piman@chromium.org370eaf12013-05-18 09:19:49129 GLenum target, TextureRef* texture_ref);
gman@chromium.orged9f9cd2013-02-27 21:12:35130
131 const Attachment* GetAttachment(GLenum attachment) const;
132
zmo02f3a302015-08-05 22:30:38133 const Attachment* GetReadBufferAttachment() const;
134
zmoa432bd182016-06-08 21:52:27135 GLsizei GetSamples() const;
136
gman@chromium.orged9f9cd2013-02-27 21:12:35137 bool IsDeleted() const {
138 return deleted_;
139 }
140
141 void MarkAsValid() {
142 has_been_bound_ = true;
143 }
144
145 bool IsValid() const {
146 return has_been_bound_ && !IsDeleted();
147 }
148
cwallezaafbfa02016-07-06 17:13:58149 bool HasColorAttachment(int index) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35150 bool HasDepthAttachment() const;
151 bool HasStencilAttachment() const;
zmoa432bd182016-06-08 21:52:27152 GLenum GetDepthFormat() const;
153 GLenum GetStencilFormat() const;
zmo21608f882015-08-07 21:49:43154 GLenum GetDrawBufferInternalFormat() const;
155 GLenum GetReadBufferInternalFormat() const;
geofflang@chromium.org68586372013-12-11 01:27:59156 // If the color attachment is a texture, returns its type; otherwise,
157 // returns 0.
zmo21608f882015-08-07 21:49:43158 GLenum GetReadBufferTextureType() const;
gman@chromium.orged9f9cd2013-02-27 21:12:35159
160 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
161 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
162 // use this combination of attachments. Otherwise returns the value
163 // that glCheckFramebufferStatus should return for this set of attachments.
164 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
165 // not mean the real OpenGL will consider it framebuffer complete. It just
166 // means it passed our tests.
zmo59b6cc52016-01-30 02:35:59167 GLenum IsPossiblyComplete(const FeatureInfo* feature_info) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35168
169 // Implements optimized glGetFramebufferStatus.
170 GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
171
172 // Check all attachments are cleared
173 bool IsCleared() const;
174
zmo@chromium.org2f143d482013-03-14 18:04:49175 GLenum GetDrawBuffer(GLenum draw_buffer) const;
176
177 void SetDrawBuffers(GLsizei n, const GLenum* bufs);
178
zmo@chromium.orgee757922014-06-06 05:21:42179 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
180 // draw buffer for glClear().
zmod252e3ea2016-02-23 00:38:17181 // Return true if the DrawBuffers() is actually called.
zmoeaae3bb2016-07-15 19:23:19182 bool PrepareDrawBuffersForClearingUninitializedAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42183
zmoeaae3bb2016-07-15 19:23:19184 // Restore |adjusted_draw_buffers_|.
185 void RestoreDrawBuffers() const;
186
187 // Checks if a draw buffer's format and its corresponding fragment shader
188 // output's type are compatible, i.e., a signed integer typed variable is
189 // incompatible with a float or unsigned integer buffer.
190 // Return false if incompaticle.
191 // Otherwise, filter out the draw buffers that are not written to but are not
192 // NONE through DrawBuffers, to be on the safe side. Return true.
193 // This is applied before a draw call.
194 bool ValidateAndAdjustDrawBuffers(uint32_t fragment_output_type_mask,
195 uint32_t fragment_output_written_mask);
196
197 bool ContainsActiveIntegerAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42198
zmo@chromium.orgf3b191b2013-06-19 03:43:54199 // Return true if any draw buffers has an alpha channel.
200 bool HasAlphaMRT() const;
201
zmo21608f882015-08-07 21:49:43202 // Return false if any two active color attachments have different internal
203 // formats.
204 bool HasSameInternalFormatsMRT() const;
205
zmo02f3a302015-08-05 22:30:38206 void set_read_buffer(GLenum read_buffer) {
207 read_buffer_ = read_buffer;
208 }
209
210 GLenum read_buffer() const {
211 return read_buffer_;
212 }
213
zmoeaae3bb2016-07-15 19:23:19214 // See member declaration for details.
215 // The data are only valid if fbo is complete.
216 uint32_t draw_buffer_type_mask() const {
217 return draw_buffer_type_mask_;
218 }
219 uint32_t draw_buffer_bound_mask() const {
220 return draw_buffer_bound_mask_;
221 }
222
gman@chromium.orged9f9cd2013-02-27 21:12:35223 private:
224 friend class FramebufferManager;
225 friend class base::RefCounted<Framebuffer>;
226
227 ~Framebuffer();
228
229 void MarkAsDeleted();
230
231 void MarkAttachmentsAsCleared(
232 RenderbufferManager* renderbuffer_manager,
233 TextureManager* texture_manager,
234 bool cleared);
235
236 void MarkAsComplete(unsigned state_id) {
zmoeaae3bb2016-07-15 19:23:19237 UpdateDrawBufferMasks();
gman@chromium.orged9f9cd2013-02-27 21:12:35238 framebuffer_complete_state_count_id_ = state_id;
239 }
240
241 unsigned framebuffer_complete_state_count_id() const {
242 return framebuffer_complete_state_count_id_;
243 }
244
zmoeaae3bb2016-07-15 19:23:19245 // Cache color attachments' base type mask (FLOAT, INT, UINT) and bound mask.
246 // If an attachment point has no image, it's set as UNDEFINED_TYPE.
247 // This call is only valid on a complete fbo.
248 void UpdateDrawBufferMasks();
249
gman@chromium.orged9f9cd2013-02-27 21:12:35250 // The managers that owns this.
251 FramebufferManager* manager_;
252
253 bool deleted_;
254
255 // Service side framebuffer id.
256 GLuint service_id_;
257
258 // Whether this framebuffer has ever been bound.
259 bool has_been_bound_;
260
261 // state count when this framebuffer was last checked for completeness.
262 unsigned framebuffer_complete_state_count_id_;
263
264 // A map of attachments.
265 typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
266 AttachmentMap attachments_;
267
zmoeaae3bb2016-07-15 19:23:19268 // User's draw buffers setting through DrawBuffers() call.
mostynb6682b1c42016-04-19 10:17:30269 std::unique_ptr<GLenum[]> draw_buffers_;
zmo@chromium.org2f143d482013-03-14 18:04:49270
zmoeaae3bb2016-07-15 19:23:19271 // If a draw buffer does not have an image, or it has no corresponding
272 // fragment shader output variable, it might be filtered out as NONE.
273 // Note that the actually draw buffers setting sent to the driver is always
274 // consistent with |adjusted_draw_buffers_|, not |draw_buffers_|.
275 std::unique_ptr<GLenum[]> adjusted_draw_buffers_;
276
277 // Draw buffer base types: FLOAT, INT, or UINT.
278 // We have up to 16 draw buffers, each is encoded into 2 bits, total 32 bits:
279 // the lowest 2 bits for draw buffer 0, the highest 2 bits for draw buffer 15.
280 uint32_t draw_buffer_type_mask_;
281 // Same layout as above, 2 bits per draw buffer, 0x03 if a draw buffer has a
282 // bound image, 0x00 if not.
283 uint32_t draw_buffer_bound_mask_;
284 // This is the mask for the actual draw buffers sent to driver.
285 uint32_t adjusted_draw_buffer_bound_mask_;
286
zmo02f3a302015-08-05 22:30:38287 GLenum read_buffer_;
288
gman@chromium.orged9f9cd2013-02-27 21:12:35289 DISALLOW_COPY_AND_ASSIGN(Framebuffer);
290};
291
kloveless@chromium.orgc986af502013-08-14 01:04:44292struct DecoderFramebufferState {
kloveless@chromium.org9d3b2e12013-10-02 01:04:34293 DecoderFramebufferState();
294 ~DecoderFramebufferState();
kloveless@chromium.orgc986af502013-08-14 01:04:44295
296 // State saved for clearing so we can clear render buffers and then
297 // restore to these values.
298 bool clear_state_dirty;
kloveless@chromium.org9d3b2e12013-10-02 01:04:34299
300 // The currently bound framebuffers
301 scoped_refptr<Framebuffer> bound_read_framebuffer;
302 scoped_refptr<Framebuffer> bound_draw_framebuffer;
kloveless@chromium.orgc986af502013-08-14 01:04:44303};
304
gman@chromium.orga25fa872010-03-25 02:57:58305// This class keeps track of the frambebuffers and their attached renderbuffers
306// so we can correctly clear them.
rvargas@google.comdd255042012-03-05 20:14:17307class GPU_EXPORT FramebufferManager {
gman@chromium.orga25fa872010-03-25 02:57:58308 public:
avif15d60a2015-12-21 17:06:33309 FramebufferManager(uint32_t max_draw_buffers,
310 uint32_t max_color_attachments,
kkinnunen631033e2015-09-23 06:39:04311 ContextType context_type,
tobiasjsfc199b472015-08-22 00:39:06312 const scoped_refptr<FramebufferCompletenessCache>&
313 framebuffer_combo_complete_cache);
gman@chromium.orgd304cbd2010-07-01 22:41:16314 ~FramebufferManager();
315
316 // Must call before destruction.
317 void Destroy(bool have_context);
gman@chromium.orga25fa872010-03-25 02:57:58318
gman@chromium.orged9f9cd2013-02-27 21:12:35319 // Creates a Framebuffer for the given framebuffer.
320 void CreateFramebuffer(GLuint client_id, GLuint service_id);
gman@chromium.orga25fa872010-03-25 02:57:58321
322 // Gets the framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35323 Framebuffer* GetFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58324
325 // Removes a framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35326 void RemoveFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58327
gman@chromium.org6b8cf1a2010-05-06 16:13:58328 // Gets a client id for a given service id.
329 bool GetClientId(GLuint service_id, GLuint* client_id) const;
330
gman@chromium.org968351b2011-12-20 08:26:51331 void MarkAttachmentsAsCleared(
gman@chromium.orged9f9cd2013-02-27 21:12:35332 Framebuffer* framebuffer,
gman@chromium.org968351b2011-12-20 08:26:51333 RenderbufferManager* renderbuffer_manager,
334 TextureManager* texture_manager);
335
gman@chromium.orged9f9cd2013-02-27 21:12:35336 void MarkAsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51337
gman@chromium.orged9f9cd2013-02-27 21:12:35338 bool IsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51339
340 void IncFramebufferStateChangeCount() {
341 // make sure this is never 0.
342 framebuffer_state_change_count_ =
343 (framebuffer_state_change_count_ + 1) | 0x80000000U;
344 }
345
kkinnunen631033e2015-09-23 06:39:04346 ContextType context_type() const { return context_type_; }
zmoa0ee95e2015-07-11 01:33:11347
gman@chromium.orga25fa872010-03-25 02:57:58348 private:
gman@chromium.orged9f9cd2013-02-27 21:12:35349 friend class Framebuffer;
350
gman@chromium.org4d8f0dd2013-03-09 14:37:06351 void StartTracking(Framebuffer* framebuffer);
352 void StopTracking(Framebuffer* framebuffer);
gman@chromium.org7c5e8b12012-04-06 00:35:24353
tobiasjsfc199b472015-08-22 00:39:06354 FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
355 return framebuffer_combo_complete_cache_.get();
356 }
357
gman@chromium.orga25fa872010-03-25 02:57:58358 // Info for each framebuffer in the system.
gman@chromium.orged9f9cd2013-02-27 21:12:35359 typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
gman@chromium.org4d8f0dd2013-03-09 14:37:06360 FramebufferMap;
361 FramebufferMap framebuffers_;
gman@chromium.orga25fa872010-03-25 02:57:58362
gman@chromium.org968351b2011-12-20 08:26:51363 // Incremented anytime anything changes that might effect framebuffer
364 // state.
365 unsigned framebuffer_state_change_count_;
366
gman@chromium.orged9f9cd2013-02-27 21:12:35367 // Counts the number of Framebuffer allocated with 'this' as its manager.
368 // Allows to check no Framebuffer will outlive this.
gman@chromium.org4d8f0dd2013-03-09 14:37:06369 unsigned int framebuffer_count_;
gman@chromium.org7c5e8b12012-04-06 00:35:24370
371 bool have_context_;
372
avif15d60a2015-12-21 17:06:33373 uint32_t max_draw_buffers_;
374 uint32_t max_color_attachments_;
zmo@chromium.org2f143d482013-03-14 18:04:49375
kkinnunen631033e2015-09-23 06:39:04376 ContextType context_type_;
zmoa0ee95e2015-07-11 01:33:11377
tobiasjsfc199b472015-08-22 00:39:06378 scoped_refptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;
379
gman@chromium.orga25fa872010-03-25 02:57:58380 DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
381};
382
383} // namespace gles2
384} // namespace gpu
385
386#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_