mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-24 00:54:18 +08:00
tune drm video engine for acclerated graphics
This commit is contained in:
+4
-3
@@ -99,20 +99,21 @@ typedef struct _DrmDriverOps {
|
||||
void (*destroy_driver) (DrmDriver *driver);
|
||||
|
||||
uint32_t (* create_buffer) (DrmDriver *driver,
|
||||
int depth, int bpp,
|
||||
unsigned int width, unsigned int height,
|
||||
unsigned int *pitch, BOOL as_fb);
|
||||
unsigned int *pitch);
|
||||
|
||||
BOOL (* fetch_buffer) (DrmDriver *driver,
|
||||
uint32_t buffer_id,
|
||||
unsigned int *width, unsigned int *height,
|
||||
unsigned int *pitch);
|
||||
|
||||
BOOL (* map_buffer) (DrmDriver *driver,
|
||||
uint8_t* (* map_buffer) (DrmDriver *driver,
|
||||
uint32_t buffer_id);
|
||||
void (* unmap_buffer) (DrmDriver *driver,
|
||||
uint32_t buffer_id);
|
||||
|
||||
char * (* begin_flush) (DrmDriver *driver,
|
||||
uint8_t * (* begin_flush) (DrmDriver *driver,
|
||||
uint32_t buffer_id);
|
||||
|
||||
void (* end_flush) (DrmDriver *driver,
|
||||
|
||||
+209
-106
@@ -63,14 +63,14 @@ static int DRM_VideoInit(_THIS, GAL_PixelFormat *vformat);
|
||||
static GAL_Rect **DRM_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags);
|
||||
static int DRM_SetColors(_THIS, int firstcolor, int ncolors, GAL_Color *colors);
|
||||
static void DRM_VideoQuit(_THIS);
|
||||
static int DRM_Suspend(_THIS);
|
||||
static int DRM_Resume(_THIS);
|
||||
|
||||
/* DRM engine operators for dumb buffer */
|
||||
static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current,
|
||||
int width, int height, int bpp, Uint32 flags);
|
||||
static int DRM_AllocHWSurface_Dumb(_THIS, GAL_Surface *surface);
|
||||
static void DRM_FreeHWSurface_Dumb(_THIS, GAL_Surface *surface);
|
||||
static int DRM_Suspend_Dumb(_THIS);
|
||||
static int DRM_Resume_Dumb(_THIS);
|
||||
|
||||
/* DRM engine operators accelerated */
|
||||
static GAL_Surface *DRM_SetVideoMode_Accl(_THIS, GAL_Surface *current,
|
||||
@@ -103,15 +103,6 @@ static int DRM_Available(void)
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
||||
* OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
struct drm_mode_info {
|
||||
@@ -132,28 +123,6 @@ struct drm_mode_info {
|
||||
*/
|
||||
static void drm_cleanup(DrmVideoData* vdata)
|
||||
{
|
||||
struct drm_mode_info *iter;
|
||||
struct drm_mode_destroy_dumb dreq;
|
||||
|
||||
if (vdata->modes) {
|
||||
int i = 0;
|
||||
while (vdata->modes[i]) {
|
||||
free (vdata->modes[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
free(vdata->modes);
|
||||
}
|
||||
|
||||
while (vdata->mode_list) {
|
||||
/* remove from global list */
|
||||
iter = vdata->mode_list;
|
||||
vdata->mode_list = iter->next;
|
||||
|
||||
/* free allocated memory */
|
||||
free(iter);
|
||||
}
|
||||
|
||||
if (vdata->saved_crtc) {
|
||||
/* restore saved CRTC configuration */
|
||||
int ret = drmModeSetCrtc(vdata->dev_fd,
|
||||
@@ -171,28 +140,59 @@ static void drm_cleanup(DrmVideoData* vdata)
|
||||
drmModeFreeCrtc(vdata->saved_crtc);
|
||||
}
|
||||
|
||||
if (vdata->fb) {
|
||||
/* unmap buffer */
|
||||
munmap(vdata->fb, vdata->size);
|
||||
if (vdata->scanout_fb) {
|
||||
if (vdata->driver_ops) {
|
||||
vdata->driver_ops->unmap_buffer(vdata->driver, vdata->scanout_buff_id);
|
||||
vdata->driver_ops->destroy_buffer(vdata->driver, vdata->scanout_buff_id);
|
||||
}
|
||||
else {
|
||||
/* dumb buffer */
|
||||
struct drm_mode_destroy_dumb dreq;
|
||||
|
||||
/* delete framebuffer */
|
||||
drmModeRmFB(vdata->dev_fd, vdata->buff);
|
||||
/* unmap buffer */
|
||||
munmap(vdata->scanout_fb, vdata->size);
|
||||
|
||||
/* delete dumb buffer */
|
||||
memset(&dreq, 0, sizeof(dreq));
|
||||
dreq.handle = vdata->handle;
|
||||
drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
/* delete framebuffer */
|
||||
drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id);
|
||||
|
||||
/* delete dumb buffer */
|
||||
memset(&dreq, 0, sizeof(dreq));
|
||||
dreq.handle = vdata->handle;
|
||||
drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
}
|
||||
}
|
||||
|
||||
if (vdata->modes) {
|
||||
int i = 0;
|
||||
while (vdata->modes[i]) {
|
||||
free (vdata->modes[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
free(vdata->modes);
|
||||
}
|
||||
|
||||
while (vdata->mode_list) {
|
||||
struct drm_mode_info *iter;
|
||||
|
||||
/* remove from global list */
|
||||
iter = vdata->mode_list;
|
||||
vdata->mode_list = iter->next;
|
||||
|
||||
/* free allocated memory */
|
||||
free(iter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void DRM_DeleteDevice(GAL_VideoDevice *device)
|
||||
{
|
||||
drm_cleanup(device->hidden);
|
||||
|
||||
if (device->hidden->driver && device->hidden->driver_ops) {
|
||||
device->hidden->driver_ops->destroy_driver(device->hidden->driver);
|
||||
}
|
||||
|
||||
drm_cleanup(device->hidden);
|
||||
|
||||
free(device->hidden);
|
||||
free(device);
|
||||
}
|
||||
@@ -276,6 +276,7 @@ static int open_drm_device(GAL_VideoDevice *device)
|
||||
}
|
||||
|
||||
device->hidden->dev_fd = device_fd;
|
||||
device->hidden->driver = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -298,7 +299,7 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
|
||||
if ( device ) {
|
||||
memset(device, 0, (sizeof (*device)));
|
||||
device->hidden = (struct GAL_PrivateVideoData *)
|
||||
malloc((sizeof (*device->hidden)));
|
||||
calloc(1, (sizeof (*device->hidden)));
|
||||
}
|
||||
if ((device == NULL) || (device->hidden == NULL)) {
|
||||
GAL_OutOfMemory();
|
||||
@@ -337,6 +338,8 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
|
||||
device->SetHWColorKey = DRM_SetHWColorKey_Accl;
|
||||
device->SetHWAlpha = DRM_SetHWAlpha_Accl;
|
||||
device->FreeHWSurface = DRM_FreeHWSurface_Accl;
|
||||
device->Suspend = DRM_Suspend;
|
||||
device->Resume = DRM_Resume;
|
||||
}
|
||||
else {
|
||||
/* Use DUMB buffer */
|
||||
@@ -350,8 +353,8 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
|
||||
device->SetHWColorKey = NULL;
|
||||
device->SetHWAlpha = NULL;
|
||||
device->FreeHWSurface = DRM_FreeHWSurface_Dumb;
|
||||
device->Suspend = DRM_Suspend_Dumb;
|
||||
device->Resume = DRM_Resume_Dumb;
|
||||
device->Suspend = DRM_Suspend;
|
||||
device->Resume = DRM_Resume;
|
||||
}
|
||||
|
||||
device->free = DRM_DeleteDevice;
|
||||
@@ -609,6 +612,59 @@ static void DRM_VideoQuit(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
static int DRM_Resume(_THIS)
|
||||
{
|
||||
DrmVideoData* vdata = this->hidden;
|
||||
int ret = -1;
|
||||
|
||||
_DBG_PRINTF ("NEWGAL>DRM: %s called\n", __FUNCTION__);
|
||||
|
||||
if (vdata->saved_info) {
|
||||
vdata->saved_crtc = drmModeGetCrtc(vdata->dev_fd,
|
||||
vdata->saved_info->crtc);
|
||||
ret = drmModeSetCrtc(vdata->dev_fd,
|
||||
vdata->saved_info->crtc,
|
||||
vdata->scanout_buff_id, 0, 0,
|
||||
&vdata->saved_info->conn, 1,
|
||||
&vdata->saved_info->mode);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: Failed to resume dumb frame buffer: %d.\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int DRM_Suspend(_THIS)
|
||||
{
|
||||
DrmVideoData* vdata = this->hidden;
|
||||
int ret = -1;
|
||||
|
||||
_DBG_PRINTF ("NEWGAL>DRM: %s called\n", __FUNCTION__);
|
||||
|
||||
if (vdata->saved_crtc) {
|
||||
/* restore saved CRTC configuration */
|
||||
ret = drmModeSetCrtc(vdata->dev_fd,
|
||||
vdata->saved_crtc->crtc_id,
|
||||
vdata->saved_crtc->buffer_id,
|
||||
vdata->saved_crtc->x,
|
||||
vdata->saved_crtc->y,
|
||||
&vdata->saved_info->conn, 1,
|
||||
&vdata->saved_crtc->mode);
|
||||
|
||||
drmModeFreeCrtc(vdata->saved_crtc);
|
||||
vdata->saved_crtc = NULL;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: Failed to suspend dumb frame buffer: %m.\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* drm_create_dumb_fb(vdata, info):
|
||||
* Call this function to create a so called "dumb buffer".
|
||||
@@ -643,7 +699,7 @@ static int drm_create_dumb_fb(DrmVideoData* vdata, const DrmModeInfo* info,
|
||||
|
||||
/* create framebuffer object for the dumb-buffer */
|
||||
ret = drmModeAddFB(vdata->dev_fd, vdata->width, vdata->height, depth, bpp,
|
||||
vdata->pitch, vdata->handle, &vdata->buff);
|
||||
vdata->pitch, vdata->handle, &vdata->scanout_buff_id);
|
||||
if (ret) {
|
||||
_ERR_PRINTF("NEWGAL>DRM: cannot create framebuffer (%d): %m\n",
|
||||
errno);
|
||||
@@ -662,9 +718,9 @@ static int drm_create_dumb_fb(DrmVideoData* vdata, const DrmModeInfo* info,
|
||||
}
|
||||
|
||||
/* perform actual memory mapping */
|
||||
vdata->fb = mmap(0, vdata->size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
vdata->scanout_fb = mmap(0, vdata->size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
vdata->dev_fd, mreq.offset);
|
||||
if (vdata->fb == MAP_FAILED) {
|
||||
if (vdata->scanout_fb == MAP_FAILED) {
|
||||
_ERR_PRINTF("NEWGAL>DRM: cannot mmap dumb buffer (%d): %m\n", errno);
|
||||
ret = -errno;
|
||||
goto err_fb;
|
||||
@@ -673,7 +729,7 @@ static int drm_create_dumb_fb(DrmVideoData* vdata, const DrmModeInfo* info,
|
||||
return 0;
|
||||
|
||||
err_fb:
|
||||
drmModeRmFB(vdata->dev_fd, vdata->buff);
|
||||
drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id);
|
||||
|
||||
err_destroy:
|
||||
memset(&dreq, 0, sizeof(dreq));
|
||||
@@ -729,7 +785,7 @@ static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current,
|
||||
|
||||
/* perform actual modesetting on the found connector+CRTC */
|
||||
this->hidden->saved_crtc = drmModeGetCrtc(vdata->dev_fd, info->crtc);
|
||||
ret = drmModeSetCrtc(vdata->dev_fd, info->crtc, vdata->buff, 0, 0,
|
||||
ret = drmModeSetCrtc(vdata->dev_fd, info->crtc, vdata->scanout_buff_id, 0, 0,
|
||||
&info->conn, 1, &info->mode);
|
||||
if (ret) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: cannot set CRTC for connector %u (%d): %m\n",
|
||||
@@ -755,7 +811,7 @@ static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current,
|
||||
current->w = width;
|
||||
current->h = height;
|
||||
current->pitch = this->hidden->pitch;
|
||||
current->pixels = this->hidden->fb;
|
||||
current->pixels = this->hidden->scanout_fb;
|
||||
|
||||
/* We're done */
|
||||
return(current);
|
||||
@@ -771,63 +827,110 @@ static void DRM_FreeHWSurface_Dumb(_THIS, GAL_Surface *surface)
|
||||
surface->pixels = NULL;
|
||||
}
|
||||
|
||||
static int DRM_Resume_Dumb(_THIS)
|
||||
{
|
||||
DrmVideoData* vdata = this->hidden;
|
||||
int ret = -1;
|
||||
|
||||
_DBG_PRINTF ("NEWGAL>DRM: %s called\n", __FUNCTION__);
|
||||
|
||||
if (vdata->saved_info) {
|
||||
vdata->saved_crtc = drmModeGetCrtc(vdata->dev_fd,
|
||||
vdata->saved_info->crtc);
|
||||
ret = drmModeSetCrtc(vdata->dev_fd,
|
||||
vdata->saved_info->crtc,
|
||||
vdata->buff, 0, 0,
|
||||
&vdata->saved_info->conn, 1,
|
||||
&vdata->saved_info->mode);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: Failed to resume dumb frame buffer: %d.\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int DRM_Suspend_Dumb(_THIS)
|
||||
{
|
||||
DrmVideoData* vdata = this->hidden;
|
||||
int ret = -1;
|
||||
|
||||
_DBG_PRINTF ("NEWGAL>DRM: %s called\n", __FUNCTION__);
|
||||
|
||||
if (vdata->saved_crtc) {
|
||||
/* restore saved CRTC configuration */
|
||||
ret = drmModeSetCrtc(vdata->dev_fd,
|
||||
vdata->saved_crtc->crtc_id,
|
||||
vdata->saved_crtc->buffer_id,
|
||||
vdata->saved_crtc->x,
|
||||
vdata->saved_crtc->y,
|
||||
&vdata->saved_info->conn, 1,
|
||||
&vdata->saved_crtc->mode);
|
||||
|
||||
drmModeFreeCrtc(vdata->saved_crtc);
|
||||
vdata->saved_crtc = NULL;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: Failed to suspend dumb frame buffer: %m.\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* DRM engine methods for accelerated buffers */
|
||||
static GAL_Surface *DRM_SetVideoMode_Accl(_THIS, GAL_Surface *current,
|
||||
int width, int height, int bpp, Uint32 flags)
|
||||
{
|
||||
DrmVideoData* vdata = this->hidden;
|
||||
DrmModeInfo* info;
|
||||
int depth;
|
||||
unsigned int pitch;
|
||||
|
||||
if (bpp != 32) {
|
||||
_DBG_PRINTF("NEWGAL>DRM: force bpp (%d) to be 32\n", bpp);
|
||||
bpp = 32;
|
||||
}
|
||||
depth = 24;
|
||||
|
||||
/* find the connector+CRTC suitable for the resolution requested */
|
||||
info = find_mode(vdata, width, height);
|
||||
if (info == NULL) {
|
||||
_ERR_PRINTF("NEWGAL>DRM: cannot find a CRTC for video mode: %dx%d-%dbpp\n",
|
||||
width, height, bpp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_DBG_PRINTF("NEWGAL>DRM: going setting video mode: %dx%d-%dbpp\n",
|
||||
info->width, info->height, bpp);
|
||||
|
||||
#if 0
|
||||
if (drmSetMaster(this->hidden->dev_fd)) {
|
||||
_ERR_PRINTF("NEWGAL>DRM: failed to call drmSetMaster: %m\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create the scanout buffer and set up it as frame buffer */
|
||||
vdata->scanout_buff_id =
|
||||
vdata->driver_ops->create_buffer(vdata->driver, depth, bpp,
|
||||
info->width, info->height, &pitch);
|
||||
if (vdata->scanout_buff_id == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
vdata->width = info->width;
|
||||
vdata->height = info->height;
|
||||
vdata->bpp = bpp;
|
||||
vdata->pitch = pitch;
|
||||
vdata->size = pitch * info->height;
|
||||
vdata->handle = 0;
|
||||
vdata->scanout_fb = vdata->driver_ops->map_buffer(vdata->driver, vdata->scanout_buff_id);
|
||||
if (vdata->scanout_fb == NULL) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: cannot map scanout frame buffer: %m\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
_DBG_PRINTF("NEWGAL>DRM: scanout frame buffer: size (%dx%d), pitch(%d)\n",
|
||||
vdata->width, vdata->height, vdata->pitch);
|
||||
|
||||
/* get console buffer id */
|
||||
vdata->saved_crtc = drmModeGetCrtc(vdata->dev_fd, info->crtc);
|
||||
vdata->console_buff_id = vdata->saved_crtc->buffer_id;
|
||||
|
||||
/* perform actual modesetting on the found connector+CRTC */
|
||||
if (drmModeSetCrtc(vdata->dev_fd, info->crtc, vdata->scanout_buff_id, 0, 0,
|
||||
&info->conn, 1, &info->mode)) {
|
||||
_ERR_PRINTF ("NEWGAL>DRM: cannot set CRTC for connector %u (%d): %m\n",
|
||||
info->conn, errno);
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
this->hidden->saved_info = info;
|
||||
|
||||
/* Allocate the new pixel format for the screen */
|
||||
if (!GAL_ReallocFormat (current, bpp, 0, 0, 0, 0)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
_DBG_PRINTF("NEWGAL>DRM: real screen mode: %dx%d-%dbpp\n", width, height, bpp);
|
||||
|
||||
current->flags = flags & GAL_FULLSCREEN;
|
||||
current->w = width;
|
||||
current->h = height;
|
||||
current->pitch = this->hidden->pitch;
|
||||
current->pixels = this->hidden->scanout_fb;
|
||||
|
||||
/* We're done */
|
||||
return(current);
|
||||
|
||||
error:
|
||||
|
||||
if (vdata->saved_crtc) {
|
||||
drmModeFreeCrtc(vdata->saved_crtc);
|
||||
vdata->saved_crtc = NULL;
|
||||
}
|
||||
|
||||
if (vdata->scanout_fb) {
|
||||
vdata->driver_ops->unmap_buffer(vdata->driver, vdata->scanout_buff_id);
|
||||
vdata->scanout_fb = NULL;
|
||||
}
|
||||
|
||||
if (vdata->scanout_buff_id) {
|
||||
vdata->driver_ops->destroy_buffer(vdata->driver, vdata->scanout_buff_id);
|
||||
vdata->scanout_buff_id = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,12 +63,17 @@ typedef struct GAL_PrivateVideoData {
|
||||
uint32_t pitch;
|
||||
uint32_t size;
|
||||
|
||||
uint32_t buff;
|
||||
uint32_t handle;
|
||||
uint32_t scanout_buff_id;
|
||||
uint8_t* scanout_fb;
|
||||
|
||||
DrmModeInfo* saved_info;
|
||||
drmModeCrtc* saved_crtc;
|
||||
uint8_t* fb;
|
||||
|
||||
/* only valid when using DUMB frame buffer */
|
||||
uint32_t handle;
|
||||
|
||||
/* only valid when using DRM driver */
|
||||
uint32_t console_buff_id;
|
||||
} DrmVideoData;
|
||||
|
||||
#endif /* _NEWGAL_DRMVIDEO_H */
|
||||
|
||||
Reference in New Issue
Block a user