jni_gl_environment.cpp revision 84a9fb79433ee7c66fe1df7b0a754828ff89aec1
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"
2284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi#include <media/mediarecorder.h>
2330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "native/core/gl_env.h"
2430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
2584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi#include <gui/ISurfaceTexture.h>
2684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi#include <gui/SurfaceTextureClient.h>
2784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
2830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniusing android::filterfw::GLEnv;
2930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniusing android::filterfw::WindowHandle;
3084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::MediaRecorder;
3184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::sp;
3284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::ISurfaceTexture;
3384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::SurfaceTextureClient;
3484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
3530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
3630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniclass NativeWindowHandle : public WindowHandle {
3730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  public:
3830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    NativeWindowHandle(ANativeWindow* window) : window_(window) {
3930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
4030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
4130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    virtual ~NativeWindowHandle() {
4230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
4330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
4430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    virtual void Destroy() {
4530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      LOGI("Releasing ANativeWindow!");
4630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      ANativeWindow_release(window_);
4730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
4830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
4930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    virtual const void* InternalHandle() const {
5030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      return window_;
5130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
5230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
535b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala    virtual void* InternalHandle() {
545b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala      return window_;
555b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala    }
565b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala
5730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  private:
5830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    ANativeWindow* window_;
5930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni};
6030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
61edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeAllocate(JNIEnv* env, jobject thiz) {
6230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return ToJBool(WrapObjectInJava(new GLEnv(), env, thiz, true));
6330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
6430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
65edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeDeallocate(JNIEnv* env, jobject thiz) {
6630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return ToJBool(DeleteNativeObject<GLEnv>(env, thiz));
6730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
6830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
69edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithNewContext(JNIEnv* env,
70edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala                                                                           jobject thiz) {
7130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
7230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->InitWithNewContext()) : JNI_FALSE;
7330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
7430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
75edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithCurrentContext(JNIEnv* env,
76edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala                                                                               jobject thiz) {
7730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
7830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->InitWithCurrentContext()) : JNI_FALSE;
7930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
8030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
813fe79927824090988e0123781bec44f8a31779f8Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsActive(JNIEnv* env, jobject thiz) {
823fe79927824090988e0123781bec44f8a31779f8Marius Renn  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
833fe79927824090988e0123781bec44f8a31779f8Marius Renn  return gl_env ? ToJBool(gl_env->IsActive()) : JNI_FALSE;
843fe79927824090988e0123781bec44f8a31779f8Marius Renn}
853fe79927824090988e0123781bec44f8a31779f8Marius Renn
86a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* env, jobject thiz) {
87a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
88a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn  return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE;
89a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn}
90a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn
91a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env,
92a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn                                                                           jclass clazz) {
93a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn  return ToJBool(GLEnv::IsAnyContextActive());
94a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn}
95a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn
96edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeActivate(JNIEnv* env, jobject thiz) {
9730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
9830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->Activate()) : JNI_FALSE;
9930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
10030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
101edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeDeactivate(JNIEnv* env, jobject thiz) {
10230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
10330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->Deactivate()) : JNI_FALSE;
10430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
10530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
106edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeSwapBuffers(JNIEnv* env, jobject thiz) {
10730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
10830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->SwapBuffers()) : JNI_FALSE;
10930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
11030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
11184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// Get the native mediarecorder object corresponding to the java object
11284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketistatic sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject jmediarecorder) {
11384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    jclass clazz = env->FindClass("android/media/MediaRecorder");
11484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (clazz == NULL) {
11584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        return NULL;
11684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
11784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
11884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    jfieldID context = env->GetFieldID(clazz, "mNativeContext", "I");
11984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (context == NULL) {
12084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        return NULL;
12184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
12284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
12384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    MediaRecorder* const p = (MediaRecorder*)env->GetIntField(jmediarecorder, context);
12484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    env->DeleteLocalRef(clazz);
12584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    return sp<MediaRecorder>(p);
12684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi}
12784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
12884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
12930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijint Java_android_filterfw_core_GLEnvironment_nativeAddSurface(JNIEnv* env,
13030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                               jobject thiz,
13130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                               jobject surface) {
13230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
13330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  if (!surface) {
13430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    LOGE("GLEnvironment: Null Surface passed!");
13530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    return -1;
13630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  } else if (gl_env) {
13730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    // Get the ANativeWindow
13830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
13930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    if (!window) {
14030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      LOGE("GLEnvironment: Error creating window!");
14130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      return -1;
14230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
14330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
14430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    NativeWindowHandle* winHandle = new NativeWindowHandle(window);
14530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    int result = gl_env->FindSurfaceIdForWindow(winHandle);
14630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    if (result == -1) {
14730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      // Configure surface
14830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLConfig config;
14930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLint numConfigs = -1;
15030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLint configAttribs[] = {
15130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
15230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
15330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        EGL_NONE
15430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      };
15530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
15630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs);
15730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      if (numConfigs < 1) {
15830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        LOGE("GLEnvironment: No suitable EGL configuration found for surface!");
15930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        return -1;
16030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      }
16130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
16230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      // Create the EGL surface
16330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(),
16430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                      config,
16530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                      window,
16630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                      NULL);
16730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
16830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      if (GLEnv::CheckEGLError("eglCreateWindowSurface")) {
16930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        LOGE("GLEnvironment: Error creating window surface!");
17017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        return -1;
17117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      }
17217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
17317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      // Add it to GL Env and assign ID
17417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      result = gl_env->AddWindowSurface(egl_surface, winHandle);
17517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    } else {
17617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      delete winHandle;
17717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    }
17817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    return result;
17917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala  }
18017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala  return -1;
18117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala}
18217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
18317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvalajint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceTexture(JNIEnv* env,
18417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                                      jobject thiz,
18517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                                      jobject surfaceTexture,
18617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                                      jint width,
18717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                                      jint height) {
18817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
18917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala  if (!surfaceTexture) {
19017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    LOGE("GLEnvironment: Null SurfaceTexture passed!");
19117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    return -1;
19217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala  } else if (gl_env) {
19317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    // Get the ANativeWindow
19417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    ANativeWindow* window = ANativeWindow_fromSurfaceTexture(env, surfaceTexture);
19517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    if (!window) {
19617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      LOGE("GLEnvironment: Error creating window!");
19717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      return -1;
19817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    }
19917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
20017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    // Don't care about format (will get overridden by SurfaceTexture
20117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    // anyway), but do care about width and height
20284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // TODO: Probably, this should be just be
20384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // ANativeWindow_setBuffersDimensions. The pixel format is
20484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // set during the eglCreateWindowSurface
20517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    ANativeWindow_setBuffersGeometry(window, width, height, 0);
20617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
20717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    NativeWindowHandle* winHandle = new NativeWindowHandle(window);
20817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    int result = gl_env->FindSurfaceIdForWindow(winHandle);
20917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala    if (result == -1) {
21017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      // Configure surface
21117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      EGLConfig config;
21217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      EGLint numConfigs = -1;
21317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      EGLint configAttribs[] = {
21417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
21517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
21617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        EGL_NONE
21717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      };
21817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
21917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs);
22017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      if (numConfigs < 1) {
22117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        LOGE("GLEnvironment: No suitable EGL configuration found for surface texture!");
22217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        return -1;
22317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      }
22417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
22517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      // Create the EGL surface
22617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(),
22717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                      config,
22817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                      window,
22917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala                                                      NULL);
23017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala
23117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala      if (GLEnv::CheckEGLError("eglCreateWindowSurface")) {
23217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala        LOGE("GLEnvironment: Error creating window surface!");
23330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni        return -1;
23430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      }
23530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
23630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      // Add it to GL Env and assign ID
23730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      result = gl_env->AddWindowSurface(egl_surface, winHandle);
23830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    } else {
23930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni      delete winHandle;
24030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    }
24130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni    return result;
24230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  }
24330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return -1;
24430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
24530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
24684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// nativeAddSurfaceFromMediaRecorder gets an EGLSurface
24784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// using a MediaRecorder object.
24884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// When Mediarecorder is used for recording GL Frames, it
24984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// will have a reference to a Native Handle (a SurfaceTexureClient)
25084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// which talks to the StageFrightRecorder in mediaserver via
25184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// a binder interface.
25284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketijint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceFromMediaRecorder(
25384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi                                                      JNIEnv* env,
25484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi                                                      jobject thiz,
25584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi                                                      jobject jmediarecorder) {
25684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
25784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (!gl_env) {
25884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        return -1;
25984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
26084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // get a native mediarecorder object from the java object
26184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    sp<MediaRecorder> mr = getMediaRecorder(env, jmediarecorder);
26284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (mr == NULL) {
26384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        LOGE("GLEnvironment: Error- MediaRecorder could not be initialized!");
26484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        return -1;
26584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
26684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
26784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // Ask the mediarecorder to return a handle to a surfacemediasource
26884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // This will talk to the StageFrightRecorder via MediaRecorderClient
26984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // over binder calls
27084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    sp<ISurfaceTexture> surfaceMS = mr->querySurfaceMediaSourceFromMediaServer();
27184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (surfaceMS == NULL) {
27284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      LOGE("GLEnvironment: Error- MediaRecorder returned a null \
27384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi              <ISurfaceTexture> handle.");
27484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      return -1;
27584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
27684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    sp<SurfaceTextureClient> surfaceTC = new SurfaceTextureClient(surfaceMS);
27784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // Get the ANativeWindow
27884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    sp<ANativeWindow> window = surfaceTC;
27984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
28084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
28184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (window == NULL) {
28284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      LOGE("GLEnvironment: Error creating window!");
28384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      return -1;
28484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
28584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
28684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // In case of encoding, no need to set the dimensions
28784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // on the buffers. The dimensions for the final encoding are set by
28884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // the consumer side.
28984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // The pixel format is dictated by the GL, and set during the
29084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // eglCreateWindowSurface
29184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
29284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    NativeWindowHandle* winHandle = new NativeWindowHandle(window.get());
29384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    int result = gl_env->FindSurfaceIdForWindow(winHandle);
29484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // If we find a surface with that window handle, just return that id
29584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (result != -1) {
29684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        delete winHandle;
29784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi        return result;
29884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
29984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // If we do not find a surface with that window handle, create
30084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // one and assign to it the handle
30184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // Configure surface
30284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    EGLConfig config;
30384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    EGLint numConfigs = -1;
30484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    EGLint configAttribs[] = {
30584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
30684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
30784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_RED_SIZE, 8,
30884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_GREEN_SIZE, 8,
30984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_BLUE_SIZE, 8,
31084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_ANDROID_recordable, EGL_TRUE,
31184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi          EGL_NONE
31284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    };
31384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
31484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs);
31584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (numConfigs < 1) {
31684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      LOGE("GLEnvironment: No suitable EGL configuration found for surface texture!");
31784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      delete winHandle;
31884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      return -1;
31984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
32084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
32184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // Create the EGL surface
32284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(),
32384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi                                                    config,
32484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi                                                    window.get(),
32584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi                                                    NULL);
32684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
32784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    if (GLEnv::CheckEGLError("eglCreateWindowSurface")) {
32884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      LOGE("GLEnvironment: Error creating window surface!");
32984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      delete winHandle;
33084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi      return -1;
33184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    }
33284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
33384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    // Add it to GL Env and assign ID
33484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    result = gl_env->AddWindowSurface(egl_surface, winHandle);
33584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi    return result;
33684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi}
33784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi
33830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_nativeActivateSurfaceId(JNIEnv* env,
33930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                          jobject thiz,
34030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                          jint surfaceId) {
34130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
34230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->SwitchToSurfaceId(surfaceId)) : JNI_FALSE;
34330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
34430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni
34530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_nativeRemoveSurfaceId(JNIEnv* env,
34630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                        jobject thiz,
34730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni                                                                        jint surfaceId) {
34830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
34930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni  return gl_env ? ToJBool(gl_env->ReleaseSurfaceId(surfaceId)) : JNI_FALSE;
35030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}
3515b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala
3525b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeSetSurfaceTimestamp(JNIEnv* env,
3535b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala                                                                            jobject thiz,
3545b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala                                                                            jlong timestamp) {
3555b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
3565b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala  int64_t timestamp_native = timestamp;
3575b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala  return gl_env ? ToJBool(gl_env->SetSurfaceTimestamp(timestamp_native)) : JNI_FALSE;
3585b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala}
359