| Flutter Impeller |

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