michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef WEBGLFRAMEBUFFER_H_ michael@0: #define WEBGLFRAMEBUFFER_H_ michael@0: michael@0: #include "WebGLObjectModel.h" michael@0: michael@0: #include "nsWrapperCache.h" michael@0: michael@0: #include "mozilla/LinkedList.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: class WebGLFramebufferAttachable; michael@0: class WebGLTexture; michael@0: class WebGLRenderbuffer; michael@0: namespace gl { michael@0: class GLContext; michael@0: } michael@0: michael@0: class WebGLFramebuffer MOZ_FINAL michael@0: : public nsWrapperCache michael@0: , public WebGLRefCountedObject michael@0: , public LinkedListElement michael@0: , public WebGLContextBoundObject michael@0: { michael@0: public: michael@0: WebGLFramebuffer(WebGLContext* context); michael@0: michael@0: ~WebGLFramebuffer() { michael@0: DeleteOnce(); michael@0: } michael@0: michael@0: struct Attachment michael@0: { michael@0: // deleting a texture or renderbuffer immediately detaches it michael@0: WebGLRefPtr mTexturePtr; michael@0: WebGLRefPtr mRenderbufferPtr; michael@0: GLenum mAttachmentPoint; michael@0: GLenum mTexImageTarget; michael@0: GLint mTexImageLevel; michael@0: mutable bool mNeedsFinalize; michael@0: michael@0: Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0) michael@0: : mAttachmentPoint(aAttachmentPoint) michael@0: , mNeedsFinalize(false) michael@0: {} michael@0: michael@0: bool IsDefined() const { michael@0: return Texture() || Renderbuffer(); michael@0: } michael@0: michael@0: bool IsDeleteRequested() const; michael@0: michael@0: bool HasAlpha() const; michael@0: bool IsReadableFloat() const; michael@0: michael@0: void SetTexImage(WebGLTexture* tex, GLenum target, GLint level); michael@0: void SetRenderbuffer(WebGLRenderbuffer* rb); michael@0: michael@0: const WebGLTexture* Texture() const { michael@0: return mTexturePtr; michael@0: } michael@0: WebGLTexture* Texture() { michael@0: return mTexturePtr; michael@0: } michael@0: const WebGLRenderbuffer* Renderbuffer() const { michael@0: return mRenderbufferPtr; michael@0: } michael@0: WebGLRenderbuffer* Renderbuffer() { michael@0: return mRenderbufferPtr; michael@0: } michael@0: GLenum TexImageTarget() const { michael@0: return mTexImageTarget; michael@0: } michael@0: GLint TexImageLevel() const { michael@0: return mTexImageLevel; michael@0: } michael@0: michael@0: bool HasUninitializedImageData() const; michael@0: void SetImageDataStatus(WebGLImageDataStatus x); michael@0: michael@0: void Reset() { michael@0: mTexturePtr = nullptr; michael@0: mRenderbufferPtr = nullptr; michael@0: } michael@0: michael@0: const WebGLRectangleObject& RectangleObject() const; michael@0: michael@0: bool HasImage() const; michael@0: bool IsComplete() const; michael@0: michael@0: void FinalizeAttachment(gl::GLContext* gl, GLenum attachmentLoc) const; michael@0: }; michael@0: michael@0: void Delete(); michael@0: michael@0: bool HasEverBeenBound() { return mHasEverBeenBound; } michael@0: void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } michael@0: GLuint GLName() { return mGLName; } michael@0: michael@0: void FramebufferRenderbuffer(GLenum target, michael@0: GLenum attachment, michael@0: GLenum rbtarget, michael@0: WebGLRenderbuffer* wrb); michael@0: michael@0: void FramebufferTexture2D(GLenum target, michael@0: GLenum attachment, michael@0: GLenum textarget, michael@0: WebGLTexture* wtex, michael@0: GLint level); michael@0: michael@0: private: michael@0: void DetachAttachment(WebGLFramebuffer::Attachment& attachment); michael@0: void DetachAllAttachments(); michael@0: const WebGLRectangleObject& GetAnyRectObject() const; michael@0: Attachment* GetAttachmentOrNull(GLenum attachment); michael@0: michael@0: public: michael@0: bool HasDefinedAttachments() const; michael@0: bool HasIncompleteAttachments() const; michael@0: bool AllImageRectsMatch() const; michael@0: GLenum PrecheckFramebufferStatus() const; michael@0: GLenum CheckFramebufferStatus() const; michael@0: michael@0: bool HasDepthStencilConflict() const { michael@0: return int(mDepthAttachment.IsDefined()) + michael@0: int(mStencilAttachment.IsDefined()) + michael@0: int(mDepthStencilAttachment.IsDefined()) >= 2; michael@0: } michael@0: michael@0: size_t ColorAttachmentCount() const { michael@0: return mColorAttachments.Length(); michael@0: } michael@0: const Attachment& ColorAttachment(size_t colorAttachmentId) const { michael@0: return mColorAttachments[colorAttachmentId]; michael@0: } michael@0: michael@0: const Attachment& DepthAttachment() const { michael@0: return mDepthAttachment; michael@0: } michael@0: michael@0: const Attachment& StencilAttachment() const { michael@0: return mStencilAttachment; michael@0: } michael@0: michael@0: const Attachment& DepthStencilAttachment() const { michael@0: return mDepthStencilAttachment; michael@0: } michael@0: michael@0: const Attachment& GetAttachment(GLenum attachment) const; michael@0: michael@0: void DetachTexture(const WebGLTexture* tex); michael@0: michael@0: void DetachRenderbuffer(const WebGLRenderbuffer* rb); michael@0: michael@0: const WebGLRectangleObject& RectangleObject() const; michael@0: michael@0: WebGLContext* GetParentObject() const { michael@0: return Context(); michael@0: } michael@0: michael@0: void FinalizeAttachments() const; michael@0: michael@0: virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE; michael@0: michael@0: NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer) michael@0: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer) michael@0: michael@0: // mask mirrors glClear. michael@0: bool HasCompletePlanes(GLbitfield mask); michael@0: michael@0: bool CheckAndInitializeAttachments(); michael@0: michael@0: bool CheckColorAttachmentNumber(GLenum attachment, const char* functionName) const; michael@0: michael@0: void EnsureColorAttachments(size_t colorAttachmentId); michael@0: michael@0: Attachment* AttachmentFor(GLenum attachment); michael@0: void NotifyAttachableChanged() const; michael@0: michael@0: private: michael@0: mutable GLenum mStatus; michael@0: michael@0: GLuint mGLName; michael@0: bool mHasEverBeenBound; michael@0: michael@0: // we only store pointers to attached renderbuffers, not to attached textures, because michael@0: // we will only need to initialize renderbuffers. Textures are already initialized. michael@0: nsTArray mColorAttachments; michael@0: Attachment mDepthAttachment, michael@0: mStencilAttachment, michael@0: mDepthStencilAttachment; michael@0: }; michael@0: michael@0: } // namespace mozilla michael@0: michael@0: #endif