| Index: gpu/command_buffer/service/gl_utils.cc
|
| diff --git a/gpu/command_buffer/service/gl_utils.cc b/gpu/command_buffer/service/gl_utils.cc
|
| index bb8ce4b013d601c51b63b3ba9861eedadd8b04cb..8fca5d4b82b6a118ae9dbdf2b930be28f1935f82 100644
|
| --- a/gpu/command_buffer/service/gl_utils.cc
|
| +++ b/gpu/command_buffer/service/gl_utils.cc
|
| @@ -5,6 +5,9 @@
|
| #include "gpu/command_buffer/service/gl_utils.h"
|
|
|
| #include "base/metrics/histogram.h"
|
| +#include "gpu/command_buffer/common/capabilities.h"
|
| +#include "gpu/command_buffer/service/feature_info.h"
|
| +#include "ui/gl/gl_version_info.h"
|
|
|
| namespace gpu {
|
| namespace gles2 {
|
| @@ -22,5 +25,156 @@ std::vector<int> GetAllGLErrors() {
|
| arraysize(gl_errors));
|
| }
|
|
|
| +bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
|
| + GLint rangeMax,
|
| + GLint precision) {
|
| + return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
|
| +}
|
| +
|
| +void QueryShaderPrecisionFormat(const gl::GLVersionInfo& gl_version_info,
|
| + GLenum shader_type,
|
| + GLenum precision_type,
|
| + GLint* range,
|
| + GLint* precision) {
|
| + switch (precision_type) {
|
| + case GL_LOW_INT:
|
| + case GL_MEDIUM_INT:
|
| + case GL_HIGH_INT:
|
| + // These values are for a 32-bit twos-complement integer format.
|
| + range[0] = 31;
|
| + range[1] = 30;
|
| + *precision = 0;
|
| + break;
|
| + case GL_LOW_FLOAT:
|
| + case GL_MEDIUM_FLOAT:
|
| + case GL_HIGH_FLOAT:
|
| + // These values are for an IEEE single-precision floating-point format.
|
| + range[0] = 127;
|
| + range[1] = 127;
|
| + *precision = 23;
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +
|
| + if (gl_version_info.is_es) {
|
| + // This function is sometimes defined even though it's really just
|
| + // a stub, so we need to set range and precision as if it weren't
|
| + // defined before calling it.
|
| + // On Mac OS with some GPUs, calling this generates a
|
| + // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
|
| + // platforms.
|
| + glGetShaderPrecisionFormat(shader_type, precision_type, range, precision);
|
| +
|
| + // TODO(brianderson): Make the following official workarounds.
|
| +
|
| + // Some drivers have bugs where they report the ranges as a negative number.
|
| + // Taking the absolute value here shouldn't hurt because negative numbers
|
| + // aren't expected anyway.
|
| + range[0] = abs(range[0]);
|
| + range[1] = abs(range[1]);
|
| +
|
| + // If the driver reports a precision for highp float that isn't actually
|
| + // highp, don't pretend like it's supported because shader compilation will
|
| + // fail anyway.
|
| + if (precision_type == GL_HIGH_FLOAT &&
|
| + !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
|
| + range[0] = 0;
|
| + range[1] = 0;
|
| + *precision = 0;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void PopulateNumericCapabilities(Capabilities* caps,
|
| + const FeatureInfo* feature_info) {
|
| + DCHECK(caps != nullptr);
|
| +
|
| + const gl::GLVersionInfo& version_info = feature_info->gl_version_info();
|
| + caps->VisitPrecisions([&version_info](
|
| + GLenum shader, GLenum type,
|
| + Capabilities::ShaderPrecision* shader_precision) {
|
| + GLint range[2] = {0, 0};
|
| + GLint precision = 0;
|
| + QueryShaderPrecisionFormat(version_info, shader, type, range, &precision);
|
| + shader_precision->min_range = range[0];
|
| + shader_precision->max_range = range[1];
|
| + shader_precision->precision = precision;
|
| + });
|
| +
|
| + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
|
| + &caps->max_combined_texture_image_units);
|
| + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps->max_cube_map_texture_size);
|
| + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
|
| + &caps->max_fragment_uniform_vectors);
|
| + glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps->max_renderbuffer_size);
|
| + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps->max_texture_image_units);
|
| + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size);
|
| + glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps->max_varying_vectors);
|
| + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->max_vertex_attribs);
|
| + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
|
| + &caps->max_vertex_texture_image_units);
|
| + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
|
| + &caps->max_vertex_uniform_vectors);
|
| + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
|
| + &caps->num_compressed_texture_formats);
|
| + glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps->num_shader_binary_formats);
|
| +
|
| + if (feature_info->IsES3Enabled()) {
|
| + glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps->max_3d_texture_size);
|
| + glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps->max_array_texture_layers);
|
| + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps->max_color_attachments);
|
| + glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
|
| + &caps->max_combined_fragment_uniform_components);
|
| + glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
|
| + &caps->max_combined_uniform_blocks);
|
| + glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
|
| + &caps->max_combined_vertex_uniform_components);
|
| + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps->max_draw_buffers);
|
| + glGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps->max_element_index);
|
| + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps->max_elements_indices);
|
| + glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps->max_elements_vertices);
|
| + glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
|
| + &caps->max_fragment_input_components);
|
| + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
|
| + &caps->max_fragment_uniform_blocks);
|
| + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
|
| + &caps->max_fragment_uniform_components);
|
| + glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->max_program_texel_offset);
|
| + glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps->max_server_wait_timeout);
|
| + glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->max_texture_lod_bias);
|
| + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
|
| + &caps->max_transform_feedback_interleaved_components);
|
| + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
|
| + &caps->max_transform_feedback_separate_attribs);
|
| + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
|
| + &caps->max_transform_feedback_separate_components);
|
| + glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps->max_uniform_block_size);
|
| + glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
|
| + &caps->max_uniform_buffer_bindings);
|
| + glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps->max_varying_components);
|
| + glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
|
| + &caps->max_vertex_output_components);
|
| + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
|
| + &caps->max_vertex_uniform_blocks);
|
| + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
|
| + &caps->max_vertex_uniform_components);
|
| + glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->min_program_texel_offset);
|
| + glGetIntegerv(GL_NUM_EXTENSIONS, &caps->num_extensions);
|
| + glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
|
| + &caps->num_program_binary_formats);
|
| + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
|
| + &caps->uniform_buffer_offset_alignment);
|
| + caps->major_version = 3;
|
| + caps->minor_version = 0;
|
| + }
|
| + if (feature_info->feature_flags().multisampled_render_to_texture ||
|
| + feature_info->feature_flags().chromium_framebuffer_multisample ||
|
| + feature_info->IsES3Enabled()) {
|
| + glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples);
|
| + }
|
| +}
|
| +
|
| } // namespace gles2
|
| } // namespace gpu
|
|
|