test/automated/render/render.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 16 Jan 2011 17:48:04 -0800
changeset 5008 35afe807b51c
parent 3685 64ce267332c6
child 5140 e743b9c3f6d6
permissions -rw-r--r--
Fixed compiler warning
     1 /**
     2  * Automated SDL_Surface test.
     3  *
     4  * Written by Edgar Simo "bobbens"
     5  *
     6  * Released under Public Domain.
     7  */
     8 
     9 
    10 #include "SDL.h"
    11 #include "../SDL_at.h"
    12 
    13 #include "../common/common.h"
    14 
    15 
    16 /*
    17  * Pull in images for testcases.
    18  */
    19 #include "../common/images.h"
    20 
    21 
    22 #define SCREEN_W     80
    23 #define SCREEN_H     60
    24 
    25 #define FACE_W       img_face.width
    26 #define FACE_H       img_face.height
    27 
    28 
    29 /*
    30  * Prototypes.
    31  */
    32 static int render_compare( const char *msg, const SurfaceImage_t *s, int allowable_error );
    33 static int render_isSupported( int code );
    34 static int render_hasDrawColor (void);
    35 static int render_hasBlendModes (void);
    36 static int render_hasTexColor (void);
    37 static int render_hasTexAlpha (void);
    38 static int render_clearScreen (void);
    39 /* Testcases. */
    40 static int render_testReadWrite (void);
    41 static int render_testPrimitives (void);
    42 static int render_testPrimitivesBlend (void);
    43 static int render_testBlit (void);
    44 static int render_testBlitColour (void);
    45 static int render_testBlitAlpha (void);
    46 static int render_testBlitBlendMode( SDL_Texture * tface, int mode );
    47 static int render_testBlitBlend (void);
    48 
    49 
    50 /**
    51  * @brief Compares screen pixels with image pixels.
    52  *
    53  *    @param msg Message on failure.
    54  *    @param s Image to compare against.
    55  *    @return 0 on success.
    56  */
    57 static int render_compare( const char *msg, const SurfaceImage_t *s, int allowable_error )
    58 {
    59    int ret;
    60    SDL_Rect rect;
    61    Uint8 pix[4*80*60];
    62    SDL_Surface *testsur;
    63 
    64    /* Read pixels. */
    65    /* Explicitly specify the rect in case the window isn't expected size... */
    66    rect.x = 0;
    67    rect.y = 0;
    68    rect.w = 80;
    69    rect.h = 60;
    70    ret = SDL_RenderReadPixels( &rect, FORMAT, pix, 80*4 );
    71    if (SDL_ATassert( "SDL_RenderReadPixels", ret==0) )
    72       return 1;
    73 
    74    /* Create surface. */
    75    testsur = SDL_CreateRGBSurfaceFrom( pix, 80, 60, 32, 80*4,
    76                                        RMASK, GMASK, BMASK, AMASK);
    77    if (SDL_ATassert( "SDL_CreateRGBSurfaceFrom", testsur!=NULL ))
    78       return 1;
    79 
    80    /* Compare surface. */
    81    ret = surface_compare( testsur, s, allowable_error );
    82    if (SDL_ATassert( msg, ret==0 ))
    83       return 1;
    84 
    85    /* Clean up. */
    86    SDL_FreeSurface( testsur );
    87 
    88    return 0;
    89 }
    90 
    91 #if 0
    92 static int dump_screen( int index )
    93 {
    94    int ret;
    95    char name[1024];
    96    Uint8 pix[4*80*60];
    97    SDL_Surface *testsur;
    98    SDL_RendererInfo info;
    99 
   100    /* Read pixels. */
   101    ret = SDL_RenderReadPixels( NULL, FORMAT, pix, 80*4 );
   102    if (SDL_ATassert( "SDL_RenderReadPixels", ret==0) )
   103       return 1;
   104 
   105    /* Create surface. */
   106    testsur = SDL_CreateRGBSurfaceFrom( pix, 80, 60, 32, 80*4,
   107                                        RMASK, GMASK, BMASK, AMASK);
   108    if (SDL_ATassert( "SDL_CreateRGBSurfaceFrom", testsur!=NULL ))
   109       return 1;
   110 
   111    /* Dump surface. */
   112    SDL_GetRendererInfo(&info);
   113    sprintf(name, "%s-%s-%d.bmp", SDL_GetCurrentVideoDriver(), info.name, index);
   114    SDL_SaveBMP(testsur, name);
   115 
   116    /* Clean up. */
   117    SDL_FreeSurface( testsur );
   118 
   119    return 0;
   120 }
   121 #endif
   122 
   123 /**
   124  * @brief Checks to see if functionality is supported.
   125  */
   126 static int render_isSupported( int code )
   127 {
   128    return (code == 0);
   129 }
   130 
   131 
   132 /**
   133  * @brief Test to see if we can vary the draw colour.
   134  */
   135 static int render_hasDrawColor (void)
   136 {
   137    int ret, fail;
   138    Uint8 r, g, b, a;
   139 
   140    fail = 0;
   141 
   142    /* Set colour. */
   143    ret = SDL_SetRenderDrawColor( 100, 100, 100, 100 );
   144    if (!render_isSupported(ret))
   145       fail = 1;
   146    ret = SDL_GetRenderDrawColor( &r, &g, &b, &a );
   147    if (!render_isSupported(ret))
   148       fail = 1;
   149    /* Restore natural. */
   150    ret = SDL_SetRenderDrawColor( 0, 0, 0, SDL_ALPHA_OPAQUE );
   151    if (!render_isSupported(ret))
   152       fail = 1;
   153 
   154    /* Something failed, consider not available. */
   155    if (fail)
   156       return 0;
   157    /* Not set properly, consider failed. */
   158    else if ((r != 100) || (g != 100) || (b != 100) || (a != 100))
   159       return 0;
   160    return 1;
   161 }
   162 
   163 
   164 /**
   165  * @brief Test to see if we can vary the blend mode.
   166  */
   167 static int render_hasBlendModes (void)
   168 {
   169    int fail;
   170    int ret;
   171    SDL_BlendMode mode;
   172 
   173    fail = 0;
   174 
   175    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_BLEND );
   176    if (!render_isSupported(ret))
   177       fail = 1;
   178    ret = SDL_GetRenderDrawBlendMode( &mode );
   179    if (!render_isSupported(ret))
   180       fail = 1;
   181    ret = (mode != SDL_BLENDMODE_BLEND);
   182    if (!render_isSupported(ret))
   183       fail = 1;
   184    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_ADD );
   185    if (!render_isSupported(ret))
   186       fail = 1;
   187    ret = SDL_GetRenderDrawBlendMode( &mode );
   188    if (!render_isSupported(ret))
   189       fail = 1;
   190    ret = (mode != SDL_BLENDMODE_ADD);
   191    if (!render_isSupported(ret))
   192       fail = 1;
   193    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_MOD );
   194    if (!render_isSupported(ret))
   195       fail = 1;
   196    ret = SDL_GetRenderDrawBlendMode( &mode );
   197    if (!render_isSupported(ret))
   198       fail = 1;
   199    ret = (mode != SDL_BLENDMODE_MOD);
   200    if (!render_isSupported(ret))
   201       fail = 1;
   202    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_MASK );
   203    if (!render_isSupported(ret))
   204       fail = 1;
   205    ret = SDL_GetRenderDrawBlendMode( &mode );
   206    if (!render_isSupported(ret))
   207       fail = 1;
   208    ret = (mode != SDL_BLENDMODE_MASK);
   209    if (!render_isSupported(ret))
   210       fail = 1;
   211    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_NONE );
   212    if (!render_isSupported(ret))
   213       fail = 1;
   214    ret = SDL_GetRenderDrawBlendMode( &mode );
   215    if (!render_isSupported(ret))
   216       fail = 1;
   217    ret = (mode != SDL_BLENDMODE_NONE);
   218    if (!render_isSupported(ret))
   219       fail = 1;
   220 
   221    return !fail;
   222 }
   223 
   224 
   225 /**
   226  * @brief Loads the test face.
   227  */
   228 static SDL_Texture * render_loadTestFace (void)
   229 {
   230    SDL_Surface *face;
   231    SDL_Texture *tface;
   232 
   233    /* Create face surface. */
   234    face = SDL_CreateRGBSurfaceFrom( (void*)img_face.pixel_data,
   235          img_face.width, img_face.height, 32, img_face.width*4,
   236 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
   237          0xff000000, /* Red bit mask. */
   238          0x00ff0000, /* Green bit mask. */
   239          0x0000ff00, /* Blue bit mask. */
   240          0x000000ff /* Alpha bit mask. */
   241 #else
   242          0x000000ff, /* Red bit mask. */
   243          0x0000ff00, /* Green bit mask. */
   244          0x00ff0000, /* Blue bit mask. */
   245          0xff000000 /* Alpha bit mask. */
   246 #endif
   247          );
   248    if (face == NULL)
   249       return 0;
   250    tface = SDL_CreateTextureFromSurface( 0, face );
   251    SDL_FreeSurface(face);
   252 
   253    return tface;
   254 }
   255 
   256 
   257 /**
   258  * @brief Test to see if can set texture colour mode.
   259  */
   260 static int render_hasTexColor (void)
   261 {
   262    int fail;
   263    int ret;
   264    SDL_Texture *tface;
   265    Uint8 r, g, b;
   266 
   267    /* Get test face. */
   268    tface = render_loadTestFace();
   269    if (tface == 0)
   270       return 0;
   271 
   272    /* See if supported. */
   273    fail = 0;
   274    ret = SDL_SetTextureColorMod( tface, 100, 100, 100 );
   275    if (!render_isSupported(ret))
   276       fail = 1;
   277    ret = SDL_GetTextureColorMod( tface, &r, &g, &b );
   278    if (!render_isSupported(ret))
   279       fail = 1;
   280 
   281    /* Clean up. */
   282    SDL_DestroyTexture( tface );
   283 
   284    if (fail)
   285       return 0;
   286    else if ((r != 100) || (g != 100) || (b != 100))
   287       return 0;
   288    return 1;
   289 }
   290 
   291 
   292 /**
   293  * @brief Test to see if we can vary the alpha of the texture.
   294  */
   295 static int render_hasTexAlpha (void)
   296 {
   297    int fail;
   298    int ret;
   299    SDL_Texture *tface;
   300    Uint8 a;
   301 
   302    /* Get test face. */
   303    tface = render_loadTestFace();
   304    if (tface == 0)
   305       return 0;
   306 
   307    /* See if supported. */
   308    fail = 0;
   309    ret = SDL_SetTextureAlphaMod( tface, 100 );
   310    if (!render_isSupported(ret))
   311       fail = 1;
   312    ret = SDL_GetTextureAlphaMod( tface, &a );
   313    if (!render_isSupported(ret))
   314       fail = 1;
   315 
   316    /* Clean up. */
   317    SDL_DestroyTexture( tface );
   318 
   319    if (fail)
   320       return 0;
   321    else if (a != 100)
   322       return 0;
   323    return 1;
   324 }
   325 
   326 
   327 /**
   328  * @brief Clears the screen.
   329  *
   330  * @note We don't test for errors, but they shouldn't happen.
   331  */
   332 static int render_clearScreen (void)
   333 {
   334    int ret;
   335 
   336    /* Set colour. */
   337    ret = SDL_SetRenderDrawColor( 0, 0, 0, SDL_ALPHA_OPAQUE );
   338    /*
   339    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   340       return -1;
   341    */
   342 
   343    /* Clear screen. */
   344    ret = SDL_RenderFillRect( NULL );
   345    /*
   346    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   347       return -1;
   348    */
   349 
   350    /* Set defaults. */
   351    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_NONE );
   352    /*
   353    if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   354       return -1;
   355    */
   356    ret = SDL_SetRenderDrawColor( 255, 255, 255, SDL_ALPHA_OPAQUE );
   357    /*
   358    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   359       return -1;
   360    */
   361 
   362    return 0;
   363 }
   364 
   365 
   366 /**
   367  * @brief Test reading and writing framebuffer
   368  */
   369 static int render_testReadWrite (void)
   370 {
   371    int ret;
   372    SDL_Rect rect;
   373 
   374    /* Write pixels. */
   375    rect.x = 0;
   376    rect.y = 0;
   377    rect.w = 80;
   378    rect.h = 60;
   379    ret = SDL_RenderWritePixels( &rect, SDL_PIXELFORMAT_RGB24, img_primitives.pixel_data, img_primitives.width*img_primitives.bytes_per_pixel );
   380    if (SDL_ATassert( "SDL_RenderWritePixels", ret==0) )
   381       return 1;
   382 
   383    /* See if it's the same. */
   384    if (render_compare( "Read/write output not the same.", &img_primitives, ALLOWABLE_ERROR_OPAQUE ))
   385       return -1;
   386 
   387    return 0;
   388 }
   389 
   390 
   391 /**
   392  * @brief Tests the SDL primitives for rendering.
   393  */
   394 static int render_testPrimitives (void)
   395 {
   396    int ret;
   397    int x, y;
   398    SDL_Rect rect;
   399 
   400    /* Clear surface. */
   401    if (render_clearScreen())
   402       return -1;
   403 
   404    /* Need drawcolour or just skip test. */
   405    if (!render_hasDrawColor())
   406       return 0;
   407 
   408    /* Draw a rectangle. */
   409    rect.x = 40;
   410    rect.y = 0;
   411    rect.w = 40;
   412    rect.h = 80;
   413    ret = SDL_SetRenderDrawColor( 13, 73, 200, SDL_ALPHA_OPAQUE );
   414    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   415       return -1;
   416    ret = SDL_RenderFillRect( &rect );
   417    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   418       return -1;
   419 
   420    /* Draw a rectangle. */
   421    rect.x = 10;
   422    rect.y = 10;
   423    rect.w = 60;
   424    rect.h = 40;
   425    ret = SDL_SetRenderDrawColor( 200, 0, 100, SDL_ALPHA_OPAQUE );
   426    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   427       return -1;
   428    ret = SDL_RenderFillRect( &rect );
   429    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   430       return -1;
   431 
   432    /* Draw some points like so:
   433     * X.X.X.X..
   434     * .X.X.X.X.
   435     * X.X.X.X.. */
   436    for (y=0; y<3; y++) {
   437       x = y % 2;
   438       for (; x<80; x+=2) {
   439          ret = SDL_SetRenderDrawColor( x*y, x*y/2, x*y/3, SDL_ALPHA_OPAQUE );
   440          if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   441             return -1;
   442          ret = SDL_RenderDrawPoint( x, y );
   443          if (SDL_ATassert( "SDL_RenderDrawPoint", ret == 0))
   444             return -1;
   445       }
   446    }
   447 
   448    /* Draw some lines. */
   449    ret = SDL_SetRenderDrawColor( 0, 255, 0, SDL_ALPHA_OPAQUE );
   450    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   451       return -1;
   452    ret = SDL_RenderDrawLine( 0, 30, 80, 30 );
   453    if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   454       return -1;
   455    ret = SDL_SetRenderDrawColor( 55, 55, 5, SDL_ALPHA_OPAQUE );
   456    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   457       return -1;
   458    ret = SDL_RenderDrawLine( 40, 30, 40, 60 );
   459    if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   460       return -1;
   461    ret = SDL_SetRenderDrawColor( 5, 105, 105, SDL_ALPHA_OPAQUE );
   462    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   463       return -1;
   464    ret = SDL_RenderDrawLine( 0, 0, 29, 29 );
   465    if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   466       return -1;
   467    ret = SDL_RenderDrawLine( 29, 30, 0, 59 );
   468    if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   469       return -1;
   470    ret = SDL_RenderDrawLine( 79, 0, 50, 29 );
   471    if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   472       return -1;
   473    ret = SDL_RenderDrawLine( 79, 59, 50, 30 );
   474    if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   475       return -1;
   476 
   477    /* See if it's the same. */
   478    if (render_compare( "Primitives output not the same.", &img_primitives, ALLOWABLE_ERROR_OPAQUE ))
   479       return -1;
   480 
   481    return 0;
   482 }
   483 
   484 
   485 /**
   486  * @brief Tests the SDL primitives with alpha for rendering.
   487  */
   488 static int render_testPrimitivesBlend (void)
   489 {
   490    int ret;
   491    int i, j;
   492    SDL_Rect rect;
   493 
   494    /* Clear surface. */
   495    if (render_clearScreen())
   496       return -1;
   497 
   498    /* Need drawcolour and blendmode or just skip test. */
   499    if (!render_hasDrawColor() || !render_hasBlendModes())
   500       return 0;
   501 
   502    /* Create some rectangles for each blend mode. */
   503    ret = SDL_SetRenderDrawColor( 255, 255, 255, 0 );
   504    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   505       return -1;
   506    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_NONE );
   507    if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   508       return -1;
   509    ret = SDL_RenderFillRect( NULL );
   510    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   511       return -1;
   512    rect.x = 10;
   513    rect.y = 25;
   514    rect.w = 40;
   515    rect.h = 25;
   516    ret = SDL_SetRenderDrawColor( 240, 10, 10, 75 );
   517    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   518       return -1;
   519    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_ADD );
   520    if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   521       return -1;
   522    ret = SDL_RenderFillRect( &rect );
   523    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   524       return -1;
   525    rect.x = 30;
   526    rect.y = 40;
   527    rect.w = 45;
   528    rect.h = 15;
   529    ret = SDL_SetRenderDrawColor( 10, 240, 10, 100 );
   530    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   531       return -1;
   532    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_BLEND );
   533    if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   534       return -1;
   535    ret = SDL_RenderFillRect( &rect );
   536    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   537       return -1;
   538    rect.x = 25;
   539    rect.y = 25;
   540    rect.w = 25;
   541    rect.h = 25;
   542    ret = SDL_SetRenderDrawColor( 10, 10, 240, 125 );
   543    if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   544       return -1;
   545    ret = SDL_SetRenderDrawBlendMode( SDL_BLENDMODE_MOD );
   546    if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   547       return -1;
   548    ret = SDL_RenderFillRect( &rect );
   549    if (SDL_ATassert( "SDL_RenderFillRect", ret == 0))
   550       return -1;
   551 
   552    /* Draw blended lines, lines for everyone. */
   553    for (i=0; i<SCREEN_W; i+=2)  {
   554       ret = SDL_SetRenderDrawColor( 60+2*i, 240-2*i, 50, 3*i );
   555       if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   556          return -1;
   557       ret = SDL_SetRenderDrawBlendMode((((i/2)%3)==0) ? SDL_BLENDMODE_BLEND :
   558             (((i/2)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD );
   559       if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   560          return -1;
   561       ret = SDL_RenderDrawLine( 0, 0, i, 59 );
   562       if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   563          return -1;
   564    }
   565    for (i=0; i<SCREEN_H; i+=2)  {
   566       ret = SDL_SetRenderDrawColor( 60+2*i, 240-2*i, 50, 3*i );
   567       if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   568          return -1;
   569       ret = SDL_SetRenderDrawBlendMode((((i/2)%3)==0) ? SDL_BLENDMODE_BLEND :
   570             (((i/2)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD );
   571       if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   572          return -1;
   573       ret = SDL_RenderDrawLine( 0, 0, 79, i );
   574       if (SDL_ATassert( "SDL_RenderDrawLine", ret == 0))
   575          return -1;
   576    }
   577 
   578    /* Draw points. */
   579    for (j=0; j<SCREEN_H; j+=3) {
   580       for (i=0; i<SCREEN_W; i+=3) {
   581          ret = SDL_SetRenderDrawColor( j*4, i*3, j*4, i*3 );
   582          if (SDL_ATassert( "SDL_SetRenderDrawColor", ret == 0))
   583             return -1;
   584          ret = SDL_SetRenderDrawBlendMode( ((((i+j)/3)%3)==0) ? SDL_BLENDMODE_BLEND :
   585                ((((i+j)/3)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD );
   586          if (SDL_ATassert( "SDL_SetRenderDrawBlendMode", ret == 0))
   587             return -1;
   588          ret = SDL_RenderDrawPoint( i, j );
   589          if (SDL_ATassert( "SDL_RenderDrawPoint", ret == 0))
   590             return -1;
   591       }
   592    }
   593 
   594    /* See if it's the same. */
   595    if (render_compare( "Blended primitives output not the same.", &img_blend, ALLOWABLE_ERROR_BLENDED ))
   596       return -1;
   597 
   598    return 0;
   599 }
   600 
   601 
   602 /**
   603  * @brief Tests some blitting routines.
   604  */
   605 static int render_testBlit (void)
   606 {
   607    int ret;
   608    SDL_Rect rect;
   609    SDL_Texture *tface;
   610    int i, j, ni, nj;
   611 
   612    /* Clear surface. */
   613    if (render_clearScreen())
   614       return -1;
   615 
   616    /* Need drawcolour or just skip test. */
   617    if (!render_hasDrawColor())
   618       return 0;
   619 
   620    /* Create face surface. */
   621    tface = render_loadTestFace();
   622    if (SDL_ATassert( "render_loadTestFace()", tface != 0))
   623       return -1;
   624 
   625    /* Constant values. */
   626    rect.w = img_face.width;
   627    rect.h = img_face.height;
   628    ni     = SCREEN_W - img_face.width;
   629    nj     = SCREEN_H - img_face.height;
   630 
   631    /* Loop blit. */
   632    for (j=0; j <= nj; j+=4) {
   633       for (i=0; i <= ni; i+=4) {
   634          /* Blitting. */
   635          rect.x = i;
   636          rect.y = j;
   637          ret = SDL_RenderCopy( tface, NULL, &rect );
   638          if (SDL_ATassert( "SDL_RenderCopy", ret == 0))
   639             return -1;
   640       }
   641    }
   642 
   643    /* Clean up. */
   644    SDL_DestroyTexture( tface );
   645 
   646    /* See if it's the same. */
   647    if (render_compare( "Blit output not the same.", &img_blit, ALLOWABLE_ERROR_OPAQUE ))
   648       return -1;
   649 
   650    return 0;
   651 }
   652 
   653 
   654 /**
   655  * @brief Blits doing colour tests.
   656  */
   657 static int render_testBlitColour (void)
   658 {
   659    int ret;
   660    SDL_Rect rect;
   661    SDL_Texture *tface;
   662    int i, j, ni, nj;
   663 
   664    /* Clear surface. */
   665    if (render_clearScreen())
   666       return -1;
   667 
   668    /* Need drawcolour or just skip test. */
   669    if (!render_hasTexColor())
   670       return 0;
   671 
   672    /* Create face surface. */
   673    tface = render_loadTestFace();
   674    if (SDL_ATassert( "render_loadTestFace()", tface != 0))
   675       return -1;
   676 
   677    /* Constant values. */
   678    rect.w = img_face.width;
   679    rect.h = img_face.height;
   680    ni     = SCREEN_W - img_face.width;
   681    nj     = SCREEN_H - img_face.height;
   682 
   683    /* Test blitting with colour mod. */
   684    for (j=0; j <= nj; j+=4) {
   685       for (i=0; i <= ni; i+=4) {
   686          /* Set colour mod. */
   687          ret = SDL_SetTextureColorMod( tface, (255/nj)*j, (255/ni)*i, (255/nj)*j );
   688          if (SDL_ATassert( "SDL_SetTextureColorMod", ret == 0))
   689             return -1;
   690 
   691          /* Blitting. */
   692          rect.x = i;
   693          rect.y = j;
   694          ret = SDL_RenderCopy( tface, NULL, &rect );
   695          if (SDL_ATassert( "SDL_RenderCopy", ret == 0))
   696             return -1;
   697       }
   698    }
   699 
   700    /* Clean up. */
   701    SDL_DestroyTexture( tface );
   702 
   703    /* See if it's the same. */
   704    if (render_compare( "Blit output not the same (using SDL_SetTextureColorMod).",
   705             &img_blitColour, ALLOWABLE_ERROR_OPAQUE ))
   706       return -1;
   707 
   708    return 0;
   709 }
   710 
   711 
   712 /**
   713  * @brief Tests blitting with alpha.
   714  */
   715 static int render_testBlitAlpha (void)
   716 {
   717    int ret;
   718    SDL_Rect rect;
   719    SDL_Texture *tface;
   720    int i, j, ni, nj;
   721 
   722    /* Clear surface. */
   723    if (render_clearScreen())
   724       return -1;
   725 
   726    /* Need alpha or just skip test. */
   727    if (!render_hasTexAlpha())
   728       return 0;
   729 
   730    /* Create face surface. */
   731    tface = render_loadTestFace();
   732    if (SDL_ATassert( "render_loadTestFace()", tface != 0))
   733       return -1;
   734 
   735    /* Constant values. */
   736    rect.w = img_face.width;
   737    rect.h = img_face.height;
   738    ni     = SCREEN_W - img_face.width;
   739    nj     = SCREEN_H - img_face.height;
   740 
   741    /* Clear surface. */
   742    if (render_clearScreen())
   743       return -1;
   744 
   745    /* Test blitting with alpha mod. */
   746    for (j=0; j <= nj; j+=4) {
   747       for (i=0; i <= ni; i+=4) {
   748          /* Set alpha mod. */
   749          ret = SDL_SetTextureAlphaMod( tface, (255/ni)*i );
   750          if (SDL_ATassert( "SDL_SetTextureAlphaMod", ret == 0))
   751             return -1;
   752 
   753          /* Blitting. */
   754          rect.x = i;
   755          rect.y = j;
   756          ret = SDL_RenderCopy( tface, NULL, &rect );
   757          if (SDL_ATassert( "SDL_RenderCopy", ret == 0))
   758             return -1;
   759       }
   760    }
   761 
   762    /* Clean up. */
   763    SDL_DestroyTexture( tface );
   764 
   765    /* See if it's the same. */
   766    if (render_compare( "Blit output not the same (using SDL_SetSurfaceAlphaMod).",
   767             &img_blitAlpha, ALLOWABLE_ERROR_BLENDED ))
   768       return -1;
   769 
   770    return 0;
   771 }
   772 
   773 
   774 /**
   775  * @brief Tests a blend mode.
   776  */
   777 static int render_testBlitBlendMode( SDL_Texture * tface, int mode )
   778 {
   779    int ret;
   780    int i, j, ni, nj;
   781    SDL_Rect rect;
   782 
   783    /* Clear surface. */
   784    if (render_clearScreen())
   785       return -1;
   786 
   787    /* Steps to take. */
   788    ni     = SCREEN_W - FACE_W;
   789    nj     = SCREEN_H - FACE_H;
   790 
   791    /* Constant values. */
   792    rect.w = FACE_W;
   793    rect.h = FACE_H;
   794 
   795    /* Test blend mode. */
   796    for (j=0; j <= nj; j+=4) {
   797       for (i=0; i <= ni; i+=4) {
   798          /* Set blend mode. */
   799          ret = SDL_SetTextureBlendMode( tface, mode );
   800          if (SDL_ATassert( "SDL_SetTextureBlendMode", ret == 0))
   801             return -1;
   802 
   803          /* Blitting. */
   804          rect.x = i;
   805          rect.y = j;
   806          ret = SDL_RenderCopy( tface, NULL, &rect );
   807          if (SDL_ATassert( "SDL_RenderCopy", ret == 0))
   808             return -1;
   809       }
   810    }
   811 
   812    return 0;
   813 }
   814 
   815 
   816 /**
   817  * @brief Tests some more blitting routines.
   818  */
   819 static int render_testBlitBlend (void)
   820 {
   821    int ret;
   822    SDL_Rect rect;
   823    SDL_Texture *tface;
   824    int i, j, ni, nj;
   825    int mode;
   826 
   827    /* Clear surface. */
   828    if (render_clearScreen())
   829       return -1;
   830 
   831    /* Need drawcolour and blendmode or just skip test. */
   832    if (!render_hasBlendModes() || !render_hasTexColor() || !render_hasTexAlpha())
   833       return 0;
   834 
   835    /* Create face surface. */
   836    tface = render_loadTestFace();
   837    if (SDL_ATassert( "render_loadTestFace()", tface != 0))
   838       return -1;
   839 
   840    /* Steps to take. */
   841    ni     = SCREEN_W - FACE_W;
   842    nj     = SCREEN_H - FACE_H;
   843 
   844    /* Constant values. */
   845    rect.w = img_face.width;
   846    rect.h = img_face.height;
   847 
   848    /* Set alpha mod. */
   849    ret = SDL_SetTextureAlphaMod( tface, 100 );
   850    if (SDL_ATassert( "SDL_SetTextureAlphaMod", ret == 0))
   851       return -1;
   852 
   853    /* Test None. */
   854    if (render_testBlitBlendMode( tface, SDL_BLENDMODE_NONE ))
   855       return -1;
   856    /* See if it's the same. */
   857    if (render_compare( "Blit blending output not the same (using SDL_BLENDMODE_NONE).",
   858             &img_blendNone, ALLOWABLE_ERROR_OPAQUE ))
   859       return -1;
   860 
   861    /* Test Mask. */
   862    if (render_testBlitBlendMode( tface, SDL_BLENDMODE_MASK ))
   863       return -1;
   864    if (render_compare( "Blit blending output not the same (using SDL_BLENDMODE_MASK).",
   865             &img_blendMask, ALLOWABLE_ERROR_OPAQUE ))
   866       return -1;
   867 
   868    /* Test Blend. */
   869    if (render_testBlitBlendMode( tface, SDL_BLENDMODE_BLEND ))
   870       return -1;
   871    if (render_compare( "Blit blending output not the same (using SDL_BLENDMODE_BLEND).",
   872             &img_blendBlend, ALLOWABLE_ERROR_BLENDED ))
   873       return -1;
   874 
   875    /* Test Add. */
   876    if (render_testBlitBlendMode( tface, SDL_BLENDMODE_ADD ))
   877       return -1;
   878    if (render_compare( "Blit blending output not the same (using SDL_BLENDMODE_ADD).",
   879             &img_blendAdd, ALLOWABLE_ERROR_BLENDED ))
   880       return -1;
   881 
   882    /* Test Mod. */
   883    if (render_testBlitBlendMode( tface, SDL_BLENDMODE_MOD ))
   884       return -1;
   885    if (render_compare( "Blit blending output not the same (using SDL_BLENDMODE_MOD).",
   886             &img_blendMod, ALLOWABLE_ERROR_BLENDED ))
   887       return -1;
   888 
   889    /* Clear surface. */
   890    if (render_clearScreen())
   891       return -1;
   892 
   893    /* Loop blit. */
   894    for (j=0; j <= nj; j+=4) {
   895       for (i=0; i <= ni; i+=4) {
   896 
   897          /* Set colour mod. */
   898          ret = SDL_SetTextureColorMod( tface, (255/nj)*j, (255/ni)*i, (255/nj)*j );
   899          if (SDL_ATassert( "SDL_SetTextureColorMod", ret == 0))
   900             return -1;
   901 
   902          /* Set alpha mod. */
   903          ret = SDL_SetTextureAlphaMod( tface, (100/ni)*i );
   904          if (SDL_ATassert( "SDL_SetTextureAlphaMod", ret == 0))
   905             return -1;
   906 
   907          /* Crazy blending mode magic. */
   908          mode = (i/4*j/4) % 4;
   909          if (mode==0) mode = SDL_BLENDMODE_MASK;
   910          else if (mode==1) mode = SDL_BLENDMODE_BLEND;
   911          else if (mode==2) mode = SDL_BLENDMODE_ADD;
   912          else if (mode==3) mode = SDL_BLENDMODE_MOD;
   913          ret = SDL_SetTextureBlendMode( tface, mode );
   914          if (SDL_ATassert( "SDL_SetTextureBlendMode", ret == 0))
   915             return -1;
   916 
   917          /* Blitting. */
   918          rect.x = i;
   919          rect.y = j;
   920          ret = SDL_RenderCopy( tface, NULL, &rect );
   921          if (SDL_ATassert( "SDL_RenderCopy", ret == 0))
   922             return -1;
   923       }
   924    }
   925 
   926    /* Clean up. */
   927    SDL_DestroyTexture( tface );
   928 
   929    /* Check to see if matches. */
   930    if (render_compare( "Blit blending output not the same (using SDL_BLENDMODE_*).",
   931             &img_blendAll, ALLOWABLE_ERROR_BLENDED ))
   932       return -1;
   933 
   934    return 0;
   935 }
   936 
   937 
   938 /**
   939  * @brief Runs all the tests on the surface.
   940  *
   941  *    @return 0 on success.
   942  */
   943 int render_runTests (void)
   944 {
   945    int ret;
   946 
   947    /* No error. */
   948    ret = 0;
   949 
   950    /* Test functionality first. */
   951    if (render_hasDrawColor())
   952       SDL_ATprintVerbose( 1, "      Draw Color supported\n" );
   953    if (render_hasBlendModes())
   954       SDL_ATprintVerbose( 1, "      Blend Modes supported\n" );
   955    if (render_hasTexColor())
   956       SDL_ATprintVerbose( 1, "      Texture Color Mod supported\n" );
   957    if (render_hasTexAlpha())
   958       SDL_ATprintVerbose( 1, "      Texture Alpha Mod supported\n" );
   959 
   960    /* Software surface blitting. */
   961    ret = render_testReadWrite();
   962    if (ret)
   963       return -1;
   964    ret = render_testPrimitives();
   965    if (ret)
   966       return -1;
   967    ret = render_testPrimitivesBlend();
   968    if (ret)
   969       return -1;
   970    ret = render_testBlit();
   971    if (ret)
   972       return -1;
   973    ret = render_testBlitColour();
   974    if (ret)
   975       return -1;
   976    ret = render_testBlitAlpha();
   977    if (ret)
   978       return -1;
   979    ret = render_testBlitBlend();
   980 
   981    return ret;
   982 }
   983 
   984 
   985 /**
   986  * @brief Entry point.
   987  *
   988  * This testsuite is tricky, we're creating a testsuite per driver, the thing
   989  *  is we do quite a of stuff outside of the actual testcase which *could*
   990  *  give issues. Don't like that very much, but no way around without creating
   991  *  superfluous testsuites.
   992  */
   993 #ifdef TEST_STANDALONE
   994 int main( int argc, const char *argv[] )
   995 {
   996    (void) argc;
   997    (void) argv;
   998 #else /* TEST_STANDALONE */
   999 int test_render (void)
  1000 {
  1001 #endif /* TEST_STANDALONE */
  1002    int failed;
  1003    int i, j, nd, nr;
  1004    int ret;
  1005    const char *driver, *str;
  1006    char msg[256];
  1007    SDL_Window *w;
  1008    SDL_RendererInfo renderer;
  1009 
  1010    /* Initializes the SDL subsystems. */
  1011    ret = SDL_Init(0);
  1012    if (ret != 0)
  1013       return -1;
  1014 
  1015    /* Get number of drivers. */
  1016    nd = SDL_GetNumVideoDrivers();
  1017    if (nd < 0)
  1018       goto err;
  1019    SDL_ATprintVerbose( 1, "%d Video Drivers found\n", nd );
  1020 
  1021    /* Now run on the video mode. */
  1022    ret = SDL_InitSubSystem( SDL_INIT_VIDEO );
  1023    if (ret != 0)
  1024       goto err;
  1025 
  1026    /*
  1027     * Surface on video mode tests.
  1028     */
  1029    /* Run for all video modes. */
  1030    failed = 0;
  1031    for (i=0; i<nd; i++) {
  1032       /* Get video mode. */
  1033       driver = SDL_GetVideoDriver(i);
  1034       if (driver == NULL)
  1035          goto err;
  1036       SDL_ATprintVerbose( 1, " %d) %s\n", i+1, driver );
  1037 
  1038       /*
  1039        * Initialize testsuite.
  1040        */
  1041       SDL_snprintf( msg, sizeof(msg) , "Rendering with %s driver", driver );
  1042       SDL_ATinit( msg );
  1043 
  1044       /*
  1045        * Initialize.
  1046        */
  1047       SDL_ATbegin( "Initializing video mode" );
  1048       /* Initialize video mode. */
  1049       ret = SDL_VideoInit( driver, 0 );
  1050       if (SDL_ATvassert( ret==0, "SDL_VideoInit( %s, 0 )", driver ))
  1051          goto err_cleanup;
  1052       /* Check to see if it's the one we want. */
  1053       str = SDL_GetCurrentVideoDriver();
  1054       if (SDL_ATassert( "SDL_GetCurrentVideoDriver", SDL_strcmp(driver,str)==0))
  1055          goto err_cleanup;
  1056       /* Create window. */
  1057       w = SDL_CreateWindow( msg, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
  1058             80, 60, SDL_WINDOW_SHOWN );
  1059       if (SDL_ATassert( "SDL_CreateWindow", w!=NULL ))
  1060          goto err_cleanup;
  1061       /* Check title. */
  1062       str = SDL_GetWindowTitle( w );
  1063       if (SDL_ATassert( "SDL_GetWindowTitle", SDL_strcmp(msg,str)==0))
  1064          goto err_cleanup;
  1065       /* Get renderers. */
  1066       nr = SDL_GetNumRenderDrivers();
  1067       if (SDL_ATassert("SDL_GetNumRenderDrivers", nr>=0))
  1068          goto err_cleanup;
  1069       SDL_ATprintVerbose( 1, "   %d Render Drivers\n", nr );
  1070       SDL_ATend();
  1071       for (j=0; j<nr; j++) {
  1072 
  1073          /* We have to recreate window each time, because opengl and opengles renderers */
  1074          /* both add SDL_WINDOW_OPENGL flag for window, that was last used              */
  1075          SDL_DestroyWindow(w);
  1076          w = SDL_CreateWindow( msg, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
  1077                80, 60, SDL_WINDOW_SHOWN );
  1078          if (SDL_ATassert( "SDL_CreateWindow", w!=NULL ))
  1079             goto err_cleanup;
  1080 
  1081          /* Get renderer info. */
  1082          ret = SDL_GetRenderDriverInfo( j, &renderer );
  1083          if (ret != 0)
  1084             goto err_cleanup;
  1085 
  1086          /* Set testcase name. */
  1087          SDL_snprintf( msg, sizeof(msg), "Renderer %s", renderer.name );
  1088          SDL_ATprintVerbose( 1, "    %d) %s\n", j+1, renderer.name );
  1089          SDL_ATbegin( msg );
  1090 
  1091          /* Set renderer. */
  1092          ret = SDL_CreateRenderer( w, j, 0 );
  1093          if (SDL_ATassert( "SDL_CreateRenderer", ret==0 ))
  1094             goto err_cleanup;
  1095 
  1096          /*
  1097           * Run tests.
  1098           */
  1099          ret = render_runTests();
  1100 
  1101          if (ret)
  1102             continue;
  1103          SDL_ATend();
  1104       }
  1105 
  1106       /* Exit the current renderer. */
  1107       SDL_VideoQuit();
  1108 
  1109       /*
  1110        * Finish testsuite.
  1111        */
  1112       failed += SDL_ATfinish();
  1113    }
  1114 
  1115    /* Exit SDL. */
  1116    SDL_Quit();
  1117 
  1118    return failed;
  1119 
  1120 err_cleanup:
  1121    SDL_ATfinish();
  1122 
  1123 err:
  1124    return 1;
  1125 }
  1126