Coverage Report

Created: 2018-09-25 14:53

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