diff options
author | Eric Anholt <[email protected]> | 2011-10-13 12:02:43 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-11-01 15:42:17 -0700 |
commit | 76d1275474d7b5ac2f0edf5856ae1c5fc234f0d9 (patch) | |
tree | 237e9241c2cd2c749b3fcb979c2e4a15bb35da00 /src/mesa/drivers/dri/swrast | |
parent | a25a452fbed6cd72b356ff96839d2097b3e4a4fe (diff) |
Add MapRenderbuffer implementations for software drivers.
Mesa core's is generic for things like osmesa.
For swrast_dri.so, we have to do Y flipping. The front-buffer path
isn't actually tested, though, because both before and after it fails
with a BadMatch in XGetImage.
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/swrast')
-rw-r--r-- | src/mesa/drivers/dri/swrast/swrast.c | 84 | ||||
-rw-r--r-- | src/mesa/drivers/dri/swrast/swrast_priv.h | 5 |
2 files changed, 85 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index 75d25253eb4..bc115e8cf1a 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -291,7 +291,7 @@ swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, rb->Data = NULL; rb->Width = width; rb->Height = height; - + rb->RowStride = width; xrb->pitch = bytes_per_line(width * xrb->bpp, 32); return GL_TRUE; @@ -315,7 +315,8 @@ swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, } static struct swrast_renderbuffer * -swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front) +swrast_new_renderbuffer(const struct gl_config *visual, __DRIdrawable *dPriv, + GLboolean front) { struct swrast_renderbuffer *xrb = calloc(1, sizeof *xrb); GLuint pixel_format; @@ -329,6 +330,7 @@ swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front) pixel_format = choose_pixel_format(visual); + xrb->dPriv = dPriv; xrb->Base.Delete = swrast_delete_renderbuffer; if (front) { xrb->Base.AllocStorage = swrast_alloc_front_storage; @@ -375,6 +377,78 @@ swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front) return xrb; } +static void +swrast_map_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride) +{ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); + GLubyte *map = rb->Data; + int cpp = _mesa_get_format_bytes(rb->Format); + int stride = rb->RowStride * cpp; + + if (rb->AllocStorage == swrast_alloc_front_storage) { + __DRIdrawable *dPriv = xrb->dPriv; + __DRIscreen *sPriv = dPriv->driScreenPriv; + + xrb->map_mode = mode; + xrb->map_x = x; + xrb->map_y = y; + xrb->map_w = w; + xrb->map_h = h; + + stride = w * cpp; + rb->Data = malloc(h * stride); + + sPriv->swrast_loader->getImage(dPriv, x, y, w, h, + (char *)rb->Data, + dPriv->loaderPrivate); + + *out_map = rb->Data; + *out_stride = stride; + return; + } + + ASSERT(rb->Data); + + if (rb->AllocStorage == swrast_alloc_back_storage) { + map += (rb->Height - 1) * stride; + stride = -stride; + } + + map += y * stride; + map += x * cpp; + + *out_map = map; + *out_stride = stride; +} + +static void +swrast_unmap_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); + + if (rb->AllocStorage == swrast_alloc_front_storage) { + __DRIdrawable *dPriv = xrb->dPriv; + __DRIscreen *sPriv = dPriv->driScreenPriv; + + if (xrb->map_mode & GL_MAP_WRITE_BIT) { + sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_DRAW, + xrb->map_x, xrb->map_y, + xrb->map_w, xrb->map_h, + rb->Data, + dPriv->loaderPrivate); + } + + free(rb->Data); + rb->Data = NULL; + } +} + static GLboolean dri_create_buffer(__DRIscreen * sPriv, __DRIdrawable * dPriv, @@ -406,12 +480,12 @@ dri_create_buffer(__DRIscreen * sPriv, _mesa_initialize_window_framebuffer(fb, visual); /* add front renderbuffer */ - frontrb = swrast_new_renderbuffer(visual, GL_TRUE); + frontrb = swrast_new_renderbuffer(visual, dPriv, GL_TRUE); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base); /* add back renderbuffer */ if (visual->doubleBufferMode) { - backrb = swrast_new_renderbuffer(visual, GL_FALSE); + backrb = swrast_new_renderbuffer(visual, dPriv, GL_FALSE); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base); } @@ -576,6 +650,8 @@ swrast_init_driver_functions(struct dd_function_table *driver) driver->GetBufferSize = NULL; driver->Viewport = viewport; driver->ChooseTextureFormat = swrastChooseTextureFormat; + driver->MapRenderbuffer = swrast_map_renderbuffer; + driver->UnmapRenderbuffer = swrast_unmap_renderbuffer; } static const char *es2_extensions[] = { diff --git a/src/mesa/drivers/dri/swrast/swrast_priv.h b/src/mesa/drivers/dri/swrast/swrast_priv.h index bdb52ef26f1..50e6a83d578 100644 --- a/src/mesa/drivers/dri/swrast/swrast_priv.h +++ b/src/mesa/drivers/dri/swrast/swrast_priv.h @@ -102,6 +102,11 @@ swrast_drawable(struct gl_framebuffer *fb) struct swrast_renderbuffer { struct gl_renderbuffer Base; + __DRIdrawable *dPriv; + + /* GL_MAP_*_BIT, used for mapping of front buffer. */ + GLbitfield map_mode; + int map_x, map_y, map_w, map_h; /* renderbuffer pitch (in bytes) */ GLuint pitch; |