Imagination PowerVR SDK Blog

eglCreateWindowSurface of fullscreen X window


#1

My program hangs in IOCTL inside PVRSRVBridgeCall function, if I try to render egl window surface with height=854 & width=480.

Strangely, everything works fine if I create egl window surface for height=853 & width=480 X window.
Can someone help to solve mystery why my program fails with height 854 and works with 853.
My display resolution is 480w x 854h and I am using OMAP35x_Graphics_SDK_setuplinux_3_01_00_02.bin


#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

#include “main.h”
#include "3d.h"

int main(int cArgs, char *aArgs)
{
    EGLDisplay sEGLDisplay;
    EGLContext sEGLContext;
    EGLSurface sEGLSurface;
    EGLint aEGLAttributes[] = {
        EGL_BUFFER_SIZE,    EGL_DONT_CARE,
        EGL_RED_SIZE,       5,
        EGL_GREEN_SIZE,     6,
        EGL_BLUE_SIZE,      5,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
        EGL_NONE};
    EGLConfig aEGLConfigs[1];
    EGLint cEGLConfigs;
    EGLint aEGLContextAttributes[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    XSetWindowAttributes win_attrs;
    int attrs[64], idx = 0, num_config = 0;
    unsigned int uiHeight = 854; // Works if changed to 853
    unsigned int uiWidth = 480;
    Window win;
    Display
display;
    int major, minor;
    Colormap colormap;
    XVisualInfo *pVisual;
    XEvent e;

    GLint iLocPosition;
    GLint iLocColour;
    GLint iLocMVP;
    GLuint uiProgram;
    GLuint uiFragShader;
    GLuint uiVertShader;

    int bDone = 0;
    int iXangle = 0 * 3;
    int iYangle = 0 * 2;
    int iZangle = 0 * 1;
    float aRotate[16];
    float aModelView[16], aPerspective[16], aMVP[16];
    int i;

    display = XOpenDisplay(NULL);
    if (NULL == display)
    {
        printf(“Failed to open display.n”);
        goto exit;
    }
   
    sEGLDisplay = EGL_CHECK(eglGetDisplay(display));
    EGL_CHECK(eglInitialize(sEGLDisplay, NULL, NULL));
    EGL_CHECK(eglChooseConfig(
        sEGLDisplay,
        aEGLAttributes,
        aEGLConfigs,
        1,
        &cEGLConfigs));
    if (cEGLConfigs == 0)
    {
        printf(“No EGL configurations were returned.n”);
        goto exit;
    }

    win = CreateXWindow(
        “OpenGL ES 2.0 Example on a Linux Desktop”,
        uiWidth,
        uiHeight,
        display,
        sEGLDisplay,
        aEGLConfigs[0],
        &colormap,
        &pVisual);
    if (!win)
    {
        printf(“Failed to create X window.n”);
        goto exit;
    }

    sEGLSurface = EGL_CHECK(eglCreateWindowSurface(
        sEGLDisplay,
        aEGLConfigs[0],
        win,
        NULL));
    if (EGL_NO_SURFACE == sEGLSurface)
    {
        printf(“Failed to create EGL surface.n”);
        goto exit;
    }

    sEGLContext = EGL_CHECK(eglCreateContext(
        sEGLDisplay,
        aEGLConfigs[0],
        EGL_NO_CONTEXT,
        aEGLContextAttributes));
    if (EGL_NO_CONTEXT == sEGLContext)
    {
        printf(“Failed to create EGL context.n”);
        goto exit;
    }

    EGL_CHECK(eglMakeCurrent(
        sEGLDisplay,
        sEGLSurface,
        sEGLSurface,
        sEGLContext));

    processShader(&uiVertShader, VERT_FILE, GL_VERTEX_SHADER);
    processShader(&uiFragShader, FRAG_FILE, GL_FRAGMENT_SHADER);

    uiProgram = GL_CHECK(glCreateProgram());

    GL_CHECK(glAttachShader(uiProgram, uiVertShader));
    GL_CHECK(glAttachShader(uiProgram, uiFragShader));
    GL_CHECK(glLinkProgram(uiProgram));

    iLocPosition = GL_CHECK(glGetAttribLocation(uiProgram, “av4position”));
    iLocColour = GL_CHECK(glGetAttribLocation(uiProgram, “av3colour”));

    iLocMVP = GL_CHECK(glGetUniformLocation(uiProgram, “mvp”));


    GL_CHECK(glUseProgram(uiProgram));

    GL_CHECK(glEnableVertexAttribArray(iLocPosition));
    GL_CHECK(glEnableVertexAttribArray(iLocColour));

    GL_CHECK(glVertexAttribPointer(
        iLocPosition,
        3,
        GL_FLOAT,
        GL_FALSE,
        0,
        aVertices));

    GL_CHECK(glVertexAttribPointer(
        iLocColour,
        3,
        GL_FLOAT,
        GL_FALSE,
        0,
        aColours));

    GL_CHECK(glEnable(GL_CULL_FACE));
    GL_CHECK(glEnable(GL_DEPTH_TEST));
   
    XSelectInput(
        display,
        win,
        KeyPressMask | ExposureMask | EnterWindowMask | LeaveWindowMask
        | PointerMotionMask | VisibilityChangeMask | ButtonPressMask
        | ButtonReleaseMask | StructureNotifyMask);

    while(!bDone)
    {
        while (XPending(display) > 0)
        {
            XNextEvent(display, &e);
            if (e.type == ButtonPress)
            {
                bDone = 1;
            }
        }

        rotateMatrix(iXangle, 1.0, 0.0, 0.0, aModelView);
        rotateMatrix(iYangle, 0.0, 1.0, 0.0, aRotate);
        multiplyMatrix(aRotate, aModelView, aModelView);
        rotateMatrix(iZangle, 0.0, 1.0, 0.0, aRotate);
        multiplyMatrix(aRotate, aModelView, aModelView);

        aModelView[14] -= 2.5;

        perspectiveMatrix(
            45.0,
            (double)uiWidth/(double)uiHeight,
            0.01,
            100.0,
            aPerspective);
        multiplyMatrix(aPerspective, aModelView, aMVP);
        GL_CHECK(glUniformMatrix4fv(iLocMVP, 1, GL_FALSE, aMVP));

        iXangle += 3;
        iYangle += 2;
        iZangle += 1;
        if(iXangle >= 360) iXangle -= 360;
        if(iXangle < 0) iXangle += 360;
        if(iYangle >= 360) iYangle -= 360;
        if(iYangle < 0) iYangle += 360;
        if(iZangle >= 360) iZangle -= 360;
        if(iZangle < 0) iZangle += 360;

        GL_CHECK(glClear(
            GL_COLOR_BUFFER_BIT
            | GL_DEPTH_BUFFER_BIT
            | GL_STENCIL_BUFFER_BIT));
        GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, 36));

        if (!eglSwapBuffers(sEGLDisplay, sEGLSurface))
        {
            printf(“Failed to swap buffers.n”);
        }

        usleep(20000);

    }

    GL_CHECK(glUseProgram(0));
    GL_CHECK(glDeleteShader(uiVertShader));
    GL_CHECK(glDeleteShader(uiFragShader));
    GL_CHECK(glDeleteProgram(uiProgram));

    EGL_CHECK(eglMakeCurrent(
        sEGLDisplay,
        EGL_NO_SURFACE,
        EGL_NO_SURFACE,
        EGL_NO_CONTEXT));
    EGL_CHECK(eglDestroySurface(sEGLDisplay, sEGLSurface));
    EGL_CHECK(eglDestroyContext(sEGLDisplay, sEGLContext));
    EGL_CHECK(eglTerminate(sEGLDisplay));

exit:
    XDestroyWindow(display, win);
    XFreeColormap(display, colormap);
    XFree(pVisual);
    XCloseDisplay(display);

    return 0;
}

void rotateMatrix(
    double angle,
    double x,
    double y,
    double z,
    float *R)
{
    double radians, c, s, c1, u[3], length;
    int i, j;

    radians = (angle * M_PI)/180.0;
    c = cos(radians);
    s = sin(radians);
    c1 = 1.0 - cos(radians);
    length = sqrt(x * x + y * y + z * z);
    u[0] = x/length;
    u[1] = y/length;
    u[2] = z/length;

    for (i = 0; i < 16; i++)
    {
        R = 0.0;
    }
    R[15] = 1.0;

    for (i = 0; i < 3; i++)
    {
        R = u[(i + 2) % 3] * s;
        R = -u[(i + 1) % 3] * s;
    }

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            R += c1 * u * u[j] + (i == j ? c : 0.0);
        }
    }
}

void perspectiveMatrix(
    double fovy,
    double aspect,
    double znear,
    double zfar,
    float *P)
{
    int i;
    double f;

    f = 1.0/tan(fovy * 0.5);

    for (i = 0; i < 16; i++)
    {
        P = 0.0;
    }

    P[0] = f/aspect;
    P[5] = f;
    P[10] = (znear + zfar)/(znear - zfar);
    P[11] = -1.0;
    P[14] = (2.0 * znear * zfar)/(znear - zfar);
    P[15] = 0.0;
}

void multiplyMatrix(float *A, float *B, float *C)
{
    int i, j, k;
    float aTmp[16];

    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            aTmp[j * 4 + i] = 0.0;
            for (k = 0; k < 4; k++)
            {
                aTmp[j * 4 + i] += A[k * 4 + i] * B[j * 4 + k];
            }
        }
    }

    for (i = 0; i < 16; i++)
    {
        C = aTmp;
    }
}

void processShader(GLuint *pShader, char *sFilename, GLint iShaderType)
{
    GLint iStatus;
    const char *aStrings[1] = { NULL };

    *pShader = GL_CHECK(glCreateShader(iShaderType));
    aStrings[0] = loadShader(sFilename);
    GL_CHECK(glShaderSource(*pShader, 1, aStrings, NULL));

    free((void *)(aStrings[0]));
    aStrings[0] = NULL;

    GL_CHECK(glCompileShader(*pShader));
    GL_CHECK(glGetShaderiv(*pShader, GL_COMPILE_STATUS, &iStatus));

    if(iStatus != GL_TRUE)
    {
        GLint iLen;
        char *sDebugSource = NULL;
        char *sErrorLog = NULL;

        GL_CHECK(glGetShaderiv(*pShader, GL_SHADER_SOURCE_LENGTH, &iLen));
        sDebugSource = malloc(iLen);
        GL_CHECK(glGetShaderSource(*pShader, iLen, NULL, sDebugSource));
        free(sDebugSource);

        GL_CHECK(glGetShaderiv(*pShader, GL_INFO_LOG_LENGTH, &iLen));
        sErrorLog = malloc(iLen);
        GL_CHECK(glGetShaderInfoLog(pShader, iLen, NULL, sErrorLog));
        free(sErrorLog);

        exit(1);
    }
}

char
loadShader(char *sFilename)
{
    char *pResult = NULL;
    FILE *pFile = NULL;
    long iLen = 0;

    pFile = fopen(sFilename, “r”);
    if(pFile == NULL)
    {
        fprintf(stderr, “Error: Cannot read file '%s’n”, sFilename);
        exit(1);
    }

    fseek(pFile, 0, SEEK_END);
    iLen = ftell(pFile);
    fseek(pFile, 0, SEEK_SET);
    pResult = calloc(iLen+1, sizeof(char));
    fread(pResult, sizeof(char), iLen, pFile);
    pResult[iLen] = ‘’;
    fclose(pFile);

    return pResult;
}

Bool WaitForMap(Display *d, XEvent e, char win_ptr)
{
    if (e->type == MapNotify && e->xmap.window == (
((Window
)win_ptr)))
    {
        return True;
    }
    return False;
}

Window CreateXWindow(
    const char title,
    int width,
    int height,
    Display
display,
    EGLDisplay sEGLDisplay,
    EGLConfig FBConfig,
    Colormap *pColormap,
    XVisualInfo **ppVisual)
{
    XSetWindowAttributes wa;
    XSizeHints sh;
    XEvent e;
    unsigned long mask;
    long screen;
    XVisualInfo visual, template;
    Colormap colormap;
    int vID, n;
    Window window;

    screen = DefaultScreen(display);
    eglGetConfigAttrib(sEGLDisplay, FBConfig, EGL_NATIVE_VISUAL_ID, &vID);
    template.visualid = vID;
    visual = XGetVisualInfo(display, VisualIDMask, &template, &n);
    colormap = XCreateColormap(
        display,
        RootWindow(display, screen),
        visual->visual,
        AllocNone);
    wa.colormap = colormap;
    wa.background_pixel = 0xFFFFFFFF;
    wa.border_pixel = 0;
    wa.event_mask = StructureNotifyMask | ExposureMask;

    mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;

    window = XCreateWindow(
       display,
       RootWindow(display, screen),
       0,
       0,
       width,
       height,
       0,
       visual->depth,
       InputOutput,
       visual->visual,
       mask,
       &wa);

    sh.flags = USPosition;
    sh.x = 0;
    sh.y = 0;
    XSetStandardProperties(display, window, title, title, None, 0, 0, &sh);
    XMapWindow(display, window);
    XIfEvent(display, &e, WaitForMap, (char
)&window);
    XSetWMColormapWindows(display, window, &window, 1);
    XFlush(display);

    *pColormap = colormap;
    *ppVisual = visual;

    return window;
}


gdb back trace 


(gdb) bt
#0  0x4023504c in ioctl () from /lib/libc.so.6
#1  0x4039b9f0 in PVRSRVBridgeCall (hServices=<value optimized out>,
    ui32FunctionID=3223086917, pvParamIn=<value optimized out>,
    ui32InBufferSize=<value optimized out>, pvParamOut=0xbedbd298,
    ui32OutBufferSize=8)
    at /home/prabu/gfxsdkcreate/builder_09/ddkbuild/ti_references/sources/GFX_Linux_DDK/src/eurasia/services4/srvclient/env/linux/common/pvr_bridge_u.c:188
#2  0x4039b1d8 in PVRSRVEventObjectWait (psConnection=<value optimized out>,
    hOSEvent=<value optimized out>)
    at /home/prabu/gfxsdkcreate/builder_09/ddkbuild/ti_references/sources/GFX_Linux_DDK/src/eurasia/services4/srvclient/env/linux/common/osfunc_um.c:307
#3  0x4039f7b4 in SGXKickTA (psDevData=0x0, psKickTA=0x1fc90,
    psKickOutput=0x1208, pvKickPDUMP=<value optimized out>, pvKickSubmit=0x0)
    at /home/prabu/gfxsdkcreate/builder_09/ddkbuild/ti_references/sources/GFX_Linux_DDK/src/eurasia/services4/srvclient/devices/sgx/sgxkick_client.c:1462
#4  0x4012d484 in ScheduleTA (gc=0x1fa40, psRenderSurface=0x1e630,
    ui32KickFlags=0) at sgxif.c:1535
#5  0x4014e6dc in GLES2EmitState (gc=<value optimized out>,
    ePrimitiveType=<value optimized out>, b32BitIndices=36,
    ui32NumIndices=1075259736, uIndexAddress={uiAddr = 27561984},
    ui32IndexOffset=0) at validate.c:4611
#6  0x4011a434 in glDrawArrays (mode=4, first=0, count=36)
    at drawvarray.c:2286
#7  0x0000a17c in main ()
(gdb)







#2

This doesn’t sound like an application issue - it sounds more like a driver problem. In this case you need to approach TI for support on this issue.


#3

okay. thanks


#4

i faced similar problem, when u try to create surface larger than your display size and perform the drawing, the program keeps on making ioctl calls.