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