CEF给出了一个linux下的离屏渲染的demo,主要使用GTK3 + GtkGLArea + OpenGL的方式实现。
起初我们模仿这个demo实现了客户端的离屏渲染功能(由于一些特殊需求,只能采用离屏渲染方式),在麒麟9006C(arm64平台,8核)+ UOS系统下运行似乎一切正常。但是当我们开始渲染视频并且全屏播放时,CPU的使用率立马直线飙升,几乎占满了8核。查看线程消耗时,发现出现了8条llvmpipe线程。
通过查资料后得知llvmpipe线程时OpenGL的软渲染线程,而后通过glxinfo命令发现该平台下的GLX并未实现硬件加速的能力,因此使用 GtkGLArea 时使用的是软渲染。当绘制平面较大并且绘制内容刷新帧率高时,性能上就无法满足了。
由于针对OpenGL的开发经验不多,并且是在新的平台上,因此花费了不少时间查阅资料和验证尝试。最后发现使用EGL可以(通过CPU的集成显卡和对应的libmali.so支持)支持硬件加速。到这一步之后方向基本明朗了,大致示例代码如下:
#include <EGL/egl.h>
#include <GLES2/gl2.h>
EGLDisplay display;
EGLConfig config;
EGLContext context;
EGLSurface surface;
EGLint numConfigs;
static EGLint const attributeList[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_NONE
};
// 获取EGL显示连接
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) {
// 错误处理
}
// 初始化EGL
if (!eglInitialize(display, NULL, NULL)) {
// 错误处理
}
// 选择配置
if (!eglChooseConfig(display, attributeList, &config, 1, &numConfigs)) {
// 错误处理
}
// 创建上下文
context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
if (context == EGL_NO_CONTEXT) {
// 错误处理
}
EGLint pbufferAttribs[] = {
EGL_WIDTH, width,
EGL_HEIGHT, height,
EGL_NONE
};
EGLSurface pbuffer = eglCreatePbufferSurface(display, config, pbufferAttribs);
......
这边需要注意下,我创建的EGLSurface实际使用的时 PBuffer,而不是 Window(eglCreateWindowSurface),原因是我尝试渲染到Window(需要和GTK创建的窗口进行绑定) 时,仍然会出现软渲染CPU高的情况。具体的原因未知,我猜想可能和GTK内部的实现方式有关,后续也没有进一步研究。最后采用了先渲染到PBuffer,再通知主线程,并且在相应的draw事件中使用 cairo 将我们从PBuffer取出的缓存数据渲染到窗口中。

+ 麒麟9006C平台下CEF离屏渲染效率优化【记录】&spm=1001.2101.3001.5002&articleId=150563156&d=1&t=3&u=94fbba0ddab44c859f8fb3bdf0553620)
5053

被折叠的 条评论
为什么被折叠?



