Android GLES20 - 如何在渲染到屏幕之前减少渲染到两个连续帧缓冲区所涉及的开销?

时间:2018-04-20 08:16:05

标签: android opengl-es

假设我有一个渲染管道,涉及使用片段着色器A将视频帧渲染到FBO A,然后使用片段着色器B从FBO A渲染到FBO B,最后在FBO中渲染纹理B使用Fragment Shader C进入屏幕。

这条管道似乎没有像Galaxy S6这样的高端设备出现任何延迟,但是当我在华为P8 Lite中进行测试时(我认为它是低端或中端设备) ),由于某种原因,有很大的开销,所以每帧大约需要0.33秒才能在屏幕上呈现。

我应该采取哪些措施来减轻低端或中端设备的开销?或者我应该完全抛弃这种方法并使用Fragment Shader Stitching?

编辑:这基本上是我onDrawFrame电话中的内容:

private void drawActual() {

    if(currentSEFilterPosition != storedSEFilterPosition || changeFragmentShader)
    {
        /*
         The code for switching filters on the fly is here
         */
    } else {
        GLES20.glDisable(GLES20.GL_BLEND);
    }

    long start = System.currentTimeMillis();

    drawBeautyCamera();
    long bCamera = (System.currentTimeMillis() - start);
    drawToFBO();
    long fbo = (System.currentTimeMillis() - start);
    postProcessFromFBO();
    long pProcess = (System.currentTimeMillis() - start);
    Log.i("draw_durations", bCamera+" "+fbo+" "+pProcess);
}

drawBeautyCamera()drawFBO()基本上是以下代码,使用不同的GL程序重复两次:

 private void drawBeautyCamera() {
    GLES20.glUseProgram(beautyCamProgram);
    checkGlError("glUseProgram");

    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mBeautyCamFramebuffer);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
    checkGlError("glBindTexture");

    //Log.i("current_float_timestamp", muTimestampFloatHandle+"");
    //onPrelimPreDrawFrame();

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(maBeautycamPositionHandle, 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maPosition");
    GLES20.glEnableVertexAttribArray(maBeautycamPositionHandle);
    checkGlError("glEnableVertexAttribArray maPositionHandle");

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
    GLES20.glVertexAttribPointer(maBeautycamTextureHandle, 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maTextureHandle");
    GLES20.glEnableVertexAttribArray(maBeautycamTextureHandle);
    checkGlError("glEnableVertexAttribArray maTextureHandle");

    Matrix.setIdentityM(mBeautyCamMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(muBeautycamMVPMatrixHandle, 1, false, mBeautyCamMVPMatrix, 0);
    checkGlError("glmuMVPMatrixHandleSetting");
    GLES20.glUniformMatrix4fv(muBeautycamSTMatrixHandle, 1, false, mBeautyCamSTMatrix, 0);
    checkGlError("glmuSTMatrixHandleSetting");

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    checkGlError("glDrawArrays");

    //USE DEFAULT FRAMEBUFFER THIS TIME
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}

postProcessFromFBO()如下:

private void postProcessFromFBO() {
    GLES20.glUseProgram(specialEffectsProgram);
    checkGlError("glUseProgram");

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mOffscreenTexture);
    checkGlError("glBindTexture");

    onSEPreDrawFrame();
    checkGlError("onPreDrawFrame");

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maPosition");
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    checkGlError("glEnableVertexAttribArray maPositionHandle");

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
    GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maTextureHandle");
    GLES20.glEnableVertexAttribArray(maTextureHandle);
    checkGlError("glEnableVertexAttribArray maTextureHandle");

    Matrix.setIdentityM(mMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    checkGlError("glmuMVPMatrixHandleSetting");
    Matrix.setIdentityM(mSTMatrix, 0);
    GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
    checkGlError("glmuSTMatrixHandleSetting");

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    checkGlError("glDrawArrays");
}

1 个答案:

答案 0 :(得分:0)

低端设备的GPU会更小/更慢,所以考虑到高端设备的延迟很好,可以假设这不是CPU软件性能问题,你可能只是想做您可用的GPU性能渲染太多。

即。你的“开销”很可能只是GPU处理,而不是可以避免的事情。尝试使用更简单的片段着色器或更低的分辨率进行渲染。