gecko/gfx/thebes/nsSurfaceTexture.cpp
Ryan VanderMeulen fb2d6dc1a4 Backed out 6 changesets (bug 913985) for suspicion of causing intermittent Android crashes on a CLOSED TREE.
Backed out changeset de21920d2b8e (bug 913985)
Backed out changeset f0f5497d65bb (bug 913985)
Backed out changeset 1e16ca4ad801 (bug 913985)
Backed out changeset 9c069a0820ea (bug 913985)
Backed out changeset 274df3abc991 (bug 913985)
Backed out changeset 05fe8b17516a (bug 913985)

--HG--
rename : build/annotationProcessors/AnnotationInfo.java => build/annotationProcessors/MethodWithAnnotationInfo.java
rename : build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java => build/annotationProcessors/utils/AlphabeticMethodComparator.java
rename : build/annotationProcessors/utils/GeneratableElementIterator.java => build/annotationProcessors/utils/GeneratableEntryPointIterator.java
rename : mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java => mobile/android/base/mozglue/GeneratableAndroidBridgeTarget.java
rename : mobile/android/base/mozglue/generatorannotations/OptionalGeneratedParameter.java => mobile/android/base/mozglue/OptionalGeneratedParameter.java
2013-09-27 17:02:09 -04:00

264 lines
6.0 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:set ts=2 sts=2 sw=2 et cin:
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef MOZ_WIDGET_ANDROID
#include <set>
#include <map>
#include <android/log.h>
#include "nsSurfaceTexture.h"
#include "gfxImageSurface.h"
#include "AndroidBridge.h"
#include "nsThreadUtils.h"
using namespace mozilla;
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "nsSurfaceTexture" , ## args)
// UGH
static std::map<int, nsSurfaceTexture*> sInstances;
static int sNextID = 0;
static class JNIFunctions {
public:
JNIFunctions() : mInitialized(false)
{
}
bool EnsureInitialized()
{
if (mInitialized)
return true;
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env);
jSurfaceTextureClass = (jclass)env->NewGlobalRef(env->FindClass("android/graphics/SurfaceTexture"));
jSurfaceTexture_Ctor = env->GetMethodID(jSurfaceTextureClass, "<init>", "(I)V");
jSurfaceTexture_updateTexImage = env->GetMethodID(jSurfaceTextureClass, "updateTexImage", "()V");
jSurfaceTexture_getTransformMatrix = env->GetMethodID(jSurfaceTextureClass, "getTransformMatrix", "([F)V");
mInitialized = true;
return true;
}
jobject CreateSurfaceTexture(GLuint aTexture)
{
if (!EnsureInitialized())
return nullptr;
JNIEnv* env = GetJNIForThread();
if (!env)
return nullptr;
AutoLocalJNIFrame jniFrame(env);
return env->NewGlobalRef(env->NewObject(jSurfaceTextureClass, jSurfaceTexture_Ctor, (int) aTexture));
}
void ReleaseSurfaceTexture(jobject aSurfaceTexture)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return;
env->DeleteGlobalRef(aSurfaceTexture);
}
void UpdateTexImage(jobject aSurfaceTexture)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env);
env->CallObjectMethod(aSurfaceTexture, jSurfaceTexture_updateTexImage);
}
bool GetTransformMatrix(jobject aSurfaceTexture, gfx3DMatrix& aMatrix)
{
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AutoLocalJNIFrame jniFrame(env);
jfloatArray jarray = env->NewFloatArray(16);
env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_getTransformMatrix, jarray);
jfloat* array = env->GetFloatArrayElements(jarray, nullptr);
aMatrix._11 = array[0];
aMatrix._12 = array[1];
aMatrix._13 = array[2];
aMatrix._14 = array[3];
aMatrix._21 = array[4];
aMatrix._22 = array[5];
aMatrix._23 = array[6];
aMatrix._24 = array[7];
aMatrix._31 = array[8];
aMatrix._32 = array[9];
aMatrix._33 = array[10];
aMatrix._34 = array[11];
aMatrix._41 = array[12];
aMatrix._42 = array[13];
aMatrix._43 = array[14];
aMatrix._44 = array[15];
env->ReleaseFloatArrayElements(jarray, array, 0);
return false;
}
private:
bool mInitialized;
jclass jSurfaceTextureClass;
jmethodID jSurfaceTexture_Ctor;
jmethodID jSurfaceTexture_updateTexImage;
jmethodID jSurfaceTexture_getTransformMatrix;
} sJNIFunctions;
nsSurfaceTexture*
nsSurfaceTexture::Create(GLuint aTexture)
{
// Right now we only support creating this on the main thread because
// of the JNIEnv assumptions in JNIHelper and elsewhere
if (!NS_IsMainThread())
return nullptr;
nsSurfaceTexture* st = new nsSurfaceTexture();
if (!st->Init(aTexture)) {
LOG("Failed to initialize nsSurfaceTexture");
delete st;
st = nullptr;
}
return st;
}
nsSurfaceTexture*
nsSurfaceTexture::Find(int id)
{
std::map<int, nsSurfaceTexture*>::iterator it;
it = sInstances.find(id);
if (it == sInstances.end())
return nullptr;
return it->second;
}
bool
nsSurfaceTexture::Check()
{
return sJNIFunctions.EnsureInitialized();
}
bool
nsSurfaceTexture::Init(GLuint aTexture)
{
if (!sJNIFunctions.EnsureInitialized())
return false;
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
mSurfaceTexture = sJNIFunctions.CreateSurfaceTexture(aTexture);
if (!mSurfaceTexture)
return false;
mNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindowFromSurfaceTexture(env, mSurfaceTexture);
mID = ++sNextID;
sInstances.insert(std::pair<int, nsSurfaceTexture*>(mID, this));
return true;
}
nsSurfaceTexture::nsSurfaceTexture()
: mSurfaceTexture(nullptr), mNativeWindow(nullptr)
{
}
nsSurfaceTexture::~nsSurfaceTexture()
{
sInstances.erase(mID);
mFrameAvailableCallback = nullptr;
if (mNativeWindow) {
AndroidBridge::Bridge()->ReleaseNativeWindowForSurfaceTexture(mSurfaceTexture);
mNativeWindow = nullptr;
}
JNIEnv* env = GetJNIForThread();
if (!env)
return;
if (mSurfaceTexture && env) {
AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
env->DeleteGlobalRef(mSurfaceTexture);
mSurfaceTexture = nullptr;
}
}
void*
nsSurfaceTexture::GetNativeWindow()
{
return mNativeWindow;
}
void
nsSurfaceTexture::UpdateTexImage()
{
sJNIFunctions.UpdateTexImage(mSurfaceTexture);
}
bool
nsSurfaceTexture::GetTransformMatrix(gfx3DMatrix& aMatrix)
{
return sJNIFunctions.GetTransformMatrix(mSurfaceTexture, aMatrix);
}
void
nsSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
{
if (aRunnable)
AndroidBridge::Bridge()->RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID);
else
AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
mFrameAvailableCallback = aRunnable;
}
void
nsSurfaceTexture::NotifyFrameAvailable()
{
if (mFrameAvailableCallback) {
// Proxy to main thread if we aren't on it
if (!NS_IsMainThread()) {
// Proxy to main thread
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &nsSurfaceTexture::NotifyFrameAvailable);
NS_DispatchToCurrentThread(event);
} else {
mFrameAvailableCallback->Run();
}
}
}
#endif // MOZ_WIDGET_ANDROID