blob: 234d33686d0468aa5908ba3cd8df8368c89f7287 [file] [log] [blame]
Geoff Lang56cf9af2015-02-17 10:16:49 -05001//
2// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// FunctionsGL.cpp: Implements the FuntionsGL class to contain loaded GL functions
8
9#include "libANGLE/renderer/gl/FunctionsGL.h"
Jacek Cabanfa60f692015-04-27 18:23:44 +020010
11#include <algorithm>
12
Jamie Madill8c5aeb62015-05-21 08:17:18 -040013#include "common/string_utils.h"
Geoff Langa4903b72015-03-02 16:02:48 -080014#include "libANGLE/renderer/gl/renderergl_utils.h"
Geoff Lang56cf9af2015-02-17 10:16:49 -050015
16namespace rx
17{
18
Geoff Lang08dcfed2015-05-25 13:38:42 -040019static void GetGLVersion(PFNGLGETSTRINGPROC getStringFunction, gl::Version *outVersion, StandardGL *outStandard)
Geoff Langa4903b72015-03-02 16:02:48 -080020{
21 const std::string version = reinterpret_cast<const char*>(getStringFunction(GL_VERSION));
22 if (version.find("OpenGL ES") == std::string::npos)
23 {
Corentin Wallezfee03502015-05-05 15:08:24 -040024 // OpenGL spec states the GL_VERSION string will be in the following format:
25 // <version number><space><vendor-specific information>
26 // The version number is either of the form major number.minor number or major
27 // number.minor number.release number, where the numbers all have one or more
28 // digits
Geoff Lang08dcfed2015-05-25 13:38:42 -040029 *outStandard = STANDARD_GL_DESKTOP;
30 *outVersion = gl::Version(version[0] - '0', version[2] - '0');
Geoff Langa4903b72015-03-02 16:02:48 -080031 }
32 else
33 {
Corentin Wallezfee03502015-05-05 15:08:24 -040034 // ES spec states that the GL_VERSION string will be in the following format:
35 // "OpenGL ES N.M vendor-specific information"
Geoff Lang08dcfed2015-05-25 13:38:42 -040036 *outStandard = STANDARD_GL_ES;
37 *outVersion = gl::Version(version[10] - '0', version[12] - '0');
Geoff Langa4903b72015-03-02 16:02:48 -080038 }
39}
40
Geoff Langa4903b72015-03-02 16:02:48 -080041static std::vector<std::string> GetIndexedExtensions(PFNGLGETINTEGERVPROC getIntegerFunction, PFNGLGETSTRINGIPROC getStringIFunction)
42{
43 std::vector<std::string> result;
44
45 GLint numExtensions;
46 getIntegerFunction(GL_NUM_EXTENSIONS, &numExtensions);
47
48 result.reserve(numExtensions);
49
50 for (GLint i = 0; i < numExtensions; i++)
51 {
52 result.push_back(reinterpret_cast<const char*>(getStringIFunction(GL_EXTENSIONS, i)));
53 }
54
55 return result;
56}
57
Jamie Madill60c65552017-05-02 14:34:05 -040058#define ASSIGN(NAME, FP) *reinterpret_cast<void **>(&FP) = loadProcAddress(NAME)
59
Jamie Madill29ddcc92017-10-21 16:10:02 -040060FunctionsGL::FunctionsGL() : version(), standard(), extensions()
Geoff Lang56cf9af2015-02-17 10:16:49 -050061{
62}
63
64FunctionsGL::~FunctionsGL()
65{
66}
67
Geoff Langa4903b72015-03-02 16:02:48 -080068void FunctionsGL::initialize()
Geoff Lang56cf9af2015-02-17 10:16:49 -050069{
Geoff Langa4903b72015-03-02 16:02:48 -080070 // Grab the version number
Jamie Madill60c65552017-05-02 14:34:05 -040071 ASSIGN("glGetString", getString);
72 ASSIGN("glGetIntegerv", getIntegerv);
Geoff Lang08dcfed2015-05-25 13:38:42 -040073 GetGLVersion(getString, &version, &standard);
Geoff Langa4903b72015-03-02 16:02:48 -080074
75 // Grab the GL extensions
Geoff Langb2d9ab62016-01-20 10:50:09 -050076 if (isAtLeastGL(gl::Version(3, 0)) || isAtLeastGLES(gl::Version(3, 0)))
Geoff Langa4903b72015-03-02 16:02:48 -080077 {
Jamie Madill60c65552017-05-02 14:34:05 -040078 ASSIGN("glGetStringi", getStringi);
Geoff Langa4903b72015-03-02 16:02:48 -080079 extensions = GetIndexedExtensions(getIntegerv, getStringi);
80 }
81 else
82 {
Jamie Madill29ddcc92017-10-21 16:10:02 -040083 const char *exts = reinterpret_cast<const char *>(getString(GL_EXTENSIONS));
Jamie Madill8c5aeb62015-05-21 08:17:18 -040084 angle::SplitStringAlongWhitespace(std::string(exts), &extensions);
Geoff Langa4903b72015-03-02 16:02:48 -080085 }
86
Jamie Madill29ddcc92017-10-21 16:10:02 -040087 std::set<std::string> extensionSet;
88 for (const auto &extension : extensions)
89 {
90 extensionSet.insert(extension);
91 }
92
93 // Note:
94 // Even though extensions are written against specific versions of GL, many drivers expose the
95 // extensions in even older versions. Always try loading the extensions regardless of GL
96 // version.
97
Geoff Langb2d9ab62016-01-20 10:50:09 -050098 // Load the entry points
99 switch (standard)
100 {
101 case STANDARD_GL_DESKTOP:
Jamie Madill29ddcc92017-10-21 16:10:02 -0400102 {
103 // Check the context profile
104 profile = 0;
105 if (isAtLeastGL(gl::Version(3, 2)))
106 {
107 getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
108 }
109
110 initProcsDesktopGL(version, extensionSet);
Geoff Langb2d9ab62016-01-20 10:50:09 -0500111 break;
Jamie Madill29ddcc92017-10-21 16:10:02 -0400112 }
Geoff Langb2d9ab62016-01-20 10:50:09 -0500113
114 case STANDARD_GL_ES:
Jamie Madill29ddcc92017-10-21 16:10:02 -0400115 // No profiles in GLES
116 profile = 0;
117
118 initProcsGLES(version, extensionSet);
Geoff Langb2d9ab62016-01-20 10:50:09 -0500119 break;
120
121 default:
122 UNREACHABLE();
123 break;
124 }
Geoff Langb2d9ab62016-01-20 10:50:09 -0500125
Jamie Madill29ddcc92017-10-21 16:10:02 -0400126 initProcsSharedExtensions(extensionSet);
Geoff Langb2d9ab62016-01-20 10:50:09 -0500127}
128
Geoff Lang08dcfed2015-05-25 13:38:42 -0400129bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const
130{
131 return standard == STANDARD_GL_DESKTOP && version >= glVersion;
132}
133
Corentin Wallezf7417802016-10-12 17:59:31 -0400134bool FunctionsGL::isAtMostGL(const gl::Version &glVersion) const
135{
136 return standard == STANDARD_GL_DESKTOP && glVersion >= version;
137}
138
Geoff Lang08dcfed2015-05-25 13:38:42 -0400139bool FunctionsGL::isAtLeastGLES(const gl::Version &glesVersion) const
140{
141 return standard == STANDARD_GL_ES && version >= glesVersion;
142}
143
Corentin Wallezf7417802016-10-12 17:59:31 -0400144bool FunctionsGL::isAtMostGLES(const gl::Version &glesVersion) const
145{
146 return standard == STANDARD_GL_ES && glesVersion >= version;
147}
148
Geoff Langf34d1db2015-05-20 14:10:46 -0400149bool FunctionsGL::hasExtension(const std::string &ext) const
150{
151 return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
152}
153
Geoff Lang862c0ba2015-05-25 15:31:16 -0400154bool FunctionsGL::hasGLExtension(const std::string &ext) const
155{
156 return standard == STANDARD_GL_DESKTOP && hasExtension(ext);
157}
158
159bool FunctionsGL::hasGLESExtension(const std::string &ext) const
160{
161 return standard == STANDARD_GL_ES && hasExtension(ext);
162}
163
Jamie Madill60c65552017-05-02 14:34:05 -0400164} // namespace gl