1e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin/*
2e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * Copyright (C) 2012 The Android Open Source Project
3e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin *
4e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * Licensed under the Apache License, Version 2.0 (the "License");
5e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * you may not use this file except in compliance with the License.
6e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * You may obtain a copy of the License at
7e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin *
8e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin *      http://www.apache.org/licenses/LICENSE-2.0
9e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin *
10e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * Unless required by applicable law or agreed to in writing, software
11e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * distributed under the License is distributed on an "AS IS" BASIS,
12e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * See the License for the specific language governing permissions and
14e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin * limitations under the License.
15e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin */
16e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin
17e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin#include "jni_egl_fence.h"
18e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin
19fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li#include <android/log.h>
20e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin#include <EGL/egl.h>
21e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin#include <EGL/eglext.h>
22fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li#include <string.h>
23fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li
24fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li#define  ALOGE(...)  __android_log_print(ANDROID_LOG_ERROR,"egl_fence",__VA_ARGS__)
25fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li
26fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Litypedef EGLSyncKHR EGLAPIENTRY (*TypeEglCreateSyncKHR)(EGLDisplay dpy,
27fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    EGLenum type, const EGLint *attrib_list);
28fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Litypedef EGLBoolean EGLAPIENTRY (*TypeEglDestroySyncKHR)(EGLDisplay dpy,
29fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    EGLSyncKHR sync);
30fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Litypedef EGLint EGLAPIENTRY (*TypeEglClientWaitSyncKHR)(EGLDisplay dpy,
31fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
32fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Listatic TypeEglCreateSyncKHR FuncEglCreateSyncKHR = NULL;
33fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Listatic TypeEglClientWaitSyncKHR FuncEglClientWaitSyncKHR = NULL;
34fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Listatic TypeEglDestroySyncKHR FuncEglDestroySyncKHR = NULL;
35fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Listatic bool initialized = false;
36fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Listatic bool egl_khr_fence_sync_supported = false;
37fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li
38fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Libool IsEglKHRFenceSyncSupported() {
39fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  if (!initialized) {
40fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    EGLDisplay display = eglGetCurrentDisplay();
41fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
42fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    if (eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync")) {
43fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li      FuncEglCreateSyncKHR = (TypeEglCreateSyncKHR) eglGetProcAddress("eglCreateSyncKHR");
44fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li      FuncEglClientWaitSyncKHR = (TypeEglClientWaitSyncKHR) eglGetProcAddress("eglClientWaitSyncKHR");
45fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li      FuncEglDestroySyncKHR = (TypeEglDestroySyncKHR) eglGetProcAddress("eglDestroySyncKHR");
46fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li      if (FuncEglCreateSyncKHR != NULL && FuncEglClientWaitSyncKHR != NULL
47fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li          && FuncEglDestroySyncKHR != NULL) {
48fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li        egl_khr_fence_sync_supported = true;
49fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li      }
50fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    }
51fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li    initialized = true;
52fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  }
53fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  return egl_khr_fence_sync_supported;
54fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li}
55e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin
56e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Linvoid
57e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung LinJava_com_android_gallery3d_photoeditor_FilterStack_nativeEglSetFenceAndWait(JNIEnv* env,
58e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin                                                                          jobject thiz) {
59fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  if (!IsEglKHRFenceSyncSupported()) return;
60e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  EGLDisplay display = eglGetCurrentDisplay();
61e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin
62e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  // Create a egl fence and wait for egl to return it.
63e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  // Additional reference on egl fence sync can be found in:
64e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  // http://www.khronos.org/registry/vg/extensions/KHR/EGL_KHR_fence_sync.txt
65fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  EGLSyncKHR fence = FuncEglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
66e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  if (fence == EGL_NO_SYNC_KHR) {
67e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin    return;
68e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  }
69e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin
70fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  EGLint result = FuncEglClientWaitSyncKHR(display,
71e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin                                       fence,
72e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin                                       EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
73e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin                                       EGL_FOREVER_KHR);
74e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  if (result == EGL_FALSE) {
75e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin    ALOGE("EGL FENCE: error waiting for fence: %#x", eglGetError());
76e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin  }
77fd0975a26fbbe5b1b8d35b46a6c9b7c5f228fdd2Wu-cheng Li  FuncEglDestroySyncKHR(display, fence);
78e5c8ed74768f16e4e82c46a31d5118788dbb3a57Ruei-sung Lin}
79