jscript: Store concatenated strings as a rope string to avoid useless copying.
[wine] / dlls / winemac.drv / opengl.c
1 /*
2  * Mac driver OpenGL support
3  *
4  * Copyright 2012 Alexandre Julliard
5  * Copyright 2012, 2013 Ken Thomases for CodeWeavers Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include "macdrv.h"
26
27 #include "winuser.h"
28 #include "winternl.h"
29 #include "wine/library.h"
30 #include "wine/debug.h"
31 #include "wine/wgl.h"
32 #include "wine/wgl_driver.h"
33 #include "wine/wglext.h"
34
35 #define __gl_h_
36 #define __gltypes_h_
37 #include <OpenGL/OpenGL.h>
38 #include <OpenGL/glu.h>
39 #include <OpenGL/CGLRenderers.h>
40 #include <dlfcn.h>
41
42 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
43
44
45 struct gl_info {
46     char *glVersion;
47     char *glExtensions;
48
49     char wglExtensions[4096];
50
51     GLint max_viewport_dims[2];
52 };
53
54 static struct gl_info gl_info;
55
56
57 struct wgl_context
58 {
59     HDC                     hdc;
60     int                     format;
61     macdrv_opengl_context   context;
62     CGLContextObj           cglcontext;
63     macdrv_view             draw_view;
64     struct wgl_pbuffer     *draw_pbuffer;
65     macdrv_view             read_view;
66     struct wgl_pbuffer     *read_pbuffer;
67     BOOL                    has_been_current;
68     BOOL                    sharing;
69 };
70
71
72 struct wgl_pbuffer
73 {
74     CGLPBufferObj   pbuffer;
75     int             format;
76     BOOL            no_texture;
77     int             max_level;
78     GLint           level;
79     GLenum          face;
80 };
81
82 static CFMutableDictionaryRef dc_pbuffers;
83
84 static CRITICAL_SECTION dc_pbuffers_section;
85 static CRITICAL_SECTION_DEBUG dc_pbuffers_section_debug =
86 {
87     0, 0, &dc_pbuffers_section,
88     { &dc_pbuffers_section_debug.ProcessLocksList, &dc_pbuffers_section_debug.ProcessLocksList },
89       0, 0, { (DWORD_PTR)(__FILE__ ": dc_pbuffers_section") }
90 };
91 static CRITICAL_SECTION dc_pbuffers_section = { &dc_pbuffers_section_debug, -1, 0, 0, 0, 0 };
92
93
94 static struct opengl_funcs opengl_funcs;
95
96 #define USE_GL_FUNC(name) #name,
97 static const char *opengl_func_names[] = { ALL_WGL_FUNCS };
98 #undef USE_GL_FUNC
99
100
101 static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y,
102                                  GLsizei width);
103 static void (*pglCopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
104 static void (*pglReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height,
105                              GLenum format, GLenum type, void *pixels);
106 static void (*pglViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
107
108
109 struct color_mode {
110     GLint   mode;
111     int     bits_per_pixel;
112     GLint   color_bits; /* including alpha_bits */
113     int     red_bits, red_shift;
114     int     green_bits, green_shift;
115     int     blue_bits, blue_shift;
116     GLint   alpha_bits, alpha_shift;
117     BOOL    is_float;
118     int     color_ordering;
119 };
120
121 /* The value of "color_ordering" is somewhat arbitrary.  It incorporates some
122    observations of the behavior of Windows systems, but also subjective judgments
123    about what color formats are more "normal" than others.
124
125    On at least some Windows systems, integer color formats are listed before
126    floating-point formats.  Within the integer formats, higher color bits were
127    usually listed before lower color bits, while for floating-point formats it
128    was the reverse.  However, that leads D3D to select 64-bit integer formats in
129    preference to 32-bit formats when the latter would be sufficient.  It seems
130    that a 32-bit format is much more likely to be normally used in that case.
131
132    Also, there are certain odd color formats supported on the Mac which seem like
133    they would be less appropriate than more common ones.  For instance, the color
134    formats with alpha in a separate byte (e.g. kCGLRGB888A8Bit with R8G8B8 in one
135    32-bit value and A8 in a separate 8-bit value) and the formats with 10-bit RGB
136    components.
137
138    For two color formats which differ only in whether or not they have alpha bits,
139    we use the same ordering.  pixel_format_comparator() gives alpha bits a
140    different weight than color formats.
141  */
142 static const struct color_mode color_modes[] = {
143     { kCGLRGB444Bit,        16,     12,     4,  8,      4,  4,      4,  0,      0,  0,  FALSE,  5 },
144     { kCGLARGB4444Bit,      16,     16,     4,  8,      4,  4,      4,  0,      4,  12, FALSE,  5 },
145     { kCGLRGB444A8Bit,      24,     20,     4,  8,      4,  4,      4,  0,      8,  16, FALSE,  10 },
146     { kCGLRGB555Bit,        16,     15,     5,  10,     5,  5,      5,  0,      0,  0,  FALSE,  4 },
147     { kCGLARGB1555Bit,      16,     16,     5,  10,     5,  5,      5,  0,      1,  15, FALSE,  4 },
148     { kCGLRGB555A8Bit,      24,     23,     5,  10,     5,  5,      5,  0,      8,  16, FALSE,  9 },
149     { kCGLRGB565Bit,        16,     16,     5,  11,     6,  5,      5,  0,      0,  0,  FALSE,  3 },
150     { kCGLRGB565A8Bit,      24,     24,     5,  11,     6,  5,      5,  0,      8,  16, FALSE,  8 },
151     { kCGLRGB888Bit,        32,     24,     8,  16,     8,  8,      8,  0,      0,  0,  FALSE,  0 },
152     { kCGLARGB8888Bit,      32,     32,     8,  16,     8,  8,      8,  0,      8,  24, FALSE,  0 },
153     { kCGLRGB888A8Bit,      40,     32,     8,  16,     8,  8,      8,  0,      8,  32, FALSE,  7 },
154     { kCGLRGB101010Bit,     32,     30,     10, 20,     10, 10,     10, 0,      0,  0,  FALSE,  6 },
155     { kCGLARGB2101010Bit,   32,     32,     10, 20,     10, 10,     10, 0,      2,  30, FALSE,  6 },
156     { kCGLRGB101010_A8Bit,  40,     38,     10, 20,     10, 10,     10, 0,      8,  32, FALSE,  11 },
157     { kCGLRGB121212Bit,     48,     36,     12, 24,     12, 12,     12, 0,      0,  0,  FALSE,  2 },
158     { kCGLARGB12121212Bit,  48,     48,     12, 24,     12, 12,     12, 0,      12, 36, FALSE,  2 },
159     { kCGLRGB161616Bit,     64,     48,     16, 48,     16, 32,     16, 16,     0,  0,  FALSE,  1 },
160     { kCGLRGBA16161616Bit,  64,     64,     16, 48,     16, 32,     16, 16,     16, 0,  FALSE,  1 },
161     { kCGLRGBFloat64Bit,    64,     48,     16, 32,     16, 16,     16, 0,      0,  0,  TRUE,   12 },
162     { kCGLRGBAFloat64Bit,   64,     64,     16, 48,     16, 32,     16, 16,     16, 0,  TRUE,   12 },
163     { kCGLRGBFloat128Bit,   128,    96,     32, 96,     32, 64,     32, 32,     0,  0,  TRUE,   13 },
164     { kCGLRGBAFloat128Bit,  128,    128,    32, 96,     32, 64,     32, 32,     32, 0,  TRUE,   13 },
165     { kCGLRGBFloat256Bit,   256,    192,    64, 192,    64, 128,    64, 64,     0,  0,  TRUE,   14 },
166     { kCGLRGBAFloat256Bit,  256,    256,    64, 192,    64, 128,    64, 64,     64, 0,  TRUE,   15 },
167 };
168
169
170 static const struct {
171     GLint   mode;
172     int     bits;
173 } depth_stencil_modes[] = {
174     { kCGL0Bit,     0 },
175     { kCGL1Bit,     1 },
176     { kCGL2Bit,     2 },
177     { kCGL3Bit,     3 },
178     { kCGL4Bit,     4 },
179     { kCGL5Bit,     5 },
180     { kCGL6Bit,     6 },
181     { kCGL8Bit,     8 },
182     { kCGL10Bit,    10 },
183     { kCGL12Bit,    12 },
184     { kCGL16Bit,    16 },
185     { kCGL24Bit,    24 },
186     { kCGL32Bit,    32 },
187     { kCGL48Bit,    48 },
188     { kCGL64Bit,    64 },
189     { kCGL96Bit,    96 },
190     { kCGL128Bit,   128 },
191 };
192
193
194 typedef struct {
195     GLint   renderer_id;
196     GLint   buffer_modes;
197     GLint   color_modes;
198     GLint   accum_modes;
199     GLint   depth_modes;
200     GLint   stencil_modes;
201     GLint   max_aux_buffers;
202     GLint   max_sample_buffers;
203     GLint   max_samples;
204     BOOL    offscreen;
205     BOOL    accelerated;
206     BOOL    backing_store;
207     BOOL    window;
208     BOOL    online;
209 } renderer_properties;
210
211
212 typedef struct {
213     unsigned int window:1;
214     unsigned int pbuffer:1;
215     unsigned int accelerated:1;
216     unsigned int color_mode:5; /* index into color_modes table */
217     unsigned int aux_buffers:3;
218     unsigned int depth_bits:8;
219     unsigned int stencil_bits:8;
220     unsigned int accum_mode:5; /* 1 + index into color_modes table (0 means no accum buffer) */
221     unsigned int double_buffer:1;
222     unsigned int stereo:1;
223     unsigned int sample_buffers:1;
224     unsigned int samples:5;
225     unsigned int backing_store:1;
226 } pixel_format;
227
228
229 typedef union
230 {
231     pixel_format    format;
232     UInt64          code;
233 } pixel_format_or_code;
234
235
236 static pixel_format *pixel_formats;
237 static int nb_formats, nb_displayable_formats;
238
239
240 static void *opengl_handle;
241
242
243 static BOOL get_renderer_property(CGLRendererInfoObj renderer_info, GLint renderer_index,
244                                   CGLRendererProperty property, GLint *value)
245 {
246     CGLError err = CGLDescribeRenderer(renderer_info, renderer_index, property, value);
247     if (err != kCGLNoError)
248         WARN("CGLDescribeRenderer failed for property %d: %d %s\n", property, err, CGLErrorString(err));
249     return (err == kCGLNoError);
250 }
251
252
253 static void get_renderer_properties(CGLRendererInfoObj renderer_info, int renderer_index, renderer_properties* properties)
254 {
255     GLint value;
256
257     memset(properties, 0, sizeof(*properties));
258
259     if (get_renderer_property(renderer_info, renderer_index, kCGLRPRendererID, &value))
260         properties->renderer_id = value & kCGLRendererIDMatchingMask;
261
262     if (get_renderer_property(renderer_info, renderer_index, kCGLRPBufferModes, &value))
263         properties->buffer_modes = value;
264
265     if (get_renderer_property(renderer_info, renderer_index, kCGLRPColorModes, &value))
266         properties->color_modes = value;
267
268     if (get_renderer_property(renderer_info, renderer_index, kCGLRPAccumModes, &value))
269         properties->accum_modes = value;
270
271     if (get_renderer_property(renderer_info, renderer_index, kCGLRPDepthModes, &value))
272         properties->depth_modes = value;
273
274     if (get_renderer_property(renderer_info, renderer_index, kCGLRPStencilModes, &value))
275         properties->stencil_modes = value;
276
277     if (get_renderer_property(renderer_info, renderer_index, kCGLRPMaxAuxBuffers, &value))
278         properties->max_aux_buffers = value;
279
280     if (get_renderer_property(renderer_info, renderer_index, kCGLRPMaxSampleBuffers, &value))
281         properties->max_sample_buffers = value;
282
283     if (get_renderer_property(renderer_info, renderer_index, kCGLRPMaxSamples, &value))
284         properties->max_samples = value;
285
286     if (get_renderer_property(renderer_info, renderer_index, kCGLRPOffScreen, &value))
287         properties->offscreen = (value != 0);
288
289     if (get_renderer_property(renderer_info, renderer_index, kCGLRPAccelerated, &value))
290         properties->accelerated = (value != 0);
291
292     if (get_renderer_property(renderer_info, renderer_index, kCGLRPBackingStore, &value))
293         properties->backing_store = (value != 0);
294
295     if (get_renderer_property(renderer_info, renderer_index, kCGLRPWindow, &value))
296         properties->window = (value != 0);
297
298     if (get_renderer_property(renderer_info, renderer_index, kCGLRPOnline, &value))
299         properties->online = (value != 0);
300 }
301
302
303 static void dump_renderer(const renderer_properties* renderer)
304 {
305     int i;
306
307     TRACE("Renderer ID: 0x%08x\n", renderer->renderer_id);
308     TRACE("Buffer modes:\n");
309     TRACE("    Monoscopic:    %s\n", (renderer->buffer_modes & kCGLMonoscopicBit) ? "YES" : "NO");
310     TRACE("    Stereoscopic:  %s\n", (renderer->buffer_modes & kCGLStereoscopicBit) ? "YES" : "NO");
311     TRACE("    Single buffer: %s\n", (renderer->buffer_modes & kCGLSingleBufferBit) ? "YES" : "NO");
312     TRACE("    Double buffer: %s\n", (renderer->buffer_modes & kCGLDoubleBufferBit) ? "YES" : "NO");
313
314     TRACE("Color buffer modes:\n");
315     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
316     {
317         if (renderer->color_modes & color_modes[i].mode)
318         {
319             TRACE("    Color size %d, Alpha size %d", color_modes[i].color_bits, color_modes[i].alpha_bits);
320             if (color_modes[i].is_float)
321                 TRACE(", Float");
322             TRACE("\n");
323         }
324     }
325
326     TRACE("Accumulation buffer sizes: { ");
327     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
328     {
329         if (renderer->accum_modes & color_modes[i].mode)
330             TRACE("%d, ", color_modes[i].color_bits);
331     }
332     TRACE("}\n");
333
334     TRACE("Depth buffer sizes: { ");
335     for (i = 0; i < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); i++)
336     {
337         if (renderer->depth_modes & depth_stencil_modes[i].mode)
338             TRACE("%d, ", depth_stencil_modes[i].bits);
339     }
340     TRACE("}\n");
341
342     TRACE("Stencil buffer sizes: { ");
343     for (i = 0; i < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); i++)
344     {
345         if (renderer->stencil_modes & depth_stencil_modes[i].mode)
346             TRACE("%d, ", depth_stencil_modes[i].bits);
347     }
348     TRACE("}\n");
349
350     TRACE("Max. Auxiliary Buffers: %d\n", renderer->max_aux_buffers);
351     TRACE("Max. Sample Buffers: %d\n", renderer->max_sample_buffers);
352     TRACE("Max. Samples: %d\n", renderer->max_samples);
353     TRACE("Offscreen: %s\n", renderer->offscreen ? "YES" : "NO");
354     TRACE("Accelerated: %s\n", renderer->accelerated ? "YES" : "NO");
355     TRACE("Backing store: %s\n", renderer->backing_store ? "YES" : "NO");
356     TRACE("Window: %s\n", renderer->window ? "YES" : "NO");
357     TRACE("Online: %s\n", renderer->online ? "YES" : "NO");
358 }
359
360
361 static inline UInt64 code_for_pixel_format(const pixel_format* format)
362 {
363     pixel_format_or_code pfc;
364
365     pfc.code = 0;
366     pfc.format = *format;
367     return pfc.code;
368 }
369
370
371 static inline pixel_format pixel_format_for_code(UInt64 code)
372 {
373     pixel_format_or_code pfc;
374
375     pfc.code = code;
376     return pfc.format;
377 }
378
379
380 static const char *debugstr_pf(const pixel_format *pf)
381 {
382     return wine_dbg_sprintf("w/p/a %u/%u/%u col %u%s/%u dp/stn/ac/ax/b/db/str %u/%u/%u/%u/%u/%u/%u samp %u/%u %017llx",
383                             pf->window,
384                             pf->pbuffer,
385                             pf->accelerated,
386                             color_modes[pf->color_mode].color_bits,
387                             (color_modes[pf->color_mode].is_float ? "f" : ""),
388                             color_modes[pf->color_mode].alpha_bits,
389                             pf->depth_bits,
390                             pf->stencil_bits,
391                             pf->accum_mode ? color_modes[pf->accum_mode - 1].color_bits : 0,
392                             pf->aux_buffers,
393                             pf->backing_store,
394                             pf->double_buffer,
395                             pf->stereo,
396                             pf->sample_buffers,
397                             pf->samples,
398                             code_for_pixel_format(pf));
399 }
400
401
402 static unsigned int best_color_mode(GLint modes, GLint color_size, GLint alpha_size, GLint color_float)
403 {
404     int best = -1;
405     int i;
406
407     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
408     {
409         if ((modes & color_modes[i].mode) &&
410             color_modes[i].color_bits >= color_size &&
411             color_modes[i].alpha_bits >= alpha_size &&
412             !color_modes[i].is_float == !color_float)
413         {
414             if (best < 0) /* no existing best choice */
415                 best = i;
416             else if (color_modes[i].color_bits == color_size &&
417                      color_modes[i].alpha_bits == alpha_size) /* candidate is exact match */
418             {
419                 /* prefer it over a best which isn't exact or which has a higher bpp */
420                 if (color_modes[best].color_bits != color_size ||
421                     color_modes[best].alpha_bits != alpha_size ||
422                     color_modes[i].bits_per_pixel < color_modes[best].bits_per_pixel)
423                     best = i;
424             }
425             else if (color_modes[i].color_bits < color_modes[best].color_bits ||
426                      (color_modes[i].color_bits == color_modes[best].color_bits &&
427                       color_modes[i].alpha_bits < color_modes[best].alpha_bits)) /* prefer closer */
428                 best = i;
429         }
430     }
431
432     if (best < 0)
433     {
434         /* Couldn't find a match.  Return first one that renderer supports. */
435         for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
436         {
437             if (modes & color_modes[i].mode)
438                 return i;
439         }
440     }
441
442     return best;
443 }
444
445
446 static unsigned int best_accum_mode(GLint modes, GLint accum_size)
447 {
448     int best = -1;
449     int i;
450
451     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
452     {
453         if ((modes & color_modes[i].mode) && color_modes[i].color_bits >= accum_size)
454         {
455             /* Prefer the fewest color bits, then prefer more alpha bits, then
456                prefer more bits per pixel. */
457             if (best < 0)
458                 best = i;
459             else if (color_modes[i].color_bits < color_modes[best].color_bits)
460                 best = i;
461             else if (color_modes[i].color_bits == color_modes[best].color_bits)
462             {
463                 if (color_modes[i].alpha_bits > color_modes[best].alpha_bits)
464                     best = i;
465                 else if (color_modes[i].alpha_bits == color_modes[best].alpha_bits &&
466                          color_modes[i].bits_per_pixel > color_modes[best].bits_per_pixel)
467                     best = i;
468             }
469         }
470     }
471
472     if (best < 0)
473     {
474         /* Couldn't find a match.  Return last one that renderer supports. */
475         for (i = sizeof(color_modes)/sizeof(color_modes[0]) - 1; i >= 0; i--)
476         {
477             if (modes & color_modes[i].mode)
478                 return i;
479         }
480     }
481
482     return best;
483 }
484
485
486 static void enum_renderer_pixel_formats(renderer_properties renderer, CFMutableArrayRef pixel_format_array,
487                                         CFMutableSetRef pixel_format_set)
488 {
489     CGLPixelFormatAttribute attribs[64] = {
490         kCGLPFAMinimumPolicy,
491         kCGLPFAClosestPolicy,
492         kCGLPFARendererID, renderer.renderer_id,
493         kCGLPFASingleRenderer,
494     };
495     int n = 5, n_stack[16], n_stack_idx = -1;
496     unsigned int tried_pixel_formats = 0, failed_pixel_formats = 0, dupe_pixel_formats = 0,
497                  new_pixel_formats = 0;
498     pixel_format request;
499     unsigned int double_buffer;
500     unsigned int accelerated = renderer.accelerated;
501
502     if (accelerated)
503     {
504         attribs[n++] = kCGLPFAAccelerated;
505         attribs[n++] = kCGLPFANoRecovery;
506     }
507
508     n_stack[++n_stack_idx] = n;
509     for (double_buffer = 0; double_buffer <= 1; double_buffer++)
510     {
511         unsigned int aux;
512
513         n = n_stack[n_stack_idx];
514
515         if ((!double_buffer && !(renderer.buffer_modes & kCGLSingleBufferBit)) ||
516             (double_buffer && !(renderer.buffer_modes & kCGLDoubleBufferBit)))
517             continue;
518
519         if (double_buffer)
520             attribs[n++] = kCGLPFADoubleBuffer;
521         memset(&request, 0, sizeof(request));
522         request.accelerated = accelerated;
523         request.double_buffer = double_buffer;
524
525         /* Don't bother with in-between aux buffers values: either 0 or max. */
526         n_stack[++n_stack_idx] = n;
527         for (aux = 0; aux <= renderer.max_aux_buffers; aux += renderer.max_aux_buffers)
528         {
529             unsigned int color_mode;
530
531             n = n_stack[n_stack_idx];
532
533             attribs[n++] = kCGLPFAAuxBuffers;
534             attribs[n++] = aux;
535             request.aux_buffers = aux;
536
537             n_stack[++n_stack_idx] = n;
538             for (color_mode = 0; color_mode < sizeof(color_modes)/sizeof(color_modes[0]); color_mode++)
539             {
540                 unsigned int depth_mode;
541
542                 n = n_stack[n_stack_idx];
543
544                 if (!(renderer.color_modes & color_modes[color_mode].mode))
545                     continue;
546
547                 attribs[n++] = kCGLPFAColorSize;
548                 attribs[n++] = color_modes[color_mode].color_bits;
549                 attribs[n++] = kCGLPFAAlphaSize;
550                 attribs[n++] = color_modes[color_mode].alpha_bits;
551                 if (color_modes[color_mode].is_float)
552                     attribs[n++] = kCGLPFAColorFloat;
553                 request.color_mode = color_mode;
554
555                 n_stack[++n_stack_idx] = n;
556                 for (depth_mode = 0; depth_mode < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); depth_mode++)
557                 {
558                     unsigned int stencil_mode;
559
560                     n = n_stack[n_stack_idx];
561
562                     if (!(renderer.depth_modes & depth_stencil_modes[depth_mode].mode))
563                         continue;
564
565                     attribs[n++] = kCGLPFADepthSize;
566                     attribs[n++] = depth_stencil_modes[depth_mode].bits;
567                     request.depth_bits = depth_stencil_modes[depth_mode].bits;
568
569                     n_stack[++n_stack_idx] = n;
570                     for (stencil_mode = 0; stencil_mode < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); stencil_mode++)
571                     {
572                         unsigned int stereo;
573
574                         n = n_stack[n_stack_idx];
575
576                         if (!(renderer.stencil_modes & depth_stencil_modes[stencil_mode].mode))
577                             continue;
578                         if (accelerated && depth_stencil_modes[depth_mode].bits != 24 && stencil_mode > 0)
579                             continue;
580
581                         attribs[n++] = kCGLPFAStencilSize;
582                         attribs[n++] = depth_stencil_modes[stencil_mode].bits;
583                         request.stencil_bits = depth_stencil_modes[stencil_mode].bits;
584
585                         /* FIXME: Could trim search space a bit here depending on GPU.
586                                   For ATI Radeon HD 4850, kCGLRGBA16161616Bit implies stereo-capable. */
587                         n_stack[++n_stack_idx] = n;
588                         for (stereo = 0; stereo <= 1; stereo++)
589                         {
590                             int accum_mode;
591
592                             n = n_stack[n_stack_idx];
593
594                             if ((!stereo && !(renderer.buffer_modes & kCGLMonoscopicBit)) ||
595                                 (stereo && !(renderer.buffer_modes & kCGLStereoscopicBit)))
596                                 continue;
597
598                             if (stereo)
599                                 attribs[n++] = kCGLPFAStereo;
600                             request.stereo = stereo;
601
602                             /* Starts at -1 for a 0 accum size */
603                             n_stack[++n_stack_idx] = n;
604                             for (accum_mode = -1; accum_mode < (int)(sizeof(color_modes)/sizeof(color_modes[0])); accum_mode++)
605                             {
606                                 unsigned int target_pass;
607
608                                 n = n_stack[n_stack_idx];
609
610                                 if (accum_mode >= 0)
611                                 {
612                                     if (!(renderer.accum_modes & color_modes[accum_mode].mode))
613                                         continue;
614
615                                     attribs[n++] = kCGLPFAAccumSize;
616                                     attribs[n++] = color_modes[accum_mode].color_bits;
617                                     request.accum_mode = accum_mode + 1;
618                                 }
619                                 else
620                                     request.accum_mode = 0;
621
622                                 /* Targets to request are:
623                                         accelerated: window OR window + pbuffer
624                                         software: window + pbuffer */
625                                 n_stack[++n_stack_idx] = n;
626                                 for (target_pass = 0; target_pass <= accelerated; target_pass++)
627                                 {
628                                     unsigned int samples, max_samples;
629
630                                     n = n_stack[n_stack_idx];
631
632                                     attribs[n++] = kCGLPFAWindow;
633                                     request.window = 1;
634
635                                     if (!accelerated || target_pass > 0)
636                                     {
637                                         attribs[n++] = kCGLPFAPBuffer;
638                                         request.pbuffer = 1;
639                                     }
640                                     else
641                                         request.pbuffer = 0;
642
643                                     /* FIXME: Could trim search space a bit here depending on GPU.
644                                               For Nvidia GeForce 8800 GT, limited to 4 samples for color_bits >= 128.
645                                               For ATI Radeon HD 4850, can't multi-sample for color_bits >= 64 or pbuffer. */
646                                     n_stack[++n_stack_idx] = n;
647                                     max_samples = renderer.max_sample_buffers ? max(1, renderer.max_samples) : 1;
648                                     for (samples = 1; samples <= max_samples; samples *= 2)
649                                     {
650                                         unsigned int backing_store, min_backing_store, max_backing_store;
651
652                                         n = n_stack[n_stack_idx];
653
654                                         if (samples > 1)
655                                         {
656                                             attribs[n++] = kCGLPFASampleBuffers;
657                                             attribs[n++] = renderer.max_sample_buffers;
658                                             attribs[n++] = kCGLPFASamples;
659                                             attribs[n++] = samples;
660                                             request.sample_buffers = renderer.max_sample_buffers;
661                                             request.samples = samples;
662                                         }
663                                         else
664                                             request.sample_buffers = request.samples = 0;
665
666                                         if (renderer.backing_store && double_buffer)
667                                         {
668                                             /* The software renderer seems to always preserve the backing store, whether
669                                                we ask for it or not.  So don't bother not asking for it. */
670                                             min_backing_store = accelerated ? 0 : 1;
671                                             max_backing_store = 1;
672                                         }
673                                         else
674                                             min_backing_store = max_backing_store = 0;
675                                         n_stack[++n_stack_idx] = n;
676                                         for (backing_store = min_backing_store; backing_store <= max_backing_store; backing_store++)
677                                         {
678                                             CGLPixelFormatObj pix;
679                                             GLint virtualScreens;
680                                             CGLError err;
681
682                                             n = n_stack[n_stack_idx];
683
684                                             if (backing_store)
685                                                 attribs[n++] = kCGLPFABackingStore;
686                                             request.backing_store = backing_store;
687
688                                             attribs[n] = 0;
689
690                                             err = CGLChoosePixelFormat(attribs, &pix, &virtualScreens);
691                                             if (err == kCGLNoError && pix)
692                                             {
693                                                 pixel_format pf;
694                                                 GLint value, color_size, alpha_size, color_float;
695                                                 UInt64 pf_code;
696                                                 CFNumberRef code_object;
697                                                 BOOL dupe;
698
699                                                 memset(&pf, 0, sizeof(pf));
700
701                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAccelerated, &value) == kCGLNoError)
702                                                     pf.accelerated = value;
703                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAuxBuffers, &value) == kCGLNoError)
704                                                     pf.aux_buffers = value;
705                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFADepthSize, &value) == kCGLNoError)
706                                                     pf.depth_bits = value;
707                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFADoubleBuffer, &value) == kCGLNoError)
708                                                     pf.double_buffer = value;
709                                                 if (pf.double_buffer &&
710                                                     CGLDescribePixelFormat(pix, 0, kCGLPFABackingStore, &value) == kCGLNoError)
711                                                     pf.backing_store = value;
712                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAPBuffer, &value) == kCGLNoError)
713                                                     pf.pbuffer = value;
714                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFASampleBuffers, &value) == kCGLNoError)
715                                                     pf.sample_buffers = value;
716                                                 if (pf.sample_buffers &&
717                                                     CGLDescribePixelFormat(pix, 0, kCGLPFASamples, &value) == kCGLNoError)
718                                                     pf.samples = value;
719                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAStencilSize, &value) == kCGLNoError)
720                                                     pf.stencil_bits = value;
721                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAStereo, &value) == kCGLNoError)
722                                                     pf.stereo = value;
723                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAWindow, &value) == kCGLNoError)
724                                                     pf.window = value;
725
726                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAColorSize, &color_size) != kCGLNoError)
727                                                     color_size = 0;
728                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAlphaSize, &alpha_size) != kCGLNoError)
729                                                     alpha_size = 0;
730                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAColorFloat, &color_float) != kCGLNoError)
731                                                     color_float = 0;
732                                                 pf.color_mode = best_color_mode(renderer.color_modes, color_size, alpha_size, color_float);
733
734                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAccumSize, &value) == kCGLNoError && value)
735                                                     pf.accum_mode = best_accum_mode(renderer.accum_modes, value) + 1;
736
737                                                 CGLReleasePixelFormat(pix);
738
739                                                 pf_code = code_for_pixel_format(&pf);
740
741                                                 code_object = CFNumberCreate(NULL, kCFNumberSInt64Type, &pf_code);
742                                                 if ((dupe = CFSetContainsValue(pixel_format_set, code_object)))
743                                                     dupe_pixel_formats++;
744                                                 else
745                                                 {
746                                                     CFSetAddValue(pixel_format_set, code_object);
747                                                     CFArrayAppendValue(pixel_format_array, code_object);
748                                                     new_pixel_formats++;
749                                                 }
750                                                 CFRelease(code_object);
751
752                                                 if (pf_code == code_for_pixel_format(&request))
753                                                     TRACE("%s%s\n", debugstr_pf(&pf), dupe ? " (duplicate)" : "");
754                                                 else
755                                                 {
756                                                     TRACE("%s remapped from %s%s\n", debugstr_pf(&pf), debugstr_pf(&request),
757                                                           dupe ? " (duplicate)" : "");
758                                                 }
759                                             }
760                                             else
761                                             {
762                                                 failed_pixel_formats++;
763                                                 TRACE("%s failed request err %d %s\n", debugstr_pf(&request), err, err ? CGLErrorString(err) : "");
764                                             }
765
766                                             tried_pixel_formats++;
767                                         }
768
769                                         n_stack_idx--;
770                                     }
771
772                                     n_stack_idx--;
773                                 }
774
775                                 n_stack_idx--;
776                             }
777
778                             n_stack_idx--;
779                         }
780
781                         n_stack_idx--;
782                     }
783
784                     n_stack_idx--;
785                 }
786
787                 n_stack_idx--;
788             }
789
790             n_stack_idx--;
791         }
792
793         n_stack_idx--;
794     }
795
796     n_stack_idx--;
797
798     TRACE("Number of pixel format attribute combinations: %u\n", tried_pixel_formats);
799     TRACE(" Number which failed to choose a pixel format: %u\n", failed_pixel_formats);
800     TRACE("   Number which chose redundant pixel formats: %u\n", dupe_pixel_formats);
801     TRACE("Number of new pixel formats for this renderer: %u\n", new_pixel_formats);
802 }
803
804
805 /* The docs for WGL_ARB_pixel_format say:
806     Indices are assigned to pixel formats in the following order:
807     1. Accelerated pixel formats that are displayable
808     2. Accelerated pixel formats that are displayable and which have
809        extended attributes
810     3. Generic pixel formats
811     4. Accelerated pixel formats that are non displayable
812  */
813 static int pixel_format_category(pixel_format pf)
814 {
815     /* non-displayable */
816     if (!pf.window)
817         return 4;
818
819     /* non-accelerated a.k.a. software a.k.a. generic */
820     if (!pf.accelerated)
821         return 3;
822
823     /* extended attributes that can't be represented in PIXELFORMATDESCRIPTOR */
824     if (color_modes[pf.color_mode].is_float)
825         return 2;
826
827     /* accelerated, displayable, no extended attributes */
828     return 1;
829 }
830
831
832 static CFComparisonResult pixel_format_comparator(const void *val1, const void *val2, void *context)
833 {
834     CFNumberRef number1 = val1;
835     CFNumberRef number2 = val2;
836     UInt64 code1, code2;
837     pixel_format pf1, pf2;
838     int category1, category2;
839
840     CFNumberGetValue(number1, kCFNumberLongLongType, &code1);
841     CFNumberGetValue(number2, kCFNumberLongLongType, &code2);
842     pf1 = pixel_format_for_code(code1);
843     pf2 = pixel_format_for_code(code2);
844     category1 = pixel_format_category(pf1);
845     category2 = pixel_format_category(pf2);
846
847     if (category1 < category2)
848         return kCFCompareLessThan;
849     if (category1 > category2)
850         return kCFCompareGreaterThan;
851
852     /* Within a category, sort the "best" formats toward the front since that's
853        what wglChoosePixelFormatARB() has to do.  The ordering implemented here
854        matches at least one Windows 7 machine's behavior.
855      */
856     /* Accelerated before unaccelerated. */
857     if (pf1.accelerated && !pf2.accelerated)
858         return kCFCompareLessThan;
859     if (!pf1.accelerated && pf2.accelerated)
860         return kCFCompareGreaterThan;
861
862     /* Explicit color mode ordering. */
863     if (color_modes[pf1.color_mode].color_ordering < color_modes[pf2.color_mode].color_ordering)
864         return kCFCompareLessThan;
865     if (color_modes[pf1.color_mode].color_ordering > color_modes[pf2.color_mode].color_ordering)
866         return kCFCompareGreaterThan;
867
868     /* Non-pbuffer-capable before pbuffer-capable. */
869     if (!pf1.pbuffer && pf2.pbuffer)
870         return kCFCompareLessThan;
871     if (pf1.pbuffer && !pf2.pbuffer)
872         return kCFCompareGreaterThan;
873
874     /* Fewer samples before more samples. */
875     if (pf1.samples < pf2.samples)
876         return kCFCompareLessThan;
877     if (pf1.samples > pf2.samples)
878         return kCFCompareGreaterThan;
879
880     /* Monoscopic before stereoscopic.  (This is a guess.) */
881     if (!pf1.stereo && pf2.stereo)
882         return kCFCompareLessThan;
883     if (pf1.stereo && !pf2.stereo)
884         return kCFCompareGreaterThan;
885
886     /* Single buffered before double buffered. */
887     if (!pf1.double_buffer && pf2.double_buffer)
888         return kCFCompareLessThan;
889     if (pf1.double_buffer && !pf2.double_buffer)
890         return kCFCompareGreaterThan;
891
892     /* Possibly-optimized double buffering before backing-store-preserving
893        double buffering. */
894     if (!pf1.backing_store && pf2.backing_store)
895         return kCFCompareLessThan;
896     if (pf1.backing_store && !pf2.backing_store)
897         return kCFCompareGreaterThan;
898
899     /* Bigger depth buffer before smaller depth buffer. */
900     if (pf1.depth_bits > pf2.depth_bits)
901         return kCFCompareLessThan;
902     if (pf1.depth_bits < pf2.depth_bits)
903         return kCFCompareGreaterThan;
904
905     /* Smaller stencil buffer before bigger stencil buffer. */
906     if (pf1.stencil_bits < pf2.stencil_bits)
907         return kCFCompareLessThan;
908     if (pf1.stencil_bits > pf2.stencil_bits)
909         return kCFCompareGreaterThan;
910
911     /* Smaller alpha bits before larger alpha bits. */
912     if (color_modes[pf1.color_mode].alpha_bits < color_modes[pf2.color_mode].alpha_bits)
913         return kCFCompareLessThan;
914     if (color_modes[pf1.color_mode].alpha_bits > color_modes[pf2.color_mode].alpha_bits)
915         return kCFCompareGreaterThan;
916
917     /* Smaller accum buffer before larger accum buffer.  (This is a guess.) */
918     if (pf1.accum_mode)
919     {
920         if (pf2.accum_mode)
921         {
922             if (color_modes[pf1.accum_mode - 1].color_bits - color_modes[pf1.accum_mode - 1].alpha_bits <
923                 color_modes[pf2.accum_mode - 1].color_bits - color_modes[pf2.accum_mode - 1].alpha_bits)
924                 return kCFCompareLessThan;
925             if (color_modes[pf1.accum_mode - 1].color_bits - color_modes[pf1.accum_mode - 1].alpha_bits >
926                 color_modes[pf2.accum_mode - 1].color_bits - color_modes[pf2.accum_mode - 1].alpha_bits)
927                 return kCFCompareGreaterThan;
928
929             if (color_modes[pf1.accum_mode - 1].bits_per_pixel < color_modes[pf2.accum_mode - 1].bits_per_pixel)
930                 return kCFCompareLessThan;
931             if (color_modes[pf1.accum_mode - 1].bits_per_pixel > color_modes[pf2.accum_mode - 1].bits_per_pixel)
932                 return kCFCompareGreaterThan;
933
934             if (color_modes[pf1.accum_mode - 1].alpha_bits < color_modes[pf2.accum_mode - 1].alpha_bits)
935                 return kCFCompareLessThan;
936             if (color_modes[pf1.accum_mode - 1].alpha_bits > color_modes[pf2.accum_mode - 1].alpha_bits)
937                 return kCFCompareGreaterThan;
938         }
939         else
940             return kCFCompareGreaterThan;
941     }
942     else if (pf2.accum_mode)
943         return kCFCompareLessThan;
944
945     /* Fewer auxiliary buffers before more auxiliary buffers.  (This is a guess.) */
946     if (pf1.aux_buffers < pf2.aux_buffers)
947         return kCFCompareLessThan;
948     if (pf1.aux_buffers > pf2.aux_buffers)
949         return kCFCompareGreaterThan;
950
951     /* If we get here, arbitrarily sort based on code. */
952     if (code1 < code2)
953         return kCFCompareLessThan;
954     if (code1 > code2)
955         return kCFCompareGreaterThan;
956     return kCFCompareEqualTo;
957 }
958
959
960 static BOOL init_pixel_formats(void)
961 {
962     BOOL ret = FALSE;
963     CGLRendererInfoObj renderer_info;
964     GLint rendererCount;
965     CGLError err;
966     CFMutableSetRef pixel_format_set;
967     CFMutableArrayRef pixel_format_array;
968     int i;
969     CFRange range;
970
971     TRACE("()\n");
972
973     assert(sizeof(((pixel_format_or_code*)0)->format) <= sizeof(((pixel_format_or_code*)0)->code));
974
975     err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()), &renderer_info, &rendererCount);
976     if (err)
977     {
978         WARN("CGLQueryRendererInfo failed (%d) %s\n", err, CGLErrorString(err));
979         return FALSE;
980     }
981
982     pixel_format_set = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
983     if (!pixel_format_set)
984     {
985         WARN("CFSetCreateMutable failed\n");
986         CGLDestroyRendererInfo(renderer_info);
987         return FALSE;
988     }
989
990     pixel_format_array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
991     if (!pixel_format_array)
992     {
993         WARN("CFArrayCreateMutable failed\n");
994         CFRelease(pixel_format_set);
995         CGLDestroyRendererInfo(renderer_info);
996         return FALSE;
997     }
998
999     for (i = 0; i < rendererCount; i++)
1000     {
1001         renderer_properties renderer;
1002
1003         get_renderer_properties(renderer_info, i, &renderer);
1004         if (TRACE_ON(wgl))
1005         {
1006             TRACE("renderer_properties %d:\n", i);
1007             dump_renderer(&renderer);
1008         }
1009
1010         enum_renderer_pixel_formats(renderer, pixel_format_array, pixel_format_set);
1011     }
1012
1013     CFRelease(pixel_format_set);
1014     CGLDestroyRendererInfo(renderer_info);
1015
1016     range = CFRangeMake(0, CFArrayGetCount(pixel_format_array));
1017     if (range.length)
1018     {
1019         pixel_formats = HeapAlloc(GetProcessHeap(), 0, range.length * sizeof(*pixel_formats));
1020         if (pixel_formats)
1021         {
1022             CFArraySortValues(pixel_format_array, range, pixel_format_comparator, NULL);
1023             for (i = 0; i < range.length; i++)
1024             {
1025                 CFNumberRef number = CFArrayGetValueAtIndex(pixel_format_array, i);
1026                 UInt64 code;
1027
1028                 CFNumberGetValue(number, kCFNumberLongLongType, &code);
1029                 pixel_formats[i] = pixel_format_for_code(code);
1030                 if (pixel_formats[i].window)
1031                     nb_displayable_formats++;
1032             }
1033
1034             nb_formats = range.length;
1035             TRACE("Total number of unique pixel formats: %d\n", nb_formats);
1036             ret = TRUE;
1037         }
1038         else
1039             WARN("failed to allocate pixel format list\n");
1040     }
1041     else
1042         WARN("got no pixel formats\n");
1043
1044     CFRelease(pixel_format_array);
1045     return ret;
1046 }
1047
1048
1049 static inline BOOL is_valid_pixel_format(int format)
1050 {
1051     return format > 0 && format <= nb_formats;
1052 }
1053
1054
1055 static inline BOOL is_displayable_pixel_format(int format)
1056 {
1057     return format > 0 && format <= nb_displayable_formats;
1058 }
1059
1060
1061 static const pixel_format *get_pixel_format(int format, BOOL allow_nondisplayable)
1062 {
1063     /* Check if the pixel format is valid. Note that it is legal to pass an invalid
1064      * format in case of probing the number of pixel formats.
1065      */
1066     if (is_valid_pixel_format(format) && (is_displayable_pixel_format(format) || allow_nondisplayable))
1067     {
1068         TRACE("Returning format %d\n", format);
1069         return &pixel_formats[format - 1];
1070     }
1071     return NULL;
1072 }
1073
1074
1075 static BOOL init_gl_info(void)
1076 {
1077     CGDirectDisplayID display = CGMainDisplayID();
1078     CGOpenGLDisplayMask displayMask = CGDisplayIDToOpenGLDisplayMask(display);
1079     CGLPixelFormatAttribute attribs[] = {
1080         kCGLPFADisplayMask, displayMask,
1081         0
1082     };
1083     CGLPixelFormatObj pix;
1084     GLint virtualScreens;
1085     CGLError err;
1086     CGLContextObj context;
1087     CGLContextObj old_context = CGLGetCurrentContext();
1088     const char *str;
1089
1090     err = CGLChoosePixelFormat(attribs, &pix, &virtualScreens);
1091     if (err != kCGLNoError || !pix)
1092     {
1093         WARN("CGLChoosePixelFormat() failed with error %d %s\n", err, CGLErrorString(err));
1094         return FALSE;
1095     }
1096
1097     err = CGLCreateContext(pix, NULL, &context);
1098     CGLReleasePixelFormat(pix);
1099     if (err != kCGLNoError || !context)
1100     {
1101         WARN("CGLCreateContext() failed with error %d %s\n", err, CGLErrorString(err));
1102         return FALSE;
1103     }
1104
1105     err = CGLSetCurrentContext(context);
1106     if (err != kCGLNoError)
1107     {
1108         WARN("CGLSetCurrentContext() failed with error %d %s\n", err, CGLErrorString(err));
1109         CGLReleaseContext(context);
1110         return FALSE;
1111     }
1112
1113     str = (const char*)opengl_funcs.gl.p_glGetString(GL_VERSION);
1114     gl_info.glVersion = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
1115     strcpy(gl_info.glVersion, str);
1116     str = (const char*)opengl_funcs.gl.p_glGetString(GL_EXTENSIONS);
1117     gl_info.glExtensions = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
1118     strcpy(gl_info.glExtensions, str);
1119
1120     opengl_funcs.gl.p_glGetIntegerv(GL_MAX_VIEWPORT_DIMS, gl_info.max_viewport_dims);
1121
1122     TRACE("GL version   : %s\n", gl_info.glVersion);
1123     TRACE("GL renderer  : %s\n", opengl_funcs.gl.p_glGetString(GL_RENDERER));
1124
1125     CGLSetCurrentContext(old_context);
1126     CGLReleaseContext(context);
1127
1128     return TRUE;
1129 }
1130
1131
1132 static BOOL get_gl_view_window_rect(struct macdrv_win_data *data, macdrv_window *window, RECT *rect)
1133 {
1134     BOOL ret = TRUE;
1135     *rect = data->client_rect;
1136
1137     if (data->cocoa_window)
1138     {
1139         if (window)
1140             *window = data->cocoa_window;
1141         OffsetRect(rect, -data->whole_rect.left, -data->whole_rect.top);
1142     }
1143     else
1144     {
1145         HWND top = GetAncestor(data->hwnd, GA_ROOT);
1146         HWND parent = GetAncestor(data->hwnd, GA_PARENT);
1147         struct macdrv_win_data *top_data = get_win_data(top);
1148
1149         if (top_data && top_data->cocoa_window)
1150         {
1151             if (window)
1152                 *window = top_data->cocoa_window;
1153             MapWindowPoints(parent, 0, (POINT*)rect, 2);
1154             OffsetRect(rect, -top_data->whole_rect.left, -top_data->whole_rect.top);
1155         }
1156         else
1157             ret = FALSE;
1158
1159         release_win_data(top_data);
1160     }
1161
1162     return ret;
1163 }
1164
1165
1166 /***********************************************************************
1167  *              set_win_format
1168  */
1169 static BOOL set_win_format(struct macdrv_win_data *data, int format)
1170 {
1171     macdrv_window cocoa_window;
1172
1173     TRACE("hwnd %p format %d\n", data->hwnd, format);
1174
1175     if (!get_gl_view_window_rect(data, &cocoa_window, &data->gl_rect))
1176     {
1177         ERR("no top-level parent with Cocoa window in this process\n");
1178         return FALSE;
1179     }
1180
1181     if (data->gl_view) macdrv_dispose_view(data->gl_view);
1182     data->gl_view = macdrv_create_view(cocoa_window, cgrect_from_rect(data->gl_rect));
1183
1184     if (!data->gl_view)
1185     {
1186         WARN("failed to create GL view for window %p rect %s\n", cocoa_window, wine_dbgstr_rect(&data->gl_rect));
1187         return FALSE;
1188     }
1189
1190     TRACE("created GL view %p in window %p at %s\n", data->gl_view, cocoa_window,
1191           wine_dbgstr_rect(&data->gl_rect));
1192
1193     data->pixel_format = format;
1194
1195     return TRUE;
1196 }
1197
1198
1199 /**********************************************************************
1200  *              set_pixel_format
1201  *
1202  * Implementation of wglSetPixelFormat and wglSetPixelFormatWINE.
1203  */
1204 static BOOL set_pixel_format(HDC hdc, int fmt, BOOL allow_reset)
1205 {
1206     struct macdrv_win_data *data;
1207     const pixel_format *pf;
1208     HWND hwnd = WindowFromDC(hdc);
1209     BOOL ret = FALSE;
1210
1211     TRACE("hdc %p format %d\n", hdc, fmt);
1212
1213     if (!hwnd || hwnd == GetDesktopWindow())
1214     {
1215         WARN("not a proper window DC %p/%p\n", hdc, hwnd);
1216         return FALSE;
1217     }
1218
1219     if (!(data = get_win_data(hwnd)))
1220     {
1221         FIXME("DC for window %p of other process: not implemented\n", hwnd);
1222         return FALSE;
1223     }
1224
1225     if (!allow_reset && data->pixel_format)  /* cannot change it if already set */
1226     {
1227         ret = (data->pixel_format == fmt);
1228         goto done;
1229     }
1230
1231     /* Check if fmt is in our list of supported formats to see if it is supported. */
1232     pf = get_pixel_format(fmt, FALSE /* non-displayable */);
1233     if (!pf)
1234     {
1235         ERR("Invalid pixel format: %d\n", fmt);
1236         goto done;
1237     }
1238
1239     if (!pf->window)
1240     {
1241         WARN("Pixel format %d is not compatible for window rendering\n", fmt);
1242         goto done;
1243     }
1244
1245     if (!set_win_format(data, fmt))
1246     {
1247         WARN("Couldn't set format of the window, returning failure\n");
1248         goto done;
1249     }
1250
1251     TRACE("pixel format:\n");
1252     TRACE("           window: %u\n", (unsigned int)pf->window);
1253     TRACE("          pBuffer: %u\n", (unsigned int)pf->pbuffer);
1254     TRACE("      accelerated: %u\n", (unsigned int)pf->accelerated);
1255     TRACE("       color bits: %u%s\n", (unsigned int)color_modes[pf->color_mode].color_bits, (color_modes[pf->color_mode].is_float ? " float" : ""));
1256     TRACE("       alpha bits: %u\n", (unsigned int)color_modes[pf->color_mode].alpha_bits);
1257     TRACE("      aux buffers: %u\n", (unsigned int)pf->aux_buffers);
1258     TRACE("       depth bits: %u\n", (unsigned int)pf->depth_bits);
1259     TRACE("     stencil bits: %u\n", (unsigned int)pf->stencil_bits);
1260     TRACE("       accum bits: %u\n", (unsigned int)pf->accum_mode ? color_modes[pf->accum_mode - 1].color_bits : 0);
1261     TRACE("    double_buffer: %u\n", (unsigned int)pf->double_buffer);
1262     TRACE("           stereo: %u\n", (unsigned int)pf->stereo);
1263     TRACE("   sample_buffers: %u\n", (unsigned int)pf->sample_buffers);
1264     TRACE("          samples: %u\n", (unsigned int)pf->samples);
1265     TRACE("    backing_store: %u\n", (unsigned int)pf->backing_store);
1266     ret = TRUE;
1267
1268 done:
1269     release_win_data(data);
1270     if (ret) __wine_set_pixel_format(hwnd, fmt);
1271     return ret;
1272 }
1273
1274
1275 /**********************************************************************
1276  *              set_gl_view_parent
1277  */
1278 void set_gl_view_parent(HWND hwnd, HWND parent)
1279 {
1280     struct macdrv_win_data *data;
1281
1282     if (!(data = get_win_data(hwnd))) return;
1283
1284     if (data->gl_view)
1285     {
1286         macdrv_window cocoa_window;
1287
1288         TRACE("moving GL view %p to parent %p\n", data->gl_view, parent);
1289
1290         if (!get_gl_view_window_rect(data, &cocoa_window, &data->gl_rect))
1291         {
1292             ERR("no top-level parent with Cocoa window in this process\n");
1293             macdrv_dispose_view(data->gl_view);
1294             data->gl_view = NULL;
1295             release_win_data(data);
1296             __wine_set_pixel_format( hwnd, 0 );
1297             return;
1298         }
1299
1300         macdrv_set_view_window_and_frame(data->gl_view, cocoa_window, cgrect_from_rect(data->gl_rect));
1301     }
1302
1303     release_win_data(data);
1304 }
1305
1306
1307 /**********************************************************************
1308  *              make_context_current
1309  */
1310 static void make_context_current(struct wgl_context *context, BOOL read)
1311 {
1312     macdrv_view view;
1313     struct wgl_pbuffer *pbuffer;
1314
1315     if (read)
1316     {
1317         view = context->read_view;
1318         pbuffer = context->read_pbuffer;
1319     }
1320     else
1321     {
1322         view = context->draw_view;
1323         pbuffer = context->draw_pbuffer;
1324     }
1325
1326     if (view || !pbuffer)
1327         macdrv_make_context_current(context->context, view);
1328     else
1329     {
1330         CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, pbuffer->face,
1331                       pbuffer->level, 0);
1332         CGLSetCurrentContext(context->cglcontext);
1333     }
1334 }
1335
1336
1337 /**********************************************************************
1338  *              macdrv_glCopyColorTable
1339  *
1340  * Hook into glCopyColorTable as part of the implementation of
1341  * wglMakeContextCurrentARB.  If the context has a separate readable,
1342  * temporarily make that current, do glCopyColorTable, and then set it
1343  * back to the drawable.  This is modeled after what Mesa GLX's Apple
1344  * implementation does.
1345  */
1346 static void macdrv_glCopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y,
1347                                     GLsizei width)
1348 {
1349     struct wgl_context *context = NtCurrentTeb()->glContext;
1350
1351     if (context->read_view || context->read_pbuffer)
1352         make_context_current(context, TRUE);
1353
1354     pglCopyColorTable(target, internalformat, x, y, width);
1355
1356     if (context->read_view || context->read_pbuffer)
1357         make_context_current(context, FALSE);
1358 }
1359
1360
1361 /**********************************************************************
1362  *              macdrv_glCopyPixels
1363  *
1364  * Hook into glCopyPixels as part of the implementation of
1365  * wglMakeContextCurrentARB.  If the context has a separate readable,
1366  * temporarily make that current, do glCopyPixels, and then set it back
1367  * to the drawable.  This is modeled after what Mesa GLX's Apple
1368  * implementation does.
1369  */
1370 static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1371 {
1372     struct wgl_context *context = NtCurrentTeb()->glContext;
1373
1374     if (context->read_view || context->read_pbuffer)
1375         make_context_current(context, TRUE);
1376
1377     pglCopyPixels(x, y, width, height, type);
1378
1379     if (context->read_view || context->read_pbuffer)
1380         make_context_current(context, FALSE);
1381 }
1382
1383
1384 /**********************************************************************
1385  *              macdrv_glReadPixels
1386  *
1387  * Hook into glReadPixels as part of the implementation of
1388  * wglMakeContextCurrentARB.  If the context has a separate readable,
1389  * temporarily make that current, do glReadPixels, and then set it back
1390  * to the drawable.  This is modeled after what Mesa GLX's Apple
1391  * implementation does.
1392  */
1393 static void macdrv_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1394                                 GLenum format, GLenum type, void *pixels)
1395 {
1396     struct wgl_context *context = NtCurrentTeb()->glContext;
1397
1398     if (context->read_view || context->read_pbuffer)
1399         make_context_current(context, TRUE);
1400
1401     pglReadPixels(x, y, width, height, format, type, pixels);
1402
1403     if (context->read_view || context->read_pbuffer)
1404         make_context_current(context, FALSE);
1405 }
1406
1407
1408 /**********************************************************************
1409  *              macdrv_glViewport
1410  *
1411  * Hook into glViewport as an opportunity to update the OpenGL context
1412  * if necessary.  This is modeled after what Mesa GLX's Apple
1413  * implementation does.
1414  */
1415 static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
1416 {
1417     struct wgl_context *context = NtCurrentTeb()->glContext;
1418
1419     macdrv_update_opengl_context(context->context);
1420     pglViewport(x, y, width, height);
1421 }
1422
1423
1424 /***********************************************************************
1425  *              macdrv_wglBindTexImageARB
1426  *
1427  * WGL_ARB_render_texture: wglBindTexImageARB
1428  */
1429 static BOOL macdrv_wglBindTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
1430 {
1431     struct wgl_context *context = NtCurrentTeb()->glContext;
1432     GLenum source;
1433     CGLError err;
1434
1435     TRACE("pbuffer %p iBuffer 0x%x\n", pbuffer, iBuffer);
1436
1437     if (pbuffer->no_texture)
1438     {
1439         SetLastError(ERROR_INVALID_OPERATION);
1440         return GL_FALSE;
1441     }
1442
1443     if (!context->draw_view && context->draw_pbuffer == pbuffer)
1444         opengl_funcs.gl.p_glFlush();
1445
1446     switch (iBuffer)
1447     {
1448         case WGL_FRONT_LEFT_ARB:
1449             if (pixel_formats[pbuffer->format].stereo)
1450                 source = GL_FRONT_LEFT;
1451             else
1452                 source = GL_FRONT;
1453             break;
1454         case WGL_FRONT_RIGHT_ARB:
1455             source = GL_FRONT_RIGHT;
1456             break;
1457         case WGL_BACK_LEFT_ARB:
1458             if (pixel_formats[pbuffer->format].stereo)
1459                 source = GL_BACK_LEFT;
1460             else
1461                 source = GL_BACK;
1462             break;
1463         case WGL_BACK_RIGHT_ARB:
1464             source = GL_BACK_RIGHT;
1465             break;
1466         case WGL_AUX0_ARB: source = GL_AUX0; break;
1467         case WGL_AUX1_ARB: source = GL_AUX1; break;
1468         case WGL_AUX2_ARB: source = GL_AUX2; break;
1469         case WGL_AUX3_ARB: source = GL_AUX3; break;
1470
1471         case WGL_AUX4_ARB:
1472         case WGL_AUX5_ARB:
1473         case WGL_AUX6_ARB:
1474         case WGL_AUX7_ARB:
1475         case WGL_AUX8_ARB:
1476         case WGL_AUX9_ARB:
1477             FIXME("unsupported source buffer 0x%x\n", iBuffer);
1478             SetLastError(ERROR_INVALID_DATA);
1479             return GL_FALSE;
1480
1481         default:
1482             WARN("unknown source buffer 0x%x\n", iBuffer);
1483             SetLastError(ERROR_INVALID_DATA);
1484             return GL_FALSE;
1485     }
1486
1487     err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, source);
1488     if (err != kCGLNoError)
1489     {
1490         WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
1491         SetLastError(ERROR_INVALID_OPERATION);
1492         return GL_FALSE;
1493     }
1494
1495     return GL_TRUE;
1496 }
1497
1498
1499 /***********************************************************************
1500  *              macdrv_wglChoosePixelFormatARB
1501  *
1502  * WGL_ARB_pixel_format: wglChoosePixelFormatARB
1503  */
1504 static BOOL macdrv_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList,
1505                                            const FLOAT *pfAttribFList, UINT nMaxFormats,
1506                                            int *piFormats, UINT *nNumFormats)
1507 {
1508     pixel_format pf, valid;
1509     const int *iptr;
1510     int color_bits, red_bits, green_bits, blue_bits, alpha_bits;
1511     int accum_bits, accum_red_bits, accum_green_bits, accum_blue_bits, accum_alpha_bits;
1512     int float_color;
1513     BOOL srgb;
1514     int i, found = 0;
1515
1516     TRACE("hdc %p piAttribIList %p pfAttribFList %p nMaxFormats %u piFormats %p nNumFormats %p\n",
1517           hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
1518     if (pfAttribFList)
1519         FIXME("unused pfAttribFList\n");
1520
1521     memset(&pf, 0, sizeof(pf));
1522     memset(&valid, 0, sizeof(valid));
1523     color_bits = red_bits = green_bits = blue_bits = alpha_bits = 0;
1524     accum_bits = accum_red_bits = accum_green_bits = accum_blue_bits = accum_alpha_bits = 0;
1525     float_color = -1;
1526     srgb = FALSE;
1527
1528     for (iptr = piAttribIList; iptr && *iptr; iptr += 2)
1529     {
1530         int attr = iptr[0];
1531         int value = iptr[1];
1532
1533         switch (attr)
1534         {
1535             case WGL_DRAW_TO_WINDOW_ARB:
1536                 if (valid.window && (!pf.window != !value)) goto cant_match;
1537                 pf.window = (value != 0);
1538                 valid.window = 1;
1539                 break;
1540
1541             case WGL_DRAW_TO_BITMAP_ARB:
1542                 goto cant_match;
1543
1544             case WGL_ACCELERATION_ARB:
1545                 if (value == WGL_FULL_ACCELERATION_ARB)
1546                     value = 1;
1547                 else if (value == WGL_NO_ACCELERATION_ARB)
1548                     value = 0;
1549                 else
1550                     goto cant_match;
1551                 if (valid.accelerated && pf.accelerated != value) goto cant_match;
1552                 pf.accelerated = value;
1553                 valid.accelerated = 1;
1554                 break;
1555
1556             case WGL_NEED_PALETTE_ARB:
1557             case WGL_NEED_SYSTEM_PALETTE_ARB:
1558             case WGL_SWAP_LAYER_BUFFERS_ARB:
1559                 if (value) goto cant_match;
1560                 break;
1561
1562             case WGL_SWAP_METHOD_ARB:
1563                 if (value == WGL_SWAP_COPY_ARB)
1564                     value = 1;
1565                 else if (value == WGL_SWAP_UNDEFINED_ARB)
1566                     value = 0;
1567                 else
1568                     goto cant_match;
1569                 if (valid.backing_store && pf.backing_store != value) goto cant_match;
1570                 if (valid.double_buffer && !pf.double_buffer && value) goto cant_match;
1571                 pf.backing_store = value;
1572                 valid.backing_store = 1;
1573                 break;
1574
1575             case WGL_NUMBER_OVERLAYS_ARB:
1576             case WGL_NUMBER_UNDERLAYS_ARB:
1577                 if (value) goto cant_match;
1578                 break;
1579
1580             case WGL_SHARE_DEPTH_ARB:
1581             case WGL_SHARE_STENCIL_ARB:
1582             case WGL_SHARE_ACCUM_ARB:
1583                 /* no effect */
1584                 break;
1585
1586             case WGL_SUPPORT_GDI_ARB:
1587                 if (value) goto cant_match;
1588                 break;
1589
1590             case WGL_SUPPORT_OPENGL_ARB:
1591                 if (!value) goto cant_match;
1592                 break;
1593
1594             case WGL_DOUBLE_BUFFER_ARB:
1595                 if (valid.double_buffer && (!pf.double_buffer != !value)) goto cant_match;
1596                 pf.double_buffer = (value != 0);
1597                 valid.double_buffer = 1;
1598                 if (valid.backing_store && pf.backing_store && !pf.double_buffer) goto cant_match;
1599                 break;
1600
1601             case WGL_STEREO_ARB:
1602                 if (valid.stereo && (!pf.stereo != !value)) goto cant_match;
1603                 pf.stereo = (value != 0);
1604                 valid.stereo = 1;
1605                 break;
1606
1607             case WGL_PIXEL_TYPE_ARB:
1608                 if (value == WGL_TYPE_RGBA_FLOAT_ARB)
1609                     value = 1;
1610                 else if (value == WGL_TYPE_RGBA_ARB)
1611                     value = 0;
1612                 else
1613                 {
1614                     /* Mac contexts don't support rendering to unsigned floating
1615                        point formats, even if GL_EXT_packed_float is supported.
1616                        So, WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT is not supported. */
1617                     goto cant_match;
1618                 }
1619                 if (float_color != -1 && float_color != value) goto cant_match;
1620                 if (srgb && value) goto cant_match;
1621                 float_color = value;
1622                 break;
1623
1624             case WGL_COLOR_BITS_ARB:
1625                 if (color_bits < value) color_bits = value;
1626                 break;
1627
1628             case WGL_RED_BITS_ARB:
1629                 if (srgb && value > 8) goto cant_match;
1630                 if (red_bits < value) red_bits = value;
1631                 break;
1632
1633             case WGL_GREEN_BITS_ARB:
1634                 if (srgb && value > 8) goto cant_match;
1635                 if (green_bits < value) green_bits = value;
1636                 break;
1637
1638             case WGL_BLUE_BITS_ARB:
1639                 if (srgb && value > 8) goto cant_match;
1640                 if (blue_bits < value) blue_bits = value;
1641                 break;
1642
1643             case WGL_ALPHA_BITS_ARB:
1644                 if (alpha_bits < value) alpha_bits = value;
1645                 break;
1646
1647             case WGL_ACCUM_BITS_ARB:
1648                 if (accum_bits < value) accum_bits = value;
1649                 break;
1650
1651             case WGL_ACCUM_RED_BITS_ARB:
1652                 if (accum_red_bits < value) accum_red_bits = value;
1653                 break;
1654
1655             case WGL_ACCUM_GREEN_BITS_ARB:
1656                 if (accum_green_bits < value) accum_green_bits = value;
1657                 break;
1658
1659             case WGL_ACCUM_BLUE_BITS_ARB:
1660                 if (accum_blue_bits < value) accum_blue_bits = value;
1661                 break;
1662
1663             case WGL_ACCUM_ALPHA_BITS_ARB:
1664                 if (accum_alpha_bits < value) accum_alpha_bits = value;
1665                 break;
1666
1667             case WGL_DEPTH_BITS_ARB:
1668                 if (value > 255) goto cant_match;
1669                 if (pf.depth_bits < value) pf.depth_bits = value;
1670                 break;
1671
1672             case WGL_STENCIL_BITS_ARB:
1673                 if (value > 255) goto cant_match;
1674                 if (pf.stencil_bits < value) pf.stencil_bits = value;
1675                 break;
1676
1677             case WGL_AUX_BUFFERS_ARB:
1678                 if (value > 7) goto cant_match;
1679                 if (pf.aux_buffers < value) pf.aux_buffers = value;
1680                 break;
1681
1682             case WGL_SAMPLE_BUFFERS_ARB:
1683                 if (value > 1) goto cant_match;
1684                 if (pf.sample_buffers < value) pf.sample_buffers = value;
1685                 break;
1686
1687             case WGL_SAMPLES_ARB:
1688                 if (value > 31) goto cant_match;
1689                 if (pf.samples < value) pf.samples = value;
1690                 break;
1691
1692             case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB: /* a.k.a. WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT */
1693                 /* sRGB is only supported for 8-bit integer color components */
1694                 if (float_color >= 1 || red_bits > 8 || green_bits > 8 || blue_bits > 8)
1695                     goto cant_match;
1696                 srgb = TRUE;
1697                 break;
1698
1699             case WGL_NUMBER_PIXEL_FORMATS_ARB:
1700             case WGL_RED_SHIFT_ARB:
1701             case WGL_GREEN_SHIFT_ARB:
1702             case WGL_BLUE_SHIFT_ARB:
1703             case WGL_ALPHA_SHIFT_ARB:
1704             case WGL_TRANSPARENT_ARB:
1705             case WGL_TRANSPARENT_RED_VALUE_ARB:
1706             case WGL_TRANSPARENT_GREEN_VALUE_ARB:
1707             case WGL_TRANSPARENT_BLUE_VALUE_ARB:
1708             case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
1709             case WGL_TRANSPARENT_INDEX_VALUE_ARB:
1710                 /* ignored */
1711                 break;
1712
1713             case WGL_DRAW_TO_PBUFFER_ARB:
1714             case WGL_BIND_TO_TEXTURE_RGB_ARB:
1715             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
1716             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV:
1717             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV:
1718                 if (valid.pbuffer && (!pf.pbuffer != !value)) goto cant_match;
1719                 pf.pbuffer = (value != 0);
1720                 valid.pbuffer = 1;
1721                 if ((attr == WGL_BIND_TO_TEXTURE_RGBA_ARB || attr == WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV) &&
1722                     !alpha_bits)
1723                     alpha_bits = 1;
1724                 break;
1725
1726             default:
1727                 WARN("invalid attribute %x\n", iptr[0]);
1728                 return GL_FALSE;
1729         }
1730     }
1731
1732     for (i = 0; i < nb_formats && found < nMaxFormats; i++)
1733     {
1734         const struct color_mode *mode;
1735
1736         if (valid.window && pixel_formats[i].window != pf.window) continue;
1737         if (valid.pbuffer && pixel_formats[i].pbuffer != pf.pbuffer) continue;
1738         if (valid.accelerated && pixel_formats[i].accelerated != pf.accelerated) continue;
1739         if (valid.double_buffer && pixel_formats[i].double_buffer != pf.double_buffer) continue;
1740         if (valid.stereo && pixel_formats[i].stereo != pf.stereo) continue;
1741         if (valid.backing_store && pixel_formats[i].backing_store != pf.backing_store) continue;
1742
1743         if (pixel_formats[i].aux_buffers < pf.aux_buffers) continue;
1744         if (pixel_formats[i].depth_bits < pf.depth_bits) continue;
1745         if (pixel_formats[i].stencil_bits < pf.stencil_bits) continue;
1746         if (pixel_formats[i].sample_buffers < pf.sample_buffers) continue;
1747         if (pixel_formats[i].samples < pf.samples) continue;
1748
1749         mode = &color_modes[pixel_formats[i].color_mode];
1750         /* If the mode doesn't have alpha, check requested color bits against
1751            bits per pixel instead of the mode's color bits.  On Windows, color
1752            bits sometimes exceeds r+g+b (e.g. it's 32 for an R8G8B8A0 pixel format).
1753            If an app depends on that and requests WGL_COLOR_BITS_ARB == 32 and
1754            expects that to match such a pixel format, we need to accommodate that. */
1755         if (mode->alpha_bits)
1756         {
1757             if (mode->color_bits < color_bits)
1758                 continue;
1759         }
1760         else
1761         {
1762             if (mode->bits_per_pixel < color_bits)
1763                 continue;
1764         }
1765         if (mode->red_bits < red_bits || mode->green_bits < green_bits ||
1766             mode->blue_bits < blue_bits || mode->alpha_bits < alpha_bits)
1767             continue;
1768         if (float_color != -1 && (!mode->is_float != !float_color)) continue;
1769         if (srgb && (mode->red_bits != 8 || mode->green_bits != 8 || mode->blue_bits != 8 || mode->is_float))
1770             continue;
1771
1772         if (pixel_formats[i].accum_mode)
1773         {
1774             mode = &color_modes[pixel_formats[i].accum_mode - 1];
1775             if (mode->color_bits < accum_bits || mode->red_bits < accum_red_bits ||
1776                 mode->green_bits < accum_green_bits || mode->blue_bits < accum_blue_bits ||
1777                 mode->alpha_bits < accum_alpha_bits)
1778                 continue;
1779         }
1780         else if (accum_bits || accum_red_bits || accum_green_bits || accum_blue_bits || accum_alpha_bits)
1781             continue;
1782
1783         piFormats[found++] = i;
1784     }
1785
1786 cant_match:
1787     *nNumFormats = found;
1788
1789     return TRUE;
1790 }
1791
1792
1793 /**********************************************************************
1794  *              macdrv_wglCreatePbufferARB
1795  *
1796  * WGL_ARB_pbuffer: wglCreatePbufferARB
1797  */
1798 static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight,
1799                                                       const int *piAttribList)
1800 {
1801     struct wgl_pbuffer* pbuffer;
1802     GLenum target = 0;
1803     GLenum internalFormat = 0;
1804     CGLError err;
1805
1806     TRACE("hdc %p iPixelFormat %d iWidth %d iHeight %d piAttribList %p\n",
1807           hdc, iPixelFormat, iWidth, iHeight, piAttribList);
1808
1809     if (!is_valid_pixel_format(iPixelFormat) || !pixel_formats[iPixelFormat].pbuffer)
1810     {
1811         WARN("invalid pixel format %d\n", iPixelFormat);
1812         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
1813         return NULL;
1814     }
1815
1816     pbuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pbuffer));
1817     pbuffer->format = iPixelFormat;
1818
1819     for ( ; piAttribList && *piAttribList; piAttribList += 2)
1820     {
1821         int attr = piAttribList[0];
1822         int value = piAttribList[1];
1823
1824         switch (attr)
1825         {
1826             case WGL_PBUFFER_LARGEST_ARB:
1827                 FIXME("WGL_PBUFFER_LARGEST_ARB: %d; ignoring\n", value);
1828                 break;
1829
1830             case WGL_TEXTURE_FORMAT_ARB:
1831                 switch (value)
1832                 {
1833                     case WGL_TEXTURE_RGBA_ARB:
1834                         TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGBA_ARB\n");
1835                         internalFormat = GL_RGBA;
1836                         break;
1837                     case WGL_TEXTURE_RGB_ARB:
1838                         TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGB_ARB\n");
1839                         internalFormat = GL_RGB;
1840                         break;
1841                     case WGL_NO_TEXTURE_ARB:
1842                         TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_NO_TEXTURE_ARB\n");
1843                         internalFormat = 0;
1844                         break;
1845                     default:
1846                         WARN("unknown WGL_TEXTURE_FORMAT_ARB value 0x%x\n", value);
1847                         SetLastError(ERROR_INVALID_DATA);
1848                         goto done;
1849                 }
1850                 break;
1851
1852             case WGL_TEXTURE_TARGET_ARB:
1853                 pbuffer->face = 0;
1854                 switch (value)
1855                 {
1856                     case WGL_NO_TEXTURE_ARB:
1857                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_NO_TEXTURE_ARB\n");
1858                         target = 0;
1859                         break;
1860                     case WGL_TEXTURE_CUBE_MAP_ARB:
1861                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_CUBE_MAP_ARB\n");
1862                         target = GL_TEXTURE_CUBE_MAP;
1863                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1864                         break;
1865                     case WGL_TEXTURE_1D_ARB:
1866                         FIXME("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_1D_ARB; not supported\n");
1867                         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
1868                         goto done;
1869                     case WGL_TEXTURE_2D_ARB:
1870                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_2D_ARB\n");
1871                         target = GL_TEXTURE_2D;
1872                         break;
1873                     case WGL_TEXTURE_RECTANGLE_NV:
1874                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_RECTANGLE_NV\n");
1875                         target = GL_TEXTURE_RECTANGLE;
1876                         break;
1877                     default:
1878                         WARN("unknown WGL_TEXTURE_TARGET_ARB value 0x%x\n", value);
1879                         SetLastError(ERROR_INVALID_DATA);
1880                         goto done;
1881                 }
1882                 break;
1883
1884             case WGL_MIPMAP_TEXTURE_ARB:
1885                 TRACE("WGL_MIPMAP_TEXTURE_ARB: %d\n", value);
1886                 pbuffer->max_level = 0;
1887                 if (value)
1888                 {
1889                     int size = min(iWidth, iHeight) / 2;
1890                     while (size)
1891                     {
1892                         pbuffer->max_level++;
1893                         size /= 2;
1894                     }
1895                 }
1896                 break;
1897
1898             default:
1899                 WARN("unknown attribute 0x%x\n", attr);
1900                 SetLastError(ERROR_INVALID_DATA);
1901                 goto done;
1902         }
1903     }
1904
1905     if (!target || !internalFormat)
1906     {
1907         pbuffer->no_texture = TRUE;
1908         /* no actual way to turn off ability to texture; use most permissive target */
1909         target = GL_TEXTURE_RECTANGLE;
1910         internalFormat = GL_RGB;
1911     }
1912
1913     err = CGLCreatePBuffer(iWidth, iHeight, target, internalFormat, pbuffer->max_level, &pbuffer->pbuffer);
1914     if (err != kCGLNoError)
1915     {
1916         WARN("CGLCreatePBuffer failed; err %d %s\n", err, CGLErrorString(err));
1917         pbuffer->pbuffer = NULL;
1918         if (err == kCGLBadAlloc)
1919             SetLastError(ERROR_NO_SYSTEM_RESOURCES);
1920         else
1921             SetLastError(ERROR_INVALID_DATA);
1922     }
1923
1924 done:
1925     if (!pbuffer->pbuffer)
1926     {
1927         HeapFree(GetProcessHeap(), 0, pbuffer);
1928         return NULL;
1929     }
1930
1931     TRACE(" -> %p\n", pbuffer);
1932     return pbuffer;
1933 }
1934
1935
1936 /**********************************************************************
1937  *              macdrv_wglDestroyPbufferARB
1938  *
1939  * WGL_ARB_pbuffer: wglDestroyPbufferARB
1940  */
1941 static BOOL macdrv_wglDestroyPbufferARB(struct wgl_pbuffer *pbuffer)
1942 {
1943     TRACE("pbuffer %p\n", pbuffer);
1944     if (pbuffer && pbuffer->pbuffer)
1945         CGLReleasePBuffer(pbuffer->pbuffer);
1946     HeapFree(GetProcessHeap(), 0, pbuffer);
1947     return GL_TRUE;
1948 }
1949
1950
1951 /**********************************************************************
1952  *              macdrv_wglGetExtensionsStringARB
1953  *
1954  * WGL_ARB_extensions_string: wglGetExtensionsStringARB
1955  */
1956 static const GLubyte *macdrv_wglGetExtensionsStringARB(HDC hdc)
1957 {
1958     /* FIXME: Since we're given an HDC, this should be device-specific.  I.e.
1959               this can be specific to the CGL renderer like we're supposed to do. */
1960     TRACE("returning \"%s\"\n", gl_info.wglExtensions);
1961     return (const GLubyte*)gl_info.wglExtensions;
1962 }
1963
1964
1965 /**********************************************************************
1966  *              macdrv_wglGetExtensionsStringEXT
1967  *
1968  * WGL_EXT_extensions_string: wglGetExtensionsStringEXT
1969  */
1970 static const GLubyte *macdrv_wglGetExtensionsStringEXT(void)
1971 {
1972     TRACE("returning \"%s\"\n", gl_info.wglExtensions);
1973     return (const GLubyte*)gl_info.wglExtensions;
1974 }
1975
1976
1977 /**********************************************************************
1978  *              macdrv_wglGetPbufferDCARB
1979  *
1980  * WGL_ARB_pbuffer: wglGetPbufferDCARB
1981  */
1982 static HDC macdrv_wglGetPbufferDCARB(struct wgl_pbuffer *pbuffer)
1983 {
1984     HDC hdc;
1985     struct wgl_pbuffer *prev;
1986
1987     hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
1988     if (!hdc) return 0;
1989
1990     EnterCriticalSection(&dc_pbuffers_section);
1991     prev = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc);
1992     if (prev)
1993     {
1994         CGLReleasePBuffer(prev->pbuffer);
1995         HeapFree(GetProcessHeap(), 0, prev);
1996     }
1997     CFDictionarySetValue(dc_pbuffers, hdc, pbuffer);
1998     LeaveCriticalSection(&dc_pbuffers_section);
1999
2000     TRACE("pbuffer %p -> hdc %p\n", pbuffer, hdc);
2001     return hdc;
2002 }
2003
2004
2005 /**********************************************************************
2006  *              macdrv_wglGetPixelFormatAttribivARB
2007  *
2008  * WGL_ARB_pixel_format: wglGetPixelFormatAttribivARB
2009  */
2010 static BOOL macdrv_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane,
2011                                                 UINT nAttributes, const int *piAttributes, int *piValues)
2012 {
2013     const pixel_format *pf;
2014     UINT i;
2015
2016     TRACE("hdc %p iPixelFormat %d iLayerPlane %d nAttributes %u piAttributes %p piValues %p\n",
2017           hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
2018
2019     if (!nAttributes) return GL_TRUE;
2020
2021     if (nAttributes == 1 && piAttributes[0] == WGL_NUMBER_PIXEL_FORMATS_ARB)
2022     {
2023         piValues[0] = nb_formats;
2024         return GL_TRUE;
2025     }
2026
2027     pf = get_pixel_format(iPixelFormat, TRUE /* non-displayable */);
2028     if (!pf)
2029     {
2030         WARN("invalid pixel format %d\n", iPixelFormat);
2031         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2032         return GL_FALSE;
2033     }
2034
2035     for (i = 0; i < nAttributes; ++i)
2036     {
2037         switch (piAttributes[i])
2038         {
2039             case WGL_NUMBER_PIXEL_FORMATS_ARB:
2040                 piValues[i] = nb_formats;
2041                 break;
2042
2043             case WGL_DRAW_TO_WINDOW_ARB:
2044                 piValues[i] = pf->window ? GL_TRUE : GL_FALSE;
2045                 break;
2046
2047             case WGL_DRAW_TO_BITMAP_ARB:
2048                 piValues[i] = GL_FALSE;
2049                 break;
2050
2051             case WGL_ACCELERATION_ARB:
2052                 if (iLayerPlane) goto invalid_layer;
2053                 if (pf->accelerated)
2054                     piValues[i] = WGL_FULL_ACCELERATION_ARB;
2055                 else
2056                     piValues[i] = WGL_NO_ACCELERATION_ARB;
2057                 break;
2058
2059             case WGL_NEED_PALETTE_ARB:
2060             case WGL_NEED_SYSTEM_PALETTE_ARB:
2061             case WGL_SWAP_LAYER_BUFFERS_ARB:
2062                 piValues[i] = GL_FALSE;
2063                 break;
2064
2065             case WGL_SWAP_METHOD_ARB:
2066                 if (pf->double_buffer && pf->backing_store)
2067                     piValues[i] = WGL_SWAP_COPY_ARB;
2068                 else
2069                     piValues[i] = WGL_SWAP_UNDEFINED_ARB;
2070                 break;
2071
2072             case WGL_NUMBER_OVERLAYS_ARB:
2073             case WGL_NUMBER_UNDERLAYS_ARB:
2074                 piValues[i] = 0;
2075                 break;
2076
2077             case WGL_TRANSPARENT_ARB:
2078                 if (iLayerPlane) goto invalid_layer;
2079                 piValues[i] = GL_FALSE;
2080                 break;
2081
2082             case WGL_TRANSPARENT_RED_VALUE_ARB:
2083             case WGL_TRANSPARENT_GREEN_VALUE_ARB:
2084             case WGL_TRANSPARENT_BLUE_VALUE_ARB:
2085             case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
2086             case WGL_TRANSPARENT_INDEX_VALUE_ARB:
2087                 if (iLayerPlane) goto invalid_layer;
2088                 piValues[i] = 0;
2089                 break;
2090
2091             case WGL_SHARE_DEPTH_ARB:
2092             case WGL_SHARE_STENCIL_ARB:
2093             case WGL_SHARE_ACCUM_ARB:
2094                 if (iLayerPlane) goto invalid_layer;
2095                 piValues[i] = GL_TRUE;
2096                 break;
2097
2098             case WGL_SUPPORT_GDI_ARB:
2099                 if (iLayerPlane) goto invalid_layer;
2100                 piValues[i] = GL_FALSE;
2101                 break;
2102
2103             case WGL_SUPPORT_OPENGL_ARB:
2104                 if (iLayerPlane) goto invalid_layer;
2105                 piValues[i] = GL_TRUE;
2106                 break;
2107
2108             case WGL_DOUBLE_BUFFER_ARB:
2109                 if (iLayerPlane) goto invalid_layer;
2110                 piValues[i] = pf->double_buffer ? GL_TRUE : GL_FALSE;
2111                 break;
2112
2113             case WGL_STEREO_ARB:
2114                 if (iLayerPlane) goto invalid_layer;
2115                 piValues[i] = pf->stereo ? GL_TRUE : GL_FALSE;
2116                 break;
2117
2118             case WGL_PIXEL_TYPE_ARB:
2119                 if (iLayerPlane) goto invalid_layer;
2120                 if (color_modes[pf->color_mode].is_float)
2121                     piValues[i] = WGL_TYPE_RGBA_FLOAT_ARB;
2122                 else
2123                     piValues[i] = WGL_TYPE_RGBA_ARB;
2124                 /* WGL_EXT_pixel_format_packed_float may be supported, which should in theory
2125                    make another pixel type available: WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT.
2126                    However, Mac contexts don't support rendering to unsigned floating-point
2127                    formats, even when GL_EXT_packed_float is supported. */
2128                 break;
2129
2130             case WGL_COLOR_BITS_ARB:
2131                 if (iLayerPlane) goto invalid_layer;
2132                 /* If the mode doesn't have alpha, return bits per pixel instead
2133                    of color bits.  On Windows, color bits sometimes exceeds r+g+b
2134                    (e.g. it's 32 for an R8G8B8A0 pixel format).  If an app depends
2135                    on that and expects that WGL_COLOR_BITS_ARB >= 32 for such a
2136                    pixel format, we need to accommodate that. */
2137                 if (color_modes[pf->color_mode].alpha_bits)
2138                     piValues[i] = color_modes[pf->color_mode].color_bits;
2139                 else
2140                     piValues[i] = color_modes[pf->color_mode].bits_per_pixel;
2141                 break;
2142
2143             case WGL_RED_BITS_ARB:
2144                 if (iLayerPlane) goto invalid_layer;
2145                 piValues[i] = color_modes[pf->color_mode].red_bits;
2146                 break;
2147
2148             case WGL_RED_SHIFT_ARB:
2149                 if (iLayerPlane) goto invalid_layer;
2150                 piValues[i] = color_modes[pf->color_mode].red_shift;
2151                 break;
2152
2153             case WGL_GREEN_BITS_ARB:
2154                 if (iLayerPlane) goto invalid_layer;
2155                 piValues[i] = color_modes[pf->color_mode].green_bits;
2156                 break;
2157
2158             case WGL_GREEN_SHIFT_ARB:
2159                 if (iLayerPlane) goto invalid_layer;
2160                 piValues[i] = color_modes[pf->color_mode].green_shift;
2161                 break;
2162
2163             case WGL_BLUE_BITS_ARB:
2164                 if (iLayerPlane) goto invalid_layer;
2165                 piValues[i] = color_modes[pf->color_mode].blue_bits;
2166                 break;
2167
2168             case WGL_BLUE_SHIFT_ARB:
2169                 if (iLayerPlane) goto invalid_layer;
2170                 piValues[i] = color_modes[pf->color_mode].blue_shift;
2171                 break;
2172
2173             case WGL_ALPHA_BITS_ARB:
2174                 if (iLayerPlane) goto invalid_layer;
2175                 piValues[i] = color_modes[pf->color_mode].alpha_bits;
2176                 break;
2177
2178             case WGL_ALPHA_SHIFT_ARB:
2179                 if (iLayerPlane) goto invalid_layer;
2180                 piValues[i] = color_modes[pf->color_mode].alpha_shift;
2181                 break;
2182
2183             case WGL_ACCUM_BITS_ARB:
2184                 if (iLayerPlane) goto invalid_layer;
2185                 if (pf->accum_mode)
2186                     piValues[i] = color_modes[pf->accum_mode - 1].color_bits;
2187                 else
2188                     piValues[i] = 0;
2189                 break;
2190
2191             case WGL_ACCUM_RED_BITS_ARB:
2192                 if (iLayerPlane) goto invalid_layer;
2193                 if (pf->accum_mode)
2194                     piValues[i] = color_modes[pf->accum_mode - 1].red_bits;
2195                 else
2196                     piValues[i] = 0;
2197                 break;
2198
2199             case WGL_ACCUM_GREEN_BITS_ARB:
2200                 if (iLayerPlane) goto invalid_layer;
2201                 if (pf->accum_mode)
2202                     piValues[i] = color_modes[pf->accum_mode - 1].green_bits;
2203                 else
2204                     piValues[i] = 0;
2205                 break;
2206
2207             case WGL_ACCUM_BLUE_BITS_ARB:
2208                 if (iLayerPlane) goto invalid_layer;
2209                 if (pf->accum_mode)
2210                     piValues[i] = color_modes[pf->accum_mode - 1].blue_bits;
2211                 else
2212                     piValues[i] = 0;
2213                 break;
2214
2215             case WGL_ACCUM_ALPHA_BITS_ARB:
2216                 if (iLayerPlane) goto invalid_layer;
2217                 if (pf->accum_mode)
2218                     piValues[i] = color_modes[pf->accum_mode - 1].alpha_bits;
2219                 else
2220                     piValues[i] = 0;
2221                 break;
2222
2223             case WGL_DEPTH_BITS_ARB:
2224                 if (iLayerPlane) goto invalid_layer;
2225                 piValues[i] = pf->depth_bits;
2226                 break;
2227
2228             case WGL_STENCIL_BITS_ARB:
2229                 if (iLayerPlane) goto invalid_layer;
2230                 piValues[i] = pf->stencil_bits;
2231                 break;
2232
2233             case WGL_AUX_BUFFERS_ARB:
2234                 if (iLayerPlane) goto invalid_layer;
2235                 piValues[i] = pf->aux_buffers;
2236                 break;
2237
2238             case WGL_SAMPLE_BUFFERS_ARB:
2239                 if (iLayerPlane) goto invalid_layer;
2240                 piValues[i] = pf->sample_buffers;
2241                 break;
2242
2243             case WGL_SAMPLES_ARB:
2244                 if (iLayerPlane) goto invalid_layer;
2245                 piValues[i] = pf->samples;
2246                 break;
2247
2248             case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB: /* a.k.a. WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT */
2249                 if (iLayerPlane) goto invalid_layer;
2250                 /* sRGB is only supported for 8-bit integer color components */
2251                 if (color_modes[pf->color_mode].red_bits == 8 &&
2252                     color_modes[pf->color_mode].green_bits == 8 &&
2253                     color_modes[pf->color_mode].blue_bits == 8 &&
2254                     !color_modes[pf->color_mode].is_float)
2255                     piValues[i] = GL_TRUE;
2256                 else
2257                     piValues[i] = GL_FALSE;
2258                 break;
2259
2260             case WGL_DRAW_TO_PBUFFER_ARB:
2261             case WGL_BIND_TO_TEXTURE_RGB_ARB:
2262             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV:
2263                 piValues[i] = pf->pbuffer ? GL_TRUE : GL_FALSE;
2264                 break;
2265
2266             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
2267             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV:
2268                 piValues[i] = (pf->pbuffer && color_modes[pf->color_mode].alpha_bits) ? GL_TRUE : GL_FALSE;
2269                 break;
2270
2271             case WGL_MAX_PBUFFER_WIDTH_ARB:
2272                 piValues[i] = gl_info.max_viewport_dims[0];
2273                 break;
2274
2275             case WGL_MAX_PBUFFER_HEIGHT_ARB:
2276                 piValues[i] = gl_info.max_viewport_dims[1];
2277                 break;
2278
2279             case WGL_MAX_PBUFFER_PIXELS_ARB:
2280                 piValues[i] = gl_info.max_viewport_dims[0] * gl_info.max_viewport_dims[1];
2281                 break;
2282
2283             default:
2284                 WARN("invalid attribute %x\n", piAttributes[i]);
2285                 return GL_FALSE;
2286         }
2287
2288         TRACE("piAttributes[%d] (%x) -> %x\n", i, piAttributes[i], piValues[i]);
2289     }
2290
2291     return GL_TRUE;
2292
2293 invalid_layer:
2294     FIXME("unsupported iLayerPlane %d\n", iLayerPlane);
2295     return GL_FALSE;
2296 }
2297
2298
2299 /**********************************************************************
2300  *              macdrv_wglGetPixelFormatAttribfvARB
2301  *
2302  * WGL_ARB_pixel_format: wglGetPixelFormatAttribfvARB
2303  */
2304 static BOOL macdrv_wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane,
2305                                                 UINT nAttributes, const int *piAttributes, FLOAT *pfValues)
2306 {
2307     int *attr;
2308     int ret;
2309
2310     TRACE("hdc %p iPixelFormat %d iLayerPlane %d nAttributes %u piAttributes %p pfValues %p\n",
2311           hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
2312
2313     /* Allocate a temporary array to store integer values */
2314     attr = HeapAlloc(GetProcessHeap(), 0, nAttributes * sizeof(int));
2315     if (!attr)
2316     {
2317         ERR("couldn't allocate %d array\n", nAttributes);
2318         return GL_FALSE;
2319     }
2320
2321     /* Piggy-back on wglGetPixelFormatAttribivARB */
2322     ret = macdrv_wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, attr);
2323     if (ret)
2324     {
2325         UINT i;
2326
2327         /* Convert integer values to float. Should also check for attributes
2328            that can give decimal values here */
2329         for (i = 0; i < nAttributes; i++)
2330             pfValues[i] = attr[i];
2331     }
2332
2333     HeapFree(GetProcessHeap(), 0, attr);
2334     return ret;
2335 }
2336
2337
2338 /**********************************************************************
2339  *              macdrv_wglGetSwapIntervalEXT
2340  *
2341  * WGL_EXT_swap_control: wglGetSwapIntervalEXT
2342  */
2343 static int macdrv_wglGetSwapIntervalEXT(void)
2344 {
2345     struct wgl_context *context = NtCurrentTeb()->glContext;
2346     long value;
2347     CGLError err;
2348
2349     TRACE("\n");
2350
2351     err = CGLGetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&value);
2352     if (err != kCGLNoError)
2353     {
2354         WARN("CGLGetParameter(kCGLCPSwapInterval) failed; error %d %s\n",
2355              err, CGLErrorString(err));
2356         value = 1;
2357     }
2358
2359     return value;
2360 }
2361
2362
2363 /***********************************************************************
2364  *              macdrv_wglMakeContextCurrentARB
2365  *
2366  * WGL_ARB_make_current_read: wglMakeContextCurrentARB
2367  *
2368  * This is not supported directly by OpenGL on the Mac.  We emulate it
2369  * by hooking into glReadPixels, glCopyPixels, and glCopyColorTable to
2370  * temporarily swap the drawable.  This follows the technique used in
2371  * the implementation of Mesa GLX for Apple.
2372  */
2373 static BOOL macdrv_wglMakeContextCurrentARB(HDC draw_hdc, HDC read_hdc, struct wgl_context *context)
2374 {
2375     struct macdrv_win_data *data;
2376     HWND hwnd;
2377
2378     TRACE("draw_hdc %p read_hdc %p context %p/%p/%p\n", draw_hdc, read_hdc, context,
2379           (context ? context->context : NULL), (context ? context->cglcontext : NULL));
2380
2381     if (!context)
2382     {
2383         macdrv_make_context_current(NULL, NULL);
2384         NtCurrentTeb()->glContext = NULL;
2385         return TRUE;
2386     }
2387
2388     if ((hwnd = WindowFromDC(draw_hdc)))
2389     {
2390         if (!(data = get_win_data(hwnd)))
2391         {
2392             FIXME("draw DC for window %p of other process: not implemented\n", hwnd);
2393             return FALSE;
2394         }
2395
2396         if (!data->pixel_format)
2397         {
2398             WARN("no pixel format set\n");
2399             release_win_data(data);
2400             SetLastError(ERROR_INVALID_HANDLE);
2401             return FALSE;
2402         }
2403         if (context->format != data->pixel_format)
2404         {
2405             WARN("mismatched pixel format draw_hdc %p %u context %p %u\n", draw_hdc, data->pixel_format, context, context->format);
2406             release_win_data(data);
2407             SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2408             return FALSE;
2409         }
2410
2411         context->draw_view = data->gl_view;
2412         context->draw_pbuffer = NULL;
2413         release_win_data(data);
2414     }
2415     else
2416     {
2417         struct wgl_pbuffer *pbuffer;
2418
2419         EnterCriticalSection(&dc_pbuffers_section);
2420         pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, draw_hdc);
2421         if (pbuffer)
2422         {
2423             if (context->format != pbuffer->format)
2424             {
2425                 WARN("mismatched pixel format draw_hdc %p %u context %p %u\n", draw_hdc, pbuffer->format, context, context->format);
2426                 LeaveCriticalSection(&dc_pbuffers_section);
2427                 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2428                 return FALSE;
2429             }
2430         }
2431         else
2432         {
2433             WARN("no window or pbuffer for DC\n");
2434             LeaveCriticalSection(&dc_pbuffers_section);
2435             SetLastError(ERROR_INVALID_HANDLE);
2436             return FALSE;
2437         }
2438
2439         context->draw_view = NULL;
2440         context->draw_pbuffer = pbuffer;
2441         LeaveCriticalSection(&dc_pbuffers_section);
2442     }
2443
2444     context->read_view = NULL;
2445     context->read_pbuffer = NULL;
2446     if (read_hdc && read_hdc != draw_hdc)
2447     {
2448         if ((hwnd = WindowFromDC(read_hdc)))
2449         {
2450             if ((data = get_win_data(hwnd)))
2451             {
2452                 if (data->gl_view != context->draw_view)
2453                     context->read_view = data->gl_view;
2454                 release_win_data(data);
2455             }
2456         }
2457         else
2458         {
2459             EnterCriticalSection(&dc_pbuffers_section);
2460             context->read_pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, read_hdc);
2461             LeaveCriticalSection(&dc_pbuffers_section);
2462         }
2463     }
2464
2465     TRACE("making context current with draw_view %p draw_pbuffer %p read_view %p read_pbuffer %p format %u\n",
2466           context->draw_view, context->draw_pbuffer, context->read_view, context->read_pbuffer, context->format);
2467
2468     make_context_current(context, FALSE);
2469     context->has_been_current = TRUE;
2470     NtCurrentTeb()->glContext = context;
2471
2472     return TRUE;
2473 }
2474
2475
2476 /**********************************************************************
2477  *              macdrv_wglQueryPbufferARB
2478  *
2479  * WGL_ARB_pbuffer: wglQueryPbufferARB
2480  */
2481 static BOOL macdrv_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int iAttribute, int *piValue)
2482 {
2483     CGLError err;
2484     GLsizei width;
2485     GLsizei height;
2486     GLenum target;
2487     GLenum internalFormat;
2488     GLint mipmap;
2489
2490     TRACE("pbuffer %p iAttribute 0x%x piValue %p\n", pbuffer, iAttribute, piValue);
2491
2492     err = CGLDescribePBuffer(pbuffer->pbuffer, &width, &height, &target, &internalFormat, &mipmap);
2493     if (err != kCGLNoError)
2494     {
2495         WARN("CGLDescribePBuffer failed; error %d %s\n", err, CGLErrorString(err));
2496         SetLastError(ERROR_INVALID_HANDLE);
2497         return GL_FALSE;
2498     }
2499
2500     switch (iAttribute)
2501     {
2502         case WGL_PBUFFER_WIDTH_ARB:
2503             *piValue = width;
2504             break;
2505         case WGL_PBUFFER_HEIGHT_ARB:
2506             *piValue = height;
2507             break;
2508         case WGL_PBUFFER_LOST_ARB:
2509             /* Mac PBuffers can't be lost */
2510             *piValue = GL_FALSE;
2511             break;
2512         case WGL_TEXTURE_FORMAT_ARB:
2513             if (pbuffer->no_texture)
2514                 *piValue = WGL_NO_TEXTURE_ARB;
2515             else switch (internalFormat)
2516             {
2517                 case GL_RGBA:
2518                     *piValue = WGL_TEXTURE_RGBA_ARB;
2519                     break;
2520                 case GL_RGB:
2521                 default:
2522                     *piValue = WGL_TEXTURE_RGB_ARB;
2523                     break;
2524             }
2525             break;
2526         case WGL_TEXTURE_TARGET_ARB:
2527             if (pbuffer->no_texture)
2528                 *piValue = WGL_NO_TEXTURE_ARB;
2529             else switch (target)
2530             {
2531                 case GL_TEXTURE_CUBE_MAP:
2532                     *piValue = WGL_TEXTURE_CUBE_MAP_ARB;
2533                     break;
2534                 case GL_TEXTURE_2D:
2535                     *piValue = WGL_TEXTURE_2D_ARB;
2536                     break;
2537                 case GL_TEXTURE_RECTANGLE:
2538                 default:
2539                     *piValue = WGL_TEXTURE_RECTANGLE_NV;
2540                     break;
2541             }
2542             break;
2543         case WGL_MIPMAP_TEXTURE_ARB:
2544             *piValue = (pbuffer->max_level > 0);
2545             break;
2546         case WGL_MIPMAP_LEVEL_ARB:
2547             *piValue = pbuffer->level;
2548             break;
2549         case WGL_CUBE_MAP_FACE_ARB:
2550             switch (pbuffer->face)
2551             {
2552                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2553                 default:
2554                     *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
2555                     break;
2556                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2557                     *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
2558                     break;
2559                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2560                     *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
2561                     break;
2562                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2563                     *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
2564                     break;
2565                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2566                     *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
2567                     break;
2568                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2569                     *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
2570                     break;
2571             }
2572             break;
2573         default:
2574             WARN("invalid attribute 0x%x\n", iAttribute);
2575             SetLastError(ERROR_INVALID_DATA);
2576             return GL_FALSE;
2577     }
2578
2579     return GL_TRUE;
2580 }
2581
2582
2583 /**********************************************************************
2584  *              macdrv_wglReleasePbufferDCARB
2585  *
2586  * WGL_ARB_pbuffer: wglReleasePbufferDCARB
2587  */
2588 static int macdrv_wglReleasePbufferDCARB(struct wgl_pbuffer *pbuffer, HDC hdc)
2589 {
2590     struct wgl_pbuffer *prev;
2591
2592     TRACE("pbuffer %p hdc %p\n", pbuffer, hdc);
2593
2594     EnterCriticalSection(&dc_pbuffers_section);
2595
2596     prev = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc);
2597     if (prev)
2598     {
2599         if (prev != pbuffer)
2600             FIXME("hdc %p isn't associated with pbuffer %p\n", hdc, pbuffer);
2601         CGLReleasePBuffer(prev->pbuffer);
2602         HeapFree(GetProcessHeap(), 0, prev);
2603         CFDictionaryRemoveValue(dc_pbuffers, hdc);
2604     }
2605     else hdc = 0;
2606
2607     LeaveCriticalSection(&dc_pbuffers_section);
2608
2609     return hdc && DeleteDC(hdc);
2610 }
2611
2612
2613 /**********************************************************************
2614  *              macdrv_wglReleaseTexImageARB
2615  *
2616  * WGL_ARB_render_texture: wglReleaseTexImageARB
2617  */
2618 static BOOL macdrv_wglReleaseTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
2619 {
2620     struct wgl_context *context = NtCurrentTeb()->glContext;
2621     CGLError err;
2622
2623     TRACE("pbuffer %p iBuffer 0x%x; stub!\n", pbuffer, iBuffer);
2624
2625     if (pbuffer->no_texture)
2626     {
2627         SetLastError(ERROR_INVALID_OPERATION);
2628         return GL_FALSE;
2629     }
2630
2631     err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, GL_NONE);
2632     if (err != kCGLNoError)
2633     {
2634         WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
2635         SetLastError(ERROR_INVALID_OPERATION);
2636         return GL_FALSE;
2637     }
2638
2639     return GL_TRUE;
2640 }
2641
2642
2643 /**********************************************************************
2644  *              macdrv_wglSetPbufferAttribARB
2645  *
2646  * WGL_ARB_render_texture: wglSetPbufferAttribARB
2647  */
2648 static BOOL macdrv_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const int *piAttribList)
2649 {
2650     struct wgl_context *context = NtCurrentTeb()->glContext;
2651
2652     TRACE("pbuffer %p piAttribList %p\n", pbuffer, piAttribList);
2653
2654     for ( ; piAttribList && *piAttribList; piAttribList += 2)
2655     {
2656         int attr = piAttribList[0];
2657         int value = piAttribList[1];
2658         switch (attr)
2659         {
2660             case WGL_MIPMAP_LEVEL_ARB:
2661                 TRACE("WGL_MIPMAP_LEVEL_ARB: %d\n", value);
2662                 pbuffer->level = value;
2663                 break;
2664             case WGL_CUBE_MAP_FACE_ARB:
2665                 switch (value)
2666                 {
2667                     case WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
2668                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\n");
2669                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
2670                         break;
2671                     case WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
2672                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\n");
2673                         pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
2674                         break;
2675                     case WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
2676                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\n");
2677                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
2678                         break;
2679                     case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
2680                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\n");
2681                         pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
2682                         break;
2683                     case WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
2684                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\n");
2685                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
2686                         break;
2687                     case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
2688                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\n");
2689                         pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
2690                         break;
2691                     default:
2692                         WARN("unknown WGL_CUBE_MAP_FACE_ARB value 0x%x\n", value);
2693                         SetLastError(ERROR_INVALID_DATA);
2694                         return GL_FALSE;
2695                 }
2696                 break;
2697             default:
2698                 WARN("invalide attribute 0x%x\n", attr);
2699                 SetLastError(ERROR_INVALID_DATA);
2700                 return GL_FALSE;
2701         }
2702     }
2703
2704     if (context && context->draw_pbuffer == pbuffer)
2705         make_context_current(context, FALSE);
2706
2707     return GL_TRUE;
2708 }
2709
2710
2711 /**********************************************************************
2712  *              macdrv_wglSetPixelFormatWINE
2713  *
2714  * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE
2715  */
2716 static BOOL macdrv_wglSetPixelFormatWINE(HDC hdc, int fmt)
2717 {
2718     return set_pixel_format(hdc, fmt, TRUE);
2719 }
2720
2721
2722 /**********************************************************************
2723  *              macdrv_wglSwapIntervalEXT
2724  *
2725  * WGL_EXT_swap_control: wglSwapIntervalEXT
2726  */
2727 static BOOL macdrv_wglSwapIntervalEXT(int interval)
2728 {
2729     struct wgl_context *context = NtCurrentTeb()->glContext;
2730     long value;
2731     CGLError err;
2732
2733     TRACE("interval %d\n", interval);
2734
2735     if (interval < 0)
2736     {
2737         SetLastError(ERROR_INVALID_DATA);
2738         return FALSE;
2739     }
2740
2741     if (interval > 1)
2742         interval = 1;
2743
2744     value = interval;
2745     err = CGLSetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&value);
2746     if (err != kCGLNoError)
2747     {
2748         WARN("CGLSetParameter(kCGLCPSwapInterval) failed; error %d %s\n",
2749              err, CGLErrorString(err));
2750         SetLastError(ERROR_GEN_FAILURE);
2751         return FALSE;
2752     }
2753
2754     return TRUE;
2755 }
2756
2757
2758 static void register_extension(const char *ext)
2759 {
2760     if (gl_info.wglExtensions[0])
2761         strcat(gl_info.wglExtensions, " ");
2762     strcat(gl_info.wglExtensions, ext);
2763
2764     TRACE("'%s'\n", ext);
2765 }
2766
2767 static void load_extensions(void)
2768 {
2769     /*
2770      * ARB Extensions
2771      */
2772     register_extension("WGL_ARB_extensions_string");
2773     opengl_funcs.ext.p_wglGetExtensionsStringARB = macdrv_wglGetExtensionsStringARB;
2774
2775     register_extension("WGL_ARB_make_current_read");
2776     opengl_funcs.ext.p_wglGetCurrentReadDCARB   = (void *)1;  /* never called */
2777     opengl_funcs.ext.p_wglMakeContextCurrentARB = macdrv_wglMakeContextCurrentARB;
2778
2779     register_extension("WGL_ARB_pixel_format");
2780     opengl_funcs.ext.p_wglChoosePixelFormatARB      = macdrv_wglChoosePixelFormatARB;
2781     opengl_funcs.ext.p_wglGetPixelFormatAttribfvARB = macdrv_wglGetPixelFormatAttribfvARB;
2782     opengl_funcs.ext.p_wglGetPixelFormatAttribivARB = macdrv_wglGetPixelFormatAttribivARB;
2783
2784     if (gluCheckExtension((GLubyte*)"GL_ARB_color_buffer_float", (GLubyte*)gl_info.glExtensions))
2785     {
2786         register_extension("WGL_ARB_pixel_format_float");
2787         register_extension("WGL_ATI_pixel_format_float");
2788     }
2789
2790     if (gluCheckExtension((GLubyte*)"GL_ARB_multisample", (GLubyte*)gl_info.glExtensions))
2791         register_extension("WGL_ARB_multisample");
2792
2793     if (gluCheckExtension((GLubyte*)"GL_ARB_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions))
2794         register_extension("WGL_ARB_framebuffer_sRGB");
2795
2796     if (gluCheckExtension((GLubyte*)"GL_APPLE_pixel_buffer", (GLubyte*)gl_info.glExtensions))
2797     {
2798         register_extension("WGL_ARB_pbuffer");
2799         opengl_funcs.ext.p_wglCreatePbufferARB    = macdrv_wglCreatePbufferARB;
2800         opengl_funcs.ext.p_wglDestroyPbufferARB   = macdrv_wglDestroyPbufferARB;
2801         opengl_funcs.ext.p_wglGetPbufferDCARB     = macdrv_wglGetPbufferDCARB;
2802         opengl_funcs.ext.p_wglQueryPbufferARB     = macdrv_wglQueryPbufferARB;
2803         opengl_funcs.ext.p_wglReleasePbufferDCARB = macdrv_wglReleasePbufferDCARB;
2804
2805         register_extension("WGL_ARB_render_texture");
2806         opengl_funcs.ext.p_wglBindTexImageARB       = macdrv_wglBindTexImageARB;
2807         opengl_funcs.ext.p_wglReleaseTexImageARB    = macdrv_wglReleaseTexImageARB;
2808         opengl_funcs.ext.p_wglSetPbufferAttribARB   = macdrv_wglSetPbufferAttribARB;
2809
2810         if (gluCheckExtension((GLubyte*)"GL_ARB_texture_rectangle", (GLubyte*)gl_info.glExtensions) ||
2811             gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle", (GLubyte*)gl_info.glExtensions))
2812             register_extension("WGL_NV_render_texture_rectangle");
2813     }
2814
2815     /* TODO:
2816         WGL_ARB_create_context: wglCreateContextAttribsARB
2817         WGL_ARB_create_context_profile
2818      */
2819
2820     /*
2821      * EXT Extensions
2822      */
2823     register_extension("WGL_EXT_extensions_string");
2824     opengl_funcs.ext.p_wglGetExtensionsStringEXT = macdrv_wglGetExtensionsStringEXT;
2825
2826     register_extension("WGL_EXT_swap_control");
2827     opengl_funcs.ext.p_wglSwapIntervalEXT = macdrv_wglSwapIntervalEXT;
2828     opengl_funcs.ext.p_wglGetSwapIntervalEXT = macdrv_wglGetSwapIntervalEXT;
2829
2830     /* Presumably identical to [W]GL_ARB_framebuffer_sRGB, above, but clients may
2831        check for either, so register them separately. */
2832     if (gluCheckExtension((GLubyte*)"GL_EXT_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions))
2833         register_extension("WGL_EXT_framebuffer_sRGB");
2834
2835     if (gluCheckExtension((GLubyte*)"GL_EXT_packed_float", (GLubyte*)gl_info.glExtensions))
2836         register_extension("WGL_EXT_pixel_format_packed_float");
2837
2838     /*
2839      * WINE-specific WGL Extensions
2840      */
2841
2842     /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
2843      * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
2844      */
2845     register_extension("WGL_WINE_pixel_format_passthrough");
2846     opengl_funcs.ext.p_wglSetPixelFormatWINE = macdrv_wglSetPixelFormatWINE;
2847 }
2848
2849
2850 static BOOL init_opengl(void)
2851 {
2852     static int init_done;
2853     unsigned int i;
2854     char buffer[200];
2855
2856     if (init_done) return (opengl_handle != NULL);
2857     init_done = 1;
2858
2859     TRACE("()\n");
2860
2861     dc_pbuffers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
2862     if (!dc_pbuffers)
2863     {
2864         WARN("CFDictionaryCreateMutable failed\n");
2865         return FALSE;
2866     }
2867
2868     opengl_handle = wine_dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY|RTLD_LOCAL|RTLD_NOLOAD, buffer, sizeof(buffer));
2869     if (!opengl_handle)
2870     {
2871         ERR("Failed to load OpenGL: %s\n", buffer);
2872         ERR("OpenGL support is disabled.\n");
2873         return FALSE;
2874     }
2875
2876     for (i = 0; i < sizeof(opengl_func_names)/sizeof(opengl_func_names[0]); i++)
2877     {
2878         if (!(((void **)&opengl_funcs.gl)[i] = wine_dlsym(opengl_handle, opengl_func_names[i], NULL, 0)))
2879         {
2880             ERR("%s not found in OpenGL, disabling.\n", opengl_func_names[i]);
2881             goto failed;
2882         }
2883     }
2884
2885     /* redirect some standard OpenGL functions */
2886 #define REDIRECT(func) \
2887     do { p##func = opengl_funcs.gl.p_##func; opengl_funcs.gl.p_##func = macdrv_##func; } while(0)
2888     REDIRECT(glCopyPixels);
2889     REDIRECT(glReadPixels);
2890     REDIRECT(glViewport);
2891 #undef REDIRECT
2892
2893     /* redirect some OpenGL extension functions */
2894 #define REDIRECT(func) \
2895     do { if (opengl_funcs.ext.p_##func) { p##func = opengl_funcs.ext.p_##func; opengl_funcs.ext.p_##func = macdrv_##func; } } while(0)
2896     REDIRECT(glCopyColorTable);
2897 #undef REDIRECT
2898
2899     if (!init_gl_info())
2900         goto failed;
2901
2902     load_extensions();
2903     if (!init_pixel_formats())
2904         goto failed;
2905
2906     return TRUE;
2907
2908 failed:
2909     wine_dlclose(opengl_handle, NULL, 0);
2910     opengl_handle = NULL;
2911     return FALSE;
2912 }
2913
2914
2915 /***********************************************************************
2916  *              sync_gl_view
2917  *
2918  * Synchronize the Mac GL view position with the Windows child window
2919  * position.
2920  */
2921 void sync_gl_view(struct macdrv_win_data *data)
2922 {
2923     RECT rect;
2924
2925     TRACE("hwnd %p gl_view %p\n", data->hwnd, data->gl_view);
2926
2927     if (!data->gl_view) return;
2928
2929     if (get_gl_view_window_rect(data, NULL, &rect) && memcmp(&data->gl_rect, &rect, sizeof(rect)))
2930     {
2931         TRACE("Setting GL view %p frame to %s\n", data->gl_view, wine_dbgstr_rect(&rect));
2932         macdrv_set_view_window_and_frame(data->gl_view, NULL, cgrect_from_rect(rect));
2933         data->gl_rect = rect;
2934     }
2935 }
2936
2937
2938 static int get_dc_pixel_format(HDC hdc)
2939 {
2940     int format;
2941     HWND hwnd;
2942
2943     if ((hwnd = WindowFromDC(hdc)))
2944     {
2945         struct macdrv_win_data *data;
2946
2947         if (!(data = get_win_data(hwnd)))
2948         {
2949             FIXME("DC for window %p of other process: not implemented\n", hwnd);
2950             return 0;
2951         }
2952
2953         format = data->pixel_format;
2954         release_win_data(data);
2955     }
2956     else
2957     {
2958         struct wgl_pbuffer *pbuffer;
2959
2960         EnterCriticalSection(&dc_pbuffers_section);
2961         pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc);
2962         if (pbuffer)
2963             format = pbuffer->format;
2964         else
2965         {
2966             WARN("no window or pbuffer for DC %p\n", hdc);
2967             format = 0;
2968         }
2969         LeaveCriticalSection(&dc_pbuffers_section);
2970     }
2971
2972     return format;
2973 }
2974
2975
2976 /**********************************************************************
2977  *              create_context
2978  */
2979 static BOOL create_context(struct wgl_context *context, CGLContextObj share)
2980 {
2981     const pixel_format *pf;
2982     CGLPixelFormatAttribute attribs[64];
2983     int n = 0;
2984     CGLPixelFormatObj pix;
2985     GLint virtualScreens;
2986     CGLError err;
2987     long swap_interval;
2988
2989     pf = get_pixel_format(context->format, TRUE /* non-displayable */);
2990     if (!pf)
2991     {
2992         ERR("Invalid pixel format %d, expect problems!\n", context->format);
2993         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2994         return FALSE;
2995     }
2996
2997     attribs[n++] = kCGLPFAMinimumPolicy;
2998     attribs[n++] = kCGLPFAClosestPolicy;
2999
3000     if (pf->accelerated)
3001     {
3002         attribs[n++] = kCGLPFAAccelerated;
3003         attribs[n++] = kCGLPFANoRecovery;
3004     }
3005     else
3006     {
3007         attribs[n++] = kCGLPFARendererID;
3008         attribs[n++] = kCGLRendererGenericFloatID;
3009     }
3010
3011     if (pf->double_buffer)
3012         attribs[n++] = kCGLPFADoubleBuffer;
3013
3014     attribs[n++] = kCGLPFAAuxBuffers;
3015     attribs[n++] = pf->aux_buffers;
3016
3017     attribs[n++] = kCGLPFAColorSize;
3018     attribs[n++] = color_modes[pf->color_mode].color_bits;
3019     attribs[n++] = kCGLPFAAlphaSize;
3020     attribs[n++] = color_modes[pf->color_mode].alpha_bits;
3021     if (color_modes[pf->color_mode].is_float)
3022         attribs[n++] = kCGLPFAColorFloat;
3023
3024     attribs[n++] = kCGLPFADepthSize;
3025     attribs[n++] = pf->depth_bits;
3026
3027     attribs[n++] = kCGLPFAStencilSize;
3028     attribs[n++] = pf->stencil_bits;
3029
3030     if (pf->stereo)
3031         attribs[n++] = kCGLPFAStereo;
3032
3033     if (pf->accum_mode)
3034     {
3035         attribs[n++] = kCGLPFAAccumSize;
3036         attribs[n++] = color_modes[pf->accum_mode - 1].color_bits;
3037     }
3038
3039     if (pf->window)
3040         attribs[n++] = kCGLPFAWindow;
3041     if (pf->pbuffer)
3042         attribs[n++] = kCGLPFAPBuffer;
3043
3044     if (pf->sample_buffers && pf->samples)
3045     {
3046         attribs[n++] = kCGLPFASampleBuffers;
3047         attribs[n++] = pf->sample_buffers;
3048         attribs[n++] = kCGLPFASamples;
3049         attribs[n++] = pf->samples;
3050     }
3051
3052     if (pf->backing_store)
3053         attribs[n++] = kCGLPFABackingStore;
3054
3055     attribs[n] = 0;
3056
3057     err = CGLChoosePixelFormat(attribs, &pix, &virtualScreens);
3058     if (err != kCGLNoError || !pix)
3059     {
3060         WARN("CGLChoosePixelFormat() failed with error %d %s\n", err, CGLErrorString(err));
3061         return FALSE;
3062     }
3063
3064     err = CGLCreateContext(pix, share, &context->cglcontext);
3065     CGLReleasePixelFormat(pix);
3066     if (err != kCGLNoError || !context->cglcontext)
3067     {
3068         context->cglcontext = NULL;
3069         WARN("CGLCreateContext() failed with error %d %s\n", err, CGLErrorString(err));
3070         return FALSE;
3071     }
3072
3073     /* According to the WGL_EXT_swap_control docs, the default swap interval for
3074        a context is 1.  CGL contexts default to 0, so we need to set it. */
3075     swap_interval = 1;
3076     err = CGLSetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&swap_interval);
3077     if (err != kCGLNoError)
3078         WARN("CGLSetParameter(kCGLCPSwapInterval) failed with error %d %s; leaving un-vsynced\n", err, CGLErrorString(err));
3079
3080     context->context = macdrv_create_opengl_context(context->cglcontext);
3081     CGLReleaseContext(context->cglcontext);
3082     if (!context->context)
3083     {
3084         WARN("macdrv_create_opengl_context() failed\n");
3085         return FALSE;
3086     }
3087
3088     TRACE("created context %p/%p/%p\n", context, context->context, context->cglcontext);
3089
3090     return TRUE;
3091 }
3092
3093
3094 /**********************************************************************
3095  *              macdrv_wglDescribePixelFormat
3096  */
3097 int macdrv_wglDescribePixelFormat(HDC hdc, int fmt, UINT size, PIXELFORMATDESCRIPTOR *descr)
3098 {
3099     int ret = nb_formats;
3100     const pixel_format *pf;
3101     const struct color_mode *mode;
3102
3103     TRACE("hdc %p fmt %d size %u descr %p\n", hdc, fmt, size, descr);
3104
3105     if (fmt <= 0 || fmt > ret) return ret;
3106     if (size < sizeof(*descr)) return 0;
3107
3108     pf = &pixel_formats[fmt - 1];
3109
3110     memset(descr, 0, sizeof(*descr));
3111     descr->nSize            = sizeof(*descr);
3112     descr->nVersion         = 1;
3113
3114     descr->dwFlags          = PFD_SUPPORT_OPENGL;
3115     if (pf->window)         descr->dwFlags |= PFD_DRAW_TO_WINDOW;
3116     if (!pf->accelerated)   descr->dwFlags |= PFD_GENERIC_FORMAT;
3117     if (pf->double_buffer)  descr->dwFlags |= PFD_DOUBLEBUFFER;
3118     if (pf->stereo)         descr->dwFlags |= PFD_STEREO;
3119     if (pf->backing_store)  descr->dwFlags |= PFD_SWAP_COPY;
3120
3121     descr->iPixelType       = PFD_TYPE_RGBA;
3122
3123     mode = &color_modes[pf->color_mode];
3124     /* If the mode doesn't have alpha, return bits per pixel instead of color bits.
3125        On Windows, color bits sometimes exceeds r+g+b (e.g. it's 32 for an
3126        R8G8B8A0 pixel format).  If an app depends on that and expects that
3127        cColorBits >= 32 for such a pixel format, we need to accommodate that. */
3128     if (mode->alpha_bits)
3129         descr->cColorBits   = mode->color_bits;
3130     else
3131         descr->cColorBits   = mode->bits_per_pixel;
3132     descr->cRedBits         = mode->red_bits;
3133     descr->cRedShift        = mode->red_shift;
3134     descr->cGreenBits       = mode->green_bits;
3135     descr->cGreenShift      = mode->green_shift;
3136     descr->cBlueBits        = mode->blue_bits;
3137     descr->cBlueShift       = mode->blue_shift;
3138     descr->cAlphaBits       = mode->alpha_bits;
3139     descr->cAlphaShift      = mode->alpha_shift;
3140
3141     if (pf->accum_mode)
3142     {
3143         mode = &color_modes[pf->accum_mode - 1];
3144         descr->cAccumBits       = mode->color_bits;
3145         descr->cAccumRedBits    = mode->red_bits;
3146         descr->cAccumGreenBits  = mode->green_bits;
3147         descr->cAccumBlueBits   = mode->blue_bits;
3148         descr->cAccumAlphaBits  = mode->alpha_bits;
3149     }
3150
3151     descr->cDepthBits       = pf->depth_bits;
3152     descr->cStencilBits     = pf->stencil_bits;
3153     descr->cAuxBuffers      = pf->aux_buffers;
3154     descr->iLayerType       = PFD_MAIN_PLANE;
3155     return ret;
3156 }
3157
3158 /***********************************************************************
3159  *              macdrv_wglCopyContext
3160  */
3161 static BOOL macdrv_wglCopyContext(struct wgl_context *src, struct wgl_context *dst, UINT mask)
3162 {
3163     CGLError err;
3164
3165     TRACE("src %p dst %p mask %x\n", src, dst, mask);
3166
3167     err = CGLCopyContext(src->cglcontext, dst->cglcontext, mask);
3168     if (err != kCGLNoError)
3169         WARN("CGLCopyContext() failed with err %d %s\n", err, CGLErrorString(err));
3170     return (err == kCGLNoError);
3171 }
3172
3173 /***********************************************************************
3174  *              macdrv_wglCreateContext
3175  */
3176 static struct wgl_context *macdrv_wglCreateContext(HDC hdc)
3177 {
3178     int format;
3179     struct wgl_context *context;
3180
3181     TRACE("hdc %p\n", hdc);
3182
3183     format = get_dc_pixel_format(hdc);
3184
3185     if (!is_valid_pixel_format(format))
3186     {
3187         ERR("Invalid pixel format %d, expect problems!\n", format);
3188         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
3189         return NULL;
3190     }
3191
3192     if (!(context = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context)))) return NULL;
3193
3194     context->format = format;
3195     if (!create_context(context, NULL))
3196     {
3197         HeapFree(GetProcessHeap(), 0, context);
3198         return NULL;
3199     }
3200
3201     return context;
3202 }
3203
3204 /***********************************************************************
3205  *              macdrv_wglDeleteContext
3206  */
3207 static void macdrv_wglDeleteContext(struct wgl_context *context)
3208 {
3209     TRACE("deleting context %p/%p/%p\n", context, context->context, context->cglcontext);
3210     macdrv_dispose_opengl_context(context->context);
3211     HeapFree(GetProcessHeap(), 0, context);
3212 }
3213
3214 /***********************************************************************
3215  *              macdrv_wglGetPixelFormat
3216  */
3217 static int macdrv_wglGetPixelFormat(HDC hdc)
3218 {
3219     int format;
3220
3221     format = get_dc_pixel_format(hdc);
3222
3223     if (!is_valid_pixel_format(format))  /* not set yet */
3224         format = 0;
3225     else if (!is_displayable_pixel_format(format))
3226     {
3227         /* Non-displayable formats can't be used with traditional WGL calls.
3228          * As has been verified on Windows GetPixelFormat doesn't fail but returns pixel format 1. */
3229         format = 1;
3230     }
3231
3232     TRACE(" hdc %p -> %d\n", hdc, format);
3233     return format;
3234 }
3235
3236 /***********************************************************************
3237  *              macdrv_wglGetProcAddress
3238  */
3239 static PROC macdrv_wglGetProcAddress(const char *proc)
3240 {
3241     void *ret;
3242
3243     if (!strncmp(proc, "wgl", 3)) return NULL;
3244     ret = wine_dlsym(opengl_handle, proc, NULL, 0);
3245     if (ret)
3246     {
3247         if (TRACE_ON(wgl))
3248         {
3249             Dl_info info;
3250             if (dladdr(ret, &info))
3251                 TRACE("%s -> %s from %s\n", proc, info.dli_sname, info.dli_fname);
3252             else
3253                 TRACE("%s -> %p (no library info)\n", proc, ret);
3254         }
3255     }
3256     else
3257         WARN("failed to find proc %s\n", debugstr_a(proc));
3258     return ret;
3259 }
3260
3261 /***********************************************************************
3262  *              macdrv_wglMakeCurrent
3263  */
3264 static BOOL macdrv_wglMakeCurrent(HDC hdc, struct wgl_context *context)
3265 {
3266     TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL),
3267           (context ? context->cglcontext : NULL));
3268
3269     return macdrv_wglMakeContextCurrentARB(hdc, hdc, context);
3270 }
3271
3272 /**********************************************************************
3273  *              macdrv_wglSetPixelFormat
3274  */
3275 static BOOL macdrv_wglSetPixelFormat(HDC hdc, int fmt, const PIXELFORMATDESCRIPTOR *descr)
3276 {
3277     return set_pixel_format(hdc, fmt, FALSE);
3278 }
3279
3280 /***********************************************************************
3281  *              macdrv_wglShareLists
3282  */
3283 static BOOL macdrv_wglShareLists(struct wgl_context *org, struct wgl_context *dest)
3284 {
3285     macdrv_opengl_context saved_context;
3286     CGLContextObj saved_cglcontext;
3287
3288     TRACE("org %p dest %p\n", org, dest);
3289
3290     /* Sharing of display lists works differently in Mac OpenGL and WGL.  In Mac OpenGL it is done
3291      * at context creation time but in case of WGL it is done using wglShareLists.
3292      *
3293      * The approach is to create a Mac OpenGL context in wglCreateContext / wglCreateContextAttribsARB
3294      * and when a program requests sharing we recreate the destination context if it hasn't been made
3295      * current or when it hasn't shared display lists before.
3296      */
3297
3298     if (dest->has_been_current)
3299     {
3300         WARN("could not share display lists, the destination context has been current already\n");
3301         return FALSE;
3302     }
3303     else if (dest->sharing)
3304     {
3305         WARN("could not share display lists because dest has already shared lists before\n");
3306         return FALSE;
3307     }
3308
3309     /* Re-create the Mac context and share display lists */
3310     saved_context = dest->context;
3311     saved_cglcontext = dest->cglcontext;
3312     dest->context = NULL;
3313     dest->cglcontext = NULL;
3314     if (!create_context(dest, org->cglcontext))
3315     {
3316         dest->context = saved_context;
3317         dest->cglcontext = saved_cglcontext;
3318         return FALSE;
3319     }
3320
3321     /* Implicitly disposes of saved_cglcontext. */
3322     macdrv_dispose_opengl_context(saved_context);
3323
3324     TRACE("re-created OpenGL context %p/%p/%p sharing lists with context %p/%p/%p\n",
3325           dest, dest->context, dest->cglcontext, org, org->context, org->cglcontext);
3326
3327     org->sharing = TRUE;
3328     dest->sharing = TRUE;
3329
3330     return TRUE;
3331 }
3332
3333 /**********************************************************************
3334  *              macdrv_wglSwapBuffers
3335  */
3336 static BOOL macdrv_wglSwapBuffers(HDC hdc)
3337 {
3338     struct wgl_context *context = NtCurrentTeb()->glContext;
3339
3340     TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL),
3341           (context ? context->cglcontext : NULL));
3342
3343     if (!context)
3344     {
3345         SetLastError(ERROR_INVALID_HANDLE);
3346         return FALSE;
3347     }
3348
3349     macdrv_flush_opengl_context(context->context);
3350     return TRUE;
3351 }
3352
3353 static struct opengl_funcs opengl_funcs =
3354 {
3355     {
3356         macdrv_wglCopyContext,          /* p_wglCopyContext */
3357         macdrv_wglCreateContext,        /* p_wglCreateContext */
3358         macdrv_wglDeleteContext,        /* p_wglDeleteContext */
3359         macdrv_wglDescribePixelFormat,  /* p_wglDescribePixelFormat */
3360         macdrv_wglGetPixelFormat,       /* p_wglGetPixelFormat */
3361         macdrv_wglGetProcAddress,       /* p_wglGetProcAddress */
3362         macdrv_wglMakeCurrent,          /* p_wglMakeCurrent */
3363         macdrv_wglSetPixelFormat,       /* p_wglSetPixelFormat */
3364         macdrv_wglShareLists,           /* p_wglShareLists */
3365         macdrv_wglSwapBuffers,          /* p_wglSwapBuffers */
3366     }
3367 };
3368
3369 /**********************************************************************
3370  *              macdrv_wine_get_wgl_driver
3371  */
3372 struct opengl_funcs *macdrv_wine_get_wgl_driver(PHYSDEV dev, UINT version)
3373 {
3374     if (version != WINE_WGL_DRIVER_VERSION)
3375     {
3376         ERR("version mismatch, opengl32 wants %u but macdrv has %u\n", version, WINE_WGL_DRIVER_VERSION);
3377         return NULL;
3378     }
3379
3380     if (!init_opengl()) return (void *)-1;
3381
3382     return &opengl_funcs;
3383 }