[Mesa-dev] [PATCH 2/6] gallium: new DirectFB backend for the EGL state tracker
Ilyes Gouta
ilyes.gouta at gmail.com
Sun Apr 14 10:50:45 PDT 2013
Signed-off-by: Ilyes Gouta <ilyes.gouta at gmail.com>
---
src/gallium/state_trackers/egl/Makefile.am | 9 +
src/gallium/state_trackers/egl/common/native.h | 3 +
.../state_trackers/egl/directfb/native_directfb.c | 585 +++++++++++++++++++++
3 files changed, 597 insertions(+)
create mode 100644 src/gallium/state_trackers/egl/directfb/native_directfb.c
diff --git a/src/gallium/state_trackers/egl/Makefile.am b/src/gallium/state_trackers/egl/Makefile.am
index f78b36e..27925b9 100644
--- a/src/gallium/state_trackers/egl/Makefile.am
+++ b/src/gallium/state_trackers/egl/Makefile.am
@@ -102,3 +102,12 @@ AM_CPPFLAGS += \
-I$(top_srcdir)/src/gallium/winsys/sw \
-DHAVE_NULL_BACKEND
endif
+
+if HAVE_EGL_PLATFORM_DIRECTFB
+libegl_la_SOURCES += directfb/native_directfb.c
+AM_CPPFLAGS += \
+ -I$(top_srcdir)/src/gallium/winsys/sw \
+ -DHAVE_DIRECTFB_BACKEND
+AM_CFLAGS += \
+ $(DIRECTFB_CFLAGS)
+endif
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 312b079..553d8f9 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -336,6 +336,9 @@ native_get_null_platform(const struct native_event_handler *event_handler);
const struct native_platform *
native_get_android_platform(const struct native_event_handler *event_handler);
+const struct native_platform *
+native_get_directfb_platform(const struct native_event_handler *event_handler);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/state_trackers/egl/directfb/native_directfb.c b/src/gallium/state_trackers/egl/directfb/native_directfb.c
new file mode 100644
index 0000000..6c3be7d
--- /dev/null
+++ b/src/gallium/state_trackers/egl/directfb/native_directfb.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2013 Ilyes Gouta, ilyes.gouta at gmail.com.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * For DirectFB window system,
+ *
+ * - the only valid native display is EGL_DEFAULT_DISPLAY
+ */
+
+#include <stdio.h>
+#include <time.h>
+
+#include <directfb.h>
+
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "util/u_inlines.h"
+#include "directfb/directfb_sw_winsys.h"
+
+#include "common/native_helper.h"
+#include "common/native.h"
+
+struct directfb_display {
+ struct native_display base;
+ const struct native_event_handler *event_handler;
+ IDirectFBSurface *pSurface;
+ struct native_config *configs;
+ int num_configs;
+};
+
+struct directfb_surface {
+ struct native_surface base;
+ enum pipe_format format;
+ struct directfb_display *display;
+ IDirectFBSurface *pSurface;
+ unsigned int server_stamp;
+ unsigned int client_stamp;
+ struct resource_surface *rsurf;
+};
+
+static INLINE struct directfb_display*
+directfb_display( const struct native_display *ndpy )
+{
+ return (struct directfb_display*)ndpy;
+}
+
+static INLINE struct directfb_surface*
+directfb_surface( const struct native_surface *nsurf )
+{
+ return (struct directfb_surface*)nsurf;
+}
+
+static const struct native_config **
+directfb_display_get_configs( struct native_display *ndpy, int *num_configs )
+{
+ struct directfb_display *display =
+ directfb_display( ndpy );
+ const struct native_config **configs;
+ int i;
+
+ configs = MALLOC( sizeof(*configs) * display->num_configs );
+ if (configs) {
+ for (i = 0; i < display->num_configs; i++)
+ configs[i] = &display->configs[i];
+ if (num_configs)
+ *num_configs = display->num_configs;
+ }
+
+ return configs;
+}
+
+static int
+directfb_display_get_param( struct native_display *ndpy,
+ enum native_param_type param )
+{
+ int val = 0;
+
+ switch (param) {
+ case NATIVE_PARAM_PRESERVE_BUFFER:
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ val = 1;
+ break;
+ case NATIVE_PARAM_MAX_SWAP_INTERVAL:
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static void
+directfb_display_destroy( struct native_display *ndpy )
+{
+ struct directfb_display *display =
+ directfb_display( ndpy );
+
+ FREE( display->configs );
+ ndpy_uninit( &display->base );
+ FREE( display );
+}
+
+static boolean
+directfb_display_init_config( struct native_display *ndpy )
+{
+ const enum pipe_format formats[] = {
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_B5G6R5_UNORM,
+ PIPE_FORMAT_NONE
+ };
+
+ struct directfb_display *display =
+ directfb_display( ndpy );
+
+ display->configs =
+ CALLOC( 2 * Elements(formats) - 1,
+ sizeof( *display->configs ) );
+
+ if (!display->configs)
+ return FALSE;
+
+ struct native_config *nconf;
+
+ for (int i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
+ struct pipe_screen* screen = display->base.screen;
+ if (screen->is_format_supported( display->base.screen,
+ formats[i],
+ PIPE_TEXTURE_2D,
+ 0,
+ PIPE_BIND_RENDER_TARGET
+ | PIPE_BIND_DISPLAY_TARGET )) {
+ nconf = &display->configs[display->num_configs++];
+ nconf->color_format = formats[i];
+ nconf->buffer_mask = (1 << NATIVE_ATTACHMENT_BACK_LEFT)
+ | (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
+ nconf->window_bit = TRUE;
+ nconf = &display->configs[display->num_configs++];
+ nconf->color_format = formats[i];
+ nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
+ nconf->pixmap_bit = TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+static boolean
+directfb_display_init_screen( struct native_display *ndpy )
+{
+ struct directfb_display *display =
+ directfb_display( ndpy );
+ struct sw_winsys *ws;
+
+ ws = directfb_sw_create();
+ if (!ws)
+ return FALSE;
+
+ display->base.screen =
+ display->event_handler->new_sw_screen( &display->base, ws );
+
+ if (!display->base.screen) {
+ if (ws->destroy)
+ ws->destroy( ws );
+ return FALSE;
+ }
+
+ if (!directfb_display_init_config( &display->base )) {
+ ndpy_uninit( &display->base );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Update the geometry of the surface. This is a slow functions.
+ */
+static void
+directfb_surface_update_geometry( struct native_surface *nsurf )
+{
+ struct directfb_surface *surf =
+ directfb_surface( nsurf );
+ int w, h;
+
+ surf->pSurface->GetSize( surf->pSurface, &w, &h );
+ if (resource_surface_set_size( surf->rsurf, w, h ))
+ surf->server_stamp++;
+}
+
+/**
+ * Update the buffers of the surface.
+ */
+static boolean
+directfb_surface_update_buffers( struct native_surface *nsurf,
+ uint buffer_mask )
+{
+ struct directfb_surface *surf =
+ directfb_surface(nsurf);
+
+ if (surf->client_stamp != surf->server_stamp) {
+ directfb_surface_update_geometry( &surf->base );
+ surf->client_stamp = surf->server_stamp;
+ }
+
+ return resource_surface_add_resources( surf->rsurf, buffer_mask );
+}
+
+/**
+ * Emulate an invalidate event.
+ */
+static void
+directfb_surface_invalidate( struct native_surface *nsurf )
+{
+ struct directfb_surface *surf =
+ directfb_surface( nsurf );
+ struct directfb_display *display =
+ surf->display;
+
+ surf->server_stamp++;
+ display->event_handler->invalid_surface( &display->base,
+ &surf->base,
+ surf->server_stamp );
+}
+
+static boolean
+directfb_surface_flush_frontbuffer( struct native_surface *nsurf )
+{
+ struct directfb_surface *surf =
+ directfb_surface( nsurf );
+ boolean ret;
+
+ ret = resource_surface_present( surf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT,
+ (void *)surf->pSurface );
+
+ /* force buffers to be updated in next validation call */
+ directfb_surface_invalidate( &surf->base );
+
+ return ret;
+}
+
+static boolean
+directfb_surface_swap_buffers( struct native_surface *nsurf )
+{
+ struct directfb_surface *surf =
+ directfb_surface( nsurf );
+ boolean ret;
+
+ /* surf will be flipped in directfb_sw_displaytarget_display() */
+ ret = resource_surface_present( surf->rsurf,
+ NATIVE_ATTACHMENT_BACK_LEFT,
+ (void *)surf->pSurface );
+
+ resource_surface_swap_buffers( surf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT,
+ NATIVE_ATTACHMENT_BACK_LEFT,
+ TRUE );
+
+ /* the front/back buffers have been swapped */
+ directfb_surface_invalidate( &surf->base );
+
+ return ret;
+}
+
+static boolean
+directfb_surface_present( struct native_surface *nsurf,
+ const struct native_present_control *ctrl )
+{
+ boolean ret;
+
+ if (ctrl->preserve || ctrl->swap_interval)
+ return FALSE;
+
+ switch (ctrl->natt) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ ret = directfb_surface_flush_frontbuffer( nsurf );
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ ret = directfb_surface_swap_buffers( nsurf );
+ break;
+ default:
+ ret = FALSE;
+ break;
+ }
+
+ return ret;
+}
+
+static boolean
+directfb_surface_validate( struct native_surface *nsurf,
+ uint attachment_mask,
+ unsigned int *seq_num,
+ struct pipe_resource **textures,
+ int *width,
+ int *height )
+{
+ struct directfb_surface *surf =
+ directfb_surface( nsurf );
+ uint w, h;
+
+ if (!directfb_surface_update_buffers( &surf->base, attachment_mask ))
+ return FALSE;
+
+ if (seq_num)
+ *seq_num = surf->client_stamp;
+
+ if (textures)
+ resource_surface_get_resources( surf->rsurf, textures, attachment_mask );
+
+ resource_surface_get_size( surf->rsurf, &w, &h );
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+
+ return TRUE;
+}
+
+static void
+directfb_surface_wait( struct native_surface *nsurf )
+{
+ /* no-op */
+}
+
+static void
+directfb_surface_destroy( struct native_surface *nsurf )
+{
+ struct directfb_surface *surf =
+ directfb_surface( nsurf );
+
+ surf->pSurface->Release( surf->pSurface );
+ resource_surface_destroy( surf->rsurf );
+ FREE( surf );
+}
+
+static boolean
+directfb_display_get_pixmap_format( struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format )
+{
+ return false;
+}
+
+static boolean
+directfb_display_copy_to_pixmap( struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ struct pipe_resource *src)
+{
+ /* for eglCopyBuffers() */
+ return false;
+}
+
+static bool
+supported_pixelformat( DFBSurfacePixelFormat fmt )
+{
+ switch (fmt) {
+ case DSPF_RGB16:
+ case DSPF_ARGB:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static DFBSurfacePixelFormat
+dfb_pixelformat( enum pipe_format format )
+{
+ switch (format) {
+ case PIPE_FORMAT_B5G6R5_UNORM: /* 16bit RGB */
+ return DSPF_RGB16;
+ case PIPE_FORMAT_B8G8R8A8_UNORM: /* 32bit ARGB */
+ return DSPF_ARGB;
+ default:
+ return DSPF_UNKNOWN;
+ }
+}
+
+static struct native_surface*
+directfb_display_create_pixmap_surface( struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct directfb_display *display =
+ directfb_display( ndpy );
+ struct directfb_surface *surf;
+
+ DFBSurfaceCapabilities caps;
+ DFBSurfacePixelFormat fmt;
+ DFBResult ret;
+
+ int w, h;
+
+ IDirectFBSurface *pSurface = (IDirectFBSurface*)pix;
+ if (!pSurface)
+ return NULL;
+
+ ret = pSurface->GetSize( pSurface, &w, &h );
+ if (ret)
+ return NULL;
+ if (w <= 0 || h <= 0)
+ return NULL;
+ ret = pSurface->GetCapabilities( pSurface, &caps );
+ if (ret)
+ return NULL;
+ if (caps & (DSCAPS_FLIPPING|DSCAPS_SUBSURFACE))
+ return NULL;
+ pSurface->GetPixelFormat( pSurface, &fmt );
+ if (!supported_pixelformat( fmt ))
+ return NULL;
+ if (dfb_pixelformat( nconf->color_format ) != fmt)
+ return NULL;
+
+ surf = CALLOC_STRUCT( directfb_surface );
+ if (!surf)
+ return NULL;
+ ret = pSurface->GetSubSurface( pSurface, NULL, &surf->pSurface );
+ if (ret) {
+ FREE( surf );
+ return NULL;
+ }
+
+ /* store the parent surface in the directfb_display */
+ display->pSurface = pSurface;
+
+ surf->display = display;
+ surf->format = nconf->color_format;
+ surf->rsurf = resource_surface_create( display->base.screen,
+ surf->format,
+ PIPE_BIND_RENDER_TARGET
+ /* winsys will provide dedicated
+ storage for the resource rather
+ than letting llvmpipe allocate
+ from system memory */
+ | PIPE_BIND_DISPLAY_TARGET );
+ if (!surf->rsurf) {
+ FREE( surf );
+ return NULL;
+ }
+
+ directfb_surface_update_geometry( &surf->base );
+
+ surf->base.destroy = directfb_surface_destroy;
+ surf->base.present = directfb_surface_present;
+ surf->base.validate = directfb_surface_validate;
+ surf->base.wait = directfb_surface_wait;
+
+ return &surf->base;
+}
+
+static struct native_surface *
+directfb_display_create_window_surface( struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf )
+{
+ struct directfb_display *display =
+ directfb_display( ndpy );
+ struct directfb_surface *surf;
+
+ DFBSurfaceCapabilities caps;
+ DFBSurfacePixelFormat fmt;
+ DFBResult ret;
+
+ int w, h;
+
+ IDirectFBSurface *pSurface = (IDirectFBSurface*)win;
+ if (!pSurface)
+ return NULL;
+
+ ret = pSurface->GetSize( pSurface, &w, &h );
+ if (ret)
+ return NULL;
+ if (w <= 0 || h <= 0)
+ return NULL;
+ ret = pSurface->GetCapabilities( pSurface, &caps );
+ if (ret)
+ return NULL;
+ if (!(caps & DSCAPS_FLIPPING)
+ || (caps & DSCAPS_SUBSURFACE))
+ return NULL;
+ pSurface->GetPixelFormat( pSurface, &fmt );
+ if (!supported_pixelformat( fmt ))
+ return NULL;
+ if (dfb_pixelformat( nconf->color_format ) != fmt)
+ return NULL;
+
+ surf = CALLOC_STRUCT( directfb_surface );
+ if (!surf)
+ return NULL;
+ ret = pSurface->GetSubSurface( pSurface, NULL, &surf->pSurface );
+ if (ret) {
+ FREE( surf );
+ return NULL;
+ }
+
+ /* store the parent surface in the directfb_display */
+ display->pSurface = pSurface;
+
+ surf->display = display;
+ surf->format = nconf->color_format;
+ surf->rsurf = resource_surface_create( display->base.screen,
+ surf->format,
+ PIPE_BIND_RENDER_TARGET
+ | PIPE_BIND_DISPLAY_TARGET );
+ if (!surf->rsurf) {
+ FREE( surf );
+ return NULL;
+ }
+
+ directfb_surface_update_geometry( &surf->base );
+
+ surf->base.destroy = directfb_surface_destroy;
+ surf->base.present = directfb_surface_present;
+ surf->base.validate = directfb_surface_validate;
+ surf->base.wait = directfb_surface_wait;
+
+ return &surf->base;
+}
+
+static struct native_display *
+directfb_display_create( const struct native_event_handler *event_handler )
+{
+ struct directfb_display *display;
+
+ display = CALLOC_STRUCT( directfb_display );
+ if (!display)
+ return NULL;
+
+ display->event_handler = event_handler;
+
+ display->base.init_screen = directfb_display_init_screen;
+ display->base.destroy = directfb_display_destroy;
+ display->base.get_param = directfb_display_get_param;
+ display->base.get_configs = directfb_display_get_configs;
+ display->base.get_pixmap_format = directfb_display_get_pixmap_format;
+ display->base.copy_to_pixmap = directfb_display_copy_to_pixmap;
+ display->base.create_pixmap_surface =
+ directfb_display_create_pixmap_surface;
+ display->base.create_window_surface =
+ directfb_display_create_window_surface;
+
+ return &display->base;
+}
+
+static const struct native_event_handler *directfb_event_handler;
+
+static struct native_display*
+native_create_display( void *dpy, boolean use_sw )
+{
+ struct native_display *display =
+ directfb_display_create( directfb_event_handler );
+ return display;
+}
+
+static const struct native_platform directfb_platform = {
+ "DirectFB",
+ native_create_display
+};
+
+const struct native_platform *
+native_get_directfb_platform( const struct native_event_handler *event_handler )
+{
+ directfb_event_handler = event_handler;
+ return &directfb_platform;
+}
--
1.8.1.4
More information about the mesa-dev
mailing list