I have written a very simple little program to test the global opacity
capability of my custom gfxdriver for the PXA27x.
I am trying to set a background image into a base layer, and then blit
another image to another overlay that supports global opacity. I need to
see that the background image shows through the foreground image, of
varying amounts controlled by layer->SetOpacity().
Attached is the simple program to test this. If I comment out the call
to setup_fg_image(), I can see the background image, and if I comment
out the call to setup_bg_image(), I can see the foreground image. But
not both at the same time, it seems blitting the foreground image always
erases the background image first. Which makes me think that when I
->Blit and ->Flip the foreground surface, the surface is actually
getting sent to the backround layer, not the foreground layer.
So I don't really understand how to associate a Surface with a
DisplayLayer. I am using layer->GetSurface() and I assume that is one
way to make the surface <--> layer association, or am I wrong?
Thanks in advance for the help.
Steve
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <directfb.h>
/* macro for a safe call to DirectFB functions */
#define DFBCHECK(x...) \
err = x; \
if (err != DFB_OK) { \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal (#x, err); \
}
#define BACKGROUND_NAME "background.jpg"
#define FOREGROUND_NAME "apple-red.png"
static IDirectFB *dfb;
static IDirectFBDisplayLayer *bg_layer = NULL;
static IDirectFBDisplayLayer *fg_layer = NULL;
static DFBResult err;
static void
exit_application(int exitcode)
{
/* Release the layers. */
if (fg_layer)
fg_layer->Release( fg_layer );
if (bg_layer)
bg_layer->Release( bg_layer );
dfb->Release (dfb);
exit(exitcode);
}
static DFBEnumerationResult
display_layer_callback( DFBDisplayLayerID id,
DFBDisplayLayerDescription desc,
void *arg )
{
if (!bg_layer && (desc.type & DLTF_BACKGROUND)) {
printf( "Using %s for background\n", desc.name );
DFBCHECK(dfb->GetDisplayLayer( dfb, id, &bg_layer ));
} else if (!fg_layer && (desc.caps & DLCAPS_OPACITY)) {
printf( "Using %s for opacity-supported foreground\n",
desc.name );
DFBCHECK(dfb->GetDisplayLayer( dfb, id, &fg_layer ));
}
return DFB_OK;
}
static void
setup_bg_image(IDirectFBDisplayLayer *layer)
{
DFBDisplayLayerConfig config;
IDirectFBImageProvider *provider;
DFBSurfaceDescription desc;
IDirectFBSurface *background;
layer->SetCooperativeLevel( layer, DLSCL_ADMINISTRATIVE );
DFBCHECK(dfb->CreateImageProvider( dfb, BACKGROUND_NAME,
&provider ));
layer->GetConfiguration( layer, &config );
desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT;
desc.width = config.width;
desc.height = config.height;
DFBCHECK(dfb->CreateSurface( dfb, &desc, &background ) );
provider->RenderTo( provider, background, NULL );
provider->Release( provider );
config.flags = DLCONF_BUFFERMODE;
config.buffermode = DLBM_BACKSYSTEM;
layer->SetConfiguration( layer, &config );
layer->SetBackgroundImage( layer, background );
layer->SetBackgroundMode( layer, DLBM_IMAGE );
background->Release (background);
}
static void
setup_fg_image(IDirectFBDisplayLayer *layer)
{
DFBDisplayLayerConfig config;
IDirectFBImageProvider *provider;
DFBSurfaceDescription sdesc;
IDirectFBSurface *foreground;
IDirectFBSurface *image;
layer->SetCooperativeLevel( layer, DLSCL_EXCLUSIVE );
DFBCHECK(dfb->CreateImageProvider (dfb, FOREGROUND_NAME,
&provider));
DFBCHECK(provider->GetSurfaceDescription (provider, &sdesc));
DFBCHECK(dfb->CreateSurface (dfb, &sdesc, &image));
provider->RenderTo (provider, image, NULL);
provider->Release (provider);
/* Get the screen size etc. */
layer->GetConfiguration( layer, &config );
config.flags = DLCONF_BUFFERMODE;
config.buffermode = DLBM_BACKSYSTEM;
layer->SetConfiguration( layer, &config );
layer->GetSurface( layer, &foreground );
layer->SetScreenRectangle(layer, config.width/2, config.height/2,
sdesc.width, sdesc.height);
/* set to half-opaque */
layer->SetOpacity( layer, 0x80 );
foreground->Blit( foreground, image, NULL, 0, 0);
foreground->Flip( foreground, NULL, 0 );
image->Release (image);
foreground->Release (foreground);
}
void handler (int sn)
{
fprintf(stderr, "SIGINT caught\n");
exit_application(0);
}
int main (int argc, char **argv)
{
struct sigaction sa;
DFBResult ret;
memset (&sa, 0, sizeof(sa));
sa.sa_handler = &handler;
DFBCHECK (DirectFBInit (&argc, &argv));
/* create the super interface */
DFBCHECK (DirectFBCreate (&dfb));
ret = dfb->EnumDisplayLayers( dfb, display_layer_callback, NULL );
if (ret)
DirectFBError( "IDirectFBScreen::EnumDisplayLayers", ret );
if (!bg_layer) {
printf( "No background-supporting layer found\n");
exit_application(1);
}
if (!fg_layer) {
printf( "No global opacity-supporting layer found\n");
exit_application(1);
}
/* setup background layer and load background image to it */
setup_bg_image(bg_layer);
/* setup foreground layer and load image to it, with global opacity */
setup_fg_image(fg_layer);
/* wait for user to hit Ctrl-C */
printf("Hit Ctrl-C to quit\n");
sigaction(SIGINT, &sa, NULL);
while(1) pause();
exit_application(0);
}
_______________________________________________
directfb-dev mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev