- 首先,通过Canvas、OpenGL、Camera或者Video Decoder生成图像流。
- 接着,图像流通过Surface入队到BufferQueue,并通知到GLConsumer。
- 然后,GLConsumer从BufferQueue获取图像流GraphicBuffer,并转换为纹理。
- 最后,业务方可以对纹理进一步处理,例如:上特效或者上屏。
创建SurfaceTexture
@MainActivity.java
createVDSurface
@Vision.java
Vision.getInstance().createSurface
//1.创建纹理
int texture = nativeCreateTexture(width, height);
@src/main/cpp/vision/android_jni/android_jni.cpp
VisionRendering2D_createTexture(width, height);
@src/main/cpp/rendering/renders/palace_render.cpp
g_render_manager->CreateTexture(width, height);
GLCHECK(glGenTextures(1, &texture));
//2.使用纹理初始化SurfaceTexture,组合有mEGLConsumer
SurfaceTexture surfaceTexture = new SurfaceTexture(texture, false);
surfaceTexture.setOnFrameAvailableListener()
@MainActivity.java
//3.使用SurfaceTexture创建Surface,此时Surface是生产者,SurfaceTexture(Native层对应GLConsumer)是消费者,创建好
//Surface后,就可以通过多种方式向Surface绘制图像数据了,例如:Canvas绘制、Camera输出、视频解码器渲染
mMainHandler.post(() -> { callback.surfaceCreated(surfaceTexture); }
Surface surface = new Surface(texture);
addContentOnVDDisplay(surface);
//4.使用Surface创建vd应用
u3dClient.startAppOnWindow(packName, actName, "launcher", mWidth, mHeight, densityDpi, rotateSurface, new VDCreatedListener() {
更新图像
surfaceflinger:
present
// 1. 向Surface绘制图像数据
finishFrame
composeSurfaces
dequeueBuffer //获取buffer
prepareClientComposition //准备GPU合成
drawLayers
REThreaded::drawLayers //交给REThreaded组织绘制
SkiaGL::drawLayers
DrawLayer: com.android.calculator2/com.android.calculator2.Calculator#0
DrawImage
flush surface
queueBuffer //提交buffer进行GPU合成
Trace GPU completion fence 2210
vd,SurfaceTexture:
queueBuffer
OnFrameAvailableListener
// 2. 业务层主动更新目标纹理
surfaceTexture.updateTexImage();
@frameworks/base/core/jni/android_graphics_SurfaceTexture.cpp
nativeUpdateTexImage
SurfaceTexture_updateTexImage
surfaceTexture->updateTexImage();
@frameworks/native/libs/gui/GLConsumer.cpp
mEGLConsumer.updateTexImage(*this);
@frameworks/native/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp
acquireBufferLocked(&item, 0);
mEGLConsumer.onAcquireBufferLocked(item, *this);
mEglSlots[slot].mEglImage = new EglImage(st.mSlots[slot].mGraphicBuffer); //BufferQueue中获取可用的BufferItem,其中包含了GraphicBuffer。然后,基于GraphicBuffer创建EglImage
updateAndReleaseLocked(item);
err = mEglSlots[slot].mEglImage->createIfNeeded(mEglDisplay); //创建EGLImageKHR
mEglImage = createImage(mEglDisplay, mGraphicBuffer);
@frameworks/native/libs/ui/GraphicBuffer.cpp
EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer()); // EGLClientBuffer是void *类型,native/opengl/include/EGL/egl.h:
return static_cast<ANativeWindowBuffer*>(const_cast<GraphicBuffer*>(this)); //ANativeWindowBuffer在frameworks/native/libs/nativebase/include/nativebase/nativebase.h
eglInitialize(dpy, nullptr, nullptr);
EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
bindTextureImageLocked();
glBindTexture(mTexTarget, mTexName); //绑定纹理
mCurrentTextureImage->bindToTextureTarget(mTexTarget);
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(mEglImage)); //把EGLImageKHR填充为纹理数据
mMainHandler.post(() -> callback.surfaceUpdated(surfaceTexture));
@MainActivity.java
surfaceUpdated
3. 业务层使用纹理
VSyncMonitor_onVsync
g_render_manager->HandleVSync(timestamp);
PalaceRenderManager::Render()
left_eye_frame_buffer_->Bind();
render_->Draw();