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