Bug 893304 - Convert CanvasClient to new TextureClint/Host and replace SurfaceDescriptors with TextureClients inside SharedSurfaces. r=nical, r=snorp, r=jgilbert, r=bjacob

This commit is contained in:
Morris Tseng 2014-01-10 08:06:06 -05:00
parent 9ac72f131f
commit 2e9c7f08f9
11 changed files with 552 additions and 55 deletions

View File

@ -11,12 +11,14 @@
#include "SharedSurfaceGL.h"
#include "SurfaceFactory.h"
#include "GLLibraryEGL.h"
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/ShadowLayers.h"
#include "ui/GraphicBuffer.h"
#include "../layers/ipc/ShadowLayers.h"
#include "ScopedGLHelpers.h"
#include "gfxPlatform.h"
#include "gfx2DGlue.h"
#define DEBUG_GRALLOC
@ -72,22 +74,23 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
if (!HasExtensions(egl, prodGL))
return nullptr;
SurfaceDescriptor baseDesc;
SurfaceDescriptorGralloc desc;
gfxContentType type = hasAlpha ? GFX_CONTENT_COLOR_ALPHA
: GFX_CONTENT_COLOR;
if (!allocator->AllocSurfaceDescriptorWithCaps(size, type, USING_GL_RENDERING_ONLY, &baseDesc))
return false;
: GFX_CONTENT_COLOR;
if (baseDesc.type() != SurfaceDescriptor::TSurfaceDescriptorGralloc) {
allocator->DestroySharedSurface(&baseDesc);
return false;
gfxImageFormat format
= gfxPlatform::GetPlatform()->OptimalFormatForContent(type);
GrallocTextureClientOGL* grallocTC =
new GrallocTextureClientOGL(
allocator,
gfx::ImageFormatToSurfaceFormat(format),
TEXTURE_FLAGS_DEFAULT);
if (!grallocTC->AllocateForGLRendering(size)) {
return nullptr;
}
desc = baseDesc.get_SurfaceDescriptorGralloc();
sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(desc);
sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
EGLDisplay display = egl->Display();
EGLClientBuffer clientBuffer = buffer->getNativeBuffer();
@ -99,7 +102,7 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
LOCAL_EGL_NATIVE_BUFFER_ANDROID,
clientBuffer, attrs);
if (!image) {
allocator->DestroySharedSurface(&baseDesc);
grallocTC->DropTextureData()->DeallocateSharedData(allocator);
return nullptr;
}
@ -117,7 +120,7 @@ SharedSurface_Gralloc::Create(GLContext* prodGL,
egl->fDestroyImage(display, image);
SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, desc, prodTex);
SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, grallocTC, prodTex);
DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get());
@ -139,12 +142,6 @@ SharedSurface_Gralloc::~SharedSurface_Gralloc()
mGL->MakeCurrent();
mGL->fDeleteTextures(1, (GLuint*)&mProdTex);
SurfaceDescriptor desc(mDesc);
if (mAllocator) {
mAllocator->DestroySharedSurface(&desc);
}
}
void

View File

@ -7,13 +7,13 @@
#define SHARED_SURFACE_GRALLOC_H_
#include "SharedSurfaceGL.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/TextureClient.h"
namespace mozilla {
namespace layers {
class ISurfaceAllocator;
class SurfaceDescriptorGralloc;
}
namespace gl {
@ -39,16 +39,7 @@ public:
protected:
GLLibraryEGL* const mEGL;
RefPtr<layers::ISurfaceAllocator> mAllocator;
// We keep the SurfaceDescriptor around, because we'll end up
// using it often and it's handy to do so. The actual
// GraphicBuffer is kept alive by the sp<GraphicBuffer> in
// GrallocBufferActor; the actor will stay alive until we
// explicitly destroy this descriptor (and thus deallocate the
// actor) it in the destructor of this class. This is okay to do
// on the client, but is very bad to do on the server (because on
// the client, the actor has no chance of going away unless the
// whole app died).
layers::SurfaceDescriptorGralloc mDesc;
RefPtr<layers::TextureClient> mTextureClient;
const GLuint mProdTex;
SharedSurface_Gralloc(GLContext* prodGL,
@ -56,7 +47,7 @@ protected:
bool hasAlpha,
GLLibraryEGL* egl,
layers::ISurfaceAllocator* allocator,
layers::SurfaceDescriptorGralloc& desc,
layers::TextureClient* textureClient,
GLuint prodTex)
: SharedSurface_GL(SharedSurfaceType::Gralloc,
AttachmentType::GLTexture,
@ -65,7 +56,7 @@ protected:
hasAlpha)
, mEGL(egl)
, mAllocator(allocator)
, mDesc(desc)
, mTextureClient(textureClient)
, mProdTex(prodTex)
{}
@ -84,8 +75,8 @@ public:
return mProdTex;
}
layers::SurfaceDescriptorGralloc& GetDescriptor() {
return mDesc;
layers::TextureClient* GetTextureClient() {
return mTextureClient;
}
};

View File

@ -15,8 +15,10 @@
#include "gfxPlatform.h" // for gfxPlatform
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
#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,73 @@ 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);
GrallocTextureClientOGL* grallocTextureClient =
static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient());
// If IPDLActor is null means this TextureClient didn't AddTextureClient yet
if (!grallocTextureClient->GetIPDLActor()) {
grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags);
AddTextureClient(grallocTextureClient);
}
if (grallocTextureClient->GetIPDLActor()) {
GetForwarder()->UseTexture(this, grallocTextureClient);
}
#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()
{
@ -206,7 +269,8 @@ DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLaye
}
SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor());
//XXX todo
//mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor());
#else
printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
MOZ_ASSERT(false);

View File

@ -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,29 @@ 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
{
mBuffer = nullptr;
}
private:
RefPtr<TextureClient> mBuffer;
};
class DeprecatedCanvasClient2D : public CanvasClient
{
public:

View File

@ -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;
};
}
}

View File

@ -93,6 +93,7 @@ GrallocTextureClientOGL::GrallocTextureClientOGL(GrallocBufferActor* aActor,
gfx::IntSize aSize,
TextureFlags aFlags)
: BufferTextureClient(nullptr, gfx::FORMAT_UNKNOWN, aFlags)
, mAllocator(nullptr)
, mGrallocFlags(android::GraphicBuffer::USAGE_SW_READ_OFTEN)
, mMappedBuffer(nullptr)
{
@ -104,6 +105,18 @@ GrallocTextureClientOGL::GrallocTextureClientOGL(CompositableClient* aCompositab
gfx::SurfaceFormat aFormat,
TextureFlags aFlags)
: BufferTextureClient(aCompositable, aFormat, aFlags)
, mAllocator(nullptr)
, mGrallocFlags(android::GraphicBuffer::USAGE_SW_READ_OFTEN)
, mMappedBuffer(nullptr)
{
MOZ_COUNT_CTOR(GrallocTextureClientOGL);
}
GrallocTextureClientOGL::GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags)
: BufferTextureClient(nullptr, aFormat, aFlags)
, mAllocator(aAllocator)
, mGrallocFlags(android::GraphicBuffer::USAGE_SW_READ_OFTEN)
, mMappedBuffer(nullptr)
{
@ -119,13 +132,14 @@ GrallocTextureClientOGL::~GrallocTextureClientOGL()
if (mBufferLocked) {
mBufferLocked->Unlock();
} else {
MOZ_ASSERT(mCompositable);
// We just need to wrap the actor in a SurfaceDescriptor because that's what
// ISurfaceAllocator uses as input, we don't care about the other parameters.
SurfaceDescriptor sd = SurfaceDescriptorGralloc(nullptr, mGrallocActor,
IntSize(0, 0),
false, false);
mCompositable->GetForwarder()->DestroySharedSurface(&sd);
ISurfaceAllocator* allocator = GetAllocator();
allocator->DestroySharedSurface(&sd);
}
}
}
@ -195,8 +209,6 @@ GrallocTextureClientOGL::AllocateForSurface(gfx::IntSize aSize,
TextureAllocationFlags)
{
MOZ_ASSERT(IsValid());
MOZ_ASSERT(mCompositable);
ISurfaceAllocator* allocator = mCompositable->GetForwarder();
uint32_t format;
uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN;
@ -237,14 +249,46 @@ GrallocTextureClientOGL::AllocateForYCbCr(gfx::IntSize aYSize, gfx::IntSize aCbC
android::GraphicBuffer::USAGE_SW_READ_OFTEN);
}
bool
GrallocTextureClientOGL::AllocateForGLRendering(gfx::IntSize aSize)
{
MOZ_ASSERT(IsValid());
uint32_t format;
uint32_t usage = android::GraphicBuffer::USAGE_HW_RENDER |
android::GraphicBuffer::USAGE_HW_TEXTURE;
switch (mFormat) {
case gfx::FORMAT_R8G8B8A8:
case gfx::FORMAT_B8G8R8A8:
format = android::PIXEL_FORMAT_RGBA_8888;
break;
case gfx::FORMAT_R8G8B8X8:
case gfx::FORMAT_B8G8R8X8:
// there is no android BGRX format?
format = android::PIXEL_FORMAT_RGBX_8888;
break;
case gfx::FORMAT_R5G6B5:
format = android::PIXEL_FORMAT_RGB_565;
break;
case gfx::FORMAT_A8:
format = android::PIXEL_FORMAT_A_8;
break;
default:
NS_WARNING("Unsupported surface format");
return false;
}
return AllocateGralloc(aSize, format, usage);
}
bool
GrallocTextureClientOGL::AllocateGralloc(gfx::IntSize aSize,
uint32_t aAndroidFormat,
uint32_t aUsage)
{
MOZ_ASSERT(IsValid());
MOZ_ASSERT(mCompositable);
ISurfaceAllocator* allocator = mCompositable->GetForwarder();
ISurfaceAllocator* allocator = GetAllocator();
MaybeMagicGrallocBufferHandle handle;
PGrallocBufferChild* actor =
@ -295,6 +339,15 @@ GrallocTextureClientOGL::GetBufferSize() const
return 0;
}
ISurfaceAllocator*
GrallocTextureClientOGL::GetAllocator()
{
MOZ_ASSERT(mCompositable || mAllocator);
return mCompositable ?
mCompositable->GetForwarder() :
mAllocator;
}
} // namesapace layers
} // namesapace mozilla

View File

@ -39,6 +39,9 @@ public:
GrallocTextureClientOGL(CompositableClient* aCompositable,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
GrallocTextureClientOGL(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
~GrallocTextureClientOGL();
@ -56,6 +59,8 @@ public:
void InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize);
void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); }
gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
android::GraphicBuffer* GetGraphicBuffer()
@ -87,6 +92,8 @@ public:
gfx::IntSize aCbCrSize,
StereoMode aStereoMode) MOZ_OVERRIDE;
bool AllocateForGLRendering(gfx::IntSize aSize);
bool AllocateGralloc(gfx::IntSize aYSize, uint32_t aAndroidFormat, uint32_t aUsage);
virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
@ -96,6 +103,7 @@ public:
void SetGraphicBufferLocked(GraphicBufferLocked* aBufferLocked);
protected:
ISurfaceAllocator* GetAllocator();
/**
* Unfortunately, until bug 879681 is fixed we need to use a GrallocBufferActor.
@ -106,6 +114,8 @@ protected:
android::sp<android::GraphicBuffer> mGraphicBuffer;
RefPtr<ISurfaceAllocator> mAllocator;
/**
* Flags that are used when locking the gralloc buffer
*/

View File

@ -3,10 +3,11 @@
* 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 "mozilla/layers/TextureClientOGL.h"
#include "GLContext.h" // for GLContext, etc
#include "SurfaceStream.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureClientOGL.h"
#include "nsSize.h" // for nsIntSize
using namespace mozilla::gl;
@ -65,6 +66,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)

View File

@ -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:

View File

@ -108,6 +108,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 =
@ -463,6 +468,184 @@ 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);
DataSourceSurface* 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(ThebesIntSize(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;
}
void
StreamTextureSourceOGL::SetCompositor(Compositor* aCompositor)
{
mCompositor = static_cast<CompositorOGL*>(aCompositor);
}
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);

View File

@ -335,6 +335,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();
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
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.
*/