egl/dri2: implement EGL_KHR_cl_event2 (v2)
[mesa.git] / src / egl / main / eglsync.c
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 <string.h>
30
31 #include "eglsync.h"
32 #include "eglcurrent.h"
33 #include "egllog.h"
34
35
36 /**
37 * Parse the list of sync attributes and return the proper error code.
38 */
39 static EGLint
40 _eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
41 {
42 EGLint i, err = EGL_SUCCESS;
43
44 if (!attrib_list)
45 return EGL_SUCCESS;
46
47 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
48 EGLint attr = attrib_list[i++];
49 EGLint val = attrib_list[i];
50
51 switch (attr) {
52 default:
53 (void) val;
54 err = EGL_BAD_ATTRIBUTE;
55 break;
56 }
57
58 if (err != EGL_SUCCESS) {
59 _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr);
60 break;
61 }
62 }
63
64 return err;
65 }
66
67
68 static EGLint
69 _eglParseSyncAttribList64(_EGLSync *sync, const EGLAttribKHR *attrib_list)
70 {
71 EGLint i, err = EGL_SUCCESS;
72
73 if (!attrib_list)
74 return EGL_SUCCESS;
75
76 for (i = 0; attrib_list[i] != EGL_NONE; i++) {
77 EGLint attr = attrib_list[i++];
78 EGLint val = attrib_list[i];
79
80 switch (attr) {
81 case EGL_CL_EVENT_HANDLE_KHR:
82 if (sync->Type == EGL_SYNC_CL_EVENT_KHR) {
83 sync->CLEvent = val;
84 break;
85 }
86 /* fall through */
87 default:
88 (void) val;
89 err = EGL_BAD_ATTRIBUTE;
90 break;
91 }
92
93 if (err != EGL_SUCCESS) {
94 _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr);
95 break;
96 }
97 }
98
99 return err;
100 }
101
102
103 EGLBoolean
104 _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
105 const EGLint *attrib_list, const EGLAttribKHR *attrib_list64)
106 {
107 EGLint err;
108
109 if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync) &&
110 !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync) &&
111 !(type == EGL_SYNC_CL_EVENT_KHR && dpy->Extensions.KHR_cl_event2 &&
112 attrib_list64))
113 return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
114
115 _eglInitResource(&sync->Resource, sizeof(*sync), dpy);
116 sync->Type = type;
117 sync->SyncStatus = EGL_UNSIGNALED_KHR;
118
119 switch (type) {
120 case EGL_SYNC_CL_EVENT_KHR:
121 sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR;
122 break;
123 default:
124 sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
125 }
126
127 if (attrib_list64)
128 err = _eglParseSyncAttribList64(sync, attrib_list64);
129 else
130 err = _eglParseSyncAttribList(sync, attrib_list);
131
132 if (err != EGL_SUCCESS)
133 return _eglError(err, "eglCreateSyncKHR");
134
135 if (type == EGL_SYNC_CL_EVENT_KHR && !sync->CLEvent)
136 return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
137
138 return EGL_TRUE;
139 }
140
141
142 EGLBoolean
143 _eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
144 EGLint attribute, EGLint *value)
145 {
146 if (!value)
147 return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs");
148
149 switch (attribute) {
150 case EGL_SYNC_TYPE_KHR:
151 *value = sync->Type;
152 break;
153 case EGL_SYNC_STATUS_KHR:
154 *value = sync->SyncStatus;
155 break;
156 case EGL_SYNC_CONDITION_KHR:
157 if (sync->Type != EGL_SYNC_FENCE_KHR &&
158 sync->Type != EGL_SYNC_CL_EVENT_KHR)
159 return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
160 *value = sync->SyncCondition;
161 break;
162 default:
163 return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
164 break;
165 }
166
167 return EGL_TRUE;
168 }