зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322650 - Use SurfaceTexture for WebGL on Android in E10S r=jgilbert
The main advantage here is that it works cross-process. MozReview-Commit-ID: 7YUTVB4Bydg
This commit is contained in:
Родитель
6b95623eac
Коммит
a7f7a7b630
|
@ -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__
|
|
@ -69,6 +69,9 @@ public:
|
|||
virtual bool ReleaseTexImage() override;
|
||||
|
||||
void SetEGLSurfaceOverride(EGLSurface surf);
|
||||
EGLSurface GetEGLSurfaceOverride() {
|
||||
return mSurfaceOverride;
|
||||
}
|
||||
|
||||
virtual bool MakeCurrentImpl(bool aForce) override;
|
||||
|
||||
|
|
|
@ -90,6 +90,12 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
|
|||
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()) {
|
||||
|
|
|
@ -96,6 +96,10 @@ public:
|
|||
// Unlocking is harmless if we're already unlocked.
|
||||
void UnlockProd();
|
||||
|
||||
// This surface has been moved to the front buffer and will not be locked again
|
||||
// until it is recycled. Do any finalization steps here.
|
||||
virtual void Commit(){}
|
||||
|
||||
protected:
|
||||
virtual void LockProdImpl() = 0;
|
||||
virtual void UnlockProdImpl() = 0;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
|
@ -100,12 +101,6 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage()
|
|||
mProdTex = 0;
|
||||
}
|
||||
|
||||
layers::TextureFlags
|
||||
SharedSurface_EGLImage::GetTextureFlags() const
|
||||
{
|
||||
return layers::TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_EGLImage::ProducerReleaseImpl()
|
||||
{
|
||||
|
@ -185,6 +180,136 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
|
|||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::LockProdImpl()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
|
||||
|
||||
GLContextEGL *gl = GLContextEGL::Cast(mGL);
|
||||
mOrigEglSurface = gl->GetEGLSurfaceOverride();
|
||||
gl->SetEGLSurfaceOverride(mEglSurface);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::UnlockProdImpl()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
|
||||
|
||||
GLContextEGL *gl = GLContextEGL::Cast(mGL);
|
||||
MOZ_ASSERT(gl->GetEGLSurfaceOverride() == mEglSurface);
|
||||
|
||||
gl->SetEGLSurfaceOverride(mOrigEglSurface);
|
||||
mOrigEglSurface = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::Commit()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
|
||||
|
||||
LockProdImpl();
|
||||
mGL->SwapBuffers();
|
||||
UnlockProdImpl();
|
||||
mSurface->SetAvailable(false);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_SurfaceTexture::WaitForBufferOwnership()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mSurface->GetAvailable());
|
||||
mSurface->SetAvailable(true);
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_SurfaceTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
*out_descriptor = layers::SurfaceTextureDescriptor(mSurface->GetHandle(), mSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*static*/ UniquePtr<SurfaceFactory_SurfaceTexture>
|
||||
SurfaceFactory_SurfaceTexture::Create(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::LayersIPCChannel>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
UniquePtr<SurfaceFactory_SurfaceTexture> ret(
|
||||
new SurfaceFactory_SurfaceTexture(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
|
||||
NS_WARNING("Failed to allocate SurfaceTexture!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return SharedSurface_SurfaceTexture::Create(mGL, mFormats, size, hasAlpha,
|
||||
java::GeckoSurface::Ref::From(surface));
|
||||
}
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
#include "mozilla/Mutex.h"
|
||||
#include "SharedSurface.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "AndroidNativeWindow.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
|
@ -58,7 +63,9 @@ protected:
|
|||
public:
|
||||
virtual ~SharedSurface_EGLImage();
|
||||
|
||||
virtual layers::TextureFlags GetTextureFlags() const override;
|
||||
virtual layers::TextureFlags GetTextureFlags() const override {
|
||||
return layers::TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
virtual void LockProdImpl() override {}
|
||||
virtual void UnlockProdImpl() override {}
|
||||
|
@ -110,6 +117,90 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
java::GeckoSurface::Param JavaSurface() { return mSurface; }
|
||||
|
||||
protected:
|
||||
java::GeckoSurface::GlobalRef mSurface;
|
||||
EGLSurface mEglSurface;
|
||||
EGLSurface mOrigEglSurface;
|
||||
|
||||
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 {
|
||||
return layers::TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
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 { return false; }
|
||||
|
||||
virtual void Commit() override;
|
||||
|
||||
virtual void WaitForBufferOwnership() 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;
|
||||
};
|
||||
|
||||
#endif // MOZ_WIDGET_ANDROID
|
||||
|
||||
} // namespace gl
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -77,6 +77,7 @@ enum class SharedSurfaceType : uint8_t {
|
|||
IOSurface,
|
||||
GLXDrawable,
|
||||
SharedGLTexture,
|
||||
AndroidSurfaceTexture,
|
||||
|
||||
Max
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ if CONFIG['MOZ_GL_PROVIDER']:
|
|||
gl_provider = CONFIG['MOZ_GL_PROVIDER']
|
||||
|
||||
EXPORTS += [
|
||||
'AndroidNativeWindow.h',
|
||||
'AndroidSurfaceTexture.h',
|
||||
'DecomposeIntoNoRepeatTriangles.h',
|
||||
'EGLUtils.h',
|
||||
|
|
|
@ -98,14 +98,15 @@ GLImage::GetAsSourceSurface()
|
|||
}
|
||||
|
||||
#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
|
||||
|
||||
|
|
|
@ -64,13 +64,13 @@ private:
|
|||
|
||||
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;
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
RefPtr<gl::AndroidSurfaceTexture> mSurfaceTexture;
|
||||
AndroidSurfaceTextureHandle mHandle;
|
||||
gfx::IntSize mSize;
|
||||
gl::OriginPos mOriginPos;
|
||||
};
|
||||
|
|
|
@ -461,6 +461,8 @@ CanvasClientSharedSurface::UpdateRenderer(gfx::IntSize aSize, Renderer& aRendere
|
|||
mReadbackClient = nullptr;
|
||||
}
|
||||
|
||||
surf->Commit();
|
||||
|
||||
if (asyncRenderer) {
|
||||
// If surface type is Basic, above codes will readback
|
||||
// the GLContext to mReadbackClient in order to send frame to
|
||||
|
|
|
@ -132,7 +132,7 @@ ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwar
|
|||
} 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 {
|
||||
|
|
|
@ -601,7 +601,7 @@ protected:
|
|||
/**
|
||||
* Called when mCompositableCount becomes 0.
|
||||
*/
|
||||
void NotifyNotUsed();
|
||||
virtual void NotifyNotUsed();
|
||||
|
||||
// for Compositor.
|
||||
void CallNotifyNotUsed();
|
||||
|
|
|
@ -60,7 +60,7 @@ struct SurfaceDescriptorMacIOSurface {
|
|||
};
|
||||
|
||||
struct SurfaceTextureDescriptor {
|
||||
uintptr_t surfTex;
|
||||
uint64_t handle;
|
||||
IntSize size;
|
||||
};
|
||||
|
||||
|
|
|
@ -79,34 +79,29 @@ EGLImageTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
|||
#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()
|
||||
{}
|
||||
|
@ -125,8 +120,7 @@ AndroidSurfaceTextureData::FillInfo(TextureData::Info& aInfo) const
|
|||
bool
|
||||
AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
aOutDescriptor = SurfaceTextureDescriptor((uintptr_t)mSurfTex.get(),
|
||||
mSize);
|
||||
aOutDescriptor = SurfaceTextureDescriptor(mHandle, mSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ class AndroidSurfaceTextureData : public TextureData
|
|||
{
|
||||
public:
|
||||
static already_AddRefed<TextureClient>
|
||||
CreateTextureClient(gl::AndroidSurfaceTexture* aSurfTex,
|
||||
CreateTextureClient(AndroidSurfaceTextureHandle aHandle,
|
||||
gfx::IntSize aSize,
|
||||
gl::OriginPos aOriginPos,
|
||||
LayersIPCChannel* aAllocator,
|
||||
|
@ -75,9 +75,9 @@ public:
|
|||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -56,8 +56,12 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
case SurfaceDescriptor::TSurfaceTextureDescriptor: {
|
||||
const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
|
||||
java::GeckoSurfaceTexture::LocalRef surfaceTexture = java::GeckoSurfaceTexture::Lookup(desc.handle());
|
||||
|
||||
MOZ_RELEASE_ASSERT(surfaceTexture);
|
||||
|
||||
result = new SurfaceTextureHost(aFlags,
|
||||
(AndroidSurfaceTexture*)desc.surfTex(),
|
||||
surfaceTexture,
|
||||
desc.size());
|
||||
break;
|
||||
}
|
||||
|
@ -335,7 +339,7 @@ GLTextureSource::IsValid() const
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
||||
SurfaceTextureSource::SurfaceTextureSource(TextureSourceProvider* aProvider,
|
||||
AndroidSurfaceTexture* aSurfTex,
|
||||
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget,
|
||||
GLenum aWrapMode,
|
||||
|
@ -361,12 +365,7 @@ SurfaceTextureSource::BindTexture(GLenum aTextureUnit,
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -395,7 +394,9 @@ SurfaceTextureSource::GetTextureTransform()
|
|||
MOZ_ASSERT(mSurfTex);
|
||||
|
||||
gfx::Matrix4x4 ret;
|
||||
mSurfTex->GetTransformMatrix(ret);
|
||||
|
||||
const auto& surf = java::sdk::SurfaceTexture::LocalRef(java::sdk::SurfaceTexture::Ref::From(mSurfTex));
|
||||
AndroidSurfaceTexture::GetTransformMatrix(surf, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -409,7 +410,7 @@ SurfaceTextureSource::DeallocateDeviceData()
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SurfaceTextureHost::SurfaceTextureHost(TextureFlags aFlags,
|
||||
AndroidSurfaceTexture* aSurfTex,
|
||||
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::IntSize aSize)
|
||||
: TextureHost(aFlags)
|
||||
, mSurfTex(aSurfTex)
|
||||
|
@ -421,6 +422,19 @@ 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
|
||||
{
|
||||
|
@ -438,7 +452,7 @@ SurfaceTextureHost::Lock()
|
|||
|
||||
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,
|
||||
|
@ -448,14 +462,7 @@ SurfaceTextureHost::Lock()
|
|||
mSize);
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(mSurfTex->Attach(gl));
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceTextureHost::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mSurfTex);
|
||||
mSurfTex->Detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -474,6 +481,16 @@ SurfaceTextureHost::SetTextureSourceProvider(TextureSourceProvider* aProvider)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceTextureHost::NotifyNotUsed()
|
||||
{
|
||||
if (mSurfTex->IsSingleBuffer()) {
|
||||
mSurfTex->ReleaseTexImage();
|
||||
}
|
||||
|
||||
TextureHost::NotifyNotUsed();
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
SurfaceTextureHost::GetFormat() const
|
||||
{
|
||||
|
|
|
@ -31,15 +31,16 @@
|
|||
#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;
|
||||
|
@ -341,7 +342,7 @@ class SurfaceTextureSource : public TextureSource
|
|||
{
|
||||
public:
|
||||
SurfaceTextureSource(TextureSourceProvider* aProvider,
|
||||
mozilla::gl::AndroidSurfaceTexture* aSurfTex,
|
||||
java::GeckoSurfaceTexture::Ref& aSurfTex,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
GLenum aTarget,
|
||||
GLenum aWrapMode,
|
||||
|
@ -376,7 +377,7 @@ public:
|
|||
|
||||
protected:
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
RefPtr<gl::AndroidSurfaceTexture> mSurfTex;
|
||||
mozilla::java::GeckoSurfaceTexture::GlobalRef mSurfTex;
|
||||
const gfx::SurfaceFormat mFormat;
|
||||
const GLenum mTextureTarget;
|
||||
const GLenum mWrapMode;
|
||||
|
@ -387,21 +388,23 @@ 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 void NotifyNotUsed() override;
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
|
||||
{
|
||||
aTexture = mTextureSource;
|
||||
|
@ -420,7 +423,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -42,13 +42,18 @@ public final class SurfaceAllocator {
|
|||
}
|
||||
|
||||
@WrapForJNI
|
||||
public static GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) throws Exception {
|
||||
ensureConnection();
|
||||
|
||||
public static GeckoSurface acquireSurface(int width, int height, boolean singleBufferMode) {
|
||||
try {
|
||||
ensureConnection();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче