Flutter Engine
The Flutter Engine
description_gles.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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
6
7#include <algorithm>
8#include <cctype>
9#include <iomanip>
10#include <sstream>
11#include <string>
12#include <utility>
13#include <vector>
14
18
19namespace impeller {
20
21static std::string GetGLString(const ProcTableGLES& gl, GLenum name) {
22 auto str = gl.GetString(name);
23 if (str == nullptr) {
24 return "";
25 }
26 return reinterpret_cast<const char*>(str);
27}
28
29static std::string GetGLStringi(const ProcTableGLES& gl,
30 GLenum name,
31 int index) {
32 auto str = gl.GetStringi(name, index);
33 if (str == nullptr) {
34 return "";
35 }
36 return reinterpret_cast<const char*>(str);
37}
38
39static bool DetermineIfES(const std::string& version) {
40 return HasPrefix(version, "OpenGL ES");
41}
42
43static bool DetermineIfANGLE(const std::string& version) {
44 return version.find("ANGLE") != std::string::npos;
45}
46
47static std::optional<Version> DetermineVersion(std::string version) {
48 // Format for OpenGL "OpenGL<space>ES<space><version
49 // number><space><vendor-specific information>".
50 //
51 // Format for OpenGL SL "OpenGL<space>ES<space>GLSL<space>ES<space><version
52 // number><space><vendor-specific information>"
53 //
54 // The prefixes appear to be absent on Desktop GL.
55
56 version = StripPrefix(version, "OpenGL ES ");
57 version = StripPrefix(version, "GLSL ES ");
58
59 if (version.empty()) {
60 return std::nullopt;
61 }
62
63 std::stringstream stream;
64 for (size_t i = 0; i < version.size(); i++) {
65 const auto character = version[i];
66 if (std::isdigit(character) || character == '.') {
68 } else {
69 break;
70 }
71 }
72 std::istringstream istream;
73 istream.str(stream.str());
74 std::vector<size_t> version_components;
75 for (std::string version_component;
76 std::getline(istream, version_component, '.');) {
77 version_components.push_back(std::stoul(version_component));
78 }
79 return Version::FromVector(version_components);
80}
81
83 : vendor_(GetGLString(gl, GL_VENDOR)),
84 renderer_(GetGLString(gl, GL_RENDERER)),
85 gl_version_string_(GetGLString(gl, GL_VERSION)),
86 sl_version_string_(GetGLString(gl, GL_SHADING_LANGUAGE_VERSION)) {
87 is_es_ = DetermineIfES(gl_version_string_);
88 is_angle_ = DetermineIfANGLE(gl_version_string_);
89
90 auto gl_version = DetermineVersion(gl_version_string_);
91 if (!gl_version.has_value()) {
92 VALIDATION_LOG << "Could not determine GL version.";
93 return;
94 }
95 gl_version_ = gl_version.value();
96
97 // GL_NUM_EXTENSIONS is only available in OpenGL 3+ and OpenGL ES 3+
98 if (gl_version_.IsAtLeast(Version(3, 0, 0))) {
99 int extension_count = 0;
100 gl.GetIntegerv(GL_NUM_EXTENSIONS, &extension_count);
101 for (auto i = 0; i < extension_count; i++) {
102 extensions_.insert(GetGLStringi(gl, GL_EXTENSIONS, i));
103 }
104 } else {
105 const auto extensions = GetGLString(gl, GL_EXTENSIONS);
106 std::stringstream extensions_stream(extensions);
107 std::string extension;
108 while (std::getline(extensions_stream, extension, ' ')) {
109 extensions_.insert(extension);
110 }
111 }
112
113 auto sl_version = DetermineVersion(sl_version_string_);
114 if (!sl_version.has_value()) {
115 VALIDATION_LOG << "Could not determine SL version.";
116 return;
117 }
118 sl_version_ = sl_version.value();
119
120 is_valid_ = true;
121}
122
124
126 return is_valid_;
127}
128
129std::string DescriptionGLES::GetString() const {
130 if (!IsValid()) {
131 return "Unknown Renderer.";
132 }
133
134 std::vector<std::pair<std::string, std::string>> items;
135
136 items.emplace_back(std::make_pair("Vendor", vendor_));
137 items.emplace_back(std::make_pair("Renderer", renderer_));
138 items.emplace_back(std::make_pair("GL Version", gl_version_string_));
139 items.emplace_back(
140 std::make_pair("Shading Language Version", sl_version_string_));
141 items.emplace_back(
142 std::make_pair("Extensions", std::to_string(extensions_.size())));
143
144 size_t max_width = 0u;
145 for (const auto& item : items) {
146 max_width = std::max(max_width, item.first.size());
147 }
148
149 std::stringstream stream;
150 stream << "OpenGL Renderer:" << std::endl;
151 for (const auto& item : items) {
152 stream << std::setw(max_width + 1) << item.first << ": " << item.second
153 << std::endl;
154 }
155
156 const auto pad = std::string(max_width + 3, ' ');
157 for (const auto& extension : extensions_) {
158 stream << pad << extension << std::endl;
159 }
160
161 return stream.str();
162}
163
165 return gl_version_;
166}
167
169 return is_es_;
170}
171
173 return is_angle_;
174}
175
176bool DescriptionGLES::HasExtension(const std::string& ext) const {
177 return extensions_.find(ext) != extensions_.end();
178}
179
181 return HasExtension("GL_KHR_debug");
182}
183
184} // namespace impeller
DescriptionGLES(const ProcTableGLES &gl)
std::string GetString() const
bool HasExtension(const std::string &ext) const
bool HasDebugExtension() const
Returns whether GLES includes the debug extension.
static float max(float r, float g, float b)
Definition: hsl.cpp:49
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
static std::string GetGLString(const ProcTableGLES &gl, GLenum name)
static bool DetermineIfES(const std::string &version)
static bool DetermineIfANGLE(const std::string &version)
bool HasPrefix(const std::string &string, const std::string &prefix)
Definition: strings.cc:30
static std::optional< Version > DetermineVersion(std::string version)
std::string StripPrefix(const std::string &string, const std::string &to_strip)
Definition: strings.cc:42
static std::string GetGLStringi(const ProcTableGLES &gl, GLenum name, int index)
gl
Definition: malisc.py:41
static SkString to_string(int n)
Definition: nanobench.cpp:119
static std::optional< Version > FromVector(const std::vector< size_t > &version)
constexpr bool IsAtLeast(const Version &other) const
Definition: version.h:31
#define VALIDATION_LOG
Definition: validation.h:73