blob: 3b14720cec029e5d674e397146fc0a65d7922496 [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>
Takuto Ikutaadf31eb2019-01-05 00:32:4812#include <unordered_map>
reveman@chromium.org4aada5a92013-11-01 13:45:0013#include <vector>
14
Anand K Mistrybf055112021-03-11 09:10:4015#include "base/containers/small_map.h"
avif15d60a2015-12-21 17:06:3316#include "base/macros.h"
levin@chromium.org3b63f8f42011-03-28 01:54:1517#include "base/memory/ref_counted.h"
zmoa0ee95e2015-07-11 01:33:1118#include "gpu/command_buffer/service/context_group.h"
gman@chromium.orga25fa872010-03-25 02:57:5819#include "gpu/command_buffer/service/gl_utils.h"
zmoeaae3bb2016-07-15 19:23:1920#include "gpu/command_buffer/service/shader_manager.h"
Antoine Labour83a0aed12018-01-10 04:52:3821#include "gpu/gpu_gles2_export.h"
gman@chromium.orga25fa872010-03-25 02:57:5822
23namespace gpu {
24namespace gles2 {
25
zmo59b6cc52016-01-30 02:35:5926class FeatureInfo;
tobiasjsfc199b472015-08-22 00:39:0627class FramebufferCompletenessCache;
gman@chromium.orged9f9cd2013-02-27 21:12:3528class FramebufferManager;
gman@chromium.org31494b82013-02-28 10:10:2629class Renderbuffer;
30class RenderbufferManager;
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.
Antoine Labour83a0aed12018-01-10 04:52:3835class GPU_GLES2_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
gman@chromium.orged9f9cd2013-02-27 21:12:3536 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;
Zhenyao Mo5ae4e212018-01-08 21:00:2645 virtual GLint level() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3546 virtual bool cleared() const = 0;
47 virtual void SetCleared(
48 RenderbufferManager* renderbuffer_manager,
49 TextureManager* texture_manager,
50 bool cleared) = 0;
zmod252e3ea2016-02-23 00:38:1751 virtual bool IsPartiallyCleared() const = 0;
52 virtual bool IsTextureAttachment() const = 0;
53 virtual bool IsRenderbufferAttachment() const = 0;
piman@chromium.org370eaf12013-05-18 09:19:4954 virtual bool IsTexture(TextureRef* texture) const = 0;
qiankun.miaodb975cd2016-07-20 18:00:1955 virtual bool IsRenderbuffer(Renderbuffer* renderbuffer) const = 0;
56 virtual bool IsSameAttachment(const Attachment* attachment) const = 0;
zmod252e3ea2016-02-23 00:38:1757 virtual bool Is3D() const = 0;
zmodda9c292016-05-31 19:04:1958
59 // If it's a 3D texture attachment, return true if
60 // FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is smaller than the number of
61 // layers in the texture.
62 virtual bool IsLayerValid() const = 0;
63
zmo59b6cc52016-01-30 02:35:5964 virtual bool CanRenderTo(const FeatureInfo* feature_info) const = 0;
Kai Ninomiya821895e2017-06-06 00:03:2965 virtual void DetachFromFramebuffer(Framebuffer* framebuffer,
66 GLenum attachment) const = 0;
avif15d60a2015-12-21 17:06:3367 virtual bool ValidForAttachmentType(GLenum attachment_type,
68 uint32_t max_color_attachments) = 0;
dyencb017312014-09-29 18:16:2069 virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3570 virtual void AddToSignature(
71 TextureManager* texture_manager, std::string* signature) const = 0;
yunchao.heb29cee862016-07-29 10:14:2172 virtual bool FormsFeedbackLoop(
73 TextureRef* texture, GLint level, GLint layer) const = 0;
erikchen6e484562016-04-16 01:23:3974 virtual bool EmulatingRGB() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3575
76 protected:
77 friend class base::RefCounted<Attachment>;
Chris Watkins81030772017-12-07 01:20:5678 virtual ~Attachment() = default;
gman@chromium.orged9f9cd2013-02-27 21:12:3579 };
80
81 Framebuffer(FramebufferManager* manager, GLuint service_id);
82
83 GLuint service_id() const {
84 return service_id_;
85 }
86
87 bool HasUnclearedAttachment(GLenum attachment) const;
zmo@chromium.orgee757922014-06-06 05:21:4288 bool HasUnclearedColorAttachments() const;
gman@chromium.orged9f9cd2013-02-27 21:12:3589
zmo9d631972016-06-17 23:31:0490 bool HasSRGBAttachments() const;
qiankun.miaoaf3b3d82016-07-22 21:39:5391 bool HasDepthStencilFormatAttachment() const;
zmo9d631972016-06-17 23:31:0492
zmod252e3ea2016-02-23 00:38:1793 void ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures(
94 GLES2Decoder* decoder,
95 TextureManager* texture_manager);
96
97 bool HasUnclearedIntRenderbufferAttachments() const;
98
99 void ClearUnclearedIntRenderbufferAttachments(
100 RenderbufferManager* renderbuffer_manager);
101
gman@chromium.orged9f9cd2013-02-27 21:12:35102 void MarkAttachmentAsCleared(
103 RenderbufferManager* renderbuffer_manager,
104 TextureManager* texture_manager,
105 GLenum attachment,
106 bool cleared);
107
vmiura7d08fee52015-02-18 18:39:34108 // Unbinds all attachments from this framebuffer for workaround
109 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
110 // bound when calling this.
111 void DoUnbindGLAttachmentsForWorkaround(GLenum target);
112
gman@chromium.orged9f9cd2013-02-27 21:12:35113 // Attaches a renderbuffer to a particlar attachment.
114 // Pass null to detach.
115 void AttachRenderbuffer(
116 GLenum attachment, Renderbuffer* renderbuffer);
117
118 // Attaches a texture to a particlar attachment. Pass null to detach.
119 void AttachTexture(
piman@chromium.org370eaf12013-05-18 09:19:49120 GLenum attachment, TextureRef* texture_ref, GLenum target,
bsalomon@google.com7d3c36e2013-07-12 14:13:16121 GLint level, GLsizei samples);
qiankun.miao3071b532015-10-30 09:30:32122 void AttachTextureLayer(
123 GLenum attachment, TextureRef* texture_ref, GLenum target,
124 GLint level, GLint layer);
gman@chromium.orged9f9cd2013-02-27 21:12:35125
126 // Unbinds the given renderbuffer if it is bound.
127 void UnbindRenderbuffer(
128 GLenum target, Renderbuffer* renderbuffer);
129
130 // Unbinds the given texture if it is bound.
131 void UnbindTexture(
piman@chromium.org370eaf12013-05-18 09:19:49132 GLenum target, TextureRef* texture_ref);
gman@chromium.orged9f9cd2013-02-27 21:12:35133
134 const Attachment* GetAttachment(GLenum attachment) const;
135
zmo02f3a302015-08-05 22:30:38136 const Attachment* GetReadBufferAttachment() const;
137
Kai Ninomiyae5761542017-09-16 04:06:43138 // Returns the max dimensions which fit inside all of the attachments.
139 // Can only be called after the framebuffer has been checked to be complete.
140 gfx::Size GetFramebufferValidSize() const;
141
zmoa432bd182016-06-08 21:52:27142 GLsizei GetSamples() const;
143
gman@chromium.orged9f9cd2013-02-27 21:12:35144 bool IsDeleted() const {
145 return deleted_;
146 }
147
148 void MarkAsValid() {
149 has_been_bound_ = true;
150 }
151
152 bool IsValid() const {
153 return has_been_bound_ && !IsDeleted();
154 }
155
cwallezaafbfa02016-07-06 17:13:58156 bool HasColorAttachment(int index) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35157 bool HasDepthAttachment() const;
158 bool HasStencilAttachment() const;
shrekshaoc50e5ea2019-03-07 03:34:30159 bool HasActiveFloat32ColorAttachment() const;
shrekshao4a1b49b2019-04-05 20:14:56160 GLsizei last_color_attachment_id() const { return last_color_attachment_id_; }
zmoa432bd182016-06-08 21:52:27161 GLenum GetDepthFormat() const;
162 GLenum GetStencilFormat() const;
zmo21608f882015-08-07 21:49:43163 GLenum GetDrawBufferInternalFormat() const;
164 GLenum GetReadBufferInternalFormat() const;
geofflang@chromium.org68586372013-12-11 01:27:59165 // If the color attachment is a texture, returns its type; otherwise,
166 // returns 0.
zmo21608f882015-08-07 21:49:43167 GLenum GetReadBufferTextureType() const;
James Darpinian98d07192018-10-19 23:42:02168 bool GetReadBufferIsMultisampledTexture() const;
gman@chromium.orged9f9cd2013-02-27 21:12:35169
170 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
171 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
172 // use this combination of attachments. Otherwise returns the value
173 // that glCheckFramebufferStatus should return for this set of attachments.
174 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
175 // not mean the real OpenGL will consider it framebuffer complete. It just
176 // means it passed our tests.
zmo59b6cc52016-01-30 02:35:59177 GLenum IsPossiblyComplete(const FeatureInfo* feature_info) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35178
179 // Implements optimized glGetFramebufferStatus.
180 GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
181
182 // Check all attachments are cleared
183 bool IsCleared() const;
184
zmo@chromium.org2f143d482013-03-14 18:04:49185 GLenum GetDrawBuffer(GLenum draw_buffer) const;
186
187 void SetDrawBuffers(GLsizei n, const GLenum* bufs);
188
zmo@chromium.orgee757922014-06-06 05:21:42189 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
190 // draw buffer for glClear().
zmod252e3ea2016-02-23 00:38:17191 // Return true if the DrawBuffers() is actually called.
zmoeaae3bb2016-07-15 19:23:19192 bool PrepareDrawBuffersForClearingUninitializedAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42193
zmoeaae3bb2016-07-15 19:23:19194 // Restore |adjusted_draw_buffers_|.
195 void RestoreDrawBuffers() const;
196
197 // Checks if a draw buffer's format and its corresponding fragment shader
198 // output's type are compatible, i.e., a signed integer typed variable is
199 // incompatible with a float or unsigned integer buffer.
200 // Return false if incompaticle.
201 // Otherwise, filter out the draw buffers that are not written to but are not
202 // NONE through DrawBuffers, to be on the safe side. Return true.
203 // This is applied before a draw call.
204 bool ValidateAndAdjustDrawBuffers(uint32_t fragment_output_type_mask,
205 uint32_t fragment_output_written_mask);
206
zmo3e2c0df2017-01-07 01:38:34207 // Filter out the draw buffers that have no images attached but are not NONE
208 // through DrawBuffers, to be on the safe side.
209 // This is applied before a clear call.
210 void AdjustDrawBuffers();
211
zmoeaae3bb2016-07-15 19:23:19212 bool ContainsActiveIntegerAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42213
zmo@chromium.orgf3b191b2013-06-19 03:43:54214 // Return true if any draw buffers has an alpha channel.
215 bool HasAlphaMRT() const;
216
zmo21608f882015-08-07 21:49:43217 // Return false if any two active color attachments have different internal
218 // formats.
219 bool HasSameInternalFormatsMRT() const;
220
zmo02f3a302015-08-05 22:30:38221 void set_read_buffer(GLenum read_buffer) {
222 read_buffer_ = read_buffer;
223 }
224
225 GLenum read_buffer() const {
226 return read_buffer_;
227 }
228
zmoeaae3bb2016-07-15 19:23:19229 // See member declaration for details.
230 // The data are only valid if fbo is complete.
231 uint32_t draw_buffer_type_mask() const {
232 return draw_buffer_type_mask_;
233 }
234 uint32_t draw_buffer_bound_mask() const {
235 return draw_buffer_bound_mask_;
236 }
237
Kai Ninomiya821895e2017-06-06 00:03:29238 void UnmarkAsComplete() { framebuffer_complete_state_count_id_ = 0; }
239
gman@chromium.orged9f9cd2013-02-27 21:12:35240 private:
241 friend class FramebufferManager;
242 friend class base::RefCounted<Framebuffer>;
243
244 ~Framebuffer();
245
shrekshao4a1b49b2019-04-05 20:14:56246 // Helper function updating cached last color attachment id bound.
247 // Called when attachments_ changed
248 void OnInsertUpdateLastColorAttachmentId(GLenum attachment);
249 void OnEraseUpdateLastColorAttachmentId(GLenum attachment);
250
gman@chromium.orged9f9cd2013-02-27 21:12:35251 void MarkAsDeleted();
252
253 void MarkAttachmentsAsCleared(
254 RenderbufferManager* renderbuffer_manager,
255 TextureManager* texture_manager,
256 bool cleared);
257
258 void MarkAsComplete(unsigned state_id) {
zmoeaae3bb2016-07-15 19:23:19259 UpdateDrawBufferMasks();
gman@chromium.orged9f9cd2013-02-27 21:12:35260 framebuffer_complete_state_count_id_ = state_id;
261 }
262
263 unsigned framebuffer_complete_state_count_id() const {
264 return framebuffer_complete_state_count_id_;
265 }
266
zmoeaae3bb2016-07-15 19:23:19267 // Cache color attachments' base type mask (FLOAT, INT, UINT) and bound mask.
268 // If an attachment point has no image, it's set as UNDEFINED_TYPE.
269 // This call is only valid on a complete fbo.
270 void UpdateDrawBufferMasks();
271
zmo3e2c0df2017-01-07 01:38:34272 // Helper for ValidateAndAdjustDrawBuffers() and AdjustDrawBuffers().
273 void AdjustDrawBuffersImpl(uint32_t desired_mask);
274
gman@chromium.orged9f9cd2013-02-27 21:12:35275 // The managers that owns this.
276 FramebufferManager* manager_;
277
278 bool deleted_;
279
280 // Service side framebuffer id.
281 GLuint service_id_;
282
283 // Whether this framebuffer has ever been bound.
284 bool has_been_bound_;
285
286 // state count when this framebuffer was last checked for completeness.
287 unsigned framebuffer_complete_state_count_id_;
288
289 // A map of attachments.
Anand K Mistrybf055112021-03-11 09:10:40290 using AttachmentMap =
291 base::small_map<std::unordered_map<GLenum, scoped_refptr<Attachment>>, 8>;
gman@chromium.orged9f9cd2013-02-27 21:12:35292 AttachmentMap attachments_;
293
zmoeaae3bb2016-07-15 19:23:19294 // User's draw buffers setting through DrawBuffers() call.
mostynb6682b1c42016-04-19 10:17:30295 std::unique_ptr<GLenum[]> draw_buffers_;
zmo@chromium.org2f143d482013-03-14 18:04:49296
zmoeaae3bb2016-07-15 19:23:19297 // If a draw buffer does not have an image, or it has no corresponding
298 // fragment shader output variable, it might be filtered out as NONE.
299 // Note that the actually draw buffers setting sent to the driver is always
300 // consistent with |adjusted_draw_buffers_|, not |draw_buffers_|.
301 std::unique_ptr<GLenum[]> adjusted_draw_buffers_;
302
303 // Draw buffer base types: FLOAT, INT, or UINT.
304 // We have up to 16 draw buffers, each is encoded into 2 bits, total 32 bits:
305 // the lowest 2 bits for draw buffer 0, the highest 2 bits for draw buffer 15.
306 uint32_t draw_buffer_type_mask_;
shrekshaoc50e5ea2019-03-07 03:34:30307 // Same layout as above, 0x03 if it's 32bit float color attachment, 0x00 if
308 // not
309 uint32_t draw_buffer_float32_mask_;
zmoeaae3bb2016-07-15 19:23:19310 // Same layout as above, 2 bits per draw buffer, 0x03 if a draw buffer has a
311 // bound image, 0x00 if not.
312 uint32_t draw_buffer_bound_mask_;
313 // This is the mask for the actual draw buffers sent to driver.
314 uint32_t adjusted_draw_buffer_bound_mask_;
shrekshao4a1b49b2019-04-05 20:14:56315 // The largest i of all GL_COLOR_ATTACHMENTi
316 GLsizei last_color_attachment_id_;
zmoeaae3bb2016-07-15 19:23:19317
zmo02f3a302015-08-05 22:30:38318 GLenum read_buffer_;
319
gman@chromium.orged9f9cd2013-02-27 21:12:35320 DISALLOW_COPY_AND_ASSIGN(Framebuffer);
321};
322
kloveless@chromium.orgc986af502013-08-14 01:04:44323struct DecoderFramebufferState {
kloveless@chromium.org9d3b2e12013-10-02 01:04:34324 DecoderFramebufferState();
325 ~DecoderFramebufferState();
kloveless@chromium.orgc986af502013-08-14 01:04:44326
327 // State saved for clearing so we can clear render buffers and then
328 // restore to these values.
329 bool clear_state_dirty;
kloveless@chromium.org9d3b2e12013-10-02 01:04:34330
331 // The currently bound framebuffers
332 scoped_refptr<Framebuffer> bound_read_framebuffer;
333 scoped_refptr<Framebuffer> bound_draw_framebuffer;
kloveless@chromium.orgc986af502013-08-14 01:04:44334};
335
gman@chromium.orga25fa872010-03-25 02:57:58336// This class keeps track of the frambebuffers and their attached renderbuffers
337// so we can correctly clear them.
Antoine Labour83a0aed12018-01-10 04:52:38338class GPU_GLES2_EXPORT FramebufferManager {
gman@chromium.orga25fa872010-03-25 02:57:58339 public:
Antoine Labour6bf942492017-06-14 00:33:42340 FramebufferManager(
341 uint32_t max_draw_buffers,
342 uint32_t max_color_attachments,
343 FramebufferCompletenessCache* framebuffer_combo_complete_cache);
gman@chromium.orgd304cbd2010-07-01 22:41:16344 ~FramebufferManager();
345
346 // Must call before destruction.
347 void Destroy(bool have_context);
gman@chromium.orga25fa872010-03-25 02:57:58348
gman@chromium.orged9f9cd2013-02-27 21:12:35349 // Creates a Framebuffer for the given framebuffer.
350 void CreateFramebuffer(GLuint client_id, GLuint service_id);
gman@chromium.orga25fa872010-03-25 02:57:58351
352 // Gets the framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35353 Framebuffer* GetFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58354
355 // Removes a framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35356 void RemoveFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58357
gman@chromium.org6b8cf1a2010-05-06 16:13:58358 // Gets a client id for a given service id.
359 bool GetClientId(GLuint service_id, GLuint* client_id) const;
360
gman@chromium.org968351b2011-12-20 08:26:51361 void MarkAttachmentsAsCleared(
gman@chromium.orged9f9cd2013-02-27 21:12:35362 Framebuffer* framebuffer,
gman@chromium.org968351b2011-12-20 08:26:51363 RenderbufferManager* renderbuffer_manager,
364 TextureManager* texture_manager);
365
gman@chromium.orged9f9cd2013-02-27 21:12:35366 void MarkAsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51367
Kai Ninomiyae5761542017-09-16 04:06:43368 bool IsComplete(const Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51369
370 void IncFramebufferStateChangeCount() {
371 // make sure this is never 0.
372 framebuffer_state_change_count_ =
373 (framebuffer_state_change_count_ + 1) | 0x80000000U;
374 }
375
gman@chromium.orga25fa872010-03-25 02:57:58376 private:
gman@chromium.orged9f9cd2013-02-27 21:12:35377 friend class Framebuffer;
378
gman@chromium.org4d8f0dd2013-03-09 14:37:06379 void StartTracking(Framebuffer* framebuffer);
380 void StopTracking(Framebuffer* framebuffer);
gman@chromium.org7c5e8b12012-04-06 00:35:24381
tobiasjsfc199b472015-08-22 00:39:06382 FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
Antoine Labour6bf942492017-06-14 00:33:42383 return framebuffer_combo_complete_cache_;
tobiasjsfc199b472015-08-22 00:39:06384 }
385
gman@chromium.orga25fa872010-03-25 02:57:58386 // Info for each framebuffer in the system.
Takuto Ikutaadf31eb2019-01-05 00:32:48387 typedef std::unordered_map<GLuint, scoped_refptr<Framebuffer>> FramebufferMap;
gman@chromium.org4d8f0dd2013-03-09 14:37:06388 FramebufferMap framebuffers_;
gman@chromium.orga25fa872010-03-25 02:57:58389
gman@chromium.org968351b2011-12-20 08:26:51390 // Incremented anytime anything changes that might effect framebuffer
391 // state.
392 unsigned framebuffer_state_change_count_;
393
gman@chromium.orged9f9cd2013-02-27 21:12:35394 // Counts the number of Framebuffer allocated with 'this' as its manager.
395 // Allows to check no Framebuffer will outlive this.
gman@chromium.org4d8f0dd2013-03-09 14:37:06396 unsigned int framebuffer_count_;
gman@chromium.org7c5e8b12012-04-06 00:35:24397
398 bool have_context_;
399
avif15d60a2015-12-21 17:06:33400 uint32_t max_draw_buffers_;
401 uint32_t max_color_attachments_;
zmo@chromium.org2f143d482013-03-14 18:04:49402
Antoine Labour6bf942492017-06-14 00:33:42403 FramebufferCompletenessCache* framebuffer_combo_complete_cache_;
tobiasjsfc199b472015-08-22 00:39:06404
gman@chromium.orga25fa872010-03-25 02:57:58405 DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
406};
407
408} // namespace gles2
409} // namespace gpu
410
411#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_