Codebase list kmscube / 497ab78
atomic: Use CPU-side KMS fence synchronisation Atomic does not let us have multiple requests in flight at once; if we don't synchronise with the request completion on the CPU side, we can get -EBUSY from the atomic commit. We already have everything required to do this, namely the out-fence from the last commit. Block on that with a CPU-side wait before we call atomic commit, to make sure we'll never attempt to queue an atomic commit before the previous one has completed. Signed-off-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com> Daniel Stone 7 years ago
3 changed file(s) with 22 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
154154 get_proc_dpy(EGL_KHR_fence_sync, eglCreateSyncKHR);
155155 get_proc_dpy(EGL_KHR_fence_sync, eglDestroySyncKHR);
156156 get_proc_dpy(EGL_KHR_fence_sync, eglWaitSyncKHR);
157 get_proc_dpy(EGL_KHR_fence_sync, eglClientWaitSyncKHR);
157158 get_proc_dpy(EGL_ANDROID_native_fence_sync, eglDupNativeFenceFDANDROID);
158159
159160 printf("Using display %p with EGL version %d.%d\n",
7878 PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
7979 PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
8080 PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR;
81 PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR;
8182 PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
8283
8384 void (*draw)(unsigned i);
209209
210210 if (drm.kms_out_fence_fd != -1) {
211211 kms_fence = create_fence(egl, drm.kms_out_fence_fd);
212 assert(kms_fence);
212213
213214 /* driver now has ownership of the fence fd: */
214215 drm.kms_out_fence_fd = -1;
219220 * the buffer that is still on screen.
220221 */
221222 egl->eglWaitSyncKHR(egl->display, kms_fence, 0);
222 egl->eglDestroySyncKHR(egl->display, kms_fence);
223223 }
224224
225225 egl->draw(i++);
228228 * signaled when gpu rendering done
229229 */
230230 gpu_fence = create_fence(egl, EGL_NO_NATIVE_FENCE_FD_ANDROID);
231 assert(gpu_fence);
231232
232233 eglSwapBuffers(egl->display, egl->surface);
233234
243244 if (!fb) {
244245 printf("Failed to get a new framebuffer BO\n");
245246 return -1;
247 }
248
249 if (kms_fence) {
250 EGLint status;
251
252 /* Wait on the CPU side for the _previous_ commit to
253 * complete before we post the flip through KMS, as
254 * atomic will reject the commit if we post a new one
255 * whilst the previous one is still pending.
256 */
257 do {
258 status = egl->eglClientWaitSyncKHR(egl->display,
259 kms_fence,
260 0,
261 EGL_FOREVER_KHR);
262 } while (status != EGL_CONDITION_SATISFIED_KHR);
263
264 egl->eglDestroySyncKHR(egl->display, kms_fence);
246265 }
247266
248267 /*