Home | History | Annotate | Download | only in main
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 LunarG, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     24  * DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 #include <inttypes.h>
     30 #include <string.h>
     31 
     32 #include "eglsync.h"
     33 #include "eglcurrent.h"
     34 #include "egldriver.h"
     35 #include "egllog.h"
     36 
     37 
     38 /**
     39  * Parse the list of sync attributes and return the proper error code.
     40  */
     41 static EGLint
     42 _eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list)
     43 {
     44    EGLint i;
     45 
     46    if (!attrib_list)
     47       return EGL_SUCCESS;
     48 
     49    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
     50       EGLAttrib attr = attrib_list[i++];
     51       EGLAttrib val = attrib_list[i];
     52       EGLint err = EGL_SUCCESS;
     53 
     54       switch (attr) {
     55       case EGL_CL_EVENT_HANDLE_KHR:
     56          if (sync->Type == EGL_SYNC_CL_EVENT_KHR) {
     57             sync->CLEvent = val;
     58          } else {
     59             err = EGL_BAD_ATTRIBUTE;
     60          }
     61          break;
     62       case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
     63          if (sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID) {
     64             /* we take ownership of the native fd, so no dup(): */
     65             sync->SyncFd = val;
     66          } else {
     67             err = EGL_BAD_ATTRIBUTE;
     68          }
     69          break;
     70       default:
     71          err = EGL_BAD_ATTRIBUTE;
     72          break;
     73       }
     74 
     75       if (err != EGL_SUCCESS) {
     76          _eglLog(_EGL_DEBUG, "bad sync attribute 0x%" PRIxPTR, attr);
     77          return err;
     78       }
     79    }
     80 
     81    return EGL_SUCCESS;
     82 }
     83 
     84 
     85 EGLBoolean
     86 _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
     87              const EGLAttrib *attrib_list)
     88 {
     89    EGLint err;
     90 
     91    _eglInitResource(&sync->Resource, sizeof(*sync), dpy);
     92    sync->Type = type;
     93    sync->SyncStatus = EGL_UNSIGNALED_KHR;
     94    sync->SyncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
     95 
     96    err = _eglParseSyncAttribList(sync, attrib_list);
     97 
     98    switch (type) {
     99    case EGL_SYNC_CL_EVENT_KHR:
    100       sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR;
    101       break;
    102    case EGL_SYNC_NATIVE_FENCE_ANDROID:
    103       if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID)
    104          sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
    105       else
    106          sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
    107       break;
    108    default:
    109       sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
    110    }
    111 
    112    if (err != EGL_SUCCESS)
    113       return _eglError(err, "eglCreateSyncKHR");
    114 
    115    if (type == EGL_SYNC_CL_EVENT_KHR && !sync->CLEvent)
    116       return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
    117 
    118    return EGL_TRUE;
    119 }
    120 
    121 
    122 EGLBoolean
    123 _eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
    124                   EGLint attribute, EGLAttrib *value)
    125 {
    126    switch (attribute) {
    127    case EGL_SYNC_TYPE_KHR:
    128       *value = sync->Type;
    129       break;
    130    case EGL_SYNC_STATUS_KHR:
    131       /* update the sync status */
    132       if (sync->SyncStatus != EGL_SIGNALED_KHR &&
    133           (sync->Type == EGL_SYNC_FENCE_KHR ||
    134            sync->Type == EGL_SYNC_CL_EVENT_KHR ||
    135            sync->Type == EGL_SYNC_REUSABLE_KHR ||
    136            sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID))
    137          drv->API.ClientWaitSyncKHR(drv, dpy, sync, 0, 0);
    138 
    139       *value = sync->SyncStatus;
    140       break;
    141    case EGL_SYNC_CONDITION_KHR:
    142       if (sync->Type != EGL_SYNC_FENCE_KHR &&
    143           sync->Type != EGL_SYNC_CL_EVENT_KHR &&
    144           sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID)
    145          return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
    146       *value = sync->SyncCondition;
    147       break;
    148 
    149    default:
    150       return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
    151       break;
    152    }
    153 
    154    return EGL_TRUE;
    155 }
    156