Bug 894405 - Ref GLContext before sending SurfaceStream to compositor r=jgilbert

This commit is contained in:
James Willcox 2013-07-17 13:03:18 -04:00
Родитель e858f94d27
Коммит 2fed89ee3a
6 изменённых файлов: 55 добавлений и 6 удалений

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

@ -58,6 +58,7 @@ GLScreenBuffer::Create(GLContext* gl,
SurfaceStream* stream = SurfaceStream::CreateForType(
SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
caps.preserve),
gl,
nullptr);
return new GLScreenBuffer(gl, caps, factory, stream);
@ -364,7 +365,7 @@ GLScreenBuffer::Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamTyp
if (mStream->mType == streamType)
return;
SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mStream);
SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mGL, mStream);
MOZ_ASSERT(newStream);
delete mStream;

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

@ -31,20 +31,29 @@ SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc,
}
SurfaceStream*
SurfaceStream::CreateForType(SurfaceStreamType type, SurfaceStream* prevStream)
SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glContext, SurfaceStream* prevStream)
{
SurfaceStream* result = nullptr;
switch (type) {
case SurfaceStreamType::SingleBuffer:
return new SurfaceStream_SingleBuffer(prevStream);
result = new SurfaceStream_SingleBuffer(prevStream);
break;
case SurfaceStreamType::TripleBuffer_Copy:
return new SurfaceStream_TripleBuffer_Copy(prevStream);
result = new SurfaceStream_TripleBuffer_Copy(prevStream);
break;
case SurfaceStreamType::TripleBuffer_Async:
return new SurfaceStream_TripleBuffer_Async(prevStream);
result = new SurfaceStream_TripleBuffer_Async(prevStream);
break;
case SurfaceStreamType::TripleBuffer:
return new SurfaceStream_TripleBuffer(prevStream);
result = new SurfaceStream_TripleBuffer(prevStream);
break;
default:
MOZ_CRASH("Invalid Type.");
}
result->mGLContext = glContext;
return result;
}
void

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

@ -12,6 +12,7 @@
#include "mozilla/Attributes.h"
#include "gfxPoint.h"
#include "SurfaceTypes.h"
#include "GLContext.h"
namespace mozilla {
namespace gfx {
@ -31,6 +32,7 @@ public:
bool preserveBuffer);
static SurfaceStream* CreateForType(SurfaceStreamType type,
mozilla::gl::GLContext* glContext,
SurfaceStream* prevStream = nullptr);
SurfaceStreamHandle GetShareHandle() {
@ -42,6 +44,8 @@ public:
}
const SurfaceStreamType mType;
mozilla::gl::GLContext* GLContext() const { return mGLContext; }
protected:
// |mProd| is owned by us, but can be ripped away when
// creating a new GLStream from this one.
@ -51,6 +55,10 @@ protected:
mutable Monitor mMonitor;
bool mIsAlive;
// Do not use this. It exists solely so we can ref it in CanvasClientWebGL::Update()
// before sent up to the compositor. You have been warned (Bug 894405)
mozilla::gl::GLContext* mGLContext;
// |previous| can be null, indicating this is the first one.
// Otherwise, we pull in |mProd| from |previous| an our initial surface.
SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream)

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

@ -125,6 +125,12 @@ CanvasClientWebGL::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
} else {
SurfaceStreamHandle handle = stream->GetShareHandle();
mDeprecatedTextureClient->SetDescriptor(SurfaceStreamDescriptor(handle, false));
// Bug 894405
//
// Ref this so the SurfaceStream doesn't disappear unexpectedly. The
// Compositor will need to unref it when finished.
aLayer->mGLContext->AddRef();
}
aLayer->Painted();

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

@ -922,6 +922,28 @@ SurfaceStreamHostOGL::GetAsSurface() {
return surf.forget();
}
void
SurfaceStreamHostOGL::SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator)
{
MOZ_ASSERT(!mBuffer, "Will leak the old mBuffer");
mBuffer = aBuffer;
mDeAllocator = aAllocator;
if (mBuffer && mBuffer->type() == SurfaceDescriptor::TSurfaceStreamDescriptor) {
// Bug 894405
//
// The SurfaceStream's GLContext was refed before being passed up to us, so
// we need to ensure it gets unrefed when we are finished.
const SurfaceStreamDescriptor& streamDesc =
mBuffer->get_SurfaceStreamDescriptor();
SurfaceStream* surfStream = SurfaceStream::FromHandle(streamDesc.handle());
if (surfStream) {
mStreamGL = dont_AddRef(surfStream->GLContext());
}
}
}
already_AddRefed<gfxImageSurface>
TiledDeprecatedTextureHostOGL::GetAsSurface() {
nsRefPtr<gfxImageSurface> surf = IsValid() ?

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

@ -485,6 +485,8 @@ public:
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator) MOZ_OVERRIDE;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "SurfaceStreamHostOGL"; }
#endif
@ -506,6 +508,7 @@ protected:
GLenum mTextureTarget;
GLuint mUploadTexture;
GLenum mWrapMode;
nsRefPtr<GLContext> mStreamGL;
};
class TiledDeprecatedTextureHostOGL : public DeprecatedTextureHost