|
1 /* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 * |
|
3 * Permission is hereby granted, free of charge, to any person obtaining a |
|
4 * copy of this software and /or associated documentation files |
|
5 * (the "Materials "), to deal in the Materials without restriction, |
|
6 * including without limitation the rights to use, copy, modify, merge, |
|
7 * publish, distribute, sublicense, and/or sell copies of the Materials, |
|
8 * and to permit persons to whom the Materials are furnished to do so, |
|
9 * subject to the following conditions: |
|
10 * |
|
11 * The above copyright notice and this permission notice shall be included |
|
12 * in all copies or substantial portions of the Materials. |
|
13 * |
|
14 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR |
|
20 * THE USE OR OTHER DEALINGS IN THE MATERIALS. |
|
21 */ |
|
22 |
|
23 #include "SurfaceDescriptor.h" |
|
24 #include "BufferContainer.h" |
|
25 |
|
26 #include "sfEGLInterface.h" |
|
27 #include "riContext.h" |
|
28 #include "riPath.h" |
|
29 #include "vgext.h" |
|
30 #include "riImage.h" |
|
31 |
|
32 namespace |
|
33 { |
|
34 EGLtoVGInterface g_EGLtoVGInterface; |
|
35 } |
|
36 |
|
37 IEGLtoVGInterface* getVGInterface(void) |
|
38 { |
|
39 return &g_EGLtoVGInterface; |
|
40 } |
|
41 |
|
42 EGLtoVGInterface::EGLtoVGInterface() : |
|
43 m_egl(NULL) |
|
44 { |
|
45 m_contexts.reserve(4); |
|
46 } |
|
47 |
|
48 EGLtoVGInterface::~EGLtoVGInterface() |
|
49 { |
|
50 for(int i = 0; i < m_contexts.size(); i++) |
|
51 { |
|
52 RI_ASSERT(m_contexts[i]); |
|
53 RI_DELETE(m_contexts[i]); |
|
54 } |
|
55 } |
|
56 |
|
57 void EGLtoVGInterface::SetEGLInterface( IVGtoEGLInterface* egl ) |
|
58 { |
|
59 RI_ASSERT(!m_egl); |
|
60 m_egl = egl; |
|
61 } |
|
62 |
|
63 int EGLtoVGInterface::findContext(OpenVGRI::VGContext* contextPtr) |
|
64 { |
|
65 return m_contexts.findIndex(contextPtr); |
|
66 } |
|
67 |
|
68 bool EGLtoVGInterface::isValidImage(void* image) |
|
69 { |
|
70 bool ret = false; |
|
71 for(int i = 0; i < m_contexts.size() && !ret; i++) |
|
72 { |
|
73 ret = m_contexts[i]->isValidImage((VGImage)image); |
|
74 } |
|
75 return ret; |
|
76 } |
|
77 |
|
78 void* EGLtoVGInterface::CreateContext( void* shareContext ) |
|
79 { |
|
80 if (shareContext) |
|
81 { |
|
82 if (findContext((OpenVGRI::VGContext*)shareContext) < 0) |
|
83 return NULL; |
|
84 } |
|
85 |
|
86 OpenVGRI::VGContext* newContext = NULL; |
|
87 |
|
88 try |
|
89 { |
|
90 newContext = RI_NEW(OpenVGRI::VGContext, ((OpenVGRI::VGContext*)shareContext)); |
|
91 m_contexts.push_back(newContext); |
|
92 } |
|
93 catch (std::bad_alloc) |
|
94 { |
|
95 if (newContext) |
|
96 delete newContext; |
|
97 |
|
98 newContext = NULL; |
|
99 } |
|
100 |
|
101 return newContext; |
|
102 } |
|
103 |
|
104 bool EGLtoVGInterface::ReleaseContext( void* context ) |
|
105 { |
|
106 int contextIndex = findContext((OpenVGRI::VGContext*)context); |
|
107 |
|
108 if (contextIndex < 0) |
|
109 return false; |
|
110 |
|
111 OpenVGRI::VGContext* ctx = (OpenVGRI::VGContext*)context; |
|
112 if( !m_contexts.remove(ctx) ) |
|
113 return false; |
|
114 |
|
115 RI_DELETE(ctx); |
|
116 |
|
117 return true; |
|
118 } |
|
119 |
|
120 OpenVGRI::Color::Descriptor EGLtoVGInterface::vgDescriptorFromSurfaceDescriptor(const SurfaceDescriptor* sdesc) |
|
121 { |
|
122 const CColorDescriptor& scdesc = sdesc->m_colorDescriptor; |
|
123 OpenVGRI::Color::Descriptor vdesc; |
|
124 unsigned int formatBits = 0; |
|
125 |
|
126 // VG formats are built favoring the first ones in the enum (RGBA, RGBX, etc.) |
|
127 |
|
128 // Padded alpha (RGBX, etc.) must be handled. For example: |
|
129 // if (vdesc.bitsPerPixel < sdesc.bitsPerPixel) |
|
130 // alphabits = 0, alphashift = 8 |
|
131 vdesc.bitsPerPixel = scdesc.m_bpp; |
|
132 vdesc.bytesPerPixel = vdesc.bitsPerPixel >> 3; |
|
133 |
|
134 vdesc.alphaBits = scdesc.m_alphaSize; |
|
135 vdesc.alphaShift = sdesc->m_alphaShift; |
|
136 vdesc.redBits = scdesc.m_redSize; |
|
137 vdesc.redShift = sdesc->m_redShift; |
|
138 vdesc.greenBits = scdesc.m_greenSize; |
|
139 vdesc.greenShift = sdesc->m_greenShift; |
|
140 vdesc.blueBits = scdesc.m_blueSize; |
|
141 vdesc.blueShift = sdesc->m_blueShift; |
|
142 vdesc.luminanceBits = scdesc.m_luminanceSize; |
|
143 vdesc.luminanceShift = sdesc->m_luminanceShift; |
|
144 |
|
145 if(scdesc.isLuminance()) |
|
146 formatBits |= OpenVGRI::Color::LUMINANCE; |
|
147 |
|
148 // \note Could be copied if LUMINANCE == LUMINANCE, etc. |
|
149 if (scdesc.isPremultiplied()) |
|
150 formatBits |= OpenVGRI::Color::PREMULTIPLIED; |
|
151 |
|
152 if (scdesc.isNonlinear()) |
|
153 formatBits |= OpenVGRI::Color::NONLINEAR; |
|
154 |
|
155 vdesc.internalFormat = (OpenVGRI::Color::InternalFormat)formatBits; |
|
156 // \todo format |
|
157 vdesc.vgFormat = (VGImageFormat)-1; // Not necessarily any VG image format |
|
158 vdesc.shape = vdesc.getShape(); |
|
159 |
|
160 return vdesc; |
|
161 } |
|
162 |
|
163 bool EGLtoVGInterface::CreateSurface(const SurfaceDescriptor* desc, BufferContainer* buffers, void* image) |
|
164 { |
|
165 RI_ASSERT( buffers ); |
|
166 OpenVGRI::Color::Descriptor vgColorDescriptor; |
|
167 OpenVGRI::Image* newImage = NULL; |
|
168 if(image) |
|
169 { |
|
170 if(!isValidImage(image)) |
|
171 return false; |
|
172 newImage = (OpenVGRI::Image*)image; |
|
173 vgColorDescriptor = newImage->getDescriptor(); |
|
174 } |
|
175 else |
|
176 { |
|
177 vgColorDescriptor = vgDescriptorFromSurfaceDescriptor(desc); |
|
178 } |
|
179 OpenVGRI::Drawable* newDrawable = NULL; |
|
180 |
|
181 //VGImageQuality quality = VG_IMAGE_QUALITY_BETTER; |
|
182 |
|
183 int w = desc->m_width; |
|
184 int h = desc->m_height; |
|
185 int stride = OpenVGRI::Image::descriptorToStride(vgColorDescriptor, w); |
|
186 size_t bufSize = h * stride; |
|
187 |
|
188 OpenVGRI::RIuint8* dataPtr = NULL; |
|
189 |
|
190 try |
|
191 { |
|
192 int maskBits = 0; |
|
193 if( !newImage ) |
|
194 { |
|
195 newImage = RI_NEW(OpenVGRI::Image,(vgColorDescriptor, w, h, VG_IMAGE_QUALITY_BETTER)); |
|
196 maskBits = desc->m_maskSize; |
|
197 } |
|
198 else |
|
199 { |
|
200 dataPtr = newImage->getData(); |
|
201 maskBits = newImage->getDescriptor().maskBits; |
|
202 } |
|
203 newDrawable = RI_NEW(OpenVGRI::Drawable, (newImage, maskBits)); |
|
204 newDrawable->addReference(); |
|
205 } |
|
206 catch (std::bad_alloc) |
|
207 { |
|
208 if (dataPtr) RI_DELETE_ARRAY(dataPtr); |
|
209 if (newImage) RI_DELETE(newImage); |
|
210 if (newDrawable) RI_DELETE(newDrawable); |
|
211 |
|
212 return false; |
|
213 } |
|
214 buffers->m_clientSurface = newDrawable; |
|
215 buffers->m_colorBuffer = newDrawable->getColorBuffer()->getImage()->getData(); |
|
216 buffers->m_maskBuffer = newDrawable->getMaskBuffer(); |
|
217 return true; |
|
218 } |
|
219 |
|
220 bool EGLtoVGInterface::ReleaseSurface(void* surface) |
|
221 { |
|
222 RI_ASSERT(surface); |
|
223 |
|
224 OpenVGRI::Drawable *drawable = (OpenVGRI::Drawable*)surface; |
|
225 |
|
226 if (!drawable->removeReference()) |
|
227 RI_DELETE(drawable); |
|
228 |
|
229 return true; |
|
230 } |
|
231 |
|
232 bool EGLtoVGInterface::SetCurrentSurface( void* context, void* surface ) |
|
233 { |
|
234 OpenVGRI::Drawable* drawable = (OpenVGRI::Drawable*)surface; |
|
235 OpenVGRI::VGContext *ctx = (OpenVGRI::VGContext*)context; |
|
236 |
|
237 int i = findContext(ctx); |
|
238 |
|
239 if (i < 0) |
|
240 return false; |
|
241 |
|
242 ctx->setDefaultDrawable(drawable); |
|
243 |
|
244 return true; |
|
245 } |
|
246 |
|
247 bool EGLtoVGInterface::ResizeSurface( void* context, void* surface, int width, int height, BufferContainer* buffers ) |
|
248 { |
|
249 OpenVGRI::Drawable* drawable = (OpenVGRI::Drawable*)surface; |
|
250 OpenVGRI::VGContext *ctx = (OpenVGRI::VGContext*)context; |
|
251 int i = findContext(ctx); |
|
252 if(i < 0) |
|
253 return false; |
|
254 |
|
255 try |
|
256 { |
|
257 drawable->resize( ctx, width, height ); |
|
258 } |
|
259 catch (std::bad_alloc) |
|
260 { |
|
261 return false; |
|
262 } |
|
263 buffers->m_clientSurface = drawable; |
|
264 buffers->m_colorBuffer = drawable->getColorBuffer()->getImage()->getData(); |
|
265 buffers->m_maskBuffer = drawable->getMaskBuffer(); |
|
266 return true; |
|
267 } |
|
268 |
|
269 bool EGLtoVGInterface::IsValidImage( void* image, CColorDescriptor* colorDesc, int* width, int* height ) |
|
270 { |
|
271 bool ret = isValidImage(image); |
|
272 if(ret) |
|
273 { |
|
274 *width = ((OpenVGRI::Image*)image)->getWidth(); |
|
275 *height = ((OpenVGRI::Image*)image)->getHeight(); |
|
276 const OpenVGRI::Color::Descriptor& desc = ((OpenVGRI::Image*)image)->getDescriptor(); |
|
277 colorDesc->m_bpp = desc.bitsPerPixel; |
|
278 colorDesc->m_redSize = desc.redBits; |
|
279 colorDesc->m_greenSize = desc.greenBits; |
|
280 colorDesc->m_blueSize = desc.blueBits; |
|
281 colorDesc->m_alphaSize = desc.alphaBits; |
|
282 colorDesc->m_luminanceSize = desc.luminanceBits; |
|
283 colorDesc->m_alphaMaskSize = desc.maskBits; |
|
284 colorDesc->m_format = (CColorDescriptor::ColorFormat)desc.internalFormat; |
|
285 } |
|
286 |
|
287 return ret; |
|
288 } |
|
289 |
|
290 bool EGLtoVGInterface::IsImageInUse( void* image ) |
|
291 { |
|
292 bool ret = false; |
|
293 if(image && isValidImage(image)) |
|
294 { |
|
295 ret = ((OpenVGRI::Image*)image)->isInUse(); |
|
296 } |
|
297 return ret; |
|
298 } |
|
299 |
|
300 void* EGLtoVGInterface::CreateImage() |
|
301 { |
|
302 RI_ASSERT(false); |
|
303 return NULL; |
|
304 } |
|
305 |
|
306 bool EGLtoVGInterface::ReleaseImage() |
|
307 { |
|
308 RI_ASSERT(false); |
|
309 return false; |
|
310 } |
|
311 |
|
312 void EGLtoVGInterface::Flush() |
|
313 { |
|
314 vgFlush(); |
|
315 } |
|
316 |
|
317 void EGLtoVGInterface::Finish() |
|
318 { |
|
319 vgFinish(); |
|
320 } |
|
321 |
|
322 fpVGProc EGLtoVGInterface::GetVGProcAddress( const char *procname ) |
|
323 { |
|
324 fpVGProc ret = NULL; |
|
325 if(strcmp(procname, "vgePathCoordsSizeInBytes") == 0) |
|
326 { |
|
327 ret = (fpVGProc)vgePathCoordsSizeInBytes; |
|
328 } |
|
329 return ret; |
|
330 } |
|
331 |
|
332 void EGLtoVGInterface::CopyBuffers( void* buffer, int stride, void* surface ) |
|
333 { |
|
334 OpenVGRI::Drawable *drawable = (OpenVGRI::Drawable*)surface; |
|
335 int width = drawable->getColorBuffer()->getWidth(); |
|
336 int height = drawable->getColorBuffer()->getHeight(); |
|
337 // \todo Pixel format. |
|
338 VGImageFormat format = VG_sARGB_8888_PRE; |
|
339 vgReadPixels( buffer, stride, format, 0, 0, width, height ); |
|
340 } |
|
341 |
|
342 void EGLtoVGInterface::UpdateBuffers( void* buffer, int stride, const SurfaceDescriptor* desc ) |
|
343 { |
|
344 // \todo format, errors |
|
345 VGImageFormat format = VG_sARGB_8888_PRE; |
|
346 vgWritePixels( buffer, stride, format, 0, 0, desc->m_width, desc->m_height ); |
|
347 } |
|
348 |
|
349 bool EGLtoVGInterface::IsRootImage( void* image ) |
|
350 { |
|
351 if( !image ) return false; |
|
352 if ( vgGetParent( (VGImage)image ) ) |
|
353 { |
|
354 // if vgGetParent returns not NULL image it is not parent image |
|
355 // , only child image has parent image, and this should return false |
|
356 return false; |
|
357 } |
|
358 // vgGetParent is NULL and image is parent image |
|
359 return true; |
|
360 } |
|
361 |
|
362 void EGLtoVGInterface::GetImageData( void* image, SurfaceDescriptor& desc, void* data ) |
|
363 { |
|
364 OpenVGRI::Image* vgimage = (OpenVGRI::Image*)image; |
|
365 if( !image ) |
|
366 { |
|
367 return; |
|
368 } |
|
369 desc.m_height = vgimage->getHeight(); |
|
370 desc.m_width = vgimage->getWidth(); |
|
371 int bufSize; |
|
372 |
|
373 OpenVGRI::Color::Descriptor colorDesc = vgimage->getDescriptor(); |
|
374 VGImageFormat vgFormat; |
|
375 // Convert some formats into more GL-friendly formats. |
|
376 if( colorDesc.vgFormat == VG_BW_1 ) |
|
377 { |
|
378 vgFormat = VG_lL_8; |
|
379 } |
|
380 else if( colorDesc.vgFormat == VG_A_1 || colorDesc.vgFormat == VG_A_4 ) |
|
381 { |
|
382 vgFormat = VG_A_8; |
|
383 } |
|
384 else |
|
385 { |
|
386 vgFormat = colorDesc.vgFormat; |
|
387 } |
|
388 desc.m_colorDescriptor.m_format = (CColorDescriptor::ColorFormat)colorDesc.internalFormat; |
|
389 desc.m_alphaShift = colorDesc.alphaShift; |
|
390 desc.m_blueShift = colorDesc.blueShift; |
|
391 desc.m_greenShift = colorDesc.greenShift; |
|
392 desc.m_redShift = colorDesc.redShift; |
|
393 desc.m_luminanceShift = colorDesc.luminanceShift; |
|
394 desc.m_stride = vgimage->getStride(); |
|
395 |
|
396 bufSize = (desc.m_stride * desc.m_height); |
|
397 // Allocate data from memory. |
|
398 data = RI_NEW_ARRAY(OpenVGRI::RIuint8, bufSize); |
|
399 // Get data from VG |
|
400 vgGetImageSubData( (VGImage)vgimage, data, vgimage->getStride(), vgFormat, 0, 0, vgimage->getWidth(), vgimage->getWidth() ); |
|
401 |
|
402 } |
|
403 |
|
404 void EGLtoVGInterface::AddRef( void* image ) |
|
405 { |
|
406 OpenVGRI::Image* vgimage = (OpenVGRI::Image*)image; |
|
407 if( !image ) |
|
408 { |
|
409 return; |
|
410 } |
|
411 vgimage->addReference(); |
|
412 } |
|
413 |
|
414 void EGLtoVGInterface::RemoveRef( void* image ) |
|
415 { |
|
416 OpenVGRI::Image* vgimage = (OpenVGRI::Image*)image; |
|
417 if( !image ) |
|
418 { |
|
419 return; |
|
420 } |
|
421 vgimage->removeReference(); |
|
422 } |
|
423 |
|
424 /*static*/ IVGtoEGLInterface* EGLtoVGInterface::GetEGLInterface() |
|
425 { |
|
426 return g_EGLtoVGInterface.m_egl; |
|
427 } |
|
428 |
|
429 void* OpenVGRI::eglvgGetCurrentVGContext(void) |
|
430 { |
|
431 return EGLtoVGInterface::GetEGLInterface()->GetVGContext(); |
|
432 } |
|
433 |
|
434 bool OpenVGRI::eglvgIsInUse(void* image) |
|
435 { |
|
436 return EGLtoVGInterface::GetEGLInterface()->IsImageInUse(image); |
|
437 } |
|
438 |
|
439 bool OpenVGRI::eglvgLockSurface(bool read, bool write) |
|
440 { |
|
441 return EGLtoVGInterface::GetEGLInterface()->LockVGSurface(read, write); |
|
442 } |
|
443 |
|
444 bool OpenVGRI::eglvgUnlockSurface() |
|
445 { |
|
446 return EGLtoVGInterface::GetEGLInterface()->UnlockVGSurface(); |
|
447 } |
|
448 |
|
449 void OpenVGRI::OSAcquireMutex(void) |
|
450 { |
|
451 } |
|
452 |
|
453 void OpenVGRI::OSReleaseMutex(void) |
|
454 { |
|
455 } |
|
456 |
|
457 void OpenVGRI::eglvgGetImageDescriptor( void* image, Color::Descriptor &desc, int &width, int &height, int &stride ) |
|
458 { |
|
459 SurfaceDescriptor surfDesc; |
|
460 EGLtoVGInterface::GetEGLInterface()->GetDescForImage( image, surfDesc ); |
|
461 desc = EGLtoVGInterface::vgDescriptorFromSurfaceDescriptor( &surfDesc ); |
|
462 width = surfDesc.m_width; |
|
463 height = surfDesc.m_height; |
|
464 stride = surfDesc.m_stride; |
|
465 } |
|
466 |
|
467 void* OpenVGRI::eglvgGetImageData( void* image ) |
|
468 { |
|
469 return EGLtoVGInterface::GetEGLInterface()->GetDataForImage( image ); |
|
470 } |