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 |
|