mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-17 23:40:29 +01:00
drisw: use shared memory when possible
If drisw_loader_funcs implements put_image_shm, allocates display target data with shared memory and display with put_image_shm(). Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
63c427fa71
commit
cf54bd5e83
1 changed files with 60 additions and 12 deletions
|
|
@ -26,6 +26,9 @@
|
||||||
*
|
*
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
|
||||||
#include "pipe/p_compiler.h"
|
#include "pipe/p_compiler.h"
|
||||||
#include "pipe/p_format.h"
|
#include "pipe/p_format.h"
|
||||||
#include "util/u_inlines.h"
|
#include "util/u_inlines.h"
|
||||||
|
|
@ -45,6 +48,7 @@ struct dri_sw_displaytarget
|
||||||
unsigned stride;
|
unsigned stride;
|
||||||
|
|
||||||
unsigned map_flags;
|
unsigned map_flags;
|
||||||
|
int shmid;
|
||||||
void *data;
|
void *data;
|
||||||
void *mapped;
|
void *mapped;
|
||||||
const void *front_private;
|
const void *front_private;
|
||||||
|
|
@ -79,6 +83,25 @@ dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
alloc_shm(struct dri_sw_displaytarget *dri_sw_dt, unsigned size)
|
||||||
|
{
|
||||||
|
char *addr;
|
||||||
|
|
||||||
|
dri_sw_dt->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
|
||||||
|
if (dri_sw_dt->shmid < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
addr = (char *) shmat(dri_sw_dt->shmid, 0, 0);
|
||||||
|
/* mark the segment immediately for deletion to avoid leaks */
|
||||||
|
shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
|
if (addr == (char *) -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
static struct sw_displaytarget *
|
static struct sw_displaytarget *
|
||||||
dri_sw_displaytarget_create(struct sw_winsys *winsys,
|
dri_sw_displaytarget_create(struct sw_winsys *winsys,
|
||||||
unsigned tex_usage,
|
unsigned tex_usage,
|
||||||
|
|
@ -88,6 +111,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
|
||||||
const void *front_private,
|
const void *front_private,
|
||||||
unsigned *stride)
|
unsigned *stride)
|
||||||
{
|
{
|
||||||
|
struct dri_sw_winsys *ws = dri_sw_winsys(winsys);
|
||||||
struct dri_sw_displaytarget *dri_sw_dt;
|
struct dri_sw_displaytarget *dri_sw_dt;
|
||||||
unsigned nblocksy, size, format_stride;
|
unsigned nblocksy, size, format_stride;
|
||||||
|
|
||||||
|
|
@ -106,7 +130,13 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
|
||||||
nblocksy = util_format_get_nblocksy(format, height);
|
nblocksy = util_format_get_nblocksy(format, height);
|
||||||
size = dri_sw_dt->stride * nblocksy;
|
size = dri_sw_dt->stride * nblocksy;
|
||||||
|
|
||||||
dri_sw_dt->data = align_malloc(size, alignment);
|
dri_sw_dt->shmid = -1;
|
||||||
|
if (ws->lf->put_image_shm)
|
||||||
|
dri_sw_dt->data = alloc_shm(dri_sw_dt, size);
|
||||||
|
|
||||||
|
if(!dri_sw_dt->data)
|
||||||
|
dri_sw_dt->data = align_malloc(size, alignment);
|
||||||
|
|
||||||
if(!dri_sw_dt->data)
|
if(!dri_sw_dt->data)
|
||||||
goto no_data;
|
goto no_data;
|
||||||
|
|
||||||
|
|
@ -125,7 +155,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
|
||||||
{
|
{
|
||||||
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
|
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
|
||||||
|
|
||||||
align_free(dri_sw_dt->data);
|
if (dri_sw_dt->shmid >= 0) {
|
||||||
|
shmdt(dri_sw_dt->data);
|
||||||
|
shmctl(dri_sw_dt->shmid, IPC_RMID, 0);
|
||||||
|
} else {
|
||||||
|
align_free(dri_sw_dt->data);
|
||||||
|
}
|
||||||
|
|
||||||
FREE(dri_sw_dt);
|
FREE(dri_sw_dt);
|
||||||
}
|
}
|
||||||
|
|
@ -187,25 +222,38 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
|
||||||
struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
|
struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
|
||||||
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
|
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
|
||||||
struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
|
struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
|
||||||
unsigned width, height;
|
unsigned width, height, x = 0, y = 0;
|
||||||
unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
|
unsigned blsize = util_format_get_blocksize(dri_sw_dt->format);
|
||||||
|
unsigned offset = 0;
|
||||||
|
void *data = dri_sw_dt->data;
|
||||||
|
|
||||||
/* Set the width to 'stride / cpp'.
|
/* Set the width to 'stride / cpp'.
|
||||||
*
|
*
|
||||||
* PutImage correctly clips to the width of the dst drawable.
|
* PutImage correctly clips to the width of the dst drawable.
|
||||||
*/
|
*/
|
||||||
width = dri_sw_dt->stride / blsize;
|
|
||||||
|
|
||||||
height = dri_sw_dt->height;
|
|
||||||
|
|
||||||
if (box) {
|
if (box) {
|
||||||
void *data;
|
offset = (dri_sw_dt->stride * box->y) + box->x * blsize;
|
||||||
data = (char *)dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x * blsize;
|
data += offset;
|
||||||
dri_sw_ws->lf->put_image2(dri_drawable, data,
|
x = box->x;
|
||||||
box->x, box->y, box->width, box->height, dri_sw_dt->stride);
|
y = box->y;
|
||||||
|
width = box->width;
|
||||||
|
height = box->height;
|
||||||
} else {
|
} else {
|
||||||
dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
|
width = dri_sw_dt->stride / blsize;
|
||||||
|
height = dri_sw_dt->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dri_sw_dt->shmid != -1) {
|
||||||
|
dri_sw_ws->lf->put_image_shm(dri_drawable, dri_sw_dt->shmid, dri_sw_dt->data, offset,
|
||||||
|
x, y, width, height, dri_sw_dt->stride);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (box)
|
||||||
|
dri_sw_ws->lf->put_image2(dri_drawable, data,
|
||||||
|
x, y, width, height, dri_sw_dt->stride);
|
||||||
|
else
|
||||||
|
dri_sw_ws->lf->put_image(dri_drawable, data, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue