Mercurial > sdl-ios-xcode
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 = |