Home | History | Annotate | Download | only in flatland
      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