Caffe2 - C++ API
A deep learning, cross platform ML framework
GLContext.cc
1 
2 #include "caffe2/core/logging.h"
3 
4 #include "GL.h"
5 #include "GLContext.h"
6 #include "GLLogging.h"
7 
8 #include <sstream>
9 #include <string>
10 #include <unordered_map>
11 #include <unordered_set>
12 
13 #if CAFFE2_IOS
14 #include "sys/utsname.h"
15 #include <regex>
16 #endif
17 
18 void getOpenGLESVersion(int& major, int& minor) {
19  glGetIntegerv(GL_MAJOR_VERSION, &major);
20  glGetIntegerv(GL_MINOR_VERSION, &minor);
21 }
22 
23 bool checkOpenGLExtensions(std::string gl_ext_str) {
24  static std::unordered_set<std::string> extensions;
25  if (extensions.empty()) {
26  const caffe2::string extension_str((const char*)glGetString(GL_EXTENSIONS));
27  LOG(INFO) << "GL_EXTENSIONS: " << extension_str;
28 
29  std::stringstream ss(extension_str);
30  while (!ss.eof()) {
31  std::string extension;
32  ss >> extension;
33  extensions.insert(extension);
34  }
35  }
36 
37  return extensions.count(gl_ext_str) > 0;
38 }
39 
40 bool GLContext::GL_EXT_texture_border_clamp_defined() {
41  static int major = 0, minor = 0;
42  if (major == 0) {
43  getOpenGLESVersion(major, minor);
44  }
45 
46  if (major == 3 && minor == 2) {
47  return true;
48  }
49 
50  return checkOpenGLExtensions("GL_EXT_texture_border_clamp") || // Most common
51  checkOpenGLExtensions("GL_OES_texture_border_clamp");
52 }
53 
54 bool supportOpenGLES3(bool* half_float_supported) {
55  int major = 0, minor = 0;
56  getOpenGLESVersion(major, minor);
57 
58  LOG(INFO) << "GL_VERSION: OpenGL ES " << major << "." << minor;
59 
60  if (major < 3) {
61  LOG(ERROR) << "OpenGL ES 3.0 not supported";
62  return false;
63  }
64 
65  if (!checkOpenGLExtensions("GL_EXT_color_buffer_half_float")) {
66  LOG(ERROR) << "GL_EXT_color_buffer_half_float is not available";
67  if (half_float_supported) {
68  *half_float_supported = false;
69  }
70  }
71  return true;
72 }
73 
74 #if CAFFE2_IOS
75 int iPhoneVersion() {
76  static int version = 0;
77  static std::once_flag once;
78  std::call_once(once, [&]() {
79  struct utsname systemInfo;
80  uname(&systemInfo);
81  std::string iphone_ver_str = systemInfo.machine;
82  LOG(INFO) << systemInfo.machine;
83 
84  if (iphone_ver_str.find("iPhone") != std::string::npos) {
85  std::regex regStr("([0-9]+)");
86  std::smatch matchs;
87  if (std::regex_search(iphone_ver_str, matchs, regStr)) {
88  version = stoi(matchs[0]);
89  }
90  }
91  });
92  return version;
93 }
94 #endif
95 
96 #if CAFFE2_ANDROID
97 // whitelist of supported GPUs
98 bool isSupportedRenderer() {
99  static std::unordered_set<std::string> supported_renderers = {
100  "Adreno (TM) 540",
101  "Adreno (TM) 530",
102  "Adreno (TM) 510",
103  "Adreno (TM) 430",
104  "Adreno (TM) 418",
105  "Mali-G71",
106  "Mali-T880",
107  "NVIDIA Tegra"};
108  std::string rendererStr((const char*)glGetString(GL_RENDERER));
109  LOG(INFO) << "GL_RENDERER: " << rendererStr;
110 
111  int start = rendererStr.find_first_not_of(" ");
112  int end = rendererStr.find_last_not_of(" ");
113  rendererStr = rendererStr.substr(start, end - start + 1);
114  return supported_renderers.count(rendererStr) > 0;
115 }
116 #endif
117 
118 bool isSupportedDevice() {
119 #if CAFFE2_IOS
120  return iPhoneVersion() >= 7; // iPhone 6 and up
121 #elif CAFFE2_ANDROID
122  return isSupportedRenderer();
123 #else
124  return false;
125 #endif
126 }