diff options
Diffstat (limited to 'cmds/flatland/Composers.cpp')
-rw-r--r-- | cmds/flatland/Composers.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/cmds/flatland/Composers.cpp b/cmds/flatland/Composers.cpp new file mode 100644 index 0000000..8365a31 --- /dev/null +++ b/cmds/flatland/Composers.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Flatland.h" +#include "GLHelper.h" + +namespace android { + +class Blitter { +public: + + bool setUp(GLHelper* helper) { + bool result; + + result = helper->getShaderProgram("Blit", &mBlitPgm); + if (!result) { + return false; + } + + mPosAttribLoc = glGetAttribLocation(mBlitPgm, "position"); + mUVAttribLoc = glGetAttribLocation(mBlitPgm, "uv"); + mUVToTexUniformLoc = glGetUniformLocation(mBlitPgm, "uvToTex"); + mObjToNdcUniformLoc = glGetUniformLocation(mBlitPgm, "objToNdc"); + mBlitSrcSamplerLoc = glGetUniformLocation(mBlitPgm, "blitSrc"); + mModColorUniformLoc = glGetUniformLocation(mBlitPgm, "modColor"); + + return true; + } + + bool blit(GLuint texName, const float* texMatrix, + int32_t x, int32_t y, uint32_t w, uint32_t h) { + float modColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + return modBlit(texName, texMatrix, modColor, x, y, w, h); + } + + bool modBlit(GLuint texName, const float* texMatrix, float* modColor, + int32_t x, int32_t y, uint32_t w, uint32_t h) { + glUseProgram(mBlitPgm); + + GLint vp[4]; + glGetIntegerv(GL_VIEWPORT, vp); + float screenToNdc[16] = { + 2.0f/float(vp[2]), 0.0f, 0.0f, 0.0f, + 0.0f, -2.0f/float(vp[3]), 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + }; + const float pos[] = { + float(x), float(y), + float(x+w), float(y), + float(x), float(y+h), + float(x+w), float(y+h), + }; + const float uv[] = { + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, + }; + + glVertexAttribPointer(mPosAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, pos); + glVertexAttribPointer(mUVAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, uv); + glEnableVertexAttribArray(mPosAttribLoc); + glEnableVertexAttribArray(mUVAttribLoc); + + glUniformMatrix4fv(mObjToNdcUniformLoc, 1, GL_FALSE, screenToNdc); + glUniformMatrix4fv(mUVToTexUniformLoc, 1, GL_FALSE, texMatrix); + glUniform4fv(mModColorUniformLoc, 1, modColor); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texName); + glUniform1i(mBlitSrcSamplerLoc, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(mPosAttribLoc); + glDisableVertexAttribArray(mUVAttribLoc); + + if (glGetError() != GL_NO_ERROR) { + fprintf(stderr, "GL error!\n"); + } + + return true; + } + +private: + GLuint mBlitPgm; + GLint mPosAttribLoc; + GLint mUVAttribLoc; + GLint mUVToTexUniformLoc; + GLint mObjToNdcUniformLoc; + GLint mBlitSrcSamplerLoc; + GLint mModColorUniformLoc; +}; + +class ComposerBase : public Composer { +public: + virtual ~ComposerBase() {} + + virtual bool setUp(const LayerDesc& desc, + GLHelper* helper) { + mLayerDesc = desc; + return setUp(helper); + } + + virtual void tearDown() { + } + + virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { + return true; + } + +protected: + virtual bool setUp(GLHelper* helper) { + return true; + } + + LayerDesc mLayerDesc; +}; + +Composer* nocomp() { + class NoComp : public ComposerBase { + }; + return new NoComp(); +} + +Composer* opaque() { + class OpaqueComp : public ComposerBase { + virtual bool setUp(GLHelper* helper) { + return mBlitter.setUp(helper); + } + + virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { + float texMatrix[16]; + glc->getTransformMatrix(texMatrix); + + int32_t x = mLayerDesc.x; + int32_t y = mLayerDesc.y; + int32_t w = mLayerDesc.width; + int32_t h = mLayerDesc.height; + + return mBlitter.blit(texName, texMatrix, x, y, w, h); + } + + Blitter mBlitter; + }; + return new OpaqueComp(); +} + +Composer* opaqueShrink() { + class OpaqueComp : public ComposerBase { + virtual bool setUp(GLHelper* helper) { + mParity = false; + return mBlitter.setUp(helper); + } + + virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { + float texMatrix[16]; + glc->getTransformMatrix(texMatrix); + + int32_t x = mLayerDesc.x; + int32_t y = mLayerDesc.y; + int32_t w = mLayerDesc.width; + int32_t h = mLayerDesc.height; + + mParity = !mParity; + if (mParity) { + x += w / 128; + y += h / 128; + w -= w / 64; + h -= h / 64; + } + + return mBlitter.blit(texName, texMatrix, x, y, w, h); + } + + Blitter mBlitter; + bool mParity; + }; + return new OpaqueComp(); +} + +Composer* blend() { + class BlendComp : public ComposerBase { + virtual bool setUp(GLHelper* helper) { + return mBlitter.setUp(helper); + } + + virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { + bool result; + + float texMatrix[16]; + glc->getTransformMatrix(texMatrix); + + float modColor[4] = { .75f, .75f, .75f, .75f }; + + int32_t x = mLayerDesc.x; + int32_t y = mLayerDesc.y; + int32_t w = mLayerDesc.width; + int32_t h = mLayerDesc.height; + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + result = mBlitter.modBlit(texName, texMatrix, modColor, + x, y, w, h); + if (!result) { + return false; + } + + glDisable(GL_BLEND); + + return true; + } + + Blitter mBlitter; + }; + return new BlendComp(); +} + +Composer* blendShrink() { + class BlendShrinkComp : public ComposerBase { + virtual bool setUp(GLHelper* helper) { + mParity = false; + return mBlitter.setUp(helper); + } + + virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) { + bool result; + + float texMatrix[16]; + glc->getTransformMatrix(texMatrix); + + float modColor[4] = { .75f, .75f, .75f, .75f }; + + int32_t x = mLayerDesc.x; + int32_t y = mLayerDesc.y; + int32_t w = mLayerDesc.width; + int32_t h = mLayerDesc.height; + + mParity = !mParity; + if (mParity) { + x += w / 128; + y += h / 128; + w -= w / 64; + h -= h / 64; + } + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + result = mBlitter.modBlit(texName, texMatrix, modColor, + x, y, w, h); + if (!result) { + return false; + } + + glDisable(GL_BLEND); + + return true; + } + + Blitter mBlitter; + bool mParity; + }; + return new BlendShrinkComp(); +} + +} // namespace android |