diff options
Diffstat (limited to 'dom/canvas/WebGLProgram.h')
-rw-r--r-- | dom/canvas/WebGLProgram.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/dom/canvas/WebGLProgram.h b/dom/canvas/WebGLProgram.h new file mode 100644 index 000000000..0f08d3df3 --- /dev/null +++ b/dom/canvas/WebGLProgram.h @@ -0,0 +1,217 @@ +/* -*- 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_PROGRAM_H_ +#define WEBGL_PROGRAM_H_ + +#include <map> +#include <set> +#include <string> +#include <vector> + +#include "mozilla/LinkedList.h" +#include "mozilla/RefPtr.h" +#include "mozilla/WeakPtr.h" +#include "nsString.h" +#include "nsWrapperCache.h" + +#include "WebGLContext.h" +#include "WebGLObjectModel.h" + +namespace mozilla { +class ErrorResult; +class WebGLActiveInfo; +class WebGLProgram; +class WebGLShader; +class WebGLUniformLocation; + +namespace dom { +template<typename> struct Nullable; +class OwningUnsignedLongOrUint32ArrayOrBoolean; +template<typename> class Sequence; +} // namespace dom + +namespace webgl { + +struct AttribInfo final +{ + const RefPtr<WebGLActiveInfo> mActiveInfo; + const GLint mLoc; // -1 for active built-ins + const GLenum mBaseType; +}; + +struct UniformInfo final +{ + typedef decltype(WebGLContext::mBound2DTextures) TexListT; + + const RefPtr<WebGLActiveInfo> mActiveInfo; + const TexListT* const mSamplerTexList; + std::vector<uint32_t> mSamplerValues; + +protected: + static const TexListT* + GetTexList(WebGLActiveInfo* activeInfo); + +public: + explicit UniformInfo(WebGLActiveInfo* activeInfo); +}; + +struct UniformBlockInfo final +{ + const nsCString mUserName; + const nsCString mMappedName; + const uint32_t mDataSize; + + const IndexedBufferBinding* mBinding; + + UniformBlockInfo(WebGLContext* webgl, const nsACString& userName, + const nsACString& mappedName, uint32_t dataSize) + : mUserName(userName) + , mMappedName(mappedName) + , mDataSize(dataSize) + , mBinding(&webgl->mIndexedUniformBufferBindings[0]) + { } +}; + +struct LinkedProgramInfo final + : public RefCounted<LinkedProgramInfo> + , public SupportsWeakPtr<LinkedProgramInfo> +{ + friend class WebGLProgram; + + MOZ_DECLARE_REFCOUNTED_TYPENAME(LinkedProgramInfo) + MOZ_DECLARE_WEAKREFERENCE_TYPENAME(LinkedProgramInfo) + + ////// + + WebGLProgram* const prog; + const GLenum transformFeedbackBufferMode; + + std::vector<AttribInfo> attribs; + std::vector<UniformInfo*> uniforms; // Owns its contents. + std::vector<UniformBlockInfo*> uniformBlocks; // Owns its contents. + std::vector<RefPtr<WebGLActiveInfo>> transformFeedbackVaryings; + + // Needed for draw call validation. + std::vector<UniformInfo*> uniformSamplers; + + mutable std::vector<size_t> componentsPerTFVert; + + ////// + + // The maps for the frag data names to the translated names. + std::map<nsCString, const nsCString> fragDataMap; + + explicit LinkedProgramInfo(WebGLProgram* prog); + ~LinkedProgramInfo(); + + bool FindAttrib(const nsCString& userName, const AttribInfo** const out_info) const; + bool FindUniform(const nsCString& userName, nsCString* const out_mappedName, + size_t* const out_arrayIndex, UniformInfo** const out_info) const; + bool MapFragDataName(const nsCString& userName, + nsCString* const out_mappedName) const; +}; + +} // namespace webgl + +class WebGLProgram final + : public nsWrapperCache + , public WebGLRefCountedObject<WebGLProgram> + , public LinkedListElement<WebGLProgram> +{ + friend class WebGLTransformFeedback; + friend struct webgl::LinkedProgramInfo; + +public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram) + + explicit WebGLProgram(WebGLContext* webgl); + + void Delete(); + + // GL funcs + void AttachShader(WebGLShader* shader); + void BindAttribLocation(GLuint index, const nsAString& name); + void DetachShader(const WebGLShader* shader); + already_AddRefed<WebGLActiveInfo> GetActiveAttrib(GLuint index) const; + already_AddRefed<WebGLActiveInfo> GetActiveUniform(GLuint index) const; + void GetAttachedShaders(nsTArray<RefPtr<WebGLShader>>* const out) const; + GLint GetAttribLocation(const nsAString& name) const; + GLint GetFragDataLocation(const nsAString& name) const; + void GetProgramInfoLog(nsAString* const out) const; + JS::Value GetProgramParameter(GLenum pname) const; + GLuint GetUniformBlockIndex(const nsAString& name) const; + void GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& name) const; + JS::Value GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname) const; + JS::Value GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex, + ErrorResult* const out_error) const; + already_AddRefed<WebGLUniformLocation> GetUniformLocation(const nsAString& name) const; + void GetUniformIndices(const dom::Sequence<nsString>& uniformNames, + dom::Nullable< nsTArray<GLuint> >& retval) const; + void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const; + + void LinkProgram(); + bool UseProgram() const; + void ValidateProgram() const; + + //////////////// + + bool FindAttribUserNameByMappedName(const nsACString& mappedName, + nsCString* const out_userName) const; + bool FindVaryingByMappedName(const nsACString& mappedName, + nsCString* const out_userName, + bool* const out_isArray) const; + bool FindUniformByMappedName(const nsACString& mappedName, + nsCString* const out_userName, + bool* const out_isArray) const; + bool UnmapUniformBlockName(const nsCString& mappedName, + nsCString* const out_userName) const; + + void TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings, + GLenum bufferMode); + already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(GLuint index) const; + + void EnumerateFragOutputs(std::map<nsCString, const nsCString> &out_FragOutputs) const; + + bool IsLinked() const { return mMostRecentLinkInfo; } + + const webgl::LinkedProgramInfo* LinkInfo() const { + return mMostRecentLinkInfo.get(); + } + + WebGLContext* GetParentObject() const { + return mContext; + } + + virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto) override; + +private: + ~WebGLProgram(); + + void LinkAndUpdate(); + bool ValidateForLink(); + bool ValidateAfterTentativeLink(nsCString* const out_linkLog) const; + +public: + const GLuint mGLName; + +private: + WebGLRefPtr<WebGLShader> mVertShader; + WebGLRefPtr<WebGLShader> mFragShader; + size_t mNumActiveTFOs; + + std::map<nsCString, GLuint> mNextLink_BoundAttribLocs; + + std::vector<nsString> mNextLink_TransformFeedbackVaryings; + GLenum mNextLink_TransformFeedbackBufferMode; + + nsCString mLinkLog; + RefPtr<const webgl::LinkedProgramInfo> mMostRecentLinkInfo; +}; + +} // namespace mozilla + +#endif // WEBGL_PROGRAM_H_ |