hostsupport/hostopenvg/src/src/macosx/riEGLOS.cpp
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 24 a3f46bb01be2
equal deleted inserted replaced
52:39e5f73667ba 53:c2ef9095503a
       
     1 /*------------------------------------------------------------------------
       
     2  *
       
     3  * EGL 1.3
       
     4  * -------
       
     5  *
       
     6  * Copyright (c) 2007 The Khronos Group Inc.
       
     7  *
       
     8  * Permission is hereby granted, free of charge, to any person obtaining a
       
     9  * copy of this software and /or associated documentation files
       
    10  * (the "Materials "), to deal in the Materials without restriction,
       
    11  * including without limitation the rights to use, copy, modify, merge,
       
    12  * publish, distribute, sublicense, and/or sell copies of the Materials,
       
    13  * and to permit persons to whom the Materials are furnished to do so,
       
    14  * subject to the following conditions: 
       
    15  *
       
    16  * The above copyright notice and this permission notice shall be included 
       
    17  * in all copies or substantial portions of the Materials. 
       
    18  *
       
    19  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       
    22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
       
    23  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
       
    24  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
       
    25  * THE USE OR OTHER DEALINGS IN THE MATERIALS.
       
    26  *
       
    27  *//**
       
    28  * \file
       
    29  * \brief	Mac OS X specific EGL functionality
       
    30  * \note
       
    31   *//*-------------------------------------------------------------------*/
       
    32 
       
    33 #include "egl.h"
       
    34 #include "riImage.h"
       
    35 #include <pthread.h>
       
    36 #include <sys/errno.h>
       
    37 
       
    38 namespace OpenVGRI
       
    39 {
       
    40 
       
    41 /*-------------------------------------------------------------------*//*!
       
    42 * \brief	
       
    43 * \param	
       
    44 * \return	
       
    45 * \note		
       
    46 *//*-------------------------------------------------------------------*/
       
    47 
       
    48 void* OSGetCurrentThreadID(void)
       
    49 {
       
    50 	return (void*)pthread_self();   //TODO this is not safe
       
    51 }
       
    52 
       
    53 /*-------------------------------------------------------------------*//*!
       
    54 * \brief	
       
    55 * \param	
       
    56 * \return	
       
    57 * \note		
       
    58 *//*-------------------------------------------------------------------*/
       
    59 
       
    60 static pthread_mutex_t mutex;
       
    61 static int mutexRefCount = 0;
       
    62 static bool mutexInitialized = false;
       
    63 //acquired mutex cannot be deinited
       
    64 void OSDeinitMutex(void)
       
    65 {
       
    66 	RI_ASSERT(mutexInitialized);
       
    67 	RI_ASSERT(mutexRefCount == 0);
       
    68 	int ret = pthread_mutex_destroy(&mutex);
       
    69 	RI_ASSERT(ret != EINVAL);	//assert that the mutex has been initialized
       
    70 	RI_ASSERT(ret != EAGAIN);	//assert that the maximum number of recursive locks hasn't been exceeded
       
    71 	RI_ASSERT(!ret);	//check that there aren't other errors
       
    72 	RI_UNREF(ret);
       
    73 }
       
    74 void OSAcquireMutex(void)
       
    75 {
       
    76 	if(!mutexInitialized)
       
    77     {
       
    78         int ret;
       
    79         pthread_mutexattr_t attr;
       
    80         ret = pthread_mutexattr_init(&attr);	//initially not locked
       
    81         RI_ASSERT(!ret);	//check that there aren't any errors
       
    82         ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);	//count the number of recursive locks
       
    83         RI_ASSERT(!ret);	//check that there aren't any errors
       
    84         ret = pthread_mutex_init(&mutex, &attr);
       
    85         pthread_mutexattr_destroy(&attr);
       
    86         RI_ASSERT(!ret);	//check that there aren't more errors
       
    87         RI_UNREF(ret);
       
    88         mutexInitialized = true;
       
    89     }
       
    90 	int ret = pthread_mutex_lock(&mutex);
       
    91 	RI_ASSERT(ret != EINVAL);	//assert that the mutex has been initialized
       
    92 	RI_ASSERT(ret != EAGAIN);	//assert that the maximum number of recursive locks hasn't been exceeded
       
    93 	RI_ASSERT(ret != EDEADLK);	//recursive mutexes shouldn't return this
       
    94 	RI_ASSERT(!ret);	//check that there aren't other errors
       
    95 	RI_UNREF(ret);
       
    96 	mutexRefCount++;
       
    97 }
       
    98 void OSReleaseMutex(void)
       
    99 {
       
   100 	RI_ASSERT(mutexInitialized);
       
   101 	mutexRefCount--;
       
   102 	RI_ASSERT(mutexRefCount >= 0);
       
   103 	int ret = pthread_mutex_unlock(&mutex);
       
   104 	RI_ASSERT(ret != EPERM);	//assert that the current thread owns the mutex
       
   105 	RI_ASSERT(!ret);	//check that there aren't more errors
       
   106 	RI_UNREF(ret);
       
   107 }
       
   108 
       
   109 /*-------------------------------------------------------------------*//*!
       
   110 * \brief	
       
   111 * \param	
       
   112 * \return	
       
   113 * \note		
       
   114 *//*-------------------------------------------------------------------*/
       
   115 
       
   116 static bool isBigEndian()
       
   117 {
       
   118 	static const RIuint32 v = 0x12345678u;
       
   119 	const RIuint8* p = (const RIuint8*)&v;
       
   120 	RI_ASSERT (*p == (RIuint8)0x12u || *p == (RIuint8)0x78u);
       
   121 	return (*p == (RIuint8)(0x12)) ? true : false;
       
   122 }
       
   123 
       
   124 
       
   125 /*-------------------------------------------------------------------*//*!
       
   126 * \brief	
       
   127 * \param	
       
   128 * \return	
       
   129 * \note		
       
   130 *//*-------------------------------------------------------------------*/
       
   131 
       
   132 #ifdef RI_USE_GLUT
       
   133 #   include <OpenGL/gl.h>
       
   134 #   include <GLUT/glut.h>
       
   135 
       
   136 struct OSWindowContext
       
   137 {
       
   138     int                 window;
       
   139     unsigned int*       tmp;
       
   140     int                 tmpWidth;
       
   141     int                 tmpHeight;
       
   142 };
       
   143 
       
   144 OSWindowContext* OSCreateWindowContext(EGLNativeWindowType window)
       
   145 {
       
   146     try
       
   147     {
       
   148         OSWindowContext* ctx = RI_NEW(OSWindowContext, ());
       
   149         ctx->window = window;
       
   150         ctx->tmp = NULL;
       
   151         ctx->tmpWidth = 0;
       
   152         ctx->tmpHeight = 0;
       
   153         return ctx;
       
   154     }
       
   155 	catch(std::bad_alloc)
       
   156 	{
       
   157 		return NULL;
       
   158 	}
       
   159 }
       
   160 
       
   161 void OSDestroyWindowContext(OSWindowContext* ctx)
       
   162 {
       
   163     if(ctx)
       
   164     {
       
   165         RI_DELETE_ARRAY(ctx->tmp);
       
   166         RI_DELETE(ctx);
       
   167     }
       
   168 }
       
   169 
       
   170 bool OSIsWindow(const void* context)
       
   171 {
       
   172     OSWindowContext* ctx = (OSWindowContext*)context;
       
   173     if(ctx)
       
   174     {
       
   175         //TODO implement
       
   176         return true;
       
   177     }
       
   178     return false;
       
   179 }
       
   180 
       
   181 void OSGetWindowSize(const OSWindowContext* ctx, int& width, int& height)
       
   182 {
       
   183     if(ctx)
       
   184     {
       
   185         int currWin = glutGetWindow();
       
   186         glutSetWindow((int)ctx->window);
       
   187         width = glutGet(GLUT_WINDOW_WIDTH);
       
   188         height = glutGet(GLUT_WINDOW_HEIGHT);
       
   189         glutSetWindow(currWin);
       
   190     }
       
   191     else
       
   192     {
       
   193         width = 0;
       
   194         height = 0;
       
   195     }
       
   196 }
       
   197 
       
   198 void OSBlitToWindow(OSWindowContext* ctx, const Drawable* drawable)
       
   199 {
       
   200     if(ctx)
       
   201     {
       
   202         int w = drawable->getWidth();
       
   203         int h = drawable->getHeight();
       
   204 
       
   205         int currWin = glutGetWindow();
       
   206         glutSetWindow((int)ctx->window);
       
   207 
       
   208         if(!ctx->tmp || ctx->tmpWidth != w || ctx->tmpHeight != h)
       
   209         {
       
   210             RI_DELETE_ARRAY(ctx->tmp);
       
   211             ctx->tmp = NULL;
       
   212             try
       
   213             {
       
   214                 ctx->tmp = RI_NEW_ARRAY(unsigned int, w*h);	//throws bad_alloc
       
   215                 ctx->tmpWidth = w;
       
   216                 ctx->tmpHeight = h;
       
   217             }
       
   218             catch(std::bad_alloc)
       
   219             {
       
   220                 //do nothing
       
   221             }
       
   222         }
       
   223 
       
   224         if(ctx->tmp)
       
   225         {
       
   226             glViewport(0, 0, w, h);
       
   227             glDisable(GL_DEPTH_TEST);
       
   228             glMatrixMode(GL_PROJECTION);
       
   229             glLoadIdentity();
       
   230             glMatrixMode(GL_MODELVIEW);
       
   231             glLoadIdentity();
       
   232             //NOTE: we assume here that the display is always in sRGB color space
       
   233             VGImageFormat f = VG_sXBGR_8888;
       
   234             if(isBigEndian())
       
   235                 f = VG_sRGBX_8888;
       
   236             vgReadPixels(ctx->tmp, w*sizeof(unsigned int), f, 0, 0, w, h);
       
   237             glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, ctx->tmp);
       
   238         }
       
   239 
       
   240         glutSwapBuffers();	//shows the OpenGL frame buffer
       
   241         glutSetWindow(currWin);		//restore the current window
       
   242     }
       
   243 }
       
   244 
       
   245 #else
       
   246 
       
   247 /*-------------------------------------------------------------------*//*!
       
   248 * \brief	
       
   249 * \param	
       
   250 * \return	
       
   251 * \note		
       
   252 *//*-------------------------------------------------------------------*/
       
   253 
       
   254 //Mac OS X native
       
   255 #include <OpenGL/gl.h>
       
   256 #include <AGL/agl.h>
       
   257 
       
   258 struct OSWindowContext
       
   259 {
       
   260     AGLPixelFormat      aglPixFmt;
       
   261     AGLContext          aglContext;
       
   262     WindowPtr           window;
       
   263     unsigned int*       tmp;
       
   264     int                 tmpWidth;
       
   265     int                 tmpHeight;
       
   266 };
       
   267 
       
   268 void* OSCreateWindowContext(EGLNativeWindowType window)
       
   269 {
       
   270     OSWindowContext* ctx = NULL;
       
   271     try
       
   272     {
       
   273         ctx = RI_NEW(OSWindowContext, ());
       
   274     }
       
   275 	catch(std::bad_alloc)
       
   276 	{
       
   277 		return NULL;
       
   278 	}
       
   279 
       
   280     GLint attrib[] = { AGL_RGBA, AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 32, AGL_NONE };
       
   281     ctx->aglPixFmt = aglChoosePixelFormat(NULL, 0, attrib);
       
   282     if(!ctx->aglPixFmt)
       
   283     {
       
   284         RI_DELETE(ctx);
       
   285         return NULL;
       
   286     }
       
   287 
       
   288     ctx->aglContext = aglCreateContext(ctx->aglPixFmt, NULL);
       
   289     if(!ctx->aglContext)
       
   290     {
       
   291         aglDestroyPixelFormat(ctx->aglPixFmt);
       
   292         RI_DELETE(ctx);
       
   293         return NULL;
       
   294     }
       
   295 
       
   296     GLint opaque = 1;
       
   297     GLint sync = 1;
       
   298     aglSetInteger(ctx->aglContext, AGL_SURFACE_OPACITY, &opaque);
       
   299     aglSetInteger(ctx->aglContext, AGL_SWAP_INTERVAL, &sync);
       
   300 
       
   301     ctx->window = (WindowPtr)window;
       
   302     ctx->tmp = NULL;
       
   303     ctx->tmpWidth = 0;
       
   304     ctx->tmpHeight = 0;
       
   305     return ctx;
       
   306 }
       
   307 
       
   308 void OSDestroyWindowContext(void* context)
       
   309 {
       
   310     OSWindowContext* ctx = (OSWindowContext*)context;
       
   311     if(ctx)
       
   312     {
       
   313         aglSetDrawable(ctx->aglContext, NULL);
       
   314         aglSetCurrentContext(NULL);
       
   315         aglDestroyContext(ctx->aglContext);
       
   316         aglDestroyPixelFormat(ctx->aglPixFmt);
       
   317         RI_DELETE_ARRAY(ctx->tmp);
       
   318         RI_DELETE(ctx);
       
   319     }
       
   320 }
       
   321 
       
   322 bool OSIsWindow(const void* context)
       
   323 {
       
   324     OSWindowContext* ctx = (OSWindowContext*)context;
       
   325     if(ctx)
       
   326     {
       
   327         if(IsValidWindowPtr(ctx->window))
       
   328             return true;
       
   329     }
       
   330     return false;
       
   331 }
       
   332 
       
   333 void OSGetWindowSize(const void* context, int& width, int& height)
       
   334 {
       
   335     OSWindowContext* ctx = (OSWindowContext*)context;
       
   336     if(ctx)
       
   337     {
       
   338         Rect rectPort;
       
   339         GetWindowPortBounds(ctx->window, &rectPort);
       
   340         width = rectPort.right - rectPort.left;
       
   341         height = rectPort.bottom - rectPort.top;
       
   342     }
       
   343     else
       
   344     {
       
   345         width = 0;
       
   346         height = 0;
       
   347     }
       
   348 }
       
   349 
       
   350 void OSBlitToWindow(void* context, const Drawable* drawable)
       
   351 {
       
   352     OSWindowContext* ctx = (OSWindowContext*)context;
       
   353     if(ctx)
       
   354     {
       
   355         int w = drawable->getWidth();
       
   356         int h = drawable->getHeight();
       
   357 
       
   358         GrafPtr portSave = NULL;
       
   359         GetPort(&portSave);
       
   360         SetPort((GrafPtr)GetWindowPort(ctx->window));
       
   361         aglSetDrawable(ctx->aglContext, GetWindowPort(ctx->window));
       
   362         aglSetCurrentContext(ctx->aglContext);
       
   363 
       
   364         if(!ctx->tmp || ctx->tmpWidth != w || ctx->tmpHeight != h)
       
   365         {
       
   366             RI_DELETE_ARRAY(ctx->tmp);
       
   367             ctx->tmp = NULL;
       
   368             try
       
   369             {
       
   370                 ctx->tmp = RI_NEW_ARRAY(unsigned int, w*h);	//throws bad_alloc
       
   371                 ctx->tmpWidth = w;
       
   372                 ctx->tmpHeight = h;
       
   373             }
       
   374             catch(std::bad_alloc)
       
   375             {
       
   376                 //do nothing
       
   377             }
       
   378         }
       
   379 
       
   380         if(ctx->tmp)
       
   381         {
       
   382             glViewport(0, 0, w, h);
       
   383             glDisable(GL_DEPTH_TEST);
       
   384             glMatrixMode(GL_PROJECTION);
       
   385             glLoadIdentity();
       
   386             glMatrixMode(GL_MODELVIEW);
       
   387             glLoadIdentity();
       
   388             //NOTE: we assume here that the display is always in sRGB color space
       
   389             VGImageFormat f = VG_sXBGR_8888;
       
   390             if(isBigEndian())
       
   391                 f = VG_sRGBX_8888;
       
   392             vgReadPixels(ctx->tmp, w*sizeof(unsigned int), f, 0, 0, w, h);
       
   393             glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, ctx->tmp);
       
   394         }
       
   395 
       
   396         aglSwapBuffers(ctx->aglContext);
       
   397         SetPort(portSave);
       
   398     }
       
   399 }
       
   400 
       
   401 #endif
       
   402 
       
   403 EGLDisplay OSGetDisplay(EGLNativeDisplayType display_id)
       
   404 {
       
   405     RI_UNREF(display_id);
       
   406     return (EGLDisplay)1;    //support only a single display
       
   407 }
       
   408 
       
   409 }   //namespace OpenVGRI