123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef WEBGL_FRAMEBUFFER_H_
- #define WEBGL_FRAMEBUFFER_H_
- #include <vector>
- #include "mozilla/LinkedList.h"
- #include "mozilla/WeakPtr.h"
- #include "nsWrapperCache.h"
- #include "WebGLContext.h"
- #include "WebGLRenderbuffer.h"
- #include "WebGLStrongTypes.h"
- #include "WebGLTexture.h"
- #include "WebGLTypes.h"
- namespace mozilla {
- class WebGLFramebuffer;
- class WebGLRenderbuffer;
- class WebGLTexture;
- template<typename T>
- class PlacementArray;
- namespace gl {
- class GLContext;
- } // namespace gl
- class WebGLFBAttachPoint final
- {
- friend class WebGLFramebuffer;
- public:
- WebGLFramebuffer* const mFB;
- const GLenum mAttachmentPoint;
- protected:
- WebGLRefPtr<WebGLTexture> mTexturePtr;
- WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
- TexImageTarget mTexImageTarget;
- GLint mTexImageLayer;
- uint32_t mTexImageLevel;
- ////
- WebGLFBAttachPoint();
- WebGLFBAttachPoint(WebGLFramebuffer* fb, GLenum attachmentPoint);
- public:
- ~WebGLFBAttachPoint();
- ////
- void Unlink();
- bool IsDefined() const;
- bool IsDeleteRequested() const;
- const webgl::FormatUsageInfo* Format() const;
- uint32_t Samples() const;
- bool HasAlpha() const;
- bool IsReadableFloat() const;
- void Clear();
- void SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level,
- GLint layer = 0);
- void SetRenderbuffer(WebGLRenderbuffer* rb);
- WebGLTexture* Texture() const { return mTexturePtr; }
- WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
- TexImageTarget ImageTarget() const {
- return mTexImageTarget;
- }
- GLint Layer() const {
- return mTexImageLayer;
- }
- uint32_t MipLevel() const {
- return mTexImageLevel;
- }
- void AttachmentName(nsCString* out) const;
- bool HasUninitializedImageData() const;
- void SetImageDataStatus(WebGLImageDataStatus x) const;
- void Size(uint32_t* const out_width, uint32_t* const out_height) const;
- bool HasImage() const;
- bool IsComplete(WebGLContext* webgl, nsCString* const out_info) const;
- void Resolve(gl::GLContext* gl) const;
- JS::Value GetParameter(const char* funcName, WebGLContext* webgl, JSContext* cx,
- GLenum target, GLenum attachment, GLenum pname,
- ErrorResult* const out_error) const;
- void OnBackingStoreRespecified() const;
- bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
- if (!IsDefined() || !other.IsDefined())
- return false;
- #define _(X) X == other.X
- return ( _(mRenderbufferPtr) &&
- _(mTexturePtr) &&
- _(mTexImageTarget.get()) &&
- _(mTexImageLevel) &&
- _(mTexImageLayer) );
- #undef _
- }
- ////
- struct Ordered {
- const WebGLFBAttachPoint& mRef;
- explicit Ordered(const WebGLFBAttachPoint& ref)
- : mRef(ref)
- { }
- bool operator<(const Ordered& other) const {
- MOZ_ASSERT(mRef.IsDefined() && other.mRef.IsDefined());
- #define ORDER_BY(X) if (X != other.X) return X < other.X;
- ORDER_BY(mRef.mRenderbufferPtr)
- ORDER_BY(mRef.mTexturePtr)
- ORDER_BY(mRef.mTexImageTarget.get())
- ORDER_BY(mRef.mTexImageLevel)
- ORDER_BY(mRef.mTexImageLayer)
- #undef ORDER_BY
- return false;
- }
- };
- };
- class WebGLFramebuffer final
- : public nsWrapperCache
- , public WebGLRefCountedObject<WebGLFramebuffer>
- , public LinkedListElement<WebGLFramebuffer>
- , public SupportsWeakPtr<WebGLFramebuffer>
- {
- friend class WebGLContext;
- public:
- MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
- const GLuint mGLName;
- protected:
- WebGLFBAttachPoint mDepthAttachment;
- WebGLFBAttachPoint mStencilAttachment;
- WebGLFBAttachPoint mDepthStencilAttachment;
- // In theory, this number can be unbounded based on the driver. However, no driver
- // appears to expose more than 8. We might as well stop there too, for now.
- // (http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COLOR_ATTACHMENTS)
- static const size_t kMaxColorAttachments = 8; // jgilbert's MacBook Pro exposes 8.
- WebGLFBAttachPoint mColorAttachments[kMaxColorAttachments];
- ////
- std::vector<const WebGLFBAttachPoint*> mColorDrawBuffers; // Non-null
- const WebGLFBAttachPoint* mColorReadBuffer; // Null if NONE
- ////
- struct ResolvedData {
- // IsFeedback
- std::vector<const WebGLFBAttachPoint*> texDrawBuffers; // Non-null
- std::set<WebGLFBAttachPoint::Ordered> drawSet;
- std::set<WebGLFBAttachPoint::Ordered> readSet;
- explicit ResolvedData(const WebGLFramebuffer& parent);
- };
- UniquePtr<const ResolvedData> mResolvedCompleteData;
- ////
- public:
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
- WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
- WebGLContext* GetParentObject() const { return mContext; }
- virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
- private:
- ~WebGLFramebuffer() {
- DeleteOnce();
- }
- public:
- void Delete();
- ////
- bool HasDefinedAttachments() const;
- bool HasIncompleteAttachments(nsCString* const out_info) const;
- bool AllImageRectsMatch() const;
- bool AllImageSamplesMatch() const;
- FBStatus PrecheckFramebufferStatus(nsCString* const out_info) const;
- protected:
- Maybe<WebGLFBAttachPoint*> GetAttachPoint(GLenum attachment); // Fallible
- Maybe<WebGLFBAttachPoint*> GetColorAttachPoint(GLenum attachment); // Fallible
- void ResolveAttachments() const;
- void RefreshDrawBuffers() const;
- void RefreshReadBuffer() const;
- bool ResolveAttachmentData(const char* funcName) const;
- public:
- void DetachTexture(const WebGLTexture* tex);
- void DetachRenderbuffer(const WebGLRenderbuffer* rb);
- bool ValidateAndInitAttachments(const char* funcName);
- bool ValidateClearBufferType(const char* funcName, GLenum buffer, uint32_t drawBuffer,
- GLenum funcType) const;
- bool ValidateForRead(const char* info,
- const webgl::FormatUsageInfo** const out_format,
- uint32_t* const out_width, uint32_t* const out_height);
- ////////////////
- // Getters
- #define GETTER(X) const decltype(m##X)& X() const { return m##X; }
- GETTER(DepthAttachment)
- GETTER(StencilAttachment)
- GETTER(DepthStencilAttachment)
- GETTER(ColorDrawBuffers)
- GETTER(ColorReadBuffer)
- GETTER(ResolvedCompleteData)
- #undef GETTER
- ////////////////
- // Invalidation
- bool IsResolvedComplete() const { return bool(mResolvedCompleteData); }
- void InvalidateFramebufferStatus() {
- mResolvedCompleteData = nullptr;
- }
- void RefreshResolvedData();
- ////////////////
- // WebGL funcs
- FBStatus CheckFramebufferStatus(const char* funcName);
- void FramebufferRenderbuffer(const char* funcName, GLenum attachment, GLenum rbtarget,
- WebGLRenderbuffer* rb);
- void FramebufferTexture2D(const char* funcName, GLenum attachment,
- GLenum texImageTarget, WebGLTexture* tex, GLint level);
- void FramebufferTextureLayer(const char* funcName, GLenum attachment,
- WebGLTexture* tex, GLint level, GLint layer);
- void DrawBuffers(const char* funcName, const dom::Sequence<GLenum>& buffers);
- void ReadBuffer(const char* funcName, GLenum attachPoint);
- JS::Value GetAttachmentParameter(const char* funcName, JSContext* cx, GLenum target,
- GLenum attachment, GLenum pname,
- ErrorResult* const out_error);
- static void BlitFramebuffer(WebGLContext* webgl,
- const WebGLFramebuffer* src, GLint srcX0, GLint srcY0,
- GLint srcX1, GLint srcY1,
- const WebGLFramebuffer* dst, GLint dstX0, GLint dstY0,
- GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
- };
- } // namespace mozilla
- #endif // WEBGL_FRAMEBUFFER_H_
|