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