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 */ 16f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi// #define LOG_NDEBUG 0 1730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <stdint.h> 1930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <android/native_window_jni.h> 2030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 2130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "jni/jni_gl_environment.h" 2230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "jni/jni_util.h" 2384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi#include <media/mediarecorder.h> 2430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "native/core/gl_env.h" 2530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 2684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi#include <gui/ISurfaceTexture.h> 2784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi#include <gui/SurfaceTextureClient.h> 28f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi#include <utils/Errors.h> 29f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi#include <system/window.h> 30f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi 3184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 3230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniusing android::filterfw::GLEnv; 3330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniusing android::filterfw::WindowHandle; 3484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::MediaRecorder; 3584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::sp; 3684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::ISurfaceTexture; 3784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketiusing android::SurfaceTextureClient; 3884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 3930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 4030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniclass NativeWindowHandle : public WindowHandle { 4130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public: 4230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni NativeWindowHandle(ANativeWindow* window) : window_(window) { 4330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 4430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 4530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni virtual ~NativeWindowHandle() { 4630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 4730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 4830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni virtual void Destroy() { 4930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGI("Releasing ANativeWindow!"); 5030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ANativeWindow_release(window_); 5130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 5230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni virtual const void* InternalHandle() const { 5430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return window_; 5530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 5630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 575b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala virtual void* InternalHandle() { 585b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala return window_; 595b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala } 605b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala 6130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private: 6230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ANativeWindow* window_; 6330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}; 6430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 65edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeAllocate(JNIEnv* env, jobject thiz) { 6630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return ToJBool(WrapObjectInJava(new GLEnv(), env, thiz, true)); 6730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 6830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 69edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeDeallocate(JNIEnv* env, jobject thiz) { 7030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return ToJBool(DeleteNativeObject<GLEnv>(env, thiz)); 7130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 7230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 73edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithNewContext(JNIEnv* env, 74edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala jobject thiz) { 7530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 7630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return gl_env ? ToJBool(gl_env->InitWithNewContext()) : JNI_FALSE; 7730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 7830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 79edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithCurrentContext(JNIEnv* env, 80edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvala jobject thiz) { 8130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 8230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return gl_env ? ToJBool(gl_env->InitWithCurrentContext()) : JNI_FALSE; 8330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 8430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 853fe79927824090988e0123781bec44f8a31779f8Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsActive(JNIEnv* env, jobject thiz) { 863fe79927824090988e0123781bec44f8a31779f8Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 873fe79927824090988e0123781bec44f8a31779f8Marius Renn return gl_env ? ToJBool(gl_env->IsActive()) : JNI_FALSE; 883fe79927824090988e0123781bec44f8a31779f8Marius Renn} 893fe79927824090988e0123781bec44f8a31779f8Marius Renn 90a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* env, jobject thiz) { 91a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 92a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE; 93a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn} 94a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn 95a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env, 96a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn jclass clazz) { 97a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn return ToJBool(GLEnv::IsAnyContextActive()); 98a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn} 99a935c0d2759dc11fc60e56d0b2751e8eaa0fac74Marius Renn 100edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeActivate(JNIEnv* env, jobject thiz) { 10130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 10230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return gl_env ? ToJBool(gl_env->Activate()) : JNI_FALSE; 10330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 10430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 105edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeDeactivate(JNIEnv* env, jobject thiz) { 10630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 10730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return gl_env ? ToJBool(gl_env->Deactivate()) : JNI_FALSE; 10830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 10930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 110edfc0941e7a9480d2bbc70e842015e6fa56a2c3fEddy Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeSwapBuffers(JNIEnv* env, jobject thiz) { 11130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 11230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return gl_env ? ToJBool(gl_env->SwapBuffers()) : JNI_FALSE; 11330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 11430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 11584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// Get the native mediarecorder object corresponding to the java object 11684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketistatic sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject jmediarecorder) { 11784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi jclass clazz = env->FindClass("android/media/MediaRecorder"); 11884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (clazz == NULL) { 11984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return NULL; 12084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 12184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 12284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi jfieldID context = env->GetFieldID(clazz, "mNativeContext", "I"); 12384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (context == NULL) { 12484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return NULL; 12584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 12684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 12784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi MediaRecorder* const p = (MediaRecorder*)env->GetIntField(jmediarecorder, context); 12884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi env->DeleteLocalRef(clazz); 12984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return sp<MediaRecorder>(p); 13084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi} 13184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 13284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 13330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijint Java_android_filterfw_core_GLEnvironment_nativeAddSurface(JNIEnv* env, 13430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject thiz, 13530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject surface) { 13630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 13730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (!surface) { 13830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGE("GLEnvironment: Null Surface passed!"); 13930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return -1; 14030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } else if (gl_env) { 14130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Get the ANativeWindow 14230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ANativeWindow* window = ANativeWindow_fromSurface(env, surface); 14330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (!window) { 14430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGE("GLEnvironment: Error creating window!"); 14530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return -1; 14630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 14730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 14830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni NativeWindowHandle* winHandle = new NativeWindowHandle(window); 14930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni int result = gl_env->FindSurfaceIdForWindow(winHandle); 15030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (result == -1) { 15130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Configure surface 15230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGLConfig config; 15330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGLint numConfigs = -1; 15430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGLint configAttribs[] = { 15530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 15630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 157f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_RED_SIZE, 8, 158f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_GREEN_SIZE, 8, 159f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_BLUE_SIZE, 8, 160f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_RECORDABLE_ANDROID, EGL_TRUE, 16130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGL_NONE 16230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni }; 16330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 164f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi 165f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi 16630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 16730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (numConfigs < 1) { 16830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGE("GLEnvironment: No suitable EGL configuration found for surface!"); 16930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return -1; 17030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 17130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 17230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create the EGL surface 17330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 17430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni config, 17530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni window, 17630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni NULL); 17730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 17830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 17930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGE("GLEnvironment: Error creating window surface!"); 18017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala return -1; 18117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } 18217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 18317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala // Add it to GL Env and assign ID 18417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala result = gl_env->AddWindowSurface(egl_surface, winHandle); 18517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } else { 18617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala delete winHandle; 18717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } 18817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala return result; 18917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } 19017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala return -1; 19117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala} 19217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 19317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvalajint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceTexture(JNIEnv* env, 19417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala jobject thiz, 19517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala jobject surfaceTexture, 19617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala jint width, 19717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala jint height) { 19817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 19917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala if (!surfaceTexture) { 20017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala LOGE("GLEnvironment: Null SurfaceTexture passed!"); 20117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala return -1; 20217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } else if (gl_env) { 20317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala // Get the ANativeWindow 20417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala ANativeWindow* window = ANativeWindow_fromSurfaceTexture(env, surfaceTexture); 20517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala if (!window) { 20617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala LOGE("GLEnvironment: Error creating window!"); 20717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala return -1; 20817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } 20917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 21017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala // Don't care about format (will get overridden by SurfaceTexture 21117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala // anyway), but do care about width and height 21284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // TODO: Probably, this should be just be 21384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // ANativeWindow_setBuffersDimensions. The pixel format is 21484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // set during the eglCreateWindowSurface 21517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala ANativeWindow_setBuffersGeometry(window, width, height, 0); 21617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 21717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala NativeWindowHandle* winHandle = new NativeWindowHandle(window); 21817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala int result = gl_env->FindSurfaceIdForWindow(winHandle); 21917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala if (result == -1) { 22017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala // Configure surface 22117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGLConfig config; 22217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGLint numConfigs = -1; 22317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGLint configAttribs[] = { 22417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 22517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 226f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_RED_SIZE, 8, 227f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_GREEN_SIZE, 8, 228f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_BLUE_SIZE, 8, 229f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_RECORDABLE_ANDROID, EGL_TRUE, 23017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGL_NONE 23117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala }; 23217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 233f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi 234f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi 23517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 23617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala if (numConfigs < 1) { 23717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala LOGE("GLEnvironment: No suitable EGL configuration found for surface texture!"); 23817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala return -1; 23917b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala } 24017b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 24117b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala // Create the EGL surface 24217b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 24317b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala config, 24417b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala window, 24517b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala NULL); 24617b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala 24717b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 24817b672fd95a037fefb3e06c2f214551a45a15954Eino-Ville Talvala LOGE("GLEnvironment: Error creating window surface!"); 24930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return -1; 25030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 25130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Add it to GL Env and assign ID 25330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni result = gl_env->AddWindowSurface(egl_surface, winHandle); 25430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } else { 25530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni delete winHandle; 25630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 25730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return result; 25830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 25930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return -1; 26030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 26130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// nativeAddSurfaceFromMediaRecorder gets an EGLSurface 26384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// using a MediaRecorder object. 26484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// When Mediarecorder is used for recording GL Frames, it 26584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// will have a reference to a Native Handle (a SurfaceTexureClient) 26684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// which talks to the StageFrightRecorder in mediaserver via 26784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi// a binder interface. 26884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketijint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceFromMediaRecorder( 26984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi JNIEnv* env, 27084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi jobject thiz, 27184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi jobject jmediarecorder) { 272f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi LOGV("GLEnv Jni: nativeAddSurfaceFromMediaRecorder"); 27384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 27484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (!gl_env) { 27584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return -1; 27684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 27784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // get a native mediarecorder object from the java object 27884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi sp<MediaRecorder> mr = getMediaRecorder(env, jmediarecorder); 27984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (mr == NULL) { 28084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi LOGE("GLEnvironment: Error- MediaRecorder could not be initialized!"); 28184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return -1; 28284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 28384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 28484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // Ask the mediarecorder to return a handle to a surfacemediasource 28584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // This will talk to the StageFrightRecorder via MediaRecorderClient 28684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // over binder calls 28784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi sp<ISurfaceTexture> surfaceMS = mr->querySurfaceMediaSourceFromMediaServer(); 28884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (surfaceMS == NULL) { 28984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi LOGE("GLEnvironment: Error- MediaRecorder returned a null \ 29084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi <ISurfaceTexture> handle."); 29184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return -1; 29284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 29384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi sp<SurfaceTextureClient> surfaceTC = new SurfaceTextureClient(surfaceMS); 29484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // Get the ANativeWindow 29584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi sp<ANativeWindow> window = surfaceTC; 29684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 29784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 29884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (window == NULL) { 29984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi LOGE("GLEnvironment: Error creating window!"); 30084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return -1; 30184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 302f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi window->incStrong((void*)ANativeWindow_acquire); 30384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 30484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // In case of encoding, no need to set the dimensions 30584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // on the buffers. The dimensions for the final encoding are set by 30684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // the consumer side. 30784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // The pixel format is dictated by the GL, and set during the 30884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // eglCreateWindowSurface 30984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 31084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi NativeWindowHandle* winHandle = new NativeWindowHandle(window.get()); 31184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi int result = gl_env->FindSurfaceIdForWindow(winHandle); 31284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // If we find a surface with that window handle, just return that id 31384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (result != -1) { 31484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi delete winHandle; 31584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return result; 31684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 31784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // If we do not find a surface with that window handle, create 31884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // one and assign to it the handle 31984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // Configure surface 32084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGLConfig config; 32184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGLint numConfigs = -1; 32284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGLint configAttribs[] = { 32384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 32484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 32584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGL_RED_SIZE, 8, 32684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGL_GREEN_SIZE, 8, 32784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGL_BLUE_SIZE, 8, 328f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi EGL_RECORDABLE_ANDROID, EGL_TRUE, 32984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGL_NONE 33084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi }; 33184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 332f283a907a88fc348b770186562c7a1046a8b7367Pannag Sanketi 33384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 33484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (numConfigs < 1) { 33584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi LOGE("GLEnvironment: No suitable EGL configuration found for surface texture!"); 33684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi delete winHandle; 33784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return -1; 33884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 33984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 34084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // Create the EGL surface 34184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 34284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi config, 34384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi window.get(), 34484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi NULL); 34584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 34684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 34784a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi LOGE("GLEnvironment: Error creating window surface!"); 34884a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi delete winHandle; 34984a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return -1; 35084a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi } 35184a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 35284a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi // Add it to GL Env and assign ID 35384a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi result = gl_env->AddWindowSurface(egl_surface, winHandle); 35484a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi return result; 35584a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi} 35684a9fb79433ee7c66fe1df7b0a754828ff89aec1Pannag Sanketi 35730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_nativeActivateSurfaceId(JNIEnv* env, 35830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject thiz, 35930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jint surfaceId) { 36030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 361470dfeec8a0fbae2a0e8f6021660ef66135b22cePannag Sanketi return gl_env ? ToJBool(gl_env->SwitchToSurfaceId(surfaceId) && gl_env->Activate()) : JNI_FALSE; 36230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 36330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 36430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean Java_android_filterfw_core_GLEnvironment_nativeRemoveSurfaceId(JNIEnv* env, 36530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject thiz, 36630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jint surfaceId) { 36730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 36830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return gl_env ? ToJBool(gl_env->ReleaseSurfaceId(surfaceId)) : JNI_FALSE; 36930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 3705b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala 3715b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvalajboolean Java_android_filterfw_core_GLEnvironment_nativeSetSurfaceTimestamp(JNIEnv* env, 3725b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala jobject thiz, 3735b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala jlong timestamp) { 3745b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 3755b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala int64_t timestamp_native = timestamp; 3765b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala return gl_env ? ToJBool(gl_env->SetSurfaceTimestamp(timestamp_native)) : JNI_FALSE; 3775b9eb6d686c439545dafcc8e25e9e3747281c3deEino-Ville Talvala} 378