blob: d5f663f307a58422082cc0f96ef0b441fed83262 [file] [log] [blame]
junov0cad1f42016-01-07 21:48:511// Copyright (c) 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gpu/command_buffer/service/gl_utils.h"
6
7#include "base/metrics/histogram.h"
geofflang124fd552016-09-08 20:02:558#include "gpu/command_buffer/common/capabilities.h"
9#include "gpu/command_buffer/service/feature_info.h"
10#include "ui/gl/gl_version_info.h"
junov0cad1f42016-01-07 21:48:5111
12namespace gpu {
13namespace gles2 {
14
geofflang326c8512016-11-03 15:11:2815namespace {
16const char* GetDebugSourceString(GLenum source) {
17 switch (source) {
18 case GL_DEBUG_SOURCE_API:
19 return "OpenGL";
20 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
21 return "Window System";
22 case GL_DEBUG_SOURCE_SHADER_COMPILER:
23 return "Shader Compiler";
24 case GL_DEBUG_SOURCE_THIRD_PARTY:
25 return "Third Party";
26 case GL_DEBUG_SOURCE_APPLICATION:
27 return "Application";
28 case GL_DEBUG_SOURCE_OTHER:
29 return "Other";
30 default:
31 return "UNKNOWN";
32 }
33}
34
35const char* GetDebugTypeString(GLenum type) {
36 switch (type) {
37 case GL_DEBUG_TYPE_ERROR:
38 return "Error";
39 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
40 return "Deprecated behavior";
41 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
42 return "Undefined behavior";
43 case GL_DEBUG_TYPE_PORTABILITY:
44 return "Portability";
45 case GL_DEBUG_TYPE_PERFORMANCE:
46 return "Performance";
47 case GL_DEBUG_TYPE_OTHER:
48 return "Other";
49 case GL_DEBUG_TYPE_MARKER:
50 return "Marker";
51 default:
52 return "UNKNOWN";
53 }
54}
55
56const char* GetDebugSeverityString(GLenum severity) {
57 switch (severity) {
58 case GL_DEBUG_SEVERITY_HIGH:
59 return "High";
60 case GL_DEBUG_SEVERITY_MEDIUM:
61 return "Medium";
62 case GL_DEBUG_SEVERITY_LOW:
63 return "Low";
64 case GL_DEBUG_SEVERITY_NOTIFICATION:
65 return "Notification";
66 default:
67 return "UNKNOWN";
68 }
69}
70}
71
junov0cad1f42016-01-07 21:48:5172std::vector<int> GetAllGLErrors() {
73 int gl_errors[] = {
74 GL_NO_ERROR,
75 GL_INVALID_ENUM,
76 GL_INVALID_VALUE,
77 GL_INVALID_OPERATION,
78 GL_INVALID_FRAMEBUFFER_OPERATION,
79 GL_OUT_OF_MEMORY,
80 };
81 return base::CustomHistogram::ArrayToCustomRanges(gl_errors,
82 arraysize(gl_errors));
83}
84
geofflang124fd552016-09-08 20:02:5585bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
86 GLint rangeMax,
87 GLint precision) {
88 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
89}
90
91void QueryShaderPrecisionFormat(const gl::GLVersionInfo& gl_version_info,
92 GLenum shader_type,
93 GLenum precision_type,
94 GLint* range,
95 GLint* precision) {
96 switch (precision_type) {
97 case GL_LOW_INT:
98 case GL_MEDIUM_INT:
99 case GL_HIGH_INT:
100 // These values are for a 32-bit twos-complement integer format.
101 range[0] = 31;
102 range[1] = 30;
103 *precision = 0;
104 break;
105 case GL_LOW_FLOAT:
106 case GL_MEDIUM_FLOAT:
107 case GL_HIGH_FLOAT:
108 // These values are for an IEEE single-precision floating-point format.
109 range[0] = 127;
110 range[1] = 127;
111 *precision = 23;
112 break;
113 default:
114 NOTREACHED();
115 break;
116 }
117
118 if (gl_version_info.is_es) {
119 // This function is sometimes defined even though it's really just
120 // a stub, so we need to set range and precision as if it weren't
121 // defined before calling it.
122 // On Mac OS with some GPUs, calling this generates a
123 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
124 // platforms.
125 glGetShaderPrecisionFormat(shader_type, precision_type, range, precision);
126
127 // TODO(brianderson): Make the following official workarounds.
128
129 // Some drivers have bugs where they report the ranges as a negative number.
130 // Taking the absolute value here shouldn't hurt because negative numbers
131 // aren't expected anyway.
132 range[0] = abs(range[0]);
133 range[1] = abs(range[1]);
134
135 // If the driver reports a precision for highp float that isn't actually
136 // highp, don't pretend like it's supported because shader compilation will
137 // fail anyway.
138 if (precision_type == GL_HIGH_FLOAT &&
139 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
140 range[0] = 0;
141 range[1] = 0;
142 *precision = 0;
143 }
144 }
145}
146
147void PopulateNumericCapabilities(Capabilities* caps,
148 const FeatureInfo* feature_info) {
149 DCHECK(caps != nullptr);
150
151 const gl::GLVersionInfo& version_info = feature_info->gl_version_info();
152 caps->VisitPrecisions([&version_info](
153 GLenum shader, GLenum type,
154 Capabilities::ShaderPrecision* shader_precision) {
155 GLint range[2] = {0, 0};
156 GLint precision = 0;
157 QueryShaderPrecisionFormat(version_info, shader, type, range, &precision);
158 shader_precision->min_range = range[0];
159 shader_precision->max_range = range[1];
160 shader_precision->precision = precision;
161 });
162
163 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
164 &caps->max_combined_texture_image_units);
165 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps->max_cube_map_texture_size);
166 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
167 &caps->max_fragment_uniform_vectors);
168 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps->max_renderbuffer_size);
169 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps->max_texture_image_units);
170 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
171 glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps->max_varying_vectors);
172 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->max_vertex_attribs);
173 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
174 &caps->max_vertex_texture_image_units);
175 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
176 &caps->max_vertex_uniform_vectors);
177 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
178 &caps->num_compressed_texture_formats);
179 glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps->num_shader_binary_formats);
180
kaininoe20d23ac2016-11-03 01:03:45181 if (feature_info->IsWebGL2OrES3Context()) {
geofflang124fd552016-09-08 20:02:55182 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps->max_3d_texture_size);
183 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps->max_array_texture_layers);
184 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps->max_color_attachments);
185 glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
186 &caps->max_combined_fragment_uniform_components);
187 glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
188 &caps->max_combined_uniform_blocks);
189 glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
190 &caps->max_combined_vertex_uniform_components);
191 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps->max_draw_buffers);
192 glGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps->max_element_index);
193 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps->max_elements_indices);
194 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps->max_elements_vertices);
195 glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
196 &caps->max_fragment_input_components);
197 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
198 &caps->max_fragment_uniform_blocks);
199 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
200 &caps->max_fragment_uniform_components);
201 glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->max_program_texel_offset);
202 glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps->max_server_wait_timeout);
203 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->max_texture_lod_bias);
204 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
205 &caps->max_transform_feedback_interleaved_components);
206 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
207 &caps->max_transform_feedback_separate_attribs);
208 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
209 &caps->max_transform_feedback_separate_components);
210 glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps->max_uniform_block_size);
211 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
212 &caps->max_uniform_buffer_bindings);
213 glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps->max_varying_components);
214 glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
215 &caps->max_vertex_output_components);
216 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
217 &caps->max_vertex_uniform_blocks);
218 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
219 &caps->max_vertex_uniform_components);
220 glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->min_program_texel_offset);
221 glGetIntegerv(GL_NUM_EXTENSIONS, &caps->num_extensions);
222 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
223 &caps->num_program_binary_formats);
224 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
225 &caps->uniform_buffer_offset_alignment);
226 caps->major_version = 3;
227 caps->minor_version = 0;
228 }
229 if (feature_info->feature_flags().multisampled_render_to_texture ||
230 feature_info->feature_flags().chromium_framebuffer_multisample ||
kaininoe20d23ac2016-11-03 01:03:45231 feature_info->IsWebGL2OrES3Context()) {
geofflang124fd552016-09-08 20:02:55232 glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples);
233 }
234}
235
geofflang851a4812016-09-14 19:20:29236bool CheckUniqueAndNonNullIds(GLsizei n, const GLuint* client_ids) {
237 if (n <= 0)
238 return true;
239 std::unordered_set<uint32_t> unique_ids(client_ids, client_ids + n);
240 return (unique_ids.size() == static_cast<size_t>(n)) &&
241 (unique_ids.find(0) == unique_ids.end());
242}
243
geofflang326c8512016-11-03 15:11:28244void APIENTRY LogGLDebugMessage(GLenum source,
245 GLenum type,
246 GLuint id,
247 GLenum severity,
248 GLsizei length,
249 const GLchar* message,
250 GLvoid* user_param) {
251 LOG(ERROR) << "GL Driver Message (" << GetDebugSourceString(source) << ", "
252 << GetDebugTypeString(type) << ", " << id << ", "
253 << GetDebugSeverityString(severity) << "): " << message;
254}
255
256void InitializeGLDebugLogging() {
257 glEnable(GL_DEBUG_OUTPUT);
258 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
259
260 // Enable logging of medium and high severity messages
261 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
262 nullptr, GL_TRUE);
263 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0,
264 nullptr, GL_TRUE);
265 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
266 nullptr, GL_FALSE);
267 glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
268 GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
269
270 glDebugMessageCallback(&LogGLDebugMessage, nullptr);
271}
272
junov0cad1f42016-01-07 21:48:51273} // namespace gles2
274} // namespace gpu