SGX540 上的 OpenGL ES 2.0 OpenGL 离屏 PIXMAP 支持
OpenGL ES 2.0 on SGX540 OpenGL Offscreen PIXMAP Support
在配备 Imagination Technologies PowerVR SGX 530 的 DM370 (TI OMAP 3) 上,我能够使用以下代码使用 CMEM 和 PIXMAP 离屏表面初始化我的 EglSurface:
// Index to bind the attributes to vertex shaders
#define VERTEX_ARRAY 0
#define TEXCOORD_ARRAY 1
// Bit types
#define SGXPERF_RGB565 0
#define SGXPERF_ARGB8888 2
// SurfaceTypes
#define SGXPERF_SURFACE_TYPE_WINDOW 0
#define SGXPERF_SURFACE_TYPE_PIXMAP_16 1
#define SGXPERF_SURFACE_TYPE_PIXMAP_32 2
typedef struct _NATIVE_PIXMAP_STRUCT
{
long pixelFormat;
long rotation;
long width;
long height;
long stride;
long sizeInBytes;
long pvAddress;
long lAddress;
} NATIVE_PIXMAP_STRUCT;
// Init EGL with offscreen PIXMAP support
void* GLWidget::commonEglInit(int surfaceType, NATIVE_PIXMAP_STRUCT** pNativePixmapPtr) {
int windowWidthTi, windowHeightTi;
EGLint iMajorVersion, iMinorVersion;
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
eglDisplay = eglGetDisplay((int)0);
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
return NULL;
if ( !eglBindAPI(EGL_OPENGL_ES_API) ) {
return NULL;
}
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT | EGL_PIXMAP_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;
int iConfigs;
if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
{
fprintf(stderr,"Error: eglChooseConfig() failed.\n");
return NULL;
}
commonCreateNativePixmap(SGXPERF_ARGB8888,WIDTH, HEIGHT, pNativePixmapPtr);
eglSurface = eglCreatePixmapSurface(eglDisplay, eglConfig, *pNativePixmapPtr, NULL);
if (!fprintf(stderr,"eglCreateSurface\n"))
return NULL;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
if (!fprintf(stderr,"eglCreateContext\n"))
return NULL;
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!fprintf(stderr,"eglMakeCurrent\n"))
return NULL;
EGLBoolean success = eglSwapInterval(eglDisplay, 1);
if ( !success ) {
fprintf(stderr,"eglSwapInterval\n");
sleep(3600);
return NULL;
}
eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &windowWidthTi);
eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &windowHeightTi);
fprintf(stderr,"Window width=%d, Height=%d\n", windowWidthTi, windowHeightTi);
(void*)(*pNativePixmapPtr)->lAddress;
return (void*)(*pNativePixmapPtr)->lAddress;
}
在 OMAP 5/Sitara - AM57xx EVM 上,使用 SGX 540 GPU,我构建并部署了带有 OpenGL 库、cmemk.ko 和 pvrsrvctl 的处理器 SDK。我可以成功 运行 PVR OpenGL 演示,它们出现在显示器上。我正在尝试 运行 我的应用程序在这个新的 EVM 上,但它总是失败:
Error: eglChooseConfig() failed.
Error creating EGL surface!
如果我删除 pi32ConfigAttribs 中的 EGL_PIXMAP_BIT,那么它会更进一步。
AM57xx OpenGL 库不支持 PIXMAP 表面吗?如果他们这样做,我怎样才能让他们工作?谢谢!
您不应该使用 EGL_PIXMAP_BIT。它要求 EGL 以与 OS 的窗口系统直接兼容的格式提供表面,以进行离屏图像传输。为此使用 FBO。
请注意,像素图与像素缓冲区或 (pbuffers) 不同。
看起来您正在使用 TI 的嵌入式 Linux 发行版,因此像素图必须与 Qt、DirectFB 或 X11 等软件兼容。 TI 从未为 OMAP 提供过针对特定窗口系统的屏幕外图像集成得很好的 EGL 驱动程序。 EGL_PIXMAP_BIT 过去可能使用过某些特定的窗口系统,但不一定是您正在使用的系统。这篇文章更详细的解释了OpenGL ES各种离屏图像的区别:
在配备 Imagination Technologies PowerVR SGX 530 的 DM370 (TI OMAP 3) 上,我能够使用以下代码使用 CMEM 和 PIXMAP 离屏表面初始化我的 EglSurface:
// Index to bind the attributes to vertex shaders
#define VERTEX_ARRAY 0
#define TEXCOORD_ARRAY 1
// Bit types
#define SGXPERF_RGB565 0
#define SGXPERF_ARGB8888 2
// SurfaceTypes
#define SGXPERF_SURFACE_TYPE_WINDOW 0
#define SGXPERF_SURFACE_TYPE_PIXMAP_16 1
#define SGXPERF_SURFACE_TYPE_PIXMAP_32 2
typedef struct _NATIVE_PIXMAP_STRUCT
{
long pixelFormat;
long rotation;
long width;
long height;
long stride;
long sizeInBytes;
long pvAddress;
long lAddress;
} NATIVE_PIXMAP_STRUCT;
// Init EGL with offscreen PIXMAP support
void* GLWidget::commonEglInit(int surfaceType, NATIVE_PIXMAP_STRUCT** pNativePixmapPtr) {
int windowWidthTi, windowHeightTi;
EGLint iMajorVersion, iMinorVersion;
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
eglDisplay = eglGetDisplay((int)0);
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
return NULL;
if ( !eglBindAPI(EGL_OPENGL_ES_API) ) {
return NULL;
}
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT | EGL_PIXMAP_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;
int iConfigs;
if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
{
fprintf(stderr,"Error: eglChooseConfig() failed.\n");
return NULL;
}
commonCreateNativePixmap(SGXPERF_ARGB8888,WIDTH, HEIGHT, pNativePixmapPtr);
eglSurface = eglCreatePixmapSurface(eglDisplay, eglConfig, *pNativePixmapPtr, NULL);
if (!fprintf(stderr,"eglCreateSurface\n"))
return NULL;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
if (!fprintf(stderr,"eglCreateContext\n"))
return NULL;
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!fprintf(stderr,"eglMakeCurrent\n"))
return NULL;
EGLBoolean success = eglSwapInterval(eglDisplay, 1);
if ( !success ) {
fprintf(stderr,"eglSwapInterval\n");
sleep(3600);
return NULL;
}
eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &windowWidthTi);
eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &windowHeightTi);
fprintf(stderr,"Window width=%d, Height=%d\n", windowWidthTi, windowHeightTi);
(void*)(*pNativePixmapPtr)->lAddress;
return (void*)(*pNativePixmapPtr)->lAddress;
}
在 OMAP 5/Sitara - AM57xx EVM 上,使用 SGX 540 GPU,我构建并部署了带有 OpenGL 库、cmemk.ko 和 pvrsrvctl 的处理器 SDK。我可以成功 运行 PVR OpenGL 演示,它们出现在显示器上。我正在尝试 运行 我的应用程序在这个新的 EVM 上,但它总是失败:
Error: eglChooseConfig() failed.
Error creating EGL surface!
如果我删除 pi32ConfigAttribs 中的 EGL_PIXMAP_BIT,那么它会更进一步。
AM57xx OpenGL 库不支持 PIXMAP 表面吗?如果他们这样做,我怎样才能让他们工作?谢谢!
您不应该使用 EGL_PIXMAP_BIT。它要求 EGL 以与 OS 的窗口系统直接兼容的格式提供表面,以进行离屏图像传输。为此使用 FBO。
请注意,像素图与像素缓冲区或 (pbuffers) 不同。
看起来您正在使用 TI 的嵌入式 Linux 发行版,因此像素图必须与 Qt、DirectFB 或 X11 等软件兼容。 TI 从未为 OMAP 提供过针对特定窗口系统的屏幕外图像集成得很好的 EGL 驱动程序。 EGL_PIXMAP_BIT 过去可能使用过某些特定的窗口系统,但不一定是您正在使用的系统。这篇文章更详细的解释了OpenGL ES各种离屏图像的区别: