GraphicBuffer使用:直接通过GraphicBuffer handle创建GraphicBuffer和直接渲染到GraphicBuffer的方法

在跨进程传递GraphicBuffer时,并不是直接传递GraphicBuffer对象,而是传递的GraphicBuffer的类型为native_handle*的handle成员。
在跨进程传递完成之后,如果期望再通过该handle获取GraphicBuffer,

可以这样采用如下代码:

sp<GraphicBuffer> spGraphicBuffer
= new GraphicBuffer(/*const native_handle_t* */memHandle,
                                                    //CLONE_HANDLE定义在
                                                    //frameworks\native\include\ui\GraphicBuffer.h
                                                    GraphicBuffer::CLONE_HANDLE,
                                                    width, height,
                                                    format, 1, // layer count
                                                    GRALLOC_USAGE_HW_RENDER,
                                                    stride);

如果期望将直接在GraphicBuffer上渲染作图,可已经GraphicBuffer,可以将GraphicBuffer作为GL_COLOR_ATTACHMENT0绑定到framebuffer上。
Android 源码一个比较好的demo,介绍了如何直接通过native_handle* handle创建GraphicBuffer对象和直接渲染到GraphicBuffer的方法
代码如下:

//Z:\ap\packages\services\Car\evs\app\RenderBase.cpp
bool RenderBase::attachRenderTarget(const BufferDesc& tgtBuffer) {
    
    
    // Hardcoded to RGBx for now
    //必须是HAL_PIXEL_FORMAT_RGBA_8888格式
    if (tgtBuffer.format != HAL_PIXEL_FORMAT_RGBA_8888) {
    
    
        ALOGE("Unsupported target buffer format");
        return false;
    }

    // create a GraphicBuffer from the existing handle
    sp<GraphicBuffer> pGfxBuffer = new GraphicBuffer(tgtBuffer.memHandle,
                                                     GraphicBuffer::CLONE_HANDLE,
                                                     tgtBuffer.width, tgtBuffer.height,
                                                     tgtBuffer.format, 1, // layer count
                                                     GRALLOC_USAGE_HW_RENDER,
                                                     tgtBuffer.stride);
    if (pGfxBuffer.get() == nullptr) {
    
    
        ALOGE("Failed to allocate GraphicBuffer to wrap image handle");
        return false;
    }

    // Get a GL compatible reference to the graphics buffer we've been given
    EGLint eglImageAttributes[] = {
    
    EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
    EGLClientBuffer clientBuf = static_cast<EGLClientBuffer>(pGfxBuffer->getNativeBuffer());
    sKHRimage = eglCreateImageKHR(sDisplay, EGL_NO_CONTEXT,
                                  EGL_NATIVE_BUFFER_ANDROID, clientBuf,
                                  eglImageAttributes);
    if (sKHRimage == EGL_NO_IMAGE_KHR) {
    
    
        ALOGE("error creating EGLImage for target buffer: %s", getEGLError());
        return false;
    }

    // Construct a render buffer around the external buffer
    glBindRenderbuffer(GL_RENDERBUFFER, sColorBuffer);
    glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, static_cast<GLeglImageOES>(sKHRimage));


    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, sColorBuffer);

    GLenum checkResult = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (checkResult != GL_FRAMEBUFFER_COMPLETE) {
    
    
        ALOGE("Offscreen framebuffer not configured successfully (%d: %s)",
              checkResult, getGLFramebufferError());
        return false;
    }

    // Store the size of our target buffer
    sWidth = tgtBuffer.width;
    sHeight = tgtBuffer.height;
    sAspectRatio = (float)sWidth / sHeight;

    // Set the viewport
    glViewport(0, 0, sWidth, sHeight);

#if 1   // We don't actually need the clear if we're going to cover the whole screen anyway
    // Clear the color buffer
    glClearColor(0.8f, 0.1f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
#endif

    return true;
}

猜你喜欢

转载自blog.csdn.net/u010116586/article/details/103641813