comparison src/video/x11/SDL_x11render.c @ 4587:25391ccf16a0

Texture rendering mostly works now. Even SDL_TEXTUREACCESS_STREAMING is supported now with a little overhead. Scaling of textures happens using XRender. :D
author Sunny Sachanandani <sunnysachanandani@gmail.com>
date Tue, 22 Jun 2010 20:01:38 +0530
parents e479c1e57c52
children 0ddd78496d68
comparison
equal deleted inserted replaced
4586:e479c1e57c52 4587:25391ccf16a0
480 shmctl(shminfo->shmid, IPC_RMID, NULL); 480 shmctl(shminfo->shmid, IPC_RMID, NULL);
481 } 481 }
482 } 482 }
483 if (!shm_error) { 483 if (!shm_error) {
484 data->pixels = shminfo->shmaddr; 484 data->pixels = shminfo->shmaddr;
485 data->pixmap =
486 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
487 texture->h, renderdata->depth);
488 if (data->pixmap == None) {
489 X11_DestroyTexture(renderer, texture);
490 SDL_SetError("XCreatePixmap() failed");
491 return -1;
492 }
485 493
486 data->image = 494 data->image =
487 XShmCreateImage(renderdata->display, renderdata->visual, 495 XShmCreateImage(renderdata->display, renderdata->visual,
488 renderdata->depth, ZPixmap, shminfo->shmaddr, 496 renderdata->depth, ZPixmap, shminfo->shmaddr,
489 shminfo, texture->w, texture->h); 497 shminfo, texture->w, texture->h);
514 X11_DestroyTexture(renderer, texture); 522 X11_DestroyTexture(renderer, texture);
515 SDL_OutOfMemory(); 523 SDL_OutOfMemory();
516 return -1; 524 return -1;
517 } 525 }
518 526
527 data->pixmap =
528 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w,
529 texture->h, renderdata->depth);
530 if (data->pixmap == None) {
531 X11_DestroyTexture(renderer, texture);
532 SDL_SetError("XCreatePixmap() failed");
533 return -1;
534 }
519 data->image = 535 data->image =
520 XCreateImage(renderdata->display, renderdata->visual, 536 XCreateImage(renderdata->display, renderdata->visual,
521 renderdata->depth, ZPixmap, 0, data->pixels, 537 renderdata->depth, ZPixmap, 0, data->pixels,
522 texture->w, texture->h, 538 texture->w, texture->h,
523 SDL_BYTESPERPIXEL(data->format) * 8, 539 SDL_BYTESPERPIXEL(data->format) * 8,
663 return 0; 679 return 0;
664 } else { 680 } else {
665 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; 681 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
666 682
667 if (data->pixels) { 683 if (data->pixels) {
668 // If we have already allocated memory or were given memory by XShm
669 Uint8 *src, *dst; 684 Uint8 *src, *dst;
670 int row; 685 int row;
671 size_t length; 686 size_t length;
672 687
673 src = (Uint8 *) pixels; 688 src = (Uint8 *) pixels;
678 for (row = 0; row < rect->h; ++row) { 693 for (row = 0; row < rect->h; ++row) {
679 SDL_memcpy(dst, src, length); 694 SDL_memcpy(dst, src, length);
680 src += pitch; 695 src += pitch;
681 dst += data->pitch; 696 dst += data->pitch;
682 } 697 }
683 /* If this is a static texture we would use Xrender for it
684 but this requires that the server side Pixmap associated
685 with this texture be updated with the data as well.
686 Hopefully the user will not update static textures so
687 frequently as to cause a slowdown.
688 */
689 if (texture->access == SDL_TEXTUREACCESS_STATIC) {
690 XPutImage(renderdata->display, data->pixmap, renderdata->gc,
691 data->image, 0, 0, rect->x, rect->y, rect->w, rect->h);
692 }
693
694 } else { 698 } else {
695 data->image->width = rect->w; 699 data->image->width = rect->w;
696 data->image->height = rect->h; 700 data->image->height = rect->h;
697 data->image->data = (char *) pixels; 701 data->image->data = (char *) pixels;
698 data->image->bytes_per_line = pitch; 702 data->image->bytes_per_line = pitch;
821 ++xpoint; 825 ++xpoint;
822 ++xcount; 826 ++xcount;
823 } 827 }
824 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 828 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
825 if (data->use_xrender == SDL_TRUE) { 829 if (data->use_xrender == SDL_TRUE) {
830 XRenderColor foreground;
831
832 foreground = xrenderdrawcolor(renderer);
833
826 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, 834 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict,
827 0, 0, 0, 0, 0, 0, window->w, window->h); 835 0, 0, 0, 0, 0, 0, window->w, window->h);
836
828 XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount, 837 XDrawPoints(data->display, data->mask, data->mask_gc, xpoints, xcount,
829 CoordModeOrigin); 838 CoordModeOrigin);
830 XRenderColor foreground = xrenderdrawcolor(renderer); 839
831 Picture fill = 840 Picture fill =
832 XRenderCreateSolidFill(data->display, &foreground); 841 XRenderCreateSolidFill(data->display, &foreground);
842
833 XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict, 843 XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict,
834 0, 0, 0, 0, 0, 0, window->w, window->h); 844 0, 0, 0, 0, 0, 0, window->w, window->h);
845
835 XRenderFreePicture(data->display, fill); 846 XRenderFreePicture(data->display, fill);
836 } 847 }
837 else 848 else
838 #endif 849 #endif
839 { 850 {
1021 X11_RenderData *data = (X11_RenderData *) renderer->driverdata; 1032 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
1022 SDL_Window *window = renderer->window; 1033 SDL_Window *window = renderer->window;
1023 SDL_Rect clip, rect; 1034 SDL_Rect clip, rect;
1024 int i, xcount; 1035 int i, xcount;
1025 XRectangle *xrects, *xrect; 1036 XRectangle *xrects, *xrect;
1026 1037 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1038 xcount = 0;
1039 for (i = 0; i < count; ++i) {
1040 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
1041 continue;
1042 }
1043
1044 xrect->x = (short)rect.x;
1045 xrect->y = (short)rect.y;
1046 xrect->width = (unsigned short)rect.w;
1047 xrect->height = (unsigned short)rect.h;
1048 ++xrect;
1049 ++xcount;
1050
1051 if (data->makedirty) {
1052 SDL_AddDirtyRect(&data->dirty, &rect);
1053 }
1054 }
1027 clip.x = 0; 1055 clip.x = 0;
1028 clip.y = 0; 1056 clip.y = 0;
1029 clip.w = window->w; 1057 clip.w = window->w;
1030 clip.h = window->h; 1058 clip.h = window->h;
1031 1059
1032 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1060 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1033 if(data->use_xrender == SDL_TRUE) { 1061 if(data->use_xrender == SDL_TRUE) {
1034 XRectangle xclip;
1035
1036 xclip.x = (short)clip.x;
1037 xclip.y = (short)clip.y;
1038 xclip.width = (unsigned short)clip.w;
1039 xclip.height = (unsigned short)clip.h;
1040
1041 XRenderColor foreground; 1062 XRenderColor foreground;
1042 foreground = xrenderdrawcolor(renderer); 1063 foreground = xrenderdrawcolor(renderer);
1043 1064
1044 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1045 xcount = 0;
1046 for (i = 0; i < count; ++i) {
1047 xrect->x = (short)rects[i]->x;
1048 xrect->y = (short)rects[i]->y;
1049 xrect->width = (unsigned short)rects[i]->w;
1050 xrect->height = (unsigned short)rects[i]->h;
1051 ++xrect;
1052 ++xcount;
1053 }
1054 if (data->makedirty) {
1055 SDL_AddDirtyRect(&data->dirty, &clip);
1056 }
1057 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, 1065 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict,
1058 0, 0, 0, 0, 0, 0, window->w, window->h); 1066 0, 0, 0, 0, 0, 0, window->w, window->h);
1059 XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount); 1067 XDrawRectangles(data->display, data->mask, data->mask_gc, xrects, xcount);
1060 Picture fill = 1068 Picture fill =
1061 XRenderCreateSolidFill(data->display, &foreground); 1069 XRenderCreateSolidFill(data->display, &foreground);
1062 XRenderSetPictureClipRectangles(data->display, data->drawable_pict, 0, 0, &xclip, 1);
1063 XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict, 1070 XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict,
1064 0, 0, 0, 0, 0, 0, window->w, window->h); 1071 0, 0, 0, 0, 0, 0, window->w, window->h);
1065 XRenderFreePicture(data->display, fill); 1072 XRenderFreePicture(data->display, fill);
1066 SDL_stack_free(xrects);
1067 } 1073 }
1068 else 1074 else
1069 #endif 1075 #endif
1070 { 1076 {
1071
1072 unsigned long foreground; 1077 unsigned long foreground;
1073 1078
1074 foreground = renderdrawcolor(renderer, 1); 1079 foreground = renderdrawcolor(renderer, 1);
1075 XSetForeground(data->display, data->gc, foreground); 1080 XSetForeground(data->display, data->gc, foreground);
1076 1081
1077 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1078 xcount = 0;
1079 for (i = 0; i < count; ++i) {
1080 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
1081 continue;
1082 }
1083
1084 xrect->x = (short)rect.x;
1085 xrect->y = (short)rect.y;
1086 xrect->width = (unsigned short)rect.w;
1087 xrect->height = (unsigned short)rect.h;
1088 ++xrect;
1089 ++xcount;
1090
1091 if (data->makedirty) {
1092 SDL_AddDirtyRect(&data->dirty, &rect);
1093 }
1094 }
1095 if (xcount > 0) { 1082 if (xcount > 0) {
1096 XDrawRectangles(data->display, data->drawable, data->gc, 1083 XDrawRectangles(data->display, data->drawable, data->gc,
1097 xrects, xcount); 1084 xrects, xcount);
1098 } 1085 }
1099 } 1086 }
1114 clip.w = window->w; 1101 clip.w = window->w;
1115 clip.h = window->h; 1102 clip.h = window->h;
1116 1103
1117 int i, xcount; 1104 int i, xcount;
1118 XRectangle *xrects, *xrect; 1105 XRectangle *xrects, *xrect;
1119
1120 xrect = xrects = SDL_stack_alloc(XRectangle, count); 1106 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1121 xcount = 0; 1107 xcount = 0;
1108 for (i = 0; i < count; ++i) {
1109 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
1110 continue;
1111 }
1112
1113 xrect->x = (short)rect.x;
1114 xrect->y = (short)rect.y;
1115 xrect->width = (unsigned short)rect.w;
1116 xrect->height = (unsigned short)rect.h;
1117 ++xrect;
1118 ++xcount;
1119
1120 if (data->makedirty) {
1121 SDL_AddDirtyRect(&data->dirty, &rect);
1122 }
1123 }
1122 1124
1123 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1125 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1124 if(data->use_xrender == SDL_TRUE) { 1126 if(data->use_xrender == SDL_TRUE) {
1125 XRectangle xclip;
1126
1127 xclip.x = (short)clip.x;
1128 xclip.y = (short)clip.y;
1129 xclip.width = (unsigned short)clip.w;
1130 xclip.height = (unsigned short)clip.h;
1131
1132 XRenderColor foreground; 1127 XRenderColor foreground;
1133 1128
1134 foreground = xrenderdrawcolor(renderer); 1129 foreground = xrenderdrawcolor(renderer);
1135 1130
1136 for (i = 0; i < count; ++i) {
1137 xrect->x = (short)rects[i]->x;
1138 xrect->y = (short)rects[i]->y;
1139 xrect->width = (unsigned short)rects[i]->w;
1140 xrect->height = (unsigned short)rects[i]->h;
1141 ++xrect;
1142 ++xcount;
1143 }
1144 if (data->makedirty) {
1145 SDL_AddDirtyRect(&data->dirty, &clip);
1146 }
1147 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict, 1131 XRenderComposite(data->display, PictOpClear, data->mask_pict, None, data->mask_pict,
1148 0, 0, 0, 0, 0, 0, window->w, window->h); 1132 0, 0, 0, 0, 0, 0, window->w, window->h);
1149 XFillRectangles(data->display, data->mask, data->mask_gc, 1133 XFillRectangles(data->display, data->mask, data->mask_gc,
1150 xrects, xcount); 1134 xrects, xcount);
1151 XRenderSetPictureClipRectangles(data->display, data->drawable_pict, 0, 0, &xclip, 1);
1152 Picture fill = 1135 Picture fill =
1153 XRenderCreateSolidFill(data->display, &foreground); 1136 XRenderCreateSolidFill(data->display, &foreground);
1154 XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict, 1137 XRenderComposite(data->display, PictOpOver, fill, data->mask_pict, data->drawable_pict,
1155 0, 0, 0, 0, 0, 0, window->w, window->h); 1138 0, 0, 0, 0, 0, 0, window->w, window->h);
1156 XRenderFreePicture(data->display, fill); 1139 XRenderFreePicture(data->display, fill);
1157 SDL_stack_free(xrects);
1158
1159 } 1140 }
1160 else 1141 else
1161 #endif 1142 #endif
1162 { 1143 {
1163 unsigned long foreground; 1144 unsigned long foreground;
1164 XRectangle *xrects, *xrect; 1145
1165
1166 foreground = renderdrawcolor(renderer, 1); 1146 foreground = renderdrawcolor(renderer, 1);
1167 XSetForeground(data->display, data->gc, foreground); 1147 XSetForeground(data->display, data->gc, foreground);
1168 1148
1169 xrect = xrects = SDL_stack_alloc(XRectangle, count);
1170 xcount = 0;
1171 for (i = 0; i < count; ++i) {
1172 if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
1173 continue;
1174 }
1175
1176 xrect->x = (short)rect.x;
1177 xrect->y = (short)rect.y;
1178 xrect->width = (unsigned short)rect.w;
1179 xrect->height = (unsigned short)rect.h;
1180 ++xrect;
1181 ++xcount;
1182
1183 if (data->makedirty) {
1184 SDL_AddDirtyRect(&data->dirty, &rect);
1185 }
1186 }
1187 XFillRectangles(data->display, data->drawable, data->gc, 1149 XFillRectangles(data->display, data->drawable, data->gc,
1188 xrects, xcount); 1150 xrects, xcount);
1189 SDL_stack_free(xrects); 1151 }
1190 } 1152
1191 1153 SDL_stack_free(xrects);
1154
1192 return 0; 1155 return 0;
1193 } 1156 }
1194 1157
1195 static int 1158 static int
1196 X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 1159 X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
1201 1164
1202 if (data->makedirty) { 1165 if (data->makedirty) {
1203 SDL_AddDirtyRect(&data->dirty, dstrect); 1166 SDL_AddDirtyRect(&data->dirty, dstrect);
1204 } 1167 }
1205 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 1168 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
1206 if (data->use_xrender && texturedata->use_xrender && texture->access == SDL_TEXTUREACCESS_STATIC) { 1169 if (data->use_xrender && texturedata->use_xrender) {
1170 if(texture->access == SDL_TEXTUREACCESS_STREAMING) {
1171 #ifndef NO_SHARED_MEMORY
1172 if(texturedata->shminfo.shmaddr) {
1173 XShmPutImage(data->display, texturedata->pixmap, data->gc,
1174 texturedata->image, srcrect->x, srcrect->y,
1175 srcrect->x, srcrect->y, srcrect->w, srcrect->h,
1176 False);
1177 }
1178 else
1179 #endif
1180 if (texturedata->pixels) {
1181 XPutImage(data->display, texturedata->pixmap, data->gc,
1182 texturedata->image, srcrect->x, srcrect->y, dstrect->x,
1183 dstrect->y, srcrect->w, srcrect->h);
1184 }
1185 }
1207 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { 1186 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
1208 XRenderComposite(data->display, PictOpOver, texturedata->picture, None, data->drawable_pict, 1187 XRenderComposite(data->display, PictOpOver, texturedata->picture, None, data->drawable_pict,
1209 srcrect->x, srcrect->y, 0, 0, dstrect->x, dstrect->y, srcrect->w, srcrect->h); 1188 srcrect->x, srcrect->y, 0, 0, dstrect->x, dstrect->y, srcrect->w, srcrect->h);
1210 } else { 1189 } else {
1211 Pixmap scaling_pixmap = 1190 Pixmap scaling_pixmap =