aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-AndrĂ© Lureau <[email protected]>2015-06-10 17:45:11 +0200
committerDave Airlie <[email protected]>2018-05-30 09:11:54 +1000
commitcf54bd5e8381dba18d52fe438acda20cc1685bf3 (patch)
tree9733976e7e81587dec8f6efc9e8d88dd16bba8c9
parent63c427fa71a07649d5c033a5c6184ef701348590 (diff)
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 <[email protected]> Reviewed-by: Adam Jackson <[email protected]>
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
index 00849985d6b..b36a53e960c 100644
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -26,6 +26,9 @@
*
**************************************************************************/
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "util/u_inlines.h"
@@ -45,6 +48,7 @@ struct dri_sw_displaytarget
unsigned stride;
unsigned map_flags;
+ int shmid;
void *data;
void *mapped;
const void *front_private;
@@ -79,6 +83,25 @@ dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
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 *
dri_sw_displaytarget_create(struct sw_winsys *winsys,
unsigned tex_usage,
@@ -88,6 +111,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
const void *front_private,
unsigned *stride)
{
+ struct dri_sw_winsys *ws = dri_sw_winsys(winsys);
struct dri_sw_displaytarget *dri_sw_dt;
unsigned nblocksy, size, format_stride;
@@ -106,7 +130,13 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
nblocksy = util_format_get_nblocksy(format, height);
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)
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);
- 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);
}
@@ -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_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
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 offset = 0;
+ void *data = dri_sw_dt->data;
/* Set the width to 'stride / cpp'.
*
* PutImage correctly clips to the width of the dst drawable.
*/
- width = dri_sw_dt->stride / blsize;
-
- height = dri_sw_dt->height;
-
if (box) {
- void *data;
- data = (char *)dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x * blsize;
- dri_sw_ws->lf->put_image2(dri_drawable, data,
- box->x, box->y, box->width, box->height, dri_sw_dt->stride);
+ offset = (dri_sw_dt->stride * box->y) + box->x * blsize;
+ data += offset;
+ x = box->x;
+ y = box->y;
+ width = box->width;
+ height = box->height;
} 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