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 17#include <GLES2/gl2.h> 18#include <GLES2/gl2ext.h> 19 20#include "Flatland.h" 21#include "GLHelper.h" 22 23namespace android { 24 25class Blitter { 26public: 27 28 bool setUp(GLHelper* helper) { 29 bool result; 30 31 result = helper->getShaderProgram("Blit", &mBlitPgm); 32 if (!result) { 33 return false; 34 } 35 36 mPosAttribLoc = glGetAttribLocation(mBlitPgm, "position"); 37 mUVAttribLoc = glGetAttribLocation(mBlitPgm, "uv"); 38 mUVToTexUniformLoc = glGetUniformLocation(mBlitPgm, "uvToTex"); 39 mObjToNdcUniformLoc = glGetUniformLocation(mBlitPgm, "objToNdc"); 40 mBlitSrcSamplerLoc = glGetUniformLocation(mBlitPgm, "blitSrc"); 41 mModColorUniformLoc = glGetUniformLocation(mBlitPgm, "modColor"); 42 43 return true; 44 } 45 46 bool blit(GLuint texName, const float* texMatrix, 47 int32_t x, int32_t y, uint32_t w, uint32_t h) { 48 float modColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; 49 return modBlit(texName, texMatrix, modColor, x, y, w, h); 50 } 51 52 bool modBlit(GLuint texName, const float* texMatrix, float* modColor, 53 int32_t x, int32_t y, uint32_t w, uint32_t h) { 54 glUseProgram(mBlitPgm); 55 56 GLint vp[4]; 57 glGetIntegerv(GL_VIEWPORT, vp); 58 float screenToNdc[16] = { 59 2.0f/float(vp[2]), 0.0f, 0.0f, 0.0f, 60 0.0f, -2.0f/float(vp[3]), 0.0f, 0.0f, 61 0.0f, 0.0f, 1.0f, 0.0f, 62 -1.0f, 1.0f, 0.0f, 1.0f, 63 }; 64 const float pos[] = { 65 float(x), float(y), 66 float(x+w), float(y), 67 float(x), float(y+h), 68 float(x+w), float(y+h), 69 }; 70 const float uv[] = { 71 0.0f, 0.0f, 72 1.0f, 0.0f, 73 0.0f, 1.0f, 74 1.0f, 1.0f, 75 }; 76 77 glVertexAttribPointer(mPosAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, pos); 78 glVertexAttribPointer(mUVAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, uv); 79 glEnableVertexAttribArray(mPosAttribLoc); 80 glEnableVertexAttribArray(mUVAttribLoc); 81 82 glUniformMatrix4fv(mObjToNdcUniformLoc, 1, GL_FALSE, screenToNdc); 83 glUniformMatrix4fv(mUVToTexUniformLoc, 1, GL_FALSE, texMatrix); 84 glUniform4fv(mModColorUniformLoc, 1, modColor); 85 86 glActiveTexture(GL_TEXTURE0); 87 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texName); 88 glUniform1i(mBlitSrcSamplerLoc, 0); 89 90 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 91 92 glDisableVertexAttribArray(mPosAttribLoc); 93 glDisableVertexAttribArray(mUVAttribLoc); 94 95 if (glGetError() != GL_NO_ERROR) { 96 fprintf(stderr, "GL error!\n"); 97 } 98 99 return true; 100 } 101 102private: 103 GLuint mBlitPgm; 104 GLint mPosAttribLoc; 105 GLint mUVAttribLoc; 106 GLint mUVToTexUniformLoc; 107 GLint mObjToNdcUniformLoc; 108 GLint mBlitSrcSamplerLoc; 109 GLint mModColorUniformLoc; 110}; 111 112class ComposerBase : public Composer { 113public: 114 virtual ~ComposerBase() {} 115 116 virtual bool setUp(const LayerDesc& desc, 117 GLHelper* helper) { 118 mLayerDesc = desc; 119 return setUp(helper); 120 } 121 122 virtual void tearDown() { 123 } 124 125 virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { 126 return true; 127 } 128 129protected: 130 virtual bool setUp(GLHelper* helper) { 131 return true; 132 } 133 134 LayerDesc mLayerDesc; 135}; 136 137Composer* nocomp() { 138 class NoComp : public ComposerBase { 139 }; 140 return new NoComp(); 141} 142 143Composer* opaque() { 144 class OpaqueComp : public ComposerBase { 145 virtual bool setUp(GLHelper* helper) { 146 return mBlitter.setUp(helper); 147 } 148 149 virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { 150 float texMatrix[16]; 151 glc->getTransformMatrix(texMatrix); 152 153 int32_t x = mLayerDesc.x; 154 int32_t y = mLayerDesc.y; 155 int32_t w = mLayerDesc.width; 156 int32_t h = mLayerDesc.height; 157 158 return mBlitter.blit(texName, texMatrix, x, y, w, h); 159 } 160 161 Blitter mBlitter; 162 }; 163 return new OpaqueComp(); 164} 165 166Composer* opaqueShrink() { 167 class OpaqueComp : public ComposerBase { 168 virtual bool setUp(GLHelper* helper) { 169 mParity = false; 170 return mBlitter.setUp(helper); 171 } 172 173 virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { 174 float texMatrix[16]; 175 glc->getTransformMatrix(texMatrix); 176 177 int32_t x = mLayerDesc.x; 178 int32_t y = mLayerDesc.y; 179 int32_t w = mLayerDesc.width; 180 int32_t h = mLayerDesc.height; 181 182 mParity = !mParity; 183 if (mParity) { 184 x += w / 128; 185 y += h / 128; 186 w -= w / 64; 187 h -= h / 64; 188 } 189 190 return mBlitter.blit(texName, texMatrix, x, y, w, h); 191 } 192 193 Blitter mBlitter; 194 bool mParity; 195 }; 196 return new OpaqueComp(); 197} 198 199Composer* blend() { 200 class BlendComp : public ComposerBase { 201 virtual bool setUp(GLHelper* helper) { 202 return mBlitter.setUp(helper); 203 } 204 205 virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { 206 bool result; 207 208 float texMatrix[16]; 209 glc->getTransformMatrix(texMatrix); 210 211 float modColor[4] = { .75f, .75f, .75f, .75f }; 212 213 int32_t x = mLayerDesc.x; 214 int32_t y = mLayerDesc.y; 215 int32_t w = mLayerDesc.width; 216 int32_t h = mLayerDesc.height; 217 218 glEnable(GL_BLEND); 219 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 220 221 result = mBlitter.modBlit(texName, texMatrix, modColor, 222 x, y, w, h); 223 if (!result) { 224 return false; 225 } 226 227 glDisable(GL_BLEND); 228 229 return true; 230 } 231 232 Blitter mBlitter; 233 }; 234 return new BlendComp(); 235} 236 237Composer* blendShrink() { 238 class BlendShrinkComp : public ComposerBase { 239 virtual bool setUp(GLHelper* helper) { 240 mParity = false; 241 return mBlitter.setUp(helper); 242 } 243 244 virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { 245 bool result; 246 247 float texMatrix[16]; 248 glc->getTransformMatrix(texMatrix); 249 250 float modColor[4] = { .75f, .75f, .75f, .75f }; 251 252 int32_t x = mLayerDesc.x; 253 int32_t y = mLayerDesc.y; 254 int32_t w = mLayerDesc.width; 255 int32_t h = mLayerDesc.height; 256 257 mParity = !mParity; 258 if (mParity) { 259 x += w / 128; 260 y += h / 128; 261 w -= w / 64; 262 h -= h / 64; 263 } 264 265 glEnable(GL_BLEND); 266 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 267 268 result = mBlitter.modBlit(texName, texMatrix, modColor, 269 x, y, w, h); 270 if (!result) { 271 return false; 272 } 273 274 glDisable(GL_BLEND); 275 276 return true; 277 } 278 279 Blitter mBlitter; 280 bool mParity; 281 }; 282 return new BlendShrinkComp(); 283} 284 285} // namespace android 286