Home | History | Annotate | Download | only in service
      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 <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/containers/hash_tables.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "gpu/command_buffer/service/gl_utils.h"
     15 #include "gpu/gpu_export.h"
     16 
     17 namespace gpu {
     18 namespace gles2 {
     19 
     20 class FramebufferManager;
     21 class Renderbuffer;
     22 class RenderbufferManager;
     23 class Texture;
     24 class TextureRef;
     25 class TextureManager;
     26 
     27 // Info about a particular Framebuffer.
     28 class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
     29  public:
     30   class Attachment : public base::RefCounted<Attachment> {
     31    public:
     32     virtual GLsizei width() const = 0;
     33     virtual GLsizei height() const = 0;
     34     virtual GLenum internal_format() const = 0;
     35     virtual GLenum texture_type() const = 0;
     36     virtual GLsizei samples() const = 0;
     37     virtual GLuint object_name() const = 0;
     38     virtual bool cleared() const = 0;
     39     virtual void SetCleared(
     40         RenderbufferManager* renderbuffer_manager,
     41         TextureManager* texture_manager,
     42         bool cleared) = 0;
     43     virtual bool IsTexture(TextureRef* texture) const = 0;
     44     virtual bool IsRenderbuffer(
     45         Renderbuffer* renderbuffer) const = 0;
     46     virtual bool CanRenderTo() const = 0;
     47     virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0;
     48     virtual bool ValidForAttachmentType(
     49         GLenum attachment_type, uint32 max_color_attachments) = 0;
     50     virtual void AddToSignature(
     51         TextureManager* texture_manager, std::string* signature) const = 0;
     52     virtual void OnWillRenderTo() const = 0;
     53     virtual void OnDidRenderTo() const = 0;
     54 
     55    protected:
     56     friend class base::RefCounted<Attachment>;
     57     virtual ~Attachment() {}
     58   };
     59 
     60   Framebuffer(FramebufferManager* manager, GLuint service_id);
     61 
     62   GLuint service_id() const {
     63     return service_id_;
     64   }
     65 
     66   bool HasUnclearedAttachment(GLenum attachment) const;
     67 
     68   void MarkAttachmentAsCleared(
     69     RenderbufferManager* renderbuffer_manager,
     70     TextureManager* texture_manager,
     71     GLenum attachment,
     72     bool cleared);
     73 
     74   // Attaches a renderbuffer to a particlar attachment.
     75   // Pass null to detach.
     76   void AttachRenderbuffer(
     77       GLenum attachment, Renderbuffer* renderbuffer);
     78 
     79   // Attaches a texture to a particlar attachment. Pass null to detach.
     80   void AttachTexture(
     81       GLenum attachment, TextureRef* texture_ref, GLenum target,
     82       GLint level, GLsizei samples);
     83 
     84   // Unbinds the given renderbuffer if it is bound.
     85   void UnbindRenderbuffer(
     86       GLenum target, Renderbuffer* renderbuffer);
     87 
     88   // Unbinds the given texture if it is bound.
     89   void UnbindTexture(
     90       GLenum target, TextureRef* texture_ref);
     91 
     92   const Attachment* GetAttachment(GLenum attachment) const;
     93 
     94   bool IsDeleted() const {
     95     return deleted_;
     96   }
     97 
     98   void MarkAsValid() {
     99     has_been_bound_ = true;
    100   }
    101 
    102   bool IsValid() const {
    103     return has_been_bound_ && !IsDeleted();
    104   }
    105 
    106   bool HasDepthAttachment() const;
    107   bool HasStencilAttachment() const;
    108   GLenum GetColorAttachmentFormat() const;
    109   // If the color attachment is a texture, returns its type; otherwise,
    110   // returns 0.
    111   GLenum GetColorAttachmentTextureType() const;
    112 
    113   // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
    114   // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
    115   // use this combination of attachments. Otherwise returns the value
    116   // that glCheckFramebufferStatus should return for this set of attachments.
    117   // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
    118   // not mean the real OpenGL will consider it framebuffer complete. It just
    119   // means it passed our tests.
    120   GLenum IsPossiblyComplete() const;
    121 
    122   // Implements optimized glGetFramebufferStatus.
    123   GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
    124 
    125   // Check all attachments are cleared
    126   bool IsCleared() const;
    127 
    128   GLenum GetDrawBuffer(GLenum draw_buffer) const;
    129 
    130   void SetDrawBuffers(GLsizei n, const GLenum* bufs);
    131 
    132   // Return true if any draw buffers has an alpha channel.
    133   bool HasAlphaMRT() const;
    134 
    135   static void ClearFramebufferCompleteComboMap();
    136 
    137   static bool AllowFramebufferComboCompleteMapForTesting() {
    138     return allow_framebuffer_combo_complete_map_;
    139   }
    140 
    141   void OnTextureRefDetached(TextureRef* texture);
    142   void OnWillRenderTo() const;
    143   void OnDidRenderTo() const;
    144 
    145  private:
    146   friend class FramebufferManager;
    147   friend class base::RefCounted<Framebuffer>;
    148 
    149   ~Framebuffer();
    150 
    151   void MarkAsDeleted();
    152 
    153   void MarkAttachmentsAsCleared(
    154     RenderbufferManager* renderbuffer_manager,
    155     TextureManager* texture_manager,
    156     bool cleared);
    157 
    158   void MarkAsComplete(unsigned state_id) {
    159     framebuffer_complete_state_count_id_ = state_id;
    160   }
    161 
    162   unsigned framebuffer_complete_state_count_id() const {
    163     return framebuffer_complete_state_count_id_;
    164   }
    165 
    166   // The managers that owns this.
    167   FramebufferManager* manager_;
    168 
    169   bool deleted_;
    170 
    171   // Service side framebuffer id.
    172   GLuint service_id_;
    173 
    174   // Whether this framebuffer has ever been bound.
    175   bool has_been_bound_;
    176 
    177   // state count when this framebuffer was last checked for completeness.
    178   unsigned framebuffer_complete_state_count_id_;
    179 
    180   // A map of attachments.
    181   typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
    182   AttachmentMap attachments_;
    183 
    184   // A map of successful frame buffer combos. If it's in the map
    185   // it should be FRAMEBUFFER_COMPLETE.
    186   typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
    187   static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
    188   static bool allow_framebuffer_combo_complete_map_;
    189 
    190   scoped_ptr<GLenum[]> draw_buffers_;
    191 
    192   DISALLOW_COPY_AND_ASSIGN(Framebuffer);
    193 };
    194 
    195 struct DecoderFramebufferState {
    196   DecoderFramebufferState();
    197   ~DecoderFramebufferState();
    198 
    199   // State saved for clearing so we can clear render buffers and then
    200   // restore to these values.
    201   bool clear_state_dirty;
    202 
    203   // The currently bound framebuffers
    204   scoped_refptr<Framebuffer> bound_read_framebuffer;
    205   scoped_refptr<Framebuffer> bound_draw_framebuffer;
    206 };
    207 
    208 // This class keeps track of the frambebuffers and their attached renderbuffers
    209 // so we can correctly clear them.
    210 class GPU_EXPORT FramebufferManager {
    211  public:
    212   class GPU_EXPORT TextureDetachObserver {
    213    public:
    214     TextureDetachObserver();
    215     virtual ~TextureDetachObserver();
    216 
    217     virtual void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) = 0;
    218 
    219    private:
    220     DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver);
    221   };
    222 
    223   FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments);
    224   ~FramebufferManager();
    225 
    226   // Must call before destruction.
    227   void Destroy(bool have_context);
    228 
    229   // Creates a Framebuffer for the given framebuffer.
    230   void CreateFramebuffer(GLuint client_id, GLuint service_id);
    231 
    232   // Gets the framebuffer info for the given framebuffer.
    233   Framebuffer* GetFramebuffer(GLuint client_id);
    234 
    235   // Removes a framebuffer info for the given framebuffer.
    236   void RemoveFramebuffer(GLuint client_id);
    237 
    238   // Gets a client id for a given service id.
    239   bool GetClientId(GLuint service_id, GLuint* client_id) const;
    240 
    241   void MarkAttachmentsAsCleared(
    242     Framebuffer* framebuffer,
    243     RenderbufferManager* renderbuffer_manager,
    244     TextureManager* texture_manager);
    245 
    246   void MarkAsComplete(Framebuffer* framebuffer);
    247 
    248   bool IsComplete(Framebuffer* framebuffer);
    249 
    250   void IncFramebufferStateChangeCount() {
    251     // make sure this is never 0.
    252     framebuffer_state_change_count_ =
    253         (framebuffer_state_change_count_ + 1) | 0x80000000U;
    254   }
    255 
    256   void AddObserver(TextureDetachObserver* observer) {
    257     texture_detach_observers_.push_back(observer);
    258   }
    259 
    260   void RemoveObserver(TextureDetachObserver* observer) {
    261     texture_detach_observers_.erase(
    262         std::remove(texture_detach_observers_.begin(),
    263                     texture_detach_observers_.end(),
    264                     observer),
    265         texture_detach_observers_.end());
    266   }
    267 
    268  private:
    269   friend class Framebuffer;
    270 
    271   void StartTracking(Framebuffer* framebuffer);
    272   void StopTracking(Framebuffer* framebuffer);
    273 
    274   void OnTextureRefDetached(TextureRef* texture);
    275 
    276   // Info for each framebuffer in the system.
    277   typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
    278       FramebufferMap;
    279   FramebufferMap framebuffers_;
    280 
    281   // Incremented anytime anything changes that might effect framebuffer
    282   // state.
    283   unsigned framebuffer_state_change_count_;
    284 
    285   // Counts the number of Framebuffer allocated with 'this' as its manager.
    286   // Allows to check no Framebuffer will outlive this.
    287   unsigned int framebuffer_count_;
    288 
    289   bool have_context_;
    290 
    291   uint32 max_draw_buffers_;
    292   uint32 max_color_attachments_;
    293 
    294   typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector;
    295   TextureDetachObserverVector texture_detach_observers_;
    296 
    297   DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
    298 };
    299 
    300 }  // namespace gles2
    301 }  // namespace gpu
    302 
    303 #endif  // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
    304