Implement support for setting texture scale mode.
authorSunny Sachanandani <sunnysachanandani@gmail.com>
Tue, 20 Jul 2010 11:43:13 +0530
changeset 4606 4e145485971b
parent 4605 0b3a509c53a0
child 4607 9e9ec5e3be95
Implement support for setting texture scale mode.
src/video/x11/SDL_x11render.c
src/video/x11/SDL_x11sym.h
--- a/src/video/x11/SDL_x11render.c	Mon Jul 19 21:02:49 2010 +0530
+++ b/src/video/x11/SDL_x11render.c	Tue Jul 20 11:43:13 2010 +0530
@@ -135,6 +135,7 @@
     Picture picture;
     XRenderPictFormat* picture_fmt;
     int blend_op;
+    const char* filter;
 #endif
     XImage *image;
 #ifndef NO_SHARED_MEMORY
@@ -376,7 +377,7 @@
                          window->w, window->h);
         /* Add some blending modes to the list of supported blending modes */
         renderer->info.blend_modes |=
-            (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK);
+            (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MASK | SDL_BLENDMODE_MOD);
         /* Create a clip mask that is used for rendering primitives. */
         data->stencil = XCreatePixmap(data->display, data->xwindow,
                                    window->w, window->h, 8);
@@ -924,24 +925,40 @@
 X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
 {
     X11_TextureData *data = (X11_TextureData *) texture->driverdata;
+    X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
     switch (texture->blendMode) {
     case SDL_BLENDMODE_NONE:
 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
-        data->blend_op = PictOpSrc;
-        return 0;
+        if (renderdata->use_xrender) {
+            data->blend_op = PictOpSrc;
+            return 0;
+        }
+    case SDL_BLENDMODE_MOD:
+        if (renderdata->use_xrender) {
+            data->blend_op = PictOpSrc;
+            return 0;
+        }
+    case SDL_BLENDMODE_MASK:
     case SDL_BLENDMODE_BLEND:
-        data->blend_op = PictOpOver;
+        if (renderdata->use_xrender) {
+            data->blend_op = PictOpOver;
+            return 0;
+        }
+    case SDL_BLENDMODE_ADD:
+        if (renderdata->use_xrender) {
+            data->blend_op = PictOpAdd;
+            return 0;
+        }
+#endif
         return 0;
-    case SDL_BLENDMODE_ADD:
-        data->blend_op = PictOpAdd;
-        return 0;
-#endif
     default:
         SDL_Unsupported();
         texture->blendMode = SDL_BLENDMODE_NONE;
 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
-        texture->blendMode = SDL_BLENDMODE_BLEND;
-        data->blend_op = PictOpOver;
+        if (renderdata->use_xrender) {
+            texture->blendMode = SDL_BLENDMODE_BLEND;
+            data->blend_op = PictOpOver;
+        }
 #endif
         return -1;
     }
@@ -951,6 +968,7 @@
 X11_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
 {
     X11_TextureData *data = (X11_TextureData *) texture->driverdata;
+    X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
 
     switch (texture->scaleMode) {
     case SDL_TEXTURESCALEMODE_NONE:
@@ -960,10 +978,33 @@
         if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) {
             return 0;
         }
-        /* Fall through to unsupported case */
+#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
+        if (renderdata->use_xrender) {
+            data->filter = FilterFast;
+            return 0;
+        }
+    case SDL_TEXTURESCALEMODE_SLOW:
+        if (renderdata->use_xrender) {
+            data->filter = FilterGood;
+            return 0;
+        }
+    case SDL_TEXTURESCALEMODE_BEST:
+        if (renderdata->use_xrender) {
+            data->filter = FilterBest;
+            return 0;
+        }
+#endif
+    /* Fall through to unsupported case */
     default:
         SDL_Unsupported();
-        texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
+#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
+        if (renderdata->use_xrender) {
+            texture->scaleMode = SDL_TEXTURESCALEMODE_FAST;
+            data->filter = FilterFast;
+        }
+        else
+#endif
+            texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
         return -1;
     }
     return 0;
@@ -1054,6 +1095,8 @@
         //PictOpSrc
         data->blend_op = PictOpSrc;
         return 0;
+    case SDL_BLENDMODE_MOD:
+    case SDL_BLENDMODE_MASK:
     case SDL_BLENDMODE_BLEND: // PictOpOver
         data->blend_op = PictOpOver;
         return 0;
@@ -1114,6 +1157,7 @@
         (unsigned short) ((renderer->g / 255.0) * alphad * 0xFFFF);
     xrender_color.blue =
         (unsigned short) ((renderer->b / 255.0) * alphad * 0xFFFF);
+
     return xrender_color;
 }
 
@@ -1167,7 +1211,7 @@
               renderer->blendMode != SDL_BLENDMODE_ADD &&
               renderer->blendMode != SDL_BLENDMODE_MOD))
         {
-            XSetForeground(data->display, data->stencil_gc, 0x00);
+            XSetForeground(data->display, data->stencil_gc, 0x00000000);
 #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
             if (data->use_xdamage)
             {
@@ -1279,7 +1323,7 @@
             drawable = data->stencil;
             gc = data->stencil_gc;
 
-            XSetForeground(data->display, data->stencil_gc, 0x00);
+            XSetForeground(data->display, data->stencil_gc, 0x00000000);
 #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
             if (data->use_xdamage)
                 XFixesSetGCClipRegion(data->display, data->stencil_gc,
@@ -1492,7 +1536,7 @@
               renderer->blendMode != SDL_BLENDMODE_ADD &&
               renderer->blendMode != SDL_BLENDMODE_MOD))
         {
-            XSetForeground(data->display, data->stencil_gc, 0x00);
+            XSetForeground(data->display, data->stencil_gc, 0x00000000);
 #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE
             if (data->use_xdamage)
                 XFixesSetGCClipRegion(data->display, data->stencil_gc,
@@ -1651,16 +1695,35 @@
                           dstrect->y, srcrect->w, srcrect->h);
             }
         }
-        Picture pict;
-        if(texture->blendMode == SDL_BLENDMODE_NONE)
-            pict = None;
-        else
-            pict = texturedata->picture;
+        Picture src, mask, dst;
+        XRenderPictureAttributes attr;
+        if(texture->blendMode == SDL_BLENDMODE_NONE) {
+            src = texturedata->picture;
+            mask = None;
+            dst = data->drawable_pict;
+        }
+        /*else if (texture->blendMode == SDL_BLENDMODE_MOD) {
+            src = data->drawable_pict;
+            mask = texturedata->picture;
+            dst = data->drawable_pict;
+            attr.alpha_map = mask;
+        }*/
+        else {
+            src = texturedata->picture;
+            mask = texturedata->picture;
+            dst = data->drawable_pict;
+        }
         if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
-            XRenderComposite(data->display, texturedata->blend_op, texturedata->picture,
-                         pict, data->drawable_pict, srcrect->x, srcrect->y,
-                         srcrect->x, srcrect->y, dstrect->x, dstrect->y,
-                         srcrect->w, srcrect->h);
+            /*if (texture->blendMode == SDL_BLENDMODE_MOD) {
+                attr.component_alpha = True;
+                XRenderChangePicture(data->display, texturedata->picture,
+                                     CPComponentAlpha, &attr);
+                XRenderChangePicture(data->display, src, CPAlphaMap, &attr);
+            }*/
+            XRenderComposite(data->display, texturedata->blend_op, src,
+                            mask, dst, srcrect->x, srcrect->y,
+                            srcrect->x, srcrect->y, dstrect->x, dstrect->y,
+                            srcrect->w, srcrect->h);
         } else {
             double xscale = ((double) dstrect->w) / srcrect->w;
             double yscale = ((double) dstrect->h) / srcrect->h;
@@ -1669,11 +1732,21 @@
                     {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)},
                     {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}};
             XRenderSetPictureTransform(data->display, texturedata->picture, &xform);
+            
+            /*if (texture->blendMode == SDL_BLENDMODE_MOD) {
+                attr.component_alpha = True;
+                XRenderChangePicture(data->display, texturedata->picture,
+                                     CPComponentAlpha, &attr);
+                XRenderChangePicture(data->display, src, CPAlphaMap, &attr);
+            }*/
+
+            XRenderSetPictureFilter(data->display, texturedata->picture,
+                                    texturedata->filter, 0, 0);
 
             XRenderComposite(data->display, texturedata->blend_op,
-                             texturedata->picture, pict, data->drawable_pict,
-                             0, 0, 0, 0, dstrect->x, dstrect->y,
-                             dstrect->w, dstrect->h);
+                             src, mask, dst,
+                             srcrect->x, srcrect->y, srcrect->x, srcrect->y,
+                             dstrect->x, dstrect->y, dstrect->w, dstrect->h);
             
             XTransform identity = {{
                     {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)},
@@ -1681,6 +1754,14 @@
                     {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}};
             XRenderSetPictureTransform(data->display, texturedata->picture, &identity);
         }
+        /*if (renderer->blendMode == SDL_BLENDMODE_MOD) {
+            attr.component_alpha = False;
+            XRenderChangePicture(data->display, texturedata->picture,
+                                 CPComponentAlpha, &attr);
+            attr.alpha_map = None;
+            XRenderChangePicture(data->display, data->drawable_pict,
+                                 CPAlphaMap, &attr);
+        }*/
     }
     else
 #endif
--- a/src/video/x11/SDL_x11sym.h	Mon Jul 19 21:02:49 2010 +0530
+++ b/src/video/x11/SDL_x11sym.h	Tue Jul 20 11:43:13 2010 +0530
@@ -154,6 +154,7 @@
 SDL_X11_SYM(int,XFillRectangle,(Display *dpy,Drawable d,GC gc,int x,int y,unsigned int width,unsigned int height),(dpy,d,gc,x,y,width,height),return)
 SDL_X11_SYM(int,XSetBackground,(Display *dpy,GC gc,unsigned long background),(dpy,gc,background),return)
 SDL_X11_SYM(Status,XInitImage,(XImage *image),(image),return)
+SDL_X11_SYM(int,XSetClipMask,(Display *dpy,GC gc,Pixmap pixmap),(dpy,gc,pixmap),return)
 
 #if NeedWidePrototypes
 SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
@@ -252,6 +253,7 @@
 SDL_X11_SYM(void,XRenderSetPictureTransform,(Display *dpy,Picture picture,XTransform *transform),(dpy,picture,transform),return)
 SDL_X11_SYM(void,XRenderFillRectangle,(Display *dpy,int op,Picture dst,_Xconst XRenderColor *color,int x,int y,unsigned int width,unsigned int height),(dpy,op,dst,color,x,y,width,height),return)
 SDL_X11_SYM(void,XRenderFillRectangles,(Display *dpy,int op,Picture dst,_Xconst XRenderColor *color,_Xconst XRectangle *rectangles,int n_rects),(dpy,op,dst,color,rectangles,n_rects),return)
+SDL_X11_SYM(void,XRenderSetPictureFilter,(Display *dpy,Picture picture,const char *filter,XFixed *params,int nparams),(dpy,picture,filter,params,nparams),return)
 #endif
 
 #ifdef SDL_VIDEO_DRIVER_X11_XDAMAGE