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