blob: 4e964104142579e92a654f61ec30415e80454447 [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;
qiankun.miaodb975cd2016-07-20 18:00:1954 virtual bool IsRenderbuffer(Renderbuffer* renderbuffer) const = 0;
55 virtual bool IsSameAttachment(const Attachment* attachment) 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;
qiankun.miaoaf3b3d82016-07-22 21:39:5389 bool HasDepthStencilFormatAttachment() const;
zmo9d631972016-06-17 23:31:0490
zmod252e3ea2016-02-23 00:38:1791 void ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures(
92 GLES2Decoder* decoder,
93 TextureManager* texture_manager);
94
95 bool HasUnclearedIntRenderbufferAttachments() const;
96
97 void ClearUnclearedIntRenderbufferAttachments(
98 RenderbufferManager* renderbuffer_manager);
99
gman@chromium.orged9f9cd2013-02-27 21:12:35100 void MarkAttachmentAsCleared(
101 RenderbufferManager* renderbuffer_manager,
102 TextureManager* texture_manager,
103 GLenum attachment,
104 bool cleared);
105
vmiura7d08fee52015-02-18 18:39:34106 // Unbinds all attachments from this framebuffer for workaround
107 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
108 // bound when calling this.
109 void DoUnbindGLAttachmentsForWorkaround(GLenum target);
110
gman@chromium.orged9f9cd2013-02-27 21:12:35111 // Attaches a renderbuffer to a particlar attachment.
112 // Pass null to detach.
113 void AttachRenderbuffer(
114 GLenum attachment, Renderbuffer* renderbuffer);
115
116 // Attaches a texture to a particlar attachment. Pass null to detach.
117 void AttachTexture(
piman@chromium.org370eaf12013-05-18 09:19:49118 GLenum attachment, TextureRef* texture_ref, GLenum target,
bsalomon@google.com7d3c36e2013-07-12 14:13:16119 GLint level, GLsizei samples);
qiankun.miao3071b532015-10-30 09:30:32120 void AttachTextureLayer(
121 GLenum attachment, TextureRef* texture_ref, GLenum target,
122 GLint level, GLint layer);
gman@chromium.orged9f9cd2013-02-27 21:12:35123
124 // Unbinds the given renderbuffer if it is bound.
125 void UnbindRenderbuffer(
126 GLenum target, Renderbuffer* renderbuffer);
127
128 // Unbinds the given texture if it is bound.
129 void UnbindTexture(
piman@chromium.org370eaf12013-05-18 09:19:49130 GLenum target, TextureRef* texture_ref);
gman@chromium.orged9f9cd2013-02-27 21:12:35131
132 const Attachment* GetAttachment(GLenum attachment) const;
133
zmo02f3a302015-08-05 22:30:38134 const Attachment* GetReadBufferAttachment() const;
135
zmoa432bd182016-06-08 21:52:27136 GLsizei GetSamples() const;
137
gman@chromium.orged9f9cd2013-02-27 21:12:35138 bool IsDeleted() const {
139 return deleted_;
140 }
141
142 void MarkAsValid() {
143 has_been_bound_ = true;
144 }
145
146 bool IsValid() const {
147 return has_been_bound_ && !IsDeleted();
148 }
149
cwallezaafbfa02016-07-06 17:13:58150 bool HasColorAttachment(int index) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35151 bool HasDepthAttachment() const;
152 bool HasStencilAttachment() const;
zmoa432bd182016-06-08 21:52:27153 GLenum GetDepthFormat() const;
154 GLenum GetStencilFormat() const;
zmo21608f882015-08-07 21:49:43155 GLenum GetDrawBufferInternalFormat() const;
156 GLenum GetReadBufferInternalFormat() const;
geofflang@chromium.org68586372013-12-11 01:27:59157 // If the color attachment is a texture, returns its type; otherwise,
158 // returns 0.
zmo21608f882015-08-07 21:49:43159 GLenum GetReadBufferTextureType() const;
gman@chromium.orged9f9cd2013-02-27 21:12:35160
161 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
162 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
163 // use this combination of attachments. Otherwise returns the value
164 // that glCheckFramebufferStatus should return for this set of attachments.
165 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
166 // not mean the real OpenGL will consider it framebuffer complete. It just
167 // means it passed our tests.
zmo59b6cc52016-01-30 02:35:59168 GLenum IsPossiblyComplete(const FeatureInfo* feature_info) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35169
170 // Implements optimized glGetFramebufferStatus.
171 GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
172
173 // Check all attachments are cleared
174 bool IsCleared() const;
175
zmo@chromium.org2f143d482013-03-14 18:04:49176 GLenum GetDrawBuffer(GLenum draw_buffer) const;
177
178 void SetDrawBuffers(GLsizei n, const GLenum* bufs);
179
zmo@chromium.orgee757922014-06-06 05:21:42180 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
181 // draw buffer for glClear().
zmod252e3ea2016-02-23 00:38:17182 // Return true if the DrawBuffers() is actually called.
zmoeaae3bb2016-07-15 19:23:19183 bool PrepareDrawBuffersForClearingUninitializedAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42184
zmoeaae3bb2016-07-15 19:23:19185 // Restore |adjusted_draw_buffers_|.
186 void RestoreDrawBuffers() const;
187
188 // Checks if a draw buffer's format and its corresponding fragment shader
189 // output's type are compatible, i.e., a signed integer typed variable is
190 // incompatible with a float or unsigned integer buffer.
191 // Return false if incompaticle.
192 // Otherwise, filter out the draw buffers that are not written to but are not
193 // NONE through DrawBuffers, to be on the safe side. Return true.
194 // This is applied before a draw call.
195 bool ValidateAndAdjustDrawBuffers(uint32_t fragment_output_type_mask,
196 uint32_t fragment_output_written_mask);
197
198 bool ContainsActiveIntegerAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42199
zmo@chromium.orgf3b191b2013-06-19 03:43:54200 // Return true if any draw buffers has an alpha channel.
201 bool HasAlphaMRT() const;
202
zmo21608f882015-08-07 21:49:43203 // Return false if any two active color attachments have different internal
204 // formats.
205 bool HasSameInternalFormatsMRT() const;
206
zmo02f3a302015-08-05 22:30:38207 void set_read_buffer(GLenum read_buffer) {
208 read_buffer_ = read_buffer;
209 }
210
211 GLenum read_buffer() const {
212 return read_buffer_;
213 }
214
zmoeaae3bb2016-07-15 19:23:19215 // See member declaration for details.
216 // The data are only valid if fbo is complete.
217 uint32_t draw_buffer_type_mask() const {
218 return draw_buffer_type_mask_;
219 }
220 uint32_t draw_buffer_bound_mask() const {
221 return draw_buffer_bound_mask_;
222 }
223
gman@chromium.orged9f9cd2013-02-27 21:12:35224 private:
225 friend class FramebufferManager;
226 friend class base::RefCounted<Framebuffer>;
227
228 ~Framebuffer();
229
230 void MarkAsDeleted();
231
232 void MarkAttachmentsAsCleared(
233 RenderbufferManager* renderbuffer_manager,
234 TextureManager* texture_manager,
235 bool cleared);
236
237 void MarkAsComplete(unsigned state_id) {
zmoeaae3bb2016-07-15 19:23:19238 UpdateDrawBufferMasks();
gman@chromium.orged9f9cd2013-02-27 21:12:35239 framebuffer_complete_state_count_id_ = state_id;
240 }
241
242 unsigned framebuffer_complete_state_count_id() const {
243 return framebuffer_complete_state_count_id_;
244 }
245
zmoeaae3bb2016-07-15 19:23:19246 // Cache color attachments' base type mask (FLOAT, INT, UINT) and bound mask.
247 // If an attachment point has no image, it's set as UNDEFINED_TYPE.
248 // This call is only valid on a complete fbo.
249 void UpdateDrawBufferMasks();
250
gman@chromium.orged9f9cd2013-02-27 21:12:35251 // The managers that owns this.
252 FramebufferManager* manager_;
253
254 bool deleted_;
255
256 // Service side framebuffer id.
257 GLuint service_id_;
258
259 // Whether this framebuffer has ever been bound.
260 bool has_been_bound_;
261
262 // state count when this framebuffer was last checked for completeness.
263 unsigned framebuffer_complete_state_count_id_;
264
265 // A map of attachments.
266 typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
267 AttachmentMap attachments_;
268
zmoeaae3bb2016-07-15 19:23:19269 // User's draw buffers setting through DrawBuffers() call.
mostynb6682b1c42016-04-19 10:17:30270 std::unique_ptr<GLenum[]> draw_buffers_;
zmo@chromium.org2f143d482013-03-14 18:04:49271
zmoeaae3bb2016-07-15 19:23:19272 // If a draw buffer does not have an image, or it has no corresponding
273 // fragment shader output variable, it might be filtered out as NONE.
274 // Note that the actually draw buffers setting sent to the driver is always
275 // consistent with |adjusted_draw_buffers_|, not |draw_buffers_|.
276 std::unique_ptr<GLenum[]> adjusted_draw_buffers_;
277
278 // Draw buffer base types: FLOAT, INT, or UINT.
279 // We have up to 16 draw buffers, each is encoded into 2 bits, total 32 bits:
280 // the lowest 2 bits for draw buffer 0, the highest 2 bits for draw buffer 15.
281 uint32_t draw_buffer_type_mask_;
282 // Same layout as above, 2 bits per draw buffer, 0x03 if a draw buffer has a
283 // bound image, 0x00 if not.
284 uint32_t draw_buffer_bound_mask_;
285 // This is the mask for the actual draw buffers sent to driver.
286 uint32_t adjusted_draw_buffer_bound_mask_;
287
zmo02f3a302015-08-05 22:30:38288 GLenum read_buffer_;
289
gman@chromium.orged9f9cd2013-02-27 21:12:35290 DISALLOW_COPY_AND_ASSIGN(Framebuffer);
291};
292
kloveless@chromium.orgc986af502013-08-14 01:04:44293struct DecoderFramebufferState {
kloveless@chromium.org9d3b2e12013-10-02 01:04:34294 DecoderFramebufferState();
295 ~DecoderFramebufferState();
kloveless@chromium.orgc986af502013-08-14 01:04:44296
297 // State saved for clearing so we can clear render buffers and then
298 // restore to these values.
299 bool clear_state_dirty;
kloveless@chromium.org9d3b2e12013-10-02 01:04:34300
301 // The currently bound framebuffers
302 scoped_refptr<Framebuffer> bound_read_framebuffer;
303 scoped_refptr<Framebuffer> bound_draw_framebuffer;
kloveless@chromium.orgc986af502013-08-14 01:04:44304};
305
gman@chromium.orga25fa872010-03-25 02:57:58306// This class keeps track of the frambebuffers and their attached renderbuffers
307// so we can correctly clear them.
rvargas@google.comdd255042012-03-05 20:14:17308class GPU_EXPORT FramebufferManager {
gman@chromium.orga25fa872010-03-25 02:57:58309 public:
avif15d60a2015-12-21 17:06:33310 FramebufferManager(uint32_t max_draw_buffers,
311 uint32_t max_color_attachments,
kkinnunen631033e2015-09-23 06:39:04312 ContextType context_type,
tobiasjsfc199b472015-08-22 00:39:06313 const scoped_refptr<FramebufferCompletenessCache>&
314 framebuffer_combo_complete_cache);
gman@chromium.orgd304cbd2010-07-01 22:41:16315 ~FramebufferManager();
316
317 // Must call before destruction.
318 void Destroy(bool have_context);
gman@chromium.orga25fa872010-03-25 02:57:58319
gman@chromium.orged9f9cd2013-02-27 21:12:35320 // Creates a Framebuffer for the given framebuffer.
321 void CreateFramebuffer(GLuint client_id, GLuint service_id);
gman@chromium.orga25fa872010-03-25 02:57:58322
323 // Gets the framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35324 Framebuffer* GetFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58325
326 // Removes a framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35327 void RemoveFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58328
gman@chromium.org6b8cf1a2010-05-06 16:13:58329 // Gets a client id for a given service id.
330 bool GetClientId(GLuint service_id, GLuint* client_id) const;
331
gman@chromium.org968351b2011-12-20 08:26:51332 void MarkAttachmentsAsCleared(
gman@chromium.orged9f9cd2013-02-27 21:12:35333 Framebuffer* framebuffer,
gman@chromium.org968351b2011-12-20 08:26:51334 RenderbufferManager* renderbuffer_manager,
335 TextureManager* texture_manager);
336
gman@chromium.orged9f9cd2013-02-27 21:12:35337 void MarkAsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51338
gman@chromium.orged9f9cd2013-02-27 21:12:35339 bool IsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51340
341 void IncFramebufferStateChangeCount() {
342 // make sure this is never 0.
343 framebuffer_state_change_count_ =
344 (framebuffer_state_change_count_ + 1) | 0x80000000U;
345 }
346
kkinnunen631033e2015-09-23 06:39:04347 ContextType context_type() const { return context_type_; }
zmoa0ee95e2015-07-11 01:33:11348
gman@chromium.orga25fa872010-03-25 02:57:58349 private:
gman@chromium.orged9f9cd2013-02-27 21:12:35350 friend class Framebuffer;
351
gman@chromium.org4d8f0dd2013-03-09 14:37:06352 void StartTracking(Framebuffer* framebuffer);
353 void StopTracking(Framebuffer* framebuffer);
gman@chromium.org7c5e8b12012-04-06 00:35:24354
tobiasjsfc199b472015-08-22 00:39:06355 FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
356 return framebuffer_combo_complete_cache_.get();
357 }
358
gman@chromium.orga25fa872010-03-25 02:57:58359 // Info for each framebuffer in the system.
gman@chromium.orged9f9cd2013-02-27 21:12:35360 typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
gman@chromium.org4d8f0dd2013-03-09 14:37:06361 FramebufferMap;
362 FramebufferMap framebuffers_;
gman@chromium.orga25fa872010-03-25 02:57:58363
gman@chromium.org968351b2011-12-20 08:26:51364 // Incremented anytime anything changes that might effect framebuffer
365 // state.
366 unsigned framebuffer_state_change_count_;
367
gman@chromium.orged9f9cd2013-02-27 21:12:35368 // Counts the number of Framebuffer allocated with 'this' as its manager.
369 // Allows to check no Framebuffer will outlive this.
gman@chromium.org4d8f0dd2013-03-09 14:37:06370 unsigned int framebuffer_count_;
gman@chromium.org7c5e8b12012-04-06 00:35:24371
372 bool have_context_;
373
avif15d60a2015-12-21 17:06:33374 uint32_t max_draw_buffers_;
375 uint32_t max_color_attachments_;
zmo@chromium.org2f143d482013-03-14 18:04:49376
kkinnunen631033e2015-09-23 06:39:04377 ContextType context_type_;
zmoa0ee95e2015-07-11 01:33:11378
tobiasjsfc199b472015-08-22 00:39:06379 scoped_refptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;
380
gman@chromium.orga25fa872010-03-25 02:57:58381 DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
382};
383
384} // namespace gles2
385} // namespace gpu
386
387#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_