Backed out changeset 29bd04fc57f0 (bug 1144906) for b2g m12 orange

--HG--
extra : amend_source : 79faafb4230715cf6af79b452d121d1e7b58e665
This commit is contained in:
Wes Kocher 2015-05-28 17:08:53 -07:00
parent 8cc4e17ee5
commit 5ee1a8327e
43 changed files with 997 additions and 796 deletions

View File

@ -2517,9 +2517,10 @@ GLContext::Readback(SharedSurface* src, gfx::DataSourceSurface* dest)
{
ScopedBindFramebuffer autoFB(this);
// We're consuming from the producer side, so which do we use?
// Really, we just want a read-only lock, so ConsumerAcquire is the best match.
src->ProducerReadAcquire();
// Even though we're reading. We're doing it on
// the producer side. So we call ProducerAcquire
// instead of ConsumerAcquire.
src->ProducerAcquire();
if (src->mAttachType == AttachmentType::Screen) {
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
@ -2546,7 +2547,7 @@ GLContext::Readback(SharedSurface* src, gfx::DataSourceSurface* dest)
ReadPixelsIntoDataSurface(this, dest);
src->ProducerReadRelease();
src->ProducerRelease();
}
if (tempFB)

View File

@ -21,7 +21,6 @@
#include "ScopedGLHelpers.h"
#include "gfx2DGlue.h"
#include "../layers/ipc/ShadowLayers.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
namespace mozilla {
namespace gl {
@ -40,43 +39,55 @@ GLScreenBuffer::Create(GLContext* gl,
return Move(ret);
}
UniquePtr<SurfaceFactory> factory;
layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
if (!caps.premultAlpha) {
flags |= layers::TextureFlags::NON_PREMULTIPLIED;
#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;
}
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
UniquePtr<SurfaceFactory> factory = MakeUnique<SurfaceFactory_Basic>(gl, caps, flags);
if (!factory) {
factory = MakeUnique<SurfaceFactory_Basic>(gl, caps);
}
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()
{
mFactory = nullptr;
mDraw = nullptr;
mRead = nullptr;
// bug 914823: it is crucial to destroy the Factory _after_ we destroy
// the SharedSurfaces around here! Reason: the shared surfaces will want
// to ask the Allocator (e.g. the ClientLayerManager) to destroy their
// buffers, but that Allocator may be kept alive by the Factory,
// as it currently the case in SurfaceFactory_Gralloc holding a nsRefPtr
// to the Allocator!
mFactory = nullptr;
}
void
GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
{
@ -454,7 +465,7 @@ GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size)
bool
GLScreenBuffer::Swap(const gfx::IntSize& size)
{
RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
if (!newBack)
return false;
@ -511,7 +522,7 @@ GLScreenBuffer::PublishFrame(const gfx::IntSize& size)
bool
GLScreenBuffer::Resize(const gfx::IntSize& size)
{
RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
if (!newBack)
return false;

View File

@ -24,10 +24,6 @@
#include "SurfaceTypes.h"
namespace mozilla {
namespace layers {
class SharedSurfaceTextureClient;
}
namespace gl {
class GLContext;
@ -140,8 +136,8 @@ public:
protected:
UniquePtr<SurfaceFactory> mFactory;
RefPtr<layers::SharedSurfaceTextureClient> mBack;
RefPtr<layers::SharedSurfaceTextureClient> mFront;
RefPtr<ShSurfHandle> mBack;
RefPtr<ShSurfHandle> mFront;
UniquePtr<DrawBuffer> mDraw;
UniquePtr<ReadBuffer> mRead;
@ -163,7 +159,21 @@ protected:
GLScreenBuffer(GLContext* gl,
const SurfaceCaps& caps,
UniquePtr<SurfaceFactory> factory);
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
{}
public:
virtual ~GLScreenBuffer();
@ -172,7 +182,7 @@ public:
return mFactory.get();
}
const RefPtr<layers::SharedSurfaceTextureClient>& Front() const {
ShSurfHandle* Front() const {
return mFront;
}

View File

@ -12,9 +12,6 @@
#include "nsThreadUtils.h"
#include "ScopedGLHelpers.h"
#include "SharedSurfaceGL.h"
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "mozilla/unused.h"
namespace mozilla {
namespace gl {
@ -35,9 +32,12 @@ 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_Basic> tempSurf;
tempSurf = SharedSurface_Basic::Create(gl, factory->mFormats, src->mSize,
factory->mCaps.alpha);
UniquePtr<SharedSurface_GLTexture> tempSurf;
tempSurf = SharedSurface_GLTexture::Create(gl,
gl,
factory->mFormats,
src->mSize,
factory->mCaps.alpha);
ProdCopy(src, tempSurf.get(), factory);
ProdCopy(tempSurf.get(), dest, factory);
@ -203,21 +203,20 @@ SharedSurface::SharedSurface(SharedSurfaceType type,
AttachmentType attachType,
GLContext* gl,
const gfx::IntSize& size,
bool hasAlpha,
bool canRecycle)
bool hasAlpha)
: 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()
@ -263,6 +262,8 @@ SharedSurface::PollSync_ContentThread()
return PollSync_ContentThread_Impl();
}
////////////////////////////////////////////////////////////////////////
// SurfaceFactory
@ -300,15 +301,12 @@ ChooseBufferBits(const SurfaceCaps& caps,
}
}
SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
: mType(type)
, mGL(gl)
SurfaceFactory::SurfaceFactory(GLContext* gl,
SharedSurfaceType type,
const SurfaceCaps& caps)
: mGL(gl)
, mCaps(caps)
, mAllocator(allocator)
, mFlags(flags)
, mType(type)
, mFormats(gl->ChooseGLFormats(caps))
{
ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps);
@ -316,95 +314,51 @@ SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
SurfaceFactory::~SurfaceFactory()
{
while (!mRecycleTotalPool.empty()) {
StopRecycling(*mRecycleTotalPool.begin());
while (!mScraps.Empty()) {
mScraps.Pop();
}
MOZ_RELEASE_ASSERT(mRecycleTotalPool.empty());
// If we mRecycleFreePool.clear() before StopRecycling(), we may try to recycle it,
// fail, call StopRecycling(), then return here and call it again.
mRecycleFreePool.clear();
}
TemporaryRef<layers::SharedSurfaceTextureClient>
SurfaceFactory::NewTexClient(const gfx::IntSize& size)
UniquePtr<SharedSurface>
SurfaceFactory::NewSharedSurface(const gfx::IntSize& size)
{
while (!mRecycleFreePool.empty()) {
RefPtr<layers::SharedSurfaceTextureClient> cur = mRecycleFreePool.front();
mRecycleFreePool.pop();
// Attempt to reuse an old surface.
while (!mScraps.Empty()) {
UniquePtr<SharedSurface> cur = mScraps.Pop();
if (cur->Surf()->mSize == size) {
return cur.forget();
}
if (cur->mSize == size)
return Move(cur);
StopRecycling(cur);
// Let `cur` be destroyed as it falls out of scope, if it wasn't
// moved.
}
UniquePtr<SharedSurface> surf = Move(CreateShared(size));
return CreateShared(size);
}
TemporaryRef<ShSurfHandle>
SurfaceFactory::NewShSurfHandle(const gfx::IntSize& size)
{
auto surf = NewSharedSurface(size);
if (!surf)
return nullptr;
RefPtr<layers::SharedSurfaceTextureClient> ret;
ret = new layers::SharedSurfaceTextureClient(mAllocator, mFlags, Move(surf), this);
// Before next use, wait until SharedSurface's buffer
// is no longer being used.
surf->WaitForBufferOwnership();
StartRecycling(ret);
return ret.forget();
return MakeAndAddRef<ShSurfHandle>(this, Move(surf));
}
// Auto-deletes surfs of the wrong type.
void
SurfaceFactory::StartRecycling(layers::SharedSurfaceTextureClient* tc)
SurfaceFactory::Recycle(UniquePtr<SharedSurface> surf)
{
tc->SetRecycleCallback(&SurfaceFactory::RecycleCallback, static_cast<void*>(this));
MOZ_ASSERT(surf);
bool didInsert = mRecycleTotalPool.insert(tc);
MOZ_RELEASE_ASSERT(didInsert);
mozilla::unused << didInsert;
}
void
SurfaceFactory::StopRecycling(layers::SharedSurfaceTextureClient* tc)
{
// Must clear before releasing ref.
tc->ClearRecycleCallback();
bool didErase = mRecycleTotalPool.erase(tc);
MOZ_RELEASE_ASSERT(didErase);
mozilla::unused << didErase;
}
/*static*/ void
SurfaceFactory::RecycleCallback(layers::TextureClient* rawTC, void* rawFactory)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<layers::SharedSurfaceTextureClient> tc;
tc = static_cast<layers::SharedSurfaceTextureClient*>(rawTC);
SurfaceFactory* factory = static_cast<SurfaceFactory*>(rawFactory);
if (tc->mSurf->mCanRecycle) {
if (factory->Recycle(tc))
return;
if (surf->mType == mType) {
mScraps.Push(Move(surf));
}
// Did not recover the tex client. End the (re)cycle!
factory->StopRecycling(tc);
}
bool
SurfaceFactory::Recycle(layers::SharedSurfaceTextureClient* texClient)
{
MOZ_ASSERT(texClient);
if (mRecycleFreePool.size() >= 2) {
return false;
}
RefPtr<layers::SharedSurfaceTextureClient> texClientRef = texClient;
mRecycleFreePool.push(texClientRef);
return true;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -16,7 +16,6 @@
#define SHARED_SURFACE_H_
#include <queue>
#include <set>
#include <stdint.h>
#include "GLContextTypes.h"
@ -35,15 +34,6 @@ 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;
@ -61,7 +51,6 @@ public:
GLContext* const mGL;
const gfx::IntSize mSize;
const bool mHasAlpha;
const bool mCanRecycle;
protected:
bool mIsLocked;
bool mIsProducerAcquired;
@ -72,8 +61,7 @@ protected:
AttachmentType attachType,
GLContext* gl,
const gfx::IntSize& size,
bool hasAlpha,
bool canRecycle);
bool hasAlpha);
public:
virtual ~SharedSurface() {
@ -98,8 +86,6 @@ protected:
virtual void ProducerReleaseImpl() {
Fence();
}
virtual void ProducerReadAcquireImpl() {}
virtual void ProducerReadReleaseImpl() {}
virtual void ConsumerAcquireImpl() {
WaitSync();
}
@ -116,16 +102,6 @@ public:
ProducerReleaseImpl();
mIsProducerAcquired = false;
}
void ProducerReadAcquire() {
MOZ_ASSERT(!mIsProducerAcquired);
ProducerReadAcquireImpl();
mIsProducerAcquired = true;
}
void ProducerReadRelease() {
MOZ_ASSERT(mIsProducerAcquired);
ProducerReadReleaseImpl();
mIsProducerAcquired = false;
}
void ConsumerAcquire() {
MOZ_ASSERT(!mIsConsumerAcquired);
ConsumerAcquireImpl();
@ -197,91 +173,36 @@ public:
virtual bool NeedsIndirectReads() const {
return false;
}
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) = 0;
};
template<typename T>
class RefSet
{
std::set<T*> mSet;
public:
~RefSet() {
clear();
}
auto begin() -> decltype(mSet.begin()) {
return mSet.begin();
}
void clear() {
for (auto itr = mSet.begin(); itr != mSet.end(); ++itr) {
(*itr)->Release();
}
mSet.clear();
}
bool empty() const {
return mSet.empty();
}
bool insert(T* x) {
if (mSet.insert(x).second) {
x->AddRef();
return true;
}
return false;
}
bool erase(T* x) {
if (mSet.erase(x)) {
x->Release();
return true;
}
return false;
}
};
template<typename T>
class RefQueue
class UniquePtrQueue
{
std::queue<T*> mQueue;
public:
~RefQueue() {
clear();
~UniquePtrQueue() {
MOZ_ASSERT(Empty());
}
void clear() {
while (!empty()) {
pop();
}
}
bool empty() const {
bool Empty() const {
return mQueue.empty();
}
size_t size() const {
return mQueue.size();
void Push(UniquePtr<T> up) {
T* p = up.release();
mQueue.push(p);
}
void push(T* x) {
mQueue.push(x);
x->AddRef();
}
UniquePtr<T> Pop() {
UniquePtr<T> ret;
T* front() const {
return mQueue.front();
}
if (!mQueue.empty()) {
ret.reset(mQueue.front());
mQueue.pop();
}
void pop() {
T* x = mQueue.front();
x->Release();
mQueue.pop();
return Move(ret);
}
};
@ -292,21 +213,18 @@ public:
// with SupportsWeakPtr. (bug 1049278)
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory)
const SharedSurfaceType mType;
GLContext* const mGL;
const SurfaceCaps mCaps;
const RefPtr<layers::ISurfaceAllocator> mAllocator;
const layers::TextureFlags mFlags;
const SharedSurfaceType mType;
const GLFormats mFormats;
protected:
SurfaceCaps mDrawCaps;
SurfaceCaps mReadCaps;
RefQueue<layers::SharedSurfaceTextureClient> mRecycleFreePool;
RefSet<layers::SharedSurfaceTextureClient> mRecycleTotalPool;
SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags);
SurfaceFactory(GLContext* gl,
SharedSurfaceType type,
const SurfaceCaps& caps);
public:
virtual ~SurfaceFactory();
@ -322,19 +240,44 @@ public:
protected:
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) = 0;
void StartRecycling(layers::SharedSurfaceTextureClient* tc);
void SetRecycleCallback(layers::SharedSurfaceTextureClient* tc);
void StopRecycling(layers::SharedSurfaceTextureClient* tc);
UniquePtrQueue<SharedSurface> mScraps;
public:
UniquePtr<SharedSurface> NewSharedSurface(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*/);
TemporaryRef<ShSurfHandle> NewShSurfHandle(const gfx::IntSize& size);
// Auto-deletes surfs of the wrong type.
bool Recycle(layers::SharedSurfaceTextureClient* texClient);
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();
}
};
class ScopedReadbackFB

View File

@ -4,12 +4,11 @@
* 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 {
@ -106,8 +105,7 @@ SharedSurface_ANGLEShareHandle::SharedSurface_ANGLEShareHandle(GLContext* gl,
AttachmentType::Screen,
gl,
size,
hasAlpha,
true)
hasAlpha)
, mEGL(egl)
, mContext(context)
, mPBuffer(pbuffer)
@ -184,21 +182,6 @@ SharedSurface_ANGLEShareHandle::ProducerReleaseImpl()
Fence();
}
void
SharedSurface_ANGLEShareHandle::ProducerReadAcquireImpl()
{
ProducerAcquireImpl();
}
void
SharedSurface_ANGLEShareHandle::ProducerReadReleaseImpl()
{
if (mKeyedMutex) {
mKeyedMutex->ReleaseSync(0);
return;
}
}
void
SharedSurface_ANGLEShareHandle::ConsumerAcquireImpl()
{
@ -270,16 +253,6 @@ 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
@ -415,9 +388,8 @@ ChooseConfig(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps)
}
/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
const SurfaceCaps& caps)
{
GLLibraryEGL* egl = &sEGLLibrary;
if (!egl)
@ -429,7 +401,7 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
bool success;
typedef SurfaceFactory_ANGLEShareHandle ptrT;
UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, &success) );
UniquePtr<ptrT> ret( new ptrT(gl, egl, caps, &success) );
if (!success)
return nullptr;
@ -438,12 +410,10 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
}
SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags,
GLLibraryEGL* egl,
const SurfaceCaps& caps,
bool* const out_success)
: SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags)
: SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
, mProdGL(gl)
, mEGL(egl)
{

View File

@ -38,9 +38,7 @@ protected:
GLLibraryEGL* const mEGL;
const EGLContext mContext;
const EGLSurface mPBuffer;
public:
const HANDLE mShareHandle;
protected:
RefPtr<IDXGIKeyedMutex> mKeyedMutex;
RefPtr<IDXGIKeyedMutex> mConsumerKeyedMutex;
RefPtr<ID3D11Texture2D> mConsumerTexture;
@ -68,8 +66,6 @@ public:
virtual void Fence() override;
virtual void ProducerAcquireImpl() override;
virtual void ProducerReleaseImpl() override;
virtual void ProducerReadAcquireImpl() override;
virtual void ProducerReadReleaseImpl() override;
virtual void ConsumerAcquireImpl() override;
virtual void ConsumerReleaseImpl() override;
virtual bool WaitSync() override;
@ -79,11 +75,14 @@ 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;
};
@ -99,14 +98,12 @@ protected:
public:
static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags);
const SurfaceCaps& caps);
protected:
SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags, GLLibraryEGL* egl,
SurfaceFactory_ANGLEShareHandle(GLContext* gl,
GLLibraryEGL* egl,
const SurfaceCaps& caps,
bool* const out_success);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {

View File

@ -9,7 +9,6 @@
#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"
@ -73,8 +72,7 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
AttachmentType::GLTexture,
gl,
size,
hasAlpha,
false) // Can't recycle, as mSync changes never update TextureHost.
hasAlpha)
, mMutex("SharedSurface_EGLImage mutex")
, mEGL(egl)
, mFormats(formats)
@ -117,7 +115,6 @@ SharedSurface_EGLImage::Fence()
mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
{
if (mSync) {
MOZ_RELEASE_ASSERT(false, "Non-recycleable should not Fence twice.");
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
mSync = 0;
}
@ -155,7 +152,14 @@ SharedSurface_EGLImage::WaitSync()
0,
LOCAL_EGL_FOREVER);
return status == LOCAL_EGL_CONDITION_SATISFIED;
if (status != LOCAL_EGL_CONDITION_SATISFIED) {
return false;
}
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
mSync = 0;
return true;
}
bool
@ -173,8 +177,14 @@ SharedSurface_EGLImage::PollSync()
mSync,
LOCAL_EGL_SYNC_STATUS_KHR,
&status) );
if (status != LOCAL_EGL_SIGNALED_KHR) {
return false;
}
return status == LOCAL_EGL_SIGNALED_KHR;
MOZ_ALWAYS_TRUE( mEGL->fDestroySync(mEGL->Display(), mSync) );
mSync = 0;
return true;
}
EGLDisplay
@ -205,20 +215,10 @@ 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, mHasAlpha);
return true;
}
////////////////////////////////////////////////////////////////////////
/*static*/ UniquePtr<SurfaceFactory_EGLImage>
SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
SurfaceFactory_EGLImage::Create(GLContext* prodGL,
const SurfaceCaps& caps)
{
EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
@ -227,7 +227,7 @@ SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
GLLibraryEGL* egl = &sEGLLibrary;
if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
ret.reset( new ptrT(prodGL, caps, allocator, flags, context) );
ret.reset( new ptrT(prodGL, context, caps) );
}
return Move(ret);

View File

@ -77,8 +77,6 @@ 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;
};
@ -89,20 +87,17 @@ class SurfaceFactory_EGLImage
public:
// Fallible:
static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags);
const SurfaceCaps& caps);
protected:
const EGLContext mContext;
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)
SurfaceFactory_EGLImage(GLContext* prodGL,
EGLContext context,
const SurfaceCaps& caps)
: SurfaceFactory(prodGL, SharedSurfaceType::EGLImageShare, caps)
, mContext(context)
{ }
{}
public:
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {

View File

@ -39,37 +39,40 @@ SharedSurface_Basic::Create(GLContext* gl,
return Move(ret);
}
bool ownsTex = true;
ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, tex, ownsTex) );
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.");
}
/*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) );
ret.reset( new SharedSurface_Basic(gl, size, hasAlpha, format, tex) );
return Move(ret);
}
SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
const IntSize& size,
bool hasAlpha,
GLuint tex,
bool ownsTex)
SurfaceFormat format,
GLuint tex)
: SharedSurface(SharedSurfaceType::Basic,
AttachmentType::GLTexture,
gl,
size,
hasAlpha,
true)
hasAlpha)
, mTex(tex)
, mOwnsTex(ownsTex)
, mFB(0)
{
mGL->MakeCurrent();
@ -94,16 +97,150 @@ SharedSurface_Basic::~SharedSurface_Basic()
if (mFB)
mGL->fDeleteFramebuffers(1, &mFB);
if (mOwnsTex)
mGL->fDeleteTextures(1, &mTex);
mGL->fDeleteTextures(1, &mTex);
}
////////////////////////////////////////////////////////////////////////
// SharedSurface_GLTexture
SurfaceFactory_Basic::SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::Basic, gl, caps, nullptr, flags)
{ }
/*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;
}
} /* namespace gfx */
} /* namespace mozilla */

View File

@ -38,11 +38,6 @@ 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);
@ -51,14 +46,13 @@ public:
protected:
const GLuint mTex;
const bool mOwnsTex;
GLuint mFB;
SharedSurface_Basic(GLContext* gl,
const gfx::IntSize& size,
bool hasAlpha,
GLuint tex,
bool ownsTex);
gfx::SurfaceFormat format,
GLuint tex);
public:
virtual ~SharedSurface_Basic();
@ -73,19 +67,15 @@ 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,
const layers::TextureFlags& flags);
SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps)
: SurfaceFactory(gl, SharedSurfaceType::Basic, caps)
{}
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
bool hasAlpha = mReadCaps.alpha;
@ -93,6 +83,99 @@ 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 */

View File

@ -35,10 +35,13 @@ namespace gl {
using namespace mozilla::layers;
using namespace android;
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)
SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
const SurfaceCaps& caps,
layers::TextureFlags flags,
layers::ISurfaceAllocator* allocator)
: SurfaceFactory(prodGL, SharedSurfaceType::Gralloc, caps)
, mFlags(flags)
, mAllocator(allocator)
{
MOZ_ASSERT(mAllocator);
}
@ -129,8 +132,7 @@ SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
AttachmentType::GLTexture,
prodGL,
size,
hasAlpha,
true)
hasAlpha)
, mEGL(egl)
, mSync(0)
, mAllocator(allocator)
@ -280,11 +282,5 @@ SharedSurface_Gralloc::WaitForBufferOwnership()
mTextureClient->WaitForBufferOwnership();
}
bool
SharedSurface_Gralloc::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
{
return mTextureClient->ToSurfaceDescriptor(*out_descriptor);
}
} // namespace gl
} // namespace mozilla
}

View File

@ -73,17 +73,20 @@ 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,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags);
SurfaceFactory_Gralloc(GLContext* prodGL,
const SurfaceCaps& caps,
layers::TextureFlags flags,
layers::ISurfaceAllocator* allocator);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
bool hasAlpha = mReadCaps.alpha;

View File

@ -6,9 +6,8 @@
#include "SharedSurfaceIO.h"
#include "GLContextCGL.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/gfx/MacIOSurface.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
#include "mozilla/DebugOnly.h"
#include "ScopedGLHelpers.h"
namespace mozilla {
@ -153,8 +152,7 @@ SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioS
AttachmentType::GLTexture,
gl,
size,
hasAlpha,
true)
hasAlpha)
, mIOSurf(ioSurf)
{
gl->MakeCurrent();
@ -172,29 +170,18 @@ 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,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags)
SurfaceFactory_IOSurface::Create(GLContext* gl,
const SurfaceCaps& caps)
{
gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
MacIOSurface::GetMaxHeight());
typedef SurfaceFactory_IOSurface ptrT;
UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, maxDims) );
UniquePtr<ptrT> ret( new ptrT(gl, caps, maxDims) );
return Move(ret);
}

View File

@ -16,21 +16,11 @@ 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 { }
@ -67,7 +57,13 @@ public:
return true;
}
virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
private:
SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
GLContext* gl, const gfx::IntSize& size,
bool hasAlpha);
RefPtr<MacIOSurface> mIOSurf;
GLuint mProdTex;
};
class SurfaceFactory_IOSurface : public SurfaceFactory
@ -75,19 +71,17 @@ class SurfaceFactory_IOSurface : public SurfaceFactory
public:
// Infallible.
static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags);
const SurfaceCaps& caps);
protected:
const gfx::IntSize mMaxDims;
SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps,
const RefPtr<layers::ISurfaceAllocator>& allocator,
const layers::TextureFlags& flags,
SurfaceFactory_IOSurface(GLContext* gl,
const SurfaceCaps& caps,
const gfx::IntSize& maxDims)
: SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags)
: SurfaceFactory(gl, SharedSurfaceType::IOSurface, caps)
, mMaxDims(maxDims)
{ }
{
}
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
};

View File

@ -70,6 +70,7 @@ enum class SharedSurfaceType : uint8_t {
Unknown = 0,
Basic,
GLTextureShare,
EGLImageShare,
EGLSurfaceANGLE,
DXGLInterop,

View File

@ -12,35 +12,16 @@
#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;
namespace gl {
template<typename T>
class RefSet;
template<typename T>
class RefQueue;
}
template<typename T>
class AtomicRefCountedWithFinalize
{
protected:
protected:
AtomicRefCountedWithFinalize()
: mRecycleCallback(nullptr)
, mRefCount(0)
, mMessageLoopToPostDestructionTo(nullptr)
#ifdef DEBUG
, mSpew(false)
, mManualAddRefs(0)
, mManualReleases(0)
#endif
{}
~AtomicRefCountedWithFinalize() {}
@ -55,69 +36,14 @@ protected:
delete ptr;
}
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;
template<typename U>
friend class ::mozilla::gl::RefSet;
template<typename U>
friend class ::mozilla::gl::RefQueue;
//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:
public:
void AddRef() {
MOZ_ASSERT(mRefCount >= 0, "AddRef() during/after Finalize()/dtor.");
MOZ_ASSERT(mRefCount >= 0);
++mRefCount;
}
void Release() {
MOZ_ASSERT(mRefCount > 0, "Release() during/after Finalize()/dtor.");
MOZ_ASSERT(mRefCount > 0);
// Read mRecycleCallback early so that it does not get set to
// deleted memory, if the object is goes away.
RecycleCallback recycleCallback = mRecycleCallback;
@ -126,7 +52,6 @@ private:
// Recycle listeners must call ClearRecycleCallback
// before releasing their strong reference.
MOZ_ASSERT(mRecycleCallback == nullptr);
MOZ_ASSERT(mManualAddRefs == mManualReleases);
#ifdef DEBUG
mRefCount = detail::DEAD;
#endif
@ -149,7 +74,6 @@ private:
}
}
public:
typedef void (*RecycleCallback)(T* aObject, void* aClosure);
/**
* Set a callback responsible for recycling this object
@ -172,15 +96,8 @@ 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

View File

@ -3,9 +3,8 @@
* 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 "CopyableCanvasLayer.h"
#include "BasicLayersImpl.h" // for FillWithMask, etc
#include "CopyableCanvasLayer.h"
#include "GLContext.h" // for GLContext
#include "GLScreenBuffer.h" // for GLScreenBuffer
#include "SharedSurface.h" // for SharedSurface
@ -22,7 +21,6 @@
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsSize.h" // for nsIntSize
#include "gfxUtils.h"
#include "client/TextureClientSharedSurface.h"
namespace mozilla {
namespace layers {
@ -58,8 +56,11 @@ CopyableCanvasLayer::Initialize(const Data& aData)
if (aData.mFrontbufferGLTex) {
gfx::IntSize size(aData.mSize.width, aData.mSize.height);
mGLFrontbuffer = SharedSurface_Basic::Wrap(aData.mGLContext, size, aData.mHasAlpha,
aData.mFrontbufferGLTex);
mGLFrontbuffer = SharedSurface_GLTexture::Create(aData.mGLContext,
nullptr,
aData.mGLContext->GetGLFormats(),
size, aData.mHasAlpha,
aData.mFrontbufferGLTex);
}
} else if (aData.mDrawTarget) {
mDrawTarget = aData.mDrawTarget;
@ -107,7 +108,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
frontbuffer = mGLFrontbuffer.get();
} else {
GLScreenBuffer* screen = mGLContext->Screen();
const auto& front = screen->Front();
ShSurfHandle* front = screen->Front();
if (front) {
frontbuffer = front->Surf();
}
@ -136,7 +137,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;

View File

@ -39,7 +39,7 @@ MacIOSurfaceTextureHostBasic::MacIOSurfaceTextureHostBasic(
)
: TextureHost(aFlags)
{
mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
aDescriptor.scaleFactor(),
!aDescriptor.isOpaque());
}

View File

@ -22,7 +22,9 @@
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsDebug.h" // for printf_stderr, NS_ASSERTION
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "TextureClientSharedSurface.h"
#ifdef MOZ_WIDGET_GONK
#include "SharedSurfaceGralloc.h"
#endif
using namespace mozilla::gfx;
using namespace mozilla::gl;
@ -35,6 +37,13 @@ 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 MakeAndAddRef<CanvasClient2D>(aForwarder, aFlags);
}
#endif
switch (aType) {
case CanvasClientTypeShSurf:
return MakeAndAddRef<CanvasClientSharedSurface>(aForwarder, aFlags);
@ -140,11 +149,28 @@ CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
TextureFlags aFlags)
: CanvasClient(aLayerForwarder, aFlags)
{ }
CanvasClientSharedSurface::~CanvasClientSharedSurface()
{
ClearSurfaces();
}
////////////////////////////////////////
// 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 MakeAndAddRef<SharedSurfaceTextureClient>(aAllocator, flags, surf);
}
}
////////////////////////////////////////
@ -304,92 +330,91 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
////////////////////////////////////////
static TemporaryRef<SharedSurfaceTextureClient>
static TemporaryRef<gl::ShSurfHandle>
CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
{
RefPtr<SharedSurfaceTextureClient> dest = factory->NewTexClient(src->mSize);
RefPtr<gl::ShSurfHandle> dest = factory->NewShSurfHandle(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) {
mShSurfClient = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
if (!mShSurfClient) {
gfxCriticalError() << "Invalid canvas front buffer";
return;
}
mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
if (mFront)
mFront->Surf()->Fence();
} else {
mShSurfClient = gl->Screen()->Front();
if (!mShSurfClient) {
return;
}
mFront = gl->Screen()->Front();
}
MOZ_ASSERT(mShSurfClient);
newFront = mShSurfClient;
SharedSurface* surf = mShSurfClient->Surf();
// Readback if needed.
mReadbackClient = nullptr;
auto forwarder = GetForwarder();
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);
newFront = mReadbackClient;
} else {
mReadbackClient = nullptr;
}
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;
if (!mFront) {
gfxCriticalError() << "Invalid canvas front buffer";
return;
}
if (mFront) {
if (mFront->GetFlags() & TextureFlags::RECYCLE) {
mFront->WaitForCompositorRecycle();
}
// 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) {
auto manager = aLayer->ClientManager();
auto shadowForwarder = manager->AsShadowForwarder();
auto layersBackend = shadowForwarder->GetCompositorBackendType();
newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend);
}
mFront = newFront;
if (!newTex) {
// May happen in a release build in case of memory pressure.
gfxCriticalError() << "Failed to allocate a TextureClient for SharedSurface Canvas. size: " << aSize;
return;
}
// Add the new TexClient.
MOZ_ALWAYS_TRUE( AddTextureClient(mFront) );
MOZ_ALWAYS_TRUE( AddTextureClient(newTex) );
forwarder->UseTexture(this, mFront);
// 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;
}
// Use the new TexClient.
mFrontTex = newTex;
forwarder->UseTexture(this, mFrontTex);
}
void
CanvasClientSharedSurface::ClearSurfaces()
{
mFrontTex = nullptr;
// It is important to destroy the SharedSurface *after* the TextureClient.
mFront = nullptr;
mShSurfClient = nullptr;
mReadbackClient = nullptr;
mPrevFront = nullptr;
}
} // namespace layers
} // namespace mozilla
}
}

View File

@ -18,12 +18,18 @@
#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.
@ -108,9 +114,10 @@ private:
class CanvasClientSharedSurface : public CanvasClient
{
private:
RefPtr<SharedSurfaceTextureClient> mShSurfClient;
RefPtr<TextureClient> mReadbackClient;
RefPtr<TextureClient> mFront;
RefPtr<gl::ShSurfHandle> mFront;
RefPtr<gl::ShSurfHandle> mPrevFront;
RefPtr<TextureClient> mFrontTex;
void ClearSurfaces();
@ -118,7 +125,10 @@ public:
CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
TextureFlags aFlags);
~CanvasClientSharedSurface();
~CanvasClientSharedSurface()
{
ClearSurfaces();
}
virtual TextureInfo GetTextureInfo() const override {
return TextureInfo(CompositableType::IMAGE);

View File

@ -70,40 +70,48 @@ 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 (forwarder->GetCompositorBackendType()) {
switch (ClientManager()->AsShadowForwarder()->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) {
bool isCrossProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
if (!isCrossProcess) {
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder,
mFlags);
#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);
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!");
}
}
#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
}
break;
}
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
#ifdef XP_WIN
if (mGLContext->IsANGLE() &&
DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device()))
{
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps, forwarder,
mFlags);
if (mGLContext->IsANGLE() && DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) {
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
}
#endif
break;
@ -119,7 +127,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, mFlags);
mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
}
} else {
if (factory)

View File

@ -6,7 +6,7 @@
#ifndef GFX_CLIENTCANVASLAYER_H
#define GFX_CLIENTCANVASLAYER_H
#include "CanvasClient.h" // for CanvasClient, etc
#include "mozilla/layers/CanvasClient.h" // for CanvasClient, etc
#include "ClientLayerManager.h" // for ClientLayerManager, etc
#include "CopyableCanvasLayer.h" // for CopyableCanvasLayer
#include "Layers.h" // for CanvasLayer, etc
@ -21,6 +21,7 @@
namespace mozilla {
namespace gl {
class SharedSurface;
class SurfaceFactory;
}
@ -80,9 +81,6 @@ public:
{
return mCanvasClient;
}
const TextureFlags& Flags() const { return mFlags; }
protected:
ClientLayerManager* ClientManager()
{
@ -95,8 +93,6 @@ protected:
UniquePtr<gl::SurfaceFactory> mFactory;
TextureFlags mFlags;
friend class DeprecatedCanvasClient2D;
friend class CanvasClient2D;
friend class CanvasClientSharedSurface;

View File

@ -20,6 +20,8 @@
#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
@ -111,7 +113,7 @@ public:
bool RecvCompositorRecycle() override
{
RECYCLE_LOG("[CLIENT] Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
mWaitForRecycle = nullptr;
return true;
}
@ -119,7 +121,7 @@ public:
void WaitForCompositorRecycle()
{
mWaitForRecycle = mTextureClient;
RECYCLE_LOG("[CLIENT] Wait for recycle %p\n", mWaitForRecycle.get());
RECYCLE_LOG("Wait for recycle %p\n", mWaitForRecycle.get());
SendClientRecycle();
}
@ -585,10 +587,6 @@ 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);
@ -917,6 +915,32 @@ 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)
{

View File

@ -8,6 +8,7 @@
#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
@ -31,6 +32,10 @@
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.
@ -471,7 +476,7 @@ public:
virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
mReadbackSink = aReadbackSink;
}
virtual void SyncWithObject(SyncObject* aSyncObject) { }
private:
@ -685,6 +690,66 @@ 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;

View File

@ -1,45 +0,0 @@
/* -*- 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))
{ }
SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
{
// Free the ShSurf implicitly.
}
gfx::IntSize
SharedSurfaceTextureClient::GetSize() const
{
return mSurf->mSize;
}
bool
SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
return mSurf->ToSurfaceDescriptor(&aOutDescriptor);
}
} // namespace layers
} // namespace mozilla

View File

@ -1,75 +0,0 @@
/* -*- 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;
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();
}
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_TEXTURECLIENT_SHAREDSURFACE_H

View File

@ -25,6 +25,7 @@ namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
using namespace mozilla::gl;
FPSCounter::FPSCounter(const char* aName)
: mWriteIndex(0)
@ -395,7 +396,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);
}
}

View File

@ -34,7 +34,8 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo)
{}
ImageHost::~ImageHost()
{}
{
}
void
ImageHost::UseTextureHost(TextureHost* aTexture)

View File

@ -22,6 +22,9 @@
#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"
@ -32,6 +35,7 @@
#ifdef MOZ_WIDGET_GONK
#include "../opengl/GrallocTextureClient.h"
#include "../opengl/GrallocTextureHost.h"
#include "SharedSurfaceGralloc.h"
#endif
#ifdef MOZ_X11
@ -39,10 +43,12 @@
#endif
#ifdef XP_MACOSX
#include "SharedSurfaceIO.h"
#include "../opengl/MacIOSurfaceTextureHostOGL.h"
#endif
#ifdef XP_WIN
#include "SharedSurfaceANGLE.h"
#include "mozilla/layers/TextureDIB.h"
#endif
@ -90,8 +96,6 @@ public:
RefPtr<TextureHost> mTextureHost;
};
////////////////////////////////////////////////////////////////////////////////
// static
PTextureParent*
TextureHost::CreateIPDLActor(CompositableParentManager* aManager,
@ -213,6 +217,9 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TSurfaceTextureDescriptor:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSharedSurfaceDescriptor:
return MakeAndAddRef<SharedSurfaceTextureHost>(aFlags, aDesc.get_SharedSurfaceDescriptor());
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
@ -861,6 +868,153 @@ 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

View File

@ -31,6 +31,9 @@
#include "mozilla/gfx/Rect.h"
namespace mozilla {
namespace gl {
class SharedSurface;
}
namespace ipc {
class Shmem;
}
@ -40,6 +43,7 @@ namespace layers {
class Compositor;
class CompositableParentManager;
class SurfaceDescriptor;
class SharedSurfaceDescriptor;
class ISurfaceAllocator;
class TextureHostOGL;
class TextureSourceOGL;
@ -675,6 +679,64 @@ 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:

View File

@ -351,7 +351,7 @@ void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient)
static void ReleaseTextureClientNow(TextureClient* aClient)
{
MOZ_ASSERT(InImageBridgeChildThread());
RELEASE_MANUALLY(aClient);
aClient->Release();
}
// 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);
RELEASE_MANUALLY(aClient);
aClient->Release();
return;
}

View File

@ -206,7 +206,7 @@ bool ImageBridgeParent::RecvWillStop()
static void
ReleaseImageBridgeParent(ImageBridgeParent* aImageBridgeParent)
{
RELEASE_MANUALLY(aImageBridgeParent);
aImageBridgeParent->Release();
}
bool ImageBridgeParent::RecvStop()
@ -218,7 +218,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_MANUALLY(this);
AddRef();
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableFunction(&ReleaseImageBridgeParent, this));

View File

@ -162,12 +162,12 @@ protected:
void AddIPDLReference() {
MOZ_ASSERT(mIPCOpen == false);
mIPCOpen = true;
ADDREF_MANUALLY(this);
AddRef();
}
void ReleaseIPDLReference() {
MOZ_ASSERT(mIPCOpen == true);
mIPCOpen = false;
RELEASE_MANUALLY(this);
Release();
}
friend class CompositorParent;
friend class CrossProcessCompositorParent;

View File

@ -65,7 +65,7 @@ struct SurfaceDescriptorDXGIYCbCr {
};
struct SurfaceDescriptorMacIOSurface {
uint32_t surfaceId;
uint32_t surface;
double scaleFactor;
bool isOpaque;
};
@ -79,7 +79,6 @@ struct EGLImageDescriptor {
uintptr_t image; // `EGLImage` is a `void*`.
uintptr_t fence;
IntSize size;
bool hasAlpha;
};
struct NewSurfaceDescriptorGralloc {
@ -93,6 +92,10 @@ struct NewSurfaceDescriptorGralloc {
bool isOpaque;
};
struct SharedSurfaceDescriptor {
uintptr_t surf;
};
/**
* Used for shmem-backed YCbCr and (flavors of) RGBA textures
*/
@ -104,7 +107,7 @@ struct SurfaceDescriptorShmem {
/**
* Used for "raw memory"-backed YCbCr and (flavors of) RGBA textures
*/
struct SurfaceDescriptorMemory {
struct SurfaceDescriptorMemory {
uintptr_t data;
SurfaceFormat format;
};
@ -122,6 +125,7 @@ union SurfaceDescriptor {
EGLImageDescriptor;
SurfaceDescriptorMacIOSurface;
NewSurfaceDescriptorGralloc;
SharedSurfaceDescriptor;
null_t;
};

View File

@ -37,10 +37,7 @@ SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
if (mCompositable->GetAsyncID() != 0 &&
!InImageBridgeChildThread()) {
ADDREF_MANUALLY(mTextureClient);
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
mTextureClient = nullptr;
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take());
ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
}
}

View File

@ -69,10 +69,7 @@ SharedRGBImage::~SharedRGBImage()
if (mCompositable->GetAsyncID() != 0 &&
!InImageBridgeChildThread()) {
ADDREF_MANUALLY(mTextureClient);
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
mTextureClient = nullptr;
ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().take());
ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().take());
}
}

View File

@ -118,7 +118,6 @@ EXPORTS.mozilla.layers += [
'client/TextureClient.h',
'client/TextureClientPool.h',
'client/TextureClientRecycleAllocator.h',
'client/TextureClientSharedSurface.h',
'client/TiledContentClient.h',
'composite/AsyncCompositionManager.h',
'composite/CanvasLayerComposite.h',
@ -268,7 +267,6 @@ UNIFIED_SOURCES += [
'client/TextureClient.cpp',
'client/TextureClientPool.cpp',
'client/TextureClientRecycleAllocator.cpp',
'client/TextureClientSharedSurface.cpp',
'client/TiledContentClient.cpp',
'composite/AsyncCompositionManager.cpp',
'composite/CanvasLayerComposite.cpp',

View File

@ -19,10 +19,6 @@ class MediaBuffer;
};
namespace mozilla {
namespace gl {
class SharedSurface;
}
namespace layers {
/**

View File

@ -14,7 +14,7 @@ MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
const SurfaceDescriptorMacIOSurface& aDescriptor)
: TextureHost(aFlags)
{
mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
aDescriptor.scaleFactor(),
!aDescriptor.isOpaque());
}

View File

@ -46,9 +46,7 @@ EGLImageTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
MOZ_ASSERT(IsAllocated());
const EGLImageImage::Data* data = mImage->GetData();
const bool hasAlpha = true;
aOutDescriptor = EGLImageDescriptor((uintptr_t)data->mImage, (uintptr_t)data->mSync,
mSize, hasAlpha);
aOutDescriptor = EGLImageDescriptor((uintptr_t)data->mImage, (uintptr_t)data->mSync, mSize);
return true;
}

View File

@ -15,6 +15,10 @@
#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"
@ -22,17 +26,11 @@
#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;
@ -71,8 +69,7 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
result = new EGLImageTextureHost(aFlags,
(EGLImage)desc.image(),
(EGLSync)desc.fence(),
desc.size(),
desc.hasAlpha());
desc.size());
break;
}
@ -497,8 +494,6 @@ EGLImageTextureSource::EGLImageTextureSource(CompositorOGL* aCompositor,
, mWrapMode(aWrapMode)
, mSize(aSize)
{
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D ||
mTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL);
}
void
@ -512,12 +507,13 @@ EGLImageTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl()),
"EGLImage not supported or disabled in runtime");
GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);
GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit);
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(mTextureTarget, tex);
gl()->fEGLImageTargetTexture2D(mTextureTarget, mImage);
MOZ_ASSERT(mTextureTarget == LOCAL_GL_TEXTURE_2D);
gl()->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage);
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
}
@ -553,18 +549,18 @@ EGLImageTextureSource::GetTextureTransform()
EGLImageTextureHost::EGLImageTextureHost(TextureFlags aFlags,
EGLImage aImage,
EGLSync aSync,
gfx::IntSize aSize,
bool hasAlpha)
gfx::IntSize aSize)
: TextureHost(aFlags)
, mImage(aImage)
, mSync(aSync)
, mSize(aSize)
, mHasAlpha(hasAlpha)
, mCompositor(nullptr)
{}
{
}
EGLImageTextureHost::~EGLImageTextureHost()
{}
{
}
gl::GLContext*
EGLImageTextureHost::gl() const
@ -579,23 +575,14 @@ EGLImageTextureHost::Lock()
return false;
}
EGLint status = LOCAL_EGL_CONDITION_SATISFIED;
if (mSync) {
MOZ_ASSERT(sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
status = sEGLLibrary.fClientWaitSync(EGL_DISPLAY(), mSync, 0, LOCAL_EGL_FOREVER);
}
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 = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
: gfx::SurfaceFormat::R8G8B8X8;
GLenum target = LOCAL_GL_TEXTURE_EXTERNAL;
gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
GLenum target = LOCAL_GL_TEXTURE_2D;
GLenum wrapMode = LOCAL_GL_CLAMP_TO_EDGE;
mTextureSource = new EGLImageTextureSource(mCompositor,
mImage,

View File

@ -425,8 +425,7 @@ public:
EGLImageTextureHost(TextureFlags aFlags,
EGLImage aImage,
EGLSync aSync,
gfx::IntSize aSize,
bool hasAlpha);
gfx::IntSize aSize);
virtual ~EGLImageTextureHost();
@ -462,7 +461,6 @@ protected:
const EGLImage mImage;
const EGLSync mSync;
const gfx::IntSize mSize;
const bool mHasAlpha;
RefPtr<CompositorOGL> mCompositor;
RefPtr<EGLImageTextureSource> mTextureSource;
};