/**************************************************************************
 *
 * Copyright 2010 LunarG, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/


#include <inttypes.h>
#include <string.h>

#include "eglsync.h"
#include "eglcurrent.h"
#include "egldriver.h"
#include "egllog.h"


/**
 * Parse the list of sync attributes and return the proper error code.
 */
static EGLint
_eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib *attrib_list)
{
   EGLint i;

   if (!attrib_list)
      return EGL_SUCCESS;

   for (i = 0; attrib_list[i] != EGL_NONE; i++) {
      EGLAttrib attr = attrib_list[i++];
      EGLAttrib val = attrib_list[i];
      EGLint err = EGL_SUCCESS;

      switch (attr) {
      case EGL_CL_EVENT_HANDLE_KHR:
         if (sync->Type == EGL_SYNC_CL_EVENT_KHR) {
            sync->CLEvent = val;
         } else {
            err = EGL_BAD_ATTRIBUTE;
         }
         break;
      case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
         if (sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID) {
            /* we take ownership of the native fd, so no dup(): */
            sync->SyncFd = val;
         } else {
            err = EGL_BAD_ATTRIBUTE;
         }
         break;
      default:
         err = EGL_BAD_ATTRIBUTE;
         break;
      }

      if (err != EGL_SUCCESS) {
         _eglLog(_EGL_DEBUG, "bad sync attribute 0x%" PRIxPTR, attr);
         return err;
      }
   }

   return EGL_SUCCESS;
}


EGLBoolean
_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
             const EGLAttrib *attrib_list)
{
   EGLint err;

   _eglInitResource(&sync->Resource, sizeof(*sync), dpy);
   sync->Type = type;
   sync->SyncStatus = EGL_UNSIGNALED_KHR;
   sync->SyncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID;

   err = _eglParseSyncAttribList(sync, attrib_list);

   switch (type) {
   case EGL_SYNC_CL_EVENT_KHR:
      sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR;
      break;
   case EGL_SYNC_NATIVE_FENCE_ANDROID:
      if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID)
         sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
      else
         sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
      break;
   default:
      sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
   }

   if (err != EGL_SUCCESS)
      return _eglError(err, "eglCreateSyncKHR");

   if (type == EGL_SYNC_CL_EVENT_KHR && !sync->CLEvent)
      return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");

   return EGL_TRUE;
}


EGLBoolean
_eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
                  EGLint attribute, EGLAttrib *value)
{
   switch (attribute) {
   case EGL_SYNC_TYPE_KHR:
      *value = sync->Type;
      break;
   case EGL_SYNC_STATUS_KHR:
      /* update the sync status */
      if (sync->SyncStatus != EGL_SIGNALED_KHR &&
          (sync->Type == EGL_SYNC_FENCE_KHR ||
           sync->Type == EGL_SYNC_CL_EVENT_KHR ||
           sync->Type == EGL_SYNC_REUSABLE_KHR ||
           sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID))
         drv->API.ClientWaitSyncKHR(drv, dpy, sync, 0, 0);

      *value = sync->SyncStatus;
      break;
   case EGL_SYNC_CONDITION_KHR:
      if (sync->Type != EGL_SYNC_FENCE_KHR &&
          sync->Type != EGL_SYNC_CL_EVENT_KHR &&
          sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID)
         return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
      *value = sync->SyncCondition;
      break;

   default:
      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
      break;
   }

   return EGL_TRUE;
}
