blob: 5fe5a79183a88b629c7f3656c23daff46194738d [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
gman@chromium.orga25fa872010-03-25 02:57:588#include "base/basictypes.h"
brettw@chromium.org14c1c232013-06-11 17:52:449#include "base/containers/hash_tables.h"
levin@chromium.org3b63f8f42011-03-28 01:54:1510#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
gman@chromium.orga25fa872010-03-25 02:57:5812#include "gpu/command_buffer/service/gl_utils.h"
rvargas@google.comdd255042012-03-05 20:14:1713#include "gpu/gpu_export.h"
gman@chromium.orga25fa872010-03-25 02:57:5814
15namespace gpu {
16namespace gles2 {
17
gman@chromium.orged9f9cd2013-02-27 21:12:3518class FramebufferManager;
gman@chromium.org31494b82013-02-28 10:10:2619class Renderbuffer;
20class RenderbufferManager;
21class Texture;
piman@chromium.org370eaf12013-05-18 09:19:4922class TextureRef;
gman@chromium.org31494b82013-02-28 10:10:2623class TextureManager;
gman@chromium.orged9f9cd2013-02-27 21:12:3524
25// Info about a particular Framebuffer.
26class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
27 public:
28 class Attachment : public base::RefCounted<Attachment> {
29 public:
30 virtual GLsizei width() const = 0;
31 virtual GLsizei height() const = 0;
32 virtual GLenum internal_format() const = 0;
33 virtual GLsizei samples() const = 0;
piman@chromium.org62e65f02013-05-29 22:28:1034 virtual GLuint object_name() const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3535 virtual bool cleared() const = 0;
36 virtual void SetCleared(
37 RenderbufferManager* renderbuffer_manager,
38 TextureManager* texture_manager,
39 bool cleared) = 0;
piman@chromium.org370eaf12013-05-18 09:19:4940 virtual bool IsTexture(TextureRef* texture) const = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3541 virtual bool IsRenderbuffer(
42 Renderbuffer* renderbuffer) const = 0;
43 virtual bool CanRenderTo() const = 0;
44 virtual void DetachFromFramebuffer() const = 0;
zmo@chromium.org2f143d482013-03-14 18:04:4945 virtual bool ValidForAttachmentType(
46 GLenum attachment_type, uint32 max_color_attachments) = 0;
gman@chromium.orged9f9cd2013-02-27 21:12:3547 virtual void AddToSignature(
48 TextureManager* texture_manager, std::string* signature) const = 0;
49
50 protected:
51 friend class base::RefCounted<Attachment>;
52 virtual ~Attachment() {}
53 };
54
55 Framebuffer(FramebufferManager* manager, GLuint service_id);
56
57 GLuint service_id() const {
58 return service_id_;
59 }
60
61 bool HasUnclearedAttachment(GLenum attachment) const;
62
63 void MarkAttachmentAsCleared(
64 RenderbufferManager* renderbuffer_manager,
65 TextureManager* texture_manager,
66 GLenum attachment,
67 bool cleared);
68
69 // Attaches a renderbuffer to a particlar attachment.
70 // Pass null to detach.
71 void AttachRenderbuffer(
72 GLenum attachment, Renderbuffer* renderbuffer);
73
74 // Attaches a texture to a particlar attachment. Pass null to detach.
75 void AttachTexture(
piman@chromium.org370eaf12013-05-18 09:19:4976 GLenum attachment, TextureRef* texture_ref, GLenum target,
gman@chromium.orged9f9cd2013-02-27 21:12:3577 GLint level);
78
79 // Unbinds the given renderbuffer if it is bound.
80 void UnbindRenderbuffer(
81 GLenum target, Renderbuffer* renderbuffer);
82
83 // Unbinds the given texture if it is bound.
84 void UnbindTexture(
piman@chromium.org370eaf12013-05-18 09:19:4985 GLenum target, TextureRef* texture_ref);
gman@chromium.orged9f9cd2013-02-27 21:12:3586
87 const Attachment* GetAttachment(GLenum attachment) const;
88
89 bool IsDeleted() const {
90 return deleted_;
91 }
92
93 void MarkAsValid() {
94 has_been_bound_ = true;
95 }
96
97 bool IsValid() const {
98 return has_been_bound_ && !IsDeleted();
99 }
100
101 bool HasDepthAttachment() const;
102 bool HasStencilAttachment() const;
103 GLenum GetColorAttachmentFormat() const;
104
105 // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
106 // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
107 // use this combination of attachments. Otherwise returns the value
108 // that glCheckFramebufferStatus should return for this set of attachments.
109 // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
110 // not mean the real OpenGL will consider it framebuffer complete. It just
111 // means it passed our tests.
112 GLenum IsPossiblyComplete() const;
113
114 // Implements optimized glGetFramebufferStatus.
115 GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
116
117 // Check all attachments are cleared
118 bool IsCleared() const;
119
zmo@chromium.org2f143d482013-03-14 18:04:49120 GLenum GetDrawBuffer(GLenum draw_buffer) const;
121
122 void SetDrawBuffers(GLsizei n, const GLenum* bufs);
123
zmo@chromium.orgf3b191b2013-06-19 03:43:54124 // Return true if any draw buffers has an alpha channel.
125 bool HasAlphaMRT() const;
126
gman@chromium.orged9f9cd2013-02-27 21:12:35127 static void ClearFramebufferCompleteComboMap();
128
ccameron@chromium.org97419c02013-04-10 02:52:38129 static bool AllowFramebufferComboCompleteMapForTesting() {
130 return allow_framebuffer_combo_complete_map_;
131 }
132
gman@chromium.orged9f9cd2013-02-27 21:12:35133 private:
134 friend class FramebufferManager;
135 friend class base::RefCounted<Framebuffer>;
136
137 ~Framebuffer();
138
139 void MarkAsDeleted();
140
141 void MarkAttachmentsAsCleared(
142 RenderbufferManager* renderbuffer_manager,
143 TextureManager* texture_manager,
144 bool cleared);
145
146 void MarkAsComplete(unsigned state_id) {
147 framebuffer_complete_state_count_id_ = state_id;
148 }
149
150 unsigned framebuffer_complete_state_count_id() const {
151 return framebuffer_complete_state_count_id_;
152 }
153
154 // The managers that owns this.
155 FramebufferManager* manager_;
156
157 bool deleted_;
158
159 // Service side framebuffer id.
160 GLuint service_id_;
161
162 // Whether this framebuffer has ever been bound.
163 bool has_been_bound_;
164
165 // state count when this framebuffer was last checked for completeness.
166 unsigned framebuffer_complete_state_count_id_;
167
168 // A map of attachments.
169 typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
170 AttachmentMap attachments_;
171
172 // A map of successful frame buffer combos. If it's in the map
173 // it should be FRAMEBUFFER_COMPLETE.
174 typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
175 static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
ccameron@chromium.org97419c02013-04-10 02:52:38176 static bool allow_framebuffer_combo_complete_map_;
gman@chromium.orged9f9cd2013-02-27 21:12:35177
dcheng@chromium.org40d90a22013-04-09 03:39:55178 scoped_ptr<GLenum[]> draw_buffers_;
zmo@chromium.org2f143d482013-03-14 18:04:49179
gman@chromium.orged9f9cd2013-02-27 21:12:35180 DISALLOW_COPY_AND_ASSIGN(Framebuffer);
181};
182
gman@chromium.orga25fa872010-03-25 02:57:58183// This class keeps track of the frambebuffers and their attached renderbuffers
184// so we can correctly clear them.
rvargas@google.comdd255042012-03-05 20:14:17185class GPU_EXPORT FramebufferManager {
gman@chromium.orga25fa872010-03-25 02:57:58186 public:
zmo@chromium.org2f143d482013-03-14 18:04:49187 FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments);
gman@chromium.orgd304cbd2010-07-01 22:41:16188 ~FramebufferManager();
189
190 // Must call before destruction.
191 void Destroy(bool have_context);
gman@chromium.orga25fa872010-03-25 02:57:58192
gman@chromium.orged9f9cd2013-02-27 21:12:35193 // Creates a Framebuffer for the given framebuffer.
194 void CreateFramebuffer(GLuint client_id, GLuint service_id);
gman@chromium.orga25fa872010-03-25 02:57:58195
196 // Gets the framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35197 Framebuffer* GetFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58198
199 // Removes a framebuffer info for the given framebuffer.
gman@chromium.orged9f9cd2013-02-27 21:12:35200 void RemoveFramebuffer(GLuint client_id);
gman@chromium.orga25fa872010-03-25 02:57:58201
gman@chromium.org6b8cf1a2010-05-06 16:13:58202 // Gets a client id for a given service id.
203 bool GetClientId(GLuint service_id, GLuint* client_id) const;
204
gman@chromium.org968351b2011-12-20 08:26:51205 void MarkAttachmentsAsCleared(
gman@chromium.orged9f9cd2013-02-27 21:12:35206 Framebuffer* framebuffer,
gman@chromium.org968351b2011-12-20 08:26:51207 RenderbufferManager* renderbuffer_manager,
208 TextureManager* texture_manager);
209
gman@chromium.orged9f9cd2013-02-27 21:12:35210 void MarkAsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51211
gman@chromium.orged9f9cd2013-02-27 21:12:35212 bool IsComplete(Framebuffer* framebuffer);
gman@chromium.org968351b2011-12-20 08:26:51213
214 void IncFramebufferStateChangeCount() {
215 // make sure this is never 0.
216 framebuffer_state_change_count_ =
217 (framebuffer_state_change_count_ + 1) | 0x80000000U;
218 }
219
gman@chromium.orga25fa872010-03-25 02:57:58220 private:
gman@chromium.orged9f9cd2013-02-27 21:12:35221 friend class Framebuffer;
222
gman@chromium.org4d8f0dd2013-03-09 14:37:06223 void StartTracking(Framebuffer* framebuffer);
224 void StopTracking(Framebuffer* framebuffer);
gman@chromium.org7c5e8b12012-04-06 00:35:24225
gman@chromium.orga25fa872010-03-25 02:57:58226 // Info for each framebuffer in the system.
gman@chromium.orged9f9cd2013-02-27 21:12:35227 typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
gman@chromium.org4d8f0dd2013-03-09 14:37:06228 FramebufferMap;
229 FramebufferMap framebuffers_;
gman@chromium.orga25fa872010-03-25 02:57:58230
gman@chromium.org968351b2011-12-20 08:26:51231 // Incremented anytime anything changes that might effect framebuffer
232 // state.
233 unsigned framebuffer_state_change_count_;
234
gman@chromium.orged9f9cd2013-02-27 21:12:35235 // Counts the number of Framebuffer allocated with 'this' as its manager.
236 // Allows to check no Framebuffer will outlive this.
gman@chromium.org4d8f0dd2013-03-09 14:37:06237 unsigned int framebuffer_count_;
gman@chromium.org7c5e8b12012-04-06 00:35:24238
239 bool have_context_;
240
zmo@chromium.org2f143d482013-03-14 18:04:49241 uint32 max_draw_buffers_;
242 uint32 max_color_attachments_;
243
gman@chromium.orga25fa872010-03-25 02:57:58244 DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
245};
246
247} // namespace gles2
248} // namespace gpu
249
250#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_