在跨进程传递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;
}