#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 <unordered_map>
#include <vector>
#include "base/containers/small_map.h"
#include "base/containers/span.h"
#include "base/memory/raw_ptr.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_gles2_export.h"
namespace gpu {
namespace gles2 {
class FeatureInfo;
class FramebufferCompletenessCache;
class FramebufferManager;
class Renderbuffer;
class RenderbufferManager;
class TextureRef;
class TextureManager;
class GPU_GLES2_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 GLint level() 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;
virtual bool IsLayerValid() const = 0;
virtual bool CanRenderTo(const FeatureInfo* feature_info) const = 0;
virtual void DetachFromFramebuffer(Framebuffer* framebuffer,
GLenum attachment) const = 0;
virtual bool ValidForAttachmentType(GLenum attachment_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,
GLint layer) const = 0;
protected:
friend class base::RefCounted<Attachment>;
virtual ~Attachment() = default;
};
Framebuffer(FramebufferManager* manager, GLuint service_id);
Framebuffer(const Framebuffer&) = delete;
Framebuffer& operator=(const Framebuffer&) = delete;
GLuint service_id() const {
return service_id_;
}
bool HasUnclearedAttachment(GLenum attachment) const;
bool HasUnclearedColorAttachments() const;
bool HasSRGBAttachments() const;
bool HasDepthStencilFormatAttachment() 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);
void DoUnbindGLAttachmentsForWorkaround(GLenum target);
void AttachRenderbuffer(
GLenum attachment, Renderbuffer* renderbuffer);
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);
void UnbindRenderbuffer(
GLenum target, Renderbuffer* renderbuffer);
void UnbindTexture(
GLenum target, TextureRef* texture_ref);
const Attachment* GetAttachment(GLenum attachment) const;
const Attachment* GetReadBufferAttachment() const;
gfx::Size GetFramebufferValidSize() 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;
bool HasActiveFloat32ColorAttachment() const;
GLsizei last_color_attachment_id() const { return last_color_attachment_id_; }
GLenum GetDepthFormat() const;
GLenum GetStencilFormat() const;
GLenum GetDrawBufferInternalFormat() const;
GLenum GetReadBufferInternalFormat() const;
GLenum GetReadBufferTextureType() const;
bool GetReadBufferIsMultisampledTexture() const;
GLenum IsPossiblyComplete(const FeatureInfo* feature_info) const;
GLenum GetStatus(TextureManager* texture_manager, GLenum target) const;
bool IsCleared() const;
GLenum GetDrawBuffer(GLenum draw_buffer) const;
void SetDrawBuffers(base::span<const GLenum> bufs);
bool PrepareDrawBuffersForClearingUninitializedAttachments() const;
void RestoreDrawBuffers() const;
bool ValidateAndAdjustDrawBuffers(uint32_t fragment_output_type_mask,
uint32_t fragment_output_written_mask);
void AdjustDrawBuffers();
bool ContainsActiveIntegerAttachments() const;
bool HasAlphaMRT() const;
bool HasSameInternalFormatsMRT() const;
void set_read_buffer(GLenum read_buffer) {
read_buffer_ = read_buffer;
}
GLenum read_buffer() const {
return read_buffer_;
}
uint32_t draw_buffer_type_mask() const {
return draw_buffer_type_mask_;
}
uint32_t draw_buffer_bound_mask() const {
return draw_buffer_bound_mask_;
}
void UnmarkAsComplete() { framebuffer_complete_state_count_id_ = 0; }
private:
friend class FramebufferManager;
friend class base::RefCounted<Framebuffer>;
~Framebuffer();
void OnInsertUpdateLastColorAttachmentId(GLenum attachment);
void OnEraseUpdateLastColorAttachmentId(GLenum attachment);
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_;
}
void UpdateDrawBufferMasks();
void AdjustDrawBuffersImpl(uint32_t desired_mask);
raw_ptr<FramebufferManager> manager_;
bool deleted_;
GLuint service_id_;
bool has_been_bound_;
unsigned framebuffer_complete_state_count_id_;
using AttachmentMap =
base::small_map<std::unordered_map<GLenum, scoped_refptr<Attachment>>, 8>;
AttachmentMap attachments_;
std::unique_ptr<GLenum[]> draw_buffers_;
std::unique_ptr<GLenum[]> adjusted_draw_buffers_;
uint32_t draw_buffer_type_mask_;
uint32_t draw_buffer_float32_mask_;
uint32_t draw_buffer_bound_mask_;
uint32_t adjusted_draw_buffer_bound_mask_;
GLsizei last_color_attachment_id_;
GLenum read_buffer_;
};
struct DecoderFramebufferState {
DecoderFramebufferState();
~DecoderFramebufferState();
bool clear_state_dirty;
scoped_refptr<Framebuffer> bound_read_framebuffer;
scoped_refptr<Framebuffer> bound_draw_framebuffer;
};
class GPU_GLES2_EXPORT FramebufferManager {
public:
FramebufferManager(
uint32_t max_draw_buffers,
uint32_t max_color_attachments,
FramebufferCompletenessCache* framebuffer_combo_complete_cache);
FramebufferManager(const FramebufferManager&) = delete;
FramebufferManager& operator=(const FramebufferManager&) = delete;
~FramebufferManager();
void Destroy(bool have_context);
void CreateFramebuffer(GLuint client_id, GLuint service_id);
Framebuffer* GetFramebuffer(GLuint client_id);
void RemoveFramebuffer(GLuint client_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(const Framebuffer* framebuffer);
void IncFramebufferStateChangeCount() {
framebuffer_state_change_count_ =
(framebuffer_state_change_count_ + 1) | 0x80000000U;
}
private:
friend class Framebuffer;
void StartTracking(Framebuffer* framebuffer);
void StopTracking(Framebuffer* framebuffer);
FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
return framebuffer_combo_complete_cache_;
}
typedef std::unordered_map<GLuint, scoped_refptr<Framebuffer>> FramebufferMap;
FramebufferMap framebuffers_;
unsigned framebuffer_state_change_count_;
unsigned int framebuffer_count_;
bool have_context_;
uint32_t max_draw_buffers_;
uint32_t max_color_attachments_;
raw_ptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;
};
}
}
#endif