If you know how X works, you won't have any problems... You can
look at some real code here.
fd=fopen("/dev/fb0",O_RDWR);
/* ... */
/* initialize the graphic mode as usual, for example 640x480x16
*/
/* ... */
/* now we build a display list which will be later executed */
p=req_buf;
FBA_SetFG(p,0);
/* set black color */
FBA_FillRect(p,0,0,640,480,FBA_ROP_COPY); /* draw a
big rectangle */
FBA_SetFG(p,0xffff);
/* set white color */
FBA_Point(p,320,240);
/* draw a pixel a the center */
/* we set the display list */
disp_list.list_ptr=req_buf;
disp_list.list_size=p - req_buf;
/* now we execute the display list. The process is stopped until
the display list is completed. The
frame buffer driver call schedule() to ensure that the other tasks
are not freezed during long
requests */
ioctl(fd,FBIOACCEL_EXEC,&disp_list);
/* ... */
#define FBA_FillRect(p,x,y,xsize,ysize,rop) \
{\
p[0]=FBA_OP_FillRect;\
p[1]=x;\
p[2]=y;\
p[3]=xsize;\
p[4]=ysize;\
p[5]=rop;\
p+=6;\
}
XXX: using a structure may be better. Care must be taken with the structure definitions in case of a 64 bit architecture.
There is only one graphic context per frame buffer device. Its means that only one process at a time can use the acceleration safely. When a console switch occurs, the process must stop sending accelerated commands and store its graphic context itself to let another process (or the console) use the acceleration. The idea behind is that the kernel acceleration must be as simple as possible. There is no point in introducing extra complexity in the kernel to handle the console switches. This is coherent with the current approach where each graphic process must handle itself most of the console switch.
The graphic context must hold at least the following values :
fg_color | Foreground color |
bg_color | Background color |
clip_x1
clip_y1 clip_x2 clip_y2 |
Current clipping rectangle. Must be inside the rectangle (0,0,xres_virtual,yres_virtual). |
The current clipping rectangle guaranties that no accelerated command
can modify some memory outside the graphical memory. This is important
with some badly designed graphic cards where there is no memory protection
within the acceleration.
This current clipping rectangle makes it possible to use the hardware
clippers available in some graphic cards. The X11 server can use this clipping
rectangle to optimize the most common case where a primtive is drawn in
a visible clipped window.
XXX: another solution would be to use a new device : /dev/fbXaccel . Writes to this device would be the same as doing the FBIOACCEL_EXEC ioctl. This is not currently implemented.
Example:
int tmp;
tmp=FBA_OP_FillRect;
ioctl(fd,FBIOACCEL_CAP,&tmp);
switch(tmp) {
case 0: /* this command is not implemented */
case 1: /* this command is software emulated in the kernel */
case 2: /* this command is hardware accelerated in the kenel */
}