mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1144906 - Fast WebGL on E10S. - r=mattwoodrow,nical
This commit is contained in:
parent
4a89e36100
commit
b0077b976e
@ -21,6 +21,7 @@
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "../layers/ipc/ShadowLayers.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
@ -39,40 +40,36 @@ GLScreenBuffer::Create(GLContext* gl,
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
UniquePtr<SurfaceFactory> factory;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
/* On B2G, we want a Gralloc factory, and we want one right at the start */
|
||||
layers::ISurfaceAllocator* allocator = caps.surfaceAllocator;
|
||||
if (!factory &&
|
||||
allocator &&
|
||||
XRE_GetProcessType() != GeckoProcessType_Default)
|
||||
{
|
||||
layers::TextureFlags flags = layers::TextureFlags::DEALLOCATE_CLIENT |
|
||||
layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
if (!caps.premultAlpha) {
|
||||
flags |= layers::TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
if (!caps.premultAlpha) {
|
||||
flags |= layers::TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps, flags,
|
||||
allocator);
|
||||
}
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
/* On OSX, we want an IOSurface factory, and we want one right at the start */
|
||||
if (!factory) {
|
||||
factory = SurfaceFactory_IOSurface::Create(gl, caps);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!factory) {
|
||||
factory = MakeUnique<SurfaceFactory_Basic>(gl, caps);
|
||||
}
|
||||
UniquePtr<SurfaceFactory> factory = MakeUnique<SurfaceFactory_Basic>(gl, caps, flags);
|
||||
|
||||
ret.reset( new GLScreenBuffer(gl, caps, Move(factory)) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
GLScreenBuffer::GLScreenBuffer(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
UniquePtr<SurfaceFactory> factory)
|
||||
: mGL(gl)
|
||||
, mCaps(caps)
|
||||
, mFactory(Move(factory))
|
||||
, mNeedsBlit(true)
|
||||
, mUserReadBufferMode(LOCAL_GL_BACK)
|
||||
, mUserDrawFB(0)
|
||||
, mUserReadFB(0)
|
||||
, mInternalDrawFB(0)
|
||||
, mInternalReadFB(0)
|
||||
#ifdef DEBUG
|
||||
, mInInternalMode_DrawFB(true)
|
||||
, mInInternalMode_ReadFB(true)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
GLScreenBuffer::~GLScreenBuffer()
|
||||
{
|
||||
mDraw = nullptr;
|
||||
@ -465,7 +462,7 @@ GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size)
|
||||
bool
|
||||
GLScreenBuffer::Swap(const gfx::IntSize& size)
|
||||
{
|
||||
RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
|
||||
RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
|
||||
if (!newBack)
|
||||
return false;
|
||||
|
||||
@ -522,7 +519,7 @@ GLScreenBuffer::PublishFrame(const gfx::IntSize& size)
|
||||
bool
|
||||
GLScreenBuffer::Resize(const gfx::IntSize& size)
|
||||
{
|
||||
RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
|
||||
RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
|
||||
if (!newBack)
|
||||
return false;
|
||||
|
||||
|
@ -24,6 +24,10 @@
|
||||
#include "SurfaceTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class SharedSurfaceTextureClient;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
|
||||
class GLContext;
|
||||
@ -136,8 +140,8 @@ public:
|
||||
protected:
|
||||
UniquePtr<SurfaceFactory> mFactory;
|
||||
|
||||
RefPtr<ShSurfHandle> mBack;
|
||||
RefPtr<ShSurfHandle> mFront;
|
||||
RefPtr<layers::SharedSurfaceTextureClient> mBack;
|
||||
RefPtr<layers::SharedSurfaceTextureClient> mFront;
|
||||
|
||||
UniquePtr<DrawBuffer> mDraw;
|
||||
UniquePtr<ReadBuffer> mRead;
|
||||
@ -159,21 +163,7 @@ protected:
|
||||
|
||||
GLScreenBuffer(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
UniquePtr<SurfaceFactory> factory)
|
||||
: mGL(gl)
|
||||
, mCaps(caps)
|
||||
, mFactory(Move(factory))
|
||||
, mNeedsBlit(true)
|
||||
, mUserReadBufferMode(LOCAL_GL_BACK)
|
||||
, mUserDrawFB(0)
|
||||
, mUserReadFB(0)
|
||||
, mInternalDrawFB(0)
|
||||
, mInternalReadFB(0)
|
||||
#ifdef DEBUG
|
||||
, mInInternalMode_DrawFB(true)
|
||||
, mInInternalMode_ReadFB(true)
|
||||
#endif
|
||||
{}
|
||||
UniquePtr<SurfaceFactory> factory);
|
||||
|
||||
public:
|
||||
virtual ~GLScreenBuffer();
|
||||
@ -182,7 +172,7 @@ public:
|
||||
return mFactory.get();
|
||||
}
|
||||
|
||||
ShSurfHandle* Front() const {
|
||||
const RefPtr<layers::SharedSurfaceTextureClient>& Front() const {
|
||||
return mFront;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
@ -32,12 +34,9 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest,
|
||||
dest->mAttachType == AttachmentType::Screen)
|
||||
{
|
||||
// Here, we actually need to blit through a temp surface, so let's make one.
|
||||
UniquePtr<SharedSurface_GLTexture> tempSurf;
|
||||
tempSurf = SharedSurface_GLTexture::Create(gl,
|
||||
gl,
|
||||
factory->mFormats,
|
||||
src->mSize,
|
||||
factory->mCaps.alpha);
|
||||
UniquePtr<SharedSurface_Basic> tempSurf;
|
||||
tempSurf = SharedSurface_Basic::Create(gl, factory->mFormats, src->mSize,
|
||||
factory->mCaps.alpha);
|
||||
|
||||
ProdCopy(src, tempSurf.get(), factory);
|
||||
ProdCopy(tempSurf.get(), dest, factory);
|
||||
@ -203,20 +202,21 @@ SharedSurface::SharedSurface(SharedSurfaceType type,
|
||||
AttachmentType attachType,
|
||||
GLContext* gl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha)
|
||||
bool hasAlpha,
|
||||
bool canRecycle)
|
||||
: mType(type)
|
||||
, mAttachType(attachType)
|
||||
, mGL(gl)
|
||||
, mSize(size)
|
||||
, mHasAlpha(hasAlpha)
|
||||
, mCanRecycle(canRecycle)
|
||||
, mIsLocked(false)
|
||||
, mIsProducerAcquired(false)
|
||||
, mIsConsumerAcquired(false)
|
||||
#ifdef DEBUG
|
||||
, mOwningThread(NS_GetCurrentThread())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
void
|
||||
SharedSurface::LockProd()
|
||||
@ -262,8 +262,6 @@ SharedSurface::PollSync_ContentThread()
|
||||
return PollSync_ContentThread_Impl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceFactory
|
||||
|
||||
@ -301,12 +299,15 @@ ChooseBufferBits(const SurfaceCaps& caps,
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceFactory::SurfaceFactory(GLContext* gl,
|
||||
SharedSurfaceType type,
|
||||
const SurfaceCaps& caps)
|
||||
: mGL(gl)
|
||||
SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
: mType(type)
|
||||
, mGL(gl)
|
||||
, mCaps(caps)
|
||||
, mType(type)
|
||||
, mAllocator(allocator)
|
||||
, mFlags(flags)
|
||||
, mFormats(gl->ChooseGLFormats(caps))
|
||||
{
|
||||
ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps);
|
||||
@ -314,51 +315,67 @@ SurfaceFactory::SurfaceFactory(GLContext* gl,
|
||||
|
||||
SurfaceFactory::~SurfaceFactory()
|
||||
{
|
||||
while (!mScraps.Empty()) {
|
||||
mScraps.Pop();
|
||||
while (!mRecyclePool.empty()) {
|
||||
RefPtr<layers::SharedSurfaceTextureClient> cur = mRecyclePool.front();
|
||||
mRecyclePool.pop();
|
||||
|
||||
cur->StopRecycling();
|
||||
}
|
||||
}
|
||||
|
||||
UniquePtr<SharedSurface>
|
||||
SurfaceFactory::NewSharedSurface(const gfx::IntSize& size)
|
||||
TemporaryRef<layers::SharedSurfaceTextureClient>
|
||||
SurfaceFactory::NewTexClient(const gfx::IntSize& size)
|
||||
{
|
||||
// Attempt to reuse an old surface.
|
||||
while (!mScraps.Empty()) {
|
||||
UniquePtr<SharedSurface> cur = mScraps.Pop();
|
||||
while (!mRecyclePool.empty()) {
|
||||
RefPtr<layers::SharedSurfaceTextureClient> cur = mRecyclePool.front();
|
||||
mRecyclePool.pop();
|
||||
|
||||
if (cur->mSize == size)
|
||||
return Move(cur);
|
||||
if (cur->Surf()->mSize == size) {
|
||||
return cur.forget();
|
||||
}
|
||||
|
||||
// Let `cur` be destroyed as it falls out of scope, if it wasn't
|
||||
// moved.
|
||||
// Let it die.
|
||||
cur->StopRecycling();
|
||||
}
|
||||
|
||||
return CreateShared(size);
|
||||
}
|
||||
|
||||
TemporaryRef<ShSurfHandle>
|
||||
SurfaceFactory::NewShSurfHandle(const gfx::IntSize& size)
|
||||
{
|
||||
auto surf = NewSharedSurface(size);
|
||||
UniquePtr<SharedSurface> surf = Move(CreateShared(size));
|
||||
if (!surf)
|
||||
return nullptr;
|
||||
|
||||
// Before next use, wait until SharedSurface's buffer
|
||||
// is no longer being used.
|
||||
surf->WaitForBufferOwnership();
|
||||
|
||||
return new ShSurfHandle(this, Move(surf));
|
||||
RefPtr<layers::SharedSurfaceTextureClient> ret;
|
||||
ret = new layers::SharedSurfaceTextureClient(mAllocator, mFlags, Move(surf), this);
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
// Auto-deletes surfs of the wrong type.
|
||||
void
|
||||
SurfaceFactory::Recycle(UniquePtr<SharedSurface> surf)
|
||||
/*static*/ void
|
||||
SurfaceFactory::RecycleCallback(layers::TextureClient* tc, void* /*closure*/)
|
||||
{
|
||||
MOZ_ASSERT(surf);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (surf->mType == mType) {
|
||||
mScraps.Push(Move(surf));
|
||||
layers::SharedSurfaceTextureClient* sstc = (layers::SharedSurfaceTextureClient*)tc;
|
||||
|
||||
if (sstc->mSurf->mCanRecycle && sstc->mFactory) {
|
||||
if (sstc->mFactory->Recycle(sstc))
|
||||
return;
|
||||
}
|
||||
|
||||
// Did not recover the tex client. End the (re)cycle!
|
||||
sstc->StopRecycling();
|
||||
}
|
||||
|
||||
bool
|
||||
SurfaceFactory::Recycle(layers::SharedSurfaceTextureClient* texClient)
|
||||
{
|
||||
MOZ_ASSERT(texClient);
|
||||
MOZ_ASSERT(texClient->mFactory == this);
|
||||
|
||||
if (mRecyclePool.size() >= 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<layers::SharedSurfaceTextureClient> texClientRef = texClient;
|
||||
mRecyclePool.push(texClientRef);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -34,6 +34,15 @@ namespace mozilla {
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
class ISurfaceAllocator;
|
||||
class SharedSurfaceTextureClient;
|
||||
enum class TextureFlags : uint32_t;
|
||||
class SurfaceDescriptor;
|
||||
class TextureClient;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
|
||||
class GLContext;
|
||||
@ -51,6 +60,7 @@ public:
|
||||
GLContext* const mGL;
|
||||
const gfx::IntSize mSize;
|
||||
const bool mHasAlpha;
|
||||
const bool mCanRecycle;
|
||||
protected:
|
||||
bool mIsLocked;
|
||||
bool mIsProducerAcquired;
|
||||
@ -61,7 +71,8 @@ protected:
|
||||
AttachmentType attachType,
|
||||
GLContext* gl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha);
|
||||
bool hasAlpha,
|
||||
bool canRecycle);
|
||||
|
||||
public:
|
||||
virtual ~SharedSurface() {
|
||||
@ -173,37 +184,8 @@ public:
|
||||
virtual bool NeedsIndirectReads() const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class UniquePtrQueue
|
||||
{
|
||||
std::queue<T*> mQueue;
|
||||
|
||||
public:
|
||||
~UniquePtrQueue() {
|
||||
MOZ_ASSERT(Empty());
|
||||
}
|
||||
|
||||
bool Empty() const {
|
||||
return mQueue.empty();
|
||||
}
|
||||
|
||||
void Push(UniquePtr<T> up) {
|
||||
T* p = up.release();
|
||||
mQueue.push(p);
|
||||
}
|
||||
|
||||
UniquePtr<T> Pop() {
|
||||
UniquePtr<T> ret;
|
||||
|
||||
if (!mQueue.empty()) {
|
||||
ret.reset(mQueue.front());
|
||||
mQueue.pop();
|
||||
}
|
||||
|
||||
return Move(ret);
|
||||
}
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) = 0;
|
||||
};
|
||||
|
||||
class SurfaceFactory : public SupportsWeakPtr<SurfaceFactory>
|
||||
@ -213,18 +195,20 @@ public:
|
||||
// with SupportsWeakPtr. (bug 1049278)
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory)
|
||||
|
||||
const SharedSurfaceType mType;
|
||||
GLContext* const mGL;
|
||||
const SurfaceCaps mCaps;
|
||||
const SharedSurfaceType mType;
|
||||
const RefPtr<layers::ISurfaceAllocator> mAllocator;
|
||||
const layers::TextureFlags mFlags;
|
||||
const GLFormats mFormats;
|
||||
|
||||
protected:
|
||||
SurfaceCaps mDrawCaps;
|
||||
SurfaceCaps mReadCaps;
|
||||
std::queue<RefPtr<layers::SharedSurfaceTextureClient>> mRecyclePool;
|
||||
|
||||
SurfaceFactory(GLContext* gl,
|
||||
SharedSurfaceType type,
|
||||
const SurfaceCaps& caps);
|
||||
SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
public:
|
||||
virtual ~SurfaceFactory();
|
||||
@ -240,44 +224,15 @@ public:
|
||||
protected:
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) = 0;
|
||||
|
||||
UniquePtrQueue<SharedSurface> mScraps;
|
||||
|
||||
public:
|
||||
UniquePtr<SharedSurface> NewSharedSurface(const gfx::IntSize& size);
|
||||
TemporaryRef<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
|
||||
//TemporaryRef<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
|
||||
TemporaryRef<layers::SharedSurfaceTextureClient> NewTexClient(const gfx::IntSize& size);
|
||||
|
||||
static void RecycleCallback(layers::TextureClient* tc, void* /*closure*/);
|
||||
|
||||
// Auto-deletes surfs of the wrong type.
|
||||
void Recycle(UniquePtr<SharedSurface> surf);
|
||||
};
|
||||
|
||||
class ShSurfHandle : public RefCounted<ShSurfHandle>
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(ShSurfHandle)
|
||||
|
||||
private:
|
||||
const WeakPtr<SurfaceFactory> mFactory;
|
||||
UniquePtr<SharedSurface> mSurf;
|
||||
|
||||
public:
|
||||
ShSurfHandle(SurfaceFactory* factory, UniquePtr<SharedSurface> surf)
|
||||
: mFactory(factory)
|
||||
, mSurf(Move(surf))
|
||||
{
|
||||
MOZ_ASSERT(mFactory);
|
||||
MOZ_ASSERT(mSurf);
|
||||
}
|
||||
|
||||
~ShSurfHandle() {
|
||||
if (mFactory) {
|
||||
mFactory->Recycle(Move(mSurf));
|
||||
}
|
||||
}
|
||||
|
||||
SharedSurface* Surf() const {
|
||||
MOZ_ASSERT(mSurf.get());
|
||||
return mSurf.get();
|
||||
}
|
||||
bool Recycle(layers::SharedSurfaceTextureClient* texClient);
|
||||
};
|
||||
|
||||
class ScopedReadbackFB
|
||||
|
@ -4,11 +4,12 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SharedSurfaceANGLE.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
@ -105,7 +106,8 @@ SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl,
|
||||
AttachmentType::Screen,
|
||||
gl,
|
||||
size,
|
||||
hasAlpha)
|
||||
hasAlpha,
|
||||
true)
|
||||
, mEGL(egl)
|
||||
, mContext(context)
|
||||
, mPBuffer(pbuffer)
|
||||
@ -253,6 +255,16 @@ SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl()
|
||||
return PollSync();
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_ANGLEShareHandle::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
|
||||
: gfx::SurfaceFormat::B8G8R8X8;
|
||||
*out_descriptor = layers::SurfaceDescriptorD3D10((WindowsHandle)mShareHandle, format,
|
||||
mSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Factory
|
||||
|
||||
@ -388,8 +400,9 @@ ChooseConfig(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps)
|
||||
}
|
||||
|
||||
/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
|
||||
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
|
||||
const SurfaceCaps& caps)
|
||||
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
GLLibraryEGL* egl = &sEGLLibrary;
|
||||
if (!egl)
|
||||
@ -401,7 +414,7 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
|
||||
|
||||
bool success;
|
||||
typedef SurfaceFactory_ANGLEShareHandle ptrT;
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, egl, caps, &success) );
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, &success) );
|
||||
|
||||
if (!success)
|
||||
return nullptr;
|
||||
@ -410,10 +423,12 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
|
||||
}
|
||||
|
||||
SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
|
||||
GLLibraryEGL* egl,
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags,
|
||||
GLLibraryEGL* egl,
|
||||
bool* const out_success)
|
||||
: SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
|
||||
: SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags)
|
||||
, mProdGL(gl)
|
||||
, mEGL(egl)
|
||||
{
|
||||
|
@ -38,7 +38,9 @@ protected:
|
||||
GLLibraryEGL* const mEGL;
|
||||
const EGLContext mContext;
|
||||
const EGLSurface mPBuffer;
|
||||
public:
|
||||
const HANDLE mShareHandle;
|
||||
protected:
|
||||
RefPtr<IDXGIKeyedMutex> mKeyedMutex;
|
||||
RefPtr<IDXGIKeyedMutex> mConsumerKeyedMutex;
|
||||
RefPtr<ID3D11Texture2D> mConsumerTexture;
|
||||
@ -75,14 +77,11 @@ public:
|
||||
virtual bool WaitSync_ContentThread_Impl() override;
|
||||
virtual bool PollSync_ContentThread_Impl() override;
|
||||
|
||||
// Implementation-specific functions below:
|
||||
HANDLE GetShareHandle() {
|
||||
return mShareHandle;
|
||||
}
|
||||
|
||||
const RefPtr<ID3D11Texture2D>& GetConsumerTexture() const {
|
||||
return mConsumerTexture;
|
||||
}
|
||||
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
|
||||
};
|
||||
|
||||
|
||||
@ -98,12 +97,14 @@ protected:
|
||||
|
||||
public:
|
||||
static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
|
||||
const SurfaceCaps& caps);
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
protected:
|
||||
SurfaceFactory_ANGLEShareHandle(GLContext* gl,
|
||||
GLLibraryEGL* egl,
|
||||
const SurfaceCaps& caps,
|
||||
SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags, GLLibraryEGL* egl,
|
||||
bool* const out_success);
|
||||
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLLibraryEGL.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "TextureGarbageBin.h"
|
||||
@ -72,7 +73,8 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
|
||||
AttachmentType::GLTexture,
|
||||
gl,
|
||||
size,
|
||||
hasAlpha)
|
||||
hasAlpha,
|
||||
false) // Can't recycle, as mSync changes never update TextureHost.
|
||||
, mMutex("SharedSurface_EGLImage mutex")
|
||||
, mEGL(egl)
|
||||
, mFormats(formats)
|
||||
@ -215,10 +217,20 @@ SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_te
|
||||
*out_target = LOCAL_GL_TEXTURE_EXTERNAL;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_EGLImage::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
*out_descriptor = layers::EGLImageDescriptor((uintptr_t)mImage, (uintptr_t)mSync,
|
||||
mSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*static*/ UniquePtr<SurfaceFactory_EGLImage>
|
||||
SurfaceFactory_EGLImage::Create(GLContext* prodGL,
|
||||
const SurfaceCaps& caps)
|
||||
SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
|
||||
|
||||
@ -227,7 +239,7 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL,
|
||||
|
||||
GLLibraryEGL* egl = &sEGLLibrary;
|
||||
if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
|
||||
ret.reset( new ptrT(prodGL, context, caps) );
|
||||
ret.reset( new ptrT(prodGL, caps, allocator, flags, context) );
|
||||
}
|
||||
|
||||
return Move(ret);
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
// Implementation-specific functions below:
|
||||
// Returns texture and target
|
||||
void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target);
|
||||
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
|
||||
};
|
||||
|
||||
|
||||
@ -87,17 +89,20 @@ class SurfaceFactory_EGLImage
|
||||
public:
|
||||
// Fallible:
|
||||
static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
|
||||
const SurfaceCaps& caps);
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
protected:
|
||||
const EGLContext mContext;
|
||||
|
||||
SurfaceFactory_EGLImage(GLContext* prodGL,
|
||||
EGLContext context,
|
||||
const SurfaceCaps& caps)
|
||||
: SurfaceFactory(prodGL, SharedSurfaceType::EGLImageShare, caps)
|
||||
SurfaceFactory_EGLImage(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags,
|
||||
EGLContext context)
|
||||
: SurfaceFactory(SharedSurfaceType::EGLImageShare, prodGL, caps, allocator, flags)
|
||||
, mContext(context)
|
||||
{}
|
||||
{ }
|
||||
|
||||
public:
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
|
||||
|
@ -39,40 +39,37 @@ SharedSurface_Basic::Create(GLContext* gl,
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
SurfaceFormat format = SurfaceFormat::B8G8R8X8;
|
||||
switch (formats.color_texInternalFormat) {
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_RGB8:
|
||||
if (formats.color_texType == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
|
||||
format = SurfaceFormat::R5G6B5;
|
||||
else
|
||||
format = SurfaceFormat::B8G8R8X8;
|
||||
break;
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_RGBA8:
|
||||
case LOCAL_GL_BGRA:
|
||||
case LOCAL_GL_BGRA8_EXT:
|
||||
format = SurfaceFormat::B8G8R8A8;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unhandled Tex format.");
|
||||
}
|
||||
bool ownsTex = true;
|
||||
ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, tex, ownsTex) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, format, tex) );
|
||||
|
||||
/*static*/ UniquePtr<SharedSurface_Basic>
|
||||
SharedSurface_Basic::Wrap(GLContext* gl,
|
||||
const IntSize& size,
|
||||
bool hasAlpha,
|
||||
GLuint tex)
|
||||
{
|
||||
bool ownsTex = false;
|
||||
UniquePtr<SharedSurface_Basic> ret( new SharedSurface_Basic(gl, size, hasAlpha, tex,
|
||||
ownsTex) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
|
||||
const IntSize& size,
|
||||
bool hasAlpha,
|
||||
SurfaceFormat format,
|
||||
GLuint tex)
|
||||
GLuint tex,
|
||||
bool ownsTex)
|
||||
: SharedSurface(SharedSurfaceType::Basic,
|
||||
AttachmentType::GLTexture,
|
||||
gl,
|
||||
size,
|
||||
hasAlpha)
|
||||
hasAlpha,
|
||||
true)
|
||||
, mTex(tex)
|
||||
, mOwnsTex(ownsTex)
|
||||
, mFB(0)
|
||||
{
|
||||
mGL->MakeCurrent();
|
||||
@ -97,150 +94,16 @@ SharedSurface_Basic::~SharedSurface_Basic()
|
||||
if (mFB)
|
||||
mGL->fDeleteFramebuffers(1, &mFB);
|
||||
|
||||
mGL->fDeleteTextures(1, &mTex);
|
||||
if (mOwnsTex)
|
||||
mGL->fDeleteTextures(1, &mTex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SharedSurface_GLTexture
|
||||
|
||||
/*static*/ UniquePtr<SharedSurface_GLTexture>
|
||||
SharedSurface_GLTexture::Create(GLContext* prodGL,
|
||||
GLContext* consGL,
|
||||
const GLFormats& formats,
|
||||
const IntSize& size,
|
||||
bool hasAlpha,
|
||||
GLuint texture)
|
||||
{
|
||||
MOZ_ASSERT(prodGL);
|
||||
MOZ_ASSERT(!consGL || prodGL->SharesWith(consGL));
|
||||
|
||||
prodGL->MakeCurrent();
|
||||
|
||||
GLuint tex = texture;
|
||||
|
||||
bool ownsTex = false;
|
||||
|
||||
UniquePtr<SharedSurface_GLTexture> ret;
|
||||
|
||||
if (!tex) {
|
||||
GLContext::LocalErrorScope localError(*prodGL);
|
||||
|
||||
tex = CreateTextureForOffscreen(prodGL, formats, size);
|
||||
|
||||
GLenum err = localError.GetError();
|
||||
MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
|
||||
if (err) {
|
||||
prodGL->fDeleteTextures(1, &tex);
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
ownsTex = true;
|
||||
}
|
||||
|
||||
ret.reset( new SharedSurface_GLTexture(prodGL, consGL, size,
|
||||
hasAlpha, tex, ownsTex) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
SharedSurface_GLTexture::~SharedSurface_GLTexture()
|
||||
{
|
||||
if (!mGL->MakeCurrent())
|
||||
return;
|
||||
|
||||
if (mOwnsTex) {
|
||||
mGL->fDeleteTextures(1, &mTex);
|
||||
}
|
||||
|
||||
if (mSync) {
|
||||
mGL->fDeleteSync(mSync);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_GLTexture::Fence()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mGL->MakeCurrent();
|
||||
|
||||
if (mConsGL && mGL->IsExtensionSupported(GLContext::ARB_sync)) {
|
||||
if (mSync) {
|
||||
mGL->fDeleteSync(mSync);
|
||||
mSync = 0;
|
||||
}
|
||||
|
||||
mSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
if (mSync) {
|
||||
mGL->fFlush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(!mSync);
|
||||
|
||||
mGL->fFinish();
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_GLTexture::WaitSync()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mSync) {
|
||||
// We either used glFinish, or we passed this fence already.
|
||||
// (PollSync/WaitSync returned true previously)
|
||||
return true;
|
||||
}
|
||||
|
||||
mConsGL->MakeCurrent();
|
||||
MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
|
||||
|
||||
mConsGL->fWaitSync(mSync,
|
||||
0,
|
||||
LOCAL_GL_TIMEOUT_IGNORED);
|
||||
mConsGL->fDeleteSync(mSync);
|
||||
mSync = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_GLTexture::PollSync()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mSync) {
|
||||
// We either used glFinish, or we passed this fence already.
|
||||
// (PollSync/WaitSync returned true previously)
|
||||
return true;
|
||||
}
|
||||
|
||||
mConsGL->MakeCurrent();
|
||||
MOZ_ASSERT(mConsGL->IsExtensionSupported(GLContext::ARB_sync));
|
||||
|
||||
GLint status = 0;
|
||||
mConsGL->fGetSynciv(mSync,
|
||||
LOCAL_GL_SYNC_STATUS,
|
||||
1,
|
||||
nullptr,
|
||||
&status);
|
||||
if (status != LOCAL_GL_SIGNALED)
|
||||
return false;
|
||||
|
||||
mConsGL->fDeleteSync(mSync);
|
||||
mSync = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GLuint
|
||||
SharedSurface_GLTexture::ConsTexture(GLContext* consGL)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_ASSERT(consGL);
|
||||
MOZ_ASSERT(mGL->SharesWith(consGL));
|
||||
MOZ_ASSERT_IF(mConsGL, consGL == mConsGL);
|
||||
|
||||
mConsGL = consGL;
|
||||
|
||||
return mTex;
|
||||
}
|
||||
SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
|
||||
const layers::TextureFlags& flags)
|
||||
: SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
|
||||
{ }
|
||||
|
||||
} /* namespace gfx */
|
||||
} /* namespace mozilla */
|
||||
|
@ -38,6 +38,11 @@ public:
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha);
|
||||
|
||||
static UniquePtr<SharedSurface_Basic> Wrap(GLContext* gl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
GLuint tex);
|
||||
|
||||
static SharedSurface_Basic* Cast(SharedSurface* surf) {
|
||||
MOZ_ASSERT(surf->mType == SharedSurfaceType::Basic);
|
||||
|
||||
@ -46,13 +51,14 @@ public:
|
||||
|
||||
protected:
|
||||
const GLuint mTex;
|
||||
const bool mOwnsTex;
|
||||
GLuint mFB;
|
||||
|
||||
SharedSurface_Basic(GLContext* gl,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
gfx::SurfaceFormat format,
|
||||
GLuint tex);
|
||||
GLuint tex,
|
||||
bool ownsTex);
|
||||
|
||||
public:
|
||||
virtual ~SharedSurface_Basic();
|
||||
@ -67,15 +73,19 @@ public:
|
||||
virtual GLuint ProdTexture() override {
|
||||
return mTex;
|
||||
}
|
||||
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override {
|
||||
MOZ_CRASH("don't do this");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class SurfaceFactory_Basic
|
||||
: public SurfaceFactory
|
||||
{
|
||||
public:
|
||||
SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps)
|
||||
: SurfaceFactory(gl, SharedSurfaceType::Basic, caps)
|
||||
{}
|
||||
SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
|
||||
bool hasAlpha = mReadCaps.alpha;
|
||||
@ -83,99 +93,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Using shared GL textures:
|
||||
class SharedSurface_GLTexture
|
||||
: public SharedSurface
|
||||
{
|
||||
public:
|
||||
static UniquePtr<SharedSurface_GLTexture> Create(GLContext* prodGL,
|
||||
GLContext* consGL,
|
||||
const GLFormats& formats,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
GLuint texture = 0);
|
||||
|
||||
static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
|
||||
MOZ_ASSERT(surf->mType == SharedSurfaceType::GLTextureShare);
|
||||
|
||||
return (SharedSurface_GLTexture*)surf;
|
||||
}
|
||||
|
||||
protected:
|
||||
GLContext* mConsGL;
|
||||
const GLuint mTex;
|
||||
const bool mOwnsTex;
|
||||
GLsync mSync;
|
||||
mutable Mutex mMutex;
|
||||
|
||||
SharedSurface_GLTexture(GLContext* prodGL,
|
||||
GLContext* consGL,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
GLuint tex,
|
||||
bool ownsTex)
|
||||
: SharedSurface(SharedSurfaceType::GLTextureShare,
|
||||
AttachmentType::GLTexture,
|
||||
prodGL,
|
||||
size,
|
||||
hasAlpha)
|
||||
, mConsGL(consGL)
|
||||
, mTex(tex)
|
||||
, mOwnsTex(ownsTex)
|
||||
, mSync(0)
|
||||
, mMutex("SharedSurface_GLTexture mutex")
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~SharedSurface_GLTexture();
|
||||
|
||||
virtual void LockProdImpl() override {}
|
||||
virtual void UnlockProdImpl() override {}
|
||||
|
||||
virtual void Fence() override;
|
||||
virtual bool WaitSync() override;
|
||||
virtual bool PollSync() override;
|
||||
|
||||
virtual GLuint ProdTexture() override {
|
||||
return mTex;
|
||||
}
|
||||
|
||||
// Custom:
|
||||
|
||||
GLuint ConsTexture(GLContext* consGL);
|
||||
|
||||
GLenum ConsTextureTarget() const {
|
||||
return ProdTextureTarget();
|
||||
}
|
||||
};
|
||||
|
||||
class SurfaceFactory_GLTexture
|
||||
: public SurfaceFactory
|
||||
{
|
||||
protected:
|
||||
GLContext* const mConsGL;
|
||||
|
||||
public:
|
||||
// If we don't know `consGL` at construction time, use `nullptr`, and call
|
||||
// `SetConsumerGL()` on each `SharedSurface_GLTexture` before calling its
|
||||
// `WaitSync()`.
|
||||
SurfaceFactory_GLTexture(GLContext* prodGL,
|
||||
GLContext* consGL,
|
||||
const SurfaceCaps& caps)
|
||||
: SurfaceFactory(prodGL, SharedSurfaceType::GLTextureShare, caps)
|
||||
, mConsGL(consGL)
|
||||
{
|
||||
MOZ_ASSERT(consGL != prodGL);
|
||||
}
|
||||
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
|
||||
bool hasAlpha = mReadCaps.alpha;
|
||||
return SharedSurface_GLTexture::Create(mGL, mConsGL, mFormats, size, hasAlpha);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gfx */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
@ -35,13 +35,10 @@ namespace gl {
|
||||
using namespace mozilla::layers;
|
||||
using namespace android;
|
||||
|
||||
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
|
||||
const SurfaceCaps& caps,
|
||||
layers::TextureFlags flags,
|
||||
layers::ISurfaceAllocator* allocator)
|
||||
: SurfaceFactory(prodGL, SharedSurfaceType::Gralloc, caps)
|
||||
, mFlags(flags)
|
||||
, mAllocator(allocator)
|
||||
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
: SurfaceFactory(SharedSurfaceType::Gralloc, prodGL, caps, allocator, flags)
|
||||
{
|
||||
MOZ_ASSERT(mAllocator);
|
||||
}
|
||||
@ -132,7 +129,8 @@ SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
|
||||
AttachmentType::GLTexture,
|
||||
prodGL,
|
||||
size,
|
||||
hasAlpha)
|
||||
hasAlpha,
|
||||
true)
|
||||
, mEGL(egl)
|
||||
, mSync(0)
|
||||
, mAllocator(allocator)
|
||||
@ -284,5 +282,11 @@ SharedSurface_Gralloc::WaitForBufferOwnership()
|
||||
mTextureClient->WaitForBufferOwnership();
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_Gralloc::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
return mTextureClient->ToSurfaceDescriptor(*out_descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mozilla
|
||||
|
@ -73,20 +73,17 @@ public:
|
||||
layers::GrallocTextureClientOGL* GetTextureClient() {
|
||||
return mTextureClient;
|
||||
}
|
||||
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
|
||||
};
|
||||
|
||||
class SurfaceFactory_Gralloc
|
||||
: public SurfaceFactory
|
||||
{
|
||||
protected:
|
||||
const layers::TextureFlags mFlags;
|
||||
RefPtr<layers::ISurfaceAllocator> mAllocator;
|
||||
|
||||
public:
|
||||
SurfaceFactory_Gralloc(GLContext* prodGL,
|
||||
const SurfaceCaps& caps,
|
||||
layers::TextureFlags flags,
|
||||
layers::ISurfaceAllocator* allocator);
|
||||
SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
|
||||
bool hasAlpha = mReadCaps.alpha;
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "SharedSurfaceIO.h"
|
||||
|
||||
#include "GLContextCGL.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
|
||||
#include "ScopedGLHelpers.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -152,7 +153,8 @@ SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioS
|
||||
AttachmentType::GLTexture,
|
||||
gl,
|
||||
size,
|
||||
hasAlpha)
|
||||
hasAlpha,
|
||||
true)
|
||||
, mIOSurf(ioSurf)
|
||||
{
|
||||
gl->MakeCurrent();
|
||||
@ -170,18 +172,29 @@ SharedSurface_IOSurface::~SharedSurface_IOSurface()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurface_IOSurface::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
|
||||
{
|
||||
bool isOpaque = !mHasAlpha;
|
||||
*out_descriptor = layers::SurfaceDescriptorMacIOSurface(mIOSurf->GetIOSurfaceID(),
|
||||
mIOSurf->GetContentsScaleFactor(),
|
||||
isOpaque);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceFactory_IOSurface
|
||||
|
||||
/*static*/ UniquePtr<SurfaceFactory_IOSurface>
|
||||
SurfaceFactory_IOSurface::Create(GLContext* gl,
|
||||
const SurfaceCaps& caps)
|
||||
SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
|
||||
MacIOSurface::GetMaxHeight());
|
||||
|
||||
typedef SurfaceFactory_IOSurface ptrT;
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, caps, maxDims) );
|
||||
UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, maxDims) );
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,21 @@ namespace gl {
|
||||
|
||||
class SharedSurface_IOSurface : public SharedSurface
|
||||
{
|
||||
private:
|
||||
const RefPtr<MacIOSurface> mIOSurf;
|
||||
GLuint mProdTex;
|
||||
|
||||
public:
|
||||
static UniquePtr<SharedSurface_IOSurface> Create(const RefPtr<MacIOSurface>& ioSurf,
|
||||
GLContext* gl,
|
||||
bool hasAlpha);
|
||||
|
||||
private:
|
||||
SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
|
||||
GLContext* gl, const gfx::IntSize& size,
|
||||
bool hasAlpha);
|
||||
|
||||
public:
|
||||
~SharedSurface_IOSurface();
|
||||
|
||||
virtual void LockProdImpl() override { }
|
||||
@ -57,13 +67,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
|
||||
GLContext* gl, const gfx::IntSize& size,
|
||||
bool hasAlpha);
|
||||
|
||||
RefPtr<MacIOSurface> mIOSurf;
|
||||
GLuint mProdTex;
|
||||
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
|
||||
};
|
||||
|
||||
class SurfaceFactory_IOSurface : public SurfaceFactory
|
||||
@ -71,17 +75,19 @@ class SurfaceFactory_IOSurface : public SurfaceFactory
|
||||
public:
|
||||
// Infallible.
|
||||
static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
|
||||
const SurfaceCaps& caps);
|
||||
const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags);
|
||||
protected:
|
||||
const gfx::IntSize mMaxDims;
|
||||
|
||||
SurfaceFactory_IOSurface(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps,
|
||||
const RefPtr<layers::ISurfaceAllocator>& allocator,
|
||||
const layers::TextureFlags& flags,
|
||||
const gfx::IntSize& maxDims)
|
||||
: SurfaceFactory(gl, SharedSurfaceType::IOSurface, caps)
|
||||
: SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags)
|
||||
, mMaxDims(maxDims)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
|
||||
};
|
||||
|
@ -70,7 +70,6 @@ enum class SharedSurfaceType : uint8_t {
|
||||
Unknown = 0,
|
||||
|
||||
Basic,
|
||||
GLTextureShare,
|
||||
EGLImageShare,
|
||||
EGLSurfaceANGLE,
|
||||
DXGLInterop,
|
||||
|
@ -12,16 +12,27 @@
|
||||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
|
||||
#define ADDREF_MANUALLY(obj) (obj)->AddRefManually(__FUNCTION__, __FILE__, __LINE__)
|
||||
#define RELEASE_MANUALLY(obj) (obj)->ReleaseManually(__FUNCTION__, __FILE__, __LINE__)
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template<class U>
|
||||
class StaticRefPtr;
|
||||
|
||||
template<typename T>
|
||||
class AtomicRefCountedWithFinalize
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
AtomicRefCountedWithFinalize()
|
||||
: mRecycleCallback(nullptr)
|
||||
, mRefCount(0)
|
||||
, mMessageLoopToPostDestructionTo(nullptr)
|
||||
#ifdef DEBUG
|
||||
, mSpew(false)
|
||||
, mManualAddRefs(0)
|
||||
, mManualReleases(0)
|
||||
#endif
|
||||
{}
|
||||
|
||||
~AtomicRefCountedWithFinalize() {}
|
||||
@ -36,14 +47,63 @@ class AtomicRefCountedWithFinalize
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
public:
|
||||
public:
|
||||
// Mark user classes that are considered flawless.
|
||||
template<typename U>
|
||||
friend class RefPtr;
|
||||
|
||||
template<class U>
|
||||
friend class ::mozilla::StaticRefPtr;
|
||||
|
||||
template<typename U>
|
||||
friend class TemporaryRef;
|
||||
|
||||
template<class U>
|
||||
friend class ::nsRefPtr;
|
||||
|
||||
template<class U>
|
||||
friend struct ::RunnableMethodTraits;
|
||||
|
||||
//friend class mozilla::gl::SurfaceFactory;
|
||||
|
||||
void AddRefManually(const char* funcName, const char* fileName, uint32_t lineNum) {
|
||||
#ifdef DEBUG
|
||||
uint32_t count = ++mManualAddRefs;
|
||||
if (mSpew) {
|
||||
printf_stderr("AddRefManually() #%u in %s at %s:%u\n", count, funcName,
|
||||
fileName, lineNum);
|
||||
}
|
||||
#else
|
||||
(void)funcName;
|
||||
(void)fileName;
|
||||
(void)lineNum;
|
||||
#endif
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void ReleaseManually(const char* funcName, const char* fileName, uint32_t lineNum) {
|
||||
#ifdef DEBUG
|
||||
uint32_t count = ++mManualReleases;
|
||||
if (mSpew) {
|
||||
printf_stderr("ReleaseManually() #%u in %s at %s:%u\n", count, funcName,
|
||||
fileName, lineNum);
|
||||
}
|
||||
#else
|
||||
(void)funcName;
|
||||
(void)fileName;
|
||||
(void)lineNum;
|
||||
#endif
|
||||
Release();
|
||||
}
|
||||
|
||||
private:
|
||||
void AddRef() {
|
||||
MOZ_ASSERT(mRefCount >= 0);
|
||||
MOZ_ASSERT(mRefCount >= 0, "AddRef() during/after Finalize()/dtor.");
|
||||
++mRefCount;
|
||||
}
|
||||
|
||||
void Release() {
|
||||
MOZ_ASSERT(mRefCount > 0);
|
||||
MOZ_ASSERT(mRefCount > 0, "Release() during/after Finalize()/dtor.");
|
||||
// Read mRecycleCallback early so that it does not get set to
|
||||
// deleted memory, if the object is goes away.
|
||||
RecycleCallback recycleCallback = mRecycleCallback;
|
||||
@ -52,6 +112,7 @@ class AtomicRefCountedWithFinalize
|
||||
// Recycle listeners must call ClearRecycleCallback
|
||||
// before releasing their strong reference.
|
||||
MOZ_ASSERT(mRecycleCallback == nullptr);
|
||||
MOZ_ASSERT(mManualAddRefs == mManualReleases);
|
||||
#ifdef DEBUG
|
||||
mRefCount = detail::DEAD;
|
||||
#endif
|
||||
@ -74,6 +135,7 @@ class AtomicRefCountedWithFinalize
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
typedef void (*RecycleCallback)(T* aObject, void* aClosure);
|
||||
/**
|
||||
* Set a callback responsible for recycling this object
|
||||
@ -96,8 +158,15 @@ private:
|
||||
void *mClosure;
|
||||
Atomic<int> mRefCount;
|
||||
MessageLoop *mMessageLoopToPostDestructionTo;
|
||||
#ifdef DEBUG
|
||||
public:
|
||||
bool mSpew;
|
||||
private:
|
||||
Atomic<uint32_t> mManualAddRefs;
|
||||
Atomic<uint32_t> mManualReleases;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -3,8 +3,9 @@
|
||||
* 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 "BasicLayersImpl.h" // for FillWithMask, etc
|
||||
#include "CopyableCanvasLayer.h"
|
||||
|
||||
#include "BasicLayersImpl.h" // for FillWithMask, etc
|
||||
#include "GLContext.h" // for GLContext
|
||||
#include "GLScreenBuffer.h" // for GLScreenBuffer
|
||||
#include "SharedSurface.h" // for SharedSurface
|
||||
@ -21,6 +22,7 @@
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
#include "nsSize.h" // for nsIntSize
|
||||
#include "gfxUtils.h"
|
||||
#include "client/TextureClientSharedSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -56,11 +58,8 @@ CopyableCanvasLayer::Initialize(const Data& aData)
|
||||
|
||||
if (aData.mFrontbufferGLTex) {
|
||||
gfx::IntSize size(aData.mSize.width, aData.mSize.height);
|
||||
mGLFrontbuffer = SharedSurface_GLTexture::Create(aData.mGLContext,
|
||||
nullptr,
|
||||
aData.mGLContext->GetGLFormats(),
|
||||
size, aData.mHasAlpha,
|
||||
aData.mFrontbufferGLTex);
|
||||
mGLFrontbuffer = SharedSurface_Basic::Wrap(aData.mGLContext, size, aData.mHasAlpha,
|
||||
aData.mFrontbufferGLTex);
|
||||
}
|
||||
} else if (aData.mDrawTarget) {
|
||||
mDrawTarget = aData.mDrawTarget;
|
||||
@ -108,7 +107,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
||||
frontbuffer = mGLFrontbuffer.get();
|
||||
} else {
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
ShSurfHandle* front = screen->Front();
|
||||
const auto& front = screen->Front();
|
||||
if (front) {
|
||||
frontbuffer = front->Surf();
|
||||
}
|
||||
@ -137,7 +136,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
||||
Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
|
||||
mGLContext->Readback(frontbuffer, data);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(data, data);
|
||||
gfxUtils::PremultiplyDataSurface(data, data);
|
||||
}
|
||||
aDestTarget->ReleaseBits(destData);
|
||||
return;
|
||||
|
@ -39,7 +39,7 @@ MacIOSurfaceTextureHostBasic::MacIOSurfaceTextureHostBasic(
|
||||
)
|
||||
: TextureHost(aFlags)
|
||||
{
|
||||
mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
|
||||
mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
|
||||
aDescriptor.scaleFactor(),
|
||||
!aDescriptor.isOpaque());
|
||||
}
|
||||
|
@ -22,9 +22,7 @@
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsDebug.h" // for printf_stderr, NS_ASSERTION
|
||||
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#endif
|
||||
#include "TextureClientSharedSurface.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
@ -37,13 +35,6 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
|
||||
CompositableForwarder* aForwarder,
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
NS_WARNING("Most platforms still need an optimized way to share GL cross process.");
|
||||
return new CanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (aType) {
|
||||
case CanvasClientTypeShSurf:
|
||||
return new CanvasClientSharedSurface(aForwarder, aFlags);
|
||||
@ -147,28 +138,11 @@ CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
|
||||
CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aLayerForwarder, aFlags)
|
||||
{ }
|
||||
|
||||
CanvasClientSharedSurface::~CanvasClientSharedSurface()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// Accelerated backends
|
||||
|
||||
static TemporaryRef<TextureClient>
|
||||
TexClientFromShSurf(ISurfaceAllocator* aAllocator, SharedSurface* surf,
|
||||
TextureFlags flags)
|
||||
{
|
||||
switch (surf->mType) {
|
||||
case SharedSurfaceType::Basic:
|
||||
return nullptr;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
case SharedSurfaceType::Gralloc:
|
||||
return GrallocTextureClientOGL::FromSharedSurface(surf, flags);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return new SharedSurfaceTextureClient(aAllocator, flags, surf);
|
||||
}
|
||||
ClearSurfaces();
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
@ -328,91 +302,92 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
static TemporaryRef<gl::ShSurfHandle>
|
||||
static TemporaryRef<SharedSurfaceTextureClient>
|
||||
CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
|
||||
{
|
||||
RefPtr<gl::ShSurfHandle> dest = factory->NewShSurfHandle(src->mSize);
|
||||
RefPtr<SharedSurfaceTextureClient> dest = factory->NewTexClient(src->mSize);
|
||||
if (!dest) {
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
SharedSurface::ProdCopy(src, dest->Surf(), factory);
|
||||
dest->Surf()->Fence();
|
||||
return dest.forget();
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
if (mFront) {
|
||||
mPrevFront = mFront;
|
||||
mFront = nullptr;
|
||||
}
|
||||
|
||||
auto gl = aLayer->mGLContext;
|
||||
gl->MakeCurrent();
|
||||
|
||||
RefPtr<TextureClient> newFront;
|
||||
|
||||
if (aLayer->mGLFrontbuffer) {
|
||||
mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
|
||||
if (mFront)
|
||||
mFront->Surf()->Fence();
|
||||
mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
|
||||
if (!mShSurfClient) {
|
||||
gfxCriticalError() << "Invalid canvas front buffer";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
mFront = gl->Screen()->Front();
|
||||
}
|
||||
if (!mFront) {
|
||||
gfxCriticalError() << "Invalid canvas front buffer";
|
||||
return;
|
||||
mShSurfClient = gl->Screen()->Front();
|
||||
if (!mShSurfClient) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(mShSurfClient);
|
||||
|
||||
newFront = mShSurfClient;
|
||||
|
||||
SharedSurface* surf = mShSurfClient->Surf();
|
||||
|
||||
// Readback if needed.
|
||||
mReadbackClient = nullptr;
|
||||
|
||||
// Alright, now sort out the IPC goop.
|
||||
SharedSurface* surf = mFront->Surf();
|
||||
auto forwarder = GetForwarder();
|
||||
auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE;
|
||||
|
||||
// Get a TexClient from our surf.
|
||||
RefPtr<TextureClient> newTex = TexClientFromShSurf(GetForwarder(), surf, flags);
|
||||
if (!newTex) {
|
||||
bool needsReadback = (surf->mType == SharedSurfaceType::Basic);
|
||||
if (needsReadback) {
|
||||
TextureFlags flags = aLayer->Flags() |
|
||||
TextureFlags::IMMUTABLE;
|
||||
|
||||
auto manager = aLayer->ClientManager();
|
||||
auto shadowForwarder = manager->AsShadowForwarder();
|
||||
auto layersBackend = shadowForwarder->GetCompositorBackendType();
|
||||
mReadbackClient = TexClientFromReadback(surf, forwarder, flags, layersBackend);
|
||||
|
||||
newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend);
|
||||
newFront = mReadbackClient;
|
||||
} else {
|
||||
mReadbackClient = nullptr;
|
||||
}
|
||||
|
||||
if (!newTex) {
|
||||
MOZ_ASSERT(newFront);
|
||||
if (!newFront) {
|
||||
// May happen in a release build in case of memory pressure.
|
||||
gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. size: " << aSize;
|
||||
gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. Size: " << aSize;
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the new TexClient.
|
||||
MOZ_ALWAYS_TRUE( AddTextureClient(newTex) );
|
||||
|
||||
// Remove the old TexClient.
|
||||
if (mFrontTex) {
|
||||
// remove old buffer from CompositableHost
|
||||
RefPtr<AsyncTransactionTracker> tracker = new RemoveTextureFromCompositableTracker();
|
||||
// Hold TextureClient until transaction complete.
|
||||
tracker->SetTextureClient(mFrontTex);
|
||||
mFrontTex->SetRemoveFromCompositableTracker(tracker);
|
||||
// RemoveTextureFromCompositableAsync() expects CompositorChild's presence.
|
||||
GetForwarder()->RemoveTextureFromCompositableAsync(tracker, this, mFrontTex);
|
||||
|
||||
mFrontTex = nullptr;
|
||||
if (mFront) {
|
||||
if (mFront->GetFlags() & TextureFlags::RECYCLE) {
|
||||
mFront->WaitForCompositorRecycle();
|
||||
}
|
||||
}
|
||||
|
||||
// Use the new TexClient.
|
||||
mFrontTex = newTex;
|
||||
mFront = newFront;
|
||||
|
||||
forwarder->UseTexture(this, mFrontTex);
|
||||
// Add the new TexClient.
|
||||
MOZ_ALWAYS_TRUE( AddTextureClient(mFront) );
|
||||
|
||||
forwarder->UseTexture(this, mFront);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClientSharedSurface::ClearSurfaces()
|
||||
{
|
||||
mFrontTex = nullptr;
|
||||
// It is important to destroy the SharedSurface *after* the TextureClient.
|
||||
mFront = nullptr;
|
||||
mPrevFront = nullptr;
|
||||
mShSurfClient = nullptr;
|
||||
mReadbackClient = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -18,18 +18,12 @@
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
class ShSurfHandle;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientCanvasLayer;
|
||||
class CompositableForwarder;
|
||||
class SharedSurfaceTextureClient;
|
||||
|
||||
/**
|
||||
* Compositable client for 2d and webgl canvas.
|
||||
@ -114,10 +108,9 @@ private:
|
||||
class CanvasClientSharedSurface : public CanvasClient
|
||||
{
|
||||
private:
|
||||
RefPtr<gl::ShSurfHandle> mFront;
|
||||
RefPtr<gl::ShSurfHandle> mPrevFront;
|
||||
|
||||
RefPtr<TextureClient> mFrontTex;
|
||||
RefPtr<SharedSurfaceTextureClient> mShSurfClient;
|
||||
RefPtr<TextureClient> mReadbackClient;
|
||||
RefPtr<TextureClient> mFront;
|
||||
|
||||
void ClearSurfaces();
|
||||
|
||||
@ -125,10 +118,7 @@ public:
|
||||
CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags);
|
||||
|
||||
~CanvasClientSharedSurface()
|
||||
{
|
||||
ClearSurfaces();
|
||||
}
|
||||
~CanvasClientSharedSurface();
|
||||
|
||||
virtual TextureInfo GetTextureInfo() const override {
|
||||
return TextureInfo(CompositableType::IMAGE);
|
||||
|
@ -70,49 +70,41 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
||||
}
|
||||
MOZ_ASSERT(caps.alpha == aData.mHasAlpha);
|
||||
|
||||
auto forwarder = ClientManager()->AsShadowForwarder();
|
||||
|
||||
mFlags = TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
if (!aData.mIsGLAlphaPremult) {
|
||||
mFlags |= TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
|
||||
UniquePtr<SurfaceFactory> factory;
|
||||
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
|
||||
switch (forwarder->GetCompositorBackendType()) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
#if defined(XP_MACOSX)
|
||||
factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags);
|
||||
#elif defined(MOZ_WIDGET_GONK)
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags);
|
||||
#else
|
||||
if (mGLContext->GetContextType() == GLContextType::EGL) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
|
||||
TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
if (!aData.mIsGLAlphaPremult) {
|
||||
flags |= TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
|
||||
caps,
|
||||
flags,
|
||||
ClientManager()->AsShadowForwarder());
|
||||
#else
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
bool isCrossProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
|
||||
if (!isCrossProcess) {
|
||||
// [Basic/OGL Layers, OMTC] WebGL layer init.
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
|
||||
} else {
|
||||
// we could do readback here maybe
|
||||
NS_NOTREACHED("isCrossProcess but not on native B2G!");
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder,
|
||||
mFlags);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
// Well, this *should* work...
|
||||
#ifdef XP_MACOSX
|
||||
factory = SurfaceFactory_IOSurface::Create(mGLContext, caps);
|
||||
#else
|
||||
GLContext* nullConsGL = nullptr; // Bug 1050044.
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, nullConsGL, caps);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D10:
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
#ifdef XP_WIN
|
||||
if (mGLContext->IsANGLE() && DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) {
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
|
||||
if (mGLContext->IsANGLE() &&
|
||||
DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device()))
|
||||
{
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps, forwarder,
|
||||
mFlags);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
@ -128,7 +120,7 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
||||
mFactory = Move(factory);
|
||||
if (!mFactory) {
|
||||
// Absolutely must have a factory here, so create a basic one
|
||||
mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
|
||||
mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps, mFlags);
|
||||
}
|
||||
} else {
|
||||
if (factory)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifndef GFX_CLIENTCANVASLAYER_H
|
||||
#define GFX_CLIENTCANVASLAYER_H
|
||||
|
||||
#include "mozilla/layers/CanvasClient.h" // for CanvasClient, etc
|
||||
#include "CanvasClient.h" // for CanvasClient, etc
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager, etc
|
||||
#include "CopyableCanvasLayer.h" // for CopyableCanvasLayer
|
||||
#include "Layers.h" // for CanvasLayer, etc
|
||||
@ -21,7 +21,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
class SurfaceFactory;
|
||||
}
|
||||
|
||||
@ -81,6 +80,9 @@ public:
|
||||
{
|
||||
return mCanvasClient;
|
||||
}
|
||||
|
||||
const TextureFlags& Flags() const { return mFlags; }
|
||||
|
||||
protected:
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
@ -93,6 +95,8 @@ protected:
|
||||
|
||||
UniquePtr<gl::SurfaceFactory> mFactory;
|
||||
|
||||
TextureFlags mFlags;
|
||||
|
||||
friend class DeprecatedCanvasClient2D;
|
||||
friend class CanvasClient2D;
|
||||
friend class CanvasClientSharedSurface;
|
||||
|
@ -20,8 +20,6 @@
|
||||
#include "mozilla/gfx/Logging.h" // for gfxDebug
|
||||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning
|
||||
#include "nsPrintfCString.h" // for nsPrintfCString
|
||||
#include "LayersLogging.h" // for AppendToString
|
||||
@ -113,7 +111,7 @@ public:
|
||||
|
||||
bool RecvCompositorRecycle() override
|
||||
{
|
||||
RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
|
||||
RECYCLE_LOG("[CLIENT] Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
|
||||
mWaitForRecycle = nullptr;
|
||||
return true;
|
||||
}
|
||||
@ -121,7 +119,7 @@ public:
|
||||
void WaitForCompositorRecycle()
|
||||
{
|
||||
mWaitForRecycle = mTextureClient;
|
||||
RECYCLE_LOG("Wait for recycle %p\n", mWaitForRecycle.get());
|
||||
RECYCLE_LOG("[CLIENT] Wait for recycle %p\n", mWaitForRecycle.get());
|
||||
SendClientRecycle();
|
||||
}
|
||||
|
||||
@ -584,6 +582,10 @@ TextureClient::Finalize()
|
||||
// Null it before RemoveTexture calls to avoid invalid actor->mTextureClient
|
||||
// when calling TextureChild::ActorDestroy()
|
||||
actor->mTextureClient = nullptr;
|
||||
|
||||
// `actor->mWaitForRecycle` may not be null, as we may be being called from setting
|
||||
// this RefPtr to null! Clearing it here will double-Release() it.
|
||||
|
||||
// this will call ForceRemove in the right thread, using a sync proxy if needed
|
||||
if (actor->GetForwarder()) {
|
||||
actor->GetForwarder()->RemoveTexture(this);
|
||||
@ -913,32 +915,6 @@ BufferTextureClient::GetLockedData() const
|
||||
return serializer.GetData();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SharedSurfaceTextureClient
|
||||
|
||||
SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
gl::SharedSurface* surf)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mIsLocked(false)
|
||||
, mSurf(surf)
|
||||
, mGL(mSurf->mGL)
|
||||
{
|
||||
AddFlags(TextureFlags::DEALLOCATE_CLIENT);
|
||||
}
|
||||
|
||||
SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
|
||||
{
|
||||
// the data is owned externally.
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
aOutDescriptor = SharedSurfaceDescriptor((uintptr_t)mSurf);
|
||||
return true;
|
||||
}
|
||||
|
||||
TemporaryRef<SyncObject>
|
||||
SyncObject::CreateSyncObject(SyncHandle aHandle)
|
||||
{
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint32_t, uint8_t, uint64_t
|
||||
#include "GLContextTypes.h" // for GLContext (ptr only), etc
|
||||
#include "GLTextureImage.h" // for TextureImage
|
||||
#include "ImageTypes.h" // for StereoMode
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
@ -32,10 +31,6 @@
|
||||
class gfxImageSurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class SharedSurface;
|
||||
}
|
||||
|
||||
// When defined, we track which pool the tile came from and test for
|
||||
// any inconsistencies. This can be defined in release build as well.
|
||||
@ -474,7 +469,7 @@ public:
|
||||
virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
|
||||
mReadbackSink = aReadbackSink;
|
||||
}
|
||||
|
||||
|
||||
virtual void SyncWithObject(SyncObject* aSyncObject) { }
|
||||
|
||||
private:
|
||||
@ -688,66 +683,6 @@ protected:
|
||||
size_t mBufSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureClient implementation to share SharedSurfaces.
|
||||
*/
|
||||
class SharedSurfaceTextureClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags,
|
||||
gl::SharedSurface* surf);
|
||||
|
||||
protected:
|
||||
~SharedSurfaceTextureClient();
|
||||
|
||||
public:
|
||||
// Boilerplate start
|
||||
virtual bool IsAllocated() const override { return true; }
|
||||
|
||||
virtual bool Lock(OpenMode) override {
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Unlock() override {
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return gfx::IntSize(); }
|
||||
|
||||
// This TextureClient should not be used in a context where we use CreateSimilar
|
||||
// (ex. component alpha) because the underlying texture data is always created by
|
||||
// an external producer.
|
||||
virtual TemporaryRef<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize,
|
||||
TextureAllocationFlags) override {
|
||||
MOZ_CRASH("Should never hit this.");
|
||||
return false;
|
||||
}
|
||||
// Boilerplate end
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
protected:
|
||||
bool mIsLocked;
|
||||
gl::SharedSurface* const mSurf;
|
||||
RefPtr<gl::GLContext> mGL; // Just for reference holding.
|
||||
};
|
||||
|
||||
struct TextureClientAutoUnlock
|
||||
{
|
||||
TextureClient* mTexture;
|
||||
|
68
gfx/layers/client/TextureClientSharedSurface.cpp
Normal file
68
gfx/layers/client/TextureClientSharedSurface.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "TextureClientSharedSurface.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Logging.h" // for gfxDebug
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "SharedSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
SharedSurfaceTextureClient::SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
UniquePtr<gl::SharedSurface> surf,
|
||||
gl::SurfaceFactory* factory)
|
||||
: TextureClient(aAllocator, aFlags | TextureFlags::RECYCLE)
|
||||
, mSurf(Move(surf))
|
||||
, mFactory(factory)
|
||||
, mRecyclingRef(this)
|
||||
{
|
||||
// AtomicRefCountedWithFinalize is a little strange. It attempts to recycle when
|
||||
// Release drops the ref count to 1. The idea is that the recycler holds a strong ref.
|
||||
// Here, we want to keep it simple, and always have a recycle callback, but only recycle
|
||||
// if the WeakPtr mFactory is still non-null. Therefore, we keep mRecyclingRef as ref to
|
||||
// ourself! Call StopRecycling() to end the cycle.
|
||||
mRecyclingRef->SetRecycleCallback(&gl::SurfaceFactory::RecycleCallback, nullptr);
|
||||
}
|
||||
|
||||
SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
|
||||
{
|
||||
// Free the ShSurf implicitly.
|
||||
|
||||
// Tricky issue! We will often call the dtor via Release via StopRecycling, where we
|
||||
// null out mRecyclingRef. Right now, we call Release before actually clearing the
|
||||
// value. This means the dtor will see that mRecyclingRef is non-null, and try to
|
||||
// Release it, even though we're mid-Release! We need to clear mRecyclingRef so the dtor
|
||||
// doesn't try to Release it.
|
||||
mozilla::unused << mRecyclingRef.forget().take();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
SharedSurfaceTextureClient::GetSize() const
|
||||
{
|
||||
return mSurf->mSize;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
return mSurf->ToSurfaceDescriptor(&aOutDescriptor);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurfaceTextureClient::StopRecycling()
|
||||
{
|
||||
mRecyclingRef->ClearRecycleCallback();
|
||||
mRecyclingRef = nullptr;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
79
gfx/layers/client/TextureClientSharedSurface.h
Normal file
79
gfx/layers/client/TextureClientSharedSurface.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H
|
||||
#define MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H
|
||||
|
||||
#include <cstddef> // for size_t
|
||||
#include <stdint.h> // for uint32_t, uint8_t, uint64_t
|
||||
#include "GLContextTypes.h" // for GLContext (ptr only), etc
|
||||
#include "TextureClient.h"
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/RefPtr.h" // for RefPtr, RefCounted
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
||||
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class SharedSurface;
|
||||
class SurfaceFactory;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class SharedSurfaceTextureClient : public TextureClient
|
||||
{
|
||||
protected:
|
||||
const UniquePtr<gl::SharedSurface> mSurf;
|
||||
const WeakPtr<gl::SurfaceFactory> mFactory;
|
||||
RefPtr<SharedSurfaceTextureClient> mRecyclingRef;
|
||||
|
||||
friend class gl::SurfaceFactory;
|
||||
|
||||
SharedSurfaceTextureClient(ISurfaceAllocator* aAllocator, TextureFlags aFlags,
|
||||
UniquePtr<gl::SharedSurface> surf,
|
||||
gl::SurfaceFactory* factory);
|
||||
|
||||
~SharedSurfaceTextureClient();
|
||||
|
||||
public:
|
||||
virtual bool IsAllocated() const override { return true; }
|
||||
virtual bool Lock(OpenMode) override { return false; }
|
||||
virtual bool IsLocked() const override { return false; }
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
virtual TemporaryRef<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize,
|
||||
TextureAllocationFlags) override {
|
||||
MOZ_CRASH("Should never hit this.");
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
gl::SharedSurface* Surf() const {
|
||||
return mSurf.get();
|
||||
}
|
||||
|
||||
void StopRecycling();
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H
|
@ -25,7 +25,6 @@ namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
|
||||
FPSCounter::FPSCounter(const char* aName)
|
||||
: mWriteIndex(0)
|
||||
@ -395,7 +394,7 @@ static void DrawDigits(unsigned int aValue,
|
||||
Rect drawRect = Rect(aOffsetX + n * FontWidth, aOffsetY, FontWidth, FontHeight);
|
||||
Rect clipRect = Rect(0, 0, 300, 100);
|
||||
aCompositor->DrawQuad(drawRect, clipRect,
|
||||
aEffectChain, opacity, transform);
|
||||
aEffectChain, opacity, transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,7 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo)
|
||||
{}
|
||||
|
||||
ImageHost::~ImageHost()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void
|
||||
ImageHost::UseTextureHost(TextureHost* aTexture)
|
||||
|
@ -22,9 +22,6 @@
|
||||
#include "mozilla/layers/PTextureParent.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include <limits>
|
||||
#include "SharedSurface.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "../opengl/CompositorOGL.h"
|
||||
#include "gfxUtils.h"
|
||||
|
||||
@ -35,7 +32,6 @@
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "../opengl/GrallocTextureClient.h"
|
||||
#include "../opengl/GrallocTextureHost.h"
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
@ -43,12 +39,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "SharedSurfaceIO.h"
|
||||
#include "../opengl/MacIOSurfaceTextureHostOGL.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "SharedSurfaceANGLE.h"
|
||||
#include "mozilla/layers/TextureDIB.h"
|
||||
#endif
|
||||
|
||||
@ -96,6 +90,8 @@ public:
|
||||
RefPtr<TextureHost> mTextureHost;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
PTextureParent*
|
||||
TextureHost::CreateIPDLActor(CompositableParentManager* aManager,
|
||||
@ -187,9 +183,6 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
|
||||
case SurfaceDescriptor::TSurfaceTextureDescriptor:
|
||||
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
|
||||
|
||||
case SurfaceDescriptor::TSharedSurfaceDescriptor:
|
||||
return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor());
|
||||
|
||||
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
|
||||
if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
|
||||
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
|
||||
@ -835,153 +828,6 @@ TextureParent::RecvRecycleTexture(const TextureFlags& aTextureFlags)
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static RefPtr<TextureSource>
|
||||
SharedSurfaceToTexSource(gl::SharedSurface* abstractSurf, Compositor* compositor)
|
||||
{
|
||||
MOZ_ASSERT(abstractSurf);
|
||||
MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Basic);
|
||||
MOZ_ASSERT(abstractSurf->mType != gl::SharedSurfaceType::Gralloc);
|
||||
|
||||
if (!compositor) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat format = abstractSurf->mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
|
||||
: gfx::SurfaceFormat::R8G8B8X8;
|
||||
|
||||
RefPtr<TextureSource> texSource;
|
||||
switch (abstractSurf->mType) {
|
||||
#ifdef XP_WIN
|
||||
case gl::SharedSurfaceType::EGLSurfaceANGLE: {
|
||||
auto surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf);
|
||||
|
||||
MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_D3D11);
|
||||
CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(compositor);
|
||||
RefPtr<ID3D11Texture2D> tex = surf->GetConsumerTexture();
|
||||
|
||||
if (!tex) {
|
||||
NS_WARNING("Failed to open shared resource.");
|
||||
break;
|
||||
}
|
||||
texSource = new DataTextureSourceD3D11(format, compositorD3D11, tex);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case gl::SharedSurfaceType::GLTextureShare: {
|
||||
auto surf = gl::SharedSurface_GLTexture::Cast(abstractSurf);
|
||||
|
||||
MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
|
||||
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
|
||||
gl::GLContext* gl = compositorOGL->gl();
|
||||
|
||||
GLenum target = surf->ConsTextureTarget();
|
||||
GLuint tex = surf->ConsTexture(gl);
|
||||
texSource = new GLTextureSource(compositorOGL, tex, target,
|
||||
surf->mSize, format,
|
||||
true/*externally owned*/);
|
||||
break;
|
||||
}
|
||||
case gl::SharedSurfaceType::EGLImageShare: {
|
||||
auto surf = gl::SharedSurface_EGLImage::Cast(abstractSurf);
|
||||
|
||||
MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
|
||||
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
|
||||
gl::GLContext* gl = compositorOGL->gl();
|
||||
MOZ_ASSERT(gl->IsCurrent());
|
||||
|
||||
GLenum target = 0;
|
||||
GLuint tex = 0;
|
||||
surf->AcquireConsumerTexture(gl, &tex, &target);
|
||||
|
||||
texSource = new GLTextureSource(compositorOGL, tex, target,
|
||||
surf->mSize, format,
|
||||
true/*externally owned*/);
|
||||
break;
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
case gl::SharedSurfaceType::IOSurface: {
|
||||
auto surf = gl::SharedSurface_IOSurface::Cast(abstractSurf);
|
||||
MacIOSurface* ioSurf = surf->GetIOSurface();
|
||||
|
||||
MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
|
||||
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
|
||||
|
||||
texSource = new MacIOSurfaceTextureSourceOGL(compositorOGL, ioSurf);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(texSource.get(), "TextureSource creation failed.");
|
||||
return texSource;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// SharedSurfaceTextureHost
|
||||
|
||||
SharedSurfaceTextureHost::SharedSurfaceTextureHost(TextureFlags aFlags,
|
||||
const SharedSurfaceDescriptor& aDesc)
|
||||
: TextureHost(aFlags)
|
||||
, mIsLocked(false)
|
||||
, mSurf((gl::SharedSurface*)aDesc.surf())
|
||||
, mCompositor(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mSurf);
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
SharedSurfaceTextureHost::GetFormat() const
|
||||
{
|
||||
MOZ_ASSERT(mTexSource);
|
||||
return mTexSource->GetFormat();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
SharedSurfaceTextureHost::GetSize() const
|
||||
{
|
||||
MOZ_ASSERT(mTexSource);
|
||||
return mTexSource->GetSize();
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurfaceTextureHost::EnsureTexSource()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
|
||||
if (mTexSource)
|
||||
return;
|
||||
|
||||
mTexSource = SharedSurfaceToTexSource(mSurf, mCompositor);
|
||||
MOZ_ASSERT(mTexSource);
|
||||
}
|
||||
|
||||
bool
|
||||
SharedSurfaceTextureHost::Lock()
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
|
||||
mSurf->ConsumerAcquire();
|
||||
|
||||
mIsLocked = true;
|
||||
|
||||
EnsureTexSource();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurfaceTextureHost::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mSurf->ConsumerRelease();
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace
|
||||
|
@ -31,9 +31,6 @@
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
}
|
||||
namespace ipc {
|
||||
class Shmem;
|
||||
}
|
||||
@ -43,7 +40,6 @@ namespace layers {
|
||||
class Compositor;
|
||||
class CompositableParentManager;
|
||||
class SurfaceDescriptor;
|
||||
class SharedSurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureHostOGL;
|
||||
class TextureSourceOGL;
|
||||
@ -662,64 +658,6 @@ protected:
|
||||
uint8_t* mBuffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureHost for SharedSurfaces
|
||||
*/
|
||||
class SharedSurfaceTextureHost : public TextureHost
|
||||
{
|
||||
public:
|
||||
SharedSurfaceTextureHost(TextureFlags aFlags,
|
||||
const SharedSurfaceDescriptor& aDesc);
|
||||
|
||||
virtual ~SharedSurfaceTextureHost() {
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
}
|
||||
|
||||
virtual void DeallocateDeviceData() override {};
|
||||
|
||||
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override {
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
|
||||
if (aCompositor == mCompositor)
|
||||
return;
|
||||
|
||||
mTexSource = nullptr;
|
||||
mCompositor = aCompositor;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual bool Lock() override;
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override {
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
MOZ_ASSERT(mTexSource);
|
||||
aTexture = mTexSource;
|
||||
return !!aTexture;
|
||||
}
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() override { return "SharedSurfaceTextureHost"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void EnsureTexSource();
|
||||
|
||||
bool mIsLocked;
|
||||
gl::SharedSurface* const mSurf;
|
||||
RefPtr<Compositor> mCompositor;
|
||||
RefPtr<TextureSource> mTexSource;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoLockTextureHost
|
||||
{
|
||||
public:
|
||||
|
@ -351,7 +351,7 @@ void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient)
|
||||
static void ReleaseTextureClientNow(TextureClient* aClient)
|
||||
{
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
aClient->Release();
|
||||
RELEASE_MANUALLY(aClient);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -368,7 +368,7 @@ void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
|
||||
// has already shut down, along with the TextureChild, which means no
|
||||
// message will be sent and it is safe to run this code from any thread.
|
||||
MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
|
||||
aClient->Release();
|
||||
RELEASE_MANUALLY(aClient);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ bool ImageBridgeParent::RecvWillStop()
|
||||
static void
|
||||
ReleaseImageBridgeParent(ImageBridgeParent* aImageBridgeParent)
|
||||
{
|
||||
aImageBridgeParent->Release();
|
||||
RELEASE_MANUALLY(aImageBridgeParent);
|
||||
}
|
||||
|
||||
bool ImageBridgeParent::RecvStop()
|
||||
@ -201,7 +201,7 @@ bool ImageBridgeParent::RecvStop()
|
||||
// the handling of this sync message can't race with the destruction of
|
||||
// the ImageBridgeParent, which would trigger the dreaded "mismatched CxxStackFrames"
|
||||
// assertion of MessageChannel.
|
||||
AddRef();
|
||||
ADDREF_MANUALLY(this);
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&ReleaseImageBridgeParent, this));
|
||||
|
@ -160,12 +160,12 @@ protected:
|
||||
void AddIPDLReference() {
|
||||
MOZ_ASSERT(mIPCOpen == false);
|
||||
mIPCOpen = true;
|
||||
AddRef();
|
||||
ADDREF_MANUALLY(this);
|
||||
}
|
||||
void ReleaseIPDLReference() {
|
||||
MOZ_ASSERT(mIPCOpen == true);
|
||||
mIPCOpen = false;
|
||||
Release();
|
||||
RELEASE_MANUALLY(this);
|
||||
}
|
||||
friend class CompositorParent;
|
||||
friend class CrossProcessCompositorParent;
|
||||
|
@ -59,7 +59,7 @@ struct SurfaceDescriptorDXGIYCbCr {
|
||||
};
|
||||
|
||||
struct SurfaceDescriptorMacIOSurface {
|
||||
uint32_t surface;
|
||||
uint32_t surfaceId;
|
||||
double scaleFactor;
|
||||
bool isOpaque;
|
||||
};
|
||||
@ -86,10 +86,6 @@ struct NewSurfaceDescriptorGralloc {
|
||||
bool isOpaque;
|
||||
};
|
||||
|
||||
struct SharedSurfaceDescriptor {
|
||||
uintptr_t surf;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for shmem-backed YCbCr and (flavors of) RGBA textures
|
||||
*/
|
||||
@ -101,7 +97,7 @@ struct SurfaceDescriptorShmem {
|
||||
/**
|
||||
* Used for "raw memory"-backed YCbCr and (flavors of) RGBA textures
|
||||
*/
|
||||
struct SurfaceDescriptorMemory {
|
||||
struct SurfaceDescriptorMemory {
|
||||
uintptr_t data;
|
||||
SurfaceFormat format;
|
||||
};
|
||||
@ -118,7 +114,6 @@ union SurfaceDescriptor {
|
||||
EGLImageDescriptor;
|
||||
SurfaceDescriptorMacIOSurface;
|
||||
NewSurfaceDescriptorGralloc;
|
||||
SharedSurfaceDescriptor;
|
||||
null_t;
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,10 @@ SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
|
||||
|
||||
if (mCompositable->GetAsyncID() != 0 &&
|
||||
!InImageBridgeChildThread()) {
|
||||
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take());
|
||||
ADDREF_MANUALLY(mTextureClient);
|
||||
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
|
||||
mTextureClient = nullptr;
|
||||
|
||||
ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,10 @@ SharedRGBImage::~SharedRGBImage()
|
||||
|
||||
if (mCompositable->GetAsyncID() != 0 &&
|
||||
!InImageBridgeChildThread()) {
|
||||
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take());
|
||||
ADDREF_MANUALLY(mTextureClient);
|
||||
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
|
||||
mTextureClient = nullptr;
|
||||
|
||||
ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,7 @@ EXPORTS.mozilla.layers += [
|
||||
'client/TextureClient.h',
|
||||
'client/TextureClientPool.h',
|
||||
'client/TextureClientRecycleAllocator.h',
|
||||
'client/TextureClientSharedSurface.h',
|
||||
'client/TiledContentClient.h',
|
||||
'composite/AsyncCompositionManager.h',
|
||||
'composite/CanvasLayerComposite.h',
|
||||
@ -269,6 +270,7 @@ UNIFIED_SOURCES += [
|
||||
'client/TextureClient.cpp',
|
||||
'client/TextureClientPool.cpp',
|
||||
'client/TextureClientRecycleAllocator.cpp',
|
||||
'client/TextureClientSharedSurface.cpp',
|
||||
'client/TiledContentClient.cpp',
|
||||
'composite/AsyncCompositionManager.cpp',
|
||||
'composite/CanvasLayerComposite.cpp',
|
||||
|
@ -19,6 +19,10 @@ class MediaBuffer;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,7 @@ MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
|
||||
const SurfaceDescriptorMacIOSurface& aDescriptor)
|
||||
: TextureHost(aFlags)
|
||||
{
|
||||
mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
|
||||
mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
|
||||
aDescriptor.scaleFactor(),
|
||||
!aDescriptor.isOpaque());
|
||||
}
|
||||
|
@ -15,10 +15,6 @@
|
||||
#include "mozilla/gfx/2D.h" // for DataSourceSurface
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/gfx/Logging.h" // for gfxCriticalError
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
# include "GrallocImages.h" // for GrallocImage
|
||||
# include "EGLImageHelpers.h"
|
||||
#endif
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
||||
#include "mozilla/layers/GrallocTextureHost.h"
|
||||
@ -26,11 +22,17 @@
|
||||
#include "AndroidSurfaceTexture.h"
|
||||
#include "GfxTexturesReporter.h" // for GfxTexturesReporter
|
||||
#include "GLBlitTextureImageHelper.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
# include "GrallocImages.h" // for GrallocImage
|
||||
# include "EGLImageHelpers.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "SharedSurfaceIO.h"
|
||||
#include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
|
||||
#endif
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::gfx;
|
||||
@ -589,6 +591,8 @@ EGLImageTextureSource::EGLImageTextureSource(CompositorOGL* aCompositor,
|
||||
, mWrapMode(aWrapMode)
|
||||
, mSize(aSize)
|
||||
{
|
||||
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
|
||||
mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -602,13 +606,12 @@ EGLImageTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
|
||||
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl()),
|
||||
"EGLImage not supported or disabled in runtime");
|
||||
|
||||
GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit);
|
||||
GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);
|
||||
|
||||
gl()->fActiveTexture(aTextureUnit);
|
||||
gl()->fBindTexture(mTextureTarget, tex);
|
||||
|
||||
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D);
|
||||
gl()->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage);
|
||||
gl()->fEGLImageTargetTexture2D(mTextureTarget, mImage);
|
||||
|
||||
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
|
||||
}
|
||||
@ -650,12 +653,10 @@ EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags,
|
||||
, mSync(aSync)
|
||||
, mSize(aSize)
|
||||
, mCompositor(nullptr)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
EGLImageTextureHost::~EGLImageTextureHost()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
gl::GLContext*
|
||||
EGLImageTextureHost::gl() const
|
||||
@ -671,13 +672,16 @@ EGLImageTextureHost::Lock()
|
||||
}
|
||||
|
||||
EGLint status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
|
||||
|
||||
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
|
||||
MOZ_ASSERT(status != 0,
|
||||
"ClientWaitSync generated an error. Has mSync already been destroyed?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mTextureSource) {
|
||||
gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
|
||||
GLenum target = LOCAL_GL_TEXTURE_2D;
|
||||
GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
|
||||
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
|
||||
mTextureSource = new EGLImageTextureSource(mCompositor,
|
||||
mImage,
|
||||
|
Loading…
Reference in New Issue
Block a user