test/testgl2.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 05 Oct 2013 19:09:03 -0700
changeset 7787 e6f3e8fc96ea
parent 7746 6a05d7352575
child 8062 4fc5f66d63cc
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@1914
    12
#include <stdlib.h>
slouken@1914
    13
#include <stdio.h>
slouken@1914
    14
#include <string.h>
slouken@1914
    15
#include <math.h>
slouken@1914
    16
slouken@6785
    17
#include "SDL_test_common.h"
slouken@1914
    18
slouken@1914
    19
#ifdef __MACOS__
slouken@1914
    20
#define HAVE_OPENGL
slouken@1914
    21
#endif
slouken@1914
    22
slouken@1914
    23
#ifdef HAVE_OPENGL
slouken@1914
    24
slouken@1914
    25
#include "SDL_opengl.h"
slouken@1914
    26
slouken@1914
    27
/* Undefine this if you want a flat cube instead of a rainbow cube */
slouken@1914
    28
#define SHADED_CUBE
slouken@1914
    29
slouken@6785
    30
static SDLTest_CommonState *state;
slouken@1915
    31
static SDL_GLContext context;
slouken@1914
    32
slouken@1915
    33
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@1915
    34
static void
slouken@1915
    35
quit(int rc)
slouken@1914
    36
{
slouken@1915
    37
    if (context) {
bob@2328
    38
        /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
slouken@1915
    39
        SDL_GL_DeleteContext(context);
slouken@1914
    40
    }
slouken@6785
    41
    SDLTest_CommonQuit(state);
slouken@1915
    42
    exit(rc);
slouken@1914
    43
}
slouken@1914
    44
slouken@1915
    45
static void
slouken@1915
    46
Render()
slouken@1914
    47
{
slouken@1915
    48
    static float color[8][3] = {
slouken@1915
    49
        {1.0, 1.0, 0.0},
slouken@1915
    50
        {1.0, 0.0, 0.0},
slouken@1915
    51
        {0.0, 0.0, 0.0},
slouken@1915
    52
        {0.0, 1.0, 0.0},
slouken@1915
    53
        {0.0, 1.0, 1.0},
slouken@1915
    54
        {1.0, 1.0, 1.0},
slouken@1915
    55
        {1.0, 0.0, 1.0},
slouken@1915
    56
        {0.0, 0.0, 1.0}
slouken@1915
    57
    };
slouken@1915
    58
    static float cube[8][3] = {
slouken@1915
    59
        {0.5, 0.5, -0.5},
slouken@1915
    60
        {0.5, -0.5, -0.5},
slouken@1915
    61
        {-0.5, -0.5, -0.5},
slouken@1915
    62
        {-0.5, 0.5, -0.5},
slouken@1915
    63
        {-0.5, 0.5, 0.5},
slouken@1915
    64
        {0.5, 0.5, 0.5},
slouken@1915
    65
        {0.5, -0.5, 0.5},
slouken@1915
    66
        {-0.5, -0.5, 0.5}
slouken@1915
    67
    };
slouken@1914
    68
slouken@1915
    69
    /* Do our drawing, too. */
slouken@1915
    70
    glClearColor(0.0, 0.0, 0.0, 1.0);
slouken@1915
    71
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
slouken@1914
    72
slouken@1915
    73
    glBegin(GL_QUADS);
slouken@1915
    74
slouken@1915
    75
#ifdef SHADED_CUBE
slouken@1915
    76
    glColor3fv(color[0]);
slouken@1915
    77
    glVertex3fv(cube[0]);
slouken@1915
    78
    glColor3fv(color[1]);
slouken@1915
    79
    glVertex3fv(cube[1]);
slouken@1915
    80
    glColor3fv(color[2]);
slouken@1915
    81
    glVertex3fv(cube[2]);
slouken@1915
    82
    glColor3fv(color[3]);
slouken@1915
    83
    glVertex3fv(cube[3]);
slouken@1915
    84
slouken@1915
    85
    glColor3fv(color[3]);
slouken@1915
    86
    glVertex3fv(cube[3]);
slouken@1915
    87
    glColor3fv(color[4]);
slouken@1915
    88
    glVertex3fv(cube[4]);
slouken@1915
    89
    glColor3fv(color[7]);
slouken@1915
    90
    glVertex3fv(cube[7]);
slouken@1915
    91
    glColor3fv(color[2]);
slouken@1915
    92
    glVertex3fv(cube[2]);
slouken@1915
    93
slouken@1915
    94
    glColor3fv(color[0]);
slouken@1915
    95
    glVertex3fv(cube[0]);
slouken@1915
    96
    glColor3fv(color[5]);
slouken@1915
    97
    glVertex3fv(cube[5]);
slouken@1915
    98
    glColor3fv(color[6]);
slouken@1915
    99
    glVertex3fv(cube[6]);
slouken@1915
   100
    glColor3fv(color[1]);
slouken@1915
   101
    glVertex3fv(cube[1]);
slouken@1915
   102
slouken@1915
   103
    glColor3fv(color[5]);
slouken@1915
   104
    glVertex3fv(cube[5]);
slouken@1915
   105
    glColor3fv(color[4]);
slouken@1915
   106
    glVertex3fv(cube[4]);
slouken@1915
   107
    glColor3fv(color[7]);
slouken@1915
   108
    glVertex3fv(cube[7]);
slouken@1915
   109
    glColor3fv(color[6]);
slouken@1915
   110
    glVertex3fv(cube[6]);
slouken@1915
   111
slouken@1915
   112
    glColor3fv(color[5]);
slouken@1915
   113
    glVertex3fv(cube[5]);
slouken@1915
   114
    glColor3fv(color[0]);
slouken@1915
   115
    glVertex3fv(cube[0]);
slouken@1915
   116
    glColor3fv(color[3]);
slouken@1915
   117
    glVertex3fv(cube[3]);
slouken@1915
   118
    glColor3fv(color[4]);
slouken@1915
   119
    glVertex3fv(cube[4]);
slouken@1915
   120
slouken@1915
   121
    glColor3fv(color[6]);
slouken@1915
   122
    glVertex3fv(cube[6]);
slouken@1915
   123
    glColor3fv(color[1]);
slouken@1915
   124
    glVertex3fv(cube[1]);
slouken@1915
   125
    glColor3fv(color[2]);
slouken@1915
   126
    glVertex3fv(cube[2]);
slouken@1915
   127
    glColor3fv(color[7]);
slouken@1915
   128
    glVertex3fv(cube[7]);
slouken@1915
   129
#else /* flat cube */
slouken@1915
   130
    glColor3f(1.0, 0.0, 0.0);
slouken@1915
   131
    glVertex3fv(cube[0]);
slouken@1915
   132
    glVertex3fv(cube[1]);
slouken@1915
   133
    glVertex3fv(cube[2]);
slouken@1915
   134
    glVertex3fv(cube[3]);
slouken@1915
   135
slouken@1915
   136
    glColor3f(0.0, 1.0, 0.0);
slouken@1915
   137
    glVertex3fv(cube[3]);
slouken@1915
   138
    glVertex3fv(cube[4]);
slouken@1915
   139
    glVertex3fv(cube[7]);
slouken@1915
   140
    glVertex3fv(cube[2]);
slouken@1915
   141
slouken@1915
   142
    glColor3f(0.0, 0.0, 1.0);
slouken@1915
   143
    glVertex3fv(cube[0]);
slouken@1915
   144
    glVertex3fv(cube[5]);
slouken@1915
   145
    glVertex3fv(cube[6]);
slouken@1915
   146
    glVertex3fv(cube[1]);
slouken@1915
   147
slouken@1915
   148
    glColor3f(0.0, 1.0, 1.0);
slouken@1915
   149
    glVertex3fv(cube[5]);
slouken@1915
   150
    glVertex3fv(cube[4]);
slouken@1915
   151
    glVertex3fv(cube[7]);
slouken@1915
   152
    glVertex3fv(cube[6]);
slouken@1915
   153
slouken@1915
   154
    glColor3f(1.0, 1.0, 0.0);
slouken@1915
   155
    glVertex3fv(cube[5]);
slouken@1915
   156
    glVertex3fv(cube[0]);
slouken@1915
   157
    glVertex3fv(cube[3]);
slouken@1915
   158
    glVertex3fv(cube[4]);
slouken@1915
   159
slouken@1915
   160
    glColor3f(1.0, 0.0, 1.0);
slouken@1915
   161
    glVertex3fv(cube[6]);
slouken@1915
   162
    glVertex3fv(cube[1]);
slouken@1915
   163
    glVertex3fv(cube[2]);
slouken@1915
   164
    glVertex3fv(cube[7]);
slouken@1915
   165
#endif /* SHADED_CUBE */
slouken@1915
   166
slouken@1915
   167
    glEnd();
slouken@1915
   168
slouken@1915
   169
    glMatrixMode(GL_MODELVIEW);
slouken@1915
   170
    glRotatef(5.0, 1.0, 1.0, 1.0);
slouken@1914
   171
}
slouken@1914
   172
slouken@1914
   173
int
slouken@1915
   174
main(int argc, char *argv[])
slouken@1914
   175
{
slouken@3571
   176
    int fsaa, accel;
slouken@1915
   177
    int value;
slouken@1915
   178
    int i, done;
slouken@1967
   179
    SDL_DisplayMode mode;
slouken@1915
   180
    SDL_Event event;
slouken@1915
   181
    Uint32 then, now, frames;
slouken@3099
   182
    int status;
urkle@7746
   183
    int dw, dh;
slouken@1914
   184
aschiffler@7639
   185
    /* Enable standard application logging */
aschiffler@7639
   186
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   187
slouken@1915
   188
    /* Initialize parameters */
slouken@1915
   189
    fsaa = 0;
slouken@3571
   190
    accel = -1;
slouken@1915
   191
slouken@1915
   192
    /* Initialize test framework */
slouken@6785
   193
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@1915
   194
    if (!state) {
slouken@1915
   195
        return 1;
slouken@1915
   196
    }
slouken@1915
   197
    for (i = 1; i < argc;) {
slouken@1915
   198
        int consumed;
slouken@1915
   199
slouken@6785
   200
        consumed = SDLTest_CommonArg(state, i);
slouken@1915
   201
        if (consumed == 0) {
urkle@7381
   202
            if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) {
urkle@7381
   203
                fsaa = atoi(argv[i+1]);
urkle@7381
   204
                consumed = 2;
slouken@3571
   205
            } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) {
slouken@3571
   206
                accel = atoi(argv[i+1]);
slouken@3571
   207
                consumed = 2;
slouken@1915
   208
            } else {
slouken@1915
   209
                consumed = -1;
slouken@1915
   210
            }
slouken@1914
   211
        }
slouken@1915
   212
        if (consumed < 0) {
aschiffler@7639
   213
            SDL_Log("Usage: %s %s [--fsaa n] [--accel n]\n", argv[0],
slouken@6785
   214
                    SDLTest_CommonUsage(state));
slouken@1915
   215
            quit(1);
slouken@1914
   216
        }
slouken@1915
   217
        i += consumed;
slouken@1914
   218
    }
slouken@1914
   219
slouken@1915
   220
    /* Set OpenGL parameters */
slouken@1915
   221
    state->window_flags |= SDL_WINDOW_OPENGL;
lestat@3408
   222
    state->gl_red_size = 5;
lestat@3408
   223
    state->gl_green_size = 5;
lestat@3408
   224
    state->gl_blue_size = 5;
lestat@3408
   225
    state->gl_depth_size = 16;
slouken@3418
   226
    state->gl_double_buffer = 1;
slouken@1914
   227
    if (fsaa) {
lestat@3408
   228
        state->gl_multisamplebuffers = 1;
lestat@3408
   229
        state->gl_multisamplesamples = fsaa;
slouken@1914
   230
    }
slouken@3571
   231
    if (accel >= 0) {
slouken@3571
   232
        state->gl_accelerated = accel;
slouken@3571
   233
    }
lestat@3408
   234
slouken@6785
   235
    if (!SDLTest_CommonInit(state)) {
slouken@1915
   236
        quit(2);
slouken@1914
   237
    }
slouken@1915
   238
slouken@1915
   239
    /* Create OpenGL context */
slouken@1915
   240
    context = SDL_GL_CreateContext(state->windows[0]);
slouken@1915
   241
    if (!context) {
aschiffler@7639
   242
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError());
slouken@1915
   243
        quit(2);
slouken@1915
   244
    }
slouken@1915
   245
slouken@1965
   246
    if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
icculus@6382
   247
        /* try late-swap-tearing first. If not supported, try normal vsync. */
icculus@6382
   248
        if (SDL_GL_SetSwapInterval(-1) == -1) {
icculus@6382
   249
            SDL_GL_SetSwapInterval(1);
icculus@6382
   250
        }
slouken@1914
   251
    } else {
icculus@6382
   252
        SDL_GL_SetSwapInterval(0);  /* disable vsync. */
slouken@1914
   253
    }
slouken@1914
   254
slouken@5244
   255
    SDL_GetCurrentDisplayMode(0, &mode);
aschiffler@7639
   256
    SDL_Log("Screen BPP    : %d\n", SDL_BITSPERPIXEL(mode.format));
aschiffler@7639
   257
    SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval());
urkle@7746
   258
    SDL_GetWindowSize(state->windows[0], &dw, &dh);
urkle@7746
   259
    SDL_Log("Window Size   : %d,%d\n", dw, dh);
urkle@7746
   260
    SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh);
urkle@7746
   261
    SDL_Log("Draw Size     : %d,%d\n", dw, dh);
aschiffler@7639
   262
    SDL_Log("\n");
aschiffler@7639
   263
    SDL_Log("Vendor        : %s\n", glGetString(GL_VENDOR));
aschiffler@7639
   264
    SDL_Log("Renderer      : %s\n", glGetString(GL_RENDERER));
aschiffler@7639
   265
    SDL_Log("Version       : %s\n", glGetString(GL_VERSION));
aschiffler@7639
   266
    SDL_Log("Extensions    : %s\n", glGetString(GL_EXTENSIONS));
aschiffler@7639
   267
    SDL_Log("\n");
slouken@1914
   268
slouken@3139
   269
    status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
slouken@3099
   270
    if (!status) {
aschiffler@7639
   271
        SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value);
slouken@3099
   272
    } else {
aschiffler@7639
   273
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", SDL_GetError());
slouken@3099
   274
    }
slouken@3139
   275
    status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value);
slouken@3099
   276
    if (!status) {
aschiffler@7639
   277
        SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value);
slouken@3099
   278
    } else {
aschiffler@7639
   279
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", SDL_GetError());
slouken@3099
   280
    }
slouken@3139
   281
    status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
slouken@3099
   282
    if (!status) {
aschiffler@7639
   283
        SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value);
slouken@3099
   284
    } else {
aschiffler@7639
   285
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", SDL_GetError());
slouken@3099
   286
    }
slouken@3139
   287
    status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
slouken@3099
   288
    if (!status) {
aschiffler@7639
   289
        SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", 16, value);
slouken@3099
   290
    } else {
aschiffler@7639
   291
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError());
slouken@3099
   292
    }
slouken@1914
   293
    if (fsaa) {
slouken@3139
   294
        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value);
slouken@3099
   295
        if (!status) {
aschiffler@7639
   296
            SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value);
slouken@3099
   297
        } else {
aschiffler@7639
   298
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n",
slouken@3139
   299
                   SDL_GetError());
slouken@3099
   300
        }
slouken@3139
   301
        status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value);
slouken@3099
   302
        if (!status) {
aschiffler@7639
   303
            SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa,
slouken@3139
   304
                   value);
slouken@3099
   305
        } else {
aschiffler@7639
   306
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n",
slouken@3139
   307
                   SDL_GetError());
slouken@3099
   308
        }
slouken@1914
   309
    }
slouken@3571
   310
    if (accel >= 0) {
slouken@3571
   311
        status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value);
slouken@3571
   312
        if (!status) {
aschiffler@7639
   313
            SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel,
slouken@3571
   314
                   value);
slouken@3571
   315
        } else {
aschiffler@7639
   316
			SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n",
slouken@3571
   317
                   SDL_GetError());
slouken@3571
   318
        }
slouken@1914
   319
    }
slouken@1915
   320
slouken@1915
   321
    /* Set rendering settings */
slouken@1915
   322
    glMatrixMode(GL_PROJECTION);
slouken@1915
   323
    glLoadIdentity();
slouken@1915
   324
    glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0);
slouken@1915
   325
    glMatrixMode(GL_MODELVIEW);
slouken@1915
   326
    glLoadIdentity();
slouken@1915
   327
    glEnable(GL_DEPTH_TEST);
slouken@1915
   328
    glDepthFunc(GL_LESS);
slouken@1915
   329
    glShadeModel(GL_SMOOTH);
urkle@7746
   330
    
slouken@1915
   331
    /* Main render loop */
slouken@1915
   332
    frames = 0;
slouken@1915
   333
    then = SDL_GetTicks();
slouken@1915
   334
    done = 0;
slouken@1915
   335
    while (!done) {
slouken@1915
   336
        /* Check for events */
slouken@1915
   337
        ++frames;
slouken@1915
   338
        while (SDL_PollEvent(&event)) {
slouken@6785
   339
            SDLTest_CommonEvent(state, &event, &done);
slouken@1915
   340
        }
slouken@1915
   341
        for (i = 0; i < state->num_windows; ++i) {
slouken@1915
   342
            int w, h;
slouken@7787
   343
            if (state->windows[i] == NULL)
slouken@7787
   344
                continue;
slouken@1915
   345
            SDL_GL_MakeCurrent(state->windows[i], context);
urkle@7746
   346
            SDL_GL_GetDrawableSize(state->windows[i], &w, &h);
slouken@1915
   347
            glViewport(0, 0, w, h);
slouken@1915
   348
            Render();
slouken@1915
   349
            SDL_GL_SwapWindow(state->windows[i]);
slouken@1915
   350
        }
slouken@1914
   351
    }
slouken@1914
   352
slouken@1915
   353
    /* Print out some timing information */
slouken@1915
   354
    now = SDL_GetTicks();
slouken@1915
   355
    if (now > then) {
aschiffler@7639
   356
        SDL_Log("%2.2f frames per second\n",
slouken@1915
   357
               ((double) frames * 1000) / (now - then));
slouken@1914
   358
    }
slouken@1915
   359
    quit(0);
slouken@2232
   360
    return 0;
slouken@1914
   361
}
slouken@1914
   362
slouken@1914
   363
#else /* HAVE_OPENGL */
slouken@1914
   364
slouken@1914
   365
int
slouken@1914
   366
main(int argc, char *argv[])
slouken@1914
   367
{
aschiffler@7639
   368
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n");
slouken@1914
   369
    return 1;
slouken@1914
   370
}
slouken@1914
   371
slouken@1914
   372
#endif /* HAVE_OPENGL */