# HG changeset patch # User Sunny Sachanandani # Date 1277217098 -19800 # Node ID 25391ccf16a07439bc25c655a303b01028905c84 # Parent e479c1e57c521f98af9f7790f6cf2cfba34f40b3 Texture rendering mostly works now. Even SDL_TEXTUREACCESS_STREAMING is supported now with a little overhead. Scaling of textures happens using XRender. :D diff -r e479c1e57c52 -r 25391ccf16a0 src/video/x11/SDL_x11render.c --- a/src/video/x11/SDL_x11render.c Wed Jun 16 10:50:01 2010 +0530 +++ b/src/video/x11/SDL_x11render.c Tue Jun 22 20:01:38 2010 +0530 @@ -482,6 +482,14 @@ } if (!shm_error) { data->pixels = shminfo->shmaddr; + data->pixmap = + XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, + texture->h, renderdata->depth); + if (data->pixmap == None) { + X11_DestroyTexture(renderer, texture); + SDL_SetError("XCreatePixmap() failed"); + return -1; + } data->image = XShmCreateImage(renderdata->display, renderdata->visual, @@ -516,6 +524,14 @@ return -1; } + data->pixmap = + XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, + texture->h, renderdata->depth); + if (data->pixmap == None) { + X11_DestroyTexture(renderer, texture); + SDL_SetError("XCreatePixmap() failed"); + return -1; + } data->image = XCreateImage(renderdata->display, renderdata->visual, renderdata->depth, ZPixmap, 0, data->pixels, @@ -665,7 +681,6 @@ X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; if (data->pixels) { - // If we have already allocated memory or were given memory by XShm Uint8 *src, *dst; int row; size_t length; @@ -680,17 +695,6 @@ src += pitch; dst += data->pitch; } - /* If this is a static texture we would use Xrender for it - but this requires that the server side Pixmap associated - with this texture be updated with the data as well. - Hopefully the user will not update static textures so - frequently as to cause a slowdown. - */ - if (texture->access == SDL_TEXTUREACCESS_STATIC) { - XPutImage(renderdata->display, data->pixmap, renderdata->gc, - data->image, 0, 0, rect->x, rect->y, rect->w, rect->h); - } - } else { data->image->width = rect->w; data->image->height = rect->h; @@ -823,15 +827,22 @@ } #ifdef SDL_VIDEO_DRIVER_X11_XRENDER if (data->use_xrender == SDL_TRUE) { + XRenderColor foreground; + + foreground = xrenderdrawcolor(renderer); + XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, - 0, 0, 0, 0, 0, 0, window->w, window->h); + 0, 0, 0, 0, 0, 0, window->w, window->h); + XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount, CoordModeOrigin); - XRenderColor foreground = xrenderdrawcolor(renderer); + Picture fill = XRenderCreateSolidFill(data->display, &foreground); + XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); + XRenderFreePicture(data->display, fill); } else @@ -1023,7 +1034,24 @@ SDL_Rect clip, rect; int i, xcount; XRectangle *xrects, *xrect; - + xrect = xrects = SDL_stack_alloc(XRectangle, count); + xcount = 0; + for (i = 0; i < count; ++i) { + if (!SDL_IntersectRect(rects[i], &clip, &rect)) { + continue; + } + + xrect->x = (short)rect.x; + xrect->y = (short)rect.y; + xrect->width = (unsigned short)rect.w; + xrect->height = (unsigned short)rect.h; + ++xrect; + ++xcount; + + if (data->makedirty) { + SDL_AddDirtyRect(&data->dirty, &rect); + } + } clip.x = 0; clip.y = 0; clip.w = window->w; @@ -1031,67 +1059,26 @@ #ifdef SDL_VIDEO_DRIVER_X11_XRENDER if(data->use_xrender == SDL_TRUE) { - XRectangle xclip; - - xclip.x = (short)clip.x; - xclip.y = (short)clip.y; - xclip.width = (unsigned short)clip.w; - xclip.height = (unsigned short)clip.h; - XRenderColor foreground; foreground = xrenderdrawcolor(renderer); - xrect = xrects = SDL_stack_alloc(XRectangle, count); - xcount = 0; - for (i = 0; i < count; ++i) { - xrect->x = (short)rects[i]->x; - xrect->y = (short)rects[i]->y; - xrect->width = (unsigned short)rects[i]->w; - xrect->height = (unsigned short)rects[i]->h; - ++xrect; - ++xcount; - } - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, &clip); - } XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount); Picture fill = XRenderCreateSolidFill(data->display, &foreground); - XRenderSetPictureClipRectangles(data->display, data->drawable_pict, 0, 0, &xclip, 1); XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); XRenderFreePicture(data->display, fill); - SDL_stack_free(xrects); } else #endif { - unsigned long foreground; foreground = renderdrawcolor(renderer, 1); XSetForeground(data->display, data->gc, foreground); - xrect = xrects = SDL_stack_alloc(XRectangle, count); - xcount = 0; - for (i = 0; i < count; ++i) { - if (!SDL_IntersectRect(rects[i], &clip, &rect)) { - continue; - } - - xrect->x = (short)rect.x; - xrect->y = (short)rect.y; - xrect->width = (unsigned short)rect.w; - xrect->height = (unsigned short)rect.h; - ++xrect; - ++xcount; - - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, &rect); - } - } if (xcount > 0) { XDrawRectangles(data->display, data->drawable, data->gc, xrects, xcount); @@ -1116,79 +1103,55 @@ int i, xcount; XRectangle *xrects, *xrect; - xrect = xrects = SDL_stack_alloc(XRectangle, count); xcount = 0; + for (i = 0; i < count; ++i) { + if (!SDL_IntersectRect(rects[i], &clip, &rect)) { + continue; + } + + xrect->x = (short)rect.x; + xrect->y = (short)rect.y; + xrect->width = (unsigned short)rect.w; + xrect->height = (unsigned short)rect.h; + ++xrect; + ++xcount; + + if (data->makedirty) { + SDL_AddDirtyRect(&data->dirty, &rect); + } + } #ifdef SDL_VIDEO_DRIVER_X11_XRENDER if(data->use_xrender == SDL_TRUE) { - XRectangle xclip; - - xclip.x = (short)clip.x; - xclip.y = (short)clip.y; - xclip.width = (unsigned short)clip.w; - xclip.height = (unsigned short)clip.h; - XRenderColor foreground; foreground = xrenderdrawcolor(renderer); - - for (i = 0; i < count; ++i) { - xrect->x = (short)rects[i]->x; - xrect->y = (short)rects[i]->y; - xrect->width = (unsigned short)rects[i]->w; - xrect->height = (unsigned short)rects[i]->h; - ++xrect; - ++xcount; - } - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, &clip); - } + XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); XFillRectangles(data->display, data->mask, data->mask_gc, xrects, xcount); - XRenderSetPictureClipRectangles(data->display, data->drawable_pict, 0, 0, &xclip, 1); Picture fill = XRenderCreateSolidFill(data->display, &foreground); XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict, 0, 0, 0, 0, 0, 0, window->w, window->h); XRenderFreePicture(data->display, fill); - SDL_stack_free(xrects); - } else #endif { unsigned long foreground; - XRectangle *xrects, *xrect; - + foreground = renderdrawcolor(renderer, 1); XSetForeground(data->display, data->gc, foreground); - - xrect = xrects = SDL_stack_alloc(XRectangle, count); - xcount = 0; - for (i = 0; i < count; ++i) { - if (!SDL_IntersectRect(rects[i], &clip, &rect)) { - continue; - } - - xrect->x = (short)rect.x; - xrect->y = (short)rect.y; - xrect->width = (unsigned short)rect.w; - xrect->height = (unsigned short)rect.h; - ++xrect; - ++xcount; - - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, &rect); - } - } + XFillRectangles(data->display, data->drawable, data->gc, xrects, xcount); - SDL_stack_free(xrects); } - + + SDL_stack_free(xrects); + return 0; } @@ -1203,7 +1166,23 @@ SDL_AddDirtyRect(&data->dirty, dstrect); } #ifdef SDL_VIDEO_DRIVER_X11_XRENDER - if (data->use_xrender && texturedata->use_xrender && texture->access == SDL_TEXTUREACCESS_STATIC) { + if (data->use_xrender && texturedata->use_xrender) { + if(texture->access == SDL_TEXTUREACCESS_STREAMING) { +#ifndef NO_SHARED_MEMORY + if(texturedata->shminfo.shmaddr) { + XShmPutImage(data->display, texturedata->pixmap, data->gc, + texturedata->image, srcrect->x, srcrect->y, + srcrect->x, srcrect->y, srcrect->w, srcrect->h, + False); + } + else +#endif + if (texturedata->pixels) { + XPutImage(data->display, texturedata->pixmap, data->gc, + texturedata->image, srcrect->x, srcrect->y, dstrect->x, + dstrect->y, srcrect->w, srcrect->h); + } + } if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { XRenderComposite(data->display, PictOpOver, texturedata->picture, None, data->drawable_pict, srcrect->x, srcrect->y, 0, 0, dstrect->x, dstrect->y, srcrect->w, srcrect->h);