Bug 893304 - Convert CanvasClient to new TextureClient/Host. r=nical, r=snorp, r=jgilbert

This commit is contained in:
Morris Tseng 2013-12-13 12:45:13 -05:00
Родитель 3a7159dca8
Коммит 287ef9237a
7 изменённых файлов: 457 добавлений и 11 удалений

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

@ -17,6 +17,8 @@
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/TextureClientOGL.h"
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsDebug.h" // for printf_stderr, NS_ASSERTION
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
@ -27,12 +29,6 @@
using namespace mozilla::gfx;
using namespace mozilla::gl;
namespace mozilla {
namespace gfx {
class SharedSurface;
}
}
namespace mozilla {
namespace layers {
@ -44,7 +40,7 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
if (aType == CanvasClientGLContext &&
aForwarder->GetCompositorBackendType() == LAYERS_OPENGL) {
aFlags |= TEXTURE_DEALLOCATE_CLIENT;
return new DeprecatedCanvasClientSurfaceStream(aForwarder, aFlags);
return new CanvasClientSurfaceStream(aForwarder, aFlags);
}
if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
aFlags |= TEXTURE_DEALLOCATE_CLIENT;
@ -106,6 +102,78 @@ CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFla
mTextureInfo.mTextureFlags | aFlags);
}
CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder,
TextureFlags aFlags)
: CanvasClient(aLayerForwarder, aFlags)
{
}
void
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
{
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
SurfaceStream* stream = screen->Stream();
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
bool bufferCreated = false;
if (isCrossProcess) {
#ifdef MOZ_WIDGET_GONK
SharedSurface* surf = stream->SwapConsumer();
if (!surf) {
printf_stderr("surf is null post-SwapConsumer!\n");
return;
}
if (surf->Type() != SharedSurfaceType::Gralloc) {
printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
MOZ_ASSERT(false);
return;
}
SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
if (mBuffers.find(surf) == mBuffers.end()) {
GrallocTextureClientOGL* grallocTC =
new GrallocTextureClientOGL(static_cast<GrallocBufferActor*>(grallocSurf->GetDescriptor().bufferChild()),
grallocSurf->Size(),
mTextureInfo.mTextureFlags);
mBuffers[surf] = grallocTC;
bufferCreated = true;
}
if (bufferCreated && !AddTextureClient(mBuffers[surf])) {
mBuffers.erase(surf);
}
if (mBuffers.find(surf) != mBuffers.end()) {
GetForwarder()->UseTexture(this, mBuffers[surf]);
}
#else
printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
MOZ_ASSERT(false);
#endif
} else {
if (!mBuffer) {
StreamTextureClientOGL* textureClient =
new StreamTextureClientOGL(mTextureInfo.mTextureFlags);
textureClient->InitWith(stream);
mBuffer = textureClient;
bufferCreated = true;
}
if (bufferCreated && !AddTextureClient(mBuffer)) {
mBuffer = nullptr;
}
if (mBuffer) {
GetForwarder()->UseTexture(this, mBuffer);
}
}
aLayer->Painted();
}
void
DeprecatedCanvasClient2D::Updated()
{

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

@ -18,6 +18,12 @@
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/Types.h" // for SurfaceFormat
namespace mozilla {
namespace gfx {
class SharedSurface;
}
}
namespace mozilla {
namespace layers {
@ -95,6 +101,31 @@ private:
RefPtr<TextureClient> mBuffer;
};
// Used for GL canvases where we don't need to do any readback, i.e., with a
// GL backend.
class CanvasClientSurfaceStream : public CanvasClient
{
public:
CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder, TextureFlags aFlags);
TextureInfo GetTextureInfo() const
{
return TextureInfo(COMPOSITABLE_IMAGE);
}
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) MOZ_OVERRIDE;
virtual void OnDetach() MOZ_OVERRIDE
{
mBuffers.clear();
mBuffer = nullptr;
}
private:
std::map<gfx::SharedSurface*, RefPtr<TextureClient> > mBuffers;
RefPtr<TextureClient> mBuffer;
};
class DeprecatedCanvasClient2D : public CanvasClient
{
public:

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

@ -51,11 +51,11 @@ public:
"Can only set properties in construction phase");
CanvasLayer::SetVisibleRegion(aRegion);
}
virtual void Initialize(const Data& aData);
virtual void RenderLayer();
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
{
aAttrs = CanvasLayerAttributes(mFilter, mBounds);
@ -63,7 +63,7 @@ public:
virtual Layer* AsLayer() { return this; }
virtual ShadowableLayer* AsShadowableLayer() { return this; }
virtual void Disconnect()
{
mCanvasClient = nullptr;
@ -79,7 +79,7 @@ protected:
{
return static_cast<ClientLayerManager*>(mManager);
}
CanvasClientType GetCanvasClientType()
{
if (mGLContext) {
@ -93,6 +93,7 @@ protected:
friend class DeprecatedCanvasClient2D;
friend class CanvasClient2D;
friend class DeprecatedCanvasClientSurfaceStream;
friend class CanvasClientSurfaceStream;
};
}
}

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

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/TextureClientOGL.h"
#include "SurfaceStream.h"
#include "GLContext.h" // for GLContext, etc
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/layers/ISurfaceAllocator.h"
@ -66,6 +67,42 @@ SharedTextureClientOGL::IsAllocated() const
return mHandle != 0;
}
StreamTextureClientOGL::StreamTextureClientOGL(TextureFlags aFlags)
: TextureClient(aFlags)
, mStream(0)
{
}
StreamTextureClientOGL::~StreamTextureClientOGL()
{
// the data is owned externally.
}
bool
StreamTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
if (!IsAllocated()) {
return false;
}
gfx::SurfaceStreamHandle handle = mStream->GetShareHandle();
aOutDescriptor = SurfaceStreamDescriptor(handle, false);
return true;
}
void
StreamTextureClientOGL::InitWith(gfx::SurfaceStream* aStream)
{
MOZ_ASSERT(!IsAllocated());
mStream = aStream;
}
bool
StreamTextureClientOGL::IsAllocated() const
{
return mStream != 0;
}
DeprecatedTextureClientSharedOGL::DeprecatedTextureClientSharedOGL(CompositableForwarder* aForwarder,
const TextureInfo& aTextureInfo)
: DeprecatedTextureClient(aForwarder, aTextureInfo)

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

@ -14,6 +14,12 @@
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/TextureClient.h" // for DeprecatedTextureClient, etc
namespace mozilla {
namespace gfx {
class SurfaceStream;
}
}
namespace mozilla {
namespace layers {
@ -57,6 +63,30 @@ protected:
bool mInverted;
};
/**
* A TextureClient implementation to share SurfaceStream.
*/
class StreamTextureClientOGL : public TextureClient
{
public:
StreamTextureClientOGL(TextureFlags aFlags);
~StreamTextureClientOGL();
virtual bool IsAllocated() const MOZ_OVERRIDE;
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
virtual TextureClientData* DropTextureData() MOZ_OVERRIDE { return nullptr; }
void InitWith(gfx::SurfaceStream* aStream);
virtual gfx::IntSize GetSize() const { return gfx::IntSize(); }
protected:
gfx::SurfaceStream* mStream;
};
class DeprecatedTextureClientSharedOGL : public DeprecatedTextureClient
{
public:

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

@ -109,6 +109,11 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
desc.inverted());
break;
}
case SurfaceDescriptor::TSurfaceStreamDescriptor: {
const SurfaceStreamDescriptor& desc = aDesc.get_SurfaceStreamDescriptor();
result = new StreamTextureHostOGL(aFlags, desc);
break;
}
#ifdef XP_MACOSX
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
const SurfaceDescriptorMacIOSurface& desc =
@ -455,6 +460,178 @@ SharedTextureHostOGL::GetFormat() const
return mTextureSource->GetFormat();
}
void
StreamTextureSourceOGL::BindTexture(GLenum activetex)
{
MOZ_ASSERT(gl());
gl()->fActiveTexture(activetex);
gl()->fBindTexture(mTextureTarget, mTextureHandle);
}
bool
StreamTextureSourceOGL::RetrieveTextureFromStream()
{
gl()->MakeCurrent();
SharedSurface* sharedSurf = mStream->SwapConsumer();
if (!sharedSurf) {
// We don't have a valid surf to show yet.
return false;
}
gl()->MakeCurrent();
mSize = IntSize(sharedSurf->Size().width, sharedSurf->Size().height);
gfxImageSurface* toUpload = nullptr;
switch (sharedSurf->Type()) {
case SharedSurfaceType::GLTextureShare: {
SharedSurface_GLTexture* glTexSurf = SharedSurface_GLTexture::Cast(sharedSurf);
glTexSurf->SetConsumerGL(gl());
mTextureHandle = glTexSurf->Texture();
mTextureTarget = glTexSurf->TextureTarget();
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
: FORMAT_R8G8B8X8;
break;
}
case SharedSurfaceType::EGLImageShare: {
SharedSurface_EGLImage* eglImageSurf =
SharedSurface_EGLImage::Cast(sharedSurf);
mTextureHandle = eglImageSurf->AcquireConsumerTexture(gl());
mTextureTarget = eglImageSurf->TextureTarget();
if (!mTextureHandle) {
toUpload = eglImageSurf->GetPixels();
MOZ_ASSERT(toUpload);
} else {
mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
: FORMAT_R8G8B8X8;
}
break;
}
#ifdef XP_MACOSX
case SharedSurfaceType::IOSurface: {
SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf);
mTextureHandle = glTexSurf->Texture();
mTextureTarget = glTexSurf->TextureTarget();
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? FORMAT_R8G8B8A8
: FORMAT_R8G8B8X8;
break;
}
#endif
case SharedSurfaceType::Basic: {
toUpload = SharedSurface_Basic::Cast(sharedSurf)->GetData();
MOZ_ASSERT(toUpload);
break;
}
default:
MOZ_CRASH("Invalid SharedSurface type.");
}
if (toUpload) {
// mBounds seems to end up as (0,0,0,0) a lot, so don't use it?
nsIntSize size(toUpload->GetSize());
nsIntRect rect(nsIntPoint(0,0), size);
nsIntRegion bounds(rect);
mFormat = UploadSurfaceToTexture(gl(),
toUpload,
bounds,
mUploadTexture,
true);
mTextureHandle = mUploadTexture;
mTextureTarget = LOCAL_GL_TEXTURE_2D;
}
MOZ_ASSERT(mTextureHandle);
gl()->fBindTexture(mTextureTarget, mTextureHandle);
gl()->fTexParameteri(mTextureTarget,
LOCAL_GL_TEXTURE_WRAP_S,
LOCAL_GL_CLAMP_TO_EDGE);
gl()->fTexParameteri(mTextureTarget,
LOCAL_GL_TEXTURE_WRAP_T,
LOCAL_GL_CLAMP_TO_EDGE);
return true;
}
void
StreamTextureSourceOGL::DeallocateDeviceData()
{
if (mUploadTexture) {
MOZ_ASSERT(gl());
gl()->MakeCurrent();
gl()->fDeleteTextures(1, &mUploadTexture);
mUploadTexture = 0;
mTextureHandle = 0;
}
}
gl::GLContext*
StreamTextureSourceOGL::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
StreamTextureHostOGL::StreamTextureHostOGL(TextureFlags aFlags,
const SurfaceStreamDescriptor& aDesc)
: TextureHost(aFlags)
{
mStream = SurfaceStream::FromHandle(aDesc.handle());
MOZ_ASSERT(mStream);
}
StreamTextureHostOGL::~StreamTextureHostOGL()
{
// If need to deallocate textures, call DeallocateSharedData() before
// the destructor
}
bool
StreamTextureHostOGL::Lock()
{
if (!mCompositor) {
return false;
}
if (!mTextureSource) {
mTextureSource = new StreamTextureSourceOGL(mCompositor,
mStream);
}
return mTextureSource->RetrieveTextureFromStream();
}
void
StreamTextureHostOGL::Unlock()
{
}
void
StreamTextureHostOGL::SetCompositor(Compositor* aCompositor)
{
CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
mCompositor = glCompositor;
if (mTextureSource) {
mTextureSource->SetCompositor(glCompositor);
}
}
gfx::SurfaceFormat
StreamTextureHostOGL::GetFormat() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetFormat();
}
gfx::IntSize
StreamTextureHostOGL::GetSize() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetSize();
}
TextureImageDeprecatedTextureHostOGL::~TextureImageDeprecatedTextureHostOGL()
{
MOZ_COUNT_DTOR(TextureImageDeprecatedTextureHostOGL);

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

@ -333,6 +333,108 @@ protected:
RefPtr<SharedTextureSourceOGL> mTextureSource;
};
/**
* A texture source meant for use with StreamTextureHostOGL.
*
* It does not own any texture, we get texture from SurfaceStream.
*/
class StreamTextureSourceOGL : public NewTextureSource
, public TextureSourceOGL
{
public:
StreamTextureSourceOGL(CompositorOGL* aCompositor,
gfx::SurfaceStream* aStream)
: mCompositor(aCompositor)
, mStream(aStream)
, mTextureHandle(0)
, mTextureTarget(LOCAL_GL_TEXTURE_2D)
, mUploadTexture(0)
, mFormat(gfx::FORMAT_UNKNOWN)
{
MOZ_COUNT_CTOR(StreamTextureSourceOGL);
}
~StreamTextureSourceOGL()
{
MOZ_COUNT_DTOR(StreamTextureSourceOGL);
}
virtual TextureSourceOGL* AsSourceOGL() { return this; }
virtual void BindTexture(GLenum activetex) MOZ_OVERRIDE;
virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); }
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
virtual GLenum GetTextureTarget() const { return mTextureTarget; }
virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
virtual void DeallocateDeviceData();
bool RetrieveTextureFromStream();
void SetCompositor(CompositorOGL* aCompositor) { mCompositor = aCompositor; }
protected:
gl::GLContext* gl() const;
CompositorOGL* mCompositor;
gfx::SurfaceStream* mStream;
GLuint mTextureHandle;
GLenum mTextureTarget;
GLuint mUploadTexture;
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
};
/**
* A TextureHost for shared SurfaceStream
*/
class StreamTextureHostOGL : public TextureHost
{
public:
StreamTextureHostOGL(TextureFlags aFlags,
const SurfaceStreamDescriptor& aDesc);
virtual ~StreamTextureHostOGL();
// SharedTextureHostOGL doesn't own any GL texture
virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
virtual bool Lock() MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE
{
return mTextureSource;
}
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE
{
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "StreamTextureHostOGL"; }
#endif
protected:
CompositorOGL* mCompositor;
gfx::SurfaceStream* mStream;
RefPtr<StreamTextureSourceOGL> mTextureSource;
};
/**
* DeprecatedTextureHost implementation using a TextureImage as the underlying texture.
*/