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