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