Bug 1000640 - Use new StreamTextureClient/Host with OMTC. - r=mattwoodrow

This commit is contained in:
Jeff Gilbert 2014-06-04 15:20:26 -07:00
Родитель 418da95c47
Коммит 4dfc0e7e48
27 изменённых файлов: 601 добавлений и 418 удалений

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

@ -895,7 +895,7 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
data.mGLContext = gl;
data.mSize = nsIntSize(mWidth, mHeight);
data.mHasAlpha = gl->Caps().alpha;
data.mIsGLAlphaPremult = IsPremultAlpha();
data.mIsGLAlphaPremult = IsPremultAlpha() || !data.mHasAlpha;
canvasLayer->Initialize(data);
uint32_t flags = gl->Caps().alpha ? 0 : Layer::CONTENT_OPAQUE;

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

@ -150,7 +150,7 @@ fuzzy(1,65536) fuzzy-if(B2G,256,83) fuzzy-if(Android||B2G,9,65536) random-if(And
# Test premult:
# random-if(B2G) from bug 983650
fuzzy(1,65536) random-if(gtk2Widget) random-if(B2G) fuzzy-if(Android,9,65536) random-if(Android&&AndroidVersion<15) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha wrapper.html?colors-half-alpha.png
fuzzy(1,65536) random-if(gtk2Widget) fails-if(B2G) fuzzy-if(Android,9,65536) fails-if(cocoaWidget||Android) random-if(Android&&AndroidVersion<15) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha wrapper.html?half-colors-half-alpha.png
fuzzy(1,65536) random-if(gtk2Widget) fuzzy-if(Android,9,65536) random-if(Android&&AndroidVersion<15) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha wrapper.html?half-colors-half-alpha.png
# random-if(B2G) from bug 983650
fuzzy(1,65536) random-if(B2G) fuzzy-if(Android,9,65536) random-if(Android&&AndroidVersion<15) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png

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

@ -50,6 +50,10 @@ public:
return LOCAL_GL_TEXTURE_RECTANGLE_ARB;
}
MacIOSurface* GetIOSurface() const {
return mSurface;
}
private:
SharedSurface_IOSurface(MacIOSurface* surface, GLContext* gl, const gfx::IntSize& size, bool hasAlpha);

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

@ -49,8 +49,6 @@ SurfaceCaps::Clear()
surfaceAllocator = nullptr;
}
SurfaceCaps::~SurfaceCaps()
{
}

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

@ -87,8 +87,11 @@ MOZ_BEGIN_ENUM_CLASS(TextureFlags, uint32_t)
// We've previously tried a texture and it didn't work for some reason. If there
// is a fallback available, try that.
ALLOC_FALLBACK = 1 << 17,
// Data in this texture has not been alpha-premultiplied.
NON_PREMULTIPLIED = 1 << 18,
// OR union of all valid bits
ALL_BITS = (1 << 18) - 1,
ALL_BITS = (1 << 19) - 1,
// the default flags
DEFAULT = FRONT
MOZ_END_ENUM_CLASS(TextureFlags)

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

@ -33,6 +33,7 @@ using namespace mozilla::gl;
CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
CanvasLayer(aLayerManager, aImplData)
, mStream(nullptr)
, mIsAlphaPremultiplied(true)
{
MOZ_COUNT_CTOR(CopyableCanvasLayer);
}
@ -50,7 +51,7 @@ CopyableCanvasLayer::Initialize(const Data& aData)
if (aData.mGLContext) {
mGLContext = aData.mGLContext;
mStream = aData.mStream;
mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
mIsAlphaPremultiplied = aData.mIsGLAlphaPremult;
mNeedsYFlip = true;
MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
@ -113,7 +114,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
? SurfaceFormat::B8G8R8X8
: SurfaceFormat::B8G8R8A8;
bool needsPremult = sharedSurf->HasAlpha() && !mIsGLAlphaPremult;
bool needsPremult = sharedSurf->HasAlpha() && !mIsAlphaPremultiplied;
// Try to read back directly into aDestTarget's output buffer
if (aDestTarget) {

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

@ -59,7 +59,7 @@ protected:
uint32_t mCanvasFramebuffer;
bool mIsGLAlphaPremult;
bool mIsAlphaPremultiplied;
bool mNeedsYFlip;
RefPtr<gfx::DataSourceSurface> mCachedTempSurface;

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

@ -195,7 +195,8 @@ struct EffectChain
inline TemporaryRef<TexturedEffect>
CreateTexturedEffect(gfx::SurfaceFormat aFormat,
TextureSource* aSource,
const gfx::Filter& aFilter)
const gfx::Filter& aFilter,
bool isAlphaPremultiplied)
{
MOZ_ASSERT(aSource);
RefPtr<TexturedEffect> result;
@ -205,7 +206,7 @@ CreateTexturedEffect(gfx::SurfaceFormat aFormat,
case gfx::SurfaceFormat::R8G8B8X8:
case gfx::SurfaceFormat::R5G6B5:
case gfx::SurfaceFormat::R8G8B8A8:
result = new EffectRGB(aSource, true, aFilter);
result = new EffectRGB(aSource, isAlphaPremultiplied, aFilter);
break;
case gfx::SurfaceFormat::YUV:
result = new EffectYCbCr(aSource, aFilter);
@ -227,7 +228,8 @@ CreateTexturedEffect(gfx::SurfaceFormat aFormat,
inline TemporaryRef<TexturedEffect>
CreateTexturedEffect(TextureSource* aSource,
TextureSource* aSourceOnWhite,
const gfx::Filter& aFilter)
const gfx::Filter& aFilter,
bool isAlphaPremultiplied)
{
MOZ_ASSERT(aSource);
if (aSourceOnWhite) {
@ -236,7 +238,10 @@ CreateTexturedEffect(TextureSource* aSource,
return new EffectComponentAlpha(aSource, aSourceOnWhite, aFilter);
}
return CreateTexturedEffect(aSource->GetFormat(), aSource, aFilter);
return CreateTexturedEffect(aSource->GetFormat(),
aSource,
aFilter,
isAlphaPremultiplied);
}
/**
@ -248,7 +253,7 @@ inline TemporaryRef<TexturedEffect>
CreateTexturedEffect(TextureSource *aTexture,
const gfx::Filter& aFilter)
{
return CreateTexturedEffect(aTexture, nullptr, aFilter);
return CreateTexturedEffect(aTexture, nullptr, aFilter, true);
}

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

@ -1870,7 +1870,7 @@ public:
, mTexID(0)
, mSize(0,0)
, mHasAlpha(false)
, mIsGLAlphaPremult(false)
, mIsGLAlphaPremult(true)
{ }
// One of these two must be specified for Canvas2D, but never both

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

@ -319,11 +319,25 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic();
if (texturedEffect->mPremultiplied) {
DrawSurfaceWithTextureCoords(dest, aRect,
source->GetSurface(dest),
texturedEffect->mTextureCoords,
texturedEffect->mFilter,
aOpacity, sourceMask, &maskTransform);
} else {
RefPtr<DataSourceSurface> srcData = source->GetSurface(dest)->GetDataSurface();
// Yes, we re-create the premultiplied data every time.
// This might be better with a cache, eventually.
RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData);
DrawSurfaceWithTextureCoords(dest, aRect,
premultData,
texturedEffect->mTextureCoords,
texturedEffect->mFilter,
aOpacity, sourceMask, &maskTransform);
}
break;
}
case EffectTypes::YCBCR: {

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

@ -42,8 +42,7 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
return new CanvasClient2D(aForwarder, aFlags);
}
#endif
if (aType == CanvasClientGLContext &&
aForwarder->GetCompositorBackendType() == LayersBackend::LAYERS_OPENGL) {
if (aType == CanvasClientGLContext) {
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
return new CanvasClientSurfaceStream(aForwarder, aFlags);
}
@ -190,8 +189,8 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
#endif
} else {
if (!mBuffer) {
StreamTextureClientOGL* textureClient =
new StreamTextureClientOGL(mTextureInfo.mTextureFlags);
StreamTextureClient* textureClient =
new StreamTextureClient(mTextureInfo.mTextureFlags);
textureClient->InitWith(stream);
mBuffer = textureClient;
bufferCreated = true;
@ -202,6 +201,7 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
}
if (mBuffer) {
GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
GetForwarder()->UseTexture(this, mBuffer);
}
}

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

@ -19,13 +19,19 @@
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "nsRect.h" // for nsIntRect
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "gfxPrefs.h" // for WebGLForceLayersReadback
#ifdef XP_WIN
#include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
#endif
#ifdef MOZ_WIDGET_GONK
#include "SharedSurfaceGralloc.h"
#endif
#ifdef XP_MACOSX
#include "SharedSurfaceIO.h"
#endif
#include "gfxPrefs.h" // for WebGLForceLayersReadback
using namespace mozilla::gfx;
using namespace mozilla::gl;
@ -69,7 +75,8 @@ ClientCanvasLayer::Initialize(const Data& aData)
screen->PreserveBuffer());
SurfaceFactory_GL* factory = nullptr;
if (!gfxPrefs::WebGLForceLayersReadback()) {
if (ClientManager()->AsShadowForwarder()->GetCompositorBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL) {
switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
if (mGLContext->GetContextType() == GLContextType::EGL) {
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
@ -94,6 +101,19 @@ ClientCanvasLayer::Initialize(const Data& aData)
factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps);
#endif
}
break;
}
case mozilla::layers::LayersBackend::LAYERS_D3D10:
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
#ifdef XP_WIN
if (mGLContext->IsANGLE()) {
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
}
#endif
break;
}
default:
break;
}
}
@ -151,8 +171,14 @@ ClientCanvasLayer::RenderLayer()
// and doesn't require layers to do any deallocation.
flags |= TextureFlags::DEALLOCATE_CLIENT;
}
if (!mIsAlphaPremultiplied) {
flags |= TextureFlags::NON_PREMULTIPLIED;
}
mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(),
ClientManager()->AsShadowForwarder(), flags);
ClientManager()->AsShadowForwarder(),
flags);
if (!mCanvasClient) {
return;
}

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

@ -26,6 +26,8 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/TextureClientOGL.h"
#include "mozilla/layers/PTextureChild.h"
#include "SurfaceStream.h"
#include "GLContext.h"
#ifdef XP_WIN
#include "mozilla/layers/TextureD3D9.h"
@ -676,5 +678,63 @@ BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize,
return true;
}
////////////////////////////////////////////////////////////////////////
// StreamTextureClient
StreamTextureClient::StreamTextureClient(TextureFlags aFlags)
: TextureClient(aFlags)
, mIsLocked(false)
{
}
StreamTextureClient::~StreamTextureClient()
{
// the data is owned externally.
}
bool
StreamTextureClient::Lock(OpenMode mode)
{
MOZ_ASSERT(!mIsLocked);
if (!IsValid() || !IsAllocated()) {
return false;
}
mIsLocked = true;
return true;
}
void
StreamTextureClient::Unlock()
{
MOZ_ASSERT(mIsLocked);
mIsLocked = false;
}
bool
StreamTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
if (!IsAllocated()) {
return false;
}
gfx::SurfaceStreamHandle handle = mStream->GetShareHandle();
aOutDescriptor = SurfaceStreamDescriptor(handle, false);
return true;
}
void
StreamTextureClient::InitWith(gfx::SurfaceStream* aStream)
{
MOZ_ASSERT(!IsAllocated());
mStream = aStream;
mGL = mStream->GLContext();
}
bool
StreamTextureClient::IsAllocated() const
{
return mStream != 0;
}
}
}

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

@ -31,6 +31,14 @@ class gfxReusableSurfaceWrapper;
class gfxImageSurface;
namespace mozilla {
namespace gfx {
class SurfaceStream;
}
namespace gl {
class GLContext;
}
namespace layers {
class AsyncTransactionTracker;
@ -481,6 +489,49 @@ protected:
size_t mBufSize;
};
/**
* A TextureClient implementation to share SurfaceStream.
*/
class StreamTextureClient : public TextureClient
{
public:
StreamTextureClient(TextureFlags aFlags);
~StreamTextureClient();
virtual bool IsAllocated() const MOZ_OVERRIDE;
virtual bool Lock(OpenMode mode) MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; }
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; }
void InitWith(gfx::SurfaceStream* aStream);
virtual gfx::IntSize GetSize() const { return gfx::IntSize(); }
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return gfx::SurfaceFormat::UNKNOWN;
}
virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) MOZ_OVERRIDE
{
MOZ_CRASH("Should never hit this.");
return false;
}
protected:
bool mIsLocked;
RefPtr<gfx::SurfaceStream> mStream;
RefPtr<gl::GLContext> mGL; // Just for reference holding.
};
struct TextureClientAutoUnlock
{
TextureClient* mTexture;

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

@ -239,7 +239,10 @@ static void DrawVelGraph(const nsIntRect& aClipRect,
textureSource->Update(data);
EffectChain effectChain;
effectChain.mPrimaryEffect = CreateTexturedEffect(SurfaceFormat::B8G8R8A8, textureSource, Filter::POINT);
effectChain.mPrimaryEffect = CreateTexturedEffect(SurfaceFormat::B8G8R8A8,
textureSource,
Filter::POINT,
true);
compositor->DrawQuad(graphRect,
clipRect,

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

@ -79,7 +79,7 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
return;
}
RefPtr<TexturedEffect> effect =
CreateTexturedEffect(source, sourceOnWhite, aFilter);
CreateTexturedEffect(source, sourceOnWhite, aFilter, true);
if (!effect) {
return;

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

@ -435,7 +435,10 @@ void FPSState::DrawFPS(TimeStamp aNow,
}
EffectChain effectChain;
effectChain.mPrimaryEffect = CreateTexturedEffect(SurfaceFormat::B8G8R8A8, mFPSTextureSource, Filter::POINT);
effectChain.mPrimaryEffect = CreateTexturedEffect(SurfaceFormat::B8G8R8A8,
mFPSTextureSource,
Filter::POINT,
true);
unsigned int fps = unsigned(mCompositionFps.AddFrameAndGetFps(aNow));
unsigned int txnFps = unsigned(mTransactionFps.GetFPS(aNow));

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

@ -90,9 +90,15 @@ ImageHost::Composite(EffectChain& aEffectChain,
if (!source) {
return;
}
bool isAlphaPremultiplied = true;
if (mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED)
isAlphaPremultiplied = false;
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
source,
aFilter);
aFilter,
isAlphaPremultiplied);
if (!effect) {
return;
}

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

@ -3,7 +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 "mozilla/layers/TextureHost.h"
#include "TextureHost.h"
#include "CompositableHost.h" // for CompositableHost
#include "LayersLogging.h" // for AppendToString
#include "gfx2DGlue.h" // for ToIntSize
@ -15,9 +16,6 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
#ifdef MOZ_X11
#include "mozilla/layers/X11TextureHost.h"
#endif
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "nsAString.h"
#include "nsAutoPtr.h" // for nsRefPtr
@ -25,6 +23,34 @@
#include "mozilla/layers/PTextureParent.h"
#include "mozilla/unused.h"
#include <limits>
#include "SharedSurface.h"
#include "SharedSurfaceEGL.h"
#include "SharedSurfaceGL.h"
#include "SurfaceStream.h"
#include "../opengl/CompositorOGL.h"
#ifdef MOZ_ENABLE_D3D10_LAYER
#include "../d3d11/CompositorD3D11.h"
#endif
#ifdef MOZ_WIDGET_GONK
#include "../opengl/GrallocTextureClient.h"
#include "../opengl/GrallocTextureHost.h"
#include "SharedSurfaceGralloc.h"
#endif
#ifdef MOZ_X11
#include "mozilla/layers/X11TextureHost.h"
#endif
#ifdef XP_MACOSX
#include "SharedSurfaceIO.h"
#include "../opengl/MacIOSurfaceTextureHostOGL.h"
#endif
#ifdef XP_WIN
#include "SharedSurfaceANGLE.h"
#endif
#if 0
#define RECYCLE_LOG(...) printf_stderr(__VA_ARGS__)
@ -176,16 +202,21 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
case SurfaceDescriptor::TSurfaceDescriptorShmem:
case SurfaceDescriptor::TSurfaceDescriptorMemory:
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSharedTextureDescriptor:
case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
case SurfaceDescriptor::TSurfaceStreamDescriptor:
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSurfaceStreamDescriptor:
return new StreamTextureHost(aFlags, aDesc.get_SurfaceStreamDescriptor());
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
} else {
return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
}
#ifdef MOZ_X11
case SurfaceDescriptor::TSurfaceDescriptorX11: {
const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11();
@ -193,10 +224,12 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
return result;
}
#endif
#ifdef XP_WIN
case SurfaceDescriptor::TSurfaceDescriptorD3D9:
case SurfaceDescriptor::TSurfaceDescriptorDIB:
return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
case SurfaceDescriptor::TSurfaceDescriptorD3D10:
if (Compositor::GetBackend() == LayersBackend::LAYERS_D3D9) {
return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
@ -774,5 +807,215 @@ TextureParent::ClearTextureHost()
mTextureHost = nullptr;
}
////////////////////////////////////////////////////////////////////////
// StreamTextureHost
StreamTextureHost::StreamTextureHost(TextureFlags aFlags,
const SurfaceStreamDescriptor& aDesc)
: TextureHost(aFlags)
{
mStream = gfx::SurfaceStream::FromHandle(aDesc.handle());
MOZ_ASSERT(mStream);
}
StreamTextureHost::~StreamTextureHost()
{
// If need to deallocate textures, call DeallocateSharedData() before
// the destructor
}
bool
StreamTextureHost::Lock()
{
if (!mCompositor) {
return false;
}
gfx::SharedSurface* abstractSurf = mStream->SwapConsumer();
bool compositorSupportsShSurfType = false;
switch (mCompositor->GetBackendType()) {
case LayersBackend::LAYERS_BASIC:
case LayersBackend::LAYERS_D3D9:
case LayersBackend::LAYERS_D3D10:
switch (abstractSurf->Type()) {
case gfx::SharedSurfaceType::Basic:
compositorSupportsShSurfType = true;
break;
default:
break;
}
break;
case LayersBackend::LAYERS_OPENGL:
switch (abstractSurf->Type()) {
case gfx::SharedSurfaceType::Basic:
case gfx::SharedSurfaceType::GLTextureShare:
case gfx::SharedSurfaceType::EGLImageShare:
case gfx::SharedSurfaceType::Gralloc:
case gfx::SharedSurfaceType::IOSurface:
compositorSupportsShSurfType = true;
break;
default:
break;
}
break;
case LayersBackend::LAYERS_D3D11:
switch (abstractSurf->Type()) {
case gfx::SharedSurfaceType::Basic:
case gfx::SharedSurfaceType::EGLSurfaceANGLE:
compositorSupportsShSurfType = true;
break;
default:
break;
}
break;
default:
break;
}
RefPtr<NewTextureSource> newTexSource;
if (compositorSupportsShSurfType) {
gfx::SurfaceFormat format = abstractSurf->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8
: gfx::SurfaceFormat::R8G8B8X8;
switch (abstractSurf->Type()) {
case gfx::SharedSurfaceType::Basic: {
gl::SharedSurface_Basic* surf = gl::SharedSurface_Basic::Cast(abstractSurf);
if (!this->mDataTextureSource) {
TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT;
this->mDataTextureSource = mCompositor->CreateDataTextureSource(flags);
}
this->mDataTextureSource->Update(surf->GetData());
newTexSource = mDataTextureSource;
break;
}
case gfx::SharedSurfaceType::GLTextureShare: {
gl::SharedSurface_GLTexture* surf = gl::SharedSurface_GLTexture::Cast(abstractSurf);
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
gl::GLContext* gl = compositorOGL->gl();
GLenum target = surf->ConsTextureTarget();
GLuint tex = surf->ConsTexture(gl);
newTexSource = new GLTextureSource(compositorOGL,
tex,
format,
target,
surf->Size());
break;
}
#ifdef MOZ_ENABLE_D3D10_LAYER
case gfx::SharedSurfaceType::EGLSurfaceANGLE: {
gl::SharedSurface_ANGLEShareHandle* surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf);
HANDLE shareHandle = surf->GetShareHandle();
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_D3D11);
CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(mCompositor);
ID3D11Device* d3d = compositorD3D11->GetDevice();
nsRefPtr<ID3D11Texture2D> tex;
HRESULT hr = d3d->OpenSharedResource(shareHandle,
__uuidof(ID3D11Texture2D),
getter_AddRefs(tex));
if (FAILED(hr)) {
NS_WARNING("Failed to open shared resource.");
break;
}
newTexSource = new DataTextureSourceD3D11(format, compositorD3D11, tex);
break;
}
#endif
case gfx::SharedSurfaceType::EGLImageShare: {
gl::SharedSurface_EGLImage* surf = gl::SharedSurface_EGLImage::Cast(abstractSurf);
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
gl::GLContext* gl = compositorOGL->gl();
MOZ_ASSERT(gl->IsCurrent());
GLenum target = 0;
GLuint tex = 0;
surf->AcquireConsumerTexture(gl, &tex, &target);
newTexSource = new GLTextureSource(compositorOGL,
tex,
format,
target,
surf->Size());
break;
}
#ifdef MOZ_WIDGET_GONK
case gfx::SharedSurfaceType::Gralloc: {
gl::SharedSurface_Gralloc* surf = gl::SharedSurface_Gralloc::Cast(abstractSurf);
GrallocTextureClientOGL* client = surf->GetTextureClient();
android::GraphicBuffer* graphicBuffer = client->GetGraphicBuffer().get();
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
newTexSource = new GrallocTextureSourceOGL(compositorOGL, graphicBuffer, format);
break;
}
#endif
#ifdef XP_MACOSX
case gfx::SharedSurfaceType::IOSurface: {
gl::SharedSurface_IOSurface* surf = gl::SharedSurface_IOSurface::Cast(abstractSurf);
MacIOSurface* ioSurf = surf->GetIOSurface();
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
newTexSource = new MacIOSurfaceTextureSourceOGL(compositorOGL,
ioSurf);
break;
}
#endif
default:
break;
}
} else {
// Do readback, and make a buffer view for it?
NS_WARNING("`!compositorSupportsShSurfType`.");
return false;
}
MOZ_ASSERT(newTexSource.get(), "TextureSource creation failed.");
if (!newTexSource)
return false;
mTextureSource = newTexSource;
return true;
}
void
StreamTextureHost::Unlock()
{
}
void
StreamTextureHost::SetCompositor(Compositor* aCompositor)
{
mCompositor = aCompositor;
}
gfx::SurfaceFormat
StreamTextureHost::GetFormat() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetFormat();
}
gfx::IntSize
StreamTextureHost::GetSize() const
{
MOZ_ASSERT(mTextureSource);
return mTextureSource->GetSize();
}
////////////////////////////////////////////////////////////////////////
} // namespace
} // namespace

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

@ -33,6 +33,9 @@ struct nsIntSize;
struct nsIntRect;
namespace mozilla {
namespace gfx {
class SurfaceStream;
}
namespace ipc {
class Shmem;
}
@ -44,6 +47,7 @@ class CompositableHost;
class CompositableBackendSpecificData;
class CompositableParentManager;
class SurfaceDescriptor;
class SurfaceStreamDescriptor;
class ISurfaceAllocator;
class TextureHostOGL;
class TextureSourceOGL;
@ -592,6 +596,50 @@ protected:
uint8_t* mBuffer;
};
/**
* A TextureHost for shared SurfaceStream
*/
class StreamTextureHost : public TextureHost
{
public:
StreamTextureHost(TextureFlags aFlags,
const SurfaceStreamDescriptor& aDesc);
virtual ~StreamTextureHost();
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 "StreamTextureHost"; }
#endif
protected:
Compositor* mCompositor;
gfx::SurfaceStream* mStream;
RefPtr<NewTextureSource> mTextureSource;
RefPtr<DataTextureSource> mDataTextureSource;
};
class MOZ_STACK_CLASS AutoLockTextureHost
{
public:

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

@ -360,8 +360,10 @@ TiledContentHost::RenderTile(const TileHost& aTile,
return;
}
RefPtr<TexturedEffect> effect =
CreateTexturedEffect(aTile.mTextureHost->GetFormat(), source, aFilter);
RefPtr<TexturedEffect> effect = CreateTexturedEffect(aTile.mTextureHost->GetFormat(),
source,
aFilter,
true);
if (!effect) {
return;
}

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

@ -138,6 +138,9 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
aDesc.get_SurfaceDescriptorD3D10());
break;
}
case SurfaceDescriptor::TSurfaceStreamDescriptor: {
MOZ_CRASH("Should never hit this.");
}
default: {
NS_WARNING("Unsupported SurfaceDescriptor type");
}

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

@ -8,7 +8,7 @@
#ifdef MOZ_WIDGET_GONK
#include "mozilla/layers/TextureClient.h"
#include "ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
#include "mozilla/layers/ISurfaceAllocator.h" // For IsSurfaceDescriptorValid
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
#include <ui/GraphicBuffer.h>

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

@ -84,61 +84,5 @@ SharedTextureClientOGL::IsAllocated() const
return mHandle != 0;
}
StreamTextureClientOGL::StreamTextureClientOGL(TextureFlags aFlags)
: TextureClient(aFlags)
, mIsLocked(false)
{
}
StreamTextureClientOGL::~StreamTextureClientOGL()
{
// the data is owned externally.
}
bool
StreamTextureClientOGL::Lock(OpenMode mode)
{
MOZ_ASSERT(!mIsLocked);
if (!IsValid() || !IsAllocated()) {
return false;
}
mIsLocked = true;
return true;
}
void
StreamTextureClientOGL::Unlock()
{
MOZ_ASSERT(mIsLocked);
mIsLocked = false;
}
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;
mGL = mStream->GLContext();
}
bool
StreamTextureClientOGL::IsAllocated() const
{
return mStream != 0;
}
} // namespace
} // namespace

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

@ -73,48 +73,6 @@ protected:
bool mIsLocked;
};
/**
* A TextureClient implementation to share SurfaceStream.
*/
class StreamTextureClientOGL : public TextureClient
{
public:
StreamTextureClientOGL(TextureFlags aFlags);
~StreamTextureClientOGL();
virtual bool IsAllocated() const MOZ_OVERRIDE;
virtual bool Lock(OpenMode mode) MOZ_OVERRIDE;
virtual void Unlock() MOZ_OVERRIDE;
virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; }
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; }
void InitWith(gfx::SurfaceStream* aStream);
virtual gfx::IntSize GetSize() const { return gfx::IntSize(); }
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
{
return gfx::SurfaceFormat::UNKNOWN;
}
virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) MOZ_OVERRIDE
{
return false;
}
protected:
bool mIsLocked;
RefPtr<gfx::SurfaceStream> mStream;
RefPtr<gl::GLContext> mGL;
};
} // namespace
} // namespace

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

@ -8,11 +8,6 @@
#include "GLSharedHandleHelpers.h"
#include "GLUploadHelpers.h"
#include "GLReadTexImageHelper.h"
#include "SharedSurface.h" // for SharedSurface
#include "SharedSurfaceEGL.h" // for SharedSurface_EGLImage
#include "SharedSurfaceGL.h" // for SharedSurface_GLTexture, etc
#include "SurfaceStream.h" // for SurfaceStream
#include "SurfaceTypes.h" // for SharedSurfaceType, etc
#include "gfx2DGlue.h" // for ContentForFormat, etc
#include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper
#include "mozilla/gfx/2D.h" // for DataSourceSurface
@ -75,11 +70,6 @@ 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 =
@ -425,6 +415,56 @@ SharedTextureSourceOGL::GetTextureTransform()
return handleDetails.mTextureTransform;
}
////////////////////////////////////////////////////////////////////////
// GLTextureSource
GLTextureSource::GLTextureSource(CompositorOGL* aCompositor,
GLuint aTex,
gfx::SurfaceFormat aFormat,
GLenum aTarget,
gfx::IntSize aSize)
: mSize(aSize)
, mCompositor(aCompositor)
, mTex(aTex)
, mFormat(aFormat)
, mTextureTarget(aTarget)
{
}
void
GLTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
if (!gl()) {
NS_WARNING("Trying to bind a texture without a GLContext");
return;
}
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(mTextureTarget, mTex);
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
}
void
GLTextureSource::SetCompositor(Compositor* aCompositor)
{
mCompositor = static_cast<CompositorOGL*>(aCompositor);
}
bool
GLTextureSource::IsValid() const
{
return !!gl();
}
gl::GLContext*
GLTextureSource::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
////////////////////////////////////////////////////////////////////////
// SharedTextureHostOGL
SharedTextureHostOGL::SharedTextureHostOGL(TextureFlags aFlags,
gl::SharedTextureShareType aShareType,
gl::SharedTextureHandle aSharedHandle,
@ -504,180 +544,5 @@ SharedTextureHostOGL::GetFormat() const
return mTextureSource->GetFormat();
}
void
StreamTextureSourceOGL::BindTexture(GLenum activetex, gfx::Filter aFilter)
{
MOZ_ASSERT(gl());
gl()->fActiveTexture(activetex);
gl()->fBindTexture(mTextureTarget, mTextureHandle);
SetFilter(gl(), aFilter);
}
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);
mTextureHandle = glTexSurf->ConsTexture(gl());
mTextureTarget = glTexSurf->ConsTextureTarget();
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
: SurfaceFormat::R8G8B8X8;
break;
}
case SharedSurfaceType::EGLImageShare: {
SharedSurface_EGLImage* eglImageSurf =
SharedSurface_EGLImage::Cast(sharedSurf);
eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget);
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
: SurfaceFormat::R8G8B8X8;
break;
}
#ifdef XP_MACOSX
case SharedSurfaceType::IOSurface: {
SharedSurface_IOSurface* glTexSurf = SharedSurface_IOSurface::Cast(sharedSurf);
mTextureHandle = glTexSurf->ConsTexture(gl());
mTextureTarget = glTexSurf->ConsTextureTarget();
MOZ_ASSERT(mTextureHandle);
mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8
: SurfaceFormat::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);
ClearCachedFilter();
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();
}
} // namespace
} // namespace

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

@ -318,7 +318,7 @@ public:
virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; }
// SharedTextureSource doesn't own any gl texture
virtual void DeallocateDeviceData() {}
virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
void DetachSharedHandle();
@ -389,36 +389,30 @@ protected:
};
/**
* A texture source meant for use with StreamTextureHostOGL.
* A texture source meant for use with SharedTextureHostOGL.
*
* It does not own any texture, we get texture from SurfaceStream.
* It does not own any GL texture, and attaches its shared handle to one of
* the compositor's temporary textures when binding.
*
* The shared texture handle is owned by the TextureHost.
*/
class StreamTextureSourceOGL : public NewTextureSource
class GLTextureSource : 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::SurfaceFormat::UNKNOWN)
{
MOZ_COUNT_CTOR(StreamTextureSourceOGL);
}
typedef gl::SharedTextureShareType SharedTextureShareType;
~StreamTextureSourceOGL()
{
MOZ_COUNT_DTOR(StreamTextureSourceOGL);
}
GLTextureSource(CompositorOGL* aCompositor,
GLuint aTex,
gfx::SurfaceFormat aFormat,
GLenum aTarget,
gfx::IntSize aSize);
virtual TextureSourceOGL* AsSourceOGL() { return this; }
virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE;
virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); }
virtual bool IsValid() const MOZ_OVERRIDE;
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
@ -428,66 +422,18 @@ public:
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
gl::GLContext* gl() const;
protected:
const gfx::IntSize mSize;
CompositorOGL* mCompositor;
gfx::SurfaceStream* mStream;
RefPtr<StreamTextureSourceOGL> mTextureSource;
const GLuint mTex;
const gfx::SurfaceFormat mFormat;
const GLenum mTextureTarget;
};
} // namespace