summaryrefslogtreecommitdiffstats
path: root/dom/canvas/WebGL2ContextState.cpp
blob: e6283b12dd9e9234e6e70831bca04da3b305e1ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */

#include "WebGL2Context.h"

#include "GLContext.h"
#include "GLScreenBuffer.h"
#include "WebGLBuffer.h"
#include "WebGLContextUtils.h"
#include "WebGLFramebuffer.h"
#include "WebGLSampler.h"
#include "WebGLTransformFeedback.h"
#include "WebGLVertexArray.h"

namespace mozilla {

JS::Value
WebGL2Context::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
{
  // The following cases are handled in WebGLContext::GetParameter():
  //     case LOCAL_GL_MAX_COLOR_ATTACHMENTS:
  //     case LOCAL_GL_MAX_DRAW_BUFFERS:
  //     case LOCAL_GL_DRAW_BUFFERi:

  if (IsContextLost())
    return JS::NullValue();

  MakeContextCurrent();

  switch (pname) {
    /* GLboolean */
    case LOCAL_GL_RASTERIZER_DISCARD:
    case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
    case LOCAL_GL_SAMPLE_COVERAGE: {
      realGLboolean b = 0;
      gl->fGetBooleanv(pname, &b);
      return JS::BooleanValue(bool(b));
    }

    case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE:
      return JS::BooleanValue(mBoundTransformFeedback->mIsActive);
    case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED:
      return JS::BooleanValue(mBoundTransformFeedback->mIsPaused);

    /* GLenum */
    case LOCAL_GL_READ_BUFFER: {
      if (!mBoundReadFramebuffer)
        return JS::Int32Value(gl->Screen()->GetReadBufferMode());

      if (!mBoundReadFramebuffer->ColorReadBuffer())
        return JS::Int32Value(LOCAL_GL_NONE);

      return JS::Int32Value(mBoundReadFramebuffer->ColorReadBuffer()->mAttachmentPoint);
    }

    case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
      /* fall through */

    /* GLint */
    case LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS:
    case LOCAL_GL_MAX_ELEMENTS_INDICES:
    case LOCAL_GL_MAX_ELEMENTS_VERTICES:
    case LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS:
    case LOCAL_GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
    case LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
    case LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET:
    case LOCAL_GL_MAX_SAMPLES:
    case LOCAL_GL_MAX_TEXTURE_LOD_BIAS:
    case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
    case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
    case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
    case LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS:
    case LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS:
    case LOCAL_GL_MAX_VERTEX_UNIFORM_BLOCKS:
    case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS:
    case LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET:
    case LOCAL_GL_PACK_ROW_LENGTH:
    case LOCAL_GL_PACK_SKIP_PIXELS:
    case LOCAL_GL_PACK_SKIP_ROWS:
    case LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
    case LOCAL_GL_UNPACK_IMAGE_HEIGHT:
    case LOCAL_GL_UNPACK_ROW_LENGTH: {
      GLint val;
      gl->fGetIntegerv(pname, &val);
      return JS::Int32Value(val);
    }

    case LOCAL_GL_UNPACK_SKIP_IMAGES:
      return JS::Int32Value(mPixelStore_UnpackSkipImages);

    case LOCAL_GL_UNPACK_SKIP_PIXELS:
      return JS::Int32Value(mPixelStore_UnpackSkipPixels);

    case LOCAL_GL_UNPACK_SKIP_ROWS:
      return JS::Int32Value(mPixelStore_UnpackSkipRows);

    case LOCAL_GL_MAX_3D_TEXTURE_SIZE:
      return JS::Int32Value(mImplMax3DTextureSize);

    case LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS:
      return JS::Int32Value(mImplMaxArrayTextureLayers);

    case LOCAL_GL_MAX_VARYING_COMPONENTS: {
      // On OS X Core Profile this is buggy.  The spec says that the
      // value is 4 * GL_MAX_VARYING_VECTORS
      GLint val;
      gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &val);
      return JS::Int32Value(4*val);
    }

    /* GLint64 */
    case LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
      return JS::NumberValue(kMaxClientWaitSyncTimeoutNS);

    case LOCAL_GL_MAX_ELEMENT_INDEX:
      // GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3
      // compatibility
      if (!gl->IsSupported(gl::GLFeature::ES3_compatibility))
        return JS::NumberValue(UINT32_MAX);

      /*** fall through to fGetInteger64v ***/
      MOZ_FALLTHROUGH;

    case LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
    case LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
    case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: {
      GLint64 val;
      gl->fGetInteger64v(pname, &val);
      return JS::DoubleValue(static_cast<double>(val));
    }


    /* GLuint64 */
    case LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT: {
      GLuint64 val;
      gl->fGetInteger64v(pname, (GLint64*) &val);
      return JS::DoubleValue(static_cast<double>(val));
    }

    case LOCAL_GL_COPY_READ_BUFFER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);

    case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);

    case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);

    case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);

    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
      {
        const auto& tf = mBoundTransformFeedback;
        return WebGLObjectAsJSValue(cx, tf->mGenericBufferBinding.get(), rv);
      }

    case LOCAL_GL_UNIFORM_BUFFER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);

    // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
    case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);

    case LOCAL_GL_SAMPLER_BINDING:
      return WebGLObjectAsJSValue(cx, mBoundSamplers[mActiveTexture].get(), rv);

    case LOCAL_GL_TEXTURE_BINDING_2D_ARRAY:
      return WebGLObjectAsJSValue(cx, mBound2DArrayTextures[mActiveTexture].get(), rv);

    case LOCAL_GL_TEXTURE_BINDING_3D:
      return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(), rv);

    case LOCAL_GL_TRANSFORM_FEEDBACK_BINDING:
      {
        const WebGLTransformFeedback* tf = mBoundTransformFeedback;
        if (tf == mDefaultTransformFeedback) {
          tf = nullptr;
        }
        return WebGLObjectAsJSValue(cx, tf, rv);
      }

    case LOCAL_GL_VERTEX_ARRAY_BINDING: {
      WebGLVertexArray* vao =
        (mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr;
      return WebGLObjectAsJSValue(cx, vao, rv);
    }

    case LOCAL_GL_VERSION:
      return StringValue(cx, "WebGL 2.0", rv);

    case LOCAL_GL_SHADING_LANGUAGE_VERSION:
      return StringValue(cx, "WebGL GLSL ES 3.00", rv);

    default:
      return WebGLContext::GetParameter(cx, pname, rv);
  }
}

} // namespace mozilla