13464ebd5Sriastradh/**************************************************************************
23464ebd5Sriastradh *
33464ebd5Sriastradh * Copyright 2010 LunarG, Inc.
43464ebd5Sriastradh * All Rights Reserved.
53464ebd5Sriastradh *
63464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
73464ebd5Sriastradh * copy of this software and associated documentation files (the
83464ebd5Sriastradh * "Software"), to deal in the Software without restriction, including
93464ebd5Sriastradh * without limitation the rights to use, copy, modify, merge, publish,
103464ebd5Sriastradh * distribute, sub license, and/or sell copies of the Software, and to
113464ebd5Sriastradh * permit persons to whom the Software is furnished to do so, subject to
123464ebd5Sriastradh * the following conditions:
133464ebd5Sriastradh *
143464ebd5Sriastradh * The above copyright notice and this permission notice (including the
153464ebd5Sriastradh * next paragraph) shall be included in all copies or substantial portions
163464ebd5Sriastradh * of the Software.
173464ebd5Sriastradh *
183464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
193464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
203464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
213464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
223464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
233464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
243464ebd5Sriastradh * DEALINGS IN THE SOFTWARE.
253464ebd5Sriastradh *
263464ebd5Sriastradh **************************************************************************/
273464ebd5Sriastradh
283464ebd5Sriastradh
2901e04c3fSmrg#include <inttypes.h>
303464ebd5Sriastradh#include <string.h>
313464ebd5Sriastradh
323464ebd5Sriastradh#include "eglsync.h"
333464ebd5Sriastradh#include "eglcurrent.h"
3401e04c3fSmrg#include "egldriver.h"
353464ebd5Sriastradh#include "egllog.h"
363464ebd5Sriastradh
373464ebd5Sriastradh
383464ebd5Sriastradh/**
393464ebd5Sriastradh * Parse the list of sync attributes and return the proper error code.
403464ebd5Sriastradh */
413464ebd5Sriastradhstatic EGLint
4201e04c3fSmrg_eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list)
433464ebd5Sriastradh{
4401e04c3fSmrg   EGLint i;
453464ebd5Sriastradh
463464ebd5Sriastradh   if (!attrib_list)
473464ebd5Sriastradh      return EGL_SUCCESS;
483464ebd5Sriastradh
493464ebd5Sriastradh   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
5001e04c3fSmrg      EGLAttrib attr = attrib_list[i++];
5101e04c3fSmrg      EGLAttrib val = attrib_list[i];
5201e04c3fSmrg      EGLint err = EGL_SUCCESS;
533464ebd5Sriastradh
543464ebd5Sriastradh      switch (attr) {
5501e04c3fSmrg      case EGL_CL_EVENT_HANDLE_KHR:
5601e04c3fSmrg         if (sync->Type == EGL_SYNC_CL_EVENT_KHR) {
5701e04c3fSmrg            sync->CLEvent = val;
5801e04c3fSmrg         } else {
5901e04c3fSmrg            err = EGL_BAD_ATTRIBUTE;
6001e04c3fSmrg         }
6101e04c3fSmrg         break;
6201e04c3fSmrg      case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
6301e04c3fSmrg         if (sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID) {
6401e04c3fSmrg            /* we take ownership of the native fd, so no dup(): */
6501e04c3fSmrg            sync->SyncFd = val;
6601e04c3fSmrg         } else {
6701e04c3fSmrg            err = EGL_BAD_ATTRIBUTE;
6801e04c3fSmrg         }
6901e04c3fSmrg         break;
703464ebd5Sriastradh      default:
713464ebd5Sriastradh         err = EGL_BAD_ATTRIBUTE;
723464ebd5Sriastradh         break;
733464ebd5Sriastradh      }
743464ebd5Sriastradh
753464ebd5Sriastradh      if (err != EGL_SUCCESS) {
7601e04c3fSmrg         _eglLog(_EGL_DEBUG, "bad sync attribute 0x%" PRIxPTR, attr);
7701e04c3fSmrg         return err;
783464ebd5Sriastradh      }
793464ebd5Sriastradh   }
803464ebd5Sriastradh
8101e04c3fSmrg   return EGL_SUCCESS;
823464ebd5Sriastradh}
833464ebd5Sriastradh
843464ebd5Sriastradh
853464ebd5SriastradhEGLBoolean
867e102996Smaya_eglInitSync(_EGLSync *sync, _EGLDisplay *disp, EGLenum type,
8701e04c3fSmrg             const EGLAttrib *attrib_list)
883464ebd5Sriastradh{
893464ebd5Sriastradh   EGLint err;
903464ebd5Sriastradh
917e102996Smaya   _eglInitResource(&sync->Resource, sizeof(*sync), disp);
923464ebd5Sriastradh   sync->Type = type;
933464ebd5Sriastradh   sync->SyncStatus = EGL_UNSIGNALED_KHR;
9401e04c3fSmrg   sync->SyncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;
953464ebd5Sriastradh
963464ebd5Sriastradh   err = _eglParseSyncAttribList(sync, attrib_list);
9701e04c3fSmrg
9801e04c3fSmrg   switch (type) {
9901e04c3fSmrg   case EGL_SYNC_CL_EVENT_KHR:
10001e04c3fSmrg      sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR;
10101e04c3fSmrg      break;
10201e04c3fSmrg   case EGL_SYNC_NATIVE_FENCE_ANDROID:
10301e04c3fSmrg      if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID)
10401e04c3fSmrg         sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
10501e04c3fSmrg      else
10601e04c3fSmrg         sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
10701e04c3fSmrg      break;
10801e04c3fSmrg   default:
10901e04c3fSmrg      sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
11001e04c3fSmrg   }
11101e04c3fSmrg
1123464ebd5Sriastradh   if (err != EGL_SUCCESS)
1133464ebd5Sriastradh      return _eglError(err, "eglCreateSyncKHR");
1143464ebd5Sriastradh
11501e04c3fSmrg   if (type == EGL_SYNC_CL_EVENT_KHR && !sync->CLEvent)
11601e04c3fSmrg      return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
11701e04c3fSmrg
1183464ebd5Sriastradh   return EGL_TRUE;
1193464ebd5Sriastradh}
1203464ebd5Sriastradh
1213464ebd5Sriastradh
1223464ebd5SriastradhEGLBoolean
1237ec681f3Smrg_eglGetSyncAttrib(_EGLDisplay *disp, _EGLSync *sync,
12401e04c3fSmrg                  EGLint attribute, EGLAttrib *value)
1253464ebd5Sriastradh{
1263464ebd5Sriastradh   switch (attribute) {
1273464ebd5Sriastradh   case EGL_SYNC_TYPE_KHR:
1283464ebd5Sriastradh      *value = sync->Type;
1293464ebd5Sriastradh      break;
1303464ebd5Sriastradh   case EGL_SYNC_STATUS_KHR:
13101e04c3fSmrg      /* update the sync status */
13201e04c3fSmrg      if (sync->SyncStatus != EGL_SIGNALED_KHR &&
13301e04c3fSmrg          (sync->Type == EGL_SYNC_FENCE_KHR ||
13401e04c3fSmrg           sync->Type == EGL_SYNC_CL_EVENT_KHR ||
13501e04c3fSmrg           sync->Type == EGL_SYNC_REUSABLE_KHR ||
13601e04c3fSmrg           sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID))
1377ec681f3Smrg         disp->Driver->ClientWaitSyncKHR(disp, sync, 0, 0);
13801e04c3fSmrg
1393464ebd5Sriastradh      *value = sync->SyncStatus;
1403464ebd5Sriastradh      break;
1413464ebd5Sriastradh   case EGL_SYNC_CONDITION_KHR:
14201e04c3fSmrg      if (sync->Type != EGL_SYNC_FENCE_KHR &&
14301e04c3fSmrg          sync->Type != EGL_SYNC_CL_EVENT_KHR &&
14401e04c3fSmrg          sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID)
1453464ebd5Sriastradh         return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
1463464ebd5Sriastradh      *value = sync->SyncCondition;
1473464ebd5Sriastradh      break;
14801e04c3fSmrg
1493464ebd5Sriastradh   default:
1503464ebd5Sriastradh      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
1513464ebd5Sriastradh      break;
1523464ebd5Sriastradh   }
1533464ebd5Sriastradh
1543464ebd5Sriastradh   return EGL_TRUE;
1553464ebd5Sriastradh}
156