165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// #define LOG_NDEBUG 0 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <stdint.h> 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <android/native_window_jni.h> 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "jni/jni_gl_environment.h" 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "jni/jni_util.h" 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <media/mediarecorder.h> 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "native/core/gl_env.h" 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden#include <gui/IGraphicBufferProducer.h> 2752800617946c456e78ed010c82d0ec4358368164Mathias Agopian#include <gui/Surface.h> 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <utils/Errors.h> 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <system/window.h> 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::filterfw::GLEnv; 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::filterfw::WindowHandle; 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::MediaRecorder; 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::sp; 36d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFaddenusing android::IGraphicBufferProducer; 3752800617946c456e78ed010c82d0ec4358368164Mathias Agopianusing android::Surface; 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass NativeWindowHandle : public WindowHandle { 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public: 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle(ANativeWindow* window) : window_(window) { 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn virtual ~NativeWindowHandle() { 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn virtual void Destroy() { 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGI("Releasing ANativeWindow!"); 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow_release(window_); 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn virtual const void* InternalHandle() const { 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return window_; 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn virtual void* InternalHandle() { 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return window_; 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private: 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow* window_; 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}; 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeAllocate(JNIEnv* env, jobject thiz) { 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return ToJBool(WrapObjectInJava(new GLEnv(), env, thiz, true)); 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeDeallocate(JNIEnv* env, jobject thiz) { 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return ToJBool(DeleteNativeObject<GLEnv>(env, thiz)); 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithNewContext(JNIEnv* env, 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz) { 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->InitWithNewContext()) : JNI_FALSE; 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithCurrentContext(JNIEnv* env, 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz) { 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->InitWithCurrentContext()) : JNI_FALSE; 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsActive(JNIEnv* env, jobject thiz) { 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->IsActive()) : JNI_FALSE; 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* env, jobject thiz) { 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE; 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env, 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jclass clazz) { 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return ToJBool(GLEnv::IsAnyContextActive()); 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeActivate(JNIEnv* env, jobject thiz) { 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->Activate()) : JNI_FALSE; 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeDeactivate(JNIEnv* env, jobject thiz) { 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->Deactivate()) : JNI_FALSE; 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeSwapBuffers(JNIEnv* env, jobject thiz) { 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->SwapBuffers()) : JNI_FALSE; 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Get the native mediarecorder object corresponding to the java object 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennstatic sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject jmediarecorder) { 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jclass clazz = env->FindClass("android/media/MediaRecorder"); 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (clazz == NULL) { 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return NULL; 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 122075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat jfieldID context = env->GetFieldID(clazz, "mNativeContext", "J"); 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context == NULL) { 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return NULL; 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 127075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat MediaRecorder* const p = (MediaRecorder*)env->GetLongField(jmediarecorder, context); 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn env->DeleteLocalRef(clazz); 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return sp<MediaRecorder>(p); 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLEnvironment_nativeAddSurface(JNIEnv* env, 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject surface) { 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!surface) { 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Null Surface passed!"); 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if (gl_env) { 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ANativeWindow 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow* window = ANativeWindow_fromSurface(env, surface); 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!window) { 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window!"); 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle* winHandle = new NativeWindowHandle(window); 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int result = gl_env->FindSurfaceIdForWindow(winHandle); 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == -1) { 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure surface 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: No suitable EGL configuration found for surface!"); 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create the EGL surface 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window, 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NULL); 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window surface!"); 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add it to GL Env and assign ID 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = gl_env->AddWindowSurface(egl_surface, winHandle); 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else { 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceWidthHeight(JNIEnv* env, 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject surface, 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint width, 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint height) { 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!surface) { 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Null SurfaceTexture passed!"); 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if (gl_env) { 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ANativeWindow 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow* window = ANativeWindow_fromSurface(env, surface); 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!window) { 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window!"); 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Don't care about format (will get overridden by SurfaceTexture 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // anyway), but do care about width and height 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // TODO: Probably, this should be just be 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // ANativeWindow_setBuffersDimensions. The pixel format is 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // set during the eglCreateWindowSurface 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow_setBuffersGeometry(window, width, height, 0); 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle* winHandle = new NativeWindowHandle(window); 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int result = gl_env->FindSurfaceIdForWindow(winHandle); 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == -1) { 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure surface 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: No suitable EGL configuration found for surface texture!"); 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create the EGL surface 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window, 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NULL); 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window surface!"); 24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add it to GL Env and assign ID 25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = gl_env->AddWindowSurface(egl_surface, winHandle); 25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else { 25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// nativeAddSurfaceFromMediaRecorder gets an EGLSurface 26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// using a MediaRecorder object. 26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// When Mediarecorder is used for recording GL Frames, it 26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// will have a reference to a Native Handle (a SurfaceTexureClient) 26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// which talks to the StageFrightRecorder in mediaserver via 26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// a binder interface. 26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceFromMediaRecorder( 26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn JNIEnv* env, 27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject jmediarecorder) { 27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGV("GLEnv Jni: nativeAddSurfaceFromMediaRecorder"); 27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!gl_env) { 27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // get a native mediarecorder object from the java object 27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn sp<MediaRecorder> mr = getMediaRecorder(env, jmediarecorder); 27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mr == NULL) { 28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error- MediaRecorder could not be initialized!"); 28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Ask the mediarecorder to return a handle to a surfacemediasource 28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // This will talk to the StageFrightRecorder via MediaRecorderClient 28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // over binder calls 287d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> surfaceMS = mr->querySurfaceMediaSourceFromMediaServer(); 28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surfaceMS == NULL) { 28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error- MediaRecorder returned a null \ 290d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden <IGraphicBufferProducer> handle."); 29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29352800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> surfaceTC = new Surface(surfaceMS); 29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ANativeWindow 29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn sp<ANativeWindow> window = surfaceTC; 29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (window == NULL) { 29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window!"); 30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window->incStrong((void*)ANativeWindow_acquire); 30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // In case of encoding, no need to set the dimensions 30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // on the buffers. The dimensions for the final encoding are set by 30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // the consumer side. 30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // The pixel format is dictated by the GL, and set during the 30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // eglCreateWindowSurface 30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle* winHandle = new NativeWindowHandle(window.get()); 31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int result = gl_env->FindSurfaceIdForWindow(winHandle); 31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // If we find a surface with that window handle, just return that id 31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result != -1) { 31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 31565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 31665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 31765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // If we do not find a surface with that window handle, create 31865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // one and assign to it the handle 31965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure surface 32065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 32165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 32265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 32365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 32465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 32565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 32665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 32765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 32865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 32965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 33065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 33165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 33265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 33365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 33465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 33565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: No suitable EGL configuration found for surface texture!"); 33665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 33765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 33865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 33965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 34065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create the EGL surface 34165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 34265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 34365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window.get(), 34465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NULL); 34565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 34665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 34765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window surface!"); 34865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 34965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 35065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 35165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add it to GL Env and assign ID 35365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = gl_env->AddWindowSurface(egl_surface, winHandle); 35465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 35565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 35665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeActivateSurfaceId(JNIEnv* env, 35865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 35965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint surfaceId) { 36065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 36165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->SwitchToSurfaceId(surfaceId) && gl_env->Activate()) : JNI_FALSE; 36265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 36365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 36465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeRemoveSurfaceId(JNIEnv* env, 36565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 36665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint surfaceId) { 36765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 36865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->ReleaseSurfaceId(surfaceId)) : JNI_FALSE; 36965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 37065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 37165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeSetSurfaceTimestamp(JNIEnv* env, 37265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 37365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jlong timestamp) { 37465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 37565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int64_t timestamp_native = timestamp; 37665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->SetSurfaceTimestamp(timestamp_native)) : JNI_FALSE; 37765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 378