0028466: Visualization, OpenGl_Context - read GPU memory using WGL_AMD_gpu_associatio...
[occt.git] / src / OpenGl / OpenGl_Window_1.mm
CommitLineData
6aca4d39 1// Created on: 2012-11-12
4fe56619 2// Created by: Kirill Gavrilov
6aca4d39 3// Copyright (c) 2012-2014 OPEN CASCADE SAS
4fe56619 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
4fe56619 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
4fe56619 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
4fe56619 15
16#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
17
0e9d3b83 18#define GL_GLEXT_LEGACY // To prevent inclusion of system glext.h on Mac OS X 10.6.8
19
a2e4f780 20#import <TargetConditionals.h>
21
22#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
23 #import <UIKit/UIKit.h>
24#else
25 #import <Cocoa/Cocoa.h>
26
27#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
28@interface NSView (LionAPI)
29- (NSSize )convertSizeToBacking: (NSSize )theSize;
30@end
31#endif
32
33#endif
4fe56619 34
4fe56619 35#include <OpenGl_Window.hxx>
a2e4f780 36#include <OpenGl_FrameBuffer.hxx>
4fe56619 37
38#include <OpenGl_Context.hxx>
4fe56619 39#include <Aspect_GraphicDeviceDefinitionError.hxx>
40#include <Cocoa_LocalPool.hxx>
41#include <TCollection_AsciiString.hxx>
4e1523ef 42#include <TCollection_ExtendedString.hxx>
4fe56619 43
a2e4f780 44#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
45 //
46#else
47 #include <OpenGL/CGLRenderers.h>
48#endif
abe46077 49
4fe56619 50// =======================================================================
51// function : OpenGl_Window
52// purpose :
53// =======================================================================
c7ccbb77 54OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
c357e426 55 const Handle(Aspect_Window)& thePlatformWindow,
4fe56619 56 Aspect_RenderingContext theGContext,
58655684 57 const Handle(OpenGl_Caps)& theCaps,
4fe56619 58 const Handle(OpenGl_Context)& theShareCtx)
73192b37 59: myGlContext (new OpenGl_Context (theCaps)),
4fe56619 60 myOwnGContext (theGContext == 0),
c357e426 61 myPlatformWindow (thePlatformWindow),
62#if defined(__APPLE__) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
a2e4f780 63 myUIView (NULL),
64#endif
f978241f 65 mySwapInterval (theCaps->swapInterval)
4fe56619 66{
5ef127d0 67 (void )theDriver;
c357e426 68 myPlatformWindow->Size (myWidth, myHeight);
69
70#if defined(__APPLE__)
71 myWidthPt = myWidth;
72 myHeightPt = myHeight;
73#endif
4fe56619 74
a2e4f780 75#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
76 EAGLContext* aGLContext = theGContext;
77 if (aGLContext == NULL)
4e1523ef 78 {
c357e426 79 void* aViewPtr = (void* )myPlatformWindow->NativeHandle();
a2e4f780 80
81 myUIView = (__bridge UIView* )aViewPtr;
82 CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
83 anEaglLayer.opaque = TRUE;
84 anEaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
85 [NSNumber numberWithBool: FALSE], kEAGLDrawablePropertyRetainedBacking,
86 kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
87 NULL];
88
89 aGLContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
90 if (aGLContext == NULL
91 || ![EAGLContext setCurrentContext: aGLContext])
92 {
93 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext creation failed");
9775fa61 94 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 95 return;
96 }
97
98 myGlContext->Init (aGLContext, Standard_False);
4e1523ef 99 }
100 else
abe46077 101 {
a2e4f780 102 if (![EAGLContext setCurrentContext: aGLContext])
103 {
104 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext can not be assigned");
9775fa61 105 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 106 return;
107 }
108
109 myGlContext->Init (aGLContext, Standard_False);
4e1523ef 110 }
a2e4f780 111#else
112
113 Cocoa_LocalPool aLocalPool;
114
115 // all GL context within one OpenGl_GraphicDriver should be shared!
116 NSOpenGLContext* aGLCtxShare = theShareCtx.IsNull() ? NULL : theShareCtx->myGContext;
117 NSOpenGLContext* aGLContext = theGContext;
118 bool isCore = false;
119 if (aGLContext == NULL)
4e1523ef 120 {
a2e4f780 121 NSOpenGLPixelFormatAttribute anAttribs[32] = {};
122 Standard_Integer aLastAttrib = 0;
123 //anAttribs[aLastAttrib++] = NSOpenGLPFAColorSize; anAttribs[aLastAttrib++] = 32,
124 anAttribs[aLastAttrib++] = NSOpenGLPFADepthSize; anAttribs[aLastAttrib++] = 24;
125 anAttribs[aLastAttrib++] = NSOpenGLPFAStencilSize; anAttribs[aLastAttrib++] = 8;
126 anAttribs[aLastAttrib++] = NSOpenGLPFADoubleBuffer;
127 if (theCaps->contextNoAccel)
4e1523ef 128 {
a2e4f780 129 anAttribs[aLastAttrib++] = NSOpenGLPFARendererID;
130 anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID;
4e1523ef 131 }
a2e4f780 132 else
133 {
134 anAttribs[aLastAttrib++] = NSOpenGLPFAAccelerated;
135 }
136 anAttribs[aLastAttrib] = 0;
137 const Standard_Integer aLastMainAttrib = aLastAttrib;
138 Standard_Integer aTryCore = 0;
139 Standard_Integer aTryStereo = 0;
140 for (aTryCore = 1; aTryCore >= 0; --aTryCore)
4e1523ef 141 {
a2e4f780 142 aLastAttrib = aLastMainAttrib;
143 if (aTryCore == 1)
4e1523ef 144 {
a2e4f780 145 if (theCaps->contextCompatible)
4e1523ef 146 {
147 continue;
148 }
a2e4f780 149
150 // supported since OS X 10.7+
151 anAttribs[aLastAttrib++] = 99; // NSOpenGLPFAOpenGLProfile
152 anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core
4e1523ef 153 }
154
a2e4f780 155 for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo)
156 {
157 if (aTryStereo == 1)
158 {
159 if (!theCaps->contextStereo)
160 {
161 continue;
162 }
163 anAttribs[aLastAttrib++] = NSOpenGLPFAStereo;
164 }
165
166 anAttribs[aLastAttrib] = 0;
167
168 NSOpenGLPixelFormat* aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
169 aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
170 shareContext: aGLCtxShare];
171 if (aGLContext != NULL)
172 {
173 break;
174 }
175 }
4e1523ef 176
4e1523ef 177 if (aGLContext != NULL)
178 {
179 break;
180 }
181 }
182
a2e4f780 183 if (aGLContext == NULL)
4e1523ef 184 {
a2e4f780 185 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed");
9775fa61 186 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 187 return;
4e1523ef 188 }
4e1523ef 189
a2e4f780 190 if (aTryStereo == 0
191 && theCaps->contextStereo)
192 {
193 TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: QuadBuffer is unavailable!");
3b523c4c 194 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
a2e4f780 195 }
196 if (aTryCore == 0
197 && !theCaps->contextCompatible)
198 {
199 TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
3b523c4c 200 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
a2e4f780 201 }
4fe56619 202
c357e426 203 NSView* aView = (NSView* )myPlatformWindow->NativeHandle();
a2e4f780 204 [aGLContext setView: aView];
205 isCore = (aTryCore == 1);
4e1523ef 206 }
207
a2e4f780 208 myGlContext->Init (aGLContext, isCore);
209#endif
4fe56619 210
4fe56619 211 myGlContext->Share (theShareCtx);
f978241f 212 myGlContext->SetSwapInterval (mySwapInterval);
4fe56619 213 Init();
214}
215
216// =======================================================================
217// function : ~OpenGl_Window
218// purpose :
219// =======================================================================
220OpenGl_Window::~OpenGl_Window()
221{
a2e4f780 222 if (!myOwnGContext
223 || myGlContext.IsNull())
224 {
225 myGlContext.Nullify();
226 return;
227 }
228
229#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
230 myGlContext.Nullify();
231 [EAGLContext setCurrentContext: NULL];
232 myUIView = NULL;
233#else
234 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
4fe56619 235 myGlContext.Nullify();
236
237 [NSOpenGLContext clearCurrentContext];
a2e4f780 238 [aGLCtx clearDrawable];
239 [aGLCtx release];
240#endif
4fe56619 241}
242
243// =======================================================================
244// function : Resize
245// purpose : call_subr_resize
246// =======================================================================
c357e426 247void OpenGl_Window::Resize()
4fe56619 248{
4fe56619 249 // If the size is not changed - do nothing
c357e426 250 Standard_Integer aWidthPt = 0;
251 Standard_Integer aHeightPt = 0;
252 myPlatformWindow->Size (aWidthPt, aHeightPt);
253 if (myWidthPt == aWidthPt
254 && myHeightPt == aHeightPt)
4fe56619 255 {
5501f9a9 256 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
4fe56619 257 return;
5501f9a9 258 #else
259 // check backing store change (moving to another screen)
260 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
261 NSView* aView = [aGLCtx view];
262 if (![aView respondsToSelector: @selector(convertSizeToBacking:)])
263 {
264 return;
265 }
266
267 NSRect aBounds = [aView bounds];
268 NSSize aRes = [aView convertSizeToBacking: aBounds.size];
269 if (myWidth == Standard_Integer(aRes.width)
270 && myHeight == Standard_Integer(aRes.height))
271 {
272 return;
273 }
274 #endif
4fe56619 275 }
276
c357e426 277 myWidthPt = aWidthPt;
278 myHeightPt = aHeightPt;
4fe56619 279
280 Init();
281}
282
283// =======================================================================
284// function : Init
285// purpose :
286// =======================================================================
287void OpenGl_Window::Init()
288{
289 if (!Activate())
290 {
291 return;
292 }
293
a2e4f780 294#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
295 Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (NULL);
296 if (!aDefFbo.IsNull())
297 {
298 aDefFbo->Release (myGlContext.operator->());
299 }
300 else
301 {
302 aDefFbo = new OpenGl_FrameBuffer();
303 }
4fe56619 304
a2e4f780 305 if (myOwnGContext)
306 {
307 EAGLContext* aGLCtx = myGlContext->myGContext;
308 CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
309 GLuint aWinRBColor = 0;
310 ::glGenRenderbuffers (1, &aWinRBColor);
311 ::glBindRenderbuffer (GL_RENDERBUFFER, aWinRBColor);
312 [aGLCtx renderbufferStorage: GL_RENDERBUFFER fromDrawable: anEaglLayer];
313 ::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &myWidth);
314 ::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myHeight);
315 ::glBindRenderbuffer (GL_RENDERBUFFER, 0);
316
3c4b62a4 317 if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, aWinRBColor))
a2e4f780 318 {
319 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
9775fa61 320 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 321 return;
322 }
323 }
324 else
325 {
326 if (!aDefFbo->InitWrapper (myGlContext))
327 {
328 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO wrapper creation failed");
9775fa61 329 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 330 return;
331 }
4fe56619 332
a2e4f780 333 myWidth = aDefFbo->GetVPSizeX();
334 myHeight = aDefFbo->GetVPSizeY();
335 }
336 myGlContext->SetDefaultFrameBuffer (aDefFbo);
337 aDefFbo->BindBuffer (myGlContext);
338 aDefFbo.Nullify();
339#else
340 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
341 NSView* aView = [aGLCtx view];
342 NSRect aBounds = [aView bounds];
4fe56619 343
a2e4f780 344 // we should call this method each time when window is resized
345 [aGLCtx update];
4fe56619 346
a2e4f780 347 if ([aView respondsToSelector: @selector(convertSizeToBacking:)])
348 {
349 NSSize aRes = [aView convertSizeToBacking: aBounds.size];
350 myWidth = Standard_Integer(aRes.width);
351 myHeight = Standard_Integer(aRes.height);
352 }
353 else
354 {
355 myWidth = Standard_Integer(aBounds.size.width);
356 myHeight = Standard_Integer(aBounds.size.height);
357 }
358 myWidthPt = Standard_Integer(aBounds.size.width);
359 myHeightPt = Standard_Integer(aBounds.size.height);
360#endif
361
362 ::glDisable (GL_DITHER);
363 ::glDisable (GL_SCISSOR_TEST);
364 ::glViewport (0, 0, myWidth, myHeight);
365#if !defined(GL_ES_VERSION_2_0)
366 ::glDrawBuffer (GL_BACK);
367 if (myGlContext->core11 != NULL)
368 {
369 ::glMatrixMode (GL_MODELVIEW);
370 }
371#endif
4fe56619 372}
373
c357e426 374// =======================================================================
375// function : SetSwapInterval
376// purpose :
377// =======================================================================
378void OpenGl_Window::SetSwapInterval()
379{
380 if (mySwapInterval != myGlContext->caps->swapInterval)
381 {
382 mySwapInterval = myGlContext->caps->swapInterval;
383 myGlContext->SetSwapInterval (mySwapInterval);
384 }
385}
386
4fe56619 387#endif // __APPLE__