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