Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Copyright © 2013 Intel Corporation
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
#include 
24
#include 
25
#include 
26
 
27
extern "C" {
28
#include "glxclient.h"
29
#include "glx_error.h"
30
}
31
 
32
extern bool GetGLXScreenConfigs_called;
33
extern struct glx_screen *psc;
34
 
35
struct attribute_test_vector {
36
   const char *string;
37
   int value;
38
};
39
 
40
#define E(x) { # x, x }
41
 
42
 
43
 
44
static bool got_sigsegv;
45
static jmp_buf jmp;
46
 
47
static void
48
sigsegv_handler(int sig)
49
{
50
   (void) sig;
51
   got_sigsegv = true;
52
   longjmp(jmp, 1);
53
}
54
 
55
static bool query_renderer_string_called = false;
56
static bool query_renderer_integer_called = false;
57
 
58
static int
59
fake_query_renderer_integer(struct glx_screen *psc, int attribute,
60
                            unsigned int *value)
61
{
62
   (void) psc;
63
   (void) attribute;
64
   (void) value;
65
 
66
   query_renderer_integer_called = true;
67
 
68
   return -1;
69
}
70
 
71
static int
72
fake_query_renderer_string(struct glx_screen *psc, int attribute,
73
                           const char **value)
74
{
75
   (void) psc;
76
   (void) attribute;
77
   (void) value;
78
 
79
   query_renderer_string_called = true;
80
 
81
   return -1;
82
}
83
 
84
struct glx_screen_vtable fake_vtable = {
85
   NULL,
86
   NULL,
87
   fake_query_renderer_integer,
88
   fake_query_renderer_string
89
};
90
 
91
class query_renderer_string_test : public ::testing::Test {
92
public:
93
   virtual void SetUp();
94
   virtual void TearDown();
95
 
96
   struct glx_screen scr;
97
   struct sigaction sa;
98
   struct sigaction old_sa;
99
   Display dpy;
100
};
101
 
102
class query_renderer_integer_test : public query_renderer_string_test {
103
};
104
 
105
void query_renderer_string_test::SetUp()
106
{
107
   memset(&scr, 0, sizeof(scr));
108
   scr.vtable = &fake_vtable;
109
   psc = &scr;
110
 
111
   got_sigsegv = false;
112
 
113
   sa.sa_handler = sigsegv_handler;
114
   sigemptyset(&sa.sa_mask);
115
   sa.sa_flags = 0;
116
   sigaction(SIGSEGV, &sa, &old_sa);
117
}
118
 
119
void query_renderer_string_test::TearDown()
120
{
121
   sigaction(SIGSEGV, &old_sa, NULL);
122
}
123
 
124
/**
125
 * glXQueryRendererStringMESA will return \c NULL if the query_render_string
126
 * vtable entry is \c NULL.  It will also not segfault.
127
 */
128
TEST_F(query_renderer_string_test, null_query_render_string)
129
{
130
   struct glx_screen_vtable vtable = {
131
      NULL,
132
      NULL,
133
      NULL,
134
      NULL
135
   };
136
 
137
   scr.vtable = &vtable;
138
 
139
   if (setjmp(jmp) == 0) {
140
      const char *str =
141
         glXQueryRendererStringMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
142
      EXPECT_EQ((char *)0, str);
143
   } else {
144
      EXPECT_FALSE(got_sigsegv);
145
   }
146
}
147
 
148
/**
149
 * glXQueryRendererStringMESA will not call the screen query_render_string
150
 * function with an invalid GLX enum value, and it will return NULL.
151
 */
152
TEST_F(query_renderer_string_test, invalid_attribute)
153
{
154
   static const attribute_test_vector invalid_attributes[] = {
155
      /* These values are just plain invalid for use with this extension.
156
       */
157
      E(0),
158
      E(GLX_VENDOR),
159
      E(GLX_VERSION),
160
      E(GLX_EXTENSIONS),
161
      E(GLX_RENDERER_VENDOR_ID_MESA + 0x10000),
162
      E(GLX_RENDERER_DEVICE_ID_MESA + 0x10000),
163
 
164
      /* These enums are part of the extension, but they are not allowed for
165
       * the string query.
166
       */
167
      E(GLX_RENDERER_VERSION_MESA),
168
      E(GLX_RENDERER_ACCELERATED_MESA),
169
      E(GLX_RENDERER_VIDEO_MEMORY_MESA),
170
      E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA),
171
      E(GLX_RENDERER_PREFERRED_PROFILE_MESA),
172
      E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA),
173
      E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA),
174
      E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA),
175
      E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA),
176
      E(GLX_RENDERER_ID_MESA),
177
   };
178
 
179
   for (unsigned i = 0; i < ARRAY_SIZE(invalid_attributes); i++) {
180
      query_renderer_integer_called = false;
181
      query_renderer_string_called = false;
182
 
183
      const char *str =
184
         glXQueryRendererStringMESA(&dpy, 0, 0, invalid_attributes[i].value);
185
      EXPECT_EQ((char *)0, str) << invalid_attributes[i].string;
186
      EXPECT_FALSE(query_renderer_integer_called)
187
         << invalid_attributes[i].string;
188
      EXPECT_FALSE(query_renderer_string_called)
189
         << invalid_attributes[i].string;
190
   }
191
}
192
 
193
/**
194
 * glXQueryRendererStringMESA will not call GetGLXScreenConfigs if the display
195
 * pointer is \c NULL.  It will also not segfault.
196
 */
197
TEST_F(query_renderer_string_test, null_display_pointer)
198
{
199
   if (setjmp(jmp) == 0) {
200
      GetGLXScreenConfigs_called = false;
201
 
202
      const char *str =
203
         glXQueryRendererStringMESA(NULL, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
204
      EXPECT_EQ((char *)0, str);
205
      EXPECT_FALSE(GetGLXScreenConfigs_called);
206
   } else {
207
      EXPECT_FALSE(got_sigsegv);
208
   }
209
}
210
 
211
/**
212
 * glXQueryRendererStringMESA will return error if GetGLXScreenConfigs returns
213
 * NULL.  It will also not segfault.
214
 */
215
TEST_F(query_renderer_string_test, null_screen_pointer)
216
{
217
   psc = NULL;
218
 
219
   if (setjmp(jmp) == 0) {
220
      GetGLXScreenConfigs_called = false;
221
 
222
      const char *str =
223
         glXQueryRendererStringMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA);
224
      EXPECT_EQ((char *)0, str);
225
      EXPECT_TRUE(GetGLXScreenConfigs_called);
226
   } else {
227
      EXPECT_FALSE(got_sigsegv);
228
   }
229
}
230
 
231
/**
232
 * glXQueryRendererStringMESA will not call the screen query_render_string
233
 * function if the renderer is invalid, and it will return NULL.
234
 */
235
TEST_F(query_renderer_string_test, invalid_renderer_index)
236
{
237
   static const int invalid_renderer_indices[] = {
238
      -1,
239
      1,
240
      999,
241
   };
242
 
243
   if (setjmp(jmp) == 0) {
244
      for (unsigned i = 0; i < ARRAY_SIZE(invalid_renderer_indices); i++) {
245
         const char *str =
246
            glXQueryRendererStringMESA(&dpy, 0,
247
                                       invalid_renderer_indices[i],
248
                                       GLX_RENDERER_VENDOR_ID_MESA);
249
         EXPECT_EQ((char *)0, str) << invalid_renderer_indices[i];
250
         EXPECT_FALSE(query_renderer_integer_called)
251
            << invalid_renderer_indices[i];
252
         EXPECT_FALSE(query_renderer_string_called)
253
            << invalid_renderer_indices[i];
254
      }
255
   } else {
256
      EXPECT_FALSE(got_sigsegv);
257
   }
258
}
259
 
260
/**
261
 * glXQueryCurrentRendererStringMESA will return error if there is no context
262
 * current.  It will also not segfault.
263
 */
264
TEST_F(query_renderer_string_test, no_current_context)
265
{
266
   if (setjmp(jmp) == 0) {
267
      const char *str =
268
         glXQueryCurrentRendererStringMESA(GLX_RENDERER_VENDOR_ID_MESA);
269
      EXPECT_EQ((char *)0, str);
270
   } else {
271
      EXPECT_FALSE(got_sigsegv);
272
   }
273
}
274
 
275
/**
276
 * glXQueryCurrentRendererIntegerMESA will return \c NULL if the
277
 * query_render_string vtable entry is \c NULL.  It will also not segfault.
278
 */
279
TEST_F(query_renderer_integer_test, null_query_render_string)
280
{
281
   struct glx_screen_vtable vtable = {
282
      NULL,
283
      NULL,
284
      NULL,
285
      NULL
286
   };
287
 
288
   scr.vtable = &vtable;
289
 
290
   if (setjmp(jmp) == 0) {
291
      unsigned value = 0xDEADBEEF;
292
      Bool success = glXQueryRendererIntegerMESA(&dpy, 0, 0,
293
                                                 GLX_RENDERER_VENDOR_ID_MESA,
294
                                                 &value);
295
      EXPECT_FALSE(success);
296
      EXPECT_EQ(0xDEADBEEF, value);
297
   } else {
298
      EXPECT_FALSE(got_sigsegv);
299
   }
300
}
301
 
302
/**
303
 * glXQueryCurrentRendererIntegerMESA will not call the screen
304
 * query_render_string function with an invalid GLX enum value, and it will
305
 * return NULL.
306
 */
307
TEST_F(query_renderer_integer_test, invalid_attribute)
308
{
309
   static const attribute_test_vector invalid_attributes[] = {
310
      /* These values are just plain invalid for use with this extension.
311
       */
312
      E(0),
313
      E(GLX_VENDOR),
314
      E(GLX_VERSION),
315
      E(GLX_EXTENSIONS),
316
      E(GLX_RENDERER_VENDOR_ID_MESA + 0x10000),
317
      E(GLX_RENDERER_DEVICE_ID_MESA + 0x10000),
318
      E(GLX_RENDERER_VERSION_MESA + 0x10000),
319
      E(GLX_RENDERER_ACCELERATED_MESA + 0x10000),
320
      E(GLX_RENDERER_VIDEO_MEMORY_MESA + 0x10000),
321
      E(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA + 0x10000),
322
      E(GLX_RENDERER_PREFERRED_PROFILE_MESA + 0x10000),
323
      E(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA + 0x10000),
324
      E(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA + 0x10000),
325
      E(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA + 0x10000),
326
      E(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA + 0x10000),
327
      E(GLX_RENDERER_ID_MESA + 0x10000),
328
   };
329
 
330
   for (unsigned i = 0; i < ARRAY_SIZE(invalid_attributes); i++) {
331
      query_renderer_integer_called = false;
332
      query_renderer_string_called = false;
333
 
334
      unsigned value = 0xDEADBEEF;
335
      Bool success =
336
         glXQueryRendererIntegerMESA(&dpy, 0, 0,
337
                                     invalid_attributes[i].value,
338
                                     &value);
339
      EXPECT_FALSE(success) << invalid_attributes[i].string;
340
      EXPECT_EQ(0xDEADBEEF, value) << invalid_attributes[i].string;
341
      EXPECT_FALSE(query_renderer_integer_called)
342
         << invalid_attributes[i].string;
343
      EXPECT_FALSE(query_renderer_string_called)
344
         << invalid_attributes[i].string;
345
   }
346
}
347
 
348
/**
349
 * glXQueryCurrentRendererIntegerMESA will not call GetGLXScreenConfigs if the
350
 * display pointer is \c NULL.  It will also not segfault.
351
 */
352
TEST_F(query_renderer_integer_test, null_display_pointer)
353
{
354
   if (setjmp(jmp) == 0) {
355
      GetGLXScreenConfigs_called = false;
356
 
357
      unsigned value = 0xDEADBEEF;
358
      Bool success =
359
         glXQueryRendererIntegerMESA(NULL, 0, 0, GLX_RENDERER_VENDOR_ID_MESA,
360
                                     &value);
361
      EXPECT_FALSE(success);
362
      EXPECT_EQ(0xDEADBEEF, value);
363
      EXPECT_FALSE(GetGLXScreenConfigs_called);
364
   } else {
365
      EXPECT_FALSE(got_sigsegv);
366
   }
367
}
368
 
369
/**
370
 * glXQueryCurrentRendererIntegerMESA will return error if GetGLXScreenConfigs
371
 * returns NULL.  It will also not segfault.
372
 */
373
TEST_F(query_renderer_integer_test, null_screen_pointer)
374
{
375
   psc = NULL;
376
 
377
   if (setjmp(jmp) == 0) {
378
      GetGLXScreenConfigs_called = false;
379
 
380
      unsigned value = 0xDEADBEEF;
381
      Bool success =
382
         glXQueryRendererIntegerMESA(&dpy, 0, 0, GLX_RENDERER_VENDOR_ID_MESA,
383
            &value);
384
      EXPECT_FALSE(success);
385
      EXPECT_EQ(0xDEADBEEF, value);
386
      EXPECT_TRUE(GetGLXScreenConfigs_called);
387
   } else {
388
      EXPECT_FALSE(got_sigsegv);
389
   }
390
}
391
 
392
/**
393
 * glXQueryRendererIntegerMESA will not call the screen query_render_integer
394
 * function if the renderer is invalid, and it will return NULL.
395
 */
396
TEST_F(query_renderer_integer_test, invalid_renderer_index)
397
{
398
   static const int invalid_renderer_indices[] = {
399
      -1,
400
      1,
401
      999,
402
   };
403
 
404
   if (setjmp(jmp) == 0) {
405
      for (unsigned i = 0; i < ARRAY_SIZE(invalid_renderer_indices); i++) {
406
         unsigned value = 0xDEADBEEF;
407
         Bool success =
408
            glXQueryRendererIntegerMESA(&dpy, 0,
409
                                        invalid_renderer_indices[i],
410
                                        GLX_RENDERER_VENDOR_ID_MESA,
411
                                        &value);
412
         EXPECT_FALSE(success) << invalid_renderer_indices[i];
413
         EXPECT_EQ(0xDEADBEEF, value) << invalid_renderer_indices[i];
414
         EXPECT_FALSE(query_renderer_integer_called)
415
            << invalid_renderer_indices[i];
416
         EXPECT_FALSE(query_renderer_string_called)
417
            << invalid_renderer_indices[i];
418
      }
419
   } else {
420
      EXPECT_FALSE(got_sigsegv);
421
   }
422
}
423
 
424
/**
425
 * glXQueryCurrentRendererIntegerMESA will return error if there is no context
426
 * current.  It will also not segfault.
427
 */
428
TEST_F(query_renderer_integer_test, no_current_context)
429
{
430
   if (setjmp(jmp) == 0) {
431
      unsigned value = 0xDEADBEEF;
432
      Bool success =
433
         glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VENDOR_ID_MESA,
434
                                            &value);
435
      EXPECT_FALSE(success);
436
      EXPECT_EQ(0xDEADBEEF, value);
437
   } else {
438
      EXPECT_FALSE(got_sigsegv);
439
   }
440
}