6

BigFlake示例之后,有一条评论指出:

// Acquire a new frame of input, and render it to the Surface.  If we had a
// GLSurfaceView we could switch EGL contexts and call drawImage() a second
// time to render it on screen.  The texture can be shared between contexts by
// passing the GLSurfaceView's EGLContext as eglCreateContext()'s share_context
// argument.

我使用EGL14.getCurrentContext()查询当前上下文并将其传递给EGL14.eglCreateContext()share_context 参数,但是您如何“切换 EGL 上下文”?

GLSurfaceView 和 MediaCodec.inputSurface 有两个不同的表面和两个不同的上下文,所以我假设您只是eglMakeCurrent()单独调用每个集合,对吗?你需要eglDestroyContext()eglDestroySurface()

添加了更新

感谢 Fadden,我想我发现了这个错误,而不是 drawFrame 我调用的是 drawImage,但你不应该再次更新图像,对吧?

现在,glError 1285在设置 EOS 后调用 dequeueBuffer 时出现内存不足错误???也许我在录音停止后打电话给它。谢谢你的帮助。

在 MyEGLWrapper.java 中创建 EGLSurface

saveToScreenRenderState();
mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], mScreenEglContext, 
        contextAttribs, 0);
checkEglError("eglCreateContext");

// Create a window surface, and attach it to the Surface we received.
mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, configs[0], mSurface,
        surfaceAttribs, 0);
checkEglError("eglCreateWindowSurface");

...

private void saveToScreenRenderState() {
    //System.arraycopy(mProjectionMatrix, 0, mSavedMatrix, 0, mProjectionMatrix.length);
    mScreenEglDisplay = EGL14.eglGetCurrentDisplay();
    mScreenEglDrawSurface = EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW);
    mScreenEglReadSurface = EGL14.eglGetCurrentSurface(EGL14.EGL_READ);
    mScreenEglContext = EGL14.eglGetCurrentContext();
}

public void makeCurrent(boolean toScreen, Surface surface) {
    if (toScreen) { //as opposed to toEncoder
        makeScreenSurfaceCurrent();
        return;
    } 
    EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);
    checkEglError("eglMakeCurrent");
}

private void makeScreenSurfaceCurrent() {
    EGL14.eglMakeCurrent(mScreenEglDisplay, mScreenEglDrawSurface, 
            mScreenEglReadSurface, mScreenEglContext);
    checkEglError("eglMakeCurrent");
}

在 CaptureManager.java 中

private void drawFrameOnInputSurface() {
    //draw a second time for inputSurface 
    mEGLWrapper.makeCurrent(false, videoCodec.videoCodecInputSurface);
    drawFrame(false);
    //ByteBuffer frame = mStManager.drawImage();
    videoCodec.runQue(false); // clear que before posting should this be on this thread???
    mEGLWrapper.setPresentationTime(mSt.getTimestamp(),!recordingStopped);
    mEGLWrapper.swapBuffers(!recordingStopped);
    videoHandler.post(new Runnable(){
        @Override
        public void run(){
            videoCodec.updateFrame(!isRecording);
        }
    });
}

private void drawFrame(boolean updateImage){
    mStManager.drawImage(updateImage);
    mGLView.mRenderer.drawFrame();
}

在 SurfaceTextureManager.java 中

public ByteBuffer drawImage(boolean updateImage) {
    // Latch the data.
    if (updateImage){
        mTextureRender.checkGlError("before updateTexImage");
        mSurfaceTexture.updateTexImage();
    }
    return mTextureRender.drawFrame(mSurfaceTexture);
}

SurfaceTextureManager.java中的错误mSurfaceTexture.updateTexImage();

4

1 回答 1

5

是的,用于eglMakeCurrent在两个上下文之间切换。

您不需要破坏当前未使用的上下文或表面(无论如何,直到您关闭事物)。

有关使用共享上下文进行两次渲染的示例,请参阅 bigflake Breakout 游戏记录器补丁

于 2013-10-31T14:55:54.667 回答