Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11render.c @ 2828:7e5ff6cd05bf
Added very slow software scaling to the X11 renderer
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 03 Dec 2008 12:10:51 +0000 |
parents | aec4399c507a |
children | 99210400e8b9 |
comparison
equal
deleted
inserted
replaced
2827:aec4399c507a | 2828:7e5ff6cd05bf |
---|---|
95 XImage *image; | 95 XImage *image; |
96 #ifndef NO_SHARED_MEMORY | 96 #ifndef NO_SHARED_MEMORY |
97 /* MIT shared memory extension information */ | 97 /* MIT shared memory extension information */ |
98 XShmSegmentInfo shminfo; | 98 XShmSegmentInfo shminfo; |
99 #endif | 99 #endif |
100 XImage *scaling_image; | |
100 void *pixels; | 101 void *pixels; |
101 int pitch; | 102 int pitch; |
102 } X11_TextureData; | 103 } X11_TextureData; |
103 | 104 |
104 #ifndef NO_SHARED_MEMORY | 105 #ifndef NO_SHARED_MEMORY |
127 rect.y = 0; | 128 rect.y = 0; |
128 rect.w = texture->w; | 129 rect.w = texture->w; |
129 rect.h = texture->h; | 130 rect.h = texture->h; |
130 SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, | 131 SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, |
131 texture->h, data->pixels, data->pitch); | 132 texture->h, data->pixels, data->pitch); |
133 } | |
134 | |
135 static int | |
136 X11_GetDepthFromPixelFormat(Uint32 format) | |
137 { | |
138 int depth, order; | |
139 | |
140 depth = SDL_BITSPERPIXEL(format); | |
141 order = SDL_PIXELORDER(format); | |
142 if (depth == 32 | |
143 && (order == SDL_PACKEDORDER_XRGB || order == SDL_PACKEDORDER_RGBX | |
144 || SDL_PACKEDORDER_XBGR || order == SDL_PACKEDORDER_BGRX)) { | |
145 depth = 24; | |
146 } | |
147 return depth; | |
132 } | 148 } |
133 | 149 |
134 static Uint32 | 150 static Uint32 |
135 X11_GetPixelFormatFromDepth(Display * display, int screen, int depth, int bpp) | 151 X11_GetPixelFormatFromDepth(Display * display, int screen, int depth, int bpp) |
136 { | 152 { |
383 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; | 399 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; |
384 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | 400 SDL_Window *window = SDL_GetWindowFromID(renderer->window); |
385 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | 401 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); |
386 X11_TextureData *data; | 402 X11_TextureData *data; |
387 XWindowAttributes attributes; | 403 XWindowAttributes attributes; |
388 int depth, order; | 404 int depth; |
389 | 405 |
390 data = (X11_TextureData *) SDL_calloc(1, sizeof(*data)); | 406 data = (X11_TextureData *) SDL_calloc(1, sizeof(*data)); |
391 if (!data) { | 407 if (!data) { |
392 SDL_OutOfMemory(); | 408 SDL_OutOfMemory(); |
393 return -1; | 409 return -1; |
407 } | 423 } |
408 data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format); | 424 data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format); |
409 | 425 |
410 XGetWindowAttributes(renderdata->display, renderdata->window, | 426 XGetWindowAttributes(renderdata->display, renderdata->window, |
411 &attributes); | 427 &attributes); |
412 depth = SDL_BITSPERPIXEL(data->format); | 428 depth = X11_GetDepthFromPixelFormat(data->format); |
413 order = SDL_PIXELORDER(data->format); | |
414 if (depth == 32 | |
415 && (order == SDL_PACKEDORDER_XRGB || order == SDL_PACKEDORDER_RGBX | |
416 || SDL_PACKEDORDER_XBGR || order == SDL_PACKEDORDER_BGRX)) { | |
417 depth = 24; | |
418 } | |
419 | 429 |
420 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { | 430 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { |
421 #ifndef NO_SHARED_MEMORY | 431 #ifndef NO_SHARED_MEMORY |
422 XShmSegmentInfo *shminfo = &data->shminfo; | 432 XShmSegmentInfo *shminfo = &data->shminfo; |
423 | 433 |
530 } | 540 } |
531 | 541 |
532 static int | 542 static int |
533 X11_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) | 543 X11_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) |
534 { | 544 { |
545 X11_TextureData *data = (X11_TextureData *) texture->driverdata; | |
546 | |
535 switch (texture->scaleMode) { | 547 switch (texture->scaleMode) { |
536 case SDL_TEXTURESCALEMODE_NONE: | 548 case SDL_TEXTURESCALEMODE_NONE: |
537 return 0; | 549 return 0; |
550 case SDL_TEXTURESCALEMODE_FAST: | |
551 /* We can sort of fake it for streaming textures */ | |
552 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { | |
553 return 0; | |
554 } | |
555 /* Fall through to unsupported case */ | |
538 default: | 556 default: |
539 SDL_Unsupported(); | 557 SDL_Unsupported(); |
540 texture->scaleMode = SDL_TEXTURESCALEMODE_NONE; | 558 texture->scaleMode = SDL_TEXTURESCALEMODE_NONE; |
541 return -1; | 559 return -1; |
542 } | 560 } |
644 X11_TextureData *texturedata = (X11_TextureData *) texture->driverdata; | 662 X11_TextureData *texturedata = (X11_TextureData *) texture->driverdata; |
645 | 663 |
646 if (data->makedirty) { | 664 if (data->makedirty) { |
647 SDL_AddDirtyRect(&data->dirty, dstrect); | 665 SDL_AddDirtyRect(&data->dirty, dstrect); |
648 } | 666 } |
667 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { | |
649 #ifndef NO_SHARED_MEMORY | 668 #ifndef NO_SHARED_MEMORY |
650 if (texturedata->shminfo.shmaddr) { | 669 if (texturedata->shminfo.shmaddr) { |
651 XShmPutImage(data->display, data->drawable, data->gc, | 670 XShmPutImage(data->display, data->drawable, data->gc, |
652 texturedata->image, srcrect->x, srcrect->y, dstrect->x, | 671 texturedata->image, srcrect->x, srcrect->y, |
653 dstrect->y, srcrect->w, srcrect->h, False); | 672 dstrect->x, dstrect->y, srcrect->w, srcrect->h, |
654 } else | 673 False); |
674 } else | |
655 #endif | 675 #endif |
656 if (texturedata->pixels) { | 676 if (texturedata->pixels) { |
657 XPutImage(data->display, data->drawable, data->gc, texturedata->image, | 677 XPutImage(data->display, data->drawable, data->gc, |
658 srcrect->x, srcrect->y, dstrect->x, dstrect->y, srcrect->w, | 678 texturedata->image, srcrect->x, srcrect->y, dstrect->x, |
659 srcrect->h); | 679 dstrect->y, srcrect->w, srcrect->h); |
680 } else { | |
681 XCopyArea(data->display, texturedata->pixmap, data->drawable, | |
682 data->gc, srcrect->x, srcrect->y, dstrect->w, | |
683 dstrect->h, srcrect->x, srcrect->y); | |
684 } | |
685 } else if (texturedata->yuv | |
686 || texture->access == SDL_TEXTUREACCESS_STREAMING) { | |
687 SDL_Surface src, dst; | |
688 SDL_PixelFormat fmt; | |
689 SDL_Rect rect; | |
690 XImage *image = texturedata->scaling_image; | |
691 | |
692 if (!image) { | |
693 XWindowAttributes attributes; | |
694 int depth; | |
695 void *pixels; | |
696 int pitch; | |
697 | |
698 XGetWindowAttributes(data->display, data->window, &attributes); | |
699 | |
700 pitch = dstrect->w * SDL_BYTESPERPIXEL(texturedata->format); | |
701 pixels = SDL_malloc(dstrect->h * pitch); | |
702 if (!pixels) { | |
703 SDL_OutOfMemory(); | |
704 return -1; | |
705 } | |
706 | |
707 depth = X11_GetDepthFromPixelFormat(texturedata->format); | |
708 image = | |
709 XCreateImage(data->display, attributes.visual, depth, ZPixmap, | |
710 0, pixels, dstrect->w, dstrect->h, | |
711 SDL_BYTESPERPIXEL(texturedata->format) * 8, | |
712 pitch); | |
713 if (!image) { | |
714 SDL_SetError("XCreateImage() failed"); | |
715 return -1; | |
716 } | |
717 texturedata->scaling_image = image; | |
718 | |
719 } else if (image->width != dstrect->w || image->height != dstrect->h | |
720 || !image->data) { | |
721 image->width = dstrect->w; | |
722 image->height = dstrect->h; | |
723 image->bytes_per_line = | |
724 image->width * SDL_BYTESPERPIXEL(texturedata->format); | |
725 image->data = | |
726 (char *) SDL_realloc(image->data, | |
727 image->height * image->bytes_per_line); | |
728 if (!image->data) { | |
729 SDL_OutOfMemory(); | |
730 return -1; | |
731 } | |
732 } | |
733 | |
734 /* Set up fake surfaces for SDL_SoftStretch() */ | |
735 src.format = &fmt; | |
736 src.w = texture->w; | |
737 src.h = texture->h; | |
738 #ifndef NO_SHARED_MEMORY | |
739 if (texturedata->shminfo.shmaddr) { | |
740 src.pixels = texturedata->shminfo.shmaddr; | |
741 } else | |
742 #endif | |
743 src.pixels = texturedata->pixels; | |
744 src.pitch = texturedata->pitch; | |
745 | |
746 dst.format = &fmt; | |
747 dst.w = image->width; | |
748 dst.h = image->height; | |
749 dst.pixels = image->data; | |
750 dst.pitch = image->bytes_per_line; | |
751 | |
752 fmt.BytesPerPixel = SDL_BYTESPERPIXEL(texturedata->format); | |
753 | |
754 rect.x = 0; | |
755 rect.y = 0; | |
756 rect.w = dstrect->w; | |
757 rect.h = dstrect->h; | |
758 if (SDL_SoftStretch(&src, srcrect, &dst, &rect) < 0) { | |
759 return -1; | |
760 } | |
761 XPutImage(data->display, data->drawable, data->gc, image, 0, 0, | |
762 dstrect->x, dstrect->y, dstrect->w, dstrect->h); | |
660 } else { | 763 } else { |
661 XCopyArea(data->display, texturedata->pixmap, data->drawable, | 764 XCopyArea(data->display, texturedata->pixmap, data->drawable, |
662 data->gc, srcrect->x, srcrect->y, dstrect->w, dstrect->h, | 765 data->gc, srcrect->x, srcrect->y, dstrect->w, dstrect->h, |
663 srcrect->x, srcrect->y); | 766 srcrect->x, srcrect->y); |
664 } | 767 } |
718 XSync(renderdata->display, False); | 821 XSync(renderdata->display, False); |
719 shmdt(data->shminfo.shmaddr); | 822 shmdt(data->shminfo.shmaddr); |
720 data->pixels = NULL; | 823 data->pixels = NULL; |
721 } | 824 } |
722 #endif | 825 #endif |
826 if (data->scaling_image) { | |
827 SDL_free(data->scaling_image->data); | |
828 data->scaling_image->data = NULL; | |
829 XDestroyImage(data->scaling_image); | |
830 } | |
723 if (data->pixels) { | 831 if (data->pixels) { |
724 SDL_free(data->pixels); | 832 SDL_free(data->pixels); |
725 } | 833 } |
726 SDL_free(data); | 834 SDL_free(data); |
727 texture->driverdata = NULL; | 835 texture->driverdata = NULL; |