283 lines
7.6 KiB
C++
283 lines
7.6 KiB
C++
|
/*
|
||
|
* 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
|