blob: c26be4b0e7ede6baecf69bed19d2c37206f26f2d [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gl_connection.h"
#include <sstream>
#include <vector>
#include <algorithm>
#include <iomanip>
namespace flow {
static std::string GLGetString(GLenum name) {
auto string = reinterpret_cast<const char*>(glGetString(name));
return string != nullptr ? string : "";
}
static GLConnection::Version GLGetVersion(GLenum name) {
GLConnection::Version version;
auto versionString = GLGetString(name);
if (versionString.length() == 0) {
return version;
}
{
// Check for the GLSL ES prefix.
const std::string glslesPrefix("OpenGL ES GLSL ES ");
if (versionString.compare(0, glslesPrefix.length(), glslesPrefix) == 0) {
version.isES = true;
versionString = versionString.substr(glslesPrefix.length());
}
}
{
// Check for the GL ES prefix.
const std::string glesPrefix("OpenGL ES ");
if (versionString.compare(0, glesPrefix.length(), glesPrefix) == 0) {
version.isES = true;
versionString = versionString.substr(glesPrefix.length());
}
}
std::istringstream stream(versionString);
for (size_t i = 0; i < 3; i++) {
size_t item = 0;
if (stream >> item) {
version.items[i] = item;
if (stream.peek() == ' ') {
stream.ignore(1); // space
stream >> version.vendorString;
break;
} else {
stream.ignore(1); // dot
}
} else {
break;
}
}
return version;
}
static std::string VersionToString(GLConnection::Version version) {
if (version.major == 0 && version.minor == 0 && version.release == 0) {
return "Unknown";
}
std::stringstream stream;
stream << version.major << "." << version.minor;
if (version.release != 0) {
stream << "." << version.release;
}
if (version.vendorString.size() != 0) {
stream << " " << version.vendorString;
}
if (version.isES) {
stream << " ES";
}
return stream.str();
}
GLConnection::GLConnection()
: vendor_(GLGetString(GL_VENDOR)),
renderer_(GLGetString(GL_RENDERER)),
version_(GLGetVersion(GL_VERSION)),
shading_language_version_(GLGetVersion(GL_SHADING_LANGUAGE_VERSION)) {
std::istringstream extensionsStream(GLGetString(GL_EXTENSIONS));
extensionsStream >> std::skipws;
std::string extension;
while (extensionsStream >> extension) {
extensions_.emplace(std::move(extension));
}
}
GLConnection::~GLConnection() = default;
const std::string& GLConnection::Vendor() const {
return vendor_;
}
const std::string& GLConnection::Renderer() const {
return renderer_;
}
const GLConnection::Version& GLConnection::GLVersion() const {
return version_;
}
std::string GLConnection::VersionString() const {
return VersionToString(version_);
}
const GLConnection::Version& GLConnection::ShadingLanguageVersion() const {
return shading_language_version_;
}
std::string GLConnection::ShadingLanguageVersionString() const {
return VersionToString(shading_language_version_);
}
std::string GLConnection::Platform() const {
std::stringstream stream;
stream << Vendor() << ": " << Renderer();
return stream.str();
}
const std::set<std::string>& GLConnection::Extensions() const {
return extensions_;
}
std::string GLConnection::Description() const {
std::vector<std::pair<std::string, std::string>> items;
items.emplace_back("Vendor", Vendor());
items.emplace_back("Renderer", Renderer());
items.emplace_back("Version", VersionString());
items.emplace_back("Shader Version", ShadingLanguageVersionString());
std::string extensionsLabel("Extensions");
size_t padding = extensionsLabel.size();
for (const auto& item : items) {
padding = std::max(padding, item.first.size());
}
padding += 1;
std::stringstream stream;
stream << std::endl;
for (const auto& item : items) {
stream << std::setw(padding) << item.first << std::setw(0) << ": "
<< item.second << std::endl;
}
if (extensions_.size() != 0) {
std::string paddingString;
paddingString.resize(padding + 2, ' ');
stream << std::setw(padding) << extensionsLabel << std::setw(0) << ": "
<< extensions_.size() << " Available" << std::endl;
for (const auto& extension : extensions_) {
stream << paddingString << extension << std::endl;
}
}
return stream.str();
}
} // namespace flow