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