hostsupport/hostopenvg/src/src/linux/riEGLOS.cpp
branchbug235_bringup_0
changeset 54 067180f57b12
parent 53 c2ef9095503a
child 55 09263774e342
equal deleted inserted replaced
53:c2ef9095503a 54:067180f57b12
     1 /*------------------------------------------------------------------------
       
     2  *
       
     3  * EGL 1.3
       
     4  * -------
       
     5  *
       
     6  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     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	Linux specific EGL functionality, modified from macosx source file
       
    30  * \note
       
    31   *//*-------------------------------------------------------------------*/
       
    32 
       
    33 #include "riEGLOS.h"
       
    34 
       
    35 #include <pthread.h>
       
    36 #include <sys/errno.h>
       
    37 #include <GL/gl.h>
       
    38 #include <GL/glut.h>
       
    39 
       
    40 #if defined(None)
       
    41 #   undef None
       
    42 #endif
       
    43 
       
    44 #include "sfCompiler.h"
       
    45 
       
    46 namespace OpenVGRI
       
    47 {
       
    48 
       
    49 /*-------------------------------------------------------------------*//*!
       
    50 * \brief
       
    51 * \param
       
    52 * \return
       
    53 * \note
       
    54 *//*-------------------------------------------------------------------*/
       
    55 
       
    56 void* OSGetCurrentThreadID(void)
       
    57 {
       
    58     return (void*)pthread_self();   //TODO this is not safe
       
    59 }
       
    60 
       
    61 /*-------------------------------------------------------------------*//*!
       
    62 * \brief
       
    63 * \param
       
    64 * \return
       
    65 * \note
       
    66 *//*-------------------------------------------------------------------*/
       
    67 
       
    68 static pthread_mutex_t mutex;
       
    69 static int mutexRefCount = 0;
       
    70 static bool mutexInitialized = false;
       
    71 //acquired mutex cannot be deinited
       
    72 void OSDeinitMutex(void)
       
    73 {
       
    74     RI_ASSERT(mutexInitialized);
       
    75     RI_ASSERT(mutexRefCount == 0);
       
    76     int ret = pthread_mutex_destroy(&mutex);
       
    77     RI_ASSERT(ret != EINVAL);	//assert that the mutex has been initialized
       
    78     RI_ASSERT(ret != EAGAIN);	//assert that the maximum number of recursive locks hasn't been exceeded
       
    79     RI_ASSERT(!ret);	//check that there aren't other errors
       
    80     RI_UNREF(ret);
       
    81 }
       
    82 void OSAcquireMutex(void)
       
    83 {
       
    84     if(!mutexInitialized)
       
    85     {
       
    86         int ret;
       
    87         pthread_mutexattr_t attr;
       
    88         ret = pthread_mutexattr_init(&attr);	//initially not locked
       
    89         RI_ASSERT(!ret);	//check that there aren't any errors
       
    90         ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);	//count the number of recursive locks
       
    91         RI_ASSERT(!ret);	//check that there aren't any errors
       
    92         ret = pthread_mutex_init(&mutex, &attr);
       
    93         pthread_mutexattr_destroy(&attr);
       
    94         RI_ASSERT(!ret);	//check that there aren't more errors
       
    95         RI_UNREF(ret);
       
    96         mutexInitialized = true;
       
    97     }
       
    98     int ret = pthread_mutex_lock(&mutex);
       
    99     RI_ASSERT(ret != EINVAL);	//assert that the mutex has been initialized
       
   100     RI_ASSERT(ret != EAGAIN);	//assert that the maximum number of recursive locks hasn't been exceeded
       
   101     RI_ASSERT(ret != EDEADLK);	//recursive mutexes shouldn't return this
       
   102     RI_ASSERT(!ret);	//check that there aren't other errors
       
   103     RI_UNREF(ret);
       
   104     mutexRefCount++;
       
   105 }
       
   106 void OSReleaseMutex(void)
       
   107 {
       
   108     RI_ASSERT(mutexInitialized);
       
   109     mutexRefCount--;
       
   110     RI_ASSERT(mutexRefCount >= 0);
       
   111     int ret = pthread_mutex_unlock(&mutex);
       
   112     RI_ASSERT(ret != EPERM);	//assert that the current thread owns the mutex
       
   113     RI_ASSERT(!ret);	//check that there aren't more errors
       
   114     RI_UNREF(ret);
       
   115 }
       
   116 
       
   117 /*-------------------------------------------------------------------*//*!
       
   118 * \brief
       
   119 * \param
       
   120 * \return
       
   121 * \note
       
   122 *//*-------------------------------------------------------------------*/
       
   123 
       
   124 static bool isBigEndian()
       
   125 {
       
   126     static const RIuint32 v = 0x12345678u;
       
   127     const RIuint8* p = (const RIuint8*)&v;
       
   128     RI_ASSERT (*p == (RIuint8)0x12u || *p == (RIuint8)0x78u);
       
   129     return (*p == (RIuint8)(0x12)) ? true : false;
       
   130 }
       
   131 
       
   132 
       
   133 /*-------------------------------------------------------------------*//*!
       
   134 * \brief
       
   135 * \param
       
   136 * \return
       
   137 * \note
       
   138 *//*-------------------------------------------------------------------*/
       
   139 
       
   140 OSWindowContext* OSCreateWindowContext(EGLNativeWindowType window)
       
   141 {
       
   142     try
       
   143     {
       
   144         OSWindowContext* ctx = RI_NEW(OSWindowContext, ());
       
   145         ctx->window = (int)window;
       
   146         ctx->tmp = NULL;
       
   147         ctx->tmpWidth = 0;
       
   148         ctx->tmpHeight = 0;
       
   149         return ctx;
       
   150     }
       
   151     catch(std::bad_alloc)
       
   152     {
       
   153         return NULL;
       
   154     }
       
   155 }
       
   156 
       
   157 void OSDestroyWindowContext(OSWindowContext* ctx)
       
   158 {
       
   159     if(ctx)
       
   160     {
       
   161         RI_DELETE_ARRAY(ctx->tmp);
       
   162         RI_DELETE(ctx);
       
   163     }
       
   164 }
       
   165 
       
   166 bool OSIsWindow(const OSWindowContext* context)
       
   167 {
       
   168     OSWindowContext* ctx = (OSWindowContext*)context;
       
   169     if(ctx)
       
   170     {
       
   171         //TODO implement
       
   172         return true;
       
   173     }
       
   174     return false;
       
   175 }
       
   176 
       
   177 void OSGetWindowSize(const OSWindowContext* ctx, int& width, int& height)
       
   178 {
       
   179     if(ctx)
       
   180     {
       
   181         int currWin = glutGetWindow();
       
   182         glutSetWindow((int)ctx->window);
       
   183         width = glutGet(GLUT_WINDOW_WIDTH);
       
   184         height = glutGet(GLUT_WINDOW_HEIGHT);
       
   185         glutSetWindow(currWin);
       
   186     }
       
   187     else
       
   188     {
       
   189         width = 0;
       
   190         height = 0;
       
   191     }
       
   192 }
       
   193 
       
   194 void OSBlitToWindow(OSWindowContext* ctx, const Drawable* drawable)
       
   195 {
       
   196     if(ctx)
       
   197     {
       
   198         int w = drawable->getWidth();
       
   199         int h = drawable->getHeight();
       
   200 
       
   201         int currWin = glutGetWindow();
       
   202         glutSetWindow((int)ctx->window);
       
   203 
       
   204         if(!ctx->tmp || ctx->tmpWidth != w || ctx->tmpHeight != h)
       
   205         {
       
   206             RI_DELETE_ARRAY(ctx->tmp);
       
   207             ctx->tmp = NULL;
       
   208             try
       
   209             {
       
   210                 ctx->tmp = RI_NEW_ARRAY(unsigned int, w*h);	//throws bad_alloc
       
   211                 ctx->tmpWidth = w;
       
   212                 ctx->tmpHeight = h;
       
   213             }
       
   214             catch(std::bad_alloc)
       
   215             {
       
   216                 //do nothing
       
   217             }
       
   218         }
       
   219 
       
   220         if(ctx->tmp)
       
   221         {
       
   222             glViewport(0, 0, w, h);
       
   223             glDisable(GL_DEPTH_TEST);
       
   224             glMatrixMode(GL_PROJECTION);
       
   225             glLoadIdentity();
       
   226             glMatrixMode(GL_MODELVIEW);
       
   227             glLoadIdentity();
       
   228             //NOTE: we assume here that the display is always in sRGB color space
       
   229             VGImageFormat f = VG_sABGR_8888_PRE;
       
   230             if(isBigEndian())
       
   231                 f = VG_sRGBA_8888_PRE;
       
   232             static bool flip = false;
       
   233             if (!flip)
       
   234             {
       
   235                 vgReadPixels(ctx->tmp, w*sizeof(unsigned int), f, 0, 0, w, h);
       
   236                 //flip = true;
       
   237             }
       
   238             else
       
   239             {
       
   240                 void* ptr = (void*)((RIuint8*)ctx->tmp + (w*sizeof(unsigned int)*(h-1)));
       
   241                 vgReadPixels(ptr, -w*sizeof(unsigned int), f, 0, 0, w, h);
       
   242                 flip = false;
       
   243             }
       
   244             glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, ctx->tmp);
       
   245         }
       
   246 
       
   247         glutSwapBuffers();	//shows the OpenGL frame buffer
       
   248         glutSetWindow(currWin);		//restore the current window
       
   249     }
       
   250 }
       
   251 
       
   252 EGLDisplay OSGetDisplay(EGLNativeDisplayType display_id)
       
   253 {
       
   254     RI_UNREF(display_id);
       
   255     return (EGLDisplay)1;    //support only a single display
       
   256 }
       
   257 
       
   258 }   //namespace OpenVGRI