winemac: Implement WGL_EXT_swap_control.
[wine] / dlls / winemac.drv / cocoa_opengl.m
1 /*
2  * MACDRV Cocoa OpenGL code
3  *
4  * Copyright 2012, 2013 Ken Thomases for CodeWeavers Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #import "cocoa_opengl.h"
22
23 #include "macdrv_cocoa.h"
24
25
26 @interface WineOpenGLContext ()
27 @property (retain, nonatomic) NSView* latentView;
28 @end
29
30
31 @implementation WineOpenGLContext
32 @synthesize latentView, needsUpdate;
33
34     - (void) dealloc
35     {
36         [latentView release];
37         [super dealloc];
38     }
39
40 @end
41
42
43 /***********************************************************************
44  *              macdrv_create_opengl_context
45  *
46  * Returns a Cocoa OpenGL context created from a CoreGL context.  The
47  * caller is responsible for calling macdrv_dispose_opengl_context()
48  * when done with the context object.
49  */
50 macdrv_opengl_context macdrv_create_opengl_context(void* cglctx)
51 {
52     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
53     WineOpenGLContext *context;
54
55     context = [[WineOpenGLContext alloc] initWithCGLContextObj:cglctx];
56
57     [pool release];
58     return (macdrv_opengl_context)context;
59 }
60
61 /***********************************************************************
62  *              macdrv_dispose_opengl_context
63  *
64  * Destroys a Cocoa OpenGL context previously created by
65  * macdrv_create_opengl_context();
66  */
67 void macdrv_dispose_opengl_context(macdrv_opengl_context c)
68 {
69     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
70     WineOpenGLContext *context = (WineOpenGLContext*)c;
71
72     if ([context view])
73         macdrv_remove_view_opengl_context((macdrv_view)[context view], c);
74     if ([context latentView])
75         macdrv_remove_view_opengl_context((macdrv_view)[context latentView], c);
76     [context clearDrawable];
77     [context release];
78
79     [pool release];
80 }
81
82 /***********************************************************************
83  *              macdrv_make_context_current
84  */
85 void macdrv_make_context_current(macdrv_opengl_context c, macdrv_view v)
86 {
87     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
88     WineOpenGLContext *context = (WineOpenGLContext*)c;
89     NSView* view = (NSView*)v;
90
91     if (context)
92     {
93         if ([context view])
94             macdrv_remove_view_opengl_context((macdrv_view)[context view], c);
95         if ([context latentView])
96             macdrv_remove_view_opengl_context((macdrv_view)[context latentView], c);
97         context.needsUpdate = FALSE;
98         if (view)
99         {
100             macdrv_add_view_opengl_context(v, c);
101             [context setLatentView:view];
102             [context makeCurrentContext];
103         }
104         else
105         {
106             [WineOpenGLContext clearCurrentContext];
107             [context clearDrawable];
108         }
109     }
110     else
111         [WineOpenGLContext clearCurrentContext];
112
113     [pool release];
114 }
115
116 /***********************************************************************
117  *              macdrv_update_opengl_context
118  */
119 void macdrv_update_opengl_context(macdrv_opengl_context c)
120 {
121     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
122     WineOpenGLContext *context = (WineOpenGLContext*)c;
123
124     if (context.needsUpdate)
125     {
126         context.needsUpdate = FALSE;
127         if (context.latentView)
128         {
129             [context setView:context.latentView];
130             context.latentView = nil;
131         }
132         else
133             [context update];
134     }
135
136     [pool release];
137 }
138
139 /***********************************************************************
140  *              macdrv_flush_opengl_context
141  *
142  * Performs an implicit glFlush() and then swaps the back buffer to the
143  * front (if the context is double-buffered).
144  */
145 void macdrv_flush_opengl_context(macdrv_opengl_context c)
146 {
147     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
148     WineOpenGLContext *context = (WineOpenGLContext*)c;
149
150     macdrv_update_opengl_context(c);
151     [context flushBuffer];
152
153     [pool release];
154 }