blob: 30f54c38420542e9ccd2b153230b0661cacba764 [file] [log] [blame]
Avi Drissman05dfbc822022-09-13 21:25:341// Copyright 2012 The Chromium Authors
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"
Stephen Nuskof4e53402025-07-23 13:39:4416#include "base/containers/span.h"
Keishi Hattori0e45c022021-11-27 09:25:5217#include "base/memory/raw_ptr.h"
levin@chromium.org3b63f8f42011-03-28 01:54:1518#include "base/memory/ref_counted.h"
zmoa0ee95e2015-07-11 01:33:1119#include "gpu/command_buffer/service/context_group.h"
gman@chromium.orga25fa872010-03-25 02:57:5820#include "gpu/command_buffer/service/gl_utils.h"
zmoeaae3bb2016-07-15 19:23:1921#include "gpu/command_buffer/service/shader_manager.h"
Antoine Labour83a0aed12018-01-10 04:52:3822#include "gpu/gpu_gles2_export.h"
gman@chromium.orga25fa872010-03-25 02:57:5823
24namespace gpu {
25namespace gles2 {
26
zmo59b6cc52016-01-30 02:35:5927class FeatureInfo;
tobiasjsfc199b472015-08-22 00:39:0628class FramebufferCompletenessCache;
gman@chromium.orged9f9cd2013-02-27 21:12:3529class FramebufferManager;
gman@chromium.org31494b82013-02-28 10:10:2630class Renderbuffer;
31class RenderbufferManager;
piman@chromium.org370eaf12013-05-18 09:19:4932class TextureRef;
gman@chromium.org31494b82013-02-28 10:10:2633class TextureManager;
gman@chromium.orged9f9cd2013-02-27 21:12:3534
35// Info about a particular Framebuffer.
Antoine Labour83a0aed12018-01-10 04:52:3836class GPU_GLES2_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
gman@chromium.orged9f9cd2013-02-27 21:12:3537 public:
38 class Attachment : public base::RefCounted<Attachment> {
39 public:
40 virtual GLsizei width() const = 0;
41 virtual GLsizei height() const = 0;
42 virtual GLenum internal_format() const = 0;
geofflang@chromium.org68586372013-12-11 01:27:5943 virtual GLenum texture_type() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3544 virtual GLsizei samples() const = 0;
piman@chromium.org62e65f02013-05-29 22:28:1045 virtual GLuint object_name() const = 0;
Zhenyao Mo5ae4e212018-01-08 21:00:2646 virtual GLint level() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3547 virtual bool cleared() const = 0;
48 virtual void SetCleared(
49 RenderbufferManager* renderbuffer_manager,
50 TextureManager* texture_manager,
51 bool cleared) = 0;
zmod252e3ea2016-02-23 00:38:1752 virtual bool IsPartiallyCleared() const = 0;
53 virtual bool IsTextureAttachment() const = 0;
54 virtual bool IsRenderbufferAttachment() const = 0;
piman@chromium.org370eaf12013-05-18 09:19:4955 virtual bool IsTexture(TextureRef* texture) const = 0;
qiankun.miaodb975cd2016-07-20 18:00:1956 virtual bool IsRenderbuffer(Renderbuffer* renderbuffer) const = 0;
57 virtual bool IsSameAttachment(const Attachment* attachment) const = 0;
zmod252e3ea2016-02-23 00:38:1758 virtual bool Is3D() const = 0;
zmodda9c292016-05-31 19:04:1959
60 // If it's a 3D texture attachment, return true if
61 // FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is smaller than the number of
62 // layers in the texture.
63 virtual bool IsLayerValid() const = 0;
64
zmo59b6cc52016-01-30 02:35:5965 virtual bool CanRenderTo(const FeatureInfo* feature_info) const = 0;
Kai Ninomiya821895e2017-06-06 00:03:2966 virtual void DetachFromFramebuffer(Framebuffer* framebuffer,
67 GLenum attachment) const = 0;
avif15d60a2015-12-21 17:06:3368 virtual bool ValidForAttachmentType(GLenum attachment_type,
69 uint32_t max_color_attachments) = 0;
dyencb017312014-09-29 18:16:2070 virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3571 virtual void AddToSignature(
72 TextureManager* texture_manager, std::string* signature) const = 0;
Colin Blundellfaa5d7f2022-12-06 08:08:4973 virtual bool FormsFeedbackLoop(TextureRef* texture,
74 GLint level,
75 GLint layer) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3576
77 protected:
78 friend class base::RefCounted<Attachment>;
Chris Watkins81030772017-12-07 01:20:5679 virtual ~Attachment() = default;
gman@chromium.orged9f9cd2013-02-27 21:12:3580 };
81
82 Framebuffer(FramebufferManager* manager, GLuint service_id);
83
Peter BostrΓΆm1ab741d2021-10-05 22:49:4184 Framebuffer(const Framebuffer&) = delete;
85 Framebuffer& operator=(const Framebuffer&) = delete;
86
gman@chromium.orged9f9cd2013-02-27 21:12:3587 GLuint service_id() const {
88 return service_id_;
89 }
90
91 bool HasUnclearedAttachment(GLenum attachment) const;
zmo@chromium.orgee757922014-06-06 05:21:4292 bool HasUnclearedColorAttachments() const;
gman@chromium.orged9f9cd2013-02-27 21:12:3593
zmo9d631972016-06-17 23:31:0494 bool HasSRGBAttachments() const;
qiankun.miaoaf3b3d82016-07-22 21:39:5395 bool HasDepthStencilFormatAttachment() const;
zmo9d631972016-06-17 23:31:0496
zmod252e3ea2016-02-23 00:38:1797 void ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures(
98 GLES2Decoder* decoder,
99 TextureManager* texture_manager);
100
101 bool HasUnclearedIntRenderbufferAttachments() const;
102
103 void ClearUnclearedIntRenderbufferAttachments(
104 RenderbufferManager* renderbuffer_manager);
105
gman@chromium.orged9f9cd2013-02-27 21:12:35106 void MarkAttachmentAsCleared(
107 RenderbufferManager* renderbuffer_manager,
108 TextureManager* texture_manager,
109 GLenum attachment,
110 bool cleared);
111
vmiura7d08fee52015-02-18 18:39:34112 // Unbinds all attachments from this framebuffer for workaround
113 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
114 // bound when calling this.
115 void DoUnbindGLAttachmentsForWorkaround(GLenum target);
116
gman@chromium.orged9f9cd2013-02-27 21:12:35117 // Attaches a renderbuffer to a particlar attachment.
118 // Pass null to detach.
119 void AttachRenderbuffer(
120 GLenum attachment, Renderbuffer* renderbuffer);
121
122 // Attaches a texture to a particlar attachment. Pass null to detach.
123 void AttachTexture(
piman@chromium.org370eaf12013-05-18 09:19:49124 GLenum attachment, TextureRef* texture_ref, GLenum target,
bsalomon@google.com7d3c36e2013-07-12 14:13:16125 GLint level, GLsizei samples);
qiankun.miao3071b532015-10-30 09:30:32126 void AttachTextureLayer(
127 GLenum attachment, TextureRef* texture_ref, GLenum target,
128 GLint level, GLint layer);
gman@chromium.orged9f9cd2013-02-27 21:12:35129
130 // Unbinds the given renderbuffer if it is bound.
131 void UnbindRenderbuffer(
132 GLenum target, Renderbuffer* renderbuffer);
133
134 // Unbinds the given texture if it is bound.
135 void UnbindTexture(
piman@chromium.org370eaf12013-05-18 09:19:49136 GLenum target, TextureRef* texture_ref);
gman@chromium.orged9f9cd2013-02-27 21:12:35137
138 const Attachment* GetAttachment(GLenum attachment) const;
139
zmo02f3a302015-08-05 22:30:38140 const Attachment* GetReadBufferAttachment() const;
141
Kai Ninomiyae5761542017-09-16 04:06:43142 // Returns the max dimensions which fit inside all of the attachments.
143 // Can only be called after the framebuffer has been checked to be complete.
144 gfx::Size GetFramebufferValidSize() const;
145
zmoa432bd182016-06-08 21:52:27146 GLsizei GetSamples() const;
147
gman@chromium.orged9f9cd2013-02-27 21:12:35148 bool IsDeleted() const {
149 return deleted_;
150 }
151
152 void MarkAsValid() {
153 has_been_bound_ = true;
154 }
155
156 bool IsValid() const {
157 return has_been_bound_ && !IsDeleted();
158 }
159
cwallezaafbfa02016-07-06 17:13:58160 bool HasColorAttachment(int index) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35161 bool HasDepthAttachment() const;
162 bool HasStencilAttachment() const;
shrekshaoc50e5ea2019-03-07 03:34:30163 bool HasActiveFloat32ColorAttachment() const;
shrekshao4a1b49b2019-04-05 20:14:56164 GLsizei last_color_attachment_id() const { return last_color_attachment_id_; }
zmoa432bd182016-06-08 21:52:27165 GLenum GetDepthFormat() const;
166 GLenum GetStencilFormat() const;
zmo21608f882015-08-07 21:49:43167 GLenum GetDrawBufferInternalFormat() const;
168 GLenum GetReadBufferInternalFormat() const;
geofflang@chromium.org68586372013-12-11 01:27:59169 // If the color attachment is a texture, returns its type; otherwise,
170 // returns 0.
zmo21608f882015-08-07 21:49:43171 GLenum GetReadBufferTextureType() const;
James Darpinian98d07192018-10-19 23:42:02172 bool GetReadBufferIsMultisampledTexture() const;
gman@chromium.orged9f9cd2013-02-27 21:12:35173
174 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
175 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
176 // use this combination of attachments. Otherwise returns the value
177 // that glCheckFramebufferStatus should return for this set of attachments.
178 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
179 // not mean the real OpenGL will consider it framebuffer complete. It just
180 // means it passed our tests.
zmo59b6cc52016-01-30 02:35:59181 GLenum IsPossiblyComplete(const FeatureInfo* feature_info) const;
gman@chromium.orged9f9cd2013-02-27 21:12:35182
183 // Implements optimized glGetFramebufferStatus.
184 GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
185
186 // Check all attachments are cleared
187 bool IsCleared() const;
188
zmo@chromium.org2f143d482013-03-14 18:04:49189 GLenum GetDrawBuffer(GLenum draw_buffer) const;
190
Stephen Nuskof4e53402025-07-23 13:39:44191 void SetDrawBuffers(GLsizei spanification_suspected_redundant_n,
192 base::span<const GLenum> bufs);
zmo@chromium.org2f143d482013-03-14 18:04:49193
zmo@chromium.orgee757922014-06-06 05:21:42194 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
195 // draw buffer for glClear().
zmod252e3ea2016-02-23 00:38:17196 // Return true if the DrawBuffers() is actually called.
zmoeaae3bb2016-07-15 19:23:19197 bool PrepareDrawBuffersForClearingUninitializedAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42198
zmoeaae3bb2016-07-15 19:23:19199 // Restore |adjusted_draw_buffers_|.
200 void RestoreDrawBuffers() const;
201
202 // Checks if a draw buffer's format and its corresponding fragment shader
203 // output's type are compatible, i.e., a signed integer typed variable is
204 // incompatible with a float or unsigned integer buffer.
205 // Return false if incompaticle.
206 // Otherwise, filter out the draw buffers that are not written to but are not
207 // NONE through DrawBuffers, to be on the safe side. Return true.
208 // This is applied before a draw call.
209 bool ValidateAndAdjustDrawBuffers(uint32_t fragment_output_type_mask,
210 uint32_t fragment_output_written_mask);
211
zmo3e2c0df2017-01-07 01:38:34212 // Filter out the draw buffers that have no images attached but are not NONE
213 // through DrawBuffers, to be on the safe side.
214 // This is applied before a clear call.
215 void AdjustDrawBuffers();
216
zmoeaae3bb2016-07-15 19:23:19217 bool ContainsActiveIntegerAttachments() const;
zmo@chromium.orgee757922014-06-06 05:21:42218
zmo@chromium.orgf3b191b2013-06-19 03:43:54219 // Return true if any draw buffers has an alpha channel.
220 bool HasAlphaMRT() const;
221
zmo21608f882015-08-07 21:49:43222 // Return false if any two active color attachments have different internal
223 // formats.
224 bool HasSameInternalFormatsMRT() const;
225
zmo02f3a302015-08-05 22:30:38226 void set_read_buffer(GLenum read_buffer) {
227 read_buffer_ = read_buffer;
228 }
229
230 GLenum read_buffer() const {
231 return read_buffer_;
232 }
233
zmoeaae3bb2016-07-15 19:23:19234 // See member declaration for details.
235 // The data are only valid if fbo is complete.
236 uint32_t draw_buffer_type_mask() const {
237 return draw_buffer_type_mask_;
238 }
239 uint32_t draw_buffer_bound_mask() const {
240 return draw_buffer_bound_mask_;
241 }
242
Kai Ninomiya821895e2017-06-06 00:03:29243 void UnmarkAsComplete() { framebuffer_complete_state_count_id_ = 0; }
244
gman@chromium.orged9f9cd2013-02-27 21:12:35245 private:
246 friend class FramebufferManager;
247 friend class base::RefCounted<Framebuffer>;
248
249 ~Framebuffer();
250
shrekshao4a1b49b2019-04-05 20:14:56251 // Helper function updating cached last color attachment id bound.
252 // Called when attachments_ changed
253 void OnInsertUpdateLastColorAttachmentId(GLenum attachment);
254 void OnEraseUpdateLastColorAttachmentId(GLenum attachment);
255
gman@chromium.orged9f9cd2013-02-27 21:12:35256 void MarkAsDeleted();
257
258 void MarkAttachmentsAsCleared(
259 RenderbufferManager* renderbuffer_manager,
260 TextureManager* texture_manager,
261 bool cleared);
262
263 void MarkAsComplete(unsigned state_id) {
zmoeaae3bb2016-07-15 19:23:19264 UpdateDrawBufferMasks();
gman@chromium.orged9f9cd2013-02-27 21:12:35265 framebuffer_complete_state_count_id_ = state_id;
266 }
267
268 unsigned framebuffer_complete_state_count_id() const {
269 return framebuffer_complete_state_count_id_;
270 }
271
zmoeaae3bb2016-07-15 19:23:19272 // Cache color attachments' base type mask (FLOAT, INT, UINT) and bound mask.
273 // If an attachment point has no image, it's set as UNDEFINED_TYPE.
274 // This call is only valid on a complete fbo.
275 void UpdateDrawBufferMasks();
276
zmo3e2c0df2017-01-07 01:38:34277 // Helper for ValidateAndAdjustDrawBuffers() and AdjustDrawBuffers().
278 void AdjustDrawBuffersImpl(uint32_t desired_mask);
279
gman@chromium.orged9f9cd2013-02-27 21:12:35280 // The managers that owns this.
Keishi Hattori0e45c022021-11-27 09:25:52281 raw_ptr<FramebufferManager> manager_;
gman@chromium.orged9f9cd2013-02-27 21:12:35282
283 bool deleted_;
284
285 // Service side framebuffer id.
286 GLuint service_id_;
287
288 // Whether this framebuffer has ever been bound.
289 bool has_been_bound_;
290
291 // state count when this framebuffer was last checked for completeness.
292 unsigned framebuffer_complete_state_count_id_;
293
294 // A map of attachments.
Anand K Mistrybf055112021-03-11 09:10:40295 using AttachmentMap =
296 base::small_map<std::unordered_map<GLenum, scoped_refptr<Attachment>>, 8>;
gman@chromium.orged9f9cd2013-02-27 21:12:35297 AttachmentMap attachments_;
298
zmoeaae3bb2016-07-15 19:23:19299 // User's draw buffers setting through DrawBuffers() call.
mostynb6682b1c42016-04-19 10:17:30300 std::unique_ptr<GLenum[]> draw_buffers_;
zmo@chromium.org2f143d482013-03-14 18:04:49301
zmoeaae3bb2016-07-15 19:23:19302 // If a draw buffer does not have an image, or it has no corresponding
303 // fragment shader output variable, it might be filtered out as NONE.
304 // Note that the actually draw buffers setting sent to the driver is always
305 // consistent with |adjusted_draw_buffers_|, not |draw_buffers_|.
306 std::unique_ptr<GLenum[]> adjusted_draw_buffers_;
307
308 // Draw buffer base types: FLOAT, INT, or UINT.
309 // We have up to 16 draw buffers, each is encoded into 2 bits, total 32 bits:
310 // the lowest 2 bits for draw buffer 0, the highest 2 bits for draw buffer 15.
311 uint32_t draw_buffer_type_mask_;
shrekshaoc50e5ea2019-03-07 03:34:30312 // Same layout as above, 0x03 if it's 32bit float color attachment, 0x00 if
313 // not
314 uint32_t draw_buffer_float32_mask_;
zmoeaae3bb2016-07-15 19:23:19315 // Same layout as above, 2 bits per draw buffer, 0x03 if a draw buffer has a
316 // bound image, 0x00 if not.
317 uint32_t draw_buffer_bound_mask_;
318 // This is the mask for the actual draw buffers sent to driver.
319 uint32_t adjusted_draw_buffer_bound_mask_;
shrekshao4a1b49b2019-04-05 20:14:56320 // The largest i of all GL_COLOR_ATTACHMENTi
321 GLsizei last_color_attachment_id_;
zmoeaae3bb2016-07-15 19:23:19322
zmo02f3a302015-08-05 22:30:38323 GLenum read_buffer_;
gman@chromium.orged9f9cd2013-02-27 21:12:35324};
325
kloveless@chromium.orgc986af502013-08-14 01:04:44326struct DecoderFramebufferState {
kloveless@chromium.org9d3b2e12013-10-02 01:04:34327 DecoderFramebufferState();
328 ~DecoderFramebufferState();
kloveless@chromium.orgc986af502013-08-14 01:04:44329
330 // State saved for clearing so we can clear render buffers and then
331 // restore to these values.
332 bool clear_state_dirty;
kloveless@chromium.org9d3b2e12013-10-02 01:04:34333
334 // The currently bound framebuffers
335 scoped_refptr<Framebuffer> bound_read_framebuffer;
336 scoped_refptr<Framebuffer> bound_draw_framebuffer;
kloveless@chromium.orgc986af502013-08-14 01:04:44337};
338
gman@chromium.orga25fa872010-03-25 02:57:58339// This class keeps track of the frambebuffers and their attached renderbuffers
340// so we can correctly clear them.
Antoine Labour83a0aed12018-01-10 04:52:38341class GPU_GLES2_EXPORT FramebufferManager {
gman@chromium.orga25fa872010-03-25 02:57:58342 public:
Antoine Labour6bf942492017-06-14 00:33:42343 FramebufferManager(
344 uint32_t max_draw_buffers,
345 uint32_t max_color_attachments,
346 FramebufferCompletenessCache* framebuffer_combo_complete_cache);
Peter BostrΓΆmdbacdc22021-09-23 22:11:46347
348 FramebufferManager(const FramebufferManager&) = delete;
349 FramebufferManager& operator=(const FramebufferManager&) = delete;
350
gman@chromium.orgd304cbd2010-07-01 22:41:16351 ~FramebufferManager();
352
353 // Must call before destruction.
354 void Destroy(bool have_context);
gman@chromium.orga25fa872010-03-25 02:57:58355
gman@chromium.orged9f9cd2013-02-27 21:12:35356 // Creates a Framebuffer for the given framebuffer.
357 void CreateFramebuffer(GLuint client_id, GLuint service_id);
gman@chromium.orga25fa872010-03-25 02:57:58358
359 // Gets the framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35360 Framebuffer* GetFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58361
362 // Removes a framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35363 void RemoveFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58364
gman@chromium.org6b8cf1a2010-05-06 16:13:58365 // Gets a client id for a given service id.
366 bool GetClientId(GLuint service_id, GLuint* client_id) const;
367
gman@chromium.org968351b2011-12-20 08:26:51368 void MarkAttachmentsAsCleared(
gman@chromium.orged9f9cd2013-02-27 21:12:35369 Framebuffer* framebuffer,
gman@chromium.org968351b2011-12-20 08:26:51370 RenderbufferManager* renderbuffer_manager,
371 TextureManager* texture_manager);
372
gman@chromium.orged9f9cd2013-02-27 21:12:35373 void MarkAsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51374
Kai Ninomiyae5761542017-09-16 04:06:43375 bool IsComplete(const Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51376
377 void IncFramebufferStateChangeCount() {
378 // make sure this is never 0.
379 framebuffer_state_change_count_ =
380 (framebuffer_state_change_count_ + 1) | 0x80000000U;
381 }
382
gman@chromium.orga25fa872010-03-25 02:57:58383 private:
gman@chromium.orged9f9cd2013-02-27 21:12:35384 friend class Framebuffer;
385
gman@chromium.org4d8f0dd2013-03-09 14:37:06386 void StartTracking(Framebuffer* framebuffer);
387 void StopTracking(Framebuffer* framebuffer);
gman@chromium.org7c5e8b12012-04-06 00:35:24388
tobiasjsfc199b472015-08-22 00:39:06389 FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
Antoine Labour6bf942492017-06-14 00:33:42390 return framebuffer_combo_complete_cache_;
tobiasjsfc199b472015-08-22 00:39:06391 }
392
gman@chromium.orga25fa872010-03-25 02:57:58393 // Info for each framebuffer in the system.
Takuto Ikutaadf31eb2019-01-05 00:32:48394 typedef std::unordered_map<GLuint, scoped_refptr<Framebuffer>> FramebufferMap;
gman@chromium.org4d8f0dd2013-03-09 14:37:06395 FramebufferMap framebuffers_;
gman@chromium.orga25fa872010-03-25 02:57:58396
gman@chromium.org968351b2011-12-20 08:26:51397 // Incremented anytime anything changes that might effect framebuffer
398 // state.
399 unsigned framebuffer_state_change_count_;
400
gman@chromium.orged9f9cd2013-02-27 21:12:35401 // Counts the number of Framebuffer allocated with 'this' as its manager.
402 // Allows to check no Framebuffer will outlive this.
gman@chromium.org4d8f0dd2013-03-09 14:37:06403 unsigned int framebuffer_count_;
gman@chromium.org7c5e8b12012-04-06 00:35:24404
405 bool have_context_;
406
avif15d60a2015-12-21 17:06:33407 uint32_t max_draw_buffers_;
408 uint32_t max_color_attachments_;
zmo@chromium.org2f143d482013-03-14 18:04:49409
Keishi Hattori0e45c022021-11-27 09:25:52410 raw_ptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;
gman@chromium.orga25fa872010-03-25 02:57:58411};
412
413} // namespace gles2
414} // namespace gpu
415
416#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_