jni_gl_environment.cpp revision 30ab3fc173709a491c9e2e103f53fb7c0d1b96b7
130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni/*
230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Copyright (C) 2011 The Android Open Source Project
330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni *
430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Licensed under the Apache License, Version 2.0 (the "License");
530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * you may not use this file except in compliance with the License.
630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * You may obtain a copy of the License at
730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni *
830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni *      http://www.apache.org/licenses/LICENSE-2.0
930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni *
1030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Unless required by applicable law or agreed to in writing, software
1130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * distributed under the License is distributed on an "AS IS" BASIS,
1230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * See the License for the specific language governing permissions and
1430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * limitations under the License.
1530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni */
1630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
1730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <stdint.h>
1830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <android/native_window_jni.h>
1930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
2030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "jni/jni_gl_environment.h"
2130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "jni/jni_util.h"
2230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
2330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "native/base/basictypes.h"
2430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "native/core/gl_env.h"
2530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
2630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniusing android::filterfw::GLEnv;
2730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniusing android::filterfw::WindowHandle;
2830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
2930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniclass NativeWindowHandle : public WindowHandle {
3030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  public:
3130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    NativeWindowHandle(ANativeWindow* window) : window_(window) {
3230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
3330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
3430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    virtual ~NativeWindowHandle() {
3530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
3630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
3730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    virtual void Destroy() {
3830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      LOGI("Releasing ANativeWindow!");
3930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      ANativeWindow_release(window_);
4030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
4130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
4230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    virtual const void* InternalHandle() const {
4330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      return window_;
4430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
4530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
4630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  private:
4730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    ANativeWindow* window_;
4830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni};
4930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
5030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_allocate(JNIEnv* env, jobject thiz) {
5130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return ToJBool(WrapObjectInJava(new GLEnv(), env, thiz, true));
5230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
5330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
5430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_deallocate(JNIEnv* env, jobject thiz) {
5530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return ToJBool(DeleteNativeObject<GLEnv>(env, thiz));
5630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
5730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
5830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_initWithNewContext(JNIEnv* env, jobject thiz) {
5930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
6030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->InitWithNewContext()) : JNI_FALSE;
6130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
6230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
6330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_initWithCurrentContext(JNIEnv* env,
6430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                         jobject thiz) {
6530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
6630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->InitWithCurrentContext()) : JNI_FALSE;
6730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
6830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
6930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_activate(JNIEnv* env, jobject thiz) {
7030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
7130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->Activate()) : JNI_FALSE;
7230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
7330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
7430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_deactivate(JNIEnv* env, jobject thiz) {
7530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
7630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->Deactivate()) : JNI_FALSE;
7730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
7830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
7930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijobject Java_android_filterfw_core_GLEnvironment_activeEnvironment(JNIEnv* env, jclass clazz) {
8030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* active = GLEnv::ActiveEnv();
8130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return active ? WrapNewObjectInJava(active, env, false) : NULL;
8230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
8330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
8430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_swapBuffers(JNIEnv* env, jobject thiz) {
8530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
8630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->SwapBuffers()) : JNI_FALSE;
8730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
8830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
8930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijint Java_android_filterfw_core_GLEnvironment_nativeAddSurface(JNIEnv* env,
9030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                               jobject thiz,
9130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                               jobject surface) {
9230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
9330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  if (!surface) {
9430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    LOGE("GLEnvironment: Null Surface passed!");
9530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    return -1;
9630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  } else if (gl_env) {
9730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    // Get the ANativeWindow
9830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
9930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    if (!window) {
10030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      LOGE("GLEnvironment: Error creating window!");
10130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      return -1;
10230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
10330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
10430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    NativeWindowHandle* winHandle = new NativeWindowHandle(window);
10530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    int result = gl_env->FindSurfaceIdForWindow(winHandle);
10630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    if (result == -1) {
10730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      // Configure surface
10830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLConfig config;
10930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLint numConfigs = -1;
11030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLint configAttribs[] = {
11130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
11230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
11330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        EGL_NONE
11430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      };
11530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
11630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs);
11730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      if (numConfigs < 1) {
11830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        LOGE("GLEnvironment: No suitable EGL configuration found for surface!");
11930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        return -1;
12030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      }
12130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
12230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      // Create the EGL surface
12330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(),
12430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                      config,
12530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                      window,
12630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                      NULL);
12730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
12830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      if (GLEnv::CheckEGLError("eglCreateWindowSurface")) {
12930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        LOGE("GLEnvironment: Error creating window surface!");
13030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        return -1;
13130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      }
13230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
13330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      // Add it to GL Env and assign ID
13430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      result = gl_env->AddWindowSurface(egl_surface, winHandle);
13530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    } else {
13630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      delete winHandle;
13730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
13830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    return result;
13930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  }
14030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return -1;
14130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
14230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
14330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_nativeActivateSurfaceId(JNIEnv* env,
14430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                          jobject thiz,
14530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                          jint surfaceId) {
14630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
14730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->SwitchToSurfaceId(surfaceId)) : JNI_FALSE;
14830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
14930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
15030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_nativeRemoveSurfaceId(JNIEnv* env,
15130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                        jobject thiz,
15230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                        jint surfaceId) {
15330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
15430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->ReleaseSurfaceId(surfaceId)) : JNI_FALSE;
15530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
15630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
157