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 : #include "WebGLContext.h"
7 : #include "WebGLTexture.h"
8 : #include "WebGLRenderbuffer.h"
9 : #include "WebGLFramebuffer.h"
10 : #include "GLContext.h"
11 : #include "GLScreenBuffer.h"
12 :
13 : namespace mozilla {
14 :
15 : void
16 0 : WebGLContext::Clear(GLbitfield mask)
17 : {
18 0 : const char funcName[] = "clear";
19 :
20 0 : if (IsContextLost())
21 0 : return;
22 :
23 0 : MakeContextCurrent();
24 :
25 0 : uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
26 0 : if (mask != m)
27 0 : return ErrorInvalidValue("%s: invalid mask bits", funcName);
28 :
29 0 : if (mask == 0) {
30 0 : GenerateWarning("Calling gl.clear(0) has no effect.");
31 0 : } else if (mRasterizerDiscardEnabled) {
32 0 : GenerateWarning("Calling gl.clear() with RASTERIZER_DISCARD enabled has no effects.");
33 : }
34 :
35 0 : if (mBoundDrawFramebuffer) {
36 0 : if (!mBoundDrawFramebuffer->ValidateAndInitAttachments(funcName))
37 0 : return;
38 :
39 0 : if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
40 0 : for (const auto& cur : mBoundDrawFramebuffer->ColorDrawBuffers()) {
41 0 : if (!cur->IsDefined())
42 0 : continue;
43 :
44 0 : switch (cur->Format()->format->componentType) {
45 : case webgl::ComponentType::Float:
46 : case webgl::ComponentType::NormInt:
47 : case webgl::ComponentType::NormUInt:
48 0 : break;
49 :
50 : default:
51 : ErrorInvalidOperation("%s: Color draw buffers must be floating-point"
52 : " or fixed-point. (normalized (u)ints)",
53 0 : funcName);
54 0 : return;
55 : }
56 : }
57 : }
58 : }
59 :
60 0 : ScopedDrawCallWrapper wrapper(*this);
61 0 : gl->fClear(mask);
62 : }
63 :
64 : static GLfloat
65 0 : GLClampFloat(GLfloat val)
66 : {
67 0 : if (val < 0.0)
68 0 : return 0.0;
69 :
70 0 : if (val > 1.0)
71 0 : return 1.0;
72 :
73 0 : return val;
74 : }
75 :
76 : void
77 0 : WebGLContext::ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
78 : {
79 0 : if (IsContextLost())
80 0 : return;
81 :
82 0 : MakeContextCurrent();
83 :
84 0 : const bool supportsFloatColorBuffers = (IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_float) ||
85 0 : IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float) ||
86 0 : IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float));
87 0 : if (!supportsFloatColorBuffers) {
88 0 : r = GLClampFloat(r);
89 0 : g = GLClampFloat(g);
90 0 : b = GLClampFloat(b);
91 0 : a = GLClampFloat(a);
92 : }
93 :
94 0 : gl->fClearColor(r, g, b, a);
95 :
96 0 : mColorClearValue[0] = r;
97 0 : mColorClearValue[1] = g;
98 0 : mColorClearValue[2] = b;
99 0 : mColorClearValue[3] = a;
100 : }
101 :
102 : void
103 0 : WebGLContext::ClearDepth(GLclampf v)
104 : {
105 0 : if (IsContextLost())
106 0 : return;
107 :
108 0 : MakeContextCurrent();
109 0 : mDepthClearValue = GLClampFloat(v);
110 0 : gl->fClearDepth(mDepthClearValue);
111 : }
112 :
113 : void
114 0 : WebGLContext::ClearStencil(GLint v)
115 : {
116 0 : if (IsContextLost())
117 0 : return;
118 :
119 0 : MakeContextCurrent();
120 0 : mStencilClearValue = v;
121 0 : gl->fClearStencil(v);
122 : }
123 :
124 : void
125 0 : WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
126 : {
127 0 : if (IsContextLost())
128 0 : return;
129 :
130 0 : MakeContextCurrent();
131 0 : mColorWriteMask[0] = r;
132 0 : mColorWriteMask[1] = g;
133 0 : mColorWriteMask[2] = b;
134 0 : mColorWriteMask[3] = a;
135 0 : gl->fColorMask(r, g, b, a);
136 : }
137 :
138 : void
139 0 : WebGLContext::DepthMask(WebGLboolean b)
140 : {
141 0 : if (IsContextLost())
142 0 : return;
143 :
144 0 : MakeContextCurrent();
145 0 : mDepthWriteMask = b;
146 0 : gl->fDepthMask(b);
147 : }
148 :
149 : void
150 0 : WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
151 : {
152 0 : const char funcName[] = "drawBuffers";
153 0 : if (IsContextLost())
154 0 : return;
155 :
156 0 : if (mBoundDrawFramebuffer) {
157 0 : mBoundDrawFramebuffer->DrawBuffers(funcName, buffers);
158 0 : return;
159 : }
160 :
161 : // GLES 3.0.4 p186:
162 : // "If the GL is bound to the default framebuffer, then `n` must be 1 and the
163 : // constant must be BACK or NONE. [...] If DrawBuffers is supplied with a
164 : // constant other than BACK and NONE, or with a value of `n` other than 1, the
165 : // error INVALID_OPERATION is generated."
166 0 : if (buffers.Length() != 1) {
167 : ErrorInvalidOperation("%s: For the default framebuffer, `buffers` must have a"
168 : " length of 1.",
169 0 : funcName);
170 0 : return;
171 : }
172 :
173 0 : switch (buffers[0]) {
174 : case LOCAL_GL_NONE:
175 : case LOCAL_GL_BACK:
176 0 : break;
177 :
178 : default:
179 : ErrorInvalidOperation("%s: For the default framebuffer, `buffers[0]` must be"
180 : " BACK or NONE.",
181 0 : funcName);
182 0 : return;
183 : }
184 :
185 0 : mDefaultFB_DrawBuffer0 = buffers[0];
186 0 : gl->Screen()->SetDrawBuffer(buffers[0]);
187 : }
188 :
189 : void
190 0 : WebGLContext::StencilMask(GLuint mask)
191 : {
192 0 : if (IsContextLost())
193 0 : return;
194 :
195 0 : mStencilWriteMaskFront = mask;
196 0 : mStencilWriteMaskBack = mask;
197 :
198 0 : MakeContextCurrent();
199 0 : gl->fStencilMask(mask);
200 : }
201 :
202 : void
203 0 : WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask)
204 : {
205 0 : if (IsContextLost())
206 0 : return;
207 :
208 0 : if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
209 0 : return;
210 :
211 0 : switch (face) {
212 : case LOCAL_GL_FRONT_AND_BACK:
213 0 : mStencilWriteMaskFront = mask;
214 0 : mStencilWriteMaskBack = mask;
215 0 : break;
216 : case LOCAL_GL_FRONT:
217 0 : mStencilWriteMaskFront = mask;
218 0 : break;
219 : case LOCAL_GL_BACK:
220 0 : mStencilWriteMaskBack = mask;
221 0 : break;
222 : }
223 :
224 0 : MakeContextCurrent();
225 0 : gl->fStencilMaskSeparate(face, mask);
226 : }
227 :
228 : } // namespace mozilla
|