blob: 8365a3183b19b81142e70097e96e6cbb013944d9 [file] [log] [blame]
Jamie Gennis9c183f22012-12-03 16:44:16 -08001/*
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
20namespace android {
21
22class Blitter {
23public:
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
99private:
100 GLuint mBlitPgm;
101 GLint mPosAttribLoc;
102 GLint mUVAttribLoc;
103 GLint mUVToTexUniformLoc;
104 GLint mObjToNdcUniformLoc;
105 GLint mBlitSrcSamplerLoc;
106 GLint mModColorUniformLoc;
107};
108
109class ComposerBase : public Composer {
110public:
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
126protected:
127 virtual bool setUp(GLHelper* helper) {
128 return true;
129 }
130
131 LayerDesc mLayerDesc;
132};
133
134Composer* nocomp() {
135 class NoComp : public ComposerBase {
136 };
137 return new NoComp();
138}
139
140Composer* 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
163Composer* 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
196Composer* 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
234Composer* 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