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