当我向相机添加滤镜时,fps太低。普通滤镜适合30 fps。 当我添加模糊滤镜时,某些测试手机的fps为10-20 fps。但是,在某些手机上,fps会低于10。 如果您查看源代码并让我知道在哪里修复它,我将不胜感激。
public class InstaFilter extends GPUImageFilter {
protected static final String VERTEX_SHADER = "attribute vec4 position;\n" +
" attribute vec4 inputTextureCoordinate;\n" +
" \n" +
" varying vec2 textureCoordinate;\n" +
" \n" +
" void main()\n" +
" {\n" +
" gl_Position = position;\n" +
" textureCoordinate = inputTextureCoordinate.xy;\n" +
" }\n";
protected int [] GL_TEXTURES = { GLES20.GL_TEXTURE3, GLES20.GL_TEXTURE4, GLES20.GL_TEXTURE5,
GLES20.GL_TEXTURE6, GLES20.GL_TEXTURE7, GLES20.GL_TEXTURE8 };
protected int textureNum; //MAX 6
protected int [] coordinateAttributes;
protected int [] inputTextureUniforms;
protected int [] sourceTextures;
protected ByteBuffer[] coordinatesBuffers;
protected Bitmap[] bitmaps;
ByteBuffer bBuffer;
FloatBuffer fBuffer;
float[] buffer;
public InstaFilter(String fragmentShader, int textures) {
this(VERTEX_SHADER, fragmentShader, textures);
}
public InstaFilter(String vertexShader, String fragmentShader, int textures) {
super(vertexShader, fragmentShader);
textureNum = textures;
coordinateAttributes = new int[textureNum];
inputTextureUniforms = new int[textureNum];
sourceTextures = new int[textureNum];
for (int i = 0; i < textureNum; i++) {
sourceTextures[i] = OpenGlUtils.NO_TEXTURE;
}
coordinatesBuffers = new ByteBuffer[textureNum];
bitmaps = new Bitmap[textureNum];
setRotation(Rotation.NORMAL, false, false);
}
public void setRotation(final Rotation rotation, final boolean flipHorizontal, final boolean flipVertical) {
float[] buffer = TextureRotationUtil.getRotation(rotation, flipHorizontal, flipVertical);
if(bBuffer == null){
bBuffer = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder());
}
if(fBuffer == null){
fBuffer = bBuffer.asFloatBuffer();
}
fBuffer.put(buffer);
fBuffer.flip();
for (int i = 0; i < textureNum; i++) {
coordinatesBuffers[i] = bBuffer;
}
}
@Override
public void onInit() {
super.onInit();
Log.d("InstaFilter", "onInit()");
int k;
for (int i = 0; i < textureNum; i++) {
k = i + 2;
coordinateAttributes[i] = GLES20.glGetAttribLocation(getProgram(), String.format("inputTextureCoordinate%d", k));
inputTextureUniforms[i] = GLES20.glGetUniformLocation(getProgram(), String.format("inputImageTexture%d", k));
GLES20.glEnableVertexAttribArray(coordinateAttributes[i]);
if (bitmaps[i] != null && !bitmaps[i].isRecycled()) {
loadBitmap(i, bitmaps[i]);
}
}
}
public void onDestroy() {
super.onDestroy();
if (textureNum > 0) {
try{
GLES20.glDeleteTextures(1, sourceTextures, 0);
for (int i = 0; i < textureNum; i++) {
sourceTextures[i] = OpenGlUtils.NO_TEXTURE;
if (bitmaps[i] != null && !bitmaps[i].isRecycled()) {
bitmaps[i].recycle();
bitmaps[i] = null;
}
}
} catch (Exception e) {
}
}
}
public void setBitmap(final int index, final Bitmap bitmap) {
if (bitmap != null && bitmap.isRecycled()) {
return;
}
if (bitmap == null) {
return;
}
bitmaps[index] = bitmap;
}
private void loadBitmap(final int index, final Bitmap bitmap) {
if (bitmap != null && bitmap.isRecycled()) {
return;
}
if (bitmap == null) {
return;
}
runOnDraw(new Runnable() {
public void run() {
if (bitmap == null || bitmap.isRecycled()) {
return;
}
if (sourceTextures[index] == OpenGlUtils.NO_TEXTURE) {
GLES20.glActiveTexture(GL_TEXTURES[index]);
sourceTextures[index] = OpenGlUtils.loadTexture(bitmap, OpenGlUtils.NO_TEXTURE, false);
}
}
});
}
@Override
protected void onDrawArraysPre() {
for (int i = 0; i < textureNum; i++) {
GLES20.glEnableVertexAttribArray(coordinateAttributes[i]);
GLES20.glActiveTexture(GL_TEXTURES[i]);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, sourceTextures[i]);
GLES20.glUniform1i(inputTextureUniforms[i], i + 3);
coordinatesBuffers[i].position(0);
GLES20.glVertexAttribPointer(coordinateAttributes[i], 2, GLES20.GL_FLOAT, false, 0, coordinatesBuffers[i]);
}
}
}
BlurFilter
public class BlurFilter extends InstaFilter{
public static final String BLUR_FRAGMENT_SHADER = "precision lowp float;\n" +
" uniform vec3 iResolution; \n" +
" uniform sampler2D inputImageTexture;\n" +
" varying vec2 textureCoordinate; \n" +
" uniform float size;\n" +
" \n" +
" void mainImage(out vec4 fragColor, in vec2 fragCoord){ \n" +
" float Pi = 6.28318530718; \n" +
" float Directions = 16.0; \n" +
" float Quality = 3.0; \n" +
" vec2 Radius = size/iResolution.xy; \n" +
" vec2 uv = fragCoord/iResolution.xy; \n" +
" vec4 Color = texture2D(inputImageTexture, uv); \n" +
" for( float d=0.0; d<Pi; d+=Pi/Directions){ \n" +
" for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality){ \n" +
" Color += texture2D( inputImageTexture, uv+vec2(cos(d),sin(d))*Radius*i); \n" +
" } \n" +
" }\n" +
" Color /= Quality * Directions - 15.0;\n" +
" fragColor = Color;\n" +
"}\n" +
"\n" +
" void main() { \n" +
" mainImage(gl_FragColor, textureCoordinate*iResolution.xy);\n" +
" }\n";
protected static final String BLUR_VERTEX_SHADER = "attribute vec2 position;\n" +
" attribute vec2 inputTextureCoordinate;\n" +
" \n" +
" varying vec2 textureCoordinate;\n" +
" \n" +
" void main()\n" +
" {\n" +
" textureCoordinate = inputTextureCoordinate;\n" +
" gl_Position = vec4 ( position.x, position.y, 0.0, 1.0 );\n" +
" }\n";
private int iResolutionLocation;
private int[] iResolutionArray;
private float sizeLevel;
private int sizeLocation;
public BlurFilter(Context context) {
super(BLUR_VERTEX_SHADER, BLUR_FRAGMENT_SHADER, 0);
this.iResolutionArray = new int[]{getOutputWidth(), getOutputHeight()};
}
@Override
public void onInit() {
super.onInit();
iResolutionLocation = GLES20.glGetUniformLocation(getProgram(), "iResolution");
sizeLocation = GLES20.glGetUniformLocation(getProgram(), "size");
sizeLevel = 70.0f;
this.setFloat(this.sizeLocation, sizeLevel);
}
@Override
public void onOutputSizeChanged(int width, int height){
super.onOutputSizeChanged(width, height);
this.iResolutionArray = new int[]{width, height};
setFloatVec3(iResolutionLocation, new float[]{(float) iResolutionArray[0], (float) iResolutionArray[1], 1.0f});
}
public void setBlurSize(float size){
this.sizeLevel = size;
Log.d("BlurFilter", "BlurFilter size : " + this.sizeLevel);
this.setFloat(sizeLocation, this.sizeLevel);
}
}
常规过滤器
public class IFNormalFilter extends InstaFilter{
public static final String SHADER = "precision lowp float;\n" +
" precision lowp float;\n" +
" varying highp vec2 textureCoordinate;\n" +
" \n" +
" uniform sampler2D inputImageTexture;\n" +
"\n" +
" void main()\n" +
" {\n" +
" \n" +
" vec3 texel = texture2D(inputImageTexture, textureCoordinate).rgb;\n" +
" \n" +
" gl_FragColor = vec4(texel, 1.0);\n" +
" }";
public IFNormalFilter(Context context) {
super(SHADER, 0);
}
}