GLHelper.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <GLES2/gl2.h>
  17. #include <GLES2/gl2ext.h>
  18. #include <ui/DisplayInfo.h>
  19. #include <gui/SurfaceComposerClient.h>
  20. #include "GLHelper.h"
  21. namespace android {
  22. GLHelper::GLHelper() :
  23. mGraphicBufferAlloc(new GraphicBufferAlloc()),
  24. mDisplay(EGL_NO_DISPLAY),
  25. mContext(EGL_NO_CONTEXT),
  26. mDummySurface(EGL_NO_SURFACE),
  27. mConfig(0),
  28. mShaderPrograms(NULL),
  29. mDitherTexture(0) {
  30. }
  31. GLHelper::~GLHelper() {
  32. }
  33. bool GLHelper::setUp(const ShaderDesc* shaderDescs, size_t numShaders) {
  34. bool result;
  35. mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  36. if (mDisplay == EGL_NO_DISPLAY) {
  37. fprintf(stderr, "eglGetDisplay error: %#x\n", eglGetError());
  38. return false;
  39. }
  40. EGLint majorVersion;
  41. EGLint minorVersion;
  42. result = eglInitialize(mDisplay, &majorVersion, &minorVersion);
  43. if (result != EGL_TRUE) {
  44. fprintf(stderr, "eglInitialize error: %#x\n", eglGetError());
  45. return false;
  46. }
  47. EGLint numConfigs = 0;
  48. EGLint configAttribs[] = {
  49. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  50. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  51. EGL_RED_SIZE, 8,
  52. EGL_GREEN_SIZE, 8,
  53. EGL_BLUE_SIZE, 8,
  54. EGL_ALPHA_SIZE, 8,
  55. EGL_NONE
  56. };
  57. result = eglChooseConfig(mDisplay, configAttribs, &mConfig, 1,
  58. &numConfigs);
  59. if (result != EGL_TRUE) {
  60. fprintf(stderr, "eglChooseConfig error: %#x\n", eglGetError());
  61. return false;
  62. }
  63. EGLint contextAttribs[] = {
  64. EGL_CONTEXT_CLIENT_VERSION, 2,
  65. EGL_NONE
  66. };
  67. mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT,
  68. contextAttribs);
  69. if (mContext == EGL_NO_CONTEXT) {
  70. fprintf(stderr, "eglCreateContext error: %#x\n", eglGetError());
  71. return false;
  72. }
  73. bool resultb = createNamedSurfaceTexture(0, 1, 1, &mDummyGLConsumer,
  74. &mDummySurface);
  75. if (!resultb) {
  76. return false;
  77. }
  78. resultb = makeCurrent(mDummySurface);
  79. if (!resultb) {
  80. return false;
  81. }
  82. resultb = setUpShaders(shaderDescs, numShaders);
  83. if (!resultb) {
  84. return false;
  85. }
  86. return true;
  87. }
  88. void GLHelper::tearDown() {
  89. if (mShaderPrograms != NULL) {
  90. delete[] mShaderPrograms;
  91. mShaderPrograms = NULL;
  92. }
  93. if (mSurfaceComposerClient != NULL) {
  94. mSurfaceComposerClient->dispose();
  95. mSurfaceComposerClient.clear();
  96. }
  97. if (mDisplay != EGL_NO_DISPLAY) {
  98. eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
  99. EGL_NO_CONTEXT);
  100. }
  101. if (mContext != EGL_NO_CONTEXT) {
  102. eglDestroyContext(mDisplay, mContext);
  103. }
  104. if (mDummySurface != EGL_NO_SURFACE) {
  105. eglDestroySurface(mDisplay, mDummySurface);
  106. }
  107. mDisplay = EGL_NO_DISPLAY;
  108. mContext = EGL_NO_CONTEXT;
  109. mDummySurface = EGL_NO_SURFACE;
  110. mDummyGLConsumer.clear();
  111. mConfig = 0;
  112. }
  113. bool GLHelper::makeCurrent(EGLSurface surface) {
  114. EGLint result;
  115. result = eglMakeCurrent(mDisplay, surface, surface, mContext);
  116. if (result != EGL_TRUE) {
  117. fprintf(stderr, "eglMakeCurrent error: %#x\n", eglGetError());
  118. return false;
  119. }
  120. EGLint w, h;
  121. eglQuerySurface(mDisplay, surface, EGL_WIDTH, &w);
  122. eglQuerySurface(mDisplay, surface, EGL_HEIGHT, &h);
  123. glViewport(0, 0, w, h);
  124. return true;
  125. }
  126. bool GLHelper::createSurfaceTexture(uint32_t w, uint32_t h,
  127. sp<GLConsumer>* glConsumer, EGLSurface* surface,
  128. GLuint* name) {
  129. if (!makeCurrent(mDummySurface)) {
  130. return false;
  131. }
  132. *name = 0;
  133. glGenTextures(1, name);
  134. if (*name == 0) {
  135. fprintf(stderr, "glGenTextures error: %#x\n", glGetError());
  136. return false;
  137. }
  138. return createNamedSurfaceTexture(*name, w, h, glConsumer, surface);
  139. }
  140. void GLHelper::destroySurface(EGLSurface* surface) {
  141. if (eglGetCurrentSurface(EGL_READ) == *surface ||
  142. eglGetCurrentSurface(EGL_DRAW) == *surface) {
  143. eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
  144. EGL_NO_CONTEXT);
  145. }
  146. eglDestroySurface(mDisplay, *surface);
  147. *surface = EGL_NO_SURFACE;
  148. }
  149. bool GLHelper::swapBuffers(EGLSurface surface) {
  150. EGLint result;
  151. result = eglSwapBuffers(mDisplay, surface);
  152. if (result != EGL_TRUE) {
  153. fprintf(stderr, "eglSwapBuffers error: %#x\n", eglGetError());
  154. return false;
  155. }
  156. return true;
  157. }
  158. bool GLHelper::getShaderProgram(const char* name, GLuint* outPgm) {
  159. for (size_t i = 0; i < mNumShaders; i++) {
  160. if (strcmp(mShaderDescs[i].name, name) == 0) {
  161. *outPgm = mShaderPrograms[i];
  162. return true;
  163. }
  164. }
  165. fprintf(stderr, "unknown shader name: \"%s\"\n", name);
  166. return false;
  167. }
  168. bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h,
  169. sp<GLConsumer>* glConsumer, EGLSurface* surface) {
  170. sp<IGraphicBufferProducer> producer;
  171. sp<IGraphicBufferConsumer> consumer;
  172. BufferQueue::createBufferQueue(&producer, &consumer, mGraphicBufferAlloc);
  173. sp<GLConsumer> glc = new GLConsumer(consumer, name,
  174. GL_TEXTURE_EXTERNAL_OES, false, true);
  175. glc->setDefaultBufferSize(w, h);
  176. glc->setDefaultMaxBufferCount(3);
  177. glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
  178. sp<ANativeWindow> anw = new Surface(producer);
  179. EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL);
  180. if (s == EGL_NO_SURFACE) {
  181. fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
  182. return false;
  183. }
  184. *glConsumer = glc;
  185. *surface = s;
  186. return true;
  187. }
  188. bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) {
  189. sp<IBinder> dpy = mSurfaceComposerClient->getBuiltInDisplay(0);
  190. if (dpy == NULL) {
  191. fprintf(stderr, "SurfaceComposer::getBuiltInDisplay failed.\n");
  192. return false;
  193. }
  194. DisplayInfo info;
  195. status_t err = mSurfaceComposerClient->getDisplayInfo(dpy, &info);
  196. if (err != NO_ERROR) {
  197. fprintf(stderr, "SurfaceComposer::getDisplayInfo failed: %#x\n", err);
  198. return false;
  199. }
  200. float scaleX = float(info.w) / float(w);
  201. float scaleY = float(info.h) / float(h);
  202. *scale = scaleX < scaleY ? scaleX : scaleY;
  203. return true;
  204. }
  205. bool GLHelper::createWindowSurface(uint32_t w, uint32_t h,
  206. sp<SurfaceControl>* surfaceControl, EGLSurface* surface) {
  207. bool result;
  208. status_t err;
  209. if (mSurfaceComposerClient == NULL) {
  210. mSurfaceComposerClient = new SurfaceComposerClient;
  211. }
  212. err = mSurfaceComposerClient->initCheck();
  213. if (err != NO_ERROR) {
  214. fprintf(stderr, "SurfaceComposerClient::initCheck error: %#x\n", err);
  215. return false;
  216. }
  217. sp<SurfaceControl> sc = mSurfaceComposerClient->createSurface(
  218. String8("Benchmark"), w, h, PIXEL_FORMAT_RGBA_8888, 0);
  219. if (sc == NULL || !sc->isValid()) {
  220. fprintf(stderr, "Failed to create SurfaceControl.\n");
  221. return false;
  222. }
  223. float scale;
  224. result = computeWindowScale(w, h, &scale);
  225. if (!result) {
  226. return false;
  227. }
  228. SurfaceComposerClient::openGlobalTransaction();
  229. err = sc->setLayer(0x7FFFFFFF);
  230. if (err != NO_ERROR) {
  231. fprintf(stderr, "SurfaceComposer::setLayer error: %#x\n", err);
  232. return false;
  233. }
  234. err = sc->setMatrix(scale, 0.0f, 0.0f, scale);
  235. if (err != NO_ERROR) {
  236. fprintf(stderr, "SurfaceComposer::setMatrix error: %#x\n", err);
  237. return false;
  238. }
  239. err = sc->show();
  240. if (err != NO_ERROR) {
  241. fprintf(stderr, "SurfaceComposer::show error: %#x\n", err);
  242. return false;
  243. }
  244. SurfaceComposerClient::closeGlobalTransaction();
  245. sp<ANativeWindow> anw = sc->getSurface();
  246. EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL);
  247. if (s == EGL_NO_SURFACE) {
  248. fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError());
  249. return false;
  250. }
  251. *surfaceControl = sc;
  252. *surface = s;
  253. return true;
  254. }
  255. static bool compileShader(GLenum shaderType, const char* src,
  256. GLuint* outShader) {
  257. GLuint shader = glCreateShader(shaderType);
  258. if (shader == 0) {
  259. fprintf(stderr, "glCreateShader error: %#x\n", glGetError());
  260. return false;
  261. }
  262. glShaderSource(shader, 1, &src, NULL);
  263. glCompileShader(shader);
  264. GLint compiled = 0;
  265. glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  266. if (!compiled) {
  267. GLint infoLen = 0;
  268. glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
  269. if (infoLen) {
  270. char* buf = new char[infoLen];
  271. if (buf) {
  272. glGetShaderInfoLog(shader, infoLen, NULL, buf);
  273. fprintf(stderr, "Shader compile log:\n%s\n", buf);
  274. delete[] buf;
  275. }
  276. }
  277. glDeleteShader(shader);
  278. return false;
  279. }
  280. *outShader = shader;
  281. return true;
  282. }
  283. static void printShaderSource(const char* const* src) {
  284. for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) {
  285. fprintf(stderr, "%3zu: %s\n", i+1, src[i]);
  286. }
  287. }
  288. static const char* makeShaderString(const char* const* src) {
  289. size_t len = 0;
  290. for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) {
  291. // The +1 is for the '\n' that will be added.
  292. len += strlen(src[i]) + 1;
  293. }
  294. char* result = new char[len+1];
  295. char* end = result;
  296. for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) {
  297. strcpy(end, src[i]);
  298. end += strlen(src[i]);
  299. *end = '\n';
  300. end++;
  301. }
  302. *end = '\0';
  303. return result;
  304. }
  305. static bool compileShaderLines(GLenum shaderType, const char* const* lines,
  306. GLuint* outShader) {
  307. const char* src = makeShaderString(lines);
  308. bool result = compileShader(shaderType, src, outShader);
  309. if (!result) {
  310. fprintf(stderr, "Shader source:\n");
  311. printShaderSource(lines);
  312. return false;
  313. }
  314. delete[] src;
  315. return true;
  316. }
  317. static bool linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm) {
  318. GLuint program = glCreateProgram();
  319. if (program == 0) {
  320. fprintf(stderr, "glCreateProgram error: %#x\n", glGetError());
  321. return false;
  322. }
  323. glAttachShader(program, vs);
  324. glAttachShader(program, fs);
  325. glLinkProgram(program);
  326. GLint linkStatus = GL_FALSE;
  327. glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
  328. if (linkStatus != GL_TRUE) {
  329. GLint bufLength = 0;
  330. glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
  331. if (bufLength) {
  332. char* buf = new char[bufLength];
  333. if (buf) {
  334. glGetProgramInfoLog(program, bufLength, NULL, buf);
  335. fprintf(stderr, "Program link log:\n%s\n", buf);
  336. delete[] buf;
  337. }
  338. }
  339. glDeleteProgram(program);
  340. program = 0;
  341. }
  342. *outPgm = program;
  343. return program != 0;
  344. }
  345. bool GLHelper::setUpShaders(const ShaderDesc* shaderDescs, size_t numShaders) {
  346. mShaderPrograms = new GLuint[numShaders];
  347. bool result = true;
  348. for (size_t i = 0; i < numShaders && result; i++) {
  349. GLuint vs, fs;
  350. result = compileShaderLines(GL_VERTEX_SHADER,
  351. shaderDescs[i].vertexShader, &vs);
  352. if (!result) {
  353. return false;
  354. }
  355. result = compileShaderLines(GL_FRAGMENT_SHADER,
  356. shaderDescs[i].fragmentShader, &fs);
  357. if (!result) {
  358. glDeleteShader(vs);
  359. return false;
  360. }
  361. result = linkShaderProgram(vs, fs, &mShaderPrograms[i]);
  362. glDeleteShader(vs);
  363. glDeleteShader(fs);
  364. }
  365. mNumShaders = numShaders;
  366. mShaderDescs = shaderDescs;
  367. return result;
  368. }
  369. bool GLHelper::getDitherTexture(GLuint* outTexName) {
  370. if (mDitherTexture == 0) {
  371. const uint8_t pattern[] = {
  372. 0, 8, 2, 10,
  373. 12, 4, 14, 6,
  374. 3, 11, 1, 9,
  375. 15, 7, 13, 5
  376. };
  377. glGenTextures(1, &mDitherTexture);
  378. glBindTexture(GL_TEXTURE_2D, mDitherTexture);
  379. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  380. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  381. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  382. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  383. glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE,
  384. DITHER_KERNEL_SIZE, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &pattern);
  385. }
  386. *outTexName = mDitherTexture;
  387. return true;
  388. }
  389. }