diff --git a/gfxdrivers/gles2/gles2_2d.c b/gfxdrivers/gles2/gles2_2d.c index c98ca9dbf..42a9f7342 100644 --- a/gfxdrivers/gles2/gles2_2d.c +++ b/gfxdrivers/gles2/gles2_2d.c @@ -450,15 +450,18 @@ gles2_validate_COLORKEY(GLES2DriverData *gdrv, D_DEBUG_AT(GLES2__2D, "%s()\n", __FUNCTION__); - /* convert RGB32 color values to int */ - int r = (state->src_colorkey & 0x00FF0000) >> 16; - int g = (state->src_colorkey & 0x0000FF00) >> 8; - int b = (state->src_colorkey & 0x000000FF) ; + /* convert color values to int */ + DFBColor colorkey; + DFBColor tolerance; + DFBSurfacePixelFormat format = state->source->config.format; + dfb_pixel_to_color(format, state->src_colorkey, &colorkey); + dfb_pixel_tolerance(format, &tolerance); /* send converted color key to shader */ - glUniform3i( prog->dfbColorkey, r, g, b ); + glUniform3i( prog->dfbColorkey, colorkey.r, colorkey.g, colorkey.b ); + glUniform3i( prog->dfbColorkeyTolerance, tolerance.r, tolerance.g, tolerance.b); - D_DEBUG_AT(GLES2__2D, " -> loaded colorkey %d %d %d\n", r, g, b); + D_DEBUG_AT(GLES2__2D, " -> loaded colorkey %d %d %d\n", colorkey.r, colorkey.g, colorkey.b); // Set the flag. GLES2_VALIDATE(COLORKEY); diff --git a/gfxdrivers/gles2/gles2_gfxdriver.h b/gfxdrivers/gles2/gles2_gfxdriver.h index 4368969b7..1f91cad52 100644 --- a/gfxdrivers/gles2/gles2_gfxdriver.h +++ b/gfxdrivers/gles2/gles2_gfxdriver.h @@ -76,6 +76,7 @@ typedef struct { GLint dfbMVPMatrix; // location of model-view-projection matrix GLint dfbColor; // location of global RGBA color GLint dfbColorkey; // location of colorkey RGB color + GLint dfbColorkeyTolerance; // location of colorkey RGB color tolerance GLint dfbTexScale; // location of scale factors to normalized tex coords GLint dfbSampler; // location of 2D texture sampler char *name; // program object name for debugging diff --git a/gfxdrivers/gles2/gles2_shaders.c b/gfxdrivers/gles2/gles2_shaders.c index 7596004be..9934ec12b 100644 --- a/gfxdrivers/gles2/gles2_shaders.c +++ b/gfxdrivers/gles2/gles2_shaders.c @@ -164,6 +164,7 @@ gles2_init_shader_programs(GLES2DeviceData *dev) dev->progs[i].dfbMVPMatrix = -1; dev->progs[i].dfbColor = -1; dev->progs[i].dfbColorkey = -1; + dev->progs[i].dfbColorkeyTolerance = -1; dev->progs[i].dfbTexScale = -1; dev->progs[i].dfbSampler = -1; dev->progs[i].v_flags = 0; @@ -325,6 +326,7 @@ gles2_init_shader_programs(GLES2DeviceData *dev) GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY, dfbTexScale); GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY, dfbSampler); GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY, dfbColorkey); + GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY, dfbColorkeyTolerance); // For now we always use texture unit 0 (GL_TEXTURE0). glUniform1i(dev->progs[GLES2_BLIT_COLORKEY].dfbSampler, 0); @@ -350,6 +352,7 @@ gles2_init_shader_programs(GLES2DeviceData *dev) GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY_MAT, dfbTexScale); GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY_MAT, dfbSampler); GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY_MAT, dfbColorkey); + GET_UNIFORM_LOCATION(dev, GLES2_BLIT_COLORKEY_MAT, dfbColorkeyTolerance); // For now we always use texture unit 0 (GL_TEXTURE0). glUniform1i(dev->progs[GLES2_BLIT_COLORKEY_MAT].dfbSampler, 0); diff --git a/gfxdrivers/gles2/gles2_shaders.h b/gfxdrivers/gles2/gles2_shaders.h index 41c21c917..335d75d56 100644 --- a/gfxdrivers/gles2/gles2_shaders.h +++ b/gfxdrivers/gles2/gles2_shaders.h @@ -167,16 +167,20 @@ static const char *blit_colorkey_frag_src = " \ uniform sampler2D dfbSampler; \ uniform "LOWP" vec4 dfbColor; \ uniform ivec3 dfbColorkey; \ +uniform ivec3 dfbColorkeyTolerance; \ varying "LOWP" vec2 varTexCoord; \ +\ +ivec3 round_down(ivec3 x, ivec3 divisor) \ +{ \ + return (x / divisor) * divisor; \ +} \ +\ void main (void) \ { \ "HIGHP" vec4 value = texture2D(dfbSampler, varTexCoord); \ \ - int r = int(value.r*255.0+0.5); \ - int g = int(value.g*255.0+0.5); \ - int b = int(value.b*255.0+0.5); \ -\ - if (r == dfbColorkey.x && g == dfbColorkey.y && b == dfbColorkey.z) \ + ivec3 color = ivec3(value.rgb * vec3(255.0) + vec3(0.5)); \ + if (round_down(color, dfbColorkeyTolerance) == round_down(dfbColorkey, dfbColorkeyTolerance)) \ discard; \ \ gl_FragColor = value * dfbColor; \ diff --git a/src/display/idirectfbsurface.c b/src/display/idirectfbsurface.c index 8f7adec4e..b6b995537 100644 --- a/src/display/idirectfbsurface.c +++ b/src/display/idirectfbsurface.c @@ -2574,6 +2574,8 @@ IDirectFBSurface_DrawString( IDirectFBSurface *thiz, return ret; } + D_ASSERT( num <= bytes ); + /* Calculate string width. */ for (i=0; ir = 1<<(8-5); + tolerance->g = 1<<(8-6); + tolerance->b = 1<<(8-5); + break; + default: + tolerance->r = 1; + tolerance->g = 1; + tolerance->b = 1; + } +} + unsigned long dfb_pixel_from_color( DFBSurfacePixelFormat format, const DFBColor *color ) diff --git a/src/gfx/convert.h b/src/gfx/convert.h index f8b3ccfd4..42cf1381d 100644 --- a/src/gfx/convert.h +++ b/src/gfx/convert.h @@ -453,6 +453,10 @@ void dfb_pixel_to_color ( DFBSurfacePixelFormat format, unsigned long pixel, DFBColor *ret_color ); +void dfb_pixel_tolerance ( DFBSurfacePixelFormat format, + DFBColor *ret_color ); + + unsigned long dfb_pixel_from_color( DFBSurfacePixelFormat format, const DFBColor *color ); diff --git a/src/media/idirectfbfont.c b/src/media/idirectfbfont.c index 62401a727..65cd03fd6 100644 --- a/src/media/idirectfbfont.c +++ b/src/media/idirectfbfont.c @@ -316,6 +316,8 @@ IDirectFBFont_GetStringExtents( IDirectFBFont *thiz, return ret; } + D_ASSERT( num <= bytes ); + for (i=0; i D_ARRAY_SIZE(dfb_config->layers)) { + if (id < 0 || id >= D_ARRAY_SIZE(dfb_config->layers)) { D_ERROR("DirectFB/Config '%s': ID %d out of bounds!\n", name, id); return DFB_INVARG; } @@ -2455,7 +2455,7 @@ DFBResult dfb_config_init( int *argc, char *(*argv[]) ) DFBResult dfb_config_read( const char *filename ) { DFBResult ret = DFB_OK; - char line[400]; + char line[400+1]; FILE *f; char *slash = 0; @@ -2491,7 +2491,7 @@ DFBResult dfb_config_read( const char *filename ) } /* must copy filename for path, due to const'ness */ - char nwd[strlen(filename)]; + char nwd[strlen(filename)+1]; strcpy( nwd, filename ); nwd[slash-filename] = 0; if (chdir( nwd )) diff --git a/systems/egl/egl_primary.c b/systems/egl/egl_primary.c index 527cb5c3b..e75074753 100644 --- a/systems/egl/egl_primary.c +++ b/systems/egl/egl_primary.c @@ -406,6 +406,7 @@ primaryUpdateRegion( CoreLayer *layer, if (left_update && !dfb_region_region_intersect( ®ion, left_update )) return DFB_OK; + eglSurfaceAttrib(egl->eglDisplay, egl->eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); eglSwapBuffers(egl->eglDisplay, egl->eglSurface); diff --git a/systems/egl/egl_surface_pool.c b/systems/egl/egl_surface_pool.c index 422d83891..8f9eb914d 100644 --- a/systems/egl/egl_surface_pool.c +++ b/systems/egl/egl_surface_pool.c @@ -384,7 +384,22 @@ eglAllocateBuffer( CoreSurfacePool *pool, return DFB_FAILURE; } - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->config.size.w, surface->config.size.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); + switch (allocation->config.format) { + case DSPF_RGB32: + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->config.size.w, surface->config.size.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); + case DSPF_ARGB: + glTexImage2D( GL_TEXTURE_2D, 0, GL_BGRA_EXT, surface->config.size.w, surface->config.size.h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL ); + break; + case DSPF_RGB16: + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, surface->config.size.w, surface->config.size.h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL ); + break; + case DSPF_LUT8: + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->config.size.w, surface->config.size.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); + break; + default: + D_ERROR( "DirectFB/EGL: glTexImage2D() unknown format %x\n" , allocation->config.format); + return DFB_UNSUPPORTED; + } // glEGLImageTargetTexture2DOES( GL_TEXTURE_2D, alloc->eglImage ); if ((err = eglGetError()) != EGL_SUCCESS) { @@ -752,11 +767,21 @@ fboWrite( CoreSurfacePool *pool, glPixelStorei( GL_UNPACK_ALIGNMENT, 8 ); - if (allocation->config.format == DSPF_ABGR) { - glTexSubImage2D(GL_TEXTURE_2D, 0, rect->x, rect->y, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, source); - } - else { - glTexSubImage2D(GL_TEXTURE_2D, 0, rect->x, rect->y, rect->w, rect->h, GL_BGRA_EXT, GL_UNSIGNED_BYTE, source); + switch (allocation->config.format) + { + case DSPF_ABGR: + glTexSubImage2D(GL_TEXTURE_2D, 0, rect->x, rect->y, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, source); + break; + case DSPF_ARGB: + glTexSubImage2D(GL_TEXTURE_2D, 0, rect->x, rect->y, rect->w, rect->h, GL_BGRA_EXT, GL_UNSIGNED_BYTE, source); + break; + case DSPF_RGB16: + glTexSubImage2D(GL_TEXTURE_2D, 0, rect->x, rect->y, rect->w, rect->h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, source); + break; + default: + D_ERROR( "DirectFB/RGL2D: glTexSubImage2D() unknown format %x\n", allocation->config.format ); + return DFB_UNSUPPORTED; + } if ((err = glGetError()) != 0) { diff --git a/systems/egl/egl_system.c b/systems/egl/egl_system.c index dfaa305a7..597fc4c2d 100644 --- a/systems/egl/egl_system.c +++ b/systems/egl/egl_system.c @@ -53,7 +53,14 @@ #include -#define RASPBERRY_PI +//#define RASPBERRY_PI +#define EGL_WAYLAND + +#ifdef EGL_WAYLAND +#include +#include +#endif + DFB_CORE_SYSTEM( egl ) @@ -63,6 +70,78 @@ static EGLData *m_data; /* FIXME: Fix Core System API to pass data in all fun /**********************************************************************************************************************/ +#if defined EGL_WAYLAND +struct geometry { + int width, height; +}; + +struct wayland_context +{ + struct wl_display *display; + struct wl_surface *surface; + struct wl_compositor *compositor; + struct wl_shell *shell; + struct wl_shell_surface *shell_surface; + struct geometry window_size; + struct wl_egl_window *native; +}; + +static void *wl_event_loop(void *arg) +{ + struct wayland_context *context = arg; + wl_display_flush(context->display); + while (1) + { + wl_display_dispatch(context->display); + } + return NULL; +} + +static void handle_shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + +static void handle_shell_surface_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height) +{ +} + +static void handle_shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface) +{ +} + +static const struct wl_shell_surface_listener shell_surface_listener = +{ + handle_shell_surface_ping, + handle_shell_surface_configure, + handle_shell_surface_popup_done +}; + +static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) +{ + struct wayland_context *d = data; + + if (strcmp(interface, "wl_compositor") == 0) { + d->compositor = + wl_registry_bind(registry, name, + &wl_compositor_interface, 1); + } else if (strcmp(interface, "wl_shell") == 0) { + d->shell = wl_registry_bind(registry, name, + &wl_shell_interface, 1); + + } +} + +static void registry_handle_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ +} + +static const struct wl_registry_listener registry_listener = { + registry_handle_global, + registry_handle_global_remove +}; +#endif static DFBResult InitEGL( EGLData *egl ) @@ -72,7 +151,7 @@ InitEGL( EGLData *egl ) EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; #ifdef RASPBERRY_PI - static EGL_DISPMANX_WINDOW_T nativewindow; + static EGL_DISPMANX_WINDOW_T *nativewindow = malloc(sizeof(EGL_DISPMANX_WINDOW_T));; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; @@ -82,7 +161,31 @@ InitEGL( EGLData *egl ) bcm_host_init(); #endif + +#if defined EGL_WAYLAND + struct wayland_context *context = calloc(1, sizeof(*context)); + + context->window_size.width = 1920; + context->window_size.height = 1080; + + context->display = wl_display_connect(NULL); + struct wl_registry *registry = wl_display_get_registry(context->display); + wl_registry_add_listener(registry, ®istry_listener, context); + wl_display_dispatch(context->display); + wl_display_roundtrip(context->display); + + egl->eglDisplay = eglGetDisplay(context->display); + + context->surface = wl_compositor_create_surface(context->compositor); + + context->shell_surface = wl_shell_get_shell_surface(context->shell, context->surface); + wl_shell_surface_add_listener(context->shell_surface, &shell_surface_listener, context); + wl_shell_surface_set_fullscreen(context->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 60000, NULL); + +#endif +#if !defined EGL_WAYLAND egl->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); +#endif if (!eglInitialize(egl->eglDisplay, &iMajorVersion, &iMinorVersion)) return DFB_INIT; @@ -140,15 +243,19 @@ InitEGL( EGLData *egl ) dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0, &dst_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, 0, 0, 0); - - nativewindow.element = dispman_element; - nativewindow.width = egl->DisplayWidth; - nativewindow.height = egl->DisplayHeight; + + nativewindow->element = dispman_element; + nativewindow->width = egl->DisplayWidth; + nativewindow->height = egl->DisplayHeight; vc_dispmanx_update_submit_sync( dispman_update ); +#endif +#ifdef EGL_WAYLAND + context->native = wl_egl_window_create(context->surface, context->window_size.width, context->window_size.height); + void *nativewindow = context->native; #endif - egl->eglSurface = eglCreateWindowSurface( egl->eglDisplay, egl->eglConfig, &nativewindow, NULL ); + egl->eglSurface = eglCreateWindowSurface( egl->eglDisplay, egl->eglConfig, nativewindow, NULL ); if (!TestEGLError("eglCreateWindowSurface")) return DFB_INIT; @@ -166,6 +273,12 @@ InitEGL( EGLData *egl ) //return DFB_FAILURE; } +#ifdef EGL_WAYLAND + wl_display_roundtrip(context->display); + pthread_t pt; + pthread_create(&pt, NULL, wl_event_loop, context); +#endif + return DFB_OK; } diff --git a/systems/egl/egl_system.h b/systems/egl/egl_system.h index b2a0c582a..03f5e2eea 100644 --- a/systems/egl/egl_system.h +++ b/systems/egl/egl_system.h @@ -109,6 +109,7 @@ EGLAPI void EGLAPIENTRY eglCreateGlobalImageBRCM(EGLint width, EGLint height, EG #define EGL_PIXEL_FORMAT_XRGB_8888_BRCM 2 #define EGL_PIXEL_FORMAT_ARGB_8888_BRCM 1 +#ifndef _BEGL_DISPPLATFORM_H__ /* This is already defined */ typedef enum { /* These formats are render target formats, but cannot be textured from */ @@ -135,6 +136,7 @@ typedef enum /* Can be used to return back an invalid format */ BEGL_BufferFormat_INVALID } BEGL_BufferFormat; +#endif typedef struct { diff --git a/systems/fbdev/fbdev.c b/systems/fbdev/fbdev.c index aee785b53..529735813 100644 --- a/systems/fbdev/fbdev.c +++ b/systems/fbdev/fbdev.c @@ -330,7 +330,7 @@ static DFBResult dfb_fbdev_open( void ) static void dfb_fbdev_get_pci_info( FBDevShared *shared ) { - char buf[512]; + char buf[512+1]; int vendor = -1; int model = -1; FILE *fp;