new file mode 100644
--- /dev/null
+++ b/gfx/gl/AndroidNativeWindow.h
@@ -0,0 +1,52 @@
+/* -*- 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/. */
+
+#ifndef AndroidNativeWindow_h__
+#define AndroidNativeWindow_h__
+#ifdef MOZ_WIDGET_ANDROID
+
+#include <jni.h>
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+#include "GeneratedJNIWrappers.h"
+#include "SurfaceTexture.h"
+
+namespace mozilla {
+namespace gl {
+
+class AndroidNativeWindow {
+public:
+ AndroidNativeWindow(java::sdk::Surface::Param aSurface) {
+ mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
+ aSurface.Get());
+ }
+
+ AndroidNativeWindow(java::GeckoSurface::Param aSurface) {
+ auto surf = java::sdk::Surface::LocalRef(java::sdk::Surface::Ref::From(aSurface));
+ mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
+ surf.Get());
+ }
+
+ ~AndroidNativeWindow() {
+ if (mNativeWindow) {
+ ANativeWindow_release(mNativeWindow);
+ mNativeWindow = nullptr;
+ }
+ }
+
+ ANativeWindow* NativeWindow() const {
+ return mNativeWindow;
+ }
+
+private:
+ ANativeWindow* mNativeWindow;
+};
+
+} // gl
+} // mozilla
+
+#endif // MOZ_WIDGET_ANDROID
+#endif // AndroidNativeWindow_h__
--- a/gfx/gl/AndroidSurfaceTexture.cpp
+++ b/gfx/gl/AndroidSurfaceTexture.cpp
@@ -1,209 +1,25 @@
-/* -*- 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
+AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
+ gfx::Matrix4x4& aMatrix)
{
JNIEnv* const env = jni::GetEnvForThread();
auto jarray = jni::FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
- mSurfaceTexture->GetTransformMatrix(jarray);
+ aSurfaceTexture->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];
@@ -220,41 +36,11 @@ AndroidSurfaceTexture::GetTransformMatri
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
--- a/gfx/gl/AndroidSurfaceTexture.h
+++ b/gfx/gl/AndroidSurfaceTexture.h
@@ -3,105 +3,28 @@
/* 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/. */
#ifndef AndroidSurfaceTexture_h__
#define AndroidSurfaceTexture_h__
#ifdef MOZ_WIDGET_ANDROID
-#include <jni.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"
+#include "mozilla/gfx/Matrix.h"
+#include "SurfaceTexture.h"
-#include "GeneratedJNIWrappers.h"
-#include "SurfaceTexture.h"
+typedef uint64_t AndroidSurfaceTextureHandle;
namespace mozilla {
namespace gl {
-class GLContext;
-
-/**
- * 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;
+ static void GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef aSurfaceTexture,
+ mozilla::gfx::Matrix4x4& aMatrix);
- 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
-#endif
+#endif // MOZ_WIDGET_ANDROID
+#endif // AndroidSurfaceTexture_h__
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -85,16 +85,22 @@ GLScreenBuffer::CreateFactory(GLContext*
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
#if defined(XP_MACOSX)
factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
#elif defined(GL_PROVIDER_GLX)
if (sGLXLibrary.UseTextureFromPixmap())
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
#elif defined(MOZ_WIDGET_UIKIT)
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel, mFlags);
+#elif defined(MOZ_WIDGET_ANDROID)
+ if (XRE_IsParentProcess()) {
+ factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
+ } else {
+ factory = SurfaceFactory_SurfaceTexture::Create(gl, caps, ipcChannel, flags);
+ }
#else
if (gl->GetContextType() == GLContextType::EGL) {
if (XRE_IsParentProcess()) {
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
}
}
#endif
break;
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -302,17 +302,17 @@ protected:
public:
UniquePtr<SharedSurface> NewSharedSurface(const gfx::IntSize& size);
//already_AddRefed<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
already_AddRefed<layers::SharedSurfaceTextureClient> NewTexClient(const gfx::IntSize& size);
static void RecycleCallback(layers::TextureClient* tc, void* /*closure*/);
// Auto-deletes surfs of the wrong type.
- bool Recycle(layers::SharedSurfaceTextureClient* texClient);
+ virtual bool Recycle(layers::SharedSurfaceTextureClient* texClient);
};
class ScopedReadbackFB
{
GLContext* const mGL;
ScopedBindFramebuffer mAutoFB;
GLuint mTempFB;
GLuint mTempTex;
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -2,16 +2,17 @@
/* 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/. */
#include "SharedSurfaceEGL.h"
#include "GLBlitHelper.h"
#include "GLContextEGL.h"
+#include "GLContextProvider.h"
#include "GLLibraryEGL.h"
#include "GLReadTexImageHelper.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
#include "SharedSurface.h"
#include "TextureGarbageBin.h"
namespace mozilla {
namespace gl {
@@ -181,11 +182,155 @@ SurfaceFactory_EGLImage::Create(GLContex
GLLibraryEGL* egl = &sEGLLibrary;
if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
ret.reset( new ptrT(prodGL, caps, allocator, flags, context) );
}
return Move(ret);
}
+////////////////////////////////////////////////////////////////////////
+
+#ifdef MOZ_WIDGET_ANDROID
+
+/*static*/ UniquePtr<SharedSurface_SurfaceTexture>
+SharedSurface_SurfaceTexture::Create(GLContext* prodGL,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ java::GeckoSurface::Param surface)
+{
+ MOZ_ASSERT(surface);
+
+ UniquePtr<SharedSurface_SurfaceTexture> ret;
+
+ AndroidNativeWindow window(surface);
+ EGLSurface eglSurface = GLContextProviderEGL::CreateEGLSurface(window.NativeWindow());
+ if (!eglSurface) {
+ return Move(ret);
+ }
+
+ ret.reset(new SharedSurface_SurfaceTexture(prodGL, size, hasAlpha,
+ formats, surface, eglSurface));
+ return Move(ret);
+}
+
+bool
+SharedSurface_SurfaceTexture::IsAvailable()
+{
+ return true;
+}
+
+SharedSurface_SurfaceTexture::SharedSurface_SurfaceTexture(GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ const GLFormats& formats,
+ java::GeckoSurface::Param surface,
+ EGLSurface eglSurface)
+ : SharedSurface(SharedSurfaceType::AndroidSurfaceTexture,
+ AttachmentType::Screen,
+ gl,
+ size,
+ hasAlpha,
+ true)
+ , mSurface(surface)
+ , mEglSurface(eglSurface)
+{
+}
+
+SharedSurface_SurfaceTexture::~SharedSurface_SurfaceTexture()
+{
+ GLContextProviderEGL::DestroyEGLSurface(mEglSurface);
+ java::SurfaceAllocator::DisposeSurface(mSurface);
+}
+
+layers::TextureFlags
+SharedSurface_SurfaceTexture::GetTextureFlags() const
+{
+ return layers::TextureFlags::DEALLOCATE_CLIENT;
+}
+
+void
+SharedSurface_SurfaceTexture::LockProdImpl()
+{
+ if (!mSurface->GetAvailable()) {
+ return;
+ }
+
+ GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(mEglSurface);
+
+}
+
+void
+SharedSurface_SurfaceTexture::UnlockProdImpl()
+{
+ if (!mSurface->GetAvailable()) {
+ return;
+ }
+
+ mGL->SwapBuffers();
+ mSurface->SetAvailable(false);
+ GLContextEGL::Cast(mGL)->SetEGLSurfaceOverride(nullptr);
+}
+
+bool
+SharedSurface_SurfaceTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
+{
+ *out_descriptor = layers::SurfaceTextureDescriptor(mSurface->GetHandle(), mSize);
+ return true;
+}
+
+bool
+SharedSurface_SurfaceTexture::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
+{
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+/*static*/ UniquePtr<SurfaceFactory_SurfaceTexture>
+SurfaceFactory_SurfaceTexture::Create(GLContext* prodGL, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+{
+ typedef SurfaceFactory_SurfaceTexture ptrT;
+ UniquePtr<ptrT> ret;
+
+ if (SharedSurface_SurfaceTexture::IsAvailable()) {
+ ret.reset(new ptrT(prodGL, caps, allocator, flags));
+ }
+
+ return Move(ret);
+}
+
+UniquePtr<SharedSurface>
+SurfaceFactory_SurfaceTexture::CreateShared(const gfx::IntSize& size)
+{
+ bool hasAlpha = mReadCaps.alpha;
+
+ jni::Object::LocalRef surface = java::SurfaceAllocator::AcquireSurface(size.width, size.height, true);
+ if (!surface) {
+ // Try multi-buffer mode
+ surface = java::SurfaceAllocator::AcquireSurface(size.width, size.height, false);
+ if (!surface) {
+ // Give up
+ return nullptr;
+ }
+ }
+
+ return SharedSurface_SurfaceTexture::Create(mGL, mFormats, size, hasAlpha,
+ java::GeckoSurface::Ref::From(surface));
+}
+
+bool
+SurfaceFactory_SurfaceTexture::Recycle(layers::SharedSurfaceTextureClient* texClient)
+{
+ SharedSurface_SurfaceTexture* surf = static_cast<SharedSurface_SurfaceTexture*>(texClient->Surf());
+ surf->JavaSurface()->SetAvailable(true);
+
+ return SurfaceFactory::Recycle(texClient);
+}
+
+#endif // MOZ_WIDGET_ANDROID
+
} // namespace gl
} /* namespace mozilla */
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -5,16 +5,21 @@
#ifndef SHARED_SURFACE_EGL_H_
#define SHARED_SURFACE_EGL_H_
#include "mozilla/Attributes.h"
#include "mozilla/Mutex.h"
#include "SharedSurface.h"
+#ifdef MOZ_WIDGET_ANDROID
+#include "GeneratedJNIWrappers.h"
+#include "AndroidNativeWindow.h"
+#endif
+
namespace mozilla {
namespace gl {
class GLContext;
class GLLibraryEGL;
class TextureGarbageBin;
class SharedSurface_EGLImage
@@ -106,13 +111,94 @@ protected:
public:
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
bool hasAlpha = mReadCaps.alpha;
return SharedSurface_EGLImage::Create(mGL, mFormats, size, hasAlpha, mContext);
}
};
+#ifdef MOZ_WIDGET_ANDROID
+
+class SharedSurface_SurfaceTexture
+ : public SharedSurface
+{
+public:
+ static UniquePtr<SharedSurface_SurfaceTexture> Create(GLContext* prodGL,
+ const GLFormats& formats,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ java::GeckoSurface::Param surface);
+
+ static SharedSurface_SurfaceTexture* Cast(SharedSurface* surf) {
+ MOZ_ASSERT(surf->mType == SharedSurfaceType::AndroidSurfaceTexture);
+
+ return (SharedSurface_SurfaceTexture*)surf;
+ }
+
+ static bool IsAvailable();
+
+ java::GeckoSurface::Param JavaSurface() { return mSurface; }
+
+protected:
+ java::GeckoSurface::GlobalRef mSurface;
+ EGLSurface mEglSurface;
+
+ SharedSurface_SurfaceTexture(GLContext* gl,
+ const gfx::IntSize& size,
+ bool hasAlpha,
+ const GLFormats& formats,
+ java::GeckoSurface::Param surface,
+ EGLSurface eglSurface);
+
+public:
+ virtual ~SharedSurface_SurfaceTexture();
+
+ virtual layers::TextureFlags GetTextureFlags() const override;
+
+ virtual void LockProdImpl() override;
+ virtual void UnlockProdImpl() override;
+
+ virtual void ProducerAcquireImpl() override {}
+ virtual void ProducerReleaseImpl() override {}
+
+ virtual void ProducerReadAcquireImpl() override {}
+ virtual void ProducerReadReleaseImpl() override {}
+
+ // Implementation-specific functions below:
+ // Returns texture and target
+ virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
+
+ virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
+};
+
+
+
+class SurfaceFactory_SurfaceTexture
+ : public SurfaceFactory
+{
+public:
+ // Fallible:
+ static UniquePtr<SurfaceFactory_SurfaceTexture> Create(GLContext* prodGL,
+ const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags);
+
+protected:
+ SurfaceFactory_SurfaceTexture(GLContext* prodGL, const SurfaceCaps& caps,
+ const RefPtr<layers::LayersIPCChannel>& allocator,
+ const layers::TextureFlags& flags)
+ : SurfaceFactory(SharedSurfaceType::AndroidSurfaceTexture, prodGL, caps, allocator, flags)
+ { }
+
+public:
+ virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
+
+ virtual bool Recycle(layers::SharedSurfaceTextureClient* texClient) override;
+};
+
+#endif // MOZ_WIDGET_ANDROID
+
} // namespace gl
} /* namespace mozilla */
#endif /* SHARED_SURFACE_EGL_H_ */
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -72,16 +72,17 @@ enum class SharedSurfaceType : uint8_t {
Basic,
EGLImageShare,
EGLSurfaceANGLE,
DXGLInterop,
DXGLInterop2,
IOSurface,
GLXDrawable,
SharedGLTexture,
+ AndroidSurfaceTexture,
Max
};
enum class AttachmentType : uint8_t {
Screen = 0,
GLTexture,
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -19,16 +19,17 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT
gl_provider = 'GLX'
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
gl_provider = 'EGL'
if CONFIG['MOZ_GL_PROVIDER']:
gl_provider = CONFIG['MOZ_GL_PROVIDER']
EXPORTS += [
+ 'AndroidNativeWindow.h',
'AndroidSurfaceTexture.h',
'DecomposeIntoNoRepeatTriangles.h',
'EGLUtils.h',
'ForceDiscreteGPUHelperCGL.h',
'GfxTexturesReporter.h',
'GLBlitHelper.h',
'GLConsts.h',
'GLContext.h',
--- a/gfx/layers/GLImages.cpp
+++ b/gfx/layers/GLImages.cpp
@@ -93,21 +93,22 @@ GLImage::GetAsSourceSurface()
}
ScopedBindFramebuffer bind(sSnapshotContext, autoFBForTex.FB());
ReadPixelsIntoDataSurface(sSnapshotContext, source);
return source.forget();
}
#ifdef MOZ_WIDGET_ANDROID
-SurfaceTextureImage::SurfaceTextureImage(gl::AndroidSurfaceTexture* aSurfTex,
+SurfaceTextureImage::SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
const gfx::IntSize& aSize,
gl::OriginPos aOriginPos)
: GLImage(ImageFormat::SURFACE_TEXTURE),
- mSurfaceTexture(aSurfTex),
+ mHandle(aHandle),
mSize(aSize),
mOriginPos(aOriginPos)
{
+ MOZ_ASSERT(mHandle);
}
#endif
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/GLImages.h
+++ b/gfx/layers/GLImages.h
@@ -59,34 +59,34 @@ private:
gl::OriginPos mPos;
bool mOwns;
};
#ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureImage : public GLImage {
public:
- SurfaceTextureImage(gl::AndroidSurfaceTexture* aSurfTex,
+ SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
const gfx::IntSize& aSize,
gl::OriginPos aOriginPos);
gfx::IntSize GetSize() override { return mSize; }
- gl::AndroidSurfaceTexture* GetSurfaceTexture() const {
- return mSurfaceTexture;
+ AndroidSurfaceTextureHandle GetHandle() const {
+ return mHandle;
}
gl::OriginPos GetOriginPos() const {
return mOriginPos;
}
SurfaceTextureImage* AsSurfaceTextureImage() override {
return this;
}
private:
- RefPtr<gl::AndroidSurfaceTexture> mSurfaceTexture;
+ AndroidSurfaceTextureHandle mHandle;
gfx::IntSize mSize;
gl::OriginPos mOriginPos;
};
#endif // MOZ_WIDGET_ANDROID
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -127,17 +127,17 @@ ImageClient::CreateTextureClientForImage
if (aImage->GetFormat() == ImageFormat::EGLIMAGE) {
EGLImageImage* typedImage = aImage->AsEGLImageImage();
texture = EGLImageTextureData::CreateTextureClient(
typedImage, size, aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
#ifdef MOZ_WIDGET_ANDROID
} else if (aImage->GetFormat() == ImageFormat::SURFACE_TEXTURE) {
SurfaceTextureImage* typedImage = aImage->AsSurfaceTextureImage();
texture = AndroidSurfaceTextureData::CreateTextureClient(
- typedImage->GetSurfaceTexture(), size, typedImage->GetOriginPos(),
+ typedImage->GetHandle(), size, typedImage->GetOriginPos(),
aForwarder->GetTextureForwarder(), TextureFlags::DEFAULT);
#endif
} else {
MOZ_ASSERT(false, "Bad ImageFormat.");
}
} else {
RefPtr<gfx::SourceSurface> surface = aImage->GetAsSourceSurface();
MOZ_ASSERT(surface);
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -593,17 +593,17 @@ protected:
void RecycleTexture(TextureFlags aFlags);
virtual void UpdatedInternal(const nsIntRegion *Region) {}
/**
* Called when mCompositableCount becomes 0.
*/
- void NotifyNotUsed();
+ virtual void NotifyNotUsed();
// for Compositor.
void CallNotifyNotUsed();
PTextureParent* mActor;
RefPtr<TextureSourceProvider> mProvider;
RefPtr<TextureReadLock> mReadLock;
TextureFlags mFlags;
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -55,17 +55,17 @@ struct SurfaceDescriptorDXGIYCbCr {
struct SurfaceDescriptorMacIOSurface {
uint32_t surfaceId;
double scaleFactor;
bool isOpaque;
};
struct SurfaceTextureDescriptor {
- uintptr_t surfTex;
+ uint64_t handle;
IntSize size;
};
struct EGLImageDescriptor {
uintptr_t image; // `EGLImage` is a `void*`.
uintptr_t fence;
IntSize size;
bool hasAlpha;
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -74,44 +74,39 @@ EGLImageTextureData::Serialize(SurfaceDe
}
////////////////////////////////////////////////////////////////////////
// AndroidSurface
#ifdef MOZ_WIDGET_ANDROID
already_AddRefed<TextureClient>
-AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTexture* aSurfTex,
+AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTextureHandle aHandle,
gfx::IntSize aSize,
gl::OriginPos aOriginPos,
LayersIPCChannel* aAllocator,
TextureFlags aFlags)
{
- MOZ_ASSERT(XRE_IsParentProcess(),
- "Can't pass an android surfaces between processes.");
-
- if (!aSurfTex || !XRE_IsParentProcess()) {
- return nullptr;
- }
-
if (aOriginPos == gl::OriginPos::BottomLeft) {
aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
}
return TextureClient::CreateWithData(
- new AndroidSurfaceTextureData(aSurfTex, aSize),
+ new AndroidSurfaceTextureData(aHandle, aSize),
aFlags, aAllocator
);
}
-AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTexture* aSurfTex,
+AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle,
gfx::IntSize aSize)
- : mSurfTex(aSurfTex)
+ : mHandle(aHandle)
, mSize(aSize)
-{}
+{
+ MOZ_ASSERT(mHandle);
+}
AndroidSurfaceTextureData::~AndroidSurfaceTextureData()
{}
void
AndroidSurfaceTextureData::FillInfo(TextureData::Info& aInfo) const
{
aInfo.size = mSize;
@@ -120,17 +115,16 @@ AndroidSurfaceTextureData::FillInfo(Text
aInfo.hasSynchronization = false;
aInfo.supportsMoz2D = false;
aInfo.canExposeMappedData = false;
}
bool
AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
- aOutDescriptor = SurfaceTextureDescriptor((uintptr_t)mSurfTex.get(),
- mSize);
+ aOutDescriptor = SurfaceTextureDescriptor(mHandle, mSize);
return true;
}
#endif // MOZ_WIDGET_ANDROID
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/opengl/TextureClientOGL.h
+++ b/gfx/layers/opengl/TextureClientOGL.h
@@ -49,17 +49,17 @@ protected:
};
#ifdef MOZ_WIDGET_ANDROID
class AndroidSurfaceTextureData : public TextureData
{
public:
static already_AddRefed<TextureClient>
- CreateTextureClient(gl::AndroidSurfaceTexture* aSurfTex,
+ CreateTextureClient(AndroidSurfaceTextureHandle aHandle,
gfx::IntSize aSize,
gl::OriginPos aOriginPos,
LayersIPCChannel* aAllocator,
TextureFlags aFlags);
~AndroidSurfaceTextureData();
virtual void FillInfo(TextureData::Info& aInfo) const override;
@@ -70,19 +70,19 @@ public:
virtual bool Lock(OpenMode) override { return true; }
virtual void Unlock() override {}
// Our data is always owned externally.
virtual void Deallocate(LayersIPCChannel*) override {}
protected:
- AndroidSurfaceTextureData(gl::AndroidSurfaceTexture* aSurfTex, gfx::IntSize aSize);
+ AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize);
- const RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
+ const AndroidSurfaceTextureHandle mHandle;
const gfx::IntSize mSize;
};
#endif // MOZ_WIDGET_ANDROID
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -51,18 +51,23 @@ CreateTextureHostOGL(const SurfaceDescri
aBackend,
aFlags);
break;
}
#ifdef MOZ_WIDGET_ANDROID
case SurfaceDescriptor::TSurfaceTextureDescriptor: {
const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
+ java::GeckoSurfaceTexture::LocalRef surfaceTexture = java::GeckoSurfaceTexture::Lookup(desc.handle());
+ if (!surfaceTexture) {
+ return nullptr;
+ }
+
result = new SurfaceTextureHost(aFlags,
- (AndroidSurfaceTexture*)desc.surfTex(),
+ surfaceTexture,
desc.size());
break;
}
#endif
case SurfaceDescriptor::TEGLImageDescriptor: {
const EGLImageDescriptor& desc = aDesc.get_EGLImageDescriptor();
result = new EGLImageTextureHost(aFlags,
@@ -330,17 +335,17 @@ GLTextureSource::IsValid() const
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// SurfaceTextureHost
#ifdef MOZ_WIDGET_ANDROID
SurfaceTextureSource::SurfaceTextureSource(TextureSourceProvider* aProvider,
- AndroidSurfaceTexture* aSurfTex,
+ mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::SurfaceFormat aFormat,
GLenum aTarget,
GLenum aWrapMode,
gfx::IntSize aSize)
: mGL(aProvider->GetGLContext())
, mSurfTex(aSurfTex)
, mFormat(aFormat)
, mTextureTarget(aTarget)
@@ -356,22 +361,17 @@ SurfaceTextureSource::BindTexture(GLenum
MOZ_ASSERT(mSurfTex);
GLContext* gl = this->gl();
if (!gl || !gl->MakeCurrent()) {
NS_WARNING("Trying to bind a texture without a GLContext");
return;
}
gl->fActiveTexture(aTextureUnit);
-
- // SurfaceTexture spams us if there are any existing GL errors, so
- // we'll clear them here in order to avoid that.
- gl->FlushErrors();
-
- mSurfTex->UpdateTexImage();
+ gl->fBindTexture(mTextureTarget, mSurfTex->GetTexName());
ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, mTextureTarget);
}
void
SurfaceTextureSource::SetTextureSourceProvider(TextureSourceProvider* aProvider)
{
GLContext* newGL = aProvider->GetGLContext();
@@ -390,42 +390,56 @@ SurfaceTextureSource::IsValid() const
}
gfx::Matrix4x4
SurfaceTextureSource::GetTextureTransform()
{
MOZ_ASSERT(mSurfTex);
gfx::Matrix4x4 ret;
- mSurfTex->GetTransformMatrix(ret);
+
+ AndroidSurfaceTexture::GetTransformMatrix(java::sdk::SurfaceTexture::LocalRef(java::sdk::SurfaceTexture::Ref::From(mSurfTex)), ret);
return ret;
}
void
SurfaceTextureSource::DeallocateDeviceData()
{
mSurfTex = nullptr;
}
////////////////////////////////////////////////////////////////////////
SurfaceTextureHost::SurfaceTextureHost(TextureFlags aFlags,
- AndroidSurfaceTexture* aSurfTex,
+ mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::IntSize aSize)
: TextureHost(aFlags)
, mSurfTex(aSurfTex)
, mSize(aSize)
{
}
SurfaceTextureHost::~SurfaceTextureHost()
{
}
+void
+SurfaceTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
+{
+ GLContext* gl = this->gl();
+ if (!gl || !gl->MakeCurrent()) {
+ return;
+ }
+
+ // This advances the SurfaceTexture's internal buffer queue. We only want to do this
+ // once per transaction. We can then composite that texture as many times as needed.
+ mSurfTex->UpdateTexImage();
+}
+
gl::GLContext*
SurfaceTextureHost::gl() const
{
return mProvider ? mProvider->GetGLContext() : nullptr;
}
bool
SurfaceTextureHost::Lock()
@@ -433,34 +447,27 @@ SurfaceTextureHost::Lock()
MOZ_ASSERT(mSurfTex);
GLContext* gl = this->gl();
if (!gl || !gl->MakeCurrent()) {
return false;
}
if (!mTextureSource) {
gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
- GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
+ GLenum target = LOCAL_GL_TEXTURE_EXTERNAL; // This is required by SurfaceTexture
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
mTextureSource = new SurfaceTextureSource(mProvider,
mSurfTex,
format,
target,
wrapMode,
mSize);
}
- return NS_SUCCEEDED(mSurfTex->Attach(gl));
-}
-
-void
-SurfaceTextureHost::Unlock()
-{
- MOZ_ASSERT(mSurfTex);
- mSurfTex->Detach();
+ return true;
}
void
SurfaceTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
{
if (mProvider != aProvider) {
if (!aProvider || !aProvider->GetGLContext()) {
DeallocateDeviceData();
@@ -469,16 +476,28 @@ SurfaceTextureHost::SetTextureSourceProv
mProvider = aProvider;
}
if (mTextureSource) {
mTextureSource->SetTextureSourceProvider(aProvider);
}
}
+void
+SurfaceTextureHost::NotifyNotUsed()
+{
+ if (mSurfTex->GetIsSingleBuffer()) {
+ mSurfTex->ReleaseTexImage();
+ }
+
+ // We don't want to wait until it's done compositing, there are fences that protect
+ // us from problems there. Send a message to recycle this surface immediately.
+ CallNotifyNotUsed();
+}
+
gfx::SurfaceFormat
SurfaceTextureHost::GetFormat() const
{
return mTextureSource ? mTextureSource->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
}
void
SurfaceTextureHost::DeallocateDeviceData()
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -26,25 +26,26 @@
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_WARNING
#include "nsISupportsImpl.h" // for TextureImage::Release, etc
#include "nsRegionFwd.h" // for nsIntRegion
#include "OGLShaderProgram.h" // for ShaderProgramType, etc
+#ifdef MOZ_WIDGET_ANDROID
+#include "GeneratedJNIWrappers.h"
+#include "AndroidSurfaceTexture.h"
+#endif
+
namespace mozilla {
namespace gfx {
class DataSourceSurface;
} // namespace gfx
-namespace gl {
-class AndroidSurfaceTexture;
-} // namespace gl
-
namespace layers {
class Compositor;
class CompositorOGL;
class TextureImageTextureSourceOGL;
class GLTextureSource;
inline void ApplySamplingFilterToBoundTexture(gl::GLContext* aGL,
@@ -336,17 +337,17 @@ protected:
#ifdef MOZ_WIDGET_ANDROID
class SurfaceTextureSource : public TextureSource
, public TextureSourceOGL
{
public:
SurfaceTextureSource(TextureSourceProvider* aProvider,
- mozilla::gl::AndroidSurfaceTexture* aSurfTex,
+ java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::SurfaceFormat aFormat,
GLenum aTarget,
GLenum aWrapMode,
gfx::IntSize aSize);
virtual const char* Name() const override { return "SurfaceTextureSource"; }
virtual TextureSourceOGL* AsSourceOGL() override { return this; }
@@ -371,41 +372,43 @@ public:
virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
gl::GLContext* gl() const {
return mGL;
}
protected:
RefPtr<gl::GLContext> mGL;
- RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
+ mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
const gfx::SurfaceFormat mFormat;
const GLenum mTextureTarget;
const GLenum mWrapMode;
const gfx::IntSize mSize;
};
class SurfaceTextureHost : public TextureHost
{
public:
SurfaceTextureHost(TextureFlags aFlags,
- mozilla::gl::AndroidSurfaceTexture* aSurfTex,
+ mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::IntSize aSize);
virtual ~SurfaceTextureHost();
+ virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) override;
+
virtual void DeallocateDeviceData() override;
virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
virtual bool Lock() override;
- virtual void Unlock() override;
+ virtual gfx::SurfaceFormat GetFormat() const override;
- virtual gfx::SurfaceFormat GetFormat() const override;
+ virtual void NotifyNotUsed() override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
{
aTexture = mTextureSource;
return !!aTexture;
}
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
@@ -415,17 +418,17 @@ public:
gl::GLContext* gl() const;
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual const char* Name() override { return "SurfaceTextureHost"; }
protected:
- RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
+ mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
const gfx::IntSize mSize;
RefPtr<CompositorOGL> mCompositor;
RefPtr<SurfaceTextureSource> mTextureSource;
};
#endif // MOZ_WIDGET_ANDROID
////////////////////////////////////////////////////////////////////////
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -576,16 +576,17 @@ media_pkg := org/mozilla/gecko/media
@echo "Processing AIDL: $< => $@"
$(AIDL) -p$(ANDROID_SDK)/framework.aidl -I$(aidl_geckoview_src_path) -o$(aidl_target_path) $<
$(aidl_target_path)/$(media_pkg)/%.java:$(aidl_geckoview_src_path)/$(media_pkg)/%.aidl
@echo "Processing AIDL: $< => $@"
$(AIDL) -p$(ANDROID_SDK)/framework.aidl -I$(aidl_geckoview_src_path) -o$(aidl_target_path) $<
GECKOVIEW_AIDLS = \
+ org/mozilla/gecko/gfx/ISurfaceAllocator.aidl \
org/mozilla/gecko/IGeckoEditableChild.aidl \
org/mozilla/gecko/IGeckoEditableParent.aidl \
org/mozilla/gecko/media/ICodec.java \
org/mozilla/gecko/media/ICodecCallbacks.java \
org/mozilla/gecko/media/IMediaDrmBridge.java \
org/mozilla/gecko/media/IMediaDrmBridgeCallbacks.java \
org/mozilla/gecko/media/IMediaManager.java \
org/mozilla/gecko/process/IChildProcess.aidl \
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SurfaceAllocator.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SurfaceAllocator.java
@@ -36,24 +36,29 @@ public final class SurfaceAllocator {
"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(exceptionMode = "nsresult")
- public static GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) throws Exception {
- ensureConnection();
+ @WrapForJNI(exceptionMode = "ignore")
+ public static GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) {
+ try {
+ ensureConnection();
- try {
+ if (singleBufferMode && !GeckoSurfaceTexture.isSingleBufferSupported()) {
+ return null;
+ }
+
return sConnection.getAllocator().acquireSurface(width, height, singleBufferMode);
- } catch (RemoteException e) {
- throw new Exception("Failed to acquire GeckoSurface", e);
+ } catch (Exception e) {
+ Log.w(LOGTAG, "Failed to acquire GeckoSurface", e);
+ return null;
}
}
@WrapForJNI(exceptionMode = "ignore")
public static void disposeSurface(GeckoSurface surface) {
try {
ensureConnection();
} catch (Exception e) {