Backed out changeset b50714bd8d10 (bug 1322650) for failing chrome's test_video_discovery.html and mda's test_Eviction_mp4.html, both on Android. r=backout

This commit is contained in:
Sebastian Hengst 2017-05-05 18:55:11 +02:00
Родитель 087bd41f0f
Коммит 6ff84ee171
12 изменённых файлов: 305 добавлений и 439 удалений

Просмотреть файл

@ -1,20 +1,204 @@
/* -*- 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 #ifdef MOZ_WIDGET_ANDROID
#include <map>
#include <android/native_window_jni.h>
#include <android/log.h>
#include "AndroidSurfaceTexture.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; using namespace mozilla;
namespace mozilla { namespace mozilla {
namespace gl { 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 void
AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture, AndroidSurfaceTexture::UpdateTexImage()
gfx::Matrix4x4& aMatrix) {
mSurfaceTexture->UpdateTexImage();
}
void
AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix) const
{ {
JNIEnv* const env = jni::GetEnvForThread(); JNIEnv* const env = jni::GetEnvForThread();
auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16)); auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
aSurfaceTexture->GetTransformMatrix(jarray); mSurfaceTexture->GetTransformMatrix(jarray);
jfloat* array = env->GetFloatArrayElements(jarray.Get(), nullptr); jfloat* array = env->GetFloatArrayElements(jarray.Get(), nullptr);
@ -41,6 +225,36 @@ AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aS
env->ReleaseFloatArrayElements(jarray.Get(), array, 0); 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 } // gl
} // mozilla } // mozilla
#endif // MOZ_WIDGET_ANDROID #endif // MOZ_WIDGET_ANDROID

Просмотреть файл

@ -8,23 +8,100 @@
#define AndroidSurfaceTexture_h__ #define AndroidSurfaceTexture_h__
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
#include "mozilla/gfx/Matrix.h" #include <jni.h>
#include "SurfaceTexture.h" #include <android/native_window.h>
#include "nsIRunnable.h"
#include "gfxPlatform.h"
#include "GLDefs.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/Monitor.h"
typedef uint32_t AndroidSurfaceTextureHandle; #include "GeneratedJNIWrappers.h"
#include "SurfaceTexture.h"
namespace mozilla { namespace mozilla {
namespace gl { namespace gl {
class AndroidSurfaceTexture { class GLContext;
public:
static void GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
mozilla::gfx::Matrix4x4& aMatrix);
/**
* This class is a wrapper around Android's SurfaceTexture class.
* Usage is pretty much exactly like the Java class, so see
* the Android documentation for details.
*/
class AndroidSurfaceTexture {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AndroidSurfaceTexture)
public:
// The SurfaceTexture is created in an attached state. This method requires
// Android Ice Cream Sandwich.
static already_AddRefed<AndroidSurfaceTexture> Create(GLContext* aGLContext, GLuint aTexture);
// Here the SurfaceTexture will be created in a detached state. You must call
// Attach() with the GLContext you wish to composite with. It must be done
// on the thread where that GLContext is current. This method requires
// Android Jelly Bean.
static already_AddRefed<AndroidSurfaceTexture> Create();
// If we are on Jelly Bean, the SurfaceTexture can be detached and reattached
// to allow consumption from different GLContexts. It is recommended to only
// attach while you are consuming in order to allow this.
//
// Only one GLContext may be attached at any given time. If another is already
// attached, we try to wait for it to become detached.
nsresult Attach(GLContext* aContext, PRIntervalTime aTiemout = PR_INTERVAL_NO_TIMEOUT);
nsresult Detach();
// Ability to detach is based on API version (16+), and we also block PowerVR
// since it has some type of fencing problem. Bug 1100126.
bool CanDetach() const;
GLContext* AttachedContext() const { return mAttachedContext; }
ANativeWindow* NativeWindow() const {
return mNativeWindow;
}
// This attaches the updated data to the TEXTURE_EXTERNAL target
void UpdateTexImage();
void GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix) const;
void SetDefaultSize(mozilla::gfx::IntSize size);
// The callback is guaranteed to be called on the main thread even
// if the upstream callback is received on a different thread
void SetFrameAvailableCallback(nsIRunnable* aRunnable);
GLuint Texture() const { return mTexture; }
const java::sdk::Surface::Ref& JavaSurface() const { return mSurface; }
private:
class Listener;
AndroidSurfaceTexture();
~AndroidSurfaceTexture();
bool Init(GLContext* aContext, GLuint aTexture);
GLuint mTexture;
java::sdk::SurfaceTexture::GlobalRef mSurfaceTexture;
java::sdk::Surface::GlobalRef mSurface;
java::SurfaceTextureListener::GlobalRef mListener;
GLContext* mAttachedContext;
ANativeWindow* mNativeWindow;
Monitor mMonitor;
}; };
} // gl }
} // mozilla }
#endif // MOZ_WIDGET_ANDROID
#endif // AndroidSurfaceTexture_h__ #endif
#endif

Просмотреть файл

@ -473,12 +473,5 @@
android:isolatedProcess="false"> android:isolatedProcess="false">
</service> </service>
<service
android:name="org.mozilla.gecko.gfx.SurfaceAllocatorService"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false">
</service>
</application> </application>
</manifest> </manifest>

Просмотреть файл

@ -547,7 +547,6 @@ libs:: classes.dex
GECKOVIEW_AIDLS = \ GECKOVIEW_AIDLS = \
org/mozilla/gecko/IGeckoEditableChild.aidl \ org/mozilla/gecko/IGeckoEditableChild.aidl \
org/mozilla/gecko/IGeckoEditableParent.aidl \ org/mozilla/gecko/IGeckoEditableParent.aidl \
org/mozilla/gecko/gfx/ISurfaceAllocator.aidl \
org/mozilla/gecko/media/ICodec.aidl \ org/mozilla/gecko/media/ICodec.aidl \
org/mozilla/gecko/media/ICodecCallbacks.aidl \ org/mozilla/gecko/media/ICodecCallbacks.aidl \
org/mozilla/gecko/media/IMediaDrmBridge.aidl \ org/mozilla/gecko/media/IMediaDrmBridge.aidl \

Просмотреть файл

@ -379,8 +379,6 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
'gfx/FloatSize.java', 'gfx/FloatSize.java',
'gfx/FullScreenState.java', 'gfx/FullScreenState.java',
'gfx/GeckoLayerClient.java', 'gfx/GeckoLayerClient.java',
'gfx/GeckoSurface.java',
'gfx/GeckoSurfaceTexture.java',
'gfx/ImmutableViewportMetrics.java', 'gfx/ImmutableViewportMetrics.java',
'gfx/IntSize.java', 'gfx/IntSize.java',
'gfx/LayerView.java', 'gfx/LayerView.java',
@ -393,8 +391,6 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
'gfx/RectUtils.java', 'gfx/RectUtils.java',
'gfx/RenderTask.java', 'gfx/RenderTask.java',
'gfx/StackScroller.java', 'gfx/StackScroller.java',
'gfx/SurfaceAllocator.java',
'gfx/SurfaceAllocatorService.java',
'gfx/SurfaceTextureListener.java', 'gfx/SurfaceTextureListener.java',
'gfx/ViewTransform.java', 'gfx/ViewTransform.java',
'gfx/VsyncSource.java', 'gfx/VsyncSource.java',
@ -1261,7 +1257,6 @@ DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
FINAL_TARGET_PP_FILES += ['package-name.txt.in'] FINAL_TARGET_PP_FILES += ['package-name.txt.in']
gvjar.sources += ['generated/org/mozilla/gecko/' + x for x in [ gvjar.sources += ['generated/org/mozilla/gecko/' + x for x in [
'gfx/ISurfaceAllocator.java',
'IGeckoEditableChild.java', 'IGeckoEditableChild.java',
'IGeckoEditableParent.java', 'IGeckoEditableParent.java',
'media/ICodec.java', 'media/ICodec.java',

Просмотреть файл

@ -53,13 +53,6 @@
android:process=":tab" android:process=":tab"
android:isolatedProcess="false"> android:isolatedProcess="false">
</service> </service>
<service
android:name="org.mozilla.gecko.gfx.SurfaceAllocatorService"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false">
</service>
</application> </application>
</manifest> </manifest>

Просмотреть файл

@ -1,7 +0,0 @@
/* 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/. */
package org.mozilla.gecko.gfx;
parcelable GeckoSurface;

Просмотреть файл

@ -1,12 +0,0 @@
/* 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/. */
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.gfx.GeckoSurface;
interface ISurfaceAllocator {
GeckoSurface acquireSurface(in int width, in int height, in boolean singleBufferMode);
void releaseSurface(in int handle);
}

Просмотреть файл

@ -1,98 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko.gfx;
import android.graphics.SurfaceTexture;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Surface;
import android.util.Log;
import java.util.HashMap;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
public final class GeckoSurface extends Surface {
private static final String LOGTAG = "GeckoSurface";
private static HashMap<Integer, GeckoSurfaceTexture> sSurfaceTextures = new HashMap<Integer, GeckoSurfaceTexture>();
private int mHandle;
private boolean mIsSingleBuffer;
private volatile boolean mIsAvailable;
private SurfaceTexture mDummySurfaceTexture;
@WrapForJNI(exceptionMode = "nsresult")
public GeckoSurface(GeckoSurfaceTexture gst) {
super(gst);
mHandle = gst.getHandle();
mIsSingleBuffer = gst.isSingleBuffer();
mIsAvailable = true;
}
public GeckoSurface(SurfaceTexture st) {
super(st);
mDummySurfaceTexture = st;
}
public GeckoSurface() {
// A no-arg constructor exists, but is hidden in the SDK. We need to create a dummy
// SurfaceTexture here in order to create the instance. This is used to transfer the
// GeckoSurface across binder.
super(new SurfaceTexture(0));
}
@Override
public void readFromParcel(Parcel p) {
super.readFromParcel(p);
mHandle = p.readInt();
mIsSingleBuffer = p.readByte() == 1 ? true : false;
mIsAvailable = (p.readByte() == 1 ? true : false);
if (mDummySurfaceTexture != null) {
mDummySurfaceTexture.release();
mDummySurfaceTexture = null;
}
}
public static final Parcelable.Creator<GeckoSurface> CREATOR = new Parcelable.Creator<GeckoSurface>() {
public GeckoSurface createFromParcel(Parcel p) {
GeckoSurface surf = new GeckoSurface();
surf.readFromParcel(p);
return surf;
}
public GeckoSurface[] newArray(int size) {
return new GeckoSurface[size];
}
};
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(mHandle);
out.writeByte((byte) (mIsSingleBuffer ? 1 : 0));
out.writeByte((byte) (mIsAvailable ? 1 : 0));
}
@WrapForJNI
public int getHandle() {
return mHandle;
}
@WrapForJNI
public boolean getAvailable() {
return mIsAvailable;
}
@WrapForJNI
public void setAvailable(boolean available) {
mIsAvailable = available;
}
}

Просмотреть файл

@ -1,140 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko.gfx;
import android.graphics.SurfaceTexture;
import android.util.Log;
import java.util.HashMap;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
public final class GeckoSurfaceTexture extends SurfaceTexture {
private static final String LOGTAG = "GeckoSurfaceTexture";
private static volatile int sNextHandle = 1;
private static HashMap<Integer, GeckoSurfaceTexture> sSurfaceTextures = new HashMap<Integer, GeckoSurfaceTexture>();
private int mHandle;
private boolean mIsSingleBuffer;
private int mTexName;
private GeckoSurfaceTexture.Callbacks mListener;
@WrapForJNI(dispatchTo = "current")
private static native int nativeAcquireTexture();
private GeckoSurfaceTexture(int handle, int texName) {
super(texName);
mHandle = handle;
mIsSingleBuffer = false;
mTexName = texName;
}
private GeckoSurfaceTexture(int handle, int texName, boolean singleBufferMode) {
super(texName, singleBufferMode);
mHandle = handle;
mIsSingleBuffer = singleBufferMode;
mTexName = texName;
}
@WrapForJNI
public int getHandle() {
return mHandle;
}
@WrapForJNI
public int getTexName() {
return mTexName;
}
@WrapForJNI
public boolean isSingleBuffer() {
return mIsSingleBuffer;
}
@Override
@WrapForJNI
public synchronized void updateTexImage() {
super.updateTexImage();
if (mListener != null) {
mListener.onUpdateTexImage();
}
}
@Override
@WrapForJNI
public synchronized void releaseTexImage() {
if (!mIsSingleBuffer) {
return;
}
super.releaseTexImage();
if (mListener != null) {
mListener.onReleaseTexImage();
}
}
public synchronized void setListener(GeckoSurfaceTexture.Callbacks listener) {
mListener = listener;
}
@WrapForJNI
public static boolean isSingleBufferSupported() {
return Versions.feature19Plus;
}
public static GeckoSurfaceTexture acquire(boolean singleBufferMode) {
if (singleBufferMode && !isSingleBufferSupported()) {
throw new IllegalArgumentException("single buffer mode not supported on API version < 19");
}
int handle = sNextHandle++;
int texName = nativeAcquireTexture();
final GeckoSurfaceTexture gst;
if (isSingleBufferSupported()) {
gst = new GeckoSurfaceTexture(handle, texName, singleBufferMode);
} else {
gst = new GeckoSurfaceTexture(handle, texName);
}
synchronized (sSurfaceTextures) {
if (sSurfaceTextures.containsKey(handle)) {
gst.release();
throw new IllegalArgumentException("Already have a GeckoSurfaceTexture with that handle");
}
sSurfaceTextures.put(handle, gst);
}
return gst;
}
public static void dispose(int handle) {
final GeckoSurfaceTexture gst;
synchronized (sSurfaceTextures) {
gst = sSurfaceTextures.remove(handle);
}
if (gst != null) {
gst.setListener(null);
gst.release();
}
}
@WrapForJNI
public static GeckoSurfaceTexture lookup(int handle) {
synchronized (sSurfaceTextures) {
return sSurfaceTextures.get(handle);
}
}
public interface Callbacks {
void onUpdateTexImage();
void onReleaseTexImage();
}
}

Просмотреть файл

@ -1,103 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko.gfx;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.SurfaceTexture;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.Surface;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
public final class SurfaceAllocator {
private static final String LOGTAG = "SurfaceAllocator";
private static SurfaceAllocatorConnection sConnection;
private static synchronized void ensureConnection() throws Exception {
if (sConnection != null) {
return;
}
sConnection = new SurfaceAllocatorConnection();
Intent intent = new Intent();
intent.setClassName(GeckoAppShell.getApplicationContext(),
"org.mozilla.gecko.gfx.SurfaceAllocatorService");
// FIXME: may not want to auto create
if (!GeckoAppShell.getApplicationContext().bindService(intent, sConnection, Context.BIND_AUTO_CREATE)) {
throw new Exception("Failed to connect to surface allocator service!");
}
}
@WrapForJNI
public static GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) throws Exception {
ensureConnection();
try {
return sConnection.getAllocator().acquireSurface(width, height, singleBufferMode);
} catch (RemoteException e) {
throw new Exception("Failed to acquire GeckoSurface", e);
}
}
@WrapForJNI
public static void disposeSurface(GeckoSurface surface) {
try {
ensureConnection();
} catch (Exception e) {
Log.w(LOGTAG, "Failed to dispose surface, no connection");
return;
}
// Release the SurfaceTexture on the other side
try {
sConnection.getAllocator().releaseSurface(surface.getHandle());
} catch (RemoteException e) {
Log.w(LOGTAG, "Failed to release surface texture", e);
}
// And now our Surface
try {
surface.release();
} catch (Exception e) {
Log.w(LOGTAG, "Failed to release surface", e);
}
}
private static final class SurfaceAllocatorConnection implements ServiceConnection {
private ISurfaceAllocator mAllocator;
public synchronized ISurfaceAllocator getAllocator() {
while (mAllocator == null) {
try {
this.wait();
} catch(InterruptedException e) {}
}
return mAllocator;
}
@Override
public synchronized void onServiceConnected(ComponentName name, IBinder service) {
mAllocator = ISurfaceAllocator.Stub.asInterface(service);
this.notifyAll();
}
@Override
public synchronized void onServiceDisconnected(ComponentName name) {
mAllocator = null;
}
}
}

Просмотреть файл

@ -1,45 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko.gfx;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class SurfaceAllocatorService extends Service {
static private String LOGTAG = "SurfaceAllocatorService";
public int onStartCommand(final Intent intent, final int flags, final int startId) {
return Service.START_STICKY;
}
private Binder mBinder = new ISurfaceAllocator.Stub() {
public GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) {
GeckoSurfaceTexture gst = GeckoSurfaceTexture.acquire(singleBufferMode);
if (width > 0 && height > 0) {
gst.setDefaultBufferSize(width, height);
}
return new GeckoSurface(gst);
}
public void releaseSurface(int handle) {
GeckoSurfaceTexture.dispose(handle);
}
};
public IBinder onBind(final Intent intent) {
return mBinder;
}
public boolean onUnbind(Intent intent) {
return false;
}
}