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