convert to simple shm. fix some bugs
authorU. Artie Eoff <ullysses.a.eoff@intel.com>
Fri, 27 Apr 2012 20:08:19 +0000 (13:08 -0700)
committerU. Artie Eoff <ullysses.a.eoff@intel.com>
Fri, 27 Apr 2012 20:08:19 +0000 (13:08 -0700)
Signed-off-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
src/display.cpp
src/display.h
src/simple.cpp
src/window.cpp
src/window.h

index ebb6b1d..95471d6 100644 (file)
@@ -1,6 +1,7 @@
-// #include <sys/epoll.h>
 #include <iostream>
 #include <cstdlib>
+#include <string>
+#include <sys/mman.h>
 
 #include <wayland-client.h>
 
 namespace wayland {
 
 /*static*/
-int Display::evtMaskUpdate(uint32_t mask, void *data)
+int Display::evtMaskUpdate(uint32_t mask, voiddata)
 {
        Display* display = static_cast<Display*>(data);
        display->mask_ = mask;
-
        return 0;
 }
 
 /*static*/
+void Display::handleShmFormat(void* data, wl_shm* shm, uint32_t format)
+{
+       Display* display = static_cast<Display*>(data);
+       display->formats_ |= (1 << format);
+}
+
+/*static*/
+wl_shm_listener Display::shmListener_ = {
+       Display::handleShmFormat
+};
+
+/*static*/
 void Display::handleGlobal(wl_display* wldisplay, uint32_t id, const char* interface, uint32_t version, void* data)
 {
        Display* display = static_cast<Display*>(data);
-       if ("wl_compositor" == interface)
-       {
+       const std::string intfc(interface);
+
+       if ("wl_compositor" == intfc) {
                display->compositor_ = static_cast<wl_compositor*>(
                        wl_display_bind(
                                wldisplay, id, &wl_compositor_interface
                        )
                );
        }
-       else if ("wl_shell" == interface)
-       {
+       else if ("wl_shell" == intfc) {
                display->shell_ = static_cast<wl_shell*>(
                        wl_display_bind(
                                wldisplay, id, &wl_shell_interface
                        )
                );
        }
+       else if ("wl_shm" == intfc) {
+               display->shm_ = static_cast<wl_shm*>(
+                       wl_display_bind(
+                               wldisplay, id, &wl_shm_interface
+                       )
+               );
+               wl_shm_add_listener(display->shm_, &shmListener_, display);
+       }
 }
 
 Display::Display()
        : display_(wl_display_connect(0))
+       , formats_(0)
+       , compositor_(0)
+       , shell_(0)
+       , shm_(0)
+       , mask_(0)
 {
-       if (not display_)
-       {
+       if (not display_) {
                std::cerr << "Failed to create display!" << std::endl;
                exit(1);
        }
 
        wl_display_add_global_listener(display_, handleGlobal, this);
        wl_display_iterate(display_, WL_DISPLAY_READABLE);
-       if (initEGL() < 0)
-       {
-               std::cerr << "Failed to initialize egl!" << std::endl;
+       wl_display_roundtrip(display_);
+
+       if (not (formats_ & (1 << WL_SHM_FORMAT_XRGB8888))) {
+               std::cerr << "WL_SHM_FORMAT_XRGB32 not available!" << std::endl;
                exit(1);
        }
+
+       wl_display_get_fd(display_, evtMaskUpdate, this);
 }
 
-bool Display::initEGL()
+Display::~Display()
 {
-       EGLint major, minor, n;
-
-       static const EGLint argb_cfg_attribs[] = {
-               EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
-               EGL_RED_SIZE, 1,
-               EGL_GREEN_SIZE, 1,
-               EGL_BLUE_SIZE, 1,
-               EGL_ALPHA_SIZE, 1,
-               EGL_DEPTH_SIZE, 1,
-               EGL_RENDERABLE_TYPE, GL_BIT,
-               EGL_NONE
-       };
-
-#ifdef USE_CAIRO_GLESV2
-       static const EGLint context_attribs[] = {
-               EGL_CONTEXT_CLIENT_VERSION, 2,
-               EGL_NONE
-       };
-       EGLint api = EGL_OPENGL_ES_API;
-#else
-       EGLint *context_attribs = NULL;
-       EGLint api = EGL_OPENGL_API;
-#endif
-
-       eglDisplay_ = eglGetDisplay( (EGLNativeDisplayType)display_);
-       if (not eglInitialize(eglDisplay_, &major, &minor))
-       {
-//             fprintf(stderr, "failed to initialize display\n");
-               return false;
+       if (shm_) {
+               wl_shm_destroy(shm_);
        }
 
-       if (not eglBindAPI(api))
-       {
-//             fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
-               return false;
+       if (shell_) {
+               wl_shell_destroy(shell_);
        }
 
-       if (not eglChooseConfig(eglDisplay_, argb_cfg_attribs,
-                            &argbConfig_, 1, &n) || n != 1)
-       {
-//             fprintf(stderr, "failed to choose argb config\n");
-               return false;
+       if (compositor_) {
+               wl_compositor_destroy(compositor_);
        }
 
-       argbContext_ = eglCreateContext(eglDisplay_, argbConfig_,
-                                      EGL_NO_CONTEXT, context_attribs);
-       if (not argbContext_)
-       {
-//             fprintf(stderr, "failed to create context\n");
-               return false;
+       wl_display_flush(display_);
+       wl_display_disconnect(display_);
+}
+
+wl_buffer* Display::createShmBuffer(int w, int h, uint32_t format, void** dout)
+{
+       char    filename[] = "/tmp/wayland-shm-XXXXXX";
+       int     fd(mkstemp(filename));
+
+       if (fd < 0) {
+               std::cerr << "open " << filename << " failed: %m" << std::endl;
+               return NULL;
        }
 
-       if (not eglMakeCurrent(eglDisplay_, NULL, NULL, argbContext_))
-       {
-//             fprintf(stderr, "failed to make context current\n");
-               return false;
+       int stride(w * 4);
+       int size(stride * h);
+
+       if (ftruncate(fd, size) < 0) {
+               std::cerr << "ftruncate failed: %m" << std::endl;
+               close(fd);
+               return NULL;
        }
 
-#ifdef HAVE_CAIRO_EGL
-       argbDevice_ = cairo_egl_device_create(eglDisplay_, argbContext_);
-       if (cairo_device_status(argbDevice_) != CAIRO_STATUS_SUCCESS)
-       {
-//             fprintf(stderr, "failed to get cairo egl argb device\n");
-               return false;
+       void* data(
+               mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
+       );
+       unlink(filename);
+
+       if (data == MAP_FAILED) {
+               std::cerr << "mmap failed: %m" << std::endl;
+               close(fd);
+               return NULL;
        }
-#endif
 
-       return true;
-}
+       wl_shm_pool* pool(
+               wl_shm_create_pool(shm_, fd, size)
+       );
+
+       wl_buffer* buffer(
+               wl_shm_pool_create_buffer(pool, 0, w, h, stride, format)
+       );
+
+       wl_shm_pool_destroy(pool);
 
+       close(fd);
+
+       *dout = data;
+
+       return buffer;
+}
 
 } // namespace wayland
index ec82797..2af0015 100644 (file)
@@ -1,29 +1,14 @@
 #ifndef __WAYLAND_DISPLAY_H__
 #define __WAYLAND_DISPLAY_H__
 
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#ifdef USE_CAIRO_GLESV2
-       #include <GLES2/gl2.h>
-       #include <GLES2/gl2ext.h>
-
-       #define GL_BIT EGL_OPENGL_ES2_BIT
-#else
-       #include <GL/gl.h>
-       #define GL_BIT EGL_OPENGL_BIT
-#endif
-
-#ifdef HAVE_CAIRO_EGL
-       #include <cairo-gl.h>
-#endif
-
-
 #include <cstdint>
 
 struct wl_display;
 struct wl_compositor;
 struct wl_shell;
+struct wl_shm;
+struct wl_buffer;
+struct wl_shm_listener;
 
 namespace wayland {
 
@@ -32,28 +17,27 @@ class Display {
 public:
        Display();
 
+       virtual ~Display();
+
        wl_compositor*  compositor() { return compositor_; }
        wl_display*     display() { return display_; }
        wl_shell*       shell() { return shell_; }
-       EGLConfig&      config() { return argbConfig_; }
-       EGLContext&     context() { return argbContext_; }
+
+       wl_buffer*      createShmBuffer(int, int, uint32_t, void**);
        
 private:
        wl_display*     display_;
-       uint32_t        mask_;
+       uint32_t        formats_;
        wl_compositor*  compositor_;
        wl_shell*       shell_;
-
-       bool            running_;
-
-       EGLDisplay      eglDisplay_;
-       EGLConfig       argbConfig_;
-       EGLContext      argbContext_;
+       wl_shm*         shm_;
+       uint32_t        mask_;
 
        static int evtMaskUpdate(uint32_t, void*);
+       static void handleShmFormat(void*, wl_shm*, uint32_t);
        static void handleGlobal(wl_display*, uint32_t, const char*, uint32_t, void*);
 
-       bool initEGL();
+       static wl_shm_listener shmListener_;
 };
 
 } // namespace wayland
index e844af5..f1b1442 100644 (file)
@@ -7,6 +7,6 @@
 int main(const int argc, const char** argv)
 {
        wayland::Display display;
-       wayland::Window window(display);
+       wayland::Window window(display, 200, 200);
        return 0;
 }
index 1c54d7d..cdd4a38 100644 (file)
@@ -1,27 +1,39 @@
 #include <cassert>
 #include <wayland-client.h>
-#include <wayland-egl.h>
 
 #include "window.h"
 
 namespace wayland {
 
-Window::Window(Display& display)
+Window::Window(Display& display, int width, int height)
        : display_(display)
+       , width_(width)
+       , height_(height)
+       , surface_(wl_compositor_create_surface(display_.compositor()))
+       , shellSurface_(wl_shell_get_shell_surface(display_.shell(), surface_))
+       , shmData_(0)
+       , buffer_(
+               display_.createShmBuffer(
+                         width_
+                       , height_
+                       , WL_SHM_FORMAT_XRGB8888
+                       , &shmData_
+               )
+         )
+       , callback_(0)
 {
-       EGLBoolean result;
-
-       surface_ = wl_compositor_create_surface(display_.compositor());
-       shellSurface_ = wl_shell_get_shell_surface(display_.shell(), surface_);
-       native_ = wl_egl_window_create(surface_, width_, height_);
-       eglSurface_ = eglCreateWindowSurface(display_.display(), display_.config(), native_, NULL);
-
        wl_shell_surface_set_toplevel(shellSurface_);
+}
+
+Window::~Window()
+{
+       if (callback_) {
+               wl_callback_destroy(callback_);
+       }
 
-       assert(
-               eglMakeCurrent(display_.display(), eglSurface_, eglSurface_, &display_.context())
-               == EGL_TRUE
-       );
+       wl_buffer_destroy(buffer_);
+       wl_shell_surface_destroy(shellSurface_);
+       wl_surface_destroy(surface_);
 }
 
 } // namespace wayland
index f9d11ad..1803994 100644 (file)
@@ -9,26 +9,18 @@ class Window
 {
 
 public:
-       Window(Display& display);
+       Window(Display&, int, int);
 
+       virtual ~Window();
 private:
        Display&        display_;
-       int             x_;
-       int             y_;
        int             width_;
        int             height_;
 
-       GLuint          fbo_;
-       GLuint          colorrbo_;
-       GLuint          program_;
-       GLuint          uniformRotation_;
-       GLuint          pos_;
-       GLuint          col_;
-       EGLSurface      eglSurface_;
-
-       struct wl_egl_window*           native_;
        struct wl_surface*              surface_;
        struct wl_shell_surface*        shellSurface_;
+       void*                           shmData_;
+       struct wl_buffer*               buffer_;
        struct wl_callback*             callback_;
 };