Re: Re: SDLoad and PAL displays
Daniel Thompson <[email protected]> Mon, 27 Feb 2006 20:51:41 +0000
| Newsgroups | gmane.linux.ports.game-cube.devel |
|---|---|
| Message-ID | <[email protected]> |
On Mon, 2006-02-27 at 20:36 +0000, Daniel Thompson wrote: > coding done these days (though I do have a rather neat little flicker > filter for SDL that I haven't quite got round to releasing yet). Sorry for a self reply; it occurred to me how annoying it can be when people brag about code they haven't released so I decided to let it out! Basically the attached patch adds a simply but highly optimised 3-tap FIR flicker filter. I have made it optional (based on an env. var.) since if you already have application level flicker filtering (or a clever TV) then it will just add extra blur. Flicker filtering made an especially big difference to X11. -- Daniel Thompson <[email protected]>
SDL-1.2.8-flicker_filter.patch
(text/x-patch, 3.2 KB)
A 3 tap FIR vertical flicker filter.
Index: SDL-1.2.8/src/video/gc/SDL_gcvideo.c
===================================================================
--- SDL-1.2.8.orig/src/video/gc/SDL_gcvideo.c 2005-11-15 07:35:39.000000000 +0000
+++ SDL-1.2.8/src/video/gc/SDL_gcvideo.c 2005-11-16 19:42:12.000000000 +0000
@@ -70,6 +70,7 @@
/* etc. */
static void GC_InitRGB2YUVTables(void);
static void GC_UpdateRects(_THIS, int numrects, SDL_Rect * rects);
+static void GC_UpdateRectRGB16_ff(_THIS, SDL_Rect * rect, int pitch);
static void GC_UpdateRectRGB16(_THIS, SDL_Rect * rect, int pitch);
static void GC_UpdateRectRGB24(_THIS, SDL_Rect * rect, int pitch);
static void GC_UpdateRectRGB32(_THIS, SDL_Rect * rect, int pitch);
@@ -375,6 +376,7 @@
Uint32 Gmask;
Uint32 Bmask;
Uint32 *p, *q;
+ const char *flicker_filter;
GC_DPRINTF("Setting %dx%d %dbpp mode\n", width, height, bpp);
@@ -514,8 +516,14 @@
_this->hidden->UpdateRect = GC_UpdateRectRGB24;
break;
case 16:
- GC_DPRINTF("Using new fast 16bpp blitter\n");
- _this->hidden->UpdateRect = GC_UpdateRectRGB16;
+ flicker_filter = getenv("SDL_GC_FLICKER_FILTER");
+ if (flicker_filter) {
+ GC_DPRINTF("Using flicker filtered 16bpp blitter\n");
+ _this->hidden->UpdateRect = GC_UpdateRectRGB16_ff;
+ } else {
+ GC_DPRINTF("Using new fast 16bpp blitter\n");
+ _this->hidden->UpdateRect = GC_UpdateRectRGB16;
+ }
break;
default:
GC_DPRINTF("Using NO blitter\n");
@@ -667,6 +675,75 @@
| (((char)Cr) << 0);
}
+static inline Uint32 rgbrgb16_ff(Uint32 rgbrgb, Uint32 above, Uint32 below)
+{
+ const Uint32 R = 0xf800;
+ const Uint32 G = 0x07e0;
+ const Uint32 B = 0x001f;
+
+ const Uint32 _G_R_B = (G << 16) | R | B;
+ const Uint32 R_B_G_ = (R << 16) | (B << 16) | G;
+
+ Uint32 _g_r_b, r_b_g_;
+
+ _g_r_b = (rgbrgb & _G_R_B) << 1;
+ _g_r_b += (above & _G_R_B);
+ _g_r_b += (below & _G_R_B);
+ _g_r_b >>= 2;
+
+ r_b_g_ = (rgbrgb & R_B_G_) >> 1;
+ r_b_g_ += (above & R_B_G_) >> 2;
+ r_b_g_ += (below & R_B_G_) >> 2;
+
+ return (_g_r_b & _G_R_B) | (r_b_g_ & R_B_G_);
+}
+
+static void GC_UpdateRectRGB16_ff(_THIS, SDL_Rect * rect, int pitch)
+{
+ const Uint32 black = 0;
+
+ int width, height, left, line, i, mod, mod32, pitch32;
+ Uint8 *src, *dst;
+ Uint32 *src32, *dst32;
+ union {
+ Uint32 rgbrgb;
+ Uint16 rgb[2];
+ } pp;
+
+ /* XXX case width < 2 needs special treatment */
+
+ /* in pixel units */
+ left = rect->x & ~1; /* 2 pixel align */
+ width = (rect->w + 1) & ~1; /* 2 pixel align in excess */
+ line = rect->y;
+ height = rect->h;
+
+ /* in bytes, src and dest are 16bpp */
+ src = _this->hidden->buffer + (line * pitch) + left * 2;
+ dst = mapped_mem + mapped_offset + (line * pitch) + left * 2;
+ mod = pitch - width * 2;
+
+ src32 = (Uint32 *) src;
+ dst32 = (Uint32 *) dst;
+ pitch32 = pitch / 4;
+ mod32 = mod / 4;
+
+ while (height--) {
+ i = width / 2;
+
+ while (i--) {
+ pp.rgbrgb = rgbrgb16_ff(src32[0],
+ 0 >= line ? black : src32[-pitch32],
+ 479 <= line ? black : src32[pitch32]);
+ *dst32++ = rgbrgb16toyuy2(pp.rgb[0], pp.rgb[1]);
+ src32++;
+ }
+ dst32 += mod32;
+ src32 += mod32;
+ line++;
+ }
+}
+
static void GC_UpdateRectRGB16(_THIS, SDL_Rect * rect, int pitch)
{
int width, height, left, i, mod, mod32;