(sunxi_gfx.c) Style nits
This commit is contained in:
parent
f32abcf532
commit
4cb819543e
|
@ -536,17 +536,17 @@ typedef struct
|
||||||
__disp_3d_out_mode_t out_trd_mode;
|
__disp_3d_out_mode_t out_trd_mode;
|
||||||
} __disp_layer_info_t;
|
} __disp_layer_info_t;
|
||||||
|
|
||||||
int sunxi_hw_cursor_hide(sunxi_disp_t *ctx)
|
static int sunxi_hw_cursor_hide(sunxi_disp_t *ctx)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
result = ioctl(ctx->fd_disp, DISP_CMD_HWC_CLOSE, &tmp);
|
result = ioctl(ctx->fd_disp, DISP_CMD_HWC_CLOSE, &tmp);
|
||||||
|
|
||||||
if (result >= 0)
|
if (result >= 0)
|
||||||
ctx->cursor_enabled = 0;
|
ctx->cursor_enabled = 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -555,182 +555,182 @@ int sunxi_hw_cursor_hide(sunxi_disp_t *ctx)
|
||||||
|
|
||||||
static int sunxi_layer_change_work_mode(sunxi_disp_t *ctx, int new_mode)
|
static int sunxi_layer_change_work_mode(sunxi_disp_t *ctx, int new_mode)
|
||||||
{
|
{
|
||||||
__disp_layer_info_t layer_info;
|
__disp_layer_info_t layer_info;
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
if (ctx->layer_id < 0)
|
if (ctx->layer_id < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&layer_info;
|
tmp[2] = (uintptr_t)&layer_info;
|
||||||
|
|
||||||
if (ioctl(ctx->fd_disp, DISP_CMD_LAYER_GET_PARA, tmp) < 0)
|
if (ioctl(ctx->fd_disp, DISP_CMD_LAYER_GET_PARA, tmp) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
layer_info.mode = new_mode;
|
layer_info.mode = new_mode;
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&layer_info;
|
tmp[2] = (uintptr_t)&layer_info;
|
||||||
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_PARA, tmp);
|
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_PARA, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sunxi_layer_reserve(sunxi_disp_t *ctx)
|
static int sunxi_layer_reserve(sunxi_disp_t *ctx)
|
||||||
{
|
{
|
||||||
__disp_layer_info_t layer_info;
|
__disp_layer_info_t layer_info;
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
/* try to allocate a layer */
|
/* try to allocate a layer */
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = DISP_LAYER_WORK_MODE_NORMAL;
|
tmp[1] = DISP_LAYER_WORK_MODE_NORMAL;
|
||||||
ctx->layer_id = ioctl(ctx->fd_disp, DISP_CMD_LAYER_REQUEST, &tmp);
|
ctx->layer_id = ioctl(ctx->fd_disp, DISP_CMD_LAYER_REQUEST, &tmp);
|
||||||
if (ctx->layer_id < 0)
|
if (ctx->layer_id < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Initially set the layer configuration to something reasonable */
|
/* Initially set the layer configuration to something reasonable */
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&layer_info;
|
tmp[2] = (uintptr_t)&layer_info;
|
||||||
if (ioctl(ctx->fd_disp, DISP_CMD_LAYER_GET_PARA, tmp) < 0)
|
if (ioctl(ctx->fd_disp, DISP_CMD_LAYER_GET_PARA, tmp) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* the screen and overlay layers need to be in different pipes */
|
/* the screen and overlay layers need to be in different pipes */
|
||||||
layer_info.pipe = 1;
|
layer_info.pipe = 1;
|
||||||
layer_info.alpha_en = 1;
|
layer_info.alpha_en = 1;
|
||||||
layer_info.alpha_val = 255;
|
layer_info.alpha_val = 255;
|
||||||
|
|
||||||
layer_info.fb.addr[0] = ctx->framebuffer_paddr;
|
layer_info.fb.addr[0] = ctx->framebuffer_paddr;
|
||||||
layer_info.fb.size.width = 1;
|
layer_info.fb.size.width = 1;
|
||||||
layer_info.fb.size.height = 1;
|
layer_info.fb.size.height = 1;
|
||||||
layer_info.fb.format = DISP_FORMAT_ARGB8888;
|
layer_info.fb.format = DISP_FORMAT_ARGB8888;
|
||||||
layer_info.fb.seq = DISP_SEQ_ARGB;
|
layer_info.fb.seq = DISP_SEQ_ARGB;
|
||||||
layer_info.fb.mode = DISP_MOD_INTERLEAVED;
|
layer_info.fb.mode = DISP_MOD_INTERLEAVED;
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&layer_info;
|
tmp[2] = (uintptr_t)&layer_info;
|
||||||
if (ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_PARA, tmp) < 0)
|
if (ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_PARA, tmp) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Now probe the scaler mode to see if there is a free scaler available */
|
/* Now probe the scaler mode to see if there is a free scaler available */
|
||||||
if (sunxi_layer_change_work_mode(ctx, DISP_LAYER_WORK_MODE_SCALER) == 0)
|
if (sunxi_layer_change_work_mode(ctx, DISP_LAYER_WORK_MODE_SCALER) == 0)
|
||||||
ctx->layer_has_scaler = 1;
|
ctx->layer_has_scaler = 1;
|
||||||
|
|
||||||
/* Revert back to normal mode */
|
/* Revert back to normal mode */
|
||||||
sunxi_layer_change_work_mode(ctx, DISP_LAYER_WORK_MODE_NORMAL);
|
sunxi_layer_change_work_mode(ctx, DISP_LAYER_WORK_MODE_NORMAL);
|
||||||
ctx->layer_scaler_is_enabled = 0;
|
ctx->layer_scaler_is_enabled = 0;
|
||||||
ctx->layer_format = DISP_FORMAT_ARGB8888;
|
ctx->layer_format = DISP_FORMAT_ARGB8888;
|
||||||
|
|
||||||
return ctx->layer_id;
|
return ctx->layer_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sunxi_layer_set_output_window(sunxi_disp_t *ctx, int x, int y, int w, int h)
|
static int sunxi_layer_set_output_window(sunxi_disp_t *ctx, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
__disp_rect_t buf_rect = {
|
__disp_rect_t buf_rect = {
|
||||||
ctx->layer_buf_x, ctx->layer_buf_y,
|
ctx->layer_buf_x, ctx->layer_buf_y,
|
||||||
ctx->layer_buf_w, ctx->layer_buf_h
|
ctx->layer_buf_w, ctx->layer_buf_h
|
||||||
};
|
};
|
||||||
__disp_rect_t win_rect = { x, y, w, h };
|
__disp_rect_t win_rect = { x, y, w, h };
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (ctx->layer_id < 0 || w <= 0 || h <= 0)
|
if (ctx->layer_id < 0 || w <= 0 || h <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle negative window Y coordinates (workaround a bug).
|
* Handle negative window Y coordinates (workaround a bug).
|
||||||
* The Allwinner A10/A13 display controller hardware is expected to
|
* The Allwinner A10/A13 display controller hardware is expected to
|
||||||
* support negative coordinates of the top left corners of the layers.
|
* support negative coordinates of the top left corners of the layers.
|
||||||
* But there is some bug either in the kernel driver or in the hardware,
|
* But there is some bug either in the kernel driver or in the hardware,
|
||||||
* which messes up the picture on screen when the Y coordinate is negative
|
* which messes up the picture on screen when the Y coordinate is negative
|
||||||
* for YUV layer. Negative X coordinates are not affected. RGB formats
|
* for YUV layer. Negative X coordinates are not affected. RGB formats
|
||||||
* are not affected too.
|
* are not affected too.
|
||||||
*
|
*
|
||||||
* We fix this by just recalculating which part of the buffer in memory
|
* We fix this by just recalculating which part of the buffer in memory
|
||||||
* corresponds to Y=0 on screen and adjust the input buffer settings.
|
* corresponds to Y=0 on screen and adjust the input buffer settings.
|
||||||
*/
|
*/
|
||||||
if (ctx->layer_format == DISP_FORMAT_YUV420 &&
|
if (ctx->layer_format == DISP_FORMAT_YUV420 &&
|
||||||
(y < 0 || ctx->layer_win_y < 0))
|
(y < 0 || ctx->layer_win_y < 0))
|
||||||
{
|
{
|
||||||
if (win_rect.y < 0)
|
if (win_rect.y < 0)
|
||||||
{
|
{
|
||||||
int y_shift = -(double)y * buf_rect.height / win_rect.height;
|
int y_shift = -(double)y * buf_rect.height / win_rect.height;
|
||||||
buf_rect.y += y_shift;
|
buf_rect.y += y_shift;
|
||||||
buf_rect.height -= y_shift;
|
buf_rect.height -= y_shift;
|
||||||
win_rect.height += win_rect.y;
|
win_rect.height += win_rect.y;
|
||||||
win_rect.y = 0;
|
win_rect.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf_rect.height <= 0 || win_rect.height <= 0)
|
if (buf_rect.height <= 0 || win_rect.height <= 0)
|
||||||
{
|
{
|
||||||
/* No part of the window is visible. Just construct a fake rectangle
|
/* No part of the window is visible. Just construct a fake rectangle
|
||||||
* outside the screen as a window placement (but with a non-negative Y
|
* outside the screen as a window placement (but with a non-negative Y
|
||||||
* coordinate). Do this to avoid passing bogus negative heights to
|
* coordinate). Do this to avoid passing bogus negative heights to
|
||||||
* the kernel driver (who knows how it would react?) */
|
* the kernel driver (who knows how it would react?) */
|
||||||
win_rect.x = -1;
|
win_rect.x = -1;
|
||||||
win_rect.y = 0;
|
win_rect.y = 0;
|
||||||
win_rect.width = 1;
|
win_rect.width = 1;
|
||||||
win_rect.height = 1;
|
win_rect.height = 1;
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&win_rect;
|
tmp[2] = (uintptr_t)&win_rect;
|
||||||
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SCN_WINDOW, &tmp);
|
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SCN_WINDOW, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&buf_rect;
|
tmp[2] = (uintptr_t)&buf_rect;
|
||||||
if ((err = ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SRC_WINDOW, &tmp)))
|
if ((err = ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SRC_WINDOW, &tmp)))
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the new non-adjusted window position */
|
/* Save the new non-adjusted window position */
|
||||||
ctx->layer_win_x = x;
|
ctx->layer_win_x = x;
|
||||||
ctx->layer_win_y = y;
|
ctx->layer_win_y = y;
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
tmp[2] = (uintptr_t)&win_rect;
|
tmp[2] = (uintptr_t)&win_rect;
|
||||||
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SCN_WINDOW, &tmp);
|
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SCN_WINDOW, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sunxi_layer_show(sunxi_disp_t *ctx)
|
static int sunxi_layer_show(sunxi_disp_t *ctx)
|
||||||
{
|
{
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
if (ctx->layer_id < 0)
|
if (ctx->layer_id < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* YUV formats need to use a scaler */
|
/* YUV formats need to use a scaler */
|
||||||
if (ctx->layer_format == DISP_FORMAT_YUV420 && !ctx->layer_scaler_is_enabled)
|
if (ctx->layer_format == DISP_FORMAT_YUV420 && !ctx->layer_scaler_is_enabled)
|
||||||
{
|
{
|
||||||
if (sunxi_layer_change_work_mode(ctx, DISP_LAYER_WORK_MODE_SCALER) == 0)
|
if (sunxi_layer_change_work_mode(ctx, DISP_LAYER_WORK_MODE_SCALER) == 0)
|
||||||
ctx->layer_scaler_is_enabled = 1;
|
ctx->layer_scaler_is_enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_OPEN, &tmp);
|
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_OPEN, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sunxi_layer_release(sunxi_disp_t *ctx)
|
static int sunxi_layer_release(sunxi_disp_t *ctx)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
if (ctx->layer_id < 0)
|
if (ctx->layer_id < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tmp[0] = ctx->fb_id;
|
tmp[0] = ctx->fb_id;
|
||||||
tmp[1] = ctx->layer_id;
|
tmp[1] = ctx->layer_id;
|
||||||
ioctl(ctx->fd_disp, DISP_CMD_LAYER_RELEASE, &tmp);
|
ioctl(ctx->fd_disp, DISP_CMD_LAYER_RELEASE, &tmp);
|
||||||
|
|
||||||
ctx->layer_id = -1;
|
ctx->layer_id = -1;
|
||||||
ctx->layer_has_scaler = 0;
|
ctx->layer_has_scaler = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -744,6 +744,7 @@ static int sunxi_layer_set_rgb_input_buffer(sunxi_disp_t *ctx,
|
||||||
__disp_fb_t fb;
|
__disp_fb_t fb;
|
||||||
__disp_rect_t rect = { 0, 0, width, height };
|
__disp_rect_t rect = { 0, 0, width, height };
|
||||||
uint32_t tmp[4];
|
uint32_t tmp[4];
|
||||||
|
|
||||||
memset(&fb, 0, sizeof(fb));
|
memset(&fb, 0, sizeof(fb));
|
||||||
|
|
||||||
if (ctx->layer_id < 0)
|
if (ctx->layer_id < 0)
|
||||||
|
@ -759,6 +760,7 @@ static int sunxi_layer_set_rgb_input_buffer(sunxi_disp_t *ctx,
|
||||||
|
|
||||||
fb.addr[0] = ctx->framebuffer_paddr + offset_in_framebuffer;
|
fb.addr[0] = ctx->framebuffer_paddr + offset_in_framebuffer;
|
||||||
fb.size.height = height;
|
fb.size.height = height;
|
||||||
|
|
||||||
if (bpp == 32)
|
if (bpp == 32)
|
||||||
{
|
{
|
||||||
fb.format = DISP_FORMAT_ARGB8888;
|
fb.format = DISP_FORMAT_ARGB8888;
|
||||||
|
@ -796,165 +798,166 @@ static int sunxi_layer_set_rgb_input_buffer(sunxi_disp_t *ctx,
|
||||||
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SRC_WINDOW, &tmp);
|
return ioctl(ctx->fd_disp, DISP_CMD_LAYER_SET_SRC_WINDOW, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
sunxi_disp_t *sunxi_disp_init(const char *device, void *xserver_fbmem)
|
static sunxi_disp_t *sunxi_disp_init(const char *device, void *xserver_fbmem)
|
||||||
{
|
{
|
||||||
int tmp, version;
|
int tmp, version;
|
||||||
int gfx_layer_size;
|
int gfx_layer_size;
|
||||||
int ovl_layer_size;
|
int ovl_layer_size;
|
||||||
struct fb_var_screeninfo fb_var;
|
struct fb_var_screeninfo fb_var;
|
||||||
struct fb_fix_screeninfo fb_fix;
|
struct fb_fix_screeninfo fb_fix;
|
||||||
sunxi_disp_t *ctx = calloc(sizeof(sunxi_disp_t), 1);
|
|
||||||
|
|
||||||
if (!ctx)
|
sunxi_disp_t *ctx = calloc(sizeof(sunxi_disp_t), 1);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* use /dev/fb0 by default */
|
if (!ctx)
|
||||||
if (!device)
|
return NULL;
|
||||||
device = "/dev/fb0";
|
|
||||||
|
|
||||||
if (strcmp(device, "/dev/fb0") == 0)
|
/* use /dev/fb0 by default */
|
||||||
ctx->fb_id = 0;
|
if (!device)
|
||||||
else if (strcmp(device, "/dev/fb1") == 0)
|
device = "/dev/fb0";
|
||||||
ctx->fb_id = 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* store the already existing mapping done by xserver */
|
if (strcmp(device, "/dev/fb0") == 0)
|
||||||
ctx->xserver_fbmem = xserver_fbmem;
|
ctx->fb_id = 0;
|
||||||
|
else if (strcmp(device, "/dev/fb1") == 0)
|
||||||
|
ctx->fb_id = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->fd_disp = open("/dev/disp", O_RDWR);
|
/* store the already existing mapping done by xserver */
|
||||||
|
ctx->xserver_fbmem = xserver_fbmem;
|
||||||
|
|
||||||
/* maybe it's even not a sunxi hardware */
|
ctx->fd_disp = open("/dev/disp", O_RDWR);
|
||||||
if (ctx->fd_disp < 0)
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* version check */
|
/* maybe it's even not a sunxi hardware */
|
||||||
tmp = SUNXI_DISP_VERSION;
|
if (ctx->fd_disp < 0)
|
||||||
version = ioctl(ctx->fd_disp, DISP_CMD_VERSION, &tmp);
|
{
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (version < 0)
|
/* version check */
|
||||||
{
|
tmp = SUNXI_DISP_VERSION;
|
||||||
close(ctx->fd_disp);
|
version = ioctl(ctx->fd_disp, DISP_CMD_VERSION, &tmp);
|
||||||
free(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->fd_fb = open(device, O_RDWR);
|
if (version < 0)
|
||||||
|
{
|
||||||
|
close(ctx->fd_disp);
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->fd_fb < 0)
|
ctx->fd_fb = open(device, O_RDWR);
|
||||||
{
|
|
||||||
close(ctx->fd_disp);
|
|
||||||
free(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(ctx->fd_fb, FBIOGET_VSCREENINFO, &fb_var) < 0 ||
|
if (ctx->fd_fb < 0)
|
||||||
ioctl(ctx->fd_fb, FBIOGET_FSCREENINFO, &fb_fix) < 0)
|
{
|
||||||
{
|
close(ctx->fd_disp);
|
||||||
close(ctx->fd_fb);
|
free(ctx);
|
||||||
close(ctx->fd_disp);
|
return NULL;
|
||||||
free(ctx);
|
}
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->xres = fb_var.xres;
|
if (ioctl(ctx->fd_fb, FBIOGET_VSCREENINFO, &fb_var) < 0 ||
|
||||||
ctx->yres = fb_var.yres;
|
ioctl(ctx->fd_fb, FBIOGET_FSCREENINFO, &fb_fix) < 0)
|
||||||
ctx->bits_per_pixel = fb_var.bits_per_pixel;
|
{
|
||||||
ctx->framebuffer_paddr = fb_fix.smem_start;
|
close(ctx->fd_fb);
|
||||||
ctx->framebuffer_size = fb_fix.smem_len;
|
close(ctx->fd_disp);
|
||||||
ctx->framebuffer_height = ctx->framebuffer_size /
|
free(ctx);
|
||||||
(ctx->xres * ctx->bits_per_pixel / 8);
|
return NULL;
|
||||||
ctx->gfx_layer_size = ctx->xres * ctx->yres * fb_var.bits_per_pixel / 8;
|
}
|
||||||
|
|
||||||
if (ctx->framebuffer_size < ctx->gfx_layer_size)
|
ctx->xres = fb_var.xres;
|
||||||
{
|
ctx->yres = fb_var.yres;
|
||||||
close(ctx->fd_fb);
|
ctx->bits_per_pixel = fb_var.bits_per_pixel;
|
||||||
close(ctx->fd_disp);
|
ctx->framebuffer_paddr = fb_fix.smem_start;
|
||||||
free(ctx);
|
ctx->framebuffer_size = fb_fix.smem_len;
|
||||||
return NULL;
|
ctx->framebuffer_height = ctx->framebuffer_size /
|
||||||
}
|
(ctx->xres * ctx->bits_per_pixel / 8);
|
||||||
|
ctx->gfx_layer_size = ctx->xres * ctx->yres * fb_var.bits_per_pixel / 8;
|
||||||
|
|
||||||
if (ctx->xserver_fbmem)
|
if (ctx->framebuffer_size < ctx->gfx_layer_size)
|
||||||
{
|
{
|
||||||
/* use already existing mapping */
|
close(ctx->fd_fb);
|
||||||
ctx->framebuffer_addr = ctx->xserver_fbmem;
|
close(ctx->fd_disp);
|
||||||
}
|
free(ctx);
|
||||||
else
|
return NULL;
|
||||||
{
|
}
|
||||||
/* mmap framebuffer memory */
|
|
||||||
ctx->framebuffer_addr = (uint8_t *)mmap(0, ctx->framebuffer_size,
|
|
||||||
PROT_READ | PROT_WRITE,
|
|
||||||
MAP_SHARED, ctx->fd_fb, 0);
|
|
||||||
|
|
||||||
if (ctx->framebuffer_addr == MAP_FAILED)
|
if (ctx->xserver_fbmem)
|
||||||
{
|
{
|
||||||
close(ctx->fd_fb);
|
/* use already existing mapping */
|
||||||
close(ctx->fd_disp);
|
ctx->framebuffer_addr = ctx->xserver_fbmem;
|
||||||
free(ctx);
|
}
|
||||||
return NULL;
|
else
|
||||||
}
|
{
|
||||||
}
|
/* mmap framebuffer memory */
|
||||||
|
ctx->framebuffer_addr = (uint8_t *)mmap(0, ctx->framebuffer_size,
|
||||||
|
PROT_READ | PROT_WRITE,
|
||||||
|
MAP_SHARED, ctx->fd_fb, 0);
|
||||||
|
|
||||||
ctx->cursor_enabled = 0;
|
if (ctx->framebuffer_addr == MAP_FAILED)
|
||||||
ctx->cursor_x = -1;
|
{
|
||||||
ctx->cursor_y = -1;
|
close(ctx->fd_fb);
|
||||||
|
close(ctx->fd_disp);
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the id of the screen layer */
|
ctx->cursor_enabled = 0;
|
||||||
if (ioctl(ctx->fd_fb,
|
ctx->cursor_x = -1;
|
||||||
ctx->fb_id == 0 ? FBIOGET_LAYER_HDL_0 : FBIOGET_LAYER_HDL_1,
|
ctx->cursor_y = -1;
|
||||||
&ctx->gfx_layer_id))
|
|
||||||
{
|
|
||||||
close(ctx->fd_fb);
|
|
||||||
close(ctx->fd_disp);
|
|
||||||
free(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sunxi_layer_reserve(ctx) < 0)
|
/* Get the id of the screen layer */
|
||||||
{
|
if (ioctl(ctx->fd_fb,
|
||||||
close(ctx->fd_fb);
|
ctx->fb_id == 0 ? FBIOGET_LAYER_HDL_0 : FBIOGET_LAYER_HDL_1,
|
||||||
close(ctx->fd_disp);
|
&ctx->gfx_layer_id))
|
||||||
free(ctx);
|
{
|
||||||
return NULL;
|
close(ctx->fd_fb);
|
||||||
}
|
close(ctx->fd_disp);
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->fd_g2d = open("/dev/g2d", O_RDWR);
|
if (sunxi_layer_reserve(ctx) < 0)
|
||||||
|
{
|
||||||
|
close(ctx->fd_fb);
|
||||||
|
close(ctx->fd_disp);
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return ctx;
|
ctx->fd_g2d = open("/dev/g2d", O_RDWR);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sunxi_disp_close(sunxi_disp_t *ctx)
|
static int sunxi_disp_close(sunxi_disp_t *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->fd_disp >= 0)
|
if (ctx->fd_disp >= 0)
|
||||||
{
|
{
|
||||||
if (ctx->fd_g2d >= 0)
|
if (ctx->fd_g2d >= 0)
|
||||||
close(ctx->fd_g2d);
|
close(ctx->fd_g2d);
|
||||||
|
|
||||||
/* release layer */
|
/* release layer */
|
||||||
sunxi_layer_release(ctx);
|
sunxi_layer_release(ctx);
|
||||||
/* disable cursor */
|
/* disable cursor */
|
||||||
if (ctx->cursor_enabled)
|
if (ctx->cursor_enabled)
|
||||||
sunxi_hw_cursor_hide(ctx);
|
sunxi_hw_cursor_hide(ctx);
|
||||||
/* close descriptors */
|
/* close descriptors */
|
||||||
if (!ctx->xserver_fbmem)
|
if (!ctx->xserver_fbmem)
|
||||||
munmap(ctx->framebuffer_addr, ctx->framebuffer_size);
|
munmap(ctx->framebuffer_addr, ctx->framebuffer_size);
|
||||||
close(ctx->fd_fb);
|
close(ctx->fd_fb);
|
||||||
close(ctx->fd_disp);
|
close(ctx->fd_disp);
|
||||||
ctx->fd_disp = -1;
|
ctx->fd_disp = -1;
|
||||||
free(ctx);
|
free(ctx);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sunxi_wait_for_vsync(sunxi_disp_t *ctx)
|
static int sunxi_wait_for_vsync(sunxi_disp_t *ctx)
|
||||||
{
|
{
|
||||||
return ioctl(ctx->fd_fb, FBIO_WAITFORVSYNC, 0);
|
return ioctl(ctx->fd_fb, FBIO_WAITFORVSYNC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END of lowlevel SunxiG2D functions block */
|
/* END of lowlevel SunxiG2D functions block */
|
||||||
|
@ -975,11 +978,11 @@ void pixman_composite_src_8888_8888_asm_neon(int width,
|
||||||
|
|
||||||
/* Pointer to the blitting function. Will be asigned
|
/* Pointer to the blitting function. Will be asigned
|
||||||
* when we find out what bpp the core uses. */
|
* when we find out what bpp the core uses. */
|
||||||
void(*pixman_blit)();
|
void(*pixman_blit)(void);
|
||||||
|
|
||||||
extern void *memcpy_neon(void *dst, const void *src, size_t n);
|
extern void *memcpy_neon(void *dst, const void *src, size_t n);
|
||||||
|
|
||||||
static void *vsync_thread_func (void *arg);
|
static void *vsync_thread_func(void *arg);
|
||||||
|
|
||||||
pthread_t vsync_thread;
|
pthread_t vsync_thread;
|
||||||
|
|
||||||
|
@ -1039,13 +1042,13 @@ struct sunxi_video
|
||||||
bool aspect_changed;
|
bool aspect_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
int sunxi_wait_flip(void)
|
static int sunxi_wait_flip(void)
|
||||||
{
|
{
|
||||||
/* Wait for next vsync */
|
/* Wait for next vsync */
|
||||||
return ioctl(disp->fd_fb, FBIO_WAITFORVSYNC, 0);
|
return ioctl(disp->fd_fb, FBIO_WAITFORVSYNC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queue_page (struct sunxi_page *page, void *data)
|
static void queue_page(struct sunxi_page *page, void *data)
|
||||||
{
|
{
|
||||||
struct sunxi_video *_dispvars = data;
|
struct sunxi_video *_dispvars = data;
|
||||||
struct sunxi_page *ppage = _dispvars->queue;
|
struct sunxi_page *ppage = _dispvars->queue;
|
||||||
|
@ -1061,7 +1064,7 @@ void queue_page (struct sunxi_page *page, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sunxi_page *unqueue_page (void *data)
|
static struct sunxi_page *unqueue_page(void *data)
|
||||||
{
|
{
|
||||||
struct sunxi_video *_dispvars = data;
|
struct sunxi_video *_dispvars = data;
|
||||||
struct sunxi_page * page = _dispvars->queue;
|
struct sunxi_page * page = _dispvars->queue;
|
||||||
|
@ -1109,7 +1112,7 @@ static struct sunxi_page *sunxi_get_free_page(void *data)
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sunxi_blank_console (void *data)
|
static void sunxi_blank_console(void *data)
|
||||||
{
|
{
|
||||||
struct sunxi_video *_dispvars = data;
|
struct sunxi_video *_dispvars = data;
|
||||||
|
|
||||||
|
@ -1120,28 +1123,28 @@ static void sunxi_blank_console (void *data)
|
||||||
_dispvars->screensize = disp->xres * disp->yres * disp->bits_per_pixel / 8;
|
_dispvars->screensize = disp->xres * disp->yres * disp->bits_per_pixel / 8;
|
||||||
|
|
||||||
/* Backup screen contents. */
|
/* Backup screen contents. */
|
||||||
_dispvars->screen_bck = (char *)malloc(_dispvars->screensize * sizeof (char));
|
_dispvars->screen_bck = (char*)malloc(_dispvars->screensize * sizeof(char));
|
||||||
|
|
||||||
if (!_dispvars->screen_bck)
|
if (!_dispvars->screen_bck)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy ((char*)_dispvars->screen_bck, (char*)disp->framebuffer_addr, _dispvars->screensize);
|
memcpy((char*)_dispvars->screen_bck, (char*)disp->framebuffer_addr, _dispvars->screensize);
|
||||||
|
|
||||||
/* Blank screen. */
|
/* Blank screen. */
|
||||||
memset ((char*)(disp->framebuffer_addr), 0x00, _dispvars->screensize);
|
memset((char*)(disp->framebuffer_addr), 0x00, _dispvars->screensize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sunxi_unblank_console (void *data)
|
static void sunxi_unblank_console(void *data)
|
||||||
{
|
{
|
||||||
struct sunxi_video *_dispvars = data;
|
struct sunxi_video *_dispvars = data;
|
||||||
|
|
||||||
system("setterm -cursor on");
|
system("setterm -cursor on");
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
memcpy ((char*)disp->framebuffer_addr, (char*)_dispvars->screen_bck, _dispvars->screensize);
|
memcpy((char*)disp->framebuffer_addr, (char*)_dispvars->screen_bck, _dispvars->screensize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free (_dispvars->screen_bck);
|
free(_dispvars->screen_bck);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *sunxi_gfx_init(const video_info_t *video,
|
static void *sunxi_gfx_init(const video_info_t *video,
|
||||||
|
@ -1162,7 +1165,7 @@ static void *sunxi_gfx_init(const video_info_t *video,
|
||||||
sunxi_blank_console(_dispvars);
|
sunxi_blank_console(_dispvars);
|
||||||
|
|
||||||
_dispvars->numpages = 2;
|
_dispvars->numpages = 2;
|
||||||
_dispvars->pages = calloc (_dispvars->numpages, sizeof (struct sunxi_page));
|
_dispvars->pages = calloc(_dispvars->numpages, sizeof (struct sunxi_page));
|
||||||
|
|
||||||
if (!_dispvars->pages)
|
if (!_dispvars->pages)
|
||||||
{
|
{
|
||||||
|
@ -1211,7 +1214,7 @@ static void *sunxi_gfx_init(const video_info_t *video,
|
||||||
return _dispvars;
|
return _dispvars;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *vsync_thread_func (void *arg)
|
static void *vsync_thread_func(void *arg)
|
||||||
{
|
{
|
||||||
struct sunxi_page *page;
|
struct sunxi_page *page;
|
||||||
struct sunxi_video *_dispvars = arg;
|
struct sunxi_video *_dispvars = arg;
|
||||||
|
@ -1272,9 +1275,7 @@ static void sunxi_gfx_free(void *data)
|
||||||
free(_dispvars);
|
free(_dispvars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sunxi_blit_flip(struct sunxi_page *page, const void *frame, void *data)
|
||||||
|
|
||||||
static void sunxi_blit_flip (struct sunxi_page *page, const void *frame, void *data)
|
|
||||||
{
|
{
|
||||||
struct sunxi_video *_dispvars = data;
|
struct sunxi_video *_dispvars = data;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue