Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef WEBGL_PROGRAM_H_
7 : #define WEBGL_PROGRAM_H_
8 :
9 : #include <map>
10 : #include <set>
11 : #include <string>
12 : #include <vector>
13 :
14 : #include "mozilla/LinkedList.h"
15 : #include "mozilla/RefPtr.h"
16 : #include "mozilla/WeakPtr.h"
17 : #include "nsString.h"
18 : #include "nsWrapperCache.h"
19 :
20 : #include "WebGLContext.h"
21 : #include "WebGLObjectModel.h"
22 :
23 : namespace mozilla {
24 : class ErrorResult;
25 : class WebGLActiveInfo;
26 : class WebGLProgram;
27 : class WebGLShader;
28 : class WebGLUniformLocation;
29 :
30 : namespace dom {
31 : template<typename> struct Nullable;
32 : class OwningUnsignedLongOrUint32ArrayOrBoolean;
33 : template<typename> class Sequence;
34 : } // namespace dom
35 :
36 : namespace webgl {
37 :
38 0 : struct AttribInfo final
39 : {
40 : const RefPtr<WebGLActiveInfo> mActiveInfo;
41 : const GLint mLoc; // -1 for active built-ins
42 : const GLenum mBaseType;
43 : };
44 :
45 0 : struct UniformInfo final
46 : {
47 : typedef decltype(WebGLContext::mBound2DTextures) TexListT;
48 :
49 : const RefPtr<WebGLActiveInfo> mActiveInfo;
50 : const TexListT* const mSamplerTexList;
51 : std::vector<uint32_t> mSamplerValues;
52 :
53 : protected:
54 : static const TexListT*
55 : GetTexList(WebGLActiveInfo* activeInfo);
56 :
57 : public:
58 : explicit UniformInfo(WebGLActiveInfo* activeInfo);
59 : };
60 :
61 0 : struct UniformBlockInfo final
62 : {
63 : const nsCString mUserName;
64 : const nsCString mMappedName;
65 : const uint32_t mDataSize;
66 :
67 : const IndexedBufferBinding* mBinding;
68 :
69 0 : UniformBlockInfo(WebGLContext* webgl, const nsACString& userName,
70 : const nsACString& mappedName, uint32_t dataSize)
71 0 : : mUserName(userName)
72 : , mMappedName(mappedName)
73 : , mDataSize(dataSize)
74 0 : , mBinding(&webgl->mIndexedUniformBufferBindings[0])
75 0 : { }
76 : };
77 :
78 : struct LinkedProgramInfo final
79 : : public RefCounted<LinkedProgramInfo>
80 : , public SupportsWeakPtr<LinkedProgramInfo>
81 : {
82 : friend class WebGLProgram;
83 :
84 0 : MOZ_DECLARE_REFCOUNTED_TYPENAME(LinkedProgramInfo)
85 0 : MOZ_DECLARE_WEAKREFERENCE_TYPENAME(LinkedProgramInfo)
86 :
87 : //////
88 :
89 : WebGLProgram* const prog;
90 : const GLenum transformFeedbackBufferMode;
91 :
92 : std::vector<AttribInfo> attribs;
93 : std::vector<UniformInfo*> uniforms; // Owns its contents.
94 : std::vector<UniformBlockInfo*> uniformBlocks; // Owns its contents.
95 : std::vector<RefPtr<WebGLActiveInfo>> transformFeedbackVaryings;
96 :
97 : // Needed for draw call validation.
98 : std::vector<UniformInfo*> uniformSamplers;
99 :
100 : mutable std::vector<size_t> componentsPerTFVert;
101 :
102 : //////
103 :
104 : // The maps for the frag data names to the translated names.
105 : std::map<nsCString, const nsCString> fragDataMap;
106 :
107 : explicit LinkedProgramInfo(WebGLProgram* prog);
108 : ~LinkedProgramInfo();
109 :
110 : bool FindAttrib(const nsCString& userName, const AttribInfo** const out_info) const;
111 : bool FindUniform(const nsCString& userName, nsCString* const out_mappedName,
112 : size_t* const out_arrayIndex, UniformInfo** const out_info) const;
113 : bool MapFragDataName(const nsCString& userName,
114 : nsCString* const out_mappedName) const;
115 : };
116 :
117 : } // namespace webgl
118 :
119 : class WebGLProgram final
120 : : public nsWrapperCache
121 : , public WebGLRefCountedObject<WebGLProgram>
122 : , public LinkedListElement<WebGLProgram>
123 : {
124 : friend class WebGLTransformFeedback;
125 : friend struct webgl::LinkedProgramInfo;
126 :
127 : public:
128 0 : NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)
129 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram)
130 :
131 : explicit WebGLProgram(WebGLContext* webgl);
132 :
133 : void Delete();
134 :
135 : // GL funcs
136 : void AttachShader(WebGLShader* shader);
137 : void BindAttribLocation(GLuint index, const nsAString& name);
138 : void DetachShader(const WebGLShader* shader);
139 : already_AddRefed<WebGLActiveInfo> GetActiveAttrib(GLuint index) const;
140 : already_AddRefed<WebGLActiveInfo> GetActiveUniform(GLuint index) const;
141 : void GetAttachedShaders(nsTArray<RefPtr<WebGLShader>>* const out) const;
142 : GLint GetAttribLocation(const nsAString& name) const;
143 : GLint GetFragDataLocation(const nsAString& name) const;
144 : void GetProgramInfoLog(nsAString* const out) const;
145 : JS::Value GetProgramParameter(GLenum pname) const;
146 : GLuint GetUniformBlockIndex(const nsAString& name) const;
147 : void GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& name) const;
148 : JS::Value GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname) const;
149 : JS::Value GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex,
150 : ErrorResult* const out_error) const;
151 : already_AddRefed<WebGLUniformLocation> GetUniformLocation(const nsAString& name) const;
152 : void GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
153 : dom::Nullable< nsTArray<GLuint> >& retval) const;
154 : void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const;
155 :
156 : void LinkProgram();
157 : bool UseProgram() const;
158 : void ValidateProgram() const;
159 :
160 : ////////////////
161 :
162 : bool FindAttribUserNameByMappedName(const nsACString& mappedName,
163 : nsCString* const out_userName) const;
164 : bool FindVaryingByMappedName(const nsACString& mappedName,
165 : nsCString* const out_userName,
166 : bool* const out_isArray) const;
167 : bool FindUniformByMappedName(const nsACString& mappedName,
168 : nsCString* const out_userName,
169 : bool* const out_isArray) const;
170 : bool UnmapUniformBlockName(const nsCString& mappedName,
171 : nsCString* const out_userName) const;
172 :
173 : void TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
174 : GLenum bufferMode);
175 : already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(GLuint index) const;
176 :
177 : void EnumerateFragOutputs(std::map<nsCString, const nsCString> &out_FragOutputs) const;
178 :
179 0 : bool IsLinked() const { return mMostRecentLinkInfo; }
180 :
181 0 : const webgl::LinkedProgramInfo* LinkInfo() const {
182 0 : return mMostRecentLinkInfo.get();
183 : }
184 :
185 0 : WebGLContext* GetParentObject() const {
186 0 : return mContext;
187 : }
188 :
189 : virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto) override;
190 :
191 : private:
192 : ~WebGLProgram();
193 :
194 : void LinkAndUpdate();
195 : bool ValidateForLink();
196 : bool ValidateAfterTentativeLink(nsCString* const out_linkLog) const;
197 :
198 : public:
199 : const GLuint mGLName;
200 :
201 : private:
202 : WebGLRefPtr<WebGLShader> mVertShader;
203 : WebGLRefPtr<WebGLShader> mFragShader;
204 : size_t mNumActiveTFOs;
205 :
206 : std::map<nsCString, GLuint> mNextLink_BoundAttribLocs;
207 :
208 : std::vector<nsString> mNextLink_TransformFeedbackVaryings;
209 : GLenum mNextLink_TransformFeedbackBufferMode;
210 :
211 : nsCString mLinkLog;
212 : RefPtr<const webgl::LinkedProgramInfo> mMostRecentLinkInfo;
213 : };
214 :
215 : } // namespace mozilla
216 :
217 : #endif // WEBGL_PROGRAM_H_
|