1/**
2 * Original code: automated SDL platform test written by Edgar Simo "bobbens"
3 * Extended and extensively updated by aschiffler at ferzkopp dot net
4 */
5
6#include <stdio.h>
7
8#include "SDL.h"
9#include "SDL_test.h"
10
11/* ================= Test Case Implementation ================== */
12
13#define TESTRENDER_SCREEN_W     80
14#define TESTRENDER_SCREEN_H     60
15
16#define RENDER_COMPARE_FORMAT  SDL_PIXELFORMAT_ARGB8888
17#define RENDER_COMPARE_AMASK   0xff000000 /**< Alpha bit mask. */
18#define RENDER_COMPARE_RMASK   0x00ff0000 /**< Red bit mask. */
19#define RENDER_COMPARE_GMASK   0x0000ff00 /**< Green bit mask. */
20#define RENDER_COMPARE_BMASK   0x000000ff /**< Blue bit mask. */
21
22#define ALLOWABLE_ERROR_OPAQUE  0
23#define ALLOWABLE_ERROR_BLENDED 64
24
25/* Test window and renderer */
26SDL_Window *window = NULL;
27SDL_Renderer *renderer = NULL;
28
29/* Prototypes for helper functions */
30
31static int _clearScreen (void);
32static void _compare(SDL_Surface *reference, int allowable_error);
33static int _hasTexAlpha(void);
34static int _hasTexColor(void);
35static SDL_Texture *_loadTestFace(void);
36static int _hasBlendModes(void);
37static int _hasDrawColor(void);
38static int _isSupported(int code);
39
40/**
41 * Create software renderer for tests
42 */
43void InitCreateRenderer(void *arg)
44{
45  int posX = 100, posY = 100, width = 320, height = 240;
46  renderer = NULL;
47  window = SDL_CreateWindow("render_testCreateRenderer", posX, posY, width, height, 0);
48  SDLTest_AssertPass("SDL_CreateWindow()");
49  SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result");
50  if (window == NULL) {
51      return;
52  }
53
54  renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
55  SDLTest_AssertPass("SDL_CreateRenderer()");
56  SDLTest_AssertCheck(renderer != 0, "Check SDL_CreateRenderer result");
57  if (renderer == NULL) {
58      SDL_DestroyWindow(window);
59      return;
60  }
61}
62
63/*
64 * Destroy renderer for tests
65 */
66void CleanupDestroyRenderer(void *arg)
67{
68  if (renderer != NULL) {
69     SDL_DestroyRenderer(renderer);
70     renderer = NULL;
71     SDLTest_AssertPass("SDL_DestroyRenderer()");
72  }
73
74  if (window != NULL) {
75     SDL_DestroyWindow(window);
76     window = NULL;
77     SDLTest_AssertPass("SDL_DestroyWindow");
78  }
79}
80
81
82/**
83 * @brief Tests call to SDL_GetNumRenderDrivers
84 *
85 * \sa
86 * http://wiki.libsdl.org/moin.cgi/SDL_GetNumRenderDrivers
87 */
88int
89render_testGetNumRenderDrivers(void *arg)
90{
91  int n;
92  n = SDL_GetNumRenderDrivers();
93  SDLTest_AssertCheck(n >= 1, "Number of renderers >= 1, reported as %i", n);
94  return TEST_COMPLETED;
95}
96
97
98/**
99 * @brief Tests the SDL primitives for rendering.
100 *
101 * \sa
102 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor
103 * http://wiki.libsdl.org/moin.cgi/SDL_RenderFillRect
104 * http://wiki.libsdl.org/moin.cgi/SDL_RenderDrawLine
105 *
106 */
107int render_testPrimitives (void *arg)
108{
109   int ret;
110   int x, y;
111   SDL_Rect rect;
112   SDL_Surface *referenceSurface = NULL;
113   int checkFailCount1;
114   int checkFailCount2;
115
116   /* Need drawcolor or just skip test. */
117   SDLTest_AssertCheck(_hasDrawColor(), "_hasDrawColor");
118
119   /* Draw a rectangle. */
120   rect.x = 40;
121   rect.y = 0;
122   rect.w = 40;
123   rect.h = 80;
124
125   ret = SDL_SetRenderDrawColor(renderer, 13, 73, 200, SDL_ALPHA_OPAQUE );
126   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
127
128   ret = SDL_RenderFillRect(renderer, &rect );
129   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
130
131   /* Draw a rectangle. */
132   rect.x = 10;
133   rect.y = 10;
134   rect.w = 60;
135   rect.h = 40;
136   ret = SDL_SetRenderDrawColor(renderer, 200, 0, 100, SDL_ALPHA_OPAQUE );
137   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
138
139   ret = SDL_RenderFillRect(renderer, &rect );
140   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
141
142   /* Draw some points like so:
143    * X.X.X.X..
144    * .X.X.X.X.
145    * X.X.X.X.. */
146   checkFailCount1 = 0;
147   checkFailCount2 = 0;
148   for (y=0; y<3; y++) {
149      for (x = y % 2; x<TESTRENDER_SCREEN_W; x+=2) {
150         ret = SDL_SetRenderDrawColor(renderer, x*y, x*y/2, x*y/3, SDL_ALPHA_OPAQUE );
151         if (ret != 0) checkFailCount1++;
152
153         ret = SDL_RenderDrawPoint(renderer, x, y );
154         if (ret != 0) checkFailCount2++;
155      }
156   }
157   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
158   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderDrawPoint, expected: 0, got: %i", checkFailCount2);
159
160   /* Draw some lines. */
161   ret = SDL_SetRenderDrawColor(renderer, 0, 255, 0, SDL_ALPHA_OPAQUE );
162   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor");
163
164   ret = SDL_RenderDrawLine(renderer, 0, 30, TESTRENDER_SCREEN_W, 30 );
165   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret);
166
167   ret = SDL_SetRenderDrawColor(renderer, 55, 55, 5, SDL_ALPHA_OPAQUE );
168   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
169
170   ret = SDL_RenderDrawLine(renderer, 40, 30, 40, 60 );
171   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret);
172
173   ret = SDL_SetRenderDrawColor(renderer, 5, 105, 105, SDL_ALPHA_OPAQUE );
174   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
175
176   ret = SDL_RenderDrawLine(renderer, 0, 0, 29, 29 );
177   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret);
178
179   ret = SDL_RenderDrawLine(renderer, 29, 30, 0, 59 );
180   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret);
181
182   ret = SDL_RenderDrawLine(renderer, 79, 0, 50, 29 );
183   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret);
184
185   ret = SDL_RenderDrawLine(renderer, 79, 59, 50, 30 );
186   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderDrawLine, expected: 0, got: %i", ret);
187
188   /* See if it's the same. */
189   referenceSurface = SDLTest_ImagePrimitives();
190   _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE );
191
192   /* Clean up. */
193   SDL_FreeSurface(referenceSurface);
194   referenceSurface = NULL;
195
196   return TEST_COMPLETED;
197}
198
199/**
200 * @brief Tests the SDL primitives with alpha for rendering.
201 *
202 * \sa
203 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor
204 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawBlendMode
205 * http://wiki.libsdl.org/moin.cgi/SDL_RenderFillRect
206 */
207int render_testPrimitivesBlend (void *arg)
208{
209   int ret;
210   int i, j;
211   SDL_Rect rect;
212   SDL_Surface *referenceSurface = NULL;
213   int checkFailCount1;
214   int checkFailCount2;
215   int checkFailCount3;
216
217   /* Need drawcolor and blendmode or just skip test. */
218   SDLTest_AssertCheck(_hasDrawColor(), "_hasDrawColor");
219   SDLTest_AssertCheck(_hasBlendModes(), "_hasBlendModes");
220
221   /* Create some rectangles for each blend mode. */
222   ret = SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0 );
223   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
224
225   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE );
226   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawBlendMode, expected: 0, got: %i", ret);
227
228   ret = SDL_RenderFillRect(renderer, NULL );
229   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
230
231   rect.x = 10;
232   rect.y = 25;
233   rect.w = 40;
234   rect.h = 25;
235   ret = SDL_SetRenderDrawColor(renderer, 240, 10, 10, 75 );
236   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
237
238   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD );
239   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawBlendMode, expected: 0, got: %i", ret);
240
241   ret = SDL_RenderFillRect(renderer, &rect );
242   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
243
244   rect.x = 30;
245   rect.y = 40;
246   rect.w = 45;
247   rect.h = 15;
248   ret = SDL_SetRenderDrawColor(renderer, 10, 240, 10, 100 );
249   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
250
251   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND );
252   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawBlendMode, expected: 0, got: %i", ret);
253
254   ret = SDL_RenderFillRect(renderer, &rect );
255   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
256
257   rect.x = 25;
258   rect.y = 25;
259   rect.w = 25;
260   rect.h = 25;
261   ret = SDL_SetRenderDrawColor(renderer, 10, 10, 240, 125 );
262   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
263
264   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE );
265   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawBlendMode, expected: 0, got: %i", ret);
266
267   ret = SDL_RenderFillRect(renderer, &rect );
268   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
269
270
271   /* Draw blended lines, lines for everyone. */
272   checkFailCount1 = 0;
273   checkFailCount2 = 0;
274   checkFailCount3 = 0;
275   for (i=0; i<TESTRENDER_SCREEN_W; i+=2)  {
276      ret = SDL_SetRenderDrawColor(renderer, 60+2*i, 240-2*i, 50, 3*i );
277      if (ret != 0) checkFailCount1++;
278
279      ret = SDL_SetRenderDrawBlendMode(renderer,(((i/2)%3)==0) ? SDL_BLENDMODE_BLEND :
280            (((i/2)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_NONE );
281      if (ret != 0) checkFailCount2++;
282
283      ret = SDL_RenderDrawLine(renderer, 0, 0, i, 59 );
284      if (ret != 0) checkFailCount3++;
285   }
286   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
287   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2);
288   SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderDrawLine, expected: 0, got: %i", checkFailCount3);
289
290   checkFailCount1 = 0;
291   checkFailCount2 = 0;
292   checkFailCount3 = 0;
293   for (i=0; i<TESTRENDER_SCREEN_H; i+=2)  {
294      ret = SDL_SetRenderDrawColor(renderer, 60+2*i, 240-2*i, 50, 3*i );
295      if (ret != 0) checkFailCount1++;
296
297      ret = SDL_SetRenderDrawBlendMode(renderer,(((i/2)%3)==0) ? SDL_BLENDMODE_BLEND :
298            (((i/2)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_NONE );
299      if (ret != 0) checkFailCount2++;
300
301      ret = SDL_RenderDrawLine(renderer, 0, 0, 79, i );
302      if (ret != 0) checkFailCount3++;
303   }
304   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
305   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2);
306   SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderDrawLine, expected: 0, got: %i", checkFailCount3);
307
308   /* Draw points. */
309   checkFailCount1 = 0;
310   checkFailCount2 = 0;
311   checkFailCount3 = 0;
312   for (j=0; j<TESTRENDER_SCREEN_H; j+=3) {
313      for (i=0; i<TESTRENDER_SCREEN_W; i+=3) {
314         ret = SDL_SetRenderDrawColor(renderer, j*4, i*3, j*4, i*3 );
315         if (ret != 0) checkFailCount1++;
316
317         ret = SDL_SetRenderDrawBlendMode(renderer, ((((i+j)/3)%3)==0) ? SDL_BLENDMODE_BLEND :
318               ((((i+j)/3)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_NONE );
319         if (ret != 0) checkFailCount2++;
320
321         ret = SDL_RenderDrawPoint(renderer, i, j );
322         if (ret != 0) checkFailCount3++;
323      }
324   }
325   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetRenderDrawColor, expected: 0, got: %i", checkFailCount1);
326   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetRenderDrawBlendMode, expected: 0, got: %i", checkFailCount2);
327   SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_RenderDrawPoint, expected: 0, got: %i", checkFailCount3);
328
329   /* See if it's the same. */
330   referenceSurface = SDLTest_ImagePrimitivesBlend();
331   _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED );
332
333   /* Clean up. */
334   SDL_FreeSurface(referenceSurface);
335   referenceSurface = NULL;
336
337   return TEST_COMPLETED;
338}
339
340
341
342/**
343 * @brief Tests some blitting routines.
344 *
345 * \sa
346 * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy
347 * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture
348 */
349int
350render_testBlit(void *arg)
351{
352   int ret;
353   SDL_Rect rect;
354   SDL_Texture *tface;
355   SDL_Surface *referenceSurface = NULL;
356   Uint32 tformat;
357   int taccess, tw, th;
358   int i, j, ni, nj;
359   int checkFailCount1;
360
361
362   /* Need drawcolor or just skip test. */
363   SDLTest_AssertCheck(_hasDrawColor(), "_hasDrawColor)");
364
365   /* Create face surface. */
366   tface = _loadTestFace();
367   SDLTest_AssertCheck(tface != NULL,  "Verify _loadTestFace() result");
368   if (tface == NULL) {
369       return TEST_ABORTED;
370   }
371
372   /* Constant values. */
373   ret = SDL_QueryTexture(tface, &tformat, &taccess, &tw, &th);
374   SDLTest_AssertCheck(ret == 0, "Verify result from SDL_QueryTexture, expected 0, got %i", ret);
375   rect.w = tw;
376   rect.h = th;
377   ni     = TESTRENDER_SCREEN_W - tw;
378   nj     = TESTRENDER_SCREEN_H - th;
379
380   /* Loop blit. */
381   checkFailCount1 = 0;
382   for (j=0; j <= nj; j+=4) {
383      for (i=0; i <= ni; i+=4) {
384         /* Blitting. */
385         rect.x = i;
386         rect.y = j;
387         ret = SDL_RenderCopy(renderer, tface, NULL, &rect );
388         if (ret != 0) checkFailCount1++;
389      }
390   }
391   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount1);
392
393   /* See if it's the same */
394   referenceSurface = SDLTest_ImageBlit();
395   _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE );
396
397   /* Clean up. */
398   SDL_DestroyTexture( tface );
399   SDL_FreeSurface(referenceSurface);
400   referenceSurface = NULL;
401
402   return TEST_COMPLETED;
403}
404
405
406/**
407 * @brief Blits doing color tests.
408 *
409 * \sa
410 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureColorMod
411 * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy
412 * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture
413 */
414int
415render_testBlitColor (void *arg)
416{
417   int ret;
418   SDL_Rect rect;
419   SDL_Texture *tface;
420   SDL_Surface *referenceSurface = NULL;
421   Uint32 tformat;
422   int taccess, tw, th;
423   int i, j, ni, nj;
424   int checkFailCount1;
425   int checkFailCount2;
426
427   /* Create face surface. */
428   tface = _loadTestFace();
429   SDLTest_AssertCheck(tface != NULL, "Verify _loadTestFace() result");
430   if (tface == NULL) {
431       return TEST_ABORTED;
432   }
433
434   /* Constant values. */
435   ret = SDL_QueryTexture(tface, &tformat, &taccess, &tw, &th);
436   SDLTest_AssertCheck(ret == 0, "Verify result from SDL_QueryTexture, expected 0, got %i", ret);
437   rect.w = tw;
438   rect.h = th;
439   ni     = TESTRENDER_SCREEN_W - tw;
440   nj     = TESTRENDER_SCREEN_H - th;
441
442   /* Test blitting with color mod. */
443   checkFailCount1 = 0;
444   checkFailCount2 = 0;
445   for (j=0; j <= nj; j+=4) {
446      for (i=0; i <= ni; i+=4) {
447         /* Set color mod. */
448         ret = SDL_SetTextureColorMod( tface, (255/nj)*j, (255/ni)*i, (255/nj)*j );
449         if (ret != 0) checkFailCount1++;
450
451         /* Blitting. */
452         rect.x = i;
453         rect.y = j;
454         ret = SDL_RenderCopy(renderer, tface, NULL, &rect );
455         if (ret != 0) checkFailCount2++;
456      }
457   }
458   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureColorMod, expected: 0, got: %i", checkFailCount1);
459   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount2);
460
461   /* See if it's the same. */
462   referenceSurface = SDLTest_ImageBlitColor();
463   _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE );
464
465   /* Clean up. */
466   SDL_DestroyTexture( tface );
467   SDL_FreeSurface(referenceSurface);
468   referenceSurface = NULL;
469
470   return TEST_COMPLETED;
471}
472
473
474/**
475 * @brief Tests blitting with alpha.
476 *
477 * \sa
478 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureAlphaMod
479 * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy
480 * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture
481 */
482int
483render_testBlitAlpha (void *arg)
484{
485   int ret;
486   SDL_Rect rect;
487   SDL_Texture *tface;
488   SDL_Surface *referenceSurface = NULL;
489   Uint32 tformat;
490   int taccess, tw, th;
491   int i, j, ni, nj;
492   int checkFailCount1;
493   int checkFailCount2;
494
495   /* Need alpha or just skip test. */
496   SDLTest_AssertCheck(_hasTexAlpha(), "_hasTexAlpha");
497
498   /* Create face surface. */
499   tface = _loadTestFace();
500   SDLTest_AssertCheck(tface != NULL, "Verify _loadTestFace() result");
501   if (tface == NULL) {
502       return TEST_ABORTED;
503   }
504
505   /* Constant values. */
506   ret = SDL_QueryTexture(tface, &tformat, &taccess, &tw, &th);
507   SDLTest_AssertCheck(ret == 0, "Verify result from SDL_QueryTexture, expected 0, got %i", ret);
508   rect.w = tw;
509   rect.h = th;
510   ni     = TESTRENDER_SCREEN_W - tw;
511   nj     = TESTRENDER_SCREEN_H - th;
512
513   /* Test blitting with alpha mod. */
514   checkFailCount1 = 0;
515   checkFailCount2 = 0;
516   for (j=0; j <= nj; j+=4) {
517      for (i=0; i <= ni; i+=4) {
518         /* Set alpha mod. */
519         ret = SDL_SetTextureAlphaMod( tface, (255/ni)*i );
520         if (ret != 0) checkFailCount1++;
521
522         /* Blitting. */
523         rect.x = i;
524         rect.y = j;
525         ret = SDL_RenderCopy(renderer, tface, NULL, &rect );
526         if (ret != 0) checkFailCount2++;
527      }
528   }
529   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureAlphaMod, expected: 0, got: %i", checkFailCount1);
530   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount2);
531
532   /* See if it's the same. */
533   referenceSurface = SDLTest_ImageBlitAlpha();
534   _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED );
535
536   /* Clean up. */
537   SDL_DestroyTexture( tface );
538   SDL_FreeSurface(referenceSurface);
539   referenceSurface = NULL;
540
541   return TEST_COMPLETED;
542}
543
544/* Helper functions */
545
546/**
547 * @brief Tests a blend mode.
548 *
549 * \sa
550 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureBlendMode
551 * http://wiki.libsdl.org/moin.cgi/SDL_RenderCopy
552 */
553static void
554_testBlitBlendMode( SDL_Texture * tface, int mode )
555{
556   int ret;
557   Uint32 tformat;
558   int taccess, tw, th;
559   int i, j, ni, nj;
560   SDL_Rect rect;
561   int checkFailCount1;
562   int checkFailCount2;
563
564   /* Clear surface. */
565   _clearScreen();
566
567   /* Constant values. */
568   ret = SDL_QueryTexture(tface, &tformat, &taccess, &tw, &th);
569   SDLTest_AssertCheck(ret == 0, "Verify result from SDL_QueryTexture, expected 0, got %i", ret);
570   rect.w = tw;
571   rect.h = th;
572   ni     = TESTRENDER_SCREEN_W - tw;
573   nj     = TESTRENDER_SCREEN_H - th;
574
575   /* Test blend mode. */
576   checkFailCount1 = 0;
577   checkFailCount2 = 0;
578   for (j=0; j <= nj; j+=4) {
579      for (i=0; i <= ni; i+=4) {
580         /* Set blend mode. */
581         ret = SDL_SetTextureBlendMode( tface, (SDL_BlendMode)mode );
582         if (ret != 0) checkFailCount1++;
583
584         /* Blitting. */
585         rect.x = i;
586         rect.y = j;
587         ret = SDL_RenderCopy(renderer, tface, NULL, &rect );
588         if (ret != 0) checkFailCount2++;
589      }
590   }
591   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureBlendMode, expected: 0, got: %i", checkFailCount1);
592   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount2);
593}
594
595
596/**
597 * @brief Tests some more blitting routines.
598 *
599 * \sa
600 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureColorMod
601 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureAlphaMod
602 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureBlendMode
603 * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture
604 */
605int
606render_testBlitBlend (void *arg)
607{
608   int ret;
609   SDL_Rect rect;
610   SDL_Texture *tface;
611   SDL_Surface *referenceSurface = NULL;
612   Uint32 tformat;
613   int taccess, tw, th;
614   int i, j, ni, nj;
615   int mode;
616   int checkFailCount1;
617   int checkFailCount2;
618   int checkFailCount3;
619   int checkFailCount4;
620
621   SDLTest_AssertCheck(_hasBlendModes(), "_hasBlendModes");
622   SDLTest_AssertCheck(_hasTexColor(), "_hasTexColor");
623   SDLTest_AssertCheck(_hasTexAlpha(), "_hasTexAlpha");
624
625   /* Create face surface. */
626   tface = _loadTestFace();
627   SDLTest_AssertCheck(tface != NULL, "Verify _loadTestFace() result");
628   if (tface == NULL) {
629       return TEST_ABORTED;
630   }
631
632   /* Constant values. */
633   ret = SDL_QueryTexture(tface, &tformat, &taccess, &tw, &th);
634   SDLTest_AssertCheck(ret == 0, "Verify result from SDL_QueryTexture, expected 0, got %i", ret);
635   rect.w = tw;
636   rect.h = th;
637   ni = TESTRENDER_SCREEN_W - tw;
638   nj = TESTRENDER_SCREEN_H - th;
639
640   /* Set alpha mod. */
641   ret = SDL_SetTextureAlphaMod( tface, 100 );
642   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetTextureAlphaMod, expected: 0, got: %i", ret);
643
644   /* Test None. */
645   _testBlitBlendMode( tface, SDL_BLENDMODE_NONE );
646   referenceSurface = SDLTest_ImageBlitBlendNone();
647   _compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE );
648   SDL_FreeSurface(referenceSurface);
649   referenceSurface = NULL;
650
651   /* Test Blend. */
652   _testBlitBlendMode( tface, SDL_BLENDMODE_BLEND );
653   referenceSurface = SDLTest_ImageBlitBlend();
654   _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED );
655   SDL_FreeSurface(referenceSurface);
656   referenceSurface = NULL;
657
658   /* Test Add. */
659   _testBlitBlendMode( tface, SDL_BLENDMODE_ADD );
660   referenceSurface = SDLTest_ImageBlitBlendAdd();
661   _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED );
662   SDL_FreeSurface(referenceSurface);
663   referenceSurface = NULL;
664
665   /* Test Mod. */
666   _testBlitBlendMode( tface, SDL_BLENDMODE_MOD);
667   referenceSurface = SDLTest_ImageBlitBlendMod();
668   _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED );
669   SDL_FreeSurface(referenceSurface);
670   referenceSurface = NULL;
671
672   /* Clear surface. */
673   _clearScreen();
674
675   /* Loop blit. */
676   checkFailCount1 = 0;
677   checkFailCount2 = 0;
678   checkFailCount3 = 0;
679   checkFailCount4 = 0;
680   for (j=0; j <= nj; j+=4) {
681      for (i=0; i <= ni; i+=4) {
682
683         /* Set color mod. */
684         ret = SDL_SetTextureColorMod( tface, (255/nj)*j, (255/ni)*i, (255/nj)*j );
685         if (ret != 0) checkFailCount1++;
686
687         /* Set alpha mod. */
688         ret = SDL_SetTextureAlphaMod( tface, (100/ni)*i );
689         if (ret != 0) checkFailCount2++;
690
691         /* Crazy blending mode magic. */
692         mode = (i/4*j/4) % 4;
693         if (mode==0) mode = SDL_BLENDMODE_NONE;
694         else if (mode==1) mode = SDL_BLENDMODE_BLEND;
695         else if (mode==2) mode = SDL_BLENDMODE_ADD;
696         else if (mode==3) mode = SDL_BLENDMODE_MOD;
697         ret = SDL_SetTextureBlendMode( tface, (SDL_BlendMode)mode );
698         if (ret != 0) checkFailCount3++;
699
700         /* Blitting. */
701         rect.x = i;
702         rect.y = j;
703         ret = SDL_RenderCopy(renderer, tface, NULL, &rect );
704         if (ret != 0) checkFailCount4++;
705      }
706   }
707   SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_SetTextureColorMod, expected: 0, got: %i", checkFailCount1);
708   SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetTextureAlphaMod, expected: 0, got: %i", checkFailCount2);
709   SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_SetTextureBlendMode, expected: 0, got: %i", checkFailCount3);
710   SDLTest_AssertCheck(checkFailCount4 == 0, "Validate results from calls to SDL_RenderCopy, expected: 0, got: %i", checkFailCount4);
711
712   /* Clean up. */
713   SDL_DestroyTexture( tface );
714
715   /* Check to see if final image matches. */
716   referenceSurface = SDLTest_ImageBlitBlendAll();
717   _compare(referenceSurface, ALLOWABLE_ERROR_BLENDED);
718   SDL_FreeSurface(referenceSurface);
719   referenceSurface = NULL;
720
721   return TEST_COMPLETED;
722}
723
724
725/**
726 * @brief Checks to see if functionality is supported. Helper function.
727 */
728static int
729_isSupported( int code )
730{
731   return (code == 0);
732}
733
734/**
735 * @brief Test to see if we can vary the draw color. Helper function.
736 *
737 * \sa
738 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor
739 * http://wiki.libsdl.org/moin.cgi/SDL_GetRenderDrawColor
740 */
741static int
742_hasDrawColor (void)
743{
744   int ret, fail;
745   Uint8 r, g, b, a;
746
747   fail = 0;
748
749   /* Set color. */
750   ret = SDL_SetRenderDrawColor(renderer, 100, 100, 100, 100 );
751   if (!_isSupported(ret))
752      fail = 1;
753   ret = SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a );
754   if (!_isSupported(ret))
755      fail = 1;
756
757   /* Restore natural. */
758   ret = SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
759   if (!_isSupported(ret))
760      fail = 1;
761
762   /* Something failed, consider not available. */
763   if (fail)
764      return 0;
765
766   /* Not set properly, consider failed. */
767   else if ((r != 100) || (g != 100) || (b != 100) || (a != 100))
768      return 0;
769   return 1;
770}
771
772/**
773 * @brief Test to see if we can vary the blend mode. Helper function.
774 *
775 * \sa
776 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawBlendMode
777 * http://wiki.libsdl.org/moin.cgi/SDL_GetRenderDrawBlendMode
778 */
779static int
780_hasBlendModes (void)
781{
782   int fail;
783   int ret;
784   SDL_BlendMode mode;
785
786   fail = 0;
787
788   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND );
789   if (!_isSupported(ret))
790      fail = 1;
791   ret = SDL_GetRenderDrawBlendMode(renderer, &mode );
792   if (!_isSupported(ret))
793      fail = 1;
794   ret = (mode != SDL_BLENDMODE_BLEND);
795   if (!_isSupported(ret))
796      fail = 1;
797   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD );
798   if (!_isSupported(ret))
799      fail = 1;
800   ret = SDL_GetRenderDrawBlendMode(renderer, &mode );
801   if (!_isSupported(ret))
802      fail = 1;
803   ret = (mode != SDL_BLENDMODE_ADD);
804   if (!_isSupported(ret))
805      fail = 1;
806   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_MOD );
807   if (!_isSupported(ret))
808      fail = 1;
809   ret = SDL_GetRenderDrawBlendMode(renderer, &mode );
810   if (!_isSupported(ret))
811      fail = 1;
812   ret = (mode != SDL_BLENDMODE_MOD);
813   if (!_isSupported(ret))
814      fail = 1;
815   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE );
816   if (!_isSupported(ret))
817      fail = 1;
818   ret = SDL_GetRenderDrawBlendMode(renderer, &mode );
819   if (!_isSupported(ret))
820      fail = 1;
821   ret = (mode != SDL_BLENDMODE_NONE);
822   if (!_isSupported(ret))
823      fail = 1;
824
825   return !fail;
826}
827
828
829/**
830 * @brief Loads the test image 'Face' as texture. Helper function.
831 *
832 * \sa
833 * http://wiki.libsdl.org/moin.cgi/SDL_CreateTextureFromSurface
834 */
835static SDL_Texture *
836_loadTestFace(void)
837{
838   SDL_Surface *face;
839   SDL_Texture *tface;
840
841   face = SDLTest_ImageFace();
842   if (face == NULL) {
843      return NULL;
844   }
845
846   tface = SDL_CreateTextureFromSurface(renderer, face);
847   if (tface == NULL) {
848       SDLTest_LogError("SDL_CreateTextureFromSurface() failed with error: %s", SDL_GetError());
849   }
850
851   SDL_FreeSurface(face);
852
853   return tface;
854}
855
856
857/**
858 * @brief Test to see if can set texture color mode. Helper function.
859 *
860 * \sa
861 * http://wiki.libsdl.org/moin.cgi/SDL_SetTextureColorMod
862 * http://wiki.libsdl.org/moin.cgi/SDL_GetTextureColorMod
863 * http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture
864 */
865static int
866_hasTexColor (void)
867{
868   int fail;
869   int ret;
870   SDL_Texture *tface;
871   Uint8 r, g, b;
872
873   /* Get test face. */
874   tface = _loadTestFace();
875   if (tface == NULL)
876      return 0;
877
878   /* See if supported. */
879   fail = 0;
880   ret = SDL_SetTextureColorMod( tface, 100, 100, 100 );
881   if (!_isSupported(ret))
882      fail = 1;
883   ret = SDL_GetTextureColorMod( tface, &r, &g, &b );
884   if (!_isSupported(ret))
885      fail = 1;
886
887   /* Clean up. */
888   SDL_DestroyTexture( tface );
889
890   if (fail)
891      return 0;
892   else if ((r != 100) || (g != 100) || (b != 100))
893      return 0;
894   return 1;
895}
896
897/**
898 * @brief Test to see if we can vary the alpha of the texture. Helper function.
899 *
900 * \sa
901 *  http://wiki.libsdl.org/moin.cgi/SDL_SetTextureAlphaMod
902 *  http://wiki.libsdl.org/moin.cgi/SDL_GetTextureAlphaMod
903 *  http://wiki.libsdl.org/moin.cgi/SDL_DestroyTexture
904 */
905static int
906_hasTexAlpha(void)
907{
908   int fail;
909   int ret;
910   SDL_Texture *tface;
911   Uint8 a;
912
913   /* Get test face. */
914   tface = _loadTestFace();
915   if (tface == NULL)
916      return 0;
917
918   /* See if supported. */
919   fail = 0;
920   ret = SDL_SetTextureAlphaMod( tface, 100 );
921   if (!_isSupported(ret))
922      fail = 1;
923   ret = SDL_GetTextureAlphaMod( tface, &a );
924   if (!_isSupported(ret))
925      fail = 1;
926
927   /* Clean up. */
928   SDL_DestroyTexture( tface );
929
930   if (fail)
931      return 0;
932   else if (a != 100)
933      return 0;
934   return 1;
935}
936
937/**
938 * @brief Compares screen pixels with image pixels. Helper function.
939 *
940 * @param s Image to compare against.
941 *
942 * \sa
943 * http://wiki.libsdl.org/moin.cgi/SDL_RenderReadPixels
944 * http://wiki.libsdl.org/moin.cgi/SDL_CreateRGBSurfaceFrom
945 * http://wiki.libsdl.org/moin.cgi/SDL_FreeSurface
946 */
947static void
948_compare(SDL_Surface *referenceSurface, int allowable_error)
949{
950   int result;
951   SDL_Rect rect;
952   Uint8 *pixels;
953   SDL_Surface *testSurface;
954
955   /* Read pixels. */
956   pixels = (Uint8 *)SDL_malloc(4*TESTRENDER_SCREEN_W*TESTRENDER_SCREEN_H);
957   SDLTest_AssertCheck(pixels != NULL, "Validate allocated temp pixel buffer");
958   if (pixels == NULL) return;
959
960   /* Explicitly specify the rect in case the window isn't the expected size... */
961   rect.x = 0;
962   rect.y = 0;
963   rect.w = TESTRENDER_SCREEN_W;
964   rect.h = TESTRENDER_SCREEN_H;
965   result = SDL_RenderReadPixels(renderer, &rect, RENDER_COMPARE_FORMAT, pixels, 80*4 );
966   SDLTest_AssertCheck(result == 0, "Validate result from SDL_RenderReadPixels, expected: 0, got: %i", result);
967
968   /* Create surface. */
969   testSurface = SDL_CreateRGBSurfaceFrom(pixels, TESTRENDER_SCREEN_W, TESTRENDER_SCREEN_H, 32, TESTRENDER_SCREEN_W*4,
970                                       RENDER_COMPARE_RMASK, RENDER_COMPARE_GMASK, RENDER_COMPARE_BMASK, RENDER_COMPARE_AMASK);
971   SDLTest_AssertCheck(testSurface != NULL, "Verify result from SDL_CreateRGBSurfaceFrom is not NULL");
972
973   /* Compare surface. */
974   result = SDLTest_CompareSurfaces( testSurface, referenceSurface, allowable_error );
975   SDLTest_AssertCheck(result == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", result);
976
977   /* Clean up. */
978   SDL_free(pixels);
979   SDL_FreeSurface(testSurface);
980}
981
982/**
983 * @brief Clears the screen. Helper function.
984 *
985 * \sa
986 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor
987 * http://wiki.libsdl.org/moin.cgi/SDL_RenderFillRect
988 * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawBlendMode
989 */
990static int
991_clearScreen(void)
992{
993   int ret;
994
995   /* Set color. */
996   ret = SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE );
997   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
998
999   /* Clear screen. */
1000   ret = SDL_RenderFillRect(renderer, NULL );
1001   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret);
1002
1003   /* Set defaults. */
1004   ret = SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE );
1005   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawBlendMode, expected: 0, got: %i", ret);
1006
1007   ret = SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE );
1008   SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret);
1009
1010   return 0;
1011}
1012
1013/* ================= Test References ================== */
1014
1015/* Render test cases */
1016static const SDLTest_TestCaseReference renderTest1 =
1017        { (SDLTest_TestCaseFp)render_testGetNumRenderDrivers, "render_testGetNumRenderDrivers", "Tests call to SDL_GetNumRenderDrivers", TEST_ENABLED };
1018
1019static const SDLTest_TestCaseReference renderTest2 =
1020        { (SDLTest_TestCaseFp)render_testPrimitives, "render_testPrimitives", "Tests rendering primitives", TEST_ENABLED };
1021
1022/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
1023static const SDLTest_TestCaseReference renderTest3 =
1024        { (SDLTest_TestCaseFp)render_testPrimitivesBlend, "render_testPrimitivesBlend", "Tests rendering primitives with blending", TEST_DISABLED };
1025
1026static const SDLTest_TestCaseReference renderTest4 =
1027        { (SDLTest_TestCaseFp)render_testBlit, "render_testBlit", "Tests blitting", TEST_ENABLED };
1028
1029static const SDLTest_TestCaseReference renderTest5 =
1030        { (SDLTest_TestCaseFp)render_testBlitColor, "render_testBlitColor", "Tests blitting with color", TEST_ENABLED };
1031
1032/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
1033static const SDLTest_TestCaseReference renderTest6 =
1034        { (SDLTest_TestCaseFp)render_testBlitAlpha, "render_testBlitAlpha", "Tests blitting with alpha", TEST_DISABLED };
1035
1036/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */
1037static const SDLTest_TestCaseReference renderTest7 =
1038        {  (SDLTest_TestCaseFp)render_testBlitBlend, "render_testBlitBlend", "Tests blitting with blending", TEST_DISABLED };
1039
1040/* Sequence of Render test cases */
1041static const SDLTest_TestCaseReference *renderTests[] =  {
1042    &renderTest1, &renderTest2, &renderTest3, &renderTest4, &renderTest5, &renderTest6, &renderTest7, NULL
1043};
1044
1045/* Render test suite (global) */
1046SDLTest_TestSuiteReference renderTestSuite = {
1047    "Render",
1048    InitCreateRenderer,
1049    renderTests,
1050    CleanupDestroyRenderer
1051};
1052