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