User avatar
cheery
Posts: 219
Joined: Wed Jan 25, 2012 9:39 pm

Desktop Compositing on Linux

Fri May 18, 2012 11:35 pm

I found a wayland patch, which implemented compositing in RPi. Decided to take it apart and reassemble into an example. Here's the key pieces. Does the foundation or broadcom ppl. have anything to say about it?

Code: Select all

#include <assert.h>
#include "GLES/gl.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#define EGL_PIXEL_FORMAT_ARGB_8888_PRE_BRCM 0
#define EGL_PIXEL_FORMAT_ARGB_8888_BRCM     1
#define EGL_PIXEL_FORMAT_XRGB_8888_BRCM     2
#define EGL_PIXEL_FORMAT_RGB_565_BRCM       3
#define EGL_PIXEL_FORMAT_A_8_BRCM           4
#define EGL_PIXEL_FORMAT_RENDER_GL_BRCM     (1 << 3)
#define EGL_PIXEL_FORMAT_RENDER_GLES_BRCM   (1 << 4)
#define EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM  (1 << 5)
#define EGL_PIXEL_FORMAT_RENDER_VG_BRCM     (1 << 6)
#define EGL_PIXEL_FORMAT_RENDER_MASK_BRCM   0x78
#define EGL_PIXEL_FORMAT_VG_IMAGE_BRCM      (1 << 7)
#define EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM  (1 << 8)
#define EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM (1 << 9)
#define EGL_PIXEL_FORMAT_TEXTURE_MASK_BRCM  0x380
#define EGL_PIXEL_FORMAT_USAGE_MASK_BRCM    0x3f8


EGLSurface create_shared_pixmap(EGLDisplay display, EGLConfig config, EGLint* global_image, int width, int height) {
    EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM;
    EGLint rt;
    eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &rt);

    if (rt & EGL_OPENGL_ES_BIT) {
        pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM;
        pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM;
    }
    if (rt & EGL_OPENGL_ES2_BIT) {
        pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM;
        pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM;
    }
    if (rt & EGL_OPENVG_BIT) {
        pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM;
        pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM;
    }
    if (rt & EGL_OPENGL_BIT) {
        pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM;
    }
    global_image[0] = 0;
    global_image[1] = 0;
    global_image[2] = width;
    global_image[3] = height;
    global_image[4] = pixel_format;

    eglCreateGlobalImageBRCM(width, height, global_image[4], 0, width*4, global_image);

    EGLint attrs[] = {
        EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB,
        EGL_VG_ALPHA_FORMAT, pixel_format & EGL_PIXEL_FORMAT_ARGB_8888_PRE_BRCM ? EGL_VG_ALPHA_FORMAT_PRE : EGL_VG_ALPHA_FORMAT_NONPRE,
        EGL_NONE
    };
    return eglCreatePixmapSurface(display, config, (EGLNativePixmapType)global_image, attrs);
}

GLuint create_texture_from_shared_pixmap(EGLDisplay display, EGLint* global_image) {
    assert (eglQueryGlobalImageBRCM(global_image, global_image+2));

    EGLImageKHR image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)global_image, (void*)0/*NULL*/);
    assert (image != EGL_NO_IMAGE_KHR);

    GLuint tid;
    glGenTextures(1, &tid);
    glBindTexture(GL_TEXTURE_2D, tid);
    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
    /*
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    */

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //GL_CLAMP_TO_EDGE);

    eglDestroyImageKHR(display, image);

    return tid;
}
What that code doesn't show is that I had to call the eglFlushBRCM along eglSwapBuffers in the process which shared its pixmap. Otherwise it really is that simple except that you have to supply a pixmap config to it of course.

Now that I have something that runs, I'll perhaps turn it into a python module or something.

I also keep wondering one thing. Now If I'd go and turn this into a desktop env, how would I synchronize the rendering such that there would be minimum issues with doing it all with compositing?

Also, how would I go if I'd want to optimize the desktop env mostly away, when the thing is in fullscreen mode? (This I might guess on my own though..)

Edit: Btw. if you try the example.. try call: sh build.sh, then ./compositing and keep it running while you call ./compositing2
Attachments
compositing_example.zip
Not very good example, demonstrating the effect.
(6.83 KiB) Downloaded 236 times

shirro
Posts: 248
Joined: Tue Jan 24, 2012 4:54 am

Re: Desktop Compositing on Linux

Sat May 19, 2012 3:17 am

Hi Cheery, I took your zip and put it on github at https://github.com/shirro/compositing-example

I hope that is ok. I am going to play around with it a bit later if I ever get time.

User avatar
cheery
Posts: 219
Joined: Wed Jan 25, 2012 9:39 pm

Re: Desktop Compositing on Linux

Sat May 19, 2012 1:29 pm

Add the MIT license (if someone requires it), and give me the push-rights as well. I think I might want to improve it.

I tend to not add licenses to my code, because I consider them waste of productive time for obsoleted values.

asb
Forum Moderator
Forum Moderator
Posts: 853
Joined: Fri Sep 16, 2011 7:16 pm
Contact: Website

Re: Desktop Compositing on Linux

Thu May 24, 2012 2:23 pm

cheery wrote:Add the MIT license (if someone requires it), and give me the push-rights as well. I think I might want to improve it.

I tend to not add licenses to my code, because I consider them waste of productive time for obsoleted values.
I for one would appreciate an explicit licence (such as MIT).

Also, the qt5 devs had some issues with the vc_dispmanx_element_add/vc_dispmanx_element_remove approach for the cursor which Dom very kindly debugged. The best reference for that is probably the Qt5 patchset for cursor support when Girish publishes it.

User avatar
cheery
Posts: 219
Joined: Wed Jan 25, 2012 9:39 pm

Re: Desktop Compositing on Linux

Thu May 24, 2012 8:50 pm

There you go, I added MIT to shirro's repository.

User avatar
cheery
Posts: 219
Joined: Wed Jan 25, 2012 9:39 pm

Re: Desktop Compositing on Linux

Fri Oct 26, 2012 3:56 pm

It's time to pick this up again. I'm going to do a desktop compositing library for nodejs, but there's one thing that bothers me.

If I make a native window for rendering (might be neat for fullscreen app to get such one), the workflow seems to be:

Code: Select all

ON SERVER:
    send nativewindow -handle to CLIENT
ON CLIENT SIDE:
    retrieve nativewindow -handle and transform it to surface
BUT this compositor workflow seems to go like:

Code: Select all

ON CLIENT SIDE:
    create globalimage and transform it to surface
    send globalimage -handle to SERVER
ON SERVER:
    retrieve globalimage -handle and transform it to a texture
So another workflow proposes that I have to send message to server, one proposes I need to send message from server. I'd rather not solve this with any silly putty solutions, but is there any alternatives?

Also, there seems to be trivial way of resizing the nativewindow element from server side by updating the element rectagle, yet I've got no clue about the composite image resizing.

Return to “Troubleshooting”

Who is online

Users browsing this forum: NetspiePi and 30 guests