os/graphics/graphicscomposition/openwfcompositionengine/composition/src/wfcapi.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /* Copyright (c) 2009-2010 The Khronos Group Inc.
     2  * Portions copyright (c) 2009-2010  Nokia Corporation and/or its subsidiary(-ies)
     3  *
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     5  * copy of this software and/or associated documentation files (the
     6  * "Materials"), to deal in the Materials without restriction, including
     7  * without limitation the rights to use, copy, modify, merge, publish,
     8  * distribute, sublicense, and/or sell copies of the Materials, and to
     9  * permit persons to whom the Materials are furnished to do so, subject to
    10  * the following conditions:
    11  *
    12  * The above copyright notice and this permission notice shall be included
    13  * in all copies or substantial portions of the Materials.
    14  *
    15  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    21  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
    22  */
    23 
    24 /*! \ingroup wfc
    25  *  \file wfcapi.c
    26  *  \brief OpenWF Composition SI, API implementation.
    27  *
    28  *  For function documentations, see OpenWF Composition specification 1.0
    29  *
    30  *  The general layout of an API function is:
    31  *  - grab API mutex (lock API)
    32  *  - check parameter validity
    33  *  - invoke implementation function (WFD_...)
    34  *  - unlock API
    35  *  - return
    36  *
    37  */
    38 
    39 #include <string.h>
    40 #include <stdio.h>
    41 #include <stdlib.h>
    42 #include <math.h>
    43 
    44 #include <WF/wfc.h>
    45 #include <WF/wfcext.h>
    46 
    47 #include "wfcstructs.h"
    48 #include "wfccontext.h"
    49 #include "owfnativestream.h"
    50 #include "owfscreen.h"
    51 
    52 #define RGB_NUM_BYTES       (sizeof(WFCuint8) * 4)
    53 
    54 #define COND_FAIL(cond,error,retval) \
    55     if (!(cond)) { \
    56         WFC_Device_SetError(dev, error); \
    57         WFC_Unlock(); \
    58         return retval; \
    59     }
    60 
    61 #define COND_FAIL_NR(cond,error) \
    62     if (!(cond)) { \
    63         WFC_Device_SetError(dev, error); \
    64         WFC_Unlock(); \
    65         return; \
    66     }
    67 
    68 #define GET_DEVICE(d, h, x) \
    69     WFC_Lock(); \
    70     d = WFC_Device_FindByHandle(h); \
    71     if (NULL == d) { \
    72         WFC_Unlock(); \
    73         return x; \
    74     }
    75 
    76 #define GET_DEVICE_NR(d, h) \
    77     WFC_Lock(); \
    78     d = WFC_Device_FindByHandle(h); \
    79     if (WFC_INVALID_HANDLE == d) { \
    80         WFC_Unlock(); \
    81         return; \
    82     }
    83 
    84 #define GET_CONTEXT_NR(c,d,h) \
    85     c = WFC_Device_FindContext(d, h); \
    86     if (WFC_INVALID_HANDLE == c) { \
    87         WFC_Device_SetError((d)->handle, WFC_ERROR_BAD_HANDLE); \
    88         WFC_Unlock(); \
    89         return; \
    90     }
    91 
    92 #define GET_CONTEXT(c,d,h,x) \
    93     c = WFC_Device_FindContext(d, h); \
    94     if (WFC_INVALID_HANDLE == c) { \
    95         WFC_Device_SetError((d)->handle, WFC_ERROR_BAD_HANDLE); \
    96         WFC_Unlock(); \
    97         return x; \
    98     }
    99 
   100 #define SUCCEED(retval) \
   101     WFC_Device_SetError(dev, WFC_ERROR_NONE); \
   102     WFC_Unlock(); \
   103     return retval
   104 
   105 #define SUCCEED_NR() \
   106     WFC_Device_SetError(dev, WFC_ERROR_NONE); \
   107     WFC_Unlock(); \
   108     return
   109 
   110 #define FAIL(err, retval) \
   111     WFC_Device_SetError(dev, err); \
   112     WFC_Unlock(); \
   113     return retval
   114 
   115 #define FAIL_NR(err) \
   116     WFC_Device_SetError(dev, err); \
   117     WFC_Unlock(); \
   118     return
   119 
   120 
   121 static OWF_MUTEX           mutex;
   122 
   123 static void WFC_Cleanup()
   124 {
   125     OWF_Mutex_Destroy(&mutex);
   126 }
   127 
   128 static void WFC_Lock()
   129 {
   130     if (!mutex)
   131     {
   132         OWF_Mutex_Init(&mutex);
   133         xatexit(WFC_Cleanup);   // Use adaptation version of atexit
   134     }
   135     OWF_Mutex_Lock(&mutex);
   136 }
   137 
   138 static void WFC_Unlock()
   139 {
   140     OWF_Mutex_Unlock(&mutex);
   141 }
   142 
   143 /*=========================================================================*/
   144 /*  4. DEVICE                                                              */
   145 /*=========================================================================*/
   146 
   147 WFC_API_CALL WFCint WFC_APIENTRY
   148 wfcEnumerateDevices(WFCint *deviceIds,
   149                     WFCint deviceIdsCount,
   150                     const WFCint *filterList)
   151 {
   152     WFCint                  n;
   153 
   154     /* populate list with device IDs */
   155     n = WFC_Devices_GetIds(deviceIds, deviceIdsCount, filterList);
   156     return n;
   157 }
   158 
   159 WFC_API_CALL WFCDevice WFC_APIENTRY
   160 wfcCreateDevice(WFCint deviceId, const WFCint *attribList)
   161 {
   162     WFCDevice               device;
   163 
   164     /* currently only empty attribute list or NULL is allowed */
   165     if (attribList && *attribList != WFC_NONE)
   166     {
   167 
   168         return WFC_INVALID_HANDLE;
   169     }
   170     WFC_Lock();
   171     device = WFC_Device_Create(deviceId);
   172     WFC_Unlock();
   173 
   174     return device;
   175 }
   176 
   177 WFC_API_CALL WFCErrorCode WFC_APIENTRY
   178 wfcDestroyDevice(WFCDevice dev)
   179 {
   180     WFC_DEVICE*             device;
   181     WFCErrorCode            result = WFC_ERROR_BAD_DEVICE;
   182 
   183     DPRINT(("wfcDestroyDevice(%d)", dev));
   184 
   185     WFC_Lock();
   186     device = WFC_Device_FindByHandle(dev);
   187     if (device)
   188     {
   189         WFC_Device_Destroy(device);
   190         result = WFC_ERROR_NONE;
   191     }
   192     WFC_Unlock();
   193     return result;
   194 }
   195 
   196 WFC_API_CALL WFCint WFC_APIENTRY
   197 wfcGetDeviceAttribi(WFCDevice dev,
   198                     WFCDeviceAttrib attrib)
   199 {
   200     WFC_DEVICE*             device;
   201     WFCint                  result = 0;
   202     WFCErrorCode            err;
   203 
   204     GET_DEVICE(device, dev, 0);
   205     err = WFC_Device_GetAttribi(device, attrib, &result);
   206 
   207     FAIL(err, result);
   208 }
   209 
   210 WFC_API_CALL WFCErrorCode WFC_APIENTRY
   211 wfcGetError(WFCDevice dev)
   212 {
   213     WFC_DEVICE* device;
   214     WFCErrorCode            err;
   215 
   216     GET_DEVICE(device, dev, WFC_ERROR_BAD_DEVICE);
   217 
   218     err = WFC_Device_GetError(device);
   219     WFC_Unlock();
   220     return err;
   221 }
   222 
   223 WFC_API_CALL void WFC_APIENTRY
   224 wfcCommit(WFCDevice dev, WFCContext ctx, WFCboolean wait)
   225 {
   226     WFC_DEVICE*             device;
   227     WFC_CONTEXT*            context;
   228     WFCErrorCode            error;
   229 
   230     DPRINT(("wfcCommit(%d,%d,%d)", dev, ctx, wait));
   231     GET_DEVICE_NR(device, dev);
   232     GET_CONTEXT_NR(context, device, ctx);
   233 
   234     error = WFC_Context_InvokeCommit(device, context, wait);
   235 
   236     FAIL_NR(error);
   237 }
   238 
   239 /*=========================================================================*/
   240 /* 5. CONTEXT                                                              */
   241 /*=========================================================================*/
   242 
   243 WFC_API_CALL WFCContext WFC_APIENTRY
   244 wfcCreateOnScreenContext(WFCDevice dev,
   245                          WFCint screenNumber,
   246                          const WFCint* attribList)
   247 {
   248     WFC_CONTEXT*            context = NULL;
   249     WFC_DEVICE*             device = NULL;
   250 
   251     GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
   252 
   253     /* currently only empty attribute list or NULL is allowed */
   254     COND_FAIL(!(attribList && *attribList != WFC_NONE),
   255               WFC_ERROR_BAD_ATTRIBUTE,
   256               WFC_INVALID_HANDLE);
   257 
   258     if (screenNumber == WFC_DEFAULT_SCREEN_NUMBER)
   259     {
   260         screenNumber = OWF_Screen_GetDefaultNumber();
   261     }
   262     
   263     /* check screen number validity */
   264     if (!OWF_Screen_Valid(screenNumber))
   265     {
   266         FAIL(WFC_ERROR_UNSUPPORTED, WFC_INVALID_HANDLE);
   267     }
   268 
   269     /* check that no other context currently uses this screen */
   270     if (WFC_Device_FindScreenNumber(screenNumber))
   271     {
   272         FAIL(WFC_ERROR_IN_USE, WFC_INVALID_HANDLE);
   273     }
   274 
   275 
   276     context = WFC_Device_CreateContext(device,
   277                                        WFC_INVALID_HANDLE,
   278                                        WFC_CONTEXT_TYPE_ON_SCREEN,
   279                                        screenNumber);
   280     if (!context)
   281     {
   282         FAIL(WFC_ERROR_OUT_OF_MEMORY, WFC_INVALID_HANDLE);
   283     }
   284 
   285     SUCCEED(context->handle);
   286 }
   287 
   288 WFC_API_CALL WFCContext WFC_APIENTRY
   289 wfcCreateOffScreenContext(WFCDevice dev,
   290                           WFCNativeStreamType stream,
   291                           const WFCint *attribList)
   292 {
   293     WFC_CONTEXT*            context = NULL;
   294     WFC_DEVICE*             device = NULL;
   295     OWFNativeStreamType 	internalStream=OWF_INVALID_HANDLE;
   296     OWF_STREAM_ERROR 		streamError;
   297     
   298     GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
   299 
   300     /* currently only empty attribute list or NULL is allowed */
   301     COND_FAIL(!(attribList && *attribList != WFC_NONE),
   302               WFC_ERROR_BAD_ATTRIBUTE,
   303               WFC_INVALID_HANDLE);
   304 
   305     COND_FAIL(OWF_INVALID_HANDLE != (OWFNativeStreamType) stream,
   306               WFC_ERROR_ILLEGAL_ARGUMENT,
   307               WFC_INVALID_HANDLE);
   308     internalStream=owfNativeStreamFromWFC(stream,&streamError);
   309     COND_FAIL(OWF_STREAM_ERROR_INVALID_STREAM!=streamError,WFC_ERROR_UNSUPPORTED,WFC_INVALID_HANDLE);
   310     COND_FAIL(OWF_STREAM_ERROR_OUT_OF_MEMORY!=streamError,WFC_ERROR_OUT_OF_MEMORY,WFC_INVALID_HANDLE);
   311     
   312     if (!WFC_Context_IsValidTargetStream(internalStream))
   313     {
   314         owfNativeStreamDestroy(internalStream); /*cancel owfNativeStreamFromWFC reference increase*/
   315         FAIL(WFC_ERROR_UNSUPPORTED,WFC_INVALID_HANDLE);
   316     }
   317     context = WFC_Device_CreateContext(device, internalStream,
   318                                        WFC_CONTEXT_TYPE_OFF_SCREEN,
   319                                        OWF_RESERVED_BAD_SCREEN_NUMBER);
   320     owfNativeStreamDestroy(internalStream);	/*cancel owfNativeStreamFromWFC reference increase*/
   321     COND_FAIL(NULL != context, WFC_ERROR_OUT_OF_MEMORY, WFC_INVALID_HANDLE);
   322 
   323     SUCCEED(context->handle);
   324 }
   325 
   326 WFC_API_CALL void WFC_APIENTRY
   327 wfcDestroyContext(WFCDevice dev,
   328                   WFCContext ctx)
   329 {
   330     WFC_DEVICE*             device = NULL;
   331     WFCErrorCode            err;
   332 
   333     DPRINT(("wfcDestroyContext(%d, %d)", dev, ctx));
   334     GET_DEVICE_NR(device, dev);
   335 
   336     err = WFC_Device_DestroyContext(device, ctx);
   337     FAIL_NR(err);
   338 }
   339 
   340 WFC_API_CALL WFCint WFC_APIENTRY
   341 wfcGetContextAttribi(WFCDevice dev,
   342                      WFCContext ctx,
   343                      WFCContextAttrib attrib)
   344 {
   345     WFC_CONTEXT*            context = NULL;
   346     WFC_DEVICE*             device = NULL;
   347     WFCint                  value = 0;
   348     WFCErrorCode            err;
   349 
   350     GET_DEVICE(device, dev, 0);
   351     GET_CONTEXT(context, device, ctx, 0);
   352 
   353     err = WFC_Context_GetAttribi(context, attrib, &value);
   354 
   355     FAIL(err, value);
   356 }
   357 
   358 WFC_API_CALL void WFC_APIENTRY
   359 wfcSetContextAttribi(WFCDevice dev,
   360                      WFCContext ctx,
   361                      WFCContextAttrib attrib,
   362                      WFCint value)
   363 {
   364     WFC_DEVICE*             device;
   365     WFC_CONTEXT*            context;
   366     WFCErrorCode            err;
   367 
   368     GET_DEVICE_NR(device, dev);
   369     GET_CONTEXT_NR(context, device, ctx);
   370 
   371     err = WFC_Context_SetAttribi(context, attrib, value);
   372     FAIL_NR(err);
   373 }
   374 
   375 WFC_API_CALL void WFC_APIENTRY
   376 wfcGetContextAttribfv(WFCDevice dev,
   377                       WFCContext ctx,
   378                       WFCContextAttrib attrib,
   379                       WFCint count,
   380                       WFCfloat *values) WFC_APIEXIT
   381 {
   382     WFC_DEVICE*             device;
   383     WFC_CONTEXT*            context;
   384     WFCErrorCode            err;
   385 
   386     GET_DEVICE_NR(device, dev);
   387     GET_CONTEXT_NR(context, device, ctx);
   388 
   389     err = WFC_Context_GetAttribfv(context, attrib, count, values);
   390     FAIL_NR(err);
   391 }
   392 
   393 WFC_API_CALL void WFC_APIENTRY
   394 wfcSetContextAttribfv(WFCDevice dev,
   395                       WFCContext ctx,
   396                       WFCContextAttrib attrib,
   397                       WFCint count,
   398                       const WFCfloat *values) WFC_APIEXIT
   399 {
   400       WFC_DEVICE*             device;
   401       WFC_CONTEXT*            context;
   402       WFCErrorCode            err;
   403 
   404       GET_DEVICE_NR(device, dev);
   405       GET_CONTEXT_NR(context, device, ctx);
   406 
   407       err = WFC_Context_SetAttribfv(context, attrib, count, values);
   408       FAIL_NR(err);
   409 }
   410 
   411 /*=========================================================================*/
   412 /* 6. IMAGE PROVIDERS (SOURCES & MASKS)                                    */
   413 /*=========================================================================*/
   414 
   415 WFC_API_CALL WFCSource WFC_APIENTRY
   416 wfcCreateSourceFromStream(WFCDevice dev,
   417                           WFCContext ctx,
   418                           WFCNativeStreamType stream,
   419                           const WFCint *attribList)
   420 {
   421     WFC_DEVICE*             device;
   422     WFC_IMAGE_PROVIDER*     source;
   423     WFC_CONTEXT*            context;
   424     OWFNativeStreamType 	internalStream=OWF_INVALID_HANDLE;
   425     OWF_STREAM_ERROR 		streamError;
   426 
   427     GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
   428 
   429     /* currently only empty attribute list or NULL is allowed */
   430     COND_FAIL(!(attribList && *attribList != WFC_NONE),
   431               WFC_ERROR_BAD_ATTRIBUTE,
   432               WFC_INVALID_HANDLE);
   433 
   434     GET_CONTEXT(context, device, ctx, WFC_INVALID_HANDLE);
   435     COND_FAIL(OWF_INVALID_HANDLE != (OWFNativeStreamType) stream,
   436               WFC_ERROR_ILLEGAL_ARGUMENT,
   437               WFC_INVALID_HANDLE);
   438 
   439     internalStream=owfNativeStreamFromWFC(stream,&streamError);
   440     COND_FAIL(OWF_STREAM_ERROR_INVALID_STREAM!=streamError,WFC_ERROR_UNSUPPORTED,WFC_INVALID_HANDLE);
   441     COND_FAIL(OWF_STREAM_ERROR_OUT_OF_MEMORY!=streamError,WFC_ERROR_OUT_OF_MEMORY,WFC_INVALID_HANDLE);
   442 
   443     if (context->stream == internalStream)
   444     	{
   445     	owfNativeStreamDestroy(internalStream);
   446         FAIL( WFC_ERROR_IN_USE, WFC_INVALID_HANDLE);
   447     	}
   448     
   449     if (!WFC_Context_IsValidSourceStream(internalStream))
   450         {
   451         owfNativeStreamDestroy(internalStream);
   452         FAIL( WFC_ERROR_UNSUPPORTED, WFC_INVALID_HANDLE);
   453         }
   454 
   455     source = WFC_Device_CreateSource(device, context, internalStream);
   456     owfNativeStreamDestroy(internalStream);	/*cancel FromWFC reference increase*/
   457     COND_FAIL(NULL != source, WFC_ERROR_OUT_OF_MEMORY, WFC_INVALID_HANDLE);
   458 
   459     SUCCEED(source->handle);
   460 }
   461 
   462 WFC_API_CALL void WFC_APIENTRY
   463 wfcDestroySource(WFCDevice dev,
   464                  WFCSource src)
   465 {
   466     WFC_DEVICE*             device;
   467     WFCErrorCode            err;
   468 
   469     GET_DEVICE_NR(device, dev);
   470 
   471     err = WFC_Device_DestroySource(device, src);
   472 
   473     FAIL_NR(err);
   474 }
   475 
   476 WFC_API_CALL WFCMask WFC_APIENTRY
   477 wfcCreateMaskFromStream(WFCDevice dev,
   478                         WFCContext ctx,
   479                         WFCNativeStreamType stream,
   480                         const WFCint *attribList) WFC_APIEXIT
   481 {
   482     WFC_DEVICE*             device;
   483     WFC_CONTEXT*            context;
   484     WFC_IMAGE_PROVIDER*     mask;
   485     WFCboolean              inUse;
   486     OWFNativeStreamType 	internalStream=OWF_INVALID_HANDLE;
   487     OWF_STREAM_ERROR 		streamError;
   488 
   489 
   490     GET_DEVICE(device, dev, WFC_ERROR_BAD_DEVICE);
   491 
   492     /* currently only empty attribute list or NULL is allowed */
   493     COND_FAIL(!(attribList && *attribList != WFC_NONE),
   494               WFC_ERROR_BAD_ATTRIBUTE,
   495               WFC_INVALID_HANDLE);
   496 
   497     GET_CONTEXT(context, device, ctx, WFC_INVALID_HANDLE);
   498     COND_FAIL(OWF_INVALID_HANDLE != (OWFNativeStreamType) stream,
   499               WFC_ERROR_ILLEGAL_ARGUMENT,
   500               WFC_INVALID_HANDLE);
   501 
   502     internalStream=owfNativeStreamFromWFC(stream,&streamError);
   503     COND_FAIL(OWF_STREAM_ERROR_INVALID_STREAM!=streamError,WFC_ERROR_UNSUPPORTED,WFC_INVALID_HANDLE);
   504     COND_FAIL(OWF_STREAM_ERROR_OUT_OF_MEMORY!=streamError,WFC_ERROR_OUT_OF_MEMORY,WFC_INVALID_HANDLE);
   505 
   506     inUse = WFC_Device_StreamIsTarget(device, internalStream);
   507     if (inUse)
   508     	{
   509        	owfNativeStreamDestroy(internalStream);
   510         FAIL( WFC_ERROR_IN_USE, WFC_INVALID_HANDLE);
   511        	}
   512 
   513     mask = WFC_Device_CreateMask(device, context, internalStream);
   514     owfNativeStreamDestroy(internalStream);	/*cancel FromWFC reference increase*/
   515     COND_FAIL(NULL != mask, WFC_ERROR_OUT_OF_MEMORY, WFC_INVALID_HANDLE);
   516 
   517     SUCCEED(mask->handle);
   518 }
   519 
   520 WFC_API_CALL void WFC_APIENTRY
   521 wfcDestroyMask(WFCDevice dev,
   522                WFCMask mask) WFC_APIEXIT
   523 {
   524     WFC_DEVICE*             device;
   525     WFCErrorCode            error;
   526 
   527     GET_DEVICE_NR(device, dev);
   528 
   529     error = WFC_Device_DestroyMask(device, mask);
   530 
   531     FAIL_NR(error);
   532 }
   533 
   534 /*=========================================================================*/
   535 /* 7. COMPOSITION ELEMENTS                                                 */
   536 /*=========================================================================*/
   537 
   538 WFC_API_CALL WFCElement WFC_APIENTRY
   539 wfcCreateElement(WFCDevice dev,
   540                  WFCContext ctx,
   541                  const WFCint* attribList) WFC_APIEXIT
   542 {
   543     WFC_DEVICE*             device;
   544     WFC_ELEMENT*            element;
   545     WFC_CONTEXT*            context;
   546 
   547     GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
   548 
   549     /* currently only empty attribute list or NULL is allowed */
   550     COND_FAIL(!(attribList && *attribList != WFC_NONE),
   551               WFC_ERROR_BAD_ATTRIBUTE,
   552               WFC_INVALID_HANDLE);
   553 
   554     GET_CONTEXT(context, device, ctx, WFC_INVALID_HANDLE);
   555 
   556     element = WFC_Device_CreateElement(device, context);
   557     COND_FAIL(NULL != element, WFC_ERROR_OUT_OF_MEMORY, WFC_INVALID_HANDLE);
   558 
   559     SUCCEED(element->handle);
   560 }
   561 
   562 WFC_API_CALL void WFC_APIENTRY
   563 wfcDestroyElement(WFCDevice dev,
   564                   WFCElement element) WFC_APIEXIT
   565 {
   566     WFC_DEVICE*             device;
   567     WFCErrorCode            error = WFC_ERROR_BAD_HANDLE;
   568 
   569     GET_DEVICE_NR(device, dev);
   570 
   571     error = WFC_Device_DestroyElement(device, element);
   572 
   573     FAIL_NR(error);
   574 }
   575 
   576 #define ATTR_FUNC_PROLOGUE  \
   577     WFCErrorCode            error; \
   578     WFC_DEVICE*             device; \
   579     \
   580     GET_DEVICE(device, dev, 0)
   581 
   582 #define ATTR_FUNC_PROLOGUE_NR  \
   583     WFCErrorCode            error; \
   584     WFC_DEVICE*             device; \
   585     \
   586     GET_DEVICE_NR(device, dev)
   587 
   588 #define ATTR_FUNC_EPILOGUE(x) \
   589     FAIL(error, x)
   590 
   591 #define ATTR_FUNC_EPILOGUE_NR \
   592     FAIL_NR(error)
   593 
   594 WFC_API_CALL WFCint WFC_APIENTRY
   595 wfcGetElementAttribi(WFCDevice dev,
   596                      WFCElement element,
   597                      WFCElementAttrib attrib) WFC_APIEXIT
   598 {
   599     WFCint                  value;
   600 
   601     ATTR_FUNC_PROLOGUE;
   602 
   603     error = WFC_Device_GetElementAttribiv(device, element, attrib, 1, &value);
   604 
   605     ATTR_FUNC_EPILOGUE(value);
   606 }
   607 
   608 WFC_API_CALL WFCfloat WFC_APIENTRY
   609 wfcGetElementAttribf(WFCDevice dev,
   610                      WFCElement element,
   611                      WFCElementAttrib attrib) WFC_APIEXIT
   612 {
   613     WFCfloat                value;
   614 
   615     ATTR_FUNC_PROLOGUE;
   616 
   617     COND_FAIL(WFC_ELEMENT_GLOBAL_ALPHA == attrib,
   618               WFC_ERROR_BAD_ATTRIBUTE,
   619               0.0f);
   620 
   621     error = WFC_Device_GetElementAttribfv(device, element, attrib, 1, &value);
   622 
   623     /* value is [0, OWF_ALPHA_MAX_VALUE], map to [0, 1] */
   624     value = value / OWF_ALPHA_MAX_VALUE;
   625 
   626     ATTR_FUNC_EPILOGUE(value);
   627 }
   628 
   629 WFC_API_CALL void WFC_APIENTRY
   630 wfcGetElementAttribiv(WFCDevice dev,
   631                       WFCElement element,
   632                       WFCElementAttrib attrib,
   633                       WFCint count,
   634                       WFCint *values) WFC_APIEXIT
   635 {
   636     ATTR_FUNC_PROLOGUE_NR;
   637 
   638     COND_FAIL_NR(WFC_ELEMENT_SOURCE_RECTANGLE == attrib ||
   639                  WFC_ELEMENT_DESTINATION_RECTANGLE == attrib,
   640                  WFC_ERROR_BAD_ATTRIBUTE);
   641 
   642     error = WFC_Device_GetElementAttribiv(device, element, attrib, count,
   643                                           values);
   644     ATTR_FUNC_EPILOGUE_NR;
   645 }
   646 
   647 WFC_API_CALL void WFC_APIENTRY
   648 wfcGetElementAttribfv(WFCDevice dev,
   649                       WFCElement element,
   650                       WFCElementAttrib attrib,
   651                       WFCint count,
   652                       WFCfloat *values) WFC_APIEXIT
   653 {
   654     ATTR_FUNC_PROLOGUE_NR;
   655 
   656     COND_FAIL_NR(WFC_ELEMENT_SOURCE_RECTANGLE == attrib ||
   657                  WFC_ELEMENT_DESTINATION_RECTANGLE == attrib,
   658                  WFC_ERROR_BAD_ATTRIBUTE);
   659 
   660     error = WFC_Device_GetElementAttribfv(device, element, attrib, count,
   661                                           values);
   662 
   663     ATTR_FUNC_EPILOGUE_NR;
   664 }
   665 
   666 WFC_API_CALL void WFC_APIENTRY
   667 wfcSetElementAttribi(WFCDevice dev,
   668                      WFCElement element,
   669                      WFCElementAttrib attrib,
   670                      WFCint value) WFC_APIEXIT
   671 {
   672     ATTR_FUNC_PROLOGUE_NR;
   673 
   674     error = WFC_Device_SetElementAttribiv(device, element, attrib, 1, &value);
   675 
   676     ATTR_FUNC_EPILOGUE_NR;
   677 }
   678 
   679 WFC_API_CALL void WFC_APIENTRY
   680 wfcSetElementAttribf(WFCDevice dev,
   681                      WFCElement element,
   682                      WFCElementAttrib attrib,
   683                      WFCfloat value) WFC_APIEXIT
   684 {
   685     ATTR_FUNC_PROLOGUE_NR;
   686 
   687     COND_FAIL_NR(WFC_ELEMENT_GLOBAL_ALPHA == attrib,
   688                  WFC_ERROR_BAD_ATTRIBUTE);
   689 
   690     error = WFC_Device_SetElementAttribfv(device, element, attrib, 1, &value);
   691 
   692     ATTR_FUNC_EPILOGUE_NR;
   693 }
   694 
   695 WFC_API_CALL void WFC_APIENTRY
   696 wfcSetElementAttribiv(WFCDevice dev,
   697                       WFCElement element,
   698                       WFCElementAttrib attrib,
   699                       WFCint count,
   700                       const WFCint *values) WFC_APIEXIT
   701 {
   702     ATTR_FUNC_PROLOGUE_NR;
   703 
   704     COND_FAIL_NR(WFC_ELEMENT_SOURCE_RECTANGLE == attrib ||
   705                  WFC_ELEMENT_DESTINATION_RECTANGLE == attrib,
   706                  WFC_ERROR_BAD_ATTRIBUTE);
   707 
   708     error = WFC_Device_SetElementAttribiv(device, element, attrib, count,
   709                                           values);
   710 
   711     ATTR_FUNC_EPILOGUE_NR;
   712 }
   713 
   714 WFC_API_CALL void WFC_APIENTRY
   715 wfcSetElementAttribfv(WFCDevice dev,
   716                       WFCElement element,
   717                       WFCElementAttrib attrib,
   718                       WFCint count,
   719                       const WFCfloat *values) WFC_APIEXIT
   720 {
   721     ATTR_FUNC_PROLOGUE_NR;
   722 
   723     COND_FAIL_NR(WFC_ELEMENT_SOURCE_RECTANGLE == attrib ||
   724                  WFC_ELEMENT_DESTINATION_RECTANGLE == attrib,
   725                  WFC_ERROR_BAD_ATTRIBUTE);
   726 
   727     error = WFC_Device_SetElementAttribfv(device, element, attrib, count,
   728                                           values);
   729 
   730     ATTR_FUNC_EPILOGUE_NR;
   731 }
   732 
   733 WFC_API_CALL void WFC_APIENTRY
   734 wfcInsertElement(WFCDevice dev,
   735                  WFCElement element,
   736                  WFCElement subordinate) WFC_APIEXIT
   737 {
   738     WFC_DEVICE*             device;
   739     WFC_ELEMENT*            elemento;
   740     WFCErrorCode            error;
   741 
   742     GET_DEVICE_NR(device, dev);
   743 
   744     /*
   745     - element is inserted immediately above subordinate
   746     - if subordinate is NULL, then element will go to bottom
   747     - both elements must be in the same scene (context)
   748     */
   749     elemento = WFC_Device_FindElement(device, element);
   750     COND_FAIL_NR(WFC_INVALID_HANDLE != elemento, WFC_ERROR_BAD_HANDLE);
   751 
   752     error = WFC_Context_InsertElement(CONTEXT(elemento->context),
   753                                       element,
   754                                       subordinate);
   755 
   756     FAIL_NR(error);
   757 }
   758 
   759 WFC_API_CALL void WFC_APIENTRY
   760 wfcRemoveElement(WFCDevice dev,
   761                  WFCElement element) WFC_APIEXIT
   762 {
   763     WFC_DEVICE*             device;
   764     WFC_ELEMENT*            elemento;
   765     WFCErrorCode            error;
   766 
   767     GET_DEVICE_NR(device, dev);
   768 
   769     elemento = WFC_Device_FindElement(device, element);
   770     COND_FAIL_NR(WFC_INVALID_HANDLE != elemento, WFC_ERROR_BAD_HANDLE);
   771 
   772     error = WFC_Context_RemoveElement(CONTEXT(elemento->context), element);
   773 
   774     FAIL_NR(error);
   775 }
   776 
   777 WFC_API_CALL WFCElement WFC_APIENTRY
   778 wfcGetElementAbove(WFCDevice dev, WFCElement element) WFC_APIEXIT
   779 {
   780     WFC_DEVICE*             device = NULL;
   781     WFC_ELEMENT*            elemento = NULL;
   782     WFCElement              result = WFC_INVALID_HANDLE;
   783     WFCErrorCode            error = WFC_ERROR_NONE;
   784 
   785     GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
   786 
   787     elemento = WFC_Device_FindElement(device, element);
   788     COND_FAIL(WFC_INVALID_HANDLE != elemento,
   789               WFC_ERROR_BAD_HANDLE,
   790               WFC_INVALID_HANDLE);
   791 
   792     error = WFC_Context_GetElementAbove(CONTEXT(elemento->context),
   793                                         element,
   794                                         &result);
   795 
   796     FAIL(error, result);
   797 }
   798 
   799 WFC_API_CALL WFCElement WFC_APIENTRY
   800 wfcGetElementBelow(WFCDevice dev, WFCElement element) WFC_APIEXIT
   801 {
   802     WFC_DEVICE*             device = NULL;
   803     WFC_ELEMENT*            elemento = NULL;
   804     WFCElement              result = WFC_INVALID_HANDLE;
   805     WFCErrorCode            error = WFC_ERROR_NONE;
   806 
   807     GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
   808 
   809     elemento = WFC_Device_FindElement(device, element);
   810     COND_FAIL(WFC_INVALID_HANDLE != elemento,
   811               WFC_ERROR_BAD_HANDLE,
   812               WFC_INVALID_HANDLE);
   813 
   814     error = WFC_Context_GetElementBelow(CONTEXT(elemento->context),
   815                                         element,
   816                                         &result);
   817 
   818     FAIL(error, result);
   819 }
   820 
   821 /*=========================================================================*/
   822 /* 8. RENDERING                                                            */
   823 /*=========================================================================*/
   824 
   825 WFC_API_CALL void WFC_APIENTRY
   826 wfcActivate(WFCDevice dev,
   827             WFCContext ctx) WFC_APIEXIT
   828 {
   829     WFC_DEVICE*             device;
   830     WFC_CONTEXT*            context;
   831 
   832     GET_DEVICE_NR(device, dev);
   833     GET_CONTEXT_NR(context, device, ctx);
   834 
   835     WFC_Context_Activate(context, WFC_TRUE);
   836 
   837     SUCCEED_NR();
   838 }
   839 
   840 WFC_API_CALL void WFC_APIENTRY
   841 wfcDeactivate(WFCDevice dev,
   842               WFCContext ctx) WFC_APIEXIT
   843 {
   844     WFC_DEVICE*             device;
   845     WFC_CONTEXT*            context;
   846 
   847     GET_DEVICE_NR(device, dev);
   848     GET_CONTEXT_NR(context, device, ctx);
   849 
   850     WFC_Context_Activate(context, WFC_FALSE);
   851 
   852     SUCCEED_NR();
   853 }
   854 
   855 WFC_API_CALL void WFC_APIENTRY
   856 wfcCompose(WFCDevice dev,
   857            WFCContext ctx,
   858            WFCboolean wait) WFC_APIEXIT
   859 {
   860     WFC_DEVICE*             device;
   861     WFC_CONTEXT*            context;
   862     WFCboolean              able;
   863 
   864     GET_DEVICE_NR(device, dev);
   865     GET_CONTEXT_NR(context, device, ctx);
   866 
   867     /* context must not be active */
   868     COND_FAIL_NR(!WFC_Context_Active(context), WFC_ERROR_UNSUPPORTED);
   869 
   870     /* send composition request */
   871     able = WFC_Context_InvokeComposition(device, context, wait);
   872     COND_FAIL_NR(WFC_TRUE == able, WFC_ERROR_BUSY);
   873 
   874     SUCCEED_NR();
   875 }
   876 
   877 
   878 /*=========================================================================*/
   879 /* 9. SYNCHRONIZATION                                                      */
   880 /*=========================================================================*/
   881 
   882 WFC_API_CALL void WFC_APIENTRY
   883 wfcFence(WFCDevice dev,
   884          WFCContext ctx,
   885          WFCEGLDisplay dpy,
   886          WFCEGLSync sync)
   887 {
   888     WFC_DEVICE*     device;
   889     WFC_CONTEXT*    context;
   890 
   891     DPRINT(("wfcFence(%08x,%08x,%08x)", dev, ctx, sync));
   892 
   893     GET_DEVICE_NR(device, dev);
   894     DPRINT(("  device = %p", device));
   895 
   896     GET_CONTEXT_NR(context, device, ctx);
   897     DPRINT(("  context = %p", context));
   898     
   899     /* unsignal sync object first */
   900     OWF_ASSERT(context->eglPrivateSignalSync);
   901     if ( !(context->eglPrivateSignalSync((EGLDisplay)dpy, sync, EGL_UNSIGNALED_KHR)) )
   902     {
   903         FAIL_NR(WFC_ERROR_ILLEGAL_ARGUMENT);
   904     }
   905 
   906     /* insert fence 'token' to command stream */
   907     WFC_Context_InsertFence(context, dpy, sync);
   908     SUCCEED_NR();
   909 }
   910 
   911 /*=========================================================================*/
   912 /* 10. EXTENSION SUPPORT                                                   */
   913 /*=========================================================================*/
   914 
   915 WFC_API_CALL WFCint WFC_APIENTRY
   916 wfcGetStrings(WFCDevice dev,
   917               WFCStringID name,
   918               const char **strings,
   919               WFCint stringsCount) WFC_APIEXIT
   920 {
   921     WFC_DEVICE*             pDevice;
   922     const char**            tmp;
   923     WFCint                  retVal;
   924 
   925     GET_DEVICE(pDevice, dev, 0);
   926     COND_FAIL(stringsCount >= 0, WFC_ERROR_ILLEGAL_ARGUMENT, 0);
   927 
   928     switch (name)
   929     {
   930     case WFC_VENDOR:
   931         retVal = 1;
   932         tmp = &wfc_strings[WFC_VENDOR_INDEX];
   933         break;
   934 
   935     case WFC_RENDERER:
   936         retVal = 1;
   937         tmp = &wfc_strings[WFC_RENDERER_INDEX];
   938         break;
   939 
   940     case WFC_VERSION:
   941         retVal = 1;
   942         tmp = &wfc_strings[WFC_VERSION_INDEX];
   943         break;
   944 
   945     case WFC_EXTENSIONS:
   946         tmp = &wfc_extensions[0];
   947 		/* we know that wfc_extensions always has NULL as the last member 
   948 		   so this loop will never exceed the size of tmp */
   949 		/* coverity[overrun-local] */
   950         for (retVal=0; tmp[retVal] != NULL; retVal++)
   951         {
   952             /* get extensions array size */
   953         }
   954         break;
   955 
   956     default:
   957         FAIL(WFC_ERROR_ILLEGAL_ARGUMENT, 0);
   958     }
   959 
   960     if (strings != NULL)
   961     {
   962         WFCint i;
   963 
   964         if (stringsCount < retVal)
   965         {
   966             retVal = stringsCount;
   967         }
   968         for (i=0; i<retVal; i++)
   969         {
   970             strings[i] = tmp[i];
   971         }
   972     }
   973 
   974     SUCCEED(retVal);
   975 }
   976 
   977 WFC_API_CALL WFCboolean WFC_APIENTRY
   978 wfcIsExtensionSupported(WFCDevice dev,
   979                         const char *string) WFC_APIEXIT
   980 {
   981     WFC_DEVICE* pDevice;
   982     WFCint i;
   983     WFCboolean retVal = WFC_FALSE;
   984 
   985     GET_DEVICE(pDevice, dev, retVal);
   986     /* Bad param does not update device error state */
   987     COND_FAIL(string,WFC_ERROR_NONE,retVal);
   988     
   989     for (i=0; wfc_extensions[i] != NULL; i++)
   990     {
   991        if (strcmp(string, wfc_extensions[i])==0)
   992        {
   993            retVal = WFC_TRUE;
   994            break;
   995        }
   996     }
   997 
   998     SUCCEED(retVal);
   999 }
  1000 
  1001 /*=========================================================================*/
  1002 /* 11. TEST ONLY API FOR ON SCREEN IMAGE EXPORTING                         */
  1003 /*=========================================================================*/
  1004 
  1005 WFC_API_CALL WFCNativeStreamType WFC_APIENTRY
  1006 extwfcGetOnScreenStream(WFCDevice dev, WFCContext ctx) WFC_APIEXIT
  1007 {
  1008 	WFC_DEVICE*             device;
  1009 	WFC_CONTEXT*            context;
  1010 
  1011 	GET_DEVICE(device, dev, WFC_INVALID_HANDLE);
  1012 	DPRINT(("  device = %p", device));
  1013 
  1014 	GET_CONTEXT(context, device, ctx, WFC_INVALID_HANDLE);
  1015 	DPRINT(("  context = %p", context));
  1016 
  1017 	/* Protect context's target stream from being destroyed by the user
  1018 	 * WFC_CONTEXT_Dtor will reset this flag. */
  1019 	owfNativeStreamSetProtectionFlag(context->stream, OWF_TRUE);
  1020 	
  1021 	OWF_DisplayContext_FlagInternalStreamAccessed(context->displayContext);
  1022 
  1023 	SUCCEED(context->stream);
  1024 }