GLES20RenderEngine.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * Copyright 2013 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. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  17. #include <GLES2/gl2.h>
  18. #include <GLES2/gl2ext.h>
  19. #include <ui/Rect.h>
  20. #include <utils/String8.h>
  21. #include <utils/Trace.h>
  22. #include <cutils/compiler.h>
  23. #include <gui/ISurfaceComposer.h>
  24. #include <math.h>
  25. #include "GLES20RenderEngine.h"
  26. #include "Program.h"
  27. #include "ProgramCache.h"
  28. #include "Description.h"
  29. #include "Mesh.h"
  30. #include "Texture.h"
  31. // ---------------------------------------------------------------------------
  32. namespace android {
  33. // ---------------------------------------------------------------------------
  34. GLES20RenderEngine::GLES20RenderEngine() :
  35. mVpWidth(0), mVpHeight(0), mProjectionRotation(Transform::ROT_0) {
  36. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
  37. glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
  38. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  39. glPixelStorei(GL_PACK_ALIGNMENT, 4);
  40. const uint16_t protTexData[] = { 0 };
  41. glGenTextures(1, &mProtectedTexName);
  42. glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
  43. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  44. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  45. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  46. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  47. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
  48. GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
  49. //mColorBlindnessCorrection = M;
  50. }
  51. GLES20RenderEngine::~GLES20RenderEngine() {
  52. }
  53. size_t GLES20RenderEngine::getMaxTextureSize() const {
  54. return mMaxTextureSize;
  55. }
  56. size_t GLES20RenderEngine::getMaxViewportDims() const {
  57. return
  58. mMaxViewportDims[0] < mMaxViewportDims[1] ?
  59. mMaxViewportDims[0] : mMaxViewportDims[1];
  60. }
  61. void GLES20RenderEngine::setViewportAndProjection(
  62. size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
  63. Transform::orientation_flags rotation) {
  64. size_t l = sourceCrop.left;
  65. size_t r = sourceCrop.right;
  66. // In GL, (0, 0) is the bottom-left corner, so flip y coordinates
  67. size_t t = hwh - sourceCrop.top;
  68. size_t b = hwh - sourceCrop.bottom;
  69. mat4 m;
  70. if (yswap) {
  71. m = mat4::ortho(l, r, t, b, 0, 1);
  72. } else {
  73. m = mat4::ortho(l, r, b, t, 0, 1);
  74. }
  75. // Apply custom rotation to the projection.
  76. float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
  77. switch (rotation) {
  78. case Transform::ROT_0:
  79. break;
  80. case Transform::ROT_90:
  81. m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m;
  82. break;
  83. case Transform::ROT_180:
  84. m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m;
  85. break;
  86. case Transform::ROT_270:
  87. m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m;
  88. break;
  89. default:
  90. break;
  91. }
  92. glViewport(0, 0, vpw, vph);
  93. mState.setProjectionMatrix(m);
  94. mVpWidth = vpw;
  95. mVpHeight = vph;
  96. mProjectionSourceCrop = sourceCrop;
  97. mProjectionYSwap = yswap;
  98. mProjectionRotation = rotation;
  99. }
  100. void GLES20RenderEngine::setupLayerBlending(
  101. bool premultipliedAlpha, bool opaque, int alpha) {
  102. mState.setPremultipliedAlpha(premultipliedAlpha);
  103. mState.setOpaque(opaque);
  104. mState.setPlaneAlpha(alpha / 255.0f);
  105. if (alpha < 0xFF || !opaque) {
  106. glEnable(GL_BLEND);
  107. glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  108. } else {
  109. glDisable(GL_BLEND);
  110. }
  111. }
  112. void GLES20RenderEngine::setupDimLayerBlending(int alpha) {
  113. mState.setPlaneAlpha(1.0f);
  114. mState.setPremultipliedAlpha(true);
  115. mState.setOpaque(false);
  116. mState.setColor(0, 0, 0, alpha/255.0f);
  117. mState.disableTexture();
  118. if (alpha == 0xFF) {
  119. glDisable(GL_BLEND);
  120. } else {
  121. glEnable(GL_BLEND);
  122. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  123. }
  124. }
  125. void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) {
  126. GLuint target = texture.getTextureTarget();
  127. glBindTexture(target, texture.getTextureName());
  128. GLenum filter = GL_NEAREST;
  129. if (texture.getFiltering()) {
  130. filter = GL_LINEAR;
  131. }
  132. glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  133. glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  134. glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
  135. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
  136. mState.setTexture(texture);
  137. }
  138. void GLES20RenderEngine::setupLayerBlackedOut() {
  139. glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
  140. Texture texture(Texture::TEXTURE_2D, mProtectedTexName);
  141. texture.setDimensions(1, 1); // FIXME: we should get that from somewhere
  142. mState.setTexture(texture);
  143. }
  144. mat4 GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
  145. mat4 oldTransform = mState.getColorMatrix();
  146. mState.setColorMatrix(colorTransform);
  147. return oldTransform;
  148. }
  149. void GLES20RenderEngine::disableTexturing() {
  150. mState.disableTexture();
  151. }
  152. void GLES20RenderEngine::disableBlending() {
  153. glDisable(GL_BLEND);
  154. }
  155. void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
  156. uint32_t* texName, uint32_t* fbName, uint32_t* status,
  157. bool useReadPixels, int reqWidth, int reqHeight) {
  158. GLuint tname, name;
  159. if (!useReadPixels) {
  160. // turn our EGLImage into a texture
  161. glGenTextures(1, &tname);
  162. glBindTexture(GL_TEXTURE_2D, tname);
  163. glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
  164. // create a Framebuffer Object to render into
  165. glGenFramebuffers(1, &name);
  166. glBindFramebuffer(GL_FRAMEBUFFER, name);
  167. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
  168. } else {
  169. // since we're going to use glReadPixels() anyways,
  170. // use an intermediate renderbuffer instead
  171. glGenRenderbuffers(1, &tname);
  172. glBindRenderbuffer(GL_RENDERBUFFER, tname);
  173. glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, reqWidth, reqHeight);
  174. // create a FBO to render into
  175. glGenFramebuffers(1, &name);
  176. glBindFramebuffer(GL_FRAMEBUFFER, name);
  177. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, tname);
  178. }
  179. *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  180. *texName = tname;
  181. *fbName = name;
  182. }
  183. void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
  184. bool useReadPixels) {
  185. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  186. glDeleteFramebuffers(1, &fbName);
  187. if (!useReadPixels)
  188. glDeleteTextures(1, &texName);
  189. else
  190. glDeleteRenderbuffers(1, &texName);
  191. }
  192. void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
  193. mState.setPlaneAlpha(1.0f);
  194. mState.setPremultipliedAlpha(true);
  195. mState.setOpaque(false);
  196. mState.setColor(r, g, b, a);
  197. mState.disableTexture();
  198. glDisable(GL_BLEND);
  199. }
  200. void GLES20RenderEngine::drawMesh(const Mesh& mesh) {
  201. ProgramCache::getInstance().useProgram(mState);
  202. if (mesh.getTexCoordsSize()) {
  203. glEnableVertexAttribArray(Program::texCoords);
  204. glVertexAttribPointer(Program::texCoords,
  205. mesh.getTexCoordsSize(),
  206. GL_FLOAT, GL_FALSE,
  207. mesh.getByteStride(),
  208. mesh.getTexCoords());
  209. }
  210. glVertexAttribPointer(Program::position,
  211. mesh.getVertexSize(),
  212. GL_FLOAT, GL_FALSE,
  213. mesh.getByteStride(),
  214. mesh.getPositions());
  215. glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
  216. if (mesh.getTexCoordsSize()) {
  217. glDisableVertexAttribArray(Program::texCoords);
  218. }
  219. }
  220. void GLES20RenderEngine::dump(String8& result) {
  221. RenderEngine::dump(result);
  222. }
  223. void GLES20RenderEngine::setupLayerMasking(const Texture& maskTexture, float alphaThreshold) {
  224. glActiveTexture(GL_TEXTURE0 + 1);
  225. GLuint target = maskTexture.getTextureTarget();
  226. glBindTexture(target, maskTexture.getTextureName());
  227. GLenum filter = GL_NEAREST;
  228. if (maskTexture.getFiltering()) {
  229. filter = GL_LINEAR;
  230. }
  231. glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  232. glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  233. glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
  234. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
  235. if (alphaThreshold < 0) alphaThreshold = 0;
  236. if (alphaThreshold > 1.0f) alphaThreshold = 1.0f;
  237. mState.setMasking(maskTexture, alphaThreshold);
  238. glActiveTexture(GL_TEXTURE0);
  239. }
  240. void GLES20RenderEngine::disableLayerMasking() {
  241. mState.disableMasking();
  242. }
  243. // ---------------------------------------------------------------------------
  244. }; // namespace android
  245. // ---------------------------------------------------------------------------
  246. #if defined(__gl_h_)
  247. #error "don't include gl/gl.h in this file"
  248. #endif