Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/canvas/WebGL2ContextQueries.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
#include "GLContext.h"
8
#include "WebGLQuery.h"
9
#include "gfxPrefs.h"
10
#include "nsThreadUtils.h"
11
12
namespace mozilla {
13
14
/*
15
 * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with
16
 * SAMPLES_PASSED on desktop.
17
 *
18
 * OpenGL ES 3.0 spec 4.1.6:
19
 *     If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE, an
20
 *     implementation may choose to use a less precise version of the test which
21
 *     can additionally set the samples-boolean state to TRUE in some other
22
 *     implementation-dependent cases.
23
 */
24
25
WebGLRefPtr<WebGLQuery>*
26
WebGLContext::ValidateQuerySlotByTarget(GLenum target)
27
0
{
28
0
    if (IsWebGL2()) {
29
0
        switch (target) {
30
0
        case LOCAL_GL_ANY_SAMPLES_PASSED:
31
0
        case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
32
0
            return &mQuerySlot_SamplesPassed;
33
0
34
0
        case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
35
0
            return &mQuerySlot_TFPrimsWritten;
36
0
37
0
        default:
38
0
            break;
39
0
        }
40
0
    }
41
0
42
0
    if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
43
0
        switch (target) {
44
0
        case LOCAL_GL_TIME_ELAPSED_EXT:
45
0
            return &mQuerySlot_TimeElapsed;
46
0
47
0
        default:
48
0
            break;
49
0
        }
50
0
    }
51
0
52
0
    ErrorInvalidEnumInfo("target", target);
53
0
    return nullptr;
54
0
}
55
56
57
// -------------------------------------------------------------------------
58
// Query Objects
59
60
already_AddRefed<WebGLQuery>
61
WebGLContext::CreateQuery()
62
0
{
63
0
    const FuncScope funcScope(*this, "createQuery");
64
0
    if (IsContextLost())
65
0
        return nullptr;
66
0
67
0
    RefPtr<WebGLQuery> globj = new WebGLQuery(this);
68
0
    return globj.forget();
69
0
}
70
71
void
72
WebGLContext::DeleteQuery(WebGLQuery* query)
73
0
{
74
0
    const FuncScope funcScope(*this, "deleteQuery");
75
0
    if (!ValidateDeleteObject(query))
76
0
        return;
77
0
78
0
    query->DeleteQuery();
79
0
}
80
81
void
82
WebGLContext::BeginQuery(GLenum target, WebGLQuery& query)
83
0
{
84
0
    const FuncScope funcScope(*this, "beginQuery");
85
0
    if (IsContextLost())
86
0
        return;
87
0
88
0
    if (!ValidateObject("query", query))
89
0
        return;
90
0
91
0
    const auto& slot = ValidateQuerySlotByTarget(target);
92
0
    if (!slot)
93
0
        return;
94
0
95
0
    if (*slot)
96
0
        return ErrorInvalidOperation("Query target already active.");
97
0
98
0
    ////
99
0
100
0
    query.BeginQuery(target, *slot);
101
0
}
102
103
void
104
WebGLContext::EndQuery(GLenum target)
105
0
{
106
0
    const FuncScope funcScope(*this, "endQuery");
107
0
    if (IsContextLost())
108
0
        return;
109
0
110
0
    const auto& slot = ValidateQuerySlotByTarget(target);
111
0
    if (!slot)
112
0
        return;
113
0
114
0
    const auto& query = *slot;
115
0
    if (!query)
116
0
        return ErrorInvalidOperation("Query target not active.");
117
0
118
0
    query->EndQuery();
119
0
}
120
121
void
122
WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
123
                       JS::MutableHandleValue retval)
124
0
{
125
0
    const FuncScope funcScope(*this, "getQuery");
126
0
127
0
    retval.setNull();
128
0
    if (IsContextLost())
129
0
        return;
130
0
131
0
    switch (pname) {
132
0
    case LOCAL_GL_CURRENT_QUERY_EXT:
133
0
        {
134
0
            if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query) &&
135
0
                target == LOCAL_GL_TIMESTAMP)
136
0
            {
137
0
                // Doesn't seem illegal to ask about, but is always null.
138
0
                // TIMESTAMP has no slot, so ValidateQuerySlotByTarget would generate
139
0
                // INVALID_ENUM.
140
0
                return;
141
0
            }
142
0
143
0
            const auto& slot = ValidateQuerySlotByTarget(target);
144
0
            if (!slot || !*slot)
145
0
                return;
146
0
147
0
            const auto& query = *slot;
148
0
            if (target != query->Target())
149
0
                return;
150
0
151
0
            JS::Rooted<JS::Value> v(cx);
152
0
            dom::GetOrCreateDOMReflector(cx, slot->get(), &v);
153
0
            retval.set(v);
154
0
        }
155
0
        return;
156
0
157
0
    case LOCAL_GL_QUERY_COUNTER_BITS_EXT:
158
0
        if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query))
159
0
            break;
160
0
161
0
        if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
162
0
            target != LOCAL_GL_TIMESTAMP_EXT)
163
0
        {
164
0
            ErrorInvalidEnumInfo("target", target);
165
0
            return;
166
0
        }
167
0
168
0
        {
169
0
            GLint bits = 0;
170
0
            gl->fGetQueryiv(target, pname, &bits);
171
0
172
0
            if (!Has64BitTimestamps() && bits > 32) {
173
0
                bits = 32;
174
0
            }
175
0
            retval.set(JS::Int32Value(bits));
176
0
        }
177
0
        return;
178
0
179
0
    default:
180
0
        break;
181
0
    }
182
0
183
0
    ErrorInvalidEnumInfo("pname", pname);
184
0
}
185
186
void
187
WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery& query, GLenum pname,
188
                                JS::MutableHandleValue retval)
189
0
{
190
0
    const FuncScope funcScope(*this, "getQueryParameter");
191
0
    retval.setNull();
192
0
    if (IsContextLost())
193
0
        return;
194
0
195
0
    if (!ValidateObject("query", query))
196
0
        return;
197
0
198
0
    query.GetQueryParameter(pname, retval);
199
0
}
200
201
} // namespace mozilla