mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 23:08:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
260
gfx/gl/AndroidSurfaceTexture.cpp
Normal file
260
gfx/gl/AndroidSurfaceTexture.cpp
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
/* -*- 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 <map>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android/log.h>
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "GeneratedJNINatives.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class AndroidSurfaceTexture::Listener
|
||||
: public java::SurfaceTextureListener::Natives<Listener>
|
||||
{
|
||||
using Base = java::SurfaceTextureListener::Natives<Listener>;
|
||||
|
||||
const nsCOMPtr<nsIRunnable> mCallback;
|
||||
|
||||
public:
|
||||
using Base::AttachNative;
|
||||
using Base::DisposeNative;
|
||||
|
||||
Listener(nsIRunnable* aCallback) : mCallback(aCallback) {}
|
||||
|
||||
void OnFrameAvailable()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
mCallback->Run();
|
||||
return;
|
||||
}
|
||||
NS_DispatchToMainThread(mCallback);
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<AndroidSurfaceTexture>
|
||||
AndroidSurfaceTexture::Create()
|
||||
{
|
||||
return Create(nullptr, 0);
|
||||
}
|
||||
|
||||
already_AddRefed<AndroidSurfaceTexture>
|
||||
AndroidSurfaceTexture::Create(GLContext* aContext, GLuint aTexture)
|
||||
{
|
||||
RefPtr<AndroidSurfaceTexture> st = new AndroidSurfaceTexture();
|
||||
if (!st->Init(aContext, aTexture)) {
|
||||
printf_stderr("Failed to initialize AndroidSurfaceTexture");
|
||||
st = nullptr;
|
||||
}
|
||||
|
||||
return st.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout)
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (mAttachedContext == aContext) {
|
||||
NS_WARNING("Tried to attach same GLContext to AndroidSurfaceTexture");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!CanDetach()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
while (mAttachedContext) {
|
||||
// Wait until it's detached (or we time out)
|
||||
if (NS_FAILED(lock.Wait(aTimeout))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aContext->IsOwningThreadCurrent(), "Trying to attach GLContext from different thread");
|
||||
|
||||
aContext->fGenTextures(1, &mTexture);
|
||||
|
||||
if (NS_FAILED(mSurfaceTexture->AttachToGLContext(mTexture))) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
mAttachedContext = aContext;
|
||||
mAttachedContext->MakeCurrent();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AndroidSurfaceTexture::Detach()
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (!CanDetach() ||
|
||||
!mAttachedContext ||
|
||||
!mAttachedContext->IsOwningThreadCurrent())
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mAttachedContext->MakeCurrent();
|
||||
|
||||
mSurfaceTexture->DetachFromGLContext();
|
||||
|
||||
mTexture = 0;
|
||||
mAttachedContext = nullptr;
|
||||
lock.NotifyAll();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidSurfaceTexture::CanDetach() const
|
||||
{
|
||||
// The API for attach/detach only exists on 16+, and PowerVR has some sort of
|
||||
// fencing issue. Additionally, attach/detach seems to be busted on at least
|
||||
// some Mali adapters (400MP2 for sure, bug 1131793)
|
||||
return AndroidBridge::Bridge()->GetAPIVersion() >= 16 &&
|
||||
(!mAttachedContext || mAttachedContext->Vendor() != GLVendor::Imagination) &&
|
||||
(!mAttachedContext || mAttachedContext->Vendor() != GLVendor::ARM /* Mali */) &&
|
||||
gfxPrefs::SurfaceTextureDetachEnabled();
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
|
||||
{
|
||||
|
||||
if (!aTexture && !CanDetach()) {
|
||||
// We have no texture and cannot initialize detached, bail out
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
java::sdk::SurfaceTexture::New(aTexture, ReturnTo(&mSurfaceTexture))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aTexture) {
|
||||
mSurfaceTexture->DetachFromGLContext();
|
||||
}
|
||||
|
||||
mAttachedContext = aContext;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
java::sdk::Surface::New(mSurfaceTexture, ReturnTo(&mSurface))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
|
||||
mSurface.Get());
|
||||
MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AndroidSurfaceTexture::AndroidSurfaceTexture()
|
||||
: mTexture(0)
|
||||
, mSurfaceTexture()
|
||||
, mSurface()
|
||||
, mAttachedContext(nullptr)
|
||||
, mMonitor("AndroidSurfaceTexture")
|
||||
{
|
||||
}
|
||||
|
||||
AndroidSurfaceTexture::~AndroidSurfaceTexture()
|
||||
{
|
||||
if (mSurfaceTexture) {
|
||||
SetFrameAvailableCallback(nullptr);
|
||||
mSurfaceTexture = nullptr;
|
||||
}
|
||||
|
||||
if (mNativeWindow) {
|
||||
ANativeWindow_release(mNativeWindow);
|
||||
mNativeWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::UpdateTexImage()
|
||||
{
|
||||
mSurfaceTexture->UpdateTexImage();
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix) const
|
||||
{
|
||||
JNIEnv* const env = jni::GetEnvForThread();
|
||||
|
||||
auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
|
||||
mSurfaceTexture->GetTransformMatrix(jarray);
|
||||
|
||||
jfloat* array = env->GetFloatArrayElements(jarray.Get(), 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.Get(), array, 0);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
|
||||
{
|
||||
java::SurfaceTextureListener::LocalRef newListener;
|
||||
|
||||
if (aRunnable) {
|
||||
newListener = java::SurfaceTextureListener::New();
|
||||
Listener::AttachNative(newListener, MakeUnique<Listener>(aRunnable));
|
||||
}
|
||||
|
||||
if (aRunnable || mListener) {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
mSurfaceTexture->SetOnFrameAvailableListener(newListener)));
|
||||
}
|
||||
|
||||
if (mListener) {
|
||||
Listener::DisposeNative(java::SurfaceTextureListener::LocalRef(
|
||||
newListener.Env(), mListener));
|
||||
}
|
||||
|
||||
mListener = newListener;
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::SetDefaultSize(mozilla::gfx::IntSize size)
|
||||
{
|
||||
mSurfaceTexture->SetDefaultBufferSize(size.width, size.height);
|
||||
}
|
||||
|
||||
} // gl
|
||||
} // mozilla
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
Loading…
Add table
Add a link
Reference in a new issue