st/egl: update fbdev backend
Considering fbdev as an in-kernel window system, - opening a device opens a connection - there is only one window: the framebuffer - fb_var_screeninfo decides window position, size, and even color format - there is no pixmap Now EGL is built on top of this window system. So we should have - the fd as the handle of the native display - reject all but one native window: NULL - no pixmap support modeset support is still around, but it should be removed soon.
This commit is contained in:
parent
a2537bbc95
commit
aa281dd392
|
@ -26,6 +26,21 @@
|
|||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Considering fbdev as an in-kernel window system,
|
||||
*
|
||||
* - opening a device opens a connection
|
||||
* - there is only one window: the framebuffer
|
||||
* - fb_var_screeninfo decides window position, size, and even color format
|
||||
* - there is no pixmap
|
||||
*
|
||||
* Now EGL is built on top of this window system. So we should have
|
||||
*
|
||||
* - the fd as the handle of the native display
|
||||
* - reject all but one native window: NULL
|
||||
* - no pixmap support
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -48,13 +63,10 @@ struct fbdev_display {
|
|||
const struct native_event_handler *event_handler;
|
||||
|
||||
struct fb_fix_screeninfo finfo;
|
||||
struct fb_var_screeninfo vinfo;
|
||||
|
||||
struct fb_var_screeninfo config_vinfo;
|
||||
struct native_config config;
|
||||
struct native_connector connector;
|
||||
struct native_mode mode;
|
||||
|
||||
struct fbdev_surface *current_surface;
|
||||
boolean assume_fixed_vinfo;
|
||||
};
|
||||
|
||||
struct fbdev_surface {
|
||||
|
@ -66,7 +78,7 @@ struct fbdev_surface {
|
|||
|
||||
unsigned int sequence_number;
|
||||
|
||||
boolean is_current;
|
||||
struct fbdev_sw_drawable drawable;
|
||||
};
|
||||
|
||||
static INLINE struct fbdev_display *
|
||||
|
@ -103,38 +115,70 @@ fbdev_surface_validate(struct native_surface *nsurf, uint attachment_mask,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_surface_flush_frontbuffer(struct native_surface *nsurf)
|
||||
static enum pipe_format
|
||||
vinfo_to_format(const struct fb_var_screeninfo *vinfo)
|
||||
{
|
||||
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
|
||||
enum pipe_format format = PIPE_FORMAT_NONE;
|
||||
|
||||
if (!fbsurf->is_current)
|
||||
return TRUE;
|
||||
/* should also check channel offsets... */
|
||||
switch (vinfo->bits_per_pixel) {
|
||||
case 32:
|
||||
if (vinfo->red.length == 8 &&
|
||||
vinfo->green.length == 8 &&
|
||||
vinfo->blue.length == 8) {
|
||||
format = (vinfo->transp.length == 8) ?
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (vinfo->red.length == 5 &&
|
||||
vinfo->green.length == 6 &&
|
||||
vinfo->blue.length == 5 &&
|
||||
vinfo->transp.length == 0)
|
||||
format = PIPE_FORMAT_B5G6R5_UNORM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return resource_surface_present(fbsurf->rsurf,
|
||||
NATIVE_ATTACHMENT_FRONT_LEFT, NULL);
|
||||
return format;
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_surface_swap_buffers(struct native_surface *nsurf)
|
||||
fbdev_surface_update_drawable(struct native_surface *nsurf,
|
||||
const struct fb_var_screeninfo *vinfo)
|
||||
{
|
||||
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
|
||||
struct fbdev_display *fbdpy = fbsurf->fbdpy;
|
||||
boolean ret = TRUE;
|
||||
unsigned x, y, width, height;
|
||||
|
||||
if (fbsurf->is_current) {
|
||||
ret = resource_surface_present(fbsurf->rsurf,
|
||||
NATIVE_ATTACHMENT_BACK_LEFT, NULL);
|
||||
x = vinfo->xoffset;
|
||||
y = vinfo->yoffset;
|
||||
width = MIN2(vinfo->xres, fbsurf->width);
|
||||
height = MIN2(vinfo->yres, fbsurf->height);
|
||||
|
||||
/* sanitize the values */
|
||||
if (x + width > vinfo->xres_virtual) {
|
||||
if (x > vinfo->xres_virtual)
|
||||
width = 0;
|
||||
else
|
||||
width = vinfo->xres_virtual - x;
|
||||
}
|
||||
if (y + height > vinfo->yres_virtual) {
|
||||
if (y > vinfo->yres_virtual)
|
||||
height = 0;
|
||||
else
|
||||
height = vinfo->yres_virtual - y;
|
||||
}
|
||||
|
||||
resource_surface_swap_buffers(fbsurf->rsurf,
|
||||
NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
|
||||
/* the front/back textures are swapped */
|
||||
fbsurf->sequence_number++;
|
||||
fbdpy->event_handler->invalid_surface(&fbdpy->base,
|
||||
&fbsurf->base, fbsurf->sequence_number);
|
||||
fbsurf->drawable.format = vinfo_to_format(vinfo);
|
||||
fbsurf->drawable.x = vinfo->xoffset;
|
||||
fbsurf->drawable.y = vinfo->yoffset;
|
||||
fbsurf->drawable.width = vinfo->xres;
|
||||
fbsurf->drawable.height = vinfo->yres;
|
||||
|
||||
return ret;
|
||||
return (fbsurf->drawable.format != PIPE_FORMAT_NONE &&
|
||||
fbsurf->drawable.width &&
|
||||
fbsurf->drawable.height);
|
||||
}
|
||||
|
||||
static boolean
|
||||
|
@ -143,21 +187,43 @@ fbdev_surface_present(struct native_surface *nsurf,
|
|||
boolean preserve,
|
||||
uint swap_interval)
|
||||
{
|
||||
boolean ret;
|
||||
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
|
||||
struct fbdev_display *fbdpy = fbsurf->fbdpy;
|
||||
boolean ret = FALSE;
|
||||
|
||||
if (preserve || swap_interval)
|
||||
if (swap_interval)
|
||||
return FALSE;
|
||||
if (natt != NATIVE_ATTACHMENT_BACK_LEFT)
|
||||
return FALSE;
|
||||
|
||||
switch (natt) {
|
||||
case NATIVE_ATTACHMENT_FRONT_LEFT:
|
||||
ret = fbdev_surface_flush_frontbuffer(nsurf);
|
||||
break;
|
||||
case NATIVE_ATTACHMENT_BACK_LEFT:
|
||||
ret = fbdev_surface_swap_buffers(nsurf);
|
||||
break;
|
||||
default:
|
||||
ret = FALSE;
|
||||
break;
|
||||
if (!fbdpy->assume_fixed_vinfo) {
|
||||
struct fb_var_screeninfo vinfo;
|
||||
|
||||
memset(&vinfo, 0, sizeof(vinfo));
|
||||
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo))
|
||||
return FALSE;
|
||||
|
||||
/* present the surface */
|
||||
if (fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
|
||||
ret = resource_surface_present(fbsurf->rsurf,
|
||||
natt, (void *) &fbsurf->drawable);
|
||||
}
|
||||
|
||||
fbsurf->width = vinfo.xres;
|
||||
fbsurf->height = vinfo.yres;
|
||||
|
||||
if (resource_surface_set_size(fbsurf->rsurf,
|
||||
fbsurf->width, fbsurf->height)) {
|
||||
/* surface resized */
|
||||
fbsurf->sequence_number++;
|
||||
fbdpy->event_handler->invalid_surface(&fbdpy->base,
|
||||
&fbsurf->base, fbsurf->sequence_number);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* the drawable never changes */
|
||||
ret = resource_surface_present(fbsurf->rsurf,
|
||||
natt, (void *) &fbsurf->drawable);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -179,26 +245,48 @@ fbdev_surface_destroy(struct native_surface *nsurf)
|
|||
}
|
||||
|
||||
static struct native_surface *
|
||||
fbdev_display_create_scanout_surface(struct native_display *ndpy,
|
||||
const struct native_config *nconf,
|
||||
uint width, uint height)
|
||||
fbdev_display_create_window_surface(struct native_display *ndpy,
|
||||
EGLNativeWindowType win,
|
||||
const struct native_config *nconf)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
struct fbdev_surface *fbsurf;
|
||||
struct fb_var_screeninfo vinfo;
|
||||
|
||||
/* there is only one native window: NULL */
|
||||
if (win)
|
||||
return NULL;
|
||||
|
||||
fbsurf = CALLOC_STRUCT(fbdev_surface);
|
||||
if (!fbsurf)
|
||||
return NULL;
|
||||
|
||||
fbsurf->fbdpy = fbdpy;
|
||||
fbsurf->width = width;
|
||||
fbsurf->height = height;
|
||||
|
||||
/* get current vinfo */
|
||||
if (fbdpy->assume_fixed_vinfo) {
|
||||
vinfo = fbdpy->config_vinfo;
|
||||
}
|
||||
else {
|
||||
memset(&vinfo, 0, sizeof(vinfo));
|
||||
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo)) {
|
||||
FREE(fbsurf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fbsurf->width = vinfo.xres;
|
||||
fbsurf->height = vinfo.yres;
|
||||
|
||||
if (!fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
|
||||
FREE(fbsurf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fbsurf->rsurf = resource_surface_create(fbdpy->base.screen,
|
||||
nconf->color_format,
|
||||
PIPE_BIND_RENDER_TARGET |
|
||||
PIPE_BIND_DISPLAY_TARGET |
|
||||
PIPE_BIND_SCANOUT);
|
||||
PIPE_BIND_DISPLAY_TARGET);
|
||||
if (!fbsurf->rsurf) {
|
||||
FREE(fbsurf);
|
||||
return NULL;
|
||||
|
@ -214,42 +302,43 @@ fbdev_display_create_scanout_surface(struct native_display *ndpy,
|
|||
return &fbsurf->base;
|
||||
}
|
||||
|
||||
static struct native_surface *
|
||||
fbdev_display_create_scanout_surface(struct native_display *ndpy,
|
||||
const struct native_config *nconf,
|
||||
uint width, uint height)
|
||||
{
|
||||
return fbdev_display_create_window_surface(ndpy,
|
||||
(EGLNativeWindowType) NULL, nconf);
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_display_program(struct native_display *ndpy, int crtc_idx,
|
||||
struct native_surface *nsurf, uint x, uint y,
|
||||
const struct native_connector **nconns, int num_nconns,
|
||||
const struct native_mode *nmode)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
|
||||
|
||||
if (x || y)
|
||||
return FALSE;
|
||||
|
||||
if (fbdpy->current_surface) {
|
||||
if (fbdpy->current_surface == fbsurf)
|
||||
return TRUE;
|
||||
fbdpy->current_surface->is_current = FALSE;
|
||||
}
|
||||
|
||||
if (fbsurf)
|
||||
fbsurf->is_current = TRUE;
|
||||
fbdpy->current_surface = fbsurf;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const struct native_mode **
|
||||
fbdev_display_get_modes(struct native_display *ndpy,
|
||||
const struct native_connector *nconn,
|
||||
int *num_modes)
|
||||
const struct native_connector *nconn,
|
||||
int *num_modes)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
static struct native_mode mode;
|
||||
const struct native_mode **modes;
|
||||
|
||||
if (!mode.desc) {
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
mode.desc = "Current Mode";
|
||||
mode.width = fbdpy->config_vinfo.xres;
|
||||
mode.height = fbdpy->config_vinfo.yres;
|
||||
mode.refresh_rate = 60 * 1000; /* dummy */
|
||||
}
|
||||
|
||||
modes = MALLOC(sizeof(*modes));
|
||||
if (modes) {
|
||||
modes[0] = &fbdpy->mode;
|
||||
modes[0] = &mode;
|
||||
if (num_modes)
|
||||
*num_modes = 1;
|
||||
}
|
||||
|
@ -261,12 +350,12 @@ static const struct native_connector **
|
|||
fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
|
||||
int *num_crtc)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
static struct native_connector connector;
|
||||
const struct native_connector **connectors;
|
||||
|
||||
connectors = MALLOC(sizeof(*connectors));
|
||||
if (connectors) {
|
||||
connectors[0] = &fbdpy->connector;
|
||||
connectors[0] = &connector;
|
||||
if (num_connectors)
|
||||
*num_connectors = 1;
|
||||
}
|
||||
|
@ -274,7 +363,8 @@ fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
|
|||
return connectors;
|
||||
}
|
||||
|
||||
static struct native_display_modeset fbdev_display_modeset = {
|
||||
/* remove modeset support one day! */
|
||||
static const struct native_display_modeset fbdev_display_modeset = {
|
||||
.get_connectors = fbdev_display_get_connectors,
|
||||
.get_modes = fbdev_display_get_modes,
|
||||
.create_scanout_surface = fbdev_display_create_scanout_surface,
|
||||
|
@ -304,8 +394,10 @@ fbdev_display_get_param(struct native_display *ndpy,
|
|||
int val;
|
||||
|
||||
switch (param) {
|
||||
case NATIVE_PARAM_USE_NATIVE_BUFFER:
|
||||
case NATIVE_PARAM_PRESERVE_BUFFER:
|
||||
val = 1;
|
||||
break;
|
||||
case NATIVE_PARAM_USE_NATIVE_BUFFER:
|
||||
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
|
||||
default:
|
||||
val = 0;
|
||||
|
@ -325,80 +417,13 @@ fbdev_display_destroy(struct native_display *ndpy)
|
|||
FREE(fbdpy);
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_display_init_modes(struct native_display *ndpy)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
struct native_mode *nmode = &fbdpy->mode;
|
||||
|
||||
nmode->desc = "Current Mode";
|
||||
nmode->width = fbdpy->vinfo.xres;
|
||||
nmode->height = fbdpy->vinfo.yres;
|
||||
nmode->refresh_rate = 60 * 1000; /* dummy */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_display_init_connectors(struct native_display *ndpy)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static enum pipe_format
|
||||
vinfo_to_format(const struct fb_var_screeninfo *vinfo)
|
||||
{
|
||||
enum pipe_format format = PIPE_FORMAT_NONE;
|
||||
|
||||
switch (vinfo->bits_per_pixel) {
|
||||
case 32:
|
||||
if (vinfo->red.length == 8 &&
|
||||
vinfo->green.length == 8 &&
|
||||
vinfo->blue.length == 8) {
|
||||
format = (vinfo->transp.length == 8) ?
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (vinfo->red.length == 5 &&
|
||||
vinfo->green.length == 6 &&
|
||||
vinfo->blue.length == 5 &&
|
||||
vinfo->transp.length == 0)
|
||||
format = PIPE_FORMAT_B5G6R5_UNORM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_display_init_configs(struct native_display *ndpy)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
struct native_config *nconf = &fbdpy->config;
|
||||
|
||||
nconf->color_format = vinfo_to_format(&fbdpy->vinfo);
|
||||
if (nconf->color_format == PIPE_FORMAT_NONE)
|
||||
return FALSE;
|
||||
|
||||
nconf->buffer_mask =
|
||||
(1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
|
||||
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
|
||||
|
||||
nconf->scanout_bit = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_display_init_screen(struct native_display *ndpy)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
struct sw_winsys *ws;
|
||||
|
||||
ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format);
|
||||
ws = fbdev_create_sw_winsys(fbdpy->fd);
|
||||
if (!ws)
|
||||
return FALSE;
|
||||
|
||||
|
@ -420,6 +445,26 @@ fbdev_display_init_screen(struct native_display *ndpy)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static boolean
|
||||
fbdev_display_init_config(struct native_display *ndpy)
|
||||
{
|
||||
struct fbdev_display *fbdpy = fbdev_display(ndpy);
|
||||
struct native_config *nconf = &fbdpy->config;
|
||||
|
||||
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->config_vinfo))
|
||||
return FALSE;
|
||||
|
||||
nconf->color_format = vinfo_to_format(&fbdpy->config_vinfo);
|
||||
if (nconf->color_format == PIPE_FORMAT_NONE)
|
||||
return FALSE;
|
||||
|
||||
nconf->buffer_mask = (1 << NATIVE_ATTACHMENT_BACK_LEFT);
|
||||
|
||||
nconf->window_bit = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
fbdev_display_create(int fd, const struct native_event_handler *event_handler)
|
||||
{
|
||||
|
@ -435,23 +480,24 @@ fbdev_display_create(int fd, const struct native_event_handler *event_handler)
|
|||
if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
|
||||
goto fail;
|
||||
|
||||
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->vinfo))
|
||||
goto fail;
|
||||
|
||||
if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
|
||||
fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
|
||||
goto fail;
|
||||
|
||||
if (!fbdev_display_init_configs(&fbdpy->base) ||
|
||||
!fbdev_display_init_connectors(&fbdpy->base) ||
|
||||
!fbdev_display_init_modes(&fbdpy->base))
|
||||
if (!fbdev_display_init_config(&fbdpy->base))
|
||||
goto fail;
|
||||
|
||||
fbdpy->assume_fixed_vinfo = TRUE;
|
||||
|
||||
fbdpy->base.init_screen = fbdev_display_init_screen;
|
||||
fbdpy->base.destroy = fbdev_display_destroy;
|
||||
fbdpy->base.get_param = fbdev_display_get_param;
|
||||
fbdpy->base.get_configs = fbdev_display_get_configs;
|
||||
|
||||
fbdpy->base.create_window_surface = fbdev_display_create_window_surface;
|
||||
|
||||
/* we'd like to remove modeset support one day */
|
||||
fbdpy->config.scanout_bit = TRUE;
|
||||
fbdpy->base.modeset = &fbdev_display_modeset;
|
||||
|
||||
return &fbdpy->base;
|
||||
|
|
|
@ -54,10 +54,8 @@ struct fbdev_sw_winsys
|
|||
struct sw_winsys base;
|
||||
|
||||
int fd;
|
||||
enum pipe_format format;
|
||||
|
||||
struct fb_fix_screeninfo finfo;
|
||||
void *fbmem;
|
||||
unsigned rows;
|
||||
unsigned stride;
|
||||
};
|
||||
|
@ -77,22 +75,53 @@ fbdev_sw_winsys(struct sw_winsys *ws)
|
|||
static void
|
||||
fbdev_displaytarget_display(struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt,
|
||||
void *context_private)
|
||||
void *winsys_private)
|
||||
{
|
||||
struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
|
||||
struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
|
||||
unsigned rows, len, i;
|
||||
struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt);
|
||||
const struct fbdev_sw_drawable *dst =
|
||||
(const struct fbdev_sw_drawable *) winsys_private;
|
||||
unsigned height, row_offset, row_len, i;
|
||||
void *fbmem;
|
||||
|
||||
rows = MIN2(fbdt->height, fbdev->rows);
|
||||
len = util_format_get_stride(fbdt->format, fbdt->width);
|
||||
len = MIN2(len, fbdev->stride);
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
void *dst = fbdev->fbmem + fbdev->stride * i;
|
||||
void *src = fbdt->data + fbdt->stride * i;
|
||||
|
||||
memcpy(dst, src, len);
|
||||
/* FIXME format conversion */
|
||||
if (dst->format != src->format) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
height = dst->height;
|
||||
if (dst->y + dst->height > fbdev->rows) {
|
||||
/* nothing to copy */
|
||||
if (dst->y >= fbdev->rows)
|
||||
return;
|
||||
|
||||
height = fbdev->rows - dst->y;
|
||||
}
|
||||
|
||||
row_offset = util_format_get_stride(dst->format, dst->x);
|
||||
row_len = util_format_get_stride(dst->format, dst->width);
|
||||
if (row_offset + row_len > fbdev->stride) {
|
||||
/* nothing to copy */
|
||||
if (row_offset >= fbdev->stride)
|
||||
return;
|
||||
|
||||
row_len = fbdev->stride - row_offset;
|
||||
}
|
||||
|
||||
fbmem = mmap(0, fbdev->finfo.smem_len,
|
||||
PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
|
||||
if (fbmem == MAP_FAILED)
|
||||
return;
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
char *from = (char *) src->data + src->stride * i;
|
||||
char *to = (char *) fbmem + fbdev->stride * (dst->y + i) + row_offset;
|
||||
|
||||
memcpy(to, from, row_len);
|
||||
}
|
||||
|
||||
munmap(fbmem, fbdev->finfo.smem_len);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -133,13 +162,9 @@ fbdev_displaytarget_create(struct sw_winsys *ws,
|
|||
unsigned alignment,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
|
||||
struct fbdev_sw_displaytarget *fbdt;
|
||||
unsigned nblocksy, size, format_stride;
|
||||
|
||||
if (fbdev->format != format)
|
||||
return NULL;
|
||||
|
||||
fbdt = CALLOC_STRUCT(fbdev_sw_displaytarget);
|
||||
if (!fbdt)
|
||||
return NULL;
|
||||
|
@ -170,8 +195,7 @@ fbdev_is_displaytarget_format_supported(struct sw_winsys *ws,
|
|||
unsigned tex_usage,
|
||||
enum pipe_format format)
|
||||
{
|
||||
struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
|
||||
return (fbdev->format == format);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -179,12 +203,11 @@ fbdev_destroy(struct sw_winsys *ws)
|
|||
{
|
||||
struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
|
||||
|
||||
munmap(fbdev->fbmem, fbdev->finfo.smem_len);
|
||||
FREE(fbdev);
|
||||
}
|
||||
|
||||
struct sw_winsys *
|
||||
fbdev_create_sw_winsys(int fd, enum pipe_format format)
|
||||
fbdev_create_sw_winsys(int fd)
|
||||
{
|
||||
struct fbdev_sw_winsys *fbdev;
|
||||
|
||||
|
@ -193,19 +216,11 @@ fbdev_create_sw_winsys(int fd, enum pipe_format format)
|
|||
return NULL;
|
||||
|
||||
fbdev->fd = fd;
|
||||
fbdev->format = format;
|
||||
if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->finfo)) {
|
||||
FREE(fbdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fbdev->fbmem = mmap(0, fbdev->finfo.smem_len,
|
||||
PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
|
||||
if (fbdev->fbmem == MAP_FAILED) {
|
||||
FREE(fbdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fbdev->rows = fbdev->finfo.smem_len / fbdev->finfo.line_length;
|
||||
fbdev->stride = fbdev->finfo.line_length;
|
||||
|
||||
|
|
|
@ -32,7 +32,14 @@
|
|||
struct sw_winsys;
|
||||
enum pipe_format;
|
||||
|
||||
/* for pipe_screen::flush_frontbuffer */
|
||||
struct fbdev_sw_drawable {
|
||||
enum pipe_format format;
|
||||
unsigned x, y;
|
||||
unsigned width, height;
|
||||
};
|
||||
|
||||
struct sw_winsys *
|
||||
fbdev_create_sw_winsys(int fd, enum pipe_format format);
|
||||
fbdev_create_sw_winsys(int fd);
|
||||
|
||||
#endif /* FBDEV_SW_WINSYS */
|
||||
|
|
Loading…
Reference in New Issue