test/testgles.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 05 Oct 2013 19:09:03 -0700
changeset 7787 e6f3e8fc96ea
parent 7639 9406b7dd2f2d
child 7794 7995e0920bf9
permissions -rw-r--r--
Fixed bug 2132 - Tests may use invalid SDL_window pointers when windows are closed

norfanin

Some of the tests keep using the pointers of a destroyed SDL_Window when the common event handling handled the close event. The event handler itself does not NULL the pointer after the destruction.

The attached patch adds a loop in the handler that will assign NULL to the destroyed window. It also adds checks to some of the tests so they skip those windows by checking for NULL.
slouken@5535
     1
/*
slouken@7517
     2
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@2765
    12
#include <stdlib.h>
slouken@2765
    13
#include <stdio.h>
slouken@2765
    14
#include <string.h>
slouken@2765
    15
#include <math.h>
slouken@2765
    16
slouken@6785
    17
#include "SDL_test_common.h"
slouken@2765
    18
slouken@4961
    19
#if defined(__IPHONEOS__) || defined(__ANDROID__)
slouken@2765
    20
#define HAVE_OPENGLES
slouken@2765
    21
#endif
slouken@2765
    22
slouken@2765
    23
#ifdef HAVE_OPENGLES
slouken@2765
    24
slouken@2765
    25
#include "SDL_opengles.h"
slouken@2765
    26
slouken@6785
    27
static SDLTest_CommonState *state;
slouken@3139
    28
static SDL_GLContext *context = NULL;
lestat@3408
    29
static int depth = 16;
slouken@2765
    30
slouken@2765
    31
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@2765
    32
static void
slouken@2765
    33
quit(int rc)
slouken@2765
    34
{
lestat@3110
    35
    int i;
lestat@3110
    36
slouken@3139
    37
    if (context != NULL) {
slouken@3139
    38
        for (i = 0; i < state->num_windows; i++) {
lestat@3110
    39
            if (context[i]) {
lestat@3110
    40
                SDL_GL_DeleteContext(context[i]);
lestat@3110
    41
            }
lestat@3110
    42
        }
lestat@3110
    43
lestat@3110
    44
        SDL_free(context);
slouken@2765
    45
    }
lestat@3110
    46
slouken@6785
    47
    SDLTest_CommonQuit(state);
slouken@2765
    48
    exit(rc);
slouken@2765
    49
}
slouken@2765
    50
slouken@2765
    51
static void
slouken@2765
    52
Render()
slouken@2765
    53
{
slouken@2765
    54
    static GLubyte color[8][4] = { {255, 0, 0, 0},
slouken@2765
    55
    {255, 0, 0, 255},
slouken@2765
    56
    {0, 255, 0, 255},
slouken@2765
    57
    {0, 255, 0, 255},
slouken@2765
    58
    {0, 255, 0, 255},
slouken@2765
    59
    {255, 255, 255, 255},
slouken@2765
    60
    {255, 0, 255, 255},
slouken@2765
    61
    {0, 0, 255, 255}
slouken@2765
    62
    };
slouken@2765
    63
    static GLfloat cube[8][3] = { {0.5, 0.5, -0.5},
slouken@2765
    64
    {0.5f, -0.5f, -0.5f},
slouken@2765
    65
    {-0.5f, -0.5f, -0.5f},
slouken@2765
    66
    {-0.5f, 0.5f, -0.5f},
slouken@2765
    67
    {-0.5f, 0.5f, 0.5f},
slouken@2765
    68
    {0.5f, 0.5f, 0.5f},
slouken@2765
    69
    {0.5f, -0.5f, 0.5f},
slouken@2765
    70
    {-0.5f, -0.5f, 0.5f}
slouken@2765
    71
    };
slouken@2765
    72
    static GLubyte indices[36] = { 0, 3, 4,
slouken@2765
    73
        4, 5, 0,
slouken@2765
    74
        0, 5, 6,
slouken@2765
    75
        6, 1, 0,
slouken@2765
    76
        6, 7, 2,
slouken@2765
    77
        2, 1, 6,
slouken@2765
    78
        7, 4, 3,
slouken@2765
    79
        3, 2, 7,
slouken@2765
    80
        5, 4, 7,
slouken@2765
    81
        7, 6, 5,
slouken@2765
    82
        2, 3, 1,
slouken@2765
    83
        3, 0, 1
slouken@2765
    84
    };
slouken@2765
    85
slouken@2765
    86
slouken@2765
    87
    /* Do our drawing, too. */
slouken@2765
    88
    glClearColor(0.0, 0.0, 0.0, 1.0);
slouken@2765
    89
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
slouken@2765
    90
slouken@2765
    91
    /* Draw the cube */
slouken@2765
    92
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, color);
slouken@2765
    93
    glEnableClientState(GL_COLOR_ARRAY);
slouken@2765
    94
    glVertexPointer(3, GL_FLOAT, 0, cube);
slouken@2765
    95
    glEnableClientState(GL_VERTEX_ARRAY);
slouken@2765
    96
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
slouken@2765
    97
slouken@2765
    98
    glMatrixMode(GL_MODELVIEW);
slouken@2765
    99
    glRotatef(5.0, 1.0, 1.0, 1.0);
slouken@2765
   100
}
slouken@2765
   101
slouken@2765
   102
int
slouken@2765
   103
main(int argc, char *argv[])
slouken@2765
   104
{
slouken@2765
   105
    int fsaa, accel;
slouken@2765
   106
    int value;
slouken@2765
   107
    int i, done;
slouken@2765
   108
    SDL_DisplayMode mode;
slouken@2765
   109
    SDL_Event event;
slouken@2765
   110
    Uint32 then, now, frames;
slouken@3099
   111
    int status;
slouken@2765
   112
aschiffler@7639
   113
    /* Enable standard application logging */
aschiffler@7639
   114
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   115
slouken@2765
   116
    /* Initialize parameters */
slouken@2765
   117
    fsaa = 0;
slouken@2765
   118
    accel = 0;
slouken@2765
   119
slouken@2765
   120
    /* Initialize test framework */
slouken@6785
   121
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@2765
   122
    if (!state) {
slouken@2765
   123
        return 1;
slouken@2765
   124
    }
slouken@2765
   125
    for (i = 1; i < argc;) {
slouken@2765
   126
        int consumed;
slouken@2765
   127
slouken@6785
   128
        consumed = SDLTest_CommonArg(state, i);
slouken@2765
   129
        if (consumed == 0) {
slouken@2765
   130
            if (SDL_strcasecmp(argv[i], "--fsaa") == 0) {
slouken@2765
   131
                ++fsaa;
slouken@2765
   132
                consumed = 1;
slouken@2765
   133
            } else if (SDL_strcasecmp(argv[i], "--accel") == 0) {
slouken@2765
   134
                ++accel;
slouken@2765
   135
                consumed = 1;
lestat@3408
   136
            } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) {
lestat@3408
   137
                i++;
lestat@3408
   138
                if (!argv[i]) {
lestat@3408
   139
                    consumed = -1;
lestat@3408
   140
                } else {
lestat@3408
   141
                    depth = SDL_atoi(argv[i]);
lestat@3408
   142
                    consumed = 1;
lestat@3408
   143
                }
slouken@2765
   144
            } else {
slouken@2765
   145
                consumed = -1;
slouken@2765
   146
            }
slouken@2765
   147
        }
slouken@2765
   148
        if (consumed < 0) {
aschiffler@7639
   149
            SDL_Log("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0],
slouken@6785
   150
                    SDLTest_CommonUsage(state));
slouken@2765
   151
            quit(1);
slouken@2765
   152
        }
slouken@2765
   153
        i += consumed;
slouken@2765
   154
    }
slouken@2765
   155
slouken@2765
   156
    /* Set OpenGL parameters */
icculus@5520
   157
    state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
lestat@3408
   158
    state->gl_red_size = 5;
lestat@3408
   159
    state->gl_green_size = 5;
lestat@3408
   160
    state->gl_blue_size = 5;
lestat@3408
   161
    state->gl_depth_size = depth;
slouken@2765
   162
    if (fsaa) {
lestat@3408
   163
        state->gl_multisamplebuffers=1;
lestat@3408
   164
        state->gl_multisamplesamples=fsaa;
slouken@2765
   165
    }
slouken@2765
   166
    if (accel) {
lestat@3408
   167
        state->gl_accelerated=1;
slouken@2765
   168
    }
slouken@6785
   169
    if (!SDLTest_CommonInit(state)) {
slouken@2765
   170
        quit(2);
slouken@2765
   171
    }
slouken@2765
   172
lestat@3398
   173
    context = SDL_calloc(state->num_windows, sizeof(context));
slouken@3139
   174
    if (context == NULL) {
aschiffler@7639
   175
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");
slouken@3139
   176
        quit(2);
lestat@3110
   177
    }
lestat@3110
   178
lestat@3110
   179
    /* Create OpenGL ES contexts */
slouken@3139
   180
    for (i = 0; i < state->num_windows; i++) {
lestat@3110
   181
        context[i] = SDL_GL_CreateContext(state->windows[i]);
lestat@3110
   182
        if (!context[i]) {
aschiffler@7639
   183
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError());
lestat@3110
   184
            quit(2);
lestat@3110
   185
        }
slouken@2765
   186
    }
slouken@2765
   187
slouken@2765
   188
    if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
slouken@2765
   189
        SDL_GL_SetSwapInterval(1);
slouken@2765
   190
    } else {
slouken@2765
   191
        SDL_GL_SetSwapInterval(0);
slouken@2765
   192
    }
slouken@2765
   193
slouken@5363
   194
    SDL_GetCurrentDisplayMode(0, &mode);
aschiffler@7639
   195
    SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format));
aschiffler@7639
   196
    SDL_Log("\n");
aschiffler@7639
   197
    SDL_Log("Vendor     : %s\n", glGetString(GL_VENDOR));
aschiffler@7639
   198
    SDL_Log("Renderer   : %s\n", glGetString(GL_RENDERER));
aschiffler@7639
   199
    SDL_Log("Version    : %s\n", glGetString(GL_VERSION));
aschiffler@7639
   200
    SDL_Log("Extensions : %s\n", glGetString(GL_EXTENSIONS));
aschiffler@7639
   201
    SDL_Log("\n");
slouken@2765
   202
slouken@3139
   203
    status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
slouken@3099
   204
    if (!status) {
aschiffler@7639
   205
        SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
slouken@3099
   206
    } else {
aschiffler@7639
   207
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n",
slouken@3139
   208
                SDL_GetError());
slouken@3099
   209
    }
slouken@3139
   210
    status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
slouken@3099
   211
    if (!status) {
aschiffler@7639
   212
        SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
slouken@3099
   213
    } else {
aschiffler@7639
   214
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n",
slouken@3139
   215
                SDL_GetError());
slouken@3099
   216
    }
slouken@3139
   217
    status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
slouken@3099
   218
    if (!status) {
aschiffler@7639
   219
        SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
slouken@3099
   220
    } else {
aschiffler@7639
   221
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n",
slouken@3139
   222
                SDL_GetError());
slouken@3099
   223
    }
slouken@3139
   224
    status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
slouken@3099
   225
    if (!status) {
aschiffler@7639
   226
        SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value);
slouken@3099
   227
    } else {
aschiffler@7639
   228
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n",
slouken@3139
   229
                SDL_GetError());
slouken@3099
   230
    }
slouken@2765
   231
    if (fsaa) {
slouken@3139
   232
        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
slouken@3099
   233
        if (!status) {
aschiffler@7639
   234
            SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
slouken@3099
   235
        } else {
aschiffler@7639
   236
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
slouken@3139
   237
                    SDL_GetError());
slouken@3099
   238
        }
slouken@3139
   239
        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
slouken@3099
   240
        if (!status) {
aschiffler@7639
   241
            SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
slouken@3139
   242
                   value);
slouken@3099
   243
        } else {
aschiffler@7639
   244
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
slouken@3139
   245
                    SDL_GetError());
slouken@3099
   246
        }
slouken@2765
   247
    }
slouken@2765
   248
    if (accel) {
slouken@3139
   249
        status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
slouken@3139
   250
        if (!status) {
aschiffler@7639
   251
            SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value);
slouken@3099
   252
        } else {
aschiffler@7639
   253
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
slouken@3139
   254
                    SDL_GetError());
slouken@3099
   255
        }
slouken@2765
   256
    }
slouken@2765
   257
lestat@3110
   258
    /* Set rendering settings for each context */
lestat@3110
   259
    for (i = 0; i < state->num_windows; ++i) {
slouken@5363
   260
        float aspectAdjust;
slouken@5363
   261
slouken@3139
   262
        status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
slouken@3139
   263
        if (status) {
aschiffler@7639
   264
            SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
lestat@3110
   265
lestat@3110
   266
            /* Continue for next window */
lestat@3110
   267
            continue;
lestat@3110
   268
        }
lestat@3110
   269
slouken@5363
   270
        aspectAdjust = (4.0f / 3.0f) / ((float)state->window_w / state->window_h);
lestat@3397
   271
        glViewport(0, 0, state->window_w, state->window_h);
lestat@3110
   272
        glMatrixMode(GL_PROJECTION);
lestat@3110
   273
        glLoadIdentity();
slouken@5363
   274
        glOrthof(-2.0, 2.0, -2.0 * aspectAdjust, 2.0 * aspectAdjust, -20.0, 20.0);
lestat@3110
   275
        glMatrixMode(GL_MODELVIEW);
lestat@3110
   276
        glLoadIdentity();
lestat@3110
   277
        glEnable(GL_DEPTH_TEST);
lestat@3110
   278
        glDepthFunc(GL_LESS);
lestat@3110
   279
        glShadeModel(GL_SMOOTH);
lestat@3110
   280
    }
slouken@2765
   281
slouken@2765
   282
    /* Main render loop */
slouken@2765
   283
    frames = 0;
slouken@2765
   284
    then = SDL_GetTicks();
slouken@2765
   285
    done = 0;
slouken@2765
   286
    while (!done) {
slouken@2765
   287
        /* Check for events */
slouken@2765
   288
        ++frames;
slouken@2765
   289
        while (SDL_PollEvent(&event)) {
lestat@3194
   290
            switch (event.type) {
lestat@3194
   291
            case SDL_WINDOWEVENT:
lestat@3194
   292
                switch (event.window.event) {
lestat@3194
   293
                    case SDL_WINDOWEVENT_RESIZED:
lestat@3194
   294
                        for (i = 0; i < state->num_windows; ++i) {
slouken@5363
   295
                            if (event.window.windowID == SDL_GetWindowID(state->windows[i])) {
lestat@3194
   296
                                status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
lestat@3194
   297
                                if (status) {
aschiffler@7639
   298
                                    SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
lestat@3194
   299
                                    break;
lestat@3194
   300
                                }
lestat@3194
   301
                                /* Change view port to the new window dimensions */
lestat@3194
   302
                                glViewport(0, 0, event.window.data1, event.window.data2);
lestat@3194
   303
                                /* Update window content */
lestat@3194
   304
                                Render();
lestat@3194
   305
                                SDL_GL_SwapWindow(state->windows[i]);
lestat@3194
   306
                                break;
lestat@3194
   307
                            }
lestat@3194
   308
                        }
lestat@3194
   309
                        break;
lestat@3194
   310
                }
lestat@3194
   311
            }
slouken@6785
   312
            SDLTest_CommonEvent(state, &event, &done);
slouken@2765
   313
        }
slouken@2765
   314
        for (i = 0; i < state->num_windows; ++i) {
slouken@7787
   315
            if (state->windows[i] == NULL)
slouken@7787
   316
                continue;
slouken@3139
   317
            status = SDL_GL_MakeCurrent(state->windows[i], context[i]);
slouken@3139
   318
            if (status) {
aschiffler@7639
   319
                SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError());
lestat@3110
   320
slouken@3139
   321
                /* Continue for next window */
slouken@3139
   322
                continue;
lestat@3110
   323
            }
slouken@2765
   324
            Render();
slouken@2765
   325
            SDL_GL_SwapWindow(state->windows[i]);
slouken@2765
   326
        }
slouken@2765
   327
    }
slouken@2765
   328
slouken@2765
   329
    /* Print out some timing information */
slouken@2765
   330
    now = SDL_GetTicks();
slouken@2765
   331
    if (now > then) {
aschiffler@7639
   332
        SDL_Log("%2.2f frames per second\n",
slouken@2765
   333
               ((double) frames * 1000) / (now - then));
slouken@2765
   334
    }
slouken@2765
   335
    quit(0);
slouken@2765
   336
    return 0;
slouken@2765
   337
}
slouken@2765
   338
slouken@2765
   339
#else /* HAVE_OPENGLES */
slouken@2765
   340
slouken@2765
   341
int
slouken@2765
   342
main(int argc, char *argv[])
slouken@2765
   343
{
aschiffler@7639
   344
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL ES support on this system\n");
slouken@2765
   345
    return 1;
slouken@2765
   346
}
slouken@2765
   347
slouken@2765
   348
#endif /* HAVE_OPENGLES */
slouken@5363
   349
slouken@5363
   350
/* vi: set ts=4 sw=4 expandtab: */