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 "WebGL2Context.h"
7 :
8 : #include "GLContext.h"
9 : #include "WebGLFramebuffer.h"
10 : #include "mozilla/SizePrintfMacros.h"
11 :
12 : namespace mozilla {
13 :
14 : bool
15 0 : WebGL2Context::ValidateClearBuffer(const char* funcName, GLenum buffer, GLint drawBuffer,
16 : size_t availElemCount, GLuint elemOffset,
17 : GLenum funcType)
18 : {
19 0 : if (elemOffset > availElemCount) {
20 0 : ErrorInvalidValue("%s: Offset too big for list.", funcName);
21 0 : return false;
22 : }
23 0 : availElemCount -= elemOffset;
24 :
25 : ////
26 :
27 : size_t requiredElements;
28 : GLint maxDrawBuffer;
29 0 : switch (buffer) {
30 : case LOCAL_GL_COLOR:
31 0 : requiredElements = 4;
32 0 : maxDrawBuffer = mGLMaxDrawBuffers - 1;
33 0 : break;
34 :
35 : case LOCAL_GL_DEPTH:
36 : case LOCAL_GL_STENCIL:
37 0 : requiredElements = 1;
38 0 : maxDrawBuffer = 0;
39 0 : break;
40 :
41 : case LOCAL_GL_DEPTH_STENCIL:
42 0 : requiredElements = 2;
43 0 : maxDrawBuffer = 0;
44 0 : break;
45 :
46 : default:
47 0 : ErrorInvalidEnumInfo(funcName, buffer);
48 0 : return false;
49 : }
50 :
51 0 : if (drawBuffer < 0 || drawBuffer > maxDrawBuffer) {
52 0 : ErrorInvalidValue("%s: Invalid drawbuffer %d. This buffer only supports"
53 : " `drawbuffer` values between 0 and %u.",
54 0 : funcName, drawBuffer, maxDrawBuffer);
55 0 : return false;
56 : }
57 :
58 0 : if (availElemCount < requiredElements) {
59 0 : ErrorInvalidValue("%s: Not enough elements. Require %" PRIuSIZE ". Given %" PRIuSIZE ".",
60 0 : funcName, requiredElements, availElemCount);
61 0 : return false;
62 : }
63 :
64 : ////
65 :
66 0 : MakeContextCurrent();
67 :
68 0 : const auto& fb = mBoundDrawFramebuffer;
69 0 : if (fb) {
70 0 : if (!fb->ValidateAndInitAttachments(funcName))
71 0 : return false;
72 :
73 0 : if (!fb->ValidateClearBufferType(funcName, buffer, drawBuffer, funcType))
74 0 : return false;
75 0 : } else if (buffer == LOCAL_GL_COLOR) {
76 0 : if (drawBuffer != 0)
77 0 : return true;
78 :
79 0 : if (mDefaultFB_DrawBuffer0 == LOCAL_GL_NONE)
80 0 : return true;
81 :
82 0 : if (funcType != LOCAL_GL_FLOAT) {
83 0 : ErrorInvalidOperation("%s: For default framebuffer, COLOR is always of type"
84 : " FLOAT.",
85 0 : funcName);
86 0 : return false;
87 : }
88 : }
89 :
90 0 : return true;
91 : }
92 :
93 : ////
94 :
95 : void
96 0 : WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src,
97 : GLuint srcElemOffset)
98 : {
99 0 : const char funcName[] = "clearBufferfv";
100 0 : if (IsContextLost())
101 0 : return;
102 :
103 0 : if (buffer != LOCAL_GL_COLOR &&
104 : buffer != LOCAL_GL_DEPTH)
105 : {
106 0 : ErrorInvalidEnum("%s: buffer must be COLOR or DEPTH.", funcName);
107 0 : return;
108 : }
109 :
110 0 : if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset,
111 : LOCAL_GL_FLOAT))
112 : {
113 0 : return;
114 : }
115 :
116 0 : ScopedDrawCallWrapper wrapper(*this);
117 0 : const auto ptr = src.elemBytes + srcElemOffset;
118 0 : gl->fClearBufferfv(buffer, drawBuffer, ptr);
119 : }
120 :
121 : void
122 0 : WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32Arr& src,
123 : GLuint srcElemOffset)
124 : {
125 0 : const char funcName[] = "clearBufferiv";
126 0 : if (IsContextLost())
127 0 : return;
128 :
129 0 : if (buffer != LOCAL_GL_COLOR &&
130 : buffer != LOCAL_GL_STENCIL)
131 : {
132 0 : ErrorInvalidEnum("%s: buffer must be COLOR or STENCIL.", funcName);
133 0 : return;
134 : }
135 :
136 0 : if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset,
137 : LOCAL_GL_INT))
138 : {
139 0 : return;
140 : }
141 :
142 0 : ScopedDrawCallWrapper wrapper(*this);
143 0 : const auto ptr = src.elemBytes + srcElemOffset;
144 0 : gl->fClearBufferiv(buffer, drawBuffer, ptr);
145 : }
146 :
147 : void
148 0 : WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32Arr& src,
149 : GLuint srcElemOffset)
150 : {
151 0 : const char funcName[] = "clearBufferuiv";
152 0 : if (IsContextLost())
153 0 : return;
154 :
155 0 : if (buffer != LOCAL_GL_COLOR)
156 0 : return ErrorInvalidEnum("%s: buffer must be COLOR.", funcName);
157 :
158 0 : if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset,
159 : LOCAL_GL_UNSIGNED_INT))
160 : {
161 0 : return;
162 : }
163 :
164 0 : ScopedDrawCallWrapper wrapper(*this);
165 0 : const auto ptr = src.elemBytes + srcElemOffset;
166 0 : gl->fClearBufferuiv(buffer, drawBuffer, ptr);
167 : }
168 :
169 : ////
170 :
171 : void
172 0 : WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth,
173 : GLint stencil)
174 : {
175 0 : const char funcName[] = "clearBufferfi";
176 0 : if (IsContextLost())
177 0 : return;
178 :
179 0 : if (buffer != LOCAL_GL_DEPTH_STENCIL)
180 0 : return ErrorInvalidEnum("%s: buffer must be DEPTH_STENCIL.", funcName);
181 :
182 0 : if (!ValidateClearBuffer(funcName, buffer, drawBuffer, 2, 0, 0))
183 0 : return;
184 :
185 0 : ScopedDrawCallWrapper wrapper(*this);
186 0 : gl->fClearBufferfi(buffer, drawBuffer, depth, stencil);
187 : }
188 :
189 : } // namespace mozilla
|