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
23 namespace android {
24
25 class Blitter {
26 public:
27
setUp(GLHelper * helper)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
blit(GLuint texName,const float * texMatrix,int32_t x,int32_t y,uint32_t w,uint32_t h)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
modBlit(GLuint texName,const float * texMatrix,float * modColor,int32_t x,int32_t y,uint32_t w,uint32_t h)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
102 private:
103 GLuint mBlitPgm;
104 GLint mPosAttribLoc;
105 GLint mUVAttribLoc;
106 GLint mUVToTexUniformLoc;
107 GLint mObjToNdcUniformLoc;
108 GLint mBlitSrcSamplerLoc;
109 GLint mModColorUniformLoc;
110 };
111
112 class ComposerBase : public Composer {
113 public:
~ComposerBase()114 virtual ~ComposerBase() {}
115
setUp(const LayerDesc & desc,GLHelper * helper)116 virtual bool setUp(const LayerDesc& desc,
117 GLHelper* helper) {
118 mLayerDesc = desc;
119 return setUp(helper);
120 }
121
tearDown()122 virtual void tearDown() {
123 }
124
compose(GLuint,const sp<GLConsumer> &)125 virtual bool compose(GLuint /*texName*/, const sp<GLConsumer>& /*glc*/) {
126 return true;
127 }
128
129 protected:
setUp(GLHelper *)130 virtual bool setUp(GLHelper* /*helper*/) {
131 return true;
132 }
133
134 LayerDesc mLayerDesc;
135 };
136
nocomp()137 Composer* nocomp() {
138 class NoComp : public ComposerBase {
139 };
140 return new NoComp();
141 }
142
opaque()143 Composer* 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
opaqueShrink()166 Composer* 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
blend()199 Composer* 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
blendShrink()237 Composer* 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