blob: 172125403d6420ad6aee31b856ddf224e2110d69 [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
reveman@chromium.org4aada5a92013-11-01 13:45:008#include <vector>
9
gman@chromium.orga25fa872010-03-25 02:57:5810#include "base/basictypes.h"
brettw@chromium.org14c1c232013-06-11 17:52:4411#include "base/containers/hash_tables.h"
levin@chromium.org3b63f8f42011-03-28 01:54:1512#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
zmoa0ee95e2015-07-11 01:33:1114#include "gpu/command_buffer/service/context_group.h"
gman@chromium.orga25fa872010-03-25 02:57:5815#include "gpu/command_buffer/service/gl_utils.h"
rvargas@google.comdd255042012-03-05 20:14:1716#include "gpu/gpu_export.h"
gman@chromium.orga25fa872010-03-25 02:57:5817
18namespace gpu {
19namespace gles2 {
20
gman@chromium.orged9f9cd2013-02-27 21:12:3521class FramebufferManager;
gman@chromium.org31494b82013-02-28 10:10:2622class Renderbuffer;
23class RenderbufferManager;
24class Texture;
piman@chromium.org370eaf12013-05-18 09:19:4925class TextureRef;
gman@chromium.org31494b82013-02-28 10:10:2626class TextureManager;
gman@chromium.orged9f9cd2013-02-27 21:12:3527
28// Info about a particular Framebuffer.
29class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
30 public:
31 class Attachment : public base::RefCounted<Attachment> {
32 public:
33 virtual GLsizei width() const = 0;
34 virtual GLsizei height() const = 0;
35 virtual GLenum internal_format() const = 0;
geofflang@chromium.org68586372013-12-11 01:27:5936 virtual GLenum texture_type() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3537 virtual GLsizei samples() const = 0;
piman@chromium.org62e65f02013-05-29 22:28:1038 virtual GLuint object_name() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3539 virtual bool cleared() const = 0;
40 virtual void SetCleared(
41 RenderbufferManager* renderbuffer_manager,
42 TextureManager* texture_manager,
43 bool cleared) = 0;
piman@chromium.org370eaf12013-05-18 09:19:4944 virtual bool IsTexture(TextureRef* texture) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3545 virtual bool IsRenderbuffer(
46 Renderbuffer* renderbuffer) const = 0;
47 virtual bool CanRenderTo() const = 0;
reveman@chromium.org91c94eb2013-10-22 10:32:5448 virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0;
zmo@chromium.org2f143d482013-03-14 18:04:4949 virtual bool ValidForAttachmentType(
50 GLenum attachment_type, uint32 max_color_attachments) = 0;
dyencb017312014-09-29 18:16:2051 virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3552 virtual void AddToSignature(
53 TextureManager* texture_manager, std::string* signature) const = 0;
sievers@chromium.org00c2cf92014-03-14 00:08:3754 virtual void OnWillRenderTo() const = 0;
55 virtual void OnDidRenderTo() const = 0;
zmo383512cf2014-10-14 00:11:0056 virtual bool FormsFeedbackLoop(TextureRef* texture, GLint level) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3557
58 protected:
59 friend class base::RefCounted<Attachment>;
60 virtual ~Attachment() {}
61 };
62
63 Framebuffer(FramebufferManager* manager, GLuint service_id);
64
65 GLuint service_id() const {
66 return service_id_;
67 }
68
69 bool HasUnclearedAttachment(GLenum attachment) const;
zmo@chromium.orgee757922014-06-06 05:21:4270 bool HasUnclearedColorAttachments() const;
gman@chromium.orged9f9cd2013-02-27 21:12:3571
72 void MarkAttachmentAsCleared(
73 RenderbufferManager* renderbuffer_manager,
74 TextureManager* texture_manager,
75 GLenum attachment,
76 bool cleared);
77
vmiura7d08fee52015-02-18 18:39:3478 // Unbinds all attachments from this framebuffer for workaround
79 // 'unbind_attachments_on_bound_render_fbo_delete'. The Framebuffer must be
80 // bound when calling this.
81 void DoUnbindGLAttachmentsForWorkaround(GLenum target);
82
gman@chromium.orged9f9cd2013-02-27 21:12:3583 // Attaches a renderbuffer to a particlar attachment.
84 // Pass null to detach.
85 void AttachRenderbuffer(
86 GLenum attachment, Renderbuffer* renderbuffer);
87
88 // Attaches a texture to a particlar attachment. Pass null to detach.
89 void AttachTexture(
piman@chromium.org370eaf12013-05-18 09:19:4990 GLenum attachment, TextureRef* texture_ref, GLenum target,
bsalomon@google.com7d3c36e2013-07-12 14:13:1691 GLint level, GLsizei samples);
gman@chromium.orged9f9cd2013-02-27 21:12:3592
93 // Unbinds the given renderbuffer if it is bound.
94 void UnbindRenderbuffer(
95 GLenum target, Renderbuffer* renderbuffer);
96
97 // Unbinds the given texture if it is bound.
98 void UnbindTexture(
piman@chromium.org370eaf12013-05-18 09:19:4999 GLenum target, TextureRef* texture_ref);
gman@chromium.orged9f9cd2013-02-27 21:12:35100
101 const Attachment* GetAttachment(GLenum attachment) const;
102
103 bool IsDeleted() const {
104 return deleted_;
105 }
106
107 void MarkAsValid() {
108 has_been_bound_ = true;
109 }
110
111 bool IsValid() const {
112 return has_been_bound_ && !IsDeleted();
113 }
114
115 bool HasDepthAttachment() const;
116 bool HasStencilAttachment() const;
117 GLenum GetColorAttachmentFormat() const;
geofflang@chromium.org68586372013-12-11 01:27:59118 // If the color attachment is a texture, returns its type; otherwise,
119 // returns 0.
120 GLenum GetColorAttachmentTextureType() const;
gman@chromium.orged9f9cd2013-02-27 21:12:35121
122 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
123 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
124 // use this combination of attachments. Otherwise returns the value
125 // that glCheckFramebufferStatus should return for this set of attachments.
126 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
127 // not mean the real OpenGL will consider it framebuffer complete. It just
128 // means it passed our tests.
129 GLenum IsPossiblyComplete() const;
130
131 // Implements optimized glGetFramebufferStatus.
132 GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
133
134 // Check all attachments are cleared
135 bool IsCleared() const;
136
zmo@chromium.org2f143d482013-03-14 18:04:49137 GLenum GetDrawBuffer(GLenum draw_buffer) const;
138
139 void SetDrawBuffers(GLsizei n, const GLenum* bufs);
140
zmo@chromium.orgee757922014-06-06 05:21:42141 // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
142 // draw buffer for glClear().
143 void PrepareDrawBuffersForClear() const;
144
145 // Restore draw buffers states that have been changed in
146 // PrepareDrawBuffersForClear().
147 void RestoreDrawBuffersAfterClear() const;
148
zmo@chromium.orgf3b191b2013-06-19 03:43:54149 // Return true if any draw buffers has an alpha channel.
150 bool HasAlphaMRT() const;
151
gman@chromium.orged9f9cd2013-02-27 21:12:35152 static void ClearFramebufferCompleteComboMap();
153
ccameron@chromium.org97419c02013-04-10 02:52:38154 static bool AllowFramebufferComboCompleteMapForTesting() {
155 return allow_framebuffer_combo_complete_map_;
156 }
157
reveman@chromium.org91c94eb2013-10-22 10:32:54158 void OnTextureRefDetached(TextureRef* texture);
sievers@chromium.org00c2cf92014-03-14 00:08:37159 void OnWillRenderTo() const;
160 void OnDidRenderTo() const;
reveman@chromium.org91c94eb2013-10-22 10:32:54161
gman@chromium.orged9f9cd2013-02-27 21:12:35162 private:
163 friend class FramebufferManager;
164 friend class base::RefCounted<Framebuffer>;
165
166 ~Framebuffer();
167
168 void MarkAsDeleted();
169
170 void MarkAttachmentsAsCleared(
171 RenderbufferManager* renderbuffer_manager,
172 TextureManager* texture_manager,
173 bool cleared);
174
175 void MarkAsComplete(unsigned state_id) {
176 framebuffer_complete_state_count_id_ = state_id;
177 }
178
179 unsigned framebuffer_complete_state_count_id() const {
180 return framebuffer_complete_state_count_id_;
181 }
182
zmo@chromium.orgee757922014-06-06 05:21:42183 // Helper function for PrepareDrawBuffersForClear() and
184 // RestoreDrawBuffersAfterClear().
185 void ChangeDrawBuffersHelper(bool recover) const;
186
gman@chromium.orged9f9cd2013-02-27 21:12:35187 // The managers that owns this.
188 FramebufferManager* manager_;
189
190 bool deleted_;
191
192 // Service side framebuffer id.
193 GLuint service_id_;
194
195 // Whether this framebuffer has ever been bound.
196 bool has_been_bound_;
197
198 // state count when this framebuffer was last checked for completeness.
199 unsigned framebuffer_complete_state_count_id_;
200
201 // A map of attachments.
202 typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
203 AttachmentMap attachments_;
204
205 // A map of successful frame buffer combos. If it's in the map
206 // it should be FRAMEBUFFER_COMPLETE.
207 typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
208 static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
ccameron@chromium.org97419c02013-04-10 02:52:38209 static bool allow_framebuffer_combo_complete_map_;
gman@chromium.orged9f9cd2013-02-27 21:12:35210
dcheng@chromium.org40d90a22013-04-09 03:39:55211 scoped_ptr<GLenum[]> draw_buffers_;
zmo@chromium.org2f143d482013-03-14 18:04:49212
gman@chromium.orged9f9cd2013-02-27 21:12:35213 DISALLOW_COPY_AND_ASSIGN(Framebuffer);
214};
215
kloveless@chromium.orgc986af502013-08-14 01:04:44216struct DecoderFramebufferState {
kloveless@chromium.org9d3b2e12013-10-02 01:04:34217 DecoderFramebufferState();
218 ~DecoderFramebufferState();
kloveless@chromium.orgc986af502013-08-14 01:04:44219
220 // State saved for clearing so we can clear render buffers and then
221 // restore to these values.
222 bool clear_state_dirty;
kloveless@chromium.org9d3b2e12013-10-02 01:04:34223
224 // The currently bound framebuffers
225 scoped_refptr<Framebuffer> bound_read_framebuffer;
226 scoped_refptr<Framebuffer> bound_draw_framebuffer;
kloveless@chromium.orgc986af502013-08-14 01:04:44227};
228
gman@chromium.orga25fa872010-03-25 02:57:58229// This class keeps track of the frambebuffers and their attached renderbuffers
230// so we can correctly clear them.
rvargas@google.comdd255042012-03-05 20:14:17231class GPU_EXPORT FramebufferManager {
gman@chromium.orga25fa872010-03-25 02:57:58232 public:
reveman@chromium.org91c94eb2013-10-22 10:32:54233 class GPU_EXPORT TextureDetachObserver {
234 public:
235 TextureDetachObserver();
236 virtual ~TextureDetachObserver();
237
238 virtual void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) = 0;
239
240 private:
241 DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver);
242 };
243
zmoa0ee95e2015-07-11 01:33:11244 FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments,
245 ContextGroup::ContextType context_type);
gman@chromium.orgd304cbd2010-07-01 22:41:16246 ~FramebufferManager();
247
248 // Must call before destruction.
249 void Destroy(bool have_context);
gman@chromium.orga25fa872010-03-25 02:57:58250
gman@chromium.orged9f9cd2013-02-27 21:12:35251 // Creates a Framebuffer for the given framebuffer.
252 void CreateFramebuffer(GLuint client_id, GLuint service_id);
gman@chromium.orga25fa872010-03-25 02:57:58253
254 // Gets the framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35255 Framebuffer* GetFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58256
257 // Removes a framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35258 void RemoveFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58259
gman@chromium.org6b8cf1a2010-05-06 16:13:58260 // Gets a client id for a given service id.
261 bool GetClientId(GLuint service_id, GLuint* client_id) const;
262
gman@chromium.org968351b2011-12-20 08:26:51263 void MarkAttachmentsAsCleared(
gman@chromium.orged9f9cd2013-02-27 21:12:35264 Framebuffer* framebuffer,
gman@chromium.org968351b2011-12-20 08:26:51265 RenderbufferManager* renderbuffer_manager,
266 TextureManager* texture_manager);
267
gman@chromium.orged9f9cd2013-02-27 21:12:35268 void MarkAsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51269
gman@chromium.orged9f9cd2013-02-27 21:12:35270 bool IsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51271
272 void IncFramebufferStateChangeCount() {
273 // make sure this is never 0.
274 framebuffer_state_change_count_ =
275 (framebuffer_state_change_count_ + 1) | 0x80000000U;
276 }
277
reveman@chromium.org91c94eb2013-10-22 10:32:54278 void AddObserver(TextureDetachObserver* observer) {
reveman@chromium.org4aada5a92013-11-01 13:45:00279 texture_detach_observers_.push_back(observer);
reveman@chromium.org91c94eb2013-10-22 10:32:54280 }
281
282 void RemoveObserver(TextureDetachObserver* observer) {
reveman@chromium.org4aada5a92013-11-01 13:45:00283 texture_detach_observers_.erase(
284 std::remove(texture_detach_observers_.begin(),
285 texture_detach_observers_.end(),
286 observer),
287 texture_detach_observers_.end());
reveman@chromium.org91c94eb2013-10-22 10:32:54288 }
289
zmoa0ee95e2015-07-11 01:33:11290 ContextGroup::ContextType context_type() const {
291 return context_type_;
292 }
293
gman@chromium.orga25fa872010-03-25 02:57:58294 private:
gman@chromium.orged9f9cd2013-02-27 21:12:35295 friend class Framebuffer;
296
gman@chromium.org4d8f0dd2013-03-09 14:37:06297 void StartTracking(Framebuffer* framebuffer);
298 void StopTracking(Framebuffer* framebuffer);
gman@chromium.org7c5e8b12012-04-06 00:35:24299
reveman@chromium.org91c94eb2013-10-22 10:32:54300 void OnTextureRefDetached(TextureRef* texture);
301
gman@chromium.orga25fa872010-03-25 02:57:58302 // Info for each framebuffer in the system.
gman@chromium.orged9f9cd2013-02-27 21:12:35303 typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
gman@chromium.org4d8f0dd2013-03-09 14:37:06304 FramebufferMap;
305 FramebufferMap framebuffers_;
gman@chromium.orga25fa872010-03-25 02:57:58306
gman@chromium.org968351b2011-12-20 08:26:51307 // Incremented anytime anything changes that might effect framebuffer
308 // state.
309 unsigned framebuffer_state_change_count_;
310
gman@chromium.orged9f9cd2013-02-27 21:12:35311 // Counts the number of Framebuffer allocated with 'this' as its manager.
312 // Allows to check no Framebuffer will outlive this.
gman@chromium.org4d8f0dd2013-03-09 14:37:06313 unsigned int framebuffer_count_;
gman@chromium.org7c5e8b12012-04-06 00:35:24314
315 bool have_context_;
316
zmo@chromium.org2f143d482013-03-14 18:04:49317 uint32 max_draw_buffers_;
318 uint32 max_color_attachments_;
319
zmoa0ee95e2015-07-11 01:33:11320 ContextGroup::ContextType context_type_;
321
reveman@chromium.org4aada5a92013-11-01 13:45:00322 typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector;
323 TextureDetachObserverVector texture_detach_observers_;
reveman@chromium.org91c94eb2013-10-22 10:32:54324
gman@chromium.orga25fa872010-03-25 02:57:58325 DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
326};
327
328} // namespace gles2
329} // namespace gpu
330
331#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_