| // |
| // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| // Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer |
| // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. |
| |
| #ifndef LIBANGLE_FRAMEBUFFER_H_ |
| #define LIBANGLE_FRAMEBUFFER_H_ |
| |
| #include <vector> |
| |
| #include "common/Optional.h" |
| #include "common/angleutils.h" |
| #include "libANGLE/Constants.h" |
| #include "libANGLE/Debug.h" |
| #include "libANGLE/Error.h" |
| #include "libANGLE/FramebufferAttachment.h" |
| #include "libANGLE/RefCountObject.h" |
| #include "libANGLE/signal_utils.h" |
| |
| namespace rx |
| { |
| class ContextImpl; |
| class GLImplFactory; |
| class FramebufferImpl; |
| class RenderbufferImpl; |
| class SurfaceImpl; |
| } |
| |
| namespace egl |
| { |
| class Display; |
| class Surface; |
| } |
| |
| namespace gl |
| { |
| class Context; |
| class ContextState; |
| class Framebuffer; |
| class Renderbuffer; |
| class State; |
| class Texture; |
| class TextureCapsMap; |
| class ValidationContext; |
| struct Caps; |
| struct Extensions; |
| struct ImageIndex; |
| struct Rectangle; |
| |
| class FramebufferState final : angle::NonCopyable |
| { |
| public: |
| FramebufferState(); |
| explicit FramebufferState(const Caps &caps); |
| ~FramebufferState(); |
| |
| const std::string &getLabel(); |
| |
| const FramebufferAttachment *getAttachment(GLenum attachment) const; |
| const FramebufferAttachment *getReadAttachment() const; |
| const FramebufferAttachment *getFirstNonNullAttachment() const; |
| const FramebufferAttachment *getFirstColorAttachment() const; |
| const FramebufferAttachment *getDepthOrStencilAttachment() const; |
| const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; |
| const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; |
| const FramebufferAttachment *getDepthAttachment() const; |
| const FramebufferAttachment *getStencilAttachment() const; |
| const FramebufferAttachment *getDepthStencilAttachment() const; |
| |
| const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; } |
| GLenum getReadBufferState() const { return mReadBufferState; } |
| const std::vector<FramebufferAttachment> &getColorAttachments() const |
| { |
| return mColorAttachments; |
| } |
| |
| bool attachmentsHaveSameDimensions() const; |
| bool colorAttachmentsAreUniqueImages() const; |
| |
| const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const; |
| size_t getDrawBufferCount() const; |
| |
| GLint getDefaultWidth() const { return mDefaultWidth; }; |
| GLint getDefaultHeight() const { return mDefaultHeight; }; |
| GLint getDefaultSamples() const { return mDefaultSamples; }; |
| GLboolean getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; }; |
| |
| private: |
| friend class Framebuffer; |
| |
| std::string mLabel; |
| |
| std::vector<FramebufferAttachment> mColorAttachments; |
| FramebufferAttachment mDepthAttachment; |
| FramebufferAttachment mStencilAttachment; |
| |
| std::vector<GLenum> mDrawBufferStates; |
| GLenum mReadBufferState; |
| angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS> mEnabledDrawBuffers; |
| |
| GLint mDefaultWidth; |
| GLint mDefaultHeight; |
| GLint mDefaultSamples; |
| GLboolean mDefaultFixedSampleLocations; |
| |
| // It's necessary to store all this extra state so we can restore attachments |
| // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1. |
| FramebufferAttachment mWebGLDepthStencilAttachment; |
| FramebufferAttachment mWebGLDepthAttachment; |
| FramebufferAttachment mWebGLStencilAttachment; |
| bool mWebGLDepthStencilConsistent; |
| }; |
| |
| using OnAttachmentDirtyBinding = angle::ChannelBinding<>; |
| using OnAttachmentDirtyChannel = angle::BroadcastChannel<>; |
| using OnAttachmentDirtyReceiver = angle::SignalReceiver<>; |
| |
| class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver |
| { |
| public: |
| // Constructor to build application-defined framebuffers |
| Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id); |
| // Constructor to build default framebuffers for a surface |
| Framebuffer(egl::Surface *surface); |
| // Constructor to build a fake default framebuffer when surfaceless |
| Framebuffer(rx::GLImplFactory *factory); |
| |
| virtual ~Framebuffer(); |
| void destroy(const Context *context); |
| void destroyDefault(const egl::Display *display); |
| |
| void setLabel(const std::string &label) override; |
| const std::string &getLabel() const override; |
| |
| rx::FramebufferImpl *getImplementation() const { return mImpl; } |
| |
| GLuint id() const { return mId; } |
| |
| void setAttachment(const Context *context, |
| GLenum type, |
| GLenum binding, |
| const ImageIndex &textureIndex, |
| FramebufferAttachmentObject *resource); |
| void resetAttachment(const Context *context, GLenum binding); |
| |
| void detachTexture(const Context *context, GLuint texture); |
| void detachRenderbuffer(const Context *context, GLuint renderbuffer); |
| |
| const FramebufferAttachment *getColorbuffer(size_t colorAttachment) const; |
| const FramebufferAttachment *getDepthbuffer() const; |
| const FramebufferAttachment *getStencilbuffer() const; |
| const FramebufferAttachment *getDepthStencilBuffer() const; |
| const FramebufferAttachment *getDepthOrStencilbuffer() const; |
| const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; |
| const FramebufferAttachment *getReadColorbuffer() const; |
| GLenum getReadColorbufferType() const; |
| const FramebufferAttachment *getFirstColorbuffer() const; |
| |
| const FramebufferAttachment *getAttachment(GLenum attachment) const; |
| |
| size_t getDrawbufferStateCount() const; |
| GLenum getDrawBufferState(size_t drawBuffer) const; |
| const std::vector<GLenum> &getDrawBufferStates() const; |
| void setDrawBuffers(size_t count, const GLenum *buffers); |
| const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const; |
| bool hasEnabledDrawBuffer() const; |
| |
| GLenum getReadBufferState() const; |
| void setReadBuffer(GLenum buffer); |
| |
| size_t getNumColorBuffers() const; |
| bool hasDepth() const; |
| bool hasStencil() const; |
| |
| bool usingExtendedDrawBuffers() const; |
| |
| // This method calls checkStatus. |
| int getSamples(const Context *context); |
| |
| Error getSamplePosition(size_t index, GLfloat *xy) const; |
| |
| GLint getDefaultWidth() const; |
| GLint getDefaultHeight() const; |
| GLint getDefaultSamples() const; |
| GLboolean getDefaultFixedSampleLocations() const; |
| void setDefaultWidth(GLint defaultWidth); |
| void setDefaultHeight(GLint defaultHeight); |
| void setDefaultSamples(GLint defaultSamples); |
| void setDefaultFixedSampleLocations(GLboolean defaultFixedSampleLocations); |
| |
| void invalidateCompletenessCache(); |
| |
| GLenum checkStatus(const Context *context); |
| |
| // TODO(jmadill): Remove this kludge. |
| GLenum checkStatus(const ValidationContext *context); |
| int getSamples(const ValidationContext *context); |
| |
| // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE. |
| bool complete(const Context *context); |
| bool cachedComplete() const; |
| |
| bool hasValidDepthStencil() const; |
| |
| Error discard(size_t count, const GLenum *attachments); |
| Error invalidate(size_t count, const GLenum *attachments); |
| Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area); |
| |
| Error clear(rx::ContextImpl *context, GLbitfield mask); |
| Error clearBufferfv(rx::ContextImpl *context, |
| GLenum buffer, |
| GLint drawbuffer, |
| const GLfloat *values); |
| Error clearBufferuiv(rx::ContextImpl *context, |
| GLenum buffer, |
| GLint drawbuffer, |
| const GLuint *values); |
| Error clearBufferiv(rx::ContextImpl *context, |
| GLenum buffer, |
| GLint drawbuffer, |
| const GLint *values); |
| Error clearBufferfi(rx::ContextImpl *context, |
| GLenum buffer, |
| GLint drawbuffer, |
| GLfloat depth, |
| GLint stencil); |
| |
| GLenum getImplementationColorReadFormat() const; |
| GLenum getImplementationColorReadType() const; |
| Error readPixels(rx::ContextImpl *context, |
| const gl::Rectangle &area, |
| GLenum format, |
| GLenum type, |
| void *pixels) const; |
| |
| Error blit(rx::ContextImpl *context, |
| const Rectangle &sourceArea, |
| const Rectangle &destArea, |
| GLbitfield mask, |
| GLenum filter); |
| |
| enum DirtyBitType : uint32_t |
| { |
| DIRTY_BIT_COLOR_ATTACHMENT_0, |
| DIRTY_BIT_COLOR_ATTACHMENT_MAX = |
| DIRTY_BIT_COLOR_ATTACHMENT_0 + gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS, |
| DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX, |
| DIRTY_BIT_STENCIL_ATTACHMENT, |
| DIRTY_BIT_DRAW_BUFFERS, |
| DIRTY_BIT_READ_BUFFER, |
| DIRTY_BIT_DEFAULT_WIDTH, |
| DIRTY_BIT_DEFAULT_HEIGHT, |
| DIRTY_BIT_DEFAULT_SAMPLES, |
| DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS, |
| DIRTY_BIT_UNKNOWN, |
| DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN |
| }; |
| |
| typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits; |
| bool hasAnyDirtyBit() const { return mDirtyBits.any(); } |
| |
| void syncState(const Context *context); |
| |
| // angle::SignalReceiver implementation |
| void signal(uint32_t token) override; |
| |
| bool formsRenderingFeedbackLoopWith(const State &state) const; |
| bool formsCopyingFeedbackLoopWith(GLuint copyTextureID, |
| GLint copyTextureLevel, |
| GLint copyTextureLayer) const; |
| |
| private: |
| void detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId); |
| void detachMatchingAttachment(FramebufferAttachment *attachment, |
| GLenum matchType, |
| GLuint matchId, |
| size_t dirtyBit); |
| GLenum checkStatusImpl(const Context *context); |
| void commitWebGL1DepthStencilIfConsistent(); |
| |
| void setAttachmentImpl(GLenum type, |
| GLenum binding, |
| const ImageIndex &textureIndex, |
| FramebufferAttachmentObject *resource); |
| void updateAttachment(FramebufferAttachment *attachment, |
| size_t dirtyBit, |
| OnAttachmentDirtyBinding *onDirtyBinding, |
| GLenum type, |
| GLenum binding, |
| const ImageIndex &textureIndex, |
| FramebufferAttachmentObject *resource); |
| |
| FramebufferState mState; |
| rx::FramebufferImpl *mImpl; |
| GLuint mId; |
| |
| Optional<GLenum> mCachedStatus; |
| std::vector<OnAttachmentDirtyBinding> mDirtyColorAttachmentBindings; |
| OnAttachmentDirtyBinding mDirtyDepthAttachmentBinding; |
| OnAttachmentDirtyBinding mDirtyStencilAttachmentBinding; |
| |
| DirtyBits mDirtyBits; |
| }; |
| |
| } // namespace gl |
| |
| #endif // LIBANGLE_FRAMEBUFFER_H_ |