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 <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 
     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 
     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 
     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:
    114     virtual ~ComposerBase() {}
    115 
    116     virtual bool setUp(const LayerDesc& desc,
    117             GLHelper* helper) {
    118         mLayerDesc = desc;
    119         return setUp(helper);
    120     }
    121 
    122     virtual void tearDown() {
    123     }
    124 
    125     virtual bool compose(GLuint /*texName*/, const sp<GLConsumer>& /*glc*/) {
    126         return true;
    127     }
    128 
    129 protected:
    130     virtual bool setUp(GLHelper* /*helper*/) {
    131         return true;
    132     }
    133 
    134     LayerDesc mLayerDesc;
    135 };
    136 
    137 Composer* nocomp() {
    138     class NoComp : public ComposerBase {
    139     };
    140     return new NoComp();
    141 }
    142 
    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 
    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 
    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 
    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