Hi, I now use the fbdev window system, I assign a fbdev_pixmap structure configured corresponding content, pass it to eglCreatePixmapSurface function, but get to the error information 0x0000300A Such as: Error: eglCreatePixmapSurface failed Error: 0x0000300A I will be how to configure fbdev_pixmap structure content, there is no successful example sent to me ah? Thank you
Hi yueliu,
The error code you are getting is the following:
EGL_BAD_NATIVE_PIXMAP may be generated if native_pixmap is not a valid native pixmap.
EGL_BAD_NATIVE_PIXMAP
native_pixmap
Can you double check that the native_pixmap that you are passing in is indeed valid?
Do you have a reproducer, or example code snippet, so we can look into why it is failing for you?
Kind Regards,
Michael McGeagh
*surfRet = eglCreatePixmapSurface(egl_dpy, config, winRet, attrib_list);
I don't see in your code snippet where winRet is defined and setup. This is the problem, not the eglCreatePixmapSurface call. It is erroring stating your winRet is not valid.
Can you double check your pixmap generation code and validate it to make sure that your pixmap 'winRet' is indeed valid?
Thanks in advance,
Hi,
So your Native Pixmap is defined here:
static struct fbdev_pixmap surface = { .width = 1920, .height = 1080, .bytes_per_pixel = 4, .buffer_size = 32, .red_size = 8, .green_size = 8, .blue_size = 8, .alpha_size = 8, .luminance_size = 0, .flags = FBDEV_PIXMAP_DEFAULT,//FBDEV_PIXMAP_SUPPORTS_UMP, .format = 1, };
static struct fbdev_pixmap surface = {
.width = 1920,
.height = 1080,
.bytes_per_pixel = 4,
.buffer_size = 32,
.red_size = 8,
.green_size = 8,
.blue_size = 8,
.alpha_size = 8,
.luminance_size = 0,
.flags = FBDEV_PIXMAP_DEFAULT,//FBDEV_PIXMAP_SUPPORTS_UMP,
.format = 1,
};
And on your device, it comes up as it being invalid.
Can you let us know what device you are targetting, what OS you are running (including kernel version), and if you know it, what version of Mali you are using.
Thanks
hi
I am now using mali 400mp2 platform, the repository is framebuffer-r3p0;
examples are as follows:
static EGLint const config_attribute_list[] = { EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,// EGL_PBUFFER_BIT EGL_WINDOW_BIT EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; setenv("EGL_PLATFORM", "fbdev", 0); setenv("FRAMEBUFFER", argv[1], 0); struct fbdev_pixmap surface = { .width = 1920, .height = 1080, .bytes_per_pixel = 32, .red_size = 8, .green_size = 8, .blue_size = 8, .alpha_size = 8, .flags = FBDEV_PIXMAP_DEFAULT, .format = 1, }; egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { printf("Error: eglInitialize() failed\n"); return -1; } if (!eglChooseConfig(egl_dpy, config_attribute_list, &config, 1, &num_configs)) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); assert(num_configs > 0); EGLint ai32ContextAttribs[4]; i=0; ai32ContextAttribs[i] = EGL_NONE; ai32ContextAttribs[i++] = EGL_CONTEXT_CLIENT_VERSION; ai32ContextAttribs[i++] = 2; ai32ContextAttribs[i] = EGL_NONE; eglBindAPI(EGL_OPENGL_ES_API); ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ai32ContextAttribs ); if (!ctx) { printf("Error: eglCreateContext failed\n"); exit(1); } EGLint attrib_list[16]; attrib_list[0] = EGL_NONE; *surfRet = eglCreatePixmapSurface(egl_dpy, config, winRet, attrib_list); if (!*surfRet) { printf("Error: eglCreatePixmapSurface failed Error:0x%08X\n", eglGetError()); exit(1); }
The program prints the error:
Error: eglCreatePixmapSurface failed Error: 0x0000300A
May I ask how to configure struct fbdev_pixmap, do not know if there are no relevant success stories?
Hi Michael McGeagh,
My complete code below:
/************************************************************************** * * Copyright 2013 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * **************************************************************************/ /* * Draw a triangle with X/EGL and OpenGL ES 2.x */ #define USE_FULL_GL 0 #include <assert.h> #include <math.h> #include <GLES2/gl2.h> /* use OpenGL ES 2.x */ #include <EGL/egl.h> #include <unistd.h> #include <stdbool.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> //#include <png.h> #include <EGL/eglext.h> #include <EGL/fbdev_window.h> #define FLOAT_TO_FIXED(X) ((X) * 65535.0) #define DEV_NAME "/dev/sns-media-mem" static EGLNativeDisplayType native_dpy; static GLfloat view_rotx = 0.0, view_roty = 0.0; static GLint u_matrix = -1; static GLint attr_pos = 0, attr_color = 1; static struct fbdev_pixmap surface = { .width = 1920, .height = 1080, .bytes_per_pixel = 4, .buffer_size = 32, .red_size = 8, .green_size = 8, .blue_size = 8, .alpha_size = 8, .luminance_size = 0, .flags = FBDEV_PIXMAP_DEFAULT,//FBDEV_PIXMAP_SUPPORTS_UMP, .format = 1, }; static void make_z_rot_matrix(GLfloat angle, GLfloat *m) { float c = cos(angle * M_PI / 180.0); float s = sin(angle * M_PI / 180.0); int i; for (i = 0; i < 16; i++) m[i] = 0.0; m[0] = m[5] = m[10] = m[15] = 1.0; m[0] = c; m[1] = s; m[4] = -s; m[5] = c; } static void make_scale_matrix(GLfloat xs, GLfloat ys, GLfloat zs, GLfloat *m) { int i; for (i = 0; i < 16; i++) m[i] = 0.0; m[0] = xs; m[5] = ys; m[10] = zs; m[15] = 1.0; } static void mul_matrix(GLfloat *prod, const GLfloat *a, const GLfloat *b) { #define A(row,col) a[(col<<2)+row] #define B(row,col) b[(col<<2)+row] #define P(row,col) p[(col<<2)+row] GLfloat p[16]; GLint i; for (i = 0; i < 4; i++) { const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); } memcpy(prod, p, sizeof(p)); #undef A #undef B #undef PROD } static void draw(void) { static const GLfloat verts[3][2] = { { -1, -1 }, { 1, -1 }, { 0, 1 } }; static const GLfloat colors[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; GLfloat mat[16], rot[16], scale[16]; /* Set modelview/projection matrix */ make_z_rot_matrix(view_rotx, rot); make_scale_matrix(0.5, 0.5, 0.5, scale); mul_matrix(mat, rot, scale); glUniformMatrix4fv(u_matrix, 1, GL_FALSE, mat); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer(attr_color, 3, GL_FLOAT, GL_FALSE, 0, colors); glEnableVertexAttribArray(attr_pos); glEnableVertexAttribArray(attr_color); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(attr_pos); glDisableVertexAttribArray(attr_color); } } /* new window size or exposure */ static void reshape(int width, int height) { glViewport(0, 0, (GLint) width, (GLint) height); } static void create_shaders(void) { static const char *fragShaderText = "precision mediump float;\n" "varying vec4 v_color;\n" "void main() {\n" " gl_FragColor = v_color;\n" "}\n"; static const char *vertShaderText = "uniform mat4 modelviewProjection;\n" "attribute vec4 pos;\n" "attribute vec4 color;\n" "varying vec4 v_color;\n" "void main() {\n" " gl_Position = modelviewProjection * pos;\n" " v_color = color;\n" "}\n"; GLuint fragShader, vertShader, program; GLint stat; fragShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragShader, 1, (const char **) &fragShaderText, NULL); glCompileShader(fragShader); glGetShaderiv(fragShader, GL_COMPILE_STATUS, &stat); if (!stat) { printf("Error: fragment shader did not compile!\n"); exit(1); } vertShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertShader, 1, (const char **) &vertShaderText, NULL); glCompileShader(vertShader); glGetShaderiv(vertShader, GL_COMPILE_STATUS, &stat); if (!stat) { printf("Error: vertex shader did not compile!\n"); exit(1); } program = glCreateProgram(); glAttachShader(program, fragShader); glAttachShader(program, vertShader); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &stat); if (!stat) { char log[1000]; GLsizei len; glGetProgramInfoLog(program, 1000, &len, log); printf("Error: linking:\n%s\n", log); exit(1); } glUseProgram(program); if (1) { /* test setting attrib locations */ glBindAttribLocation(program, attr_pos, "pos"); glBindAttribLocation(program, attr_color, "color"); glLinkProgram(program); /* needed to put attribs into effect */ } else { /* test automatic attrib locations */ attr_pos = glGetAttribLocation(program, "pos"); attr_color = glGetAttribLocation(program, "color"); } u_matrix = glGetUniformLocation(program, "modelviewProjection"); printf("Uniform modelviewProjection at %d\n", u_matrix); printf("Attrib pos at %d\n", attr_pos); printf("Attrib color at %d\n", attr_color); } static void init(void) { glClearColor(0.4, 0.4, 0.4, 0.0); create_shaders(); } static EGLint const config_attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,// EGL_PBUFFER_BIT EGL_WINDOW_BIT EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_DEPTH_SIZE, 0, EGL_NONE }; /* * Create an RGB, double-buffered X window. * Return the window and context handles. */ static void make_window( EGLDisplay egl_dpy, const char *name, int x, int y, int width, int height, void *winRet, EGLContext *ctxRet, EGLSurface *surfRet) { int scrnum; unsigned long mask; int num_visuals; EGLContext ctx; EGLConfig config; EGLint num_configs; EGLint vid; int i; if (!eglChooseConfig(egl_dpy, config_attribute_list, &config, 1, &num_configs)) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); assert(num_configs > 0); EGLint ai32ContextAttribs[4]; i=0; ai32ContextAttribs[i] = EGL_NONE; ai32ContextAttribs[i++] = EGL_CONTEXT_CLIENT_VERSION; ai32ContextAttribs[i++] = 2; ai32ContextAttribs[i] = EGL_NONE; eglBindAPI(EGL_OPENGL_ES_API); ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ai32ContextAttribs ); if (!ctx) { printf("Error: eglCreateContext failed\n"); exit(1); } EGLint attrib_list[16]; attrib_list[0] = EGL_NONE; *surfRet = eglCreatePixmapSurface(egl_dpy, config, winRet, attrib_list); if (!*surfRet) { printf("Error: eglCreatePixmapSurface failed Error:0x%08X\n", eglGetError()); exit(1); } *ctxRet = ctx; } static void event_loop(EGLDisplay egl_dpy, EGLSurface egl_surf) { int redraw = 1; // while (1) { if (redraw) { printf("event_loop------------111111 \n"); draw(); printf("event_loop------------22222222222 \n"); eglSwapBuffers(egl_dpy, egl_surf); glFlush(); printf("event_loop------------333333333333 \n"); } while (1) { ; } // } } static void usage(void) { printf("Usage:\n"); printf(" -display <displayname> set the display to run on\n"); printf(" -info display OpenGL renderer info\n"); } int main(int argc, char *argv[]) { const int winWidth = 1920, winHeight = 1080; EGLSurface egl_surf; EGLContext egl_ctx; EGLDisplay egl_dpy; char *dpyName = NULL; GLboolean printInfo = GL_FALSE; EGLint egl_major, egl_minor; int i; const char *s; setenv("EGL_PLATFORM", "fbdev", 0); setenv("FRAMEBUFFER", "/dev/fb0", 0); egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!egl_dpy) { printf("Error: eglGetDisplay() failed\n"); return -1; } if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { printf("Error: eglInitialize() failed\n"); return -1; } make_window( egl_dpy, "OpenGL ES 2.x tri", 0, 0, winWidth, winHeight, &surface, &egl_ctx, &egl_surf); if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { printf("Error: eglMakeCurrent() failed\n"); return -1; } if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); } init(); /* Set initial projection/viewing transformation. * We can't be sure we'll get a ConfigureNotify event when the window * first appears. */ event_loop( egl_dpy, egl_surf); return 0; }
I do not know if “surface” is configured correctly?
yueliu
I now use linux platform, kernel version is linux 3.4.79, is running on cubieboard2, gpu is mali400mp2, mali driver version is DX910-SW-99002-r3p0-04rel0, I used is based on the fbdev device library the repository is linux-fbdev-hf-r3p0-04rel0.tar.gz
We are now tring to transplant our graphics system from powerVR sgx540 to mali400(use fb_dev on linux). On the powerVR sgx540 platform, we used the function "eglCreateImageKHR ((EGLDisplay*)egl_dpy, egl_ctx,EGL_NATIVE_PIXMAP_KHR,(EGLClientBuffer) buffer,NULL)" to create an pointer of EGLImageKHR. But we are not sure if the function is implemented in the mali-400 openGLES libraries(linux-fbdev-hf-r3p0-04rel0.tar.gz)? If the answer is YES, are there any pieces of sample code; or, are there any alternative implementations?
thanks,
The correct definition of the fbdev_pixmap can be found at https://github.com/Pivosgroup/buildroot-linux/blob/master/package/amlogic/opengl/src/include/EGL/fbdev_window.h for you to use. Within the same repo, there are also references to the use of the eglCreateImageKHR function you are hoping to make use of https://github.com/Pivosgroup/buildroot-linux/blob/a083da1c0a7bf153e8e43bf38f2a41efdafb5f63/package/amlogic/opengl/src/include/EGL/eglext.h.
I hope this is helpful,
Rich
HI,Rich
thanks for your answer. Now we have successfully created EGLImage by the function eglCreateImageKHR, with EGL_NATIVE_PIXMAP_KHR as target and fbdev_pixmap as EGLClientBuffer, and we have output the image onto the screen now. But to make the format of the data match with our decoder, we have to make the data of the EGLImage support the formats ,YUV420/YUV422/YUV411/YUV444 .etc. Could you please give me some advices on how to create an EGLImage in formats above?
Thank you very much.
I have done some digging for you and have found the following:
You need to explicity allocate memory for the native pixmaps in the client app as the DDK will not do so. This needs to be either malloc'd or allocated through another supported memory scheme, for example UMP. If this isn't done, the DDK may start writing/copying data into the fbdev_pixmap structure data field which is then uninitialized/unallocated data.
Secondly, if you are not using UMP, you should be aware that is it not possible to have zero-copy of native pixmaps as the GPU will have to copy the rendering output into the malloc'd buffer in the client app by calling eglWaitClient for example.
Finally regarding YUV - there are currently no supported fbdev pixmaps for this. I can suggest you treat each plane as a separate alpha-only pixmap then use optimized GLES shaders to do YUV->RGBA conversion.
Hopefully this is helpful,