1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "WebGL2Context.h"
8
9 #include "GLContext.h"
10 #include "GLScreenBuffer.h"
11 #include "WebGLBuffer.h"
12 #include "WebGLContextUtils.h"
13 #include "WebGLFramebuffer.h"
14 #include "WebGLSampler.h"
15 #include "WebGLTransformFeedback.h"
16 #include "WebGLVertexArray.h"
17
18 namespace mozilla {
19
20 JS::Value
GetParameter(JSContext * cx,GLenum pname,ErrorResult & rv)21 WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
22 {
23 // The following cases are handled in WebGLContext::GetParameter():
24 // case LOCAL_GL_MAX_COLOR_ATTACHMENTS:
25 // case LOCAL_GL_MAX_DRAW_BUFFERS:
26 // case LOCAL_GL_DRAW_BUFFERi:
27
28 if (IsContextLost())
29 return JS::NullValue();
30
31 MakeContextCurrent();
32
33 switch (pname) {
34 /* GLboolean */
35 case LOCAL_GL_RASTERIZER_DISCARD:
36 case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
37 case LOCAL_GL_SAMPLE_COVERAGE: {
38 realGLboolean b = 0;
39 gl->fGetBooleanv(pname, &b);
40 return JS::BooleanValue(bool(b));
41 }
42
43 case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE:
44 return JS::BooleanValue(mBoundTransformFeedback->mIsActive);
45 case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED:
46 return JS::BooleanValue(mBoundTransformFeedback->mIsPaused);
47
48 /* GLenum */
49 case LOCAL_GL_READ_BUFFER: {
50 if (!mBoundReadFramebuffer)
51 return JS::Int32Value(gl->Screen()->GetReadBufferMode());
52
53 if (!mBoundReadFramebuffer->ColorReadBuffer())
54 return JS::Int32Value(LOCAL_GL_NONE);
55
56 return JS::Int32Value(mBoundReadFramebuffer->ColorReadBuffer()->mAttachmentPoint);
57 }
58
59 case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
60 /* fall through */
61
62 /* GLint */
63 case LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS:
64 case LOCAL_GL_MAX_ELEMENTS_INDICES:
65 case LOCAL_GL_MAX_ELEMENTS_VERTICES:
66 case LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS:
67 case LOCAL_GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
68 case LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
69 case LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET:
70 case LOCAL_GL_MAX_SAMPLES:
71 case LOCAL_GL_MAX_TEXTURE_LOD_BIAS:
72 case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
73 case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
74 case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
75 case LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS:
76 case LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS:
77 case LOCAL_GL_MAX_VERTEX_UNIFORM_BLOCKS:
78 case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS:
79 case LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET:
80 case LOCAL_GL_PACK_ROW_LENGTH:
81 case LOCAL_GL_PACK_SKIP_PIXELS:
82 case LOCAL_GL_PACK_SKIP_ROWS:
83 case LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
84 case LOCAL_GL_UNPACK_IMAGE_HEIGHT:
85 case LOCAL_GL_UNPACK_ROW_LENGTH: {
86 GLint val;
87 gl->fGetIntegerv(pname, &val);
88 return JS::Int32Value(val);
89 }
90
91 case LOCAL_GL_UNPACK_SKIP_IMAGES:
92 return JS::Int32Value(mPixelStore_UnpackSkipImages);
93
94 case LOCAL_GL_UNPACK_SKIP_PIXELS:
95 return JS::Int32Value(mPixelStore_UnpackSkipPixels);
96
97 case LOCAL_GL_UNPACK_SKIP_ROWS:
98 return JS::Int32Value(mPixelStore_UnpackSkipRows);
99
100 case LOCAL_GL_MAX_3D_TEXTURE_SIZE:
101 return JS::Int32Value(mImplMax3DTextureSize);
102
103 case LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS:
104 return JS::Int32Value(mImplMaxArrayTextureLayers);
105
106 case LOCAL_GL_MAX_VARYING_COMPONENTS: {
107 // On OS X Core Profile this is buggy. The spec says that the
108 // value is 4 * GL_MAX_VARYING_VECTORS
109 GLint val;
110 gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &val);
111 return JS::Int32Value(4*val);
112 }
113
114 /* GLint64 */
115 case LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
116 return JS::NumberValue(kMaxClientWaitSyncTimeoutNS);
117
118 case LOCAL_GL_MAX_ELEMENT_INDEX:
119 // GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3
120 // compatibility
121 if (!gl->IsSupported(gl::GLFeature::ES3_compatibility))
122 return JS::NumberValue(UINT32_MAX);
123
124 /*** fall through to fGetInteger64v ***/
125 MOZ_FALLTHROUGH;
126
127 case LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
128 case LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
129 case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: {
130 GLint64 val;
131 gl->fGetInteger64v(pname, &val);
132 return JS::DoubleValue(static_cast<double>(val));
133 }
134
135
136 /* GLuint64 */
137 case LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT: {
138 GLuint64 val;
139 gl->fGetInteger64v(pname, (GLint64*) &val);
140 return JS::DoubleValue(static_cast<double>(val));
141 }
142
143 case LOCAL_GL_COPY_READ_BUFFER_BINDING:
144 return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
145
146 case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
147 return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
148
149 case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
150 return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
151
152 case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
153 return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
154
155 case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
156 {
157 const auto& tf = mBoundTransformFeedback;
158 return WebGLObjectAsJSValue(cx, tf->mGenericBufferBinding.get(), rv);
159 }
160
161 case LOCAL_GL_UNIFORM_BUFFER_BINDING:
162 return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
163
164 // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
165 case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
166 return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
167
168 case LOCAL_GL_SAMPLER_BINDING:
169 return WebGLObjectAsJSValue(cx, mBoundSamplers[mActiveTexture].get(), rv);
170
171 case LOCAL_GL_TEXTURE_BINDING_2D_ARRAY:
172 return WebGLObjectAsJSValue(cx, mBound2DArrayTextures[mActiveTexture].get(), rv);
173
174 case LOCAL_GL_TEXTURE_BINDING_3D:
175 return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);
176
177 case LOCAL_GL_TRANSFORM_FEEDBACK_BINDING:
178 {
179 const WebGLTransformFeedback* tf = mBoundTransformFeedback;
180 if (tf == mDefaultTransformFeedback) {
181 tf = nullptr;
182 }
183 return WebGLObjectAsJSValue(cx, tf, rv);
184 }
185
186 case LOCAL_GL_VERTEX_ARRAY_BINDING: {
187 WebGLVertexArray* vao =
188 (mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr;
189 return WebGLObjectAsJSValue(cx, vao, rv);
190 }
191
192 case LOCAL_GL_VERSION:
193 return StringValue(cx, "WebGL 2.0", rv);
194
195 case LOCAL_GL_SHADING_LANGUAGE_VERSION:
196 return StringValue(cx, "WebGL GLSL ES 3.00", rv);
197
198 default:
199 return WebGLContext::GetParameter(cx, pname, rv);
200 }
201 }
202
203 } // namespace mozilla
204