Bumping manifests a=b2g-bump
[gecko.git] / dom / canvas / WebGL2ContextTransformFeedback.cpp
blob76a960786fcdc4759d17957250085f920f95ba35
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/. */
6 #include "WebGL2Context.h"
7 #include "WebGLActiveInfo.h"
8 #include "WebGLProgram.h"
9 #include "WebGLTransformFeedback.h"
10 #include "GLContext.h"
12 using namespace mozilla;
13 using namespace mozilla::dom;
15 // -------------------------------------------------------------------------
16 // Transform Feedback
18 already_AddRefed<WebGLTransformFeedback>
19 WebGL2Context::CreateTransformFeedback()
21 if (IsContextLost())
22 return nullptr;
24 GLuint tf = 0;
25 MakeContextCurrent();
26 gl->fGenTransformFeedbacks(1, &tf);
28 nsRefPtr<WebGLTransformFeedback> globj = new WebGLTransformFeedback(this, tf);
29 return globj.forget();
32 void
33 WebGL2Context::DeleteTransformFeedback(WebGLTransformFeedback* tf)
35 if (IsContextLost())
36 return;
38 if (!ValidateObjectAllowDeletedOrNull("deleteTransformFeedback", tf))
39 return;
41 if (!tf || tf->IsDeleted())
42 return;
44 if (mBoundTransformFeedback == tf)
45 BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, tf);
47 tf->RequestDelete();
50 bool
51 WebGL2Context::IsTransformFeedback(WebGLTransformFeedback* tf)
53 if (IsContextLost())
54 return false;
56 if (!ValidateObjectAllowDeleted("isTransformFeedback", tf))
57 return false;
59 if (tf->IsDeleted())
60 return false;
62 MakeContextCurrent();
63 return gl->fIsTransformFeedback(tf->GLName());
66 void
67 WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
69 if (IsContextLost())
70 return;
72 if (!ValidateObjectAllowDeletedOrNull("bindTransformFeedback", tf))
73 return;
75 if (target != LOCAL_GL_TRANSFORM_FEEDBACK)
76 return ErrorInvalidEnum("bindTransformFeedback: target must be TRANSFORM_FEEDBACK");
78 WebGLRefPtr<WebGLTransformFeedback> currentTF = mBoundTransformFeedback;
79 if (currentTF && currentTF->mIsActive && !currentTF->mIsPaused) {
80 return ErrorInvalidOperation("bindTransformFeedback: Currently bound transform "
81 "feedback is active and not paused");
84 if (tf && tf->IsDeleted())
85 return ErrorInvalidOperation("bindTransformFeedback: Attempt to bind deleted id");
87 if (tf)
88 tf->BindTo(LOCAL_GL_TRANSFORM_FEEDBACK);
90 MakeContextCurrent();
91 gl->fBindTransformFeedback(target, tf ? tf->GLName() : 0);
92 if (tf)
93 mBoundTransformFeedback = tf;
94 else
95 mBoundTransformFeedback = mDefaultTransformFeedback;
98 void
99 WebGL2Context::BeginTransformFeedback(GLenum primitiveMode)
101 if (IsContextLost())
102 return;
104 WebGLTransformFeedback* tf = mBoundTransformFeedback;
105 MOZ_ASSERT(tf);
106 if (!tf)
107 return;
109 if (tf->mIsActive)
110 return ErrorInvalidOperation("beginTransformFeedback: transform feedback is active");
112 const GLenum mode = tf->mMode;
113 if (mode != LOCAL_GL_POINTS && mode != LOCAL_GL_LINES && mode != LOCAL_GL_TRIANGLES)
114 return ErrorInvalidEnum("beginTransformFeedback: primitive must be one of POINTS, LINES, or TRIANGLES");
116 // TODO:
117 // GL_INVALID_OPERATION is generated by glBeginTransformFeedback
118 // if any binding point used in transform feedback mode does not
119 // have a buffer object bound. In interleaved mode, only the first
120 // buffer object binding point is ever written to.
122 // GL_INVALID_OPERATION is generated by glBeginTransformFeedback
123 // if no binding points would be used, either because no program
124 // object is active of because the active program object has
125 // specified no varying variables to record.
126 if (!mCurrentProgram)
127 return ErrorInvalidOperation("beginTransformFeedback: no program is active");
129 MakeContextCurrent();
130 gl->fBeginTransformFeedback(primitiveMode);
131 tf->mIsActive = true;
132 tf->mIsPaused = false;
135 void
136 WebGL2Context::EndTransformFeedback()
138 if (IsContextLost())
139 return;
141 WebGLTransformFeedback* tf = mBoundTransformFeedback;
142 MOZ_ASSERT(tf);
144 if (!tf)
145 return;
147 if (!tf->mIsActive)
148 return ErrorInvalidOperation("%s: transform feedback in not active",
149 "endTransformFeedback");
151 MakeContextCurrent();
152 gl->fEndTransformFeedback();
153 tf->mIsActive = false;
154 tf->mIsPaused = false;
157 void
158 WebGL2Context::PauseTransformFeedback()
160 if (IsContextLost())
161 return;
163 WebGLTransformFeedback* tf = mBoundTransformFeedback;
164 MOZ_ASSERT(tf);
165 if (!tf)
166 return;
168 if (!tf->mIsActive || tf->mIsPaused) {
169 return ErrorInvalidOperation("%s: transform feedback is not active or is paused",
170 "pauseTransformFeedback");
173 MakeContextCurrent();
174 gl->fPauseTransformFeedback();
175 tf->mIsPaused = true;
178 void
179 WebGL2Context::ResumeTransformFeedback()
181 if (IsContextLost())
182 return;
184 WebGLTransformFeedback* tf = mBoundTransformFeedback;
185 MOZ_ASSERT(tf);
186 if (!tf)
187 return;
189 if (!tf->mIsActive || !tf->mIsPaused)
190 return ErrorInvalidOperation("resumeTransformFeedback: transform feedback is not active or is not paused");
192 MakeContextCurrent();
193 gl->fResumeTransformFeedback();
194 tf->mIsPaused = false;
197 void
198 WebGL2Context::TransformFeedbackVaryings(WebGLProgram* program,
199 const dom::Sequence<nsString>& varyings,
200 GLenum bufferMode)
202 if (IsContextLost())
203 return;
205 if (!ValidateObject("transformFeedbackVaryings: program", program))
206 return;
208 GLsizei count = varyings.Length();
209 GLchar** tmpVaryings = (GLchar**) nsMemory::Alloc(count * sizeof(GLchar*));
211 for (GLsizei n = 0; n < count; n++) {
212 tmpVaryings[n] = (GLchar*) ToNewCString(varyings[n]);
215 GLuint progname = program->GLName();
216 MakeContextCurrent();
217 gl->fTransformFeedbackVaryings(progname, count, tmpVaryings, bufferMode);
219 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, tmpVaryings);
223 already_AddRefed<WebGLActiveInfo>
224 WebGL2Context::GetTransformFeedbackVarying(WebGLProgram* program, GLuint index)
226 if (IsContextLost())
227 return nullptr;
229 if (!ValidateObject("getTransformFeedbackVarying: program", program))
230 return nullptr;
232 MakeContextCurrent();
234 GLint len = 0;
235 GLuint progname = program->GLName();
236 gl->fGetProgramiv(progname, LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &len);
237 if (!len)
238 return nullptr;
240 UniquePtr<char[]> name(new char[len]);
241 GLint tfsize = 0;
242 GLuint tftype = 0;
244 gl->fGetTransformFeedbackVarying(progname, index, len, &len, &tfsize, &tftype, name.get());
245 if (len == 0 || tfsize == 0 || tftype == 0)
246 return nullptr;
248 // TODO(djg): Reverse lookup of name
249 // nsCString reverseMappedName;
250 // prog->ReverveMapIdentifier(nsDependentCString(name), &reverseMappedName);
252 nsRefPtr<WebGLActiveInfo> result = new WebGLActiveInfo(tfsize, tftype, nsDependentCString(name.get()));
253 return result.forget();