// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/shader_manager.h"
#include "gpu/gpu_export.h"

namespace gpu {
namespace gles2 {

class FeatureInfo;
class FramebufferCompletenessCache;
class FramebufferManager;
class Renderbuffer;
class RenderbufferManager;
class Texture;
class TextureRef;
class TextureManager;

// Info about a particular Framebuffer.
class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
 public:
  class Attachment : public base::RefCounted<Attachment> {
   public:
    virtual GLsizei width() const = 0;
    virtual GLsizei height() const = 0;
    virtual GLenum internal_format() const = 0;
    virtual GLenum texture_type() const = 0;
    virtual GLsizei samples() const = 0;
    virtual GLuint object_name() const = 0;
    virtual bool cleared() const = 0;
    virtual void SetCleared(
        RenderbufferManager* renderbuffer_manager,
        TextureManager* texture_manager,
        bool cleared) = 0;
    virtual bool IsPartiallyCleared() const = 0;
    virtual bool IsTextureAttachment() const = 0;
    virtual bool IsRenderbufferAttachment() const = 0;
    virtual bool IsTexture(TextureRef* texture) const = 0;
    virtual bool IsRenderbuffer(Renderbuffer* renderbuffer) const = 0;
    virtual bool IsSameAttachment(const Attachment* attachment) const = 0;
    virtual bool Is3D() const = 0;

    // If it's a 3D texture attachment, return true if
    // FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is smaller than the number of
    // layers in the texture.
    virtual bool IsLayerValid() const = 0;

    virtual bool CanRenderTo(const FeatureInfo* feature_info) const = 0;
    virtual void DetachFromFramebuffer(Framebuffer* framebuffer) const = 0;
    virtual bool ValidForAttachmentType(GLenum attachment_type,
                                        ContextType context_type,
                                        uint32_t max_color_attachments) = 0;
    virtual size_t GetSignatureSize(TextureManager* texture_manager) const = 0;
    virtual void AddToSignature(
        TextureManager* texture_manager, std::string* signature) const = 0;
    virtual bool FormsFeedbackLoop(TextureRef* texture, GLint level) const = 0;
    virtual bool EmulatingRGB() const = 0;

   protected:
    friend class base::RefCounted<Attachment>;
    virtual ~Attachment() {}
  };

  Framebuffer(FramebufferManager* manager, GLuint service_id);

  GLuint service_id() const {
    return service_id_;
  }

  bool HasUnclearedAttachment(GLenum attachment) const;
  bool HasUnclearedColorAttachments() const;

  bool HasSRGBAttachments() const;
  bool HasDepthStencilFormatAttachment(GLenum attachment) const;

  void ClearUnclearedIntOr3DTexturesOrPartiallyClearedTextures(
      GLES2Decoder* decoder,
      TextureManager* texture_manager);

  bool HasUnclearedIntRenderbufferAttachments() const;

  void ClearUnclearedIntRenderbufferAttachments(
    RenderbufferManager* renderbuffer_manager);

  void MarkAttachmentAsCleared(
    RenderbufferManager* renderbuffer_manager,
    TextureManager* texture_manager,
    GLenum attachment,
    bool cleared);

  // Unbinds all attachments from this framebuffer for workaround
  // 'unbind_attachments_on_bound_render_fbo_delete'.  The Framebuffer must be
  // bound when calling this.
  void DoUnbindGLAttachmentsForWorkaround(GLenum target);

  // Attaches a renderbuffer to a particlar attachment.
  // Pass null to detach.
  void AttachRenderbuffer(
      GLenum attachment, Renderbuffer* renderbuffer);

  // Attaches a texture to a particlar attachment. Pass null to detach.
  void AttachTexture(
      GLenum attachment, TextureRef* texture_ref, GLenum target,
      GLint level, GLsizei samples);
  void AttachTextureLayer(
      GLenum attachment, TextureRef* texture_ref, GLenum target,
      GLint level, GLint layer);

  // Unbinds the given renderbuffer if it is bound.
  void UnbindRenderbuffer(
      GLenum target, Renderbuffer* renderbuffer);

  // Unbinds the given texture if it is bound.
  void UnbindTexture(
      GLenum target, TextureRef* texture_ref);

  const Attachment* GetAttachment(GLenum attachment) const;

  const Attachment* GetReadBufferAttachment() const;

  GLsizei GetSamples() const;

  bool IsDeleted() const {
    return deleted_;
  }

  void MarkAsValid() {
    has_been_bound_ = true;
  }

  bool IsValid() const {
    return has_been_bound_ && !IsDeleted();
  }

  bool HasColorAttachment(int index) const;
  bool HasDepthAttachment() const;
  bool HasStencilAttachment() const;
  GLenum GetDepthFormat() const;
  GLenum GetStencilFormat() const;
  GLenum GetDrawBufferInternalFormat() const;
  GLenum GetReadBufferInternalFormat() const;
  // If the color attachment is a texture, returns its type; otherwise,
  // returns 0.
  GLenum GetReadBufferTextureType() const;

  // Verify all the rules in OpenGL ES 2.0.25 4.4.5 are followed.
  // Returns GL_FRAMEBUFFER_COMPLETE if there are no reasons we know we can't
  // use this combination of attachments. Otherwise returns the value
  // that glCheckFramebufferStatus should return for this set of attachments.
  // Note that receiving GL_FRAMEBUFFER_COMPLETE from this function does
  // not mean the real OpenGL will consider it framebuffer complete. It just
  // means it passed our tests.
  GLenum IsPossiblyComplete(const FeatureInfo* feature_info) const;

  // Implements optimized glGetFramebufferStatus.
  GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;

  // Check all attachments are cleared
  bool IsCleared() const;

  GLenum GetDrawBuffer(GLenum draw_buffer) const;

  void SetDrawBuffers(GLsizei n, const GLenum* bufs);

  // If a color buffer is attached to GL_COLOR_ATTACHMENTi, enable that
  // draw buffer for glClear().
  // Return true if the DrawBuffers() is actually called.
  bool PrepareDrawBuffersForClearingUninitializedAttachments() const;

  // Restore |adjusted_draw_buffers_|.
  void RestoreDrawBuffers() const;

  // Checks if a draw buffer's format and its corresponding fragment shader
  // output's type are compatible, i.e., a signed integer typed variable is
  // incompatible with a float or unsigned integer buffer.
  // Return false if incompaticle.
  // Otherwise, filter out the draw buffers that are not written to but are not
  // NONE through DrawBuffers, to be on the safe side. Return true.
  // This is applied before a draw call.
  bool ValidateAndAdjustDrawBuffers(uint32_t fragment_output_type_mask,
                                    uint32_t fragment_output_written_mask);

  bool ContainsActiveIntegerAttachments() const;

  // Return true if any draw buffers has an alpha channel.
  bool HasAlphaMRT() const;

  // Return false if any two active color attachments have different internal
  // formats.
  bool HasSameInternalFormatsMRT() const;

  void set_read_buffer(GLenum read_buffer) {
    read_buffer_ = read_buffer;
  }

  GLenum read_buffer() const {
    return read_buffer_;
  }

  // See member declaration for details.
  // The data are only valid if fbo is complete.
  uint32_t draw_buffer_type_mask() const {
    return draw_buffer_type_mask_;
  }
  uint32_t draw_buffer_bound_mask() const {
    return draw_buffer_bound_mask_;
  }

 private:
  friend class FramebufferManager;
  friend class base::RefCounted<Framebuffer>;

  ~Framebuffer();

  void MarkAsDeleted();

  void MarkAttachmentsAsCleared(
    RenderbufferManager* renderbuffer_manager,
    TextureManager* texture_manager,
    bool cleared);

  void MarkAsComplete(unsigned state_id) {
    UpdateDrawBufferMasks();
    framebuffer_complete_state_count_id_ = state_id;
  }

  unsigned framebuffer_complete_state_count_id() const {
    return framebuffer_complete_state_count_id_;
  }

  // Cache color attachments' base type mask (FLOAT, INT, UINT) and bound mask.
  // If an attachment point has no image, it's set as UNDEFINED_TYPE.
  // This call is only valid on a complete fbo.
  void UpdateDrawBufferMasks();

  // The managers that owns this.
  FramebufferManager* manager_;

  bool deleted_;

  // Service side framebuffer id.
  GLuint service_id_;

  // Whether this framebuffer has ever been bound.
  bool has_been_bound_;

  // state count when this framebuffer was last checked for completeness.
  unsigned framebuffer_complete_state_count_id_;

  // A map of attachments.
  typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
  AttachmentMap attachments_;

  // User's draw buffers setting through DrawBuffers() call.
  std::unique_ptr<GLenum[]> draw_buffers_;

  // If a draw buffer does not have an image, or it has no corresponding
  // fragment shader output variable, it might be filtered out as NONE.
  // Note that the actually draw buffers setting sent to the driver is always
  // consistent with |adjusted_draw_buffers_|, not |draw_buffers_|.
  std::unique_ptr<GLenum[]> adjusted_draw_buffers_;

  // Draw buffer base types: FLOAT, INT, or UINT.
  // We have up to 16 draw buffers, each is encoded into 2 bits, total 32 bits:
  // the lowest 2 bits for draw buffer 0, the highest 2 bits for draw buffer 15.
  uint32_t draw_buffer_type_mask_;
  // Same layout as above, 2 bits per draw buffer, 0x03 if a draw buffer has a
  // bound image, 0x00 if not.
  uint32_t draw_buffer_bound_mask_;
  // This is the mask for the actual draw buffers sent to driver.
  uint32_t adjusted_draw_buffer_bound_mask_;

  GLenum read_buffer_;

  DISALLOW_COPY_AND_ASSIGN(Framebuffer);
};

struct DecoderFramebufferState {
  DecoderFramebufferState();
  ~DecoderFramebufferState();

  // State saved for clearing so we can clear render buffers and then
  // restore to these values.
  bool clear_state_dirty;

  // The currently bound framebuffers
  scoped_refptr<Framebuffer> bound_read_framebuffer;
  scoped_refptr<Framebuffer> bound_draw_framebuffer;
};

// This class keeps track of the frambebuffers and their attached renderbuffers
// so we can correctly clear them.
class GPU_EXPORT FramebufferManager {
 public:
  FramebufferManager(uint32_t max_draw_buffers,
                     uint32_t max_color_attachments,
                     ContextType context_type,
                     const scoped_refptr<FramebufferCompletenessCache>&
                         framebuffer_combo_complete_cache);
  ~FramebufferManager();

  // Must call before destruction.
  void Destroy(bool have_context);

  // Creates a Framebuffer for the given framebuffer.
  void CreateFramebuffer(GLuint client_id, GLuint service_id);

  // Gets the framebuffer info for the given framebuffer.
  Framebuffer* GetFramebuffer(GLuint client_id);

  // Removes a framebuffer info for the given framebuffer.
  void RemoveFramebuffer(GLuint client_id);

  // Gets a client id for a given service id.
  bool GetClientId(GLuint service_id, GLuint* client_id) const;

  void MarkAttachmentsAsCleared(
    Framebuffer* framebuffer,
    RenderbufferManager* renderbuffer_manager,
    TextureManager* texture_manager);

  void MarkAsComplete(Framebuffer* framebuffer);

  bool IsComplete(Framebuffer* framebuffer);

  void IncFramebufferStateChangeCount() {
    // make sure this is never 0.
    framebuffer_state_change_count_ =
        (framebuffer_state_change_count_ + 1) | 0x80000000U;
  }

  ContextType context_type() const { return context_type_; }

 private:
  friend class Framebuffer;

  void StartTracking(Framebuffer* framebuffer);
  void StopTracking(Framebuffer* framebuffer);

  FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
    return framebuffer_combo_complete_cache_.get();
  }

  // Info for each framebuffer in the system.
  typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
      FramebufferMap;
  FramebufferMap framebuffers_;

  // Incremented anytime anything changes that might effect framebuffer
  // state.
  unsigned framebuffer_state_change_count_;

  // Counts the number of Framebuffer allocated with 'this' as its manager.
  // Allows to check no Framebuffer will outlive this.
  unsigned int framebuffer_count_;

  bool have_context_;

  uint32_t max_draw_buffers_;
  uint32_t max_color_attachments_;

  ContextType context_type_;

  scoped_refptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;

  DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_MANAGER_H_
