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 "native/core/gl_env.h" 24e5160e7e59f96aa457e7a4217197150086e8b7caAndreas Gampe#include <media/mediarecorder.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: 42c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit 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) { 66315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV std::unique_ptr<GLEnv> glEnv(new GLEnv()); 67315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV return ToJBool(WrapOwnedObjectInJava(std::move(glEnv), env, thiz, true)); 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeDeallocate(JNIEnv* env, jobject thiz) { 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return ToJBool(DeleteNativeObject<GLEnv>(env, thiz)); 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithNewContext(JNIEnv* env, 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz) { 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->InitWithNewContext()) : JNI_FALSE; 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeInitWithCurrentContext(JNIEnv* env, 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz) { 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->InitWithCurrentContext()) : JNI_FALSE; 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsActive(JNIEnv* env, jobject thiz) { 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->IsActive()) : JNI_FALSE; 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* env, jobject thiz) { 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE; 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 96e5160e7e59f96aa457e7a4217197150086e8b7caAndreas Gampejboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* /* env */, 97e5160e7e59f96aa457e7a4217197150086e8b7caAndreas Gampe jclass /* clazz */) { 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return ToJBool(GLEnv::IsAnyContextActive()); 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeActivate(JNIEnv* env, jobject thiz) { 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->Activate()) : JNI_FALSE; 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeDeactivate(JNIEnv* env, jobject thiz) { 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->Deactivate()) : JNI_FALSE; 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeSwapBuffers(JNIEnv* env, jobject thiz) { 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->SwapBuffers()) : JNI_FALSE; 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Get the native mediarecorder object corresponding to the java object 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennstatic sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject jmediarecorder) { 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jclass clazz = env->FindClass("android/media/MediaRecorder"); 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (clazz == NULL) { 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return NULL; 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 123075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat jfieldID context = env->GetFieldID(clazz, "mNativeContext", "J"); 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context == NULL) { 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return NULL; 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 128075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat MediaRecorder* const p = (MediaRecorder*)env->GetLongField(jmediarecorder, context); 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn env->DeleteLocalRef(clazz); 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return sp<MediaRecorder>(p); 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLEnvironment_nativeAddSurface(JNIEnv* env, 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject surface) { 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!surface) { 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Null Surface passed!"); 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if (gl_env) { 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ANativeWindow 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow* window = ANativeWindow_fromSurface(env, surface); 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!window) { 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window!"); 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle* winHandle = new NativeWindowHandle(window); 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int result = gl_env->FindSurfaceIdForWindow(winHandle); 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == -1) { 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure surface 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: No suitable EGL configuration found for surface!"); 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create the EGL surface 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window, 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NULL); 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window surface!"); 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add it to GL Env and assign ID 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = gl_env->AddWindowSurface(egl_surface, winHandle); 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else { 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceWidthHeight(JNIEnv* env, 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject surface, 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint width, 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint height) { 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!surface) { 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Null SurfaceTexture passed!"); 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else if (gl_env) { 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ANativeWindow 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow* window = ANativeWindow_fromSurface(env, surface); 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!window) { 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window!"); 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Don't care about format (will get overridden by SurfaceTexture 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // anyway), but do care about width and height 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // TODO: Probably, this should be just be 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // ANativeWindow_setBuffersDimensions. The pixel format is 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // set during the eglCreateWindowSurface 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow_setBuffersGeometry(window, width, height, 0); 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle* winHandle = new NativeWindowHandle(window); 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int result = gl_env->FindSurfaceIdForWindow(winHandle); 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result == -1) { 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure surface 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: No suitable EGL configuration found for surface texture!"); 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create the EGL surface 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window, 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NULL); 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window surface!"); 25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add it to GL Env and assign ID 25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = gl_env->AddWindowSurface(egl_surface, winHandle); 25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } else { 25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// nativeAddSurfaceFromMediaRecorder gets an EGLSurface 26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// using a MediaRecorder object. 26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// When Mediarecorder is used for recording GL Frames, it 26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// will have a reference to a Native Handle (a SurfaceTexureClient) 26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// which talks to the StageFrightRecorder in mediaserver via 26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// a binder interface. 26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLEnvironment_nativeAddSurfaceFromMediaRecorder( 27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn JNIEnv* env, 27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject jmediarecorder) { 27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGV("GLEnv Jni: nativeAddSurfaceFromMediaRecorder"); 27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (!gl_env) { 27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // get a native mediarecorder object from the java object 27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn sp<MediaRecorder> mr = getMediaRecorder(env, jmediarecorder); 28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (mr == NULL) { 28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error- MediaRecorder could not be initialized!"); 28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Ask the mediarecorder to return a handle to a surfacemediasource 28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // This will talk to the StageFrightRecorder via MediaRecorderClient 28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // over binder calls 288d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> surfaceMS = mr->querySurfaceMediaSourceFromMediaServer(); 28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surfaceMS == NULL) { 29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error- MediaRecorder returned a null \ 291d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden <IGraphicBufferProducer> handle."); 29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29452800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> surfaceTC = new Surface(surfaceMS); 29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ANativeWindow 29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn sp<ANativeWindow> window = surfaceTC; 29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (window == NULL) { 30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window!"); 30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window->incStrong((void*)ANativeWindow_acquire); 30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // In case of encoding, no need to set the dimensions 30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // on the buffers. The dimensions for the final encoding are set by 30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // the consumer side. 30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // The pixel format is dictated by the GL, and set during the 30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // eglCreateWindowSurface 31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NativeWindowHandle* winHandle = new NativeWindowHandle(window.get()); 31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int result = gl_env->FindSurfaceIdForWindow(winHandle); 31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // If we find a surface with that window handle, just return that id 31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (result != -1) { 31565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 31665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 31765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 31865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // If we do not find a surface with that window handle, create 31965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // one and assign to it the handle 32065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure surface 32165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 32265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 32365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 32465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 32565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 32665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 32765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 32865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 32965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 33065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 33165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 33265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 33365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 33465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(gl_env->display(), configAttribs, &config, 1, &numConfigs); 33565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 33665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: No suitable EGL configuration found for surface texture!"); 33765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 33865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 33965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 34065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 34165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create the EGL surface 34265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLSurface egl_surface = eglCreateWindowSurface(gl_env->display(), 34365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 34465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window.get(), 34565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn NULL); 34665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 34765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (GLEnv::CheckEGLError("eglCreateWindowSurface")) { 34865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnvironment: Error creating window surface!"); 34965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete winHandle; 35065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 35165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 35265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Add it to GL Env and assign ID 35465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn result = gl_env->AddWindowSurface(egl_surface, winHandle); 35565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 35665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 35765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeActivateSurfaceId(JNIEnv* env, 35965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 36065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint surfaceId) { 36165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 36265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->SwitchToSurfaceId(surfaceId) && gl_env->Activate()) : JNI_FALSE; 36365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 36465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 36565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeRemoveSurfaceId(JNIEnv* env, 36665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 36765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jint surfaceId) { 36865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 36965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->ReleaseSurfaceId(surfaceId)) : JNI_FALSE; 37065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 37165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 37265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLEnvironment_nativeSetSurfaceTimestamp(JNIEnv* env, 37365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject thiz, 37465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jlong timestamp) { 37565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz); 37665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int64_t timestamp_native = timestamp; 37765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return gl_env ? ToJBool(gl_env->SetSurfaceTimestamp(timestamp_native)) : JNI_FALSE; 37865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 379