framebuffer_manager.h revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// 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
8#include "base/basictypes.h"
9#include "base/hash_tables.h"
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "gpu/command_buffer/service/gl_utils.h"
13#include "gpu/gpu_export.h"
14
15namespace gpu {
16namespace gles2 {
17
18class FramebufferManager;
19class Renderbuffer;
20class RenderbufferManager;
21class Texture;
22class TextureRef;
23class TextureManager;
24
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;
34    virtual bool cleared() const = 0;
35    virtual void SetCleared(
36        RenderbufferManager* renderbuffer_manager,
37        TextureManager* texture_manager,
38        bool cleared) = 0;
39    virtual bool IsTexture(TextureRef* texture) const = 0;
40    virtual bool IsRenderbuffer(
41        Renderbuffer* renderbuffer) const = 0;
42    virtual bool CanRenderTo() const = 0;
43    virtual void DetachFromFramebuffer() const = 0;
44    virtual bool ValidForAttachmentType(
45        GLenum attachment_type, uint32 max_color_attachments) = 0;
46    virtual void AddToSignature(
47        TextureManager* texture_manager, std::string* signature) const = 0;
48
49   protected:
50    friend class base::RefCounted<Attachment>;
51    virtual ~Attachment() {}
52  };
53
54  Framebuffer(FramebufferManager* manager, GLuint service_id);
55
56  GLuint service_id() const {
57    return service_id_;
58  }
59
60  bool HasUnclearedAttachment(GLenum attachment) const;
61
62  void MarkAttachmentAsCleared(
63    RenderbufferManager* renderbuffer_manager,
64    TextureManager* texture_manager,
65    GLenum attachment,
66    bool cleared);
67
68  // Attaches a renderbuffer to a particlar attachment.
69  // Pass null to detach.
70  void AttachRenderbuffer(
71      GLenum attachment, Renderbuffer* renderbuffer);
72
73  // Attaches a texture to a particlar attachment. Pass null to detach.
74  void AttachTexture(
75      GLenum attachment, TextureRef* texture_ref, GLenum target,
76      GLint level);
77
78  // Unbinds the given renderbuffer if it is bound.
79  void UnbindRenderbuffer(
80      GLenum target, Renderbuffer* renderbuffer);
81
82  // Unbinds the given texture if it is bound.
83  void UnbindTexture(
84      GLenum target, TextureRef* texture_ref);
85
86  const Attachment* GetAttachment(GLenum attachment) const;
87
88  bool IsDeleted() const {
89    return deleted_;
90  }
91
92  void MarkAsValid() {
93    has_been_bound_ = true;
94  }
95
96  bool IsValid() const {
97    return has_been_bound_ && !IsDeleted();
98  }
99
100  bool HasDepthAttachment() const;
101  bool HasStencilAttachment() const;
102  GLenum GetColorAttachmentFormat() const;
103
104  // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
105  // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
106  // use this combination of attachments. Otherwise returns the value
107  // that glCheckFramebufferStatus should return for this set of attachments.
108  // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
109  // not mean the real OpenGL will consider it framebuffer complete. It just
110  // means it passed our tests.
111  GLenum IsPossiblyComplete() const;
112
113  // Implements optimized glGetFramebufferStatus.
114  GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
115
116  // Check all attachments are cleared
117  bool IsCleared() const;
118
119  GLenum GetDrawBuffer(GLenum draw_buffer) const;
120
121  void SetDrawBuffers(GLsizei n, const GLenum* bufs);
122
123  static void ClearFramebufferCompleteComboMap();
124
125  static bool AllowFramebufferComboCompleteMapForTesting() {
126    return allow_framebuffer_combo_complete_map_;
127  }
128
129 private:
130  friend class FramebufferManager;
131  friend class base::RefCounted<Framebuffer>;
132
133  ~Framebuffer();
134
135  void MarkAsDeleted();
136
137  void MarkAttachmentsAsCleared(
138    RenderbufferManager* renderbuffer_manager,
139    TextureManager* texture_manager,
140    bool cleared);
141
142  void MarkAsComplete(unsigned state_id) {
143    framebuffer_complete_state_count_id_ = state_id;
144  }
145
146  unsigned framebuffer_complete_state_count_id() const {
147    return framebuffer_complete_state_count_id_;
148  }
149
150  // The managers that owns this.
151  FramebufferManager* manager_;
152
153  bool deleted_;
154
155  // Service side framebuffer id.
156  GLuint service_id_;
157
158  // Whether this framebuffer has ever been bound.
159  bool has_been_bound_;
160
161  // state count when this framebuffer was last checked for completeness.
162  unsigned framebuffer_complete_state_count_id_;
163
164  // A map of attachments.
165  typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
166  AttachmentMap attachments_;
167
168  // A map of successful frame buffer combos. If it's in the map
169  // it should be FRAMEBUFFER_COMPLETE.
170  typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
171  static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
172  static bool allow_framebuffer_combo_complete_map_;
173
174  scoped_ptr<GLenum[]> draw_buffers_;
175
176  DISALLOW_COPY_AND_ASSIGN(Framebuffer);
177};
178
179// This class keeps track of the frambebuffers and their attached renderbuffers
180// so we can correctly clear them.
181class GPU_EXPORT FramebufferManager {
182 public:
183  FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments);
184  ~FramebufferManager();
185
186  // Must call before destruction.
187  void Destroy(bool have_context);
188
189  // Creates a Framebuffer for the given framebuffer.
190  void CreateFramebuffer(GLuint client_id, GLuint service_id);
191
192  // Gets the framebuffer info for the given framebuffer.
193  Framebuffer* GetFramebuffer(GLuint client_id);
194
195  // Removes a framebuffer info for the given framebuffer.
196  void RemoveFramebuffer(GLuint client_id);
197
198  // Gets a client id for a given service id.
199  bool GetClientId(GLuint service_id, GLuint* client_id) const;
200
201  void MarkAttachmentsAsCleared(
202    Framebuffer* framebuffer,
203    RenderbufferManager* renderbuffer_manager,
204    TextureManager* texture_manager);
205
206  void MarkAsComplete(Framebuffer* framebuffer);
207
208  bool IsComplete(Framebuffer* framebuffer);
209
210  void IncFramebufferStateChangeCount() {
211    // make sure this is never 0.
212    framebuffer_state_change_count_ =
213        (framebuffer_state_change_count_ + 1) | 0x80000000U;
214  }
215
216 private:
217  friend class Framebuffer;
218
219  void StartTracking(Framebuffer* framebuffer);
220  void StopTracking(Framebuffer* framebuffer);
221
222  // Info for each framebuffer in the system.
223  typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
224      FramebufferMap;
225  FramebufferMap framebuffers_;
226
227  // Incremented anytime anything changes that might effect framebuffer
228  // state.
229  unsigned framebuffer_state_change_count_;
230
231  // Counts the number of Framebuffer allocated with 'this' as its manager.
232  // Allows to check no Framebuffer will outlive this.
233  unsigned int framebuffer_count_;
234
235  bool have_context_;
236
237  uint32 max_draw_buffers_;
238  uint32 max_color_attachments_;
239
240  DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
241};
242
243}  // namespace gles2
244}  // namespace gpu
245
246#endif  // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
247