visualtest/src/action_configparser.c
author Sam Lantinga
Tue, 10 Jan 2017 08:54:33 -0800
changeset 10806 36f40b8cc979
parent 7924 fcb86d323770
permissions -rw-r--r--
Fixed bugs 2570, 3145, improved OpenGL ES context support on Windows and X11

Mark Callow

The attached patch does the following for the X11 and Windows platforms, the only ones where SDL attempts to use context_create_es_profile:

- Adds SDL_HINT_OPENGL_ES_DRIVER by which the application can
say to use the OpenGL ES driver & EGL rather than the Open GL
driver. (For bug #2570)
- Adds code to {WIN,X11}_GL_InitExtensions to determine the maximum
OpenGL ES version supported by the OpenGL driver (for bug #3145)
- Modifies the test that determines whether to use the OpenGL
driver or the real OpenGL ES driver to take into account the
hint, the requested and supported ES version and whether ES 1.X
is being requested. (For bug #2570 & bug #3145)
- Enables the testgles2 test for __WINDOWS__ and __LINUX__ and adds
the test to the VisualC projects.

With the fix in place I have run testdraw2, testgl and testgles2 without any issues and have run my own apps that use OpenGL, OpenGL ES 3 and OpenGL ES 1.1.
     1 /* See COPYING.txt for the full license governing this code. */
     2 /**
     3  * \file action_configparser.c
     4  *
     5  * Source file for the parser for action config files.
     6  */
     7 
     8 #include <SDL_stdinc.h>
     9 #include <SDL_test.h>
    10 #include <string.h>
    11 #include "SDL_visualtest_action_configparser.h"
    12 #include "SDL_visualtest_rwhelper.h"
    13 #include "SDL_visualtest_parsehelper.h"
    14 
    15 static void
    16 FreeAction(SDLVisualTest_Action* action)
    17 {
    18     if(!action)
    19         return;
    20     switch(action->type)
    21     {
    22         case SDL_ACTION_LAUNCH:
    23         {
    24             char* path;
    25             char* args;
    26 
    27             path = action->extra.process.path;
    28             args = action->extra.process.args;
    29 
    30             if(path)
    31                 SDL_free(path);
    32             if(args)
    33                 SDL_free(args);
    34 
    35             action->extra.process.path = NULL;
    36             action->extra.process.args = NULL;
    37         }
    38         break;
    39     }
    40 }
    41 
    42 int
    43 SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue,
    44                             SDLVisualTest_Action action)
    45 {
    46     SDLVisualTest_ActionNode* node;
    47     if(!queue)
    48     {
    49         SDLTest_LogError("queue argument cannot be NULL");
    50         return 0;
    51     }
    52 
    53     node = (SDLVisualTest_ActionNode*)SDL_malloc(
    54                                       sizeof(SDLVisualTest_ActionNode));
    55     if(!node)
    56     {
    57         SDLTest_LogError("malloc() failed");
    58         return 0;
    59     }
    60     node->action = action;
    61     node->next = NULL;
    62     queue->size++;
    63     if(!queue->rear)
    64         queue->rear = queue->front = node;
    65     else
    66     {
    67         queue->rear->next = node;
    68         queue->rear = node;
    69     }
    70     return 1;
    71 }
    72 
    73 int
    74 SDLVisualTest_DequeueAction(SDLVisualTest_ActionQueue* queue)
    75 {
    76     SDLVisualTest_ActionNode* node;
    77     if(!queue)
    78     {
    79         SDLTest_LogError("queue argument cannot be NULL");
    80         return 0;
    81     }
    82     if(SDLVisualTest_IsActionQueueEmpty(queue))
    83     {
    84         SDLTest_LogError("cannot dequeue from empty queue");
    85         return 0;
    86     }
    87     if(queue->front == queue->rear)
    88     {
    89         FreeAction(&queue->front->action);
    90         SDL_free(queue->front);
    91         queue->front = queue->rear = NULL;
    92     }
    93     else
    94     {
    95         node = queue->front;
    96         queue->front = queue->front->next;
    97         FreeAction(&node->action);
    98         SDL_free(node);
    99     }
   100     queue->size--;
   101     return 1;
   102 }
   103 
   104 void
   105 SDLVisualTest_InitActionQueue(SDLVisualTest_ActionQueue* queue)
   106 {
   107     if(!queue)
   108     {
   109         SDLTest_LogError("queue argument cannot be NULL");
   110         return;
   111     }
   112     queue->front = NULL;
   113     queue->rear = NULL;
   114     queue->size = 0;
   115 }
   116 
   117 SDLVisualTest_Action*
   118 SDLVisualTest_GetQueueFront(SDLVisualTest_ActionQueue* queue)
   119 {
   120     if(!queue)
   121     {
   122         SDLTest_LogError("queue argument cannot be NULL");
   123         return NULL;
   124     }
   125     if(!queue->front)
   126     {
   127         SDLTest_LogError("cannot get front of empty queue");
   128         return NULL;
   129     }
   130 
   131     return &queue->front->action;
   132 }
   133 
   134 int
   135 SDLVisualTest_IsActionQueueEmpty(SDLVisualTest_ActionQueue* queue)
   136 {
   137     if(!queue)
   138     {
   139         SDLTest_LogError("queue argument cannot be NULL");
   140         return 1;
   141     }
   142 
   143     if(queue->size > 0)
   144         return 0;
   145     return 1;
   146 }
   147 
   148 void
   149 SDLVisualTest_EmptyActionQueue(SDLVisualTest_ActionQueue* queue)
   150 {
   151     if(queue)
   152     {
   153         while(!SDLVisualTest_IsActionQueueEmpty(queue))
   154             SDLVisualTest_DequeueAction(queue);
   155     }
   156 }
   157 
   158 /* Since the size of the queue is not likely to be larger than 100 elements
   159    we can get away with using insertion sort. */
   160 static void
   161 SortQueue(SDLVisualTest_ActionQueue* queue)
   162 {
   163     SDLVisualTest_ActionNode* head;
   164     SDLVisualTest_ActionNode* tail;
   165 
   166     if(!queue || SDLVisualTest_IsActionQueueEmpty(queue))
   167         return;
   168 
   169     head = queue->front;
   170     for(tail = head; tail && tail->next;)
   171     {
   172         SDLVisualTest_ActionNode* pos;
   173         SDLVisualTest_ActionNode* element = tail->next;
   174 
   175         if(element->action.time < head->action.time)
   176         {
   177             tail->next = tail->next->next;
   178             element->next = head;
   179             head = element;
   180         }
   181         else if(element->action.time >= tail->action.time)
   182         {
   183             tail = tail->next;
   184         }
   185         else
   186         {
   187             for(pos = head;
   188                 (pos->next->action.time < element->action.time);
   189                 pos = pos->next);
   190             tail->next = tail->next->next;
   191             element->next = pos->next;
   192             pos->next = element;
   193         }
   194     }
   195 
   196     queue->front = head;
   197     queue->rear = tail;
   198 }
   199 
   200 int
   201 SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue,
   202                                     SDLVisualTest_Action action)
   203 {
   204     SDLVisualTest_ActionNode* n;
   205     SDLVisualTest_ActionNode* prev;
   206     SDLVisualTest_ActionNode* newnode;
   207     if(!queue)
   208     {
   209         SDLTest_LogError("queue argument cannot be NULL");
   210         return 0;
   211     }
   212 
   213     if(SDLVisualTest_IsActionQueueEmpty(queue))
   214     {
   215         if(!SDLVisualTest_EnqueueAction(queue, action))
   216         {
   217             SDLTest_LogError("SDLVisualTest_EnqueueAction() failed");
   218             return 0;
   219         }
   220         return 1;
   221     }
   222 
   223     newnode = (SDLVisualTest_ActionNode*)malloc(sizeof(SDLVisualTest_ActionNode));
   224     if(!newnode)
   225     {
   226         SDLTest_LogError("malloc() failed");
   227         return 0;
   228     }
   229     newnode->action = action;
   230 
   231     queue->size++;
   232     for(n = queue->front, prev = NULL; n; n = n->next)
   233     {
   234         if(action.time < n->action.time)
   235         {
   236             if(prev)
   237             {
   238                 prev->next = newnode;
   239                 newnode->next = n;
   240             }
   241             else
   242             {
   243                 newnode->next = queue->front;
   244                 queue->front = newnode;
   245             }
   246             return 1;
   247         }
   248         prev = n;
   249     }
   250 
   251     queue->rear->next = newnode;
   252     newnode->next = NULL;
   253     queue->rear = newnode;
   254 
   255     return 1;
   256 }
   257 
   258 int
   259 SDLVisualTest_ParseActionConfig(char* file, SDLVisualTest_ActionQueue* queue)
   260 {
   261     char line[MAX_ACTION_LINE_LENGTH];
   262     SDLVisualTest_RWHelperBuffer buffer;
   263     char* token_ptr;
   264     int linenum;
   265     SDL_RWops* rw;
   266 
   267     if(!file)
   268     {
   269         SDLTest_LogError("file argument cannot be NULL");
   270         return 0;
   271     }
   272     if(!queue)
   273     {
   274         SDLTest_LogError("queue argument cannot be NULL");
   275         return 0;
   276     }
   277 
   278     rw = SDL_RWFromFile(file, "r");
   279     if(!rw)
   280     {
   281         SDLTest_LogError("SDL_RWFromFile() failed");
   282         return 0;
   283     }
   284 
   285     SDLVisualTest_RWHelperResetBuffer(&buffer);
   286     SDLVisualTest_InitActionQueue(queue);
   287     linenum = 0;
   288     while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_ACTION_LINE_LENGTH,
   289                                          &buffer, '#'))
   290     {
   291         SDLVisualTest_Action action;
   292         int hr, min, sec;
   293 
   294         /* parse time */
   295         token_ptr = strtok(line, " ");
   296         if(!token_ptr ||
   297            (SDL_sscanf(token_ptr, "%d:%d:%d", &hr, &min, &sec) != 3))
   298         {
   299             SDLTest_LogError("Could not parse time token at line: %d",
   300                              linenum);
   301             SDLVisualTest_EmptyActionQueue(queue);
   302             SDL_RWclose(rw);
   303             return 0;
   304         }
   305         action.time = (((hr * 60 + min) * 60) + sec) * 1000;
   306 
   307         /* parse type */
   308         token_ptr = strtok(NULL, " ");
   309         if(SDL_strcasecmp(token_ptr, "launch") == 0)
   310             action.type = SDL_ACTION_LAUNCH;
   311         else if(SDL_strcasecmp(token_ptr, "kill") == 0)
   312             action.type = SDL_ACTION_KILL;
   313         else if(SDL_strcasecmp(token_ptr, "quit") == 0)
   314             action.type = SDL_ACTION_QUIT;
   315         else if(SDL_strcasecmp(token_ptr, "screenshot") == 0)
   316             action.type = SDL_ACTION_SCREENSHOT;
   317         else if(SDL_strcasecmp(token_ptr, "verify") == 0)
   318             action.type = SDL_ACTION_VERIFY;
   319         else
   320         {
   321             SDLTest_LogError("Could not parse type token at line: %d",
   322                              linenum);
   323             SDLVisualTest_EmptyActionQueue(queue);
   324             SDL_RWclose(rw);
   325             return 0;
   326         }
   327 
   328         /* parse the extra field */
   329         if(action.type == SDL_ACTION_LAUNCH)
   330         {
   331             int len;
   332             char* args;
   333             char* path;
   334             token_ptr = strtok(NULL, " ");
   335             len = token_ptr ? SDL_strlen(token_ptr) : 0;
   336             if(len <= 0)
   337             {
   338                 SDLTest_LogError("Please specify the process to launch at line: %d",
   339                                  linenum);
   340                 SDLVisualTest_EmptyActionQueue(queue);
   341                 SDL_RWclose(rw);
   342                 return 0;
   343             }
   344             path = (char*)SDL_malloc(sizeof(char) * (len + 1));
   345             if(!path)
   346             {
   347                 SDLTest_LogError("malloc() failed");
   348                 SDLVisualTest_EmptyActionQueue(queue);
   349                 SDL_RWclose(rw);
   350                 return 0;
   351             }
   352             SDL_strlcpy(path, token_ptr, len + 1);
   353 
   354             token_ptr = strtok(NULL, "");
   355             len = token_ptr ? SDL_strlen(token_ptr) : 0;
   356             if(len > 0)
   357             {
   358                 args = (char*)SDL_malloc(sizeof(char) * (len + 1));
   359                 if(!args)
   360                 {
   361                     SDLTest_LogError("malloc() failed");
   362                     SDL_free(path);
   363                     SDLVisualTest_EmptyActionQueue(queue);
   364                     SDL_RWclose(rw);
   365                     return 0;
   366                 }
   367                 SDL_strlcpy(args, token_ptr, len + 1);
   368             }
   369             else
   370                 args = NULL;
   371 
   372             action.extra.process.path = path;
   373             action.extra.process.args = args;
   374         }
   375 
   376         /* add the action to the queue */
   377         if(!SDLVisualTest_EnqueueAction(queue, action))
   378         {
   379             SDLTest_LogError("SDLVisualTest_EnqueueAction() failed");
   380             if(action.type == SDL_ACTION_LAUNCH)
   381             {
   382                 SDL_free(action.extra.process.path);
   383                 if(action.extra.process.args)
   384                     SDL_free(action.extra.process.args);
   385             }
   386             SDLVisualTest_EmptyActionQueue(queue);
   387             SDL_RWclose(rw);
   388             return 0;
   389         }
   390     }
   391     /* sort the queue of actions */
   392     SortQueue(queue);
   393 
   394     SDL_RWclose(rw);
   395     return 1;
   396 }