зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1066280 - Add TexClient for ShSurf. - r=kamidphish,mattwoodrow
From a7c09c0f17e19fd2254cb1d7a8ddd07b327151ad Mon Sep 17 00:00:00 2001 --- gfx/2d/HelpersCairo.h | 2 + gfx/gl/GLContext.cpp | 3 +- gfx/gl/GLContext.h | 2 - gfx/gl/GLReadTexImageHelper.cpp | 21 +-- gfx/gl/GLReadTexImageHelper.h | 6 + gfx/gl/GLScreenBuffer.h | 6 +- gfx/gl/ScopedGLHelpers.cpp | 40 +++++ gfx/gl/ScopedGLHelpers.h | 26 ++- gfx/gl/SharedSurface.cpp | 94 +++++++++++ gfx/gl/SharedSurface.h | 19 +++ gfx/gl/SharedSurfaceIO.h | 4 + gfx/layers/CopyableCanvasLayer.cpp | 3 +- gfx/layers/client/CanvasClient.cpp | 276 +++++++++++++++++++++++++++++--- gfx/layers/client/CanvasClient.h | 34 ++++ gfx/layers/client/ClientCanvasLayer.cpp | 21 ++- gfx/layers/client/ClientCanvasLayer.h | 9 +- gfx/layers/client/TextureClient.cpp | 35 ++++ gfx/layers/client/TextureClient.h | 85 +++++++++- gfx/layers/composite/TextureHost.cpp | 131 ++++++++++++++- gfx/layers/composite/TextureHost.h | 64 ++++++++ gfx/layers/d3d10/CanvasLayerD3D10.cpp | 5 +- gfx/layers/ipc/LayersSurfaces.ipdlh | 5 + 22 files changed, 828 insertions(+), 63 deletions(-)
This commit is contained in:
Родитель
70b2daa211
Коммит
bd7ba17b6a
|
@ -141,6 +141,7 @@ GfxFormatToCairoFormat(SurfaceFormat format)
|
|||
return CAIRO_FORMAT_RGB16_565;
|
||||
default:
|
||||
gfxWarning() << "Unknown image format";
|
||||
MOZ_ASSERT(false, "Unknown image format");
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +160,7 @@ GfxFormatToCairoContent(SurfaceFormat format)
|
|||
return CAIRO_CONTENT_ALPHA;
|
||||
default:
|
||||
gfxWarning() << "Unknown image format";
|
||||
MOZ_ASSERT(false, "Unknown image format");
|
||||
return CAIRO_CONTENT_COLOR_ALPHA;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2005,8 +2005,9 @@ SharedSurface*
|
|||
GLContext::RequestFrame()
|
||||
{
|
||||
MOZ_ASSERT(mScreen);
|
||||
MOZ_CRASH("Not anymore!");
|
||||
|
||||
return mScreen->Stream()->SwapConsumer();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1576,7 +1576,6 @@ public:
|
|||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
private:
|
||||
void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
|
||||
ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
|
||||
BEFORE_GL_CALL;
|
||||
|
@ -1585,7 +1584,6 @@ private:
|
|||
mHeavyGLCallsSinceLastFlush = true;
|
||||
}
|
||||
|
||||
public:
|
||||
void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
|
||||
BeforeGLReadCall();
|
||||
|
||||
|
|
|
@ -155,16 +155,19 @@ GLReadTexImageHelper::DidGLErrorOccur(const char* str)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
bool
|
||||
GetActualReadFormats(GLContext* gl,
|
||||
GLenum destFormat, GLenum destType,
|
||||
GLenum& readFormat, GLenum& readType)
|
||||
GLenum* out_readFormat, GLenum* out_readType)
|
||||
{
|
||||
MOZ_ASSERT(out_readFormat);
|
||||
MOZ_ASSERT(out_readType);
|
||||
|
||||
if (destFormat == LOCAL_GL_RGBA &&
|
||||
destType == LOCAL_GL_UNSIGNED_BYTE)
|
||||
{
|
||||
readFormat = destFormat;
|
||||
readType = destType;
|
||||
*out_readFormat = destFormat;
|
||||
*out_readType = destType;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -197,12 +200,12 @@ GetActualReadFormats(GLContext* gl,
|
|||
}
|
||||
|
||||
if (fallback) {
|
||||
readFormat = LOCAL_GL_RGBA;
|
||||
readType = LOCAL_GL_UNSIGNED_BYTE;
|
||||
*out_readFormat = LOCAL_GL_RGBA;
|
||||
*out_readType = LOCAL_GL_UNSIGNED_BYTE;
|
||||
return false;
|
||||
} else {
|
||||
readFormat = destFormat;
|
||||
readType = destType;
|
||||
*out_readFormat = destFormat;
|
||||
*out_readType = destType;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -395,7 +398,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest)
|
|||
GLenum readType = destType;
|
||||
bool needsTempSurf = !GetActualReadFormats(gl,
|
||||
destFormat, destType,
|
||||
readFormat, readType);
|
||||
&readFormat, &readType);
|
||||
|
||||
RefPtr<DataSourceSurface> tempSurf;
|
||||
DataSourceSurface* readSurf = dest;
|
||||
|
|
|
@ -22,6 +22,12 @@ class DataSourceSurface;
|
|||
|
||||
namespace gl {
|
||||
|
||||
// Returns true if the `dest{Format,Type}` are the same as the
|
||||
// `read{Format,Type}`.
|
||||
bool GetActualReadFormats(GLContext* gl,
|
||||
GLenum destFormat, GLenum destType,
|
||||
GLenum* out_readFormat, GLenum* out_readType);
|
||||
|
||||
void ReadPixelsIntoDataSurface(GLContext* aGL,
|
||||
gfx::DataSourceSurface* aSurface);
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ namespace gl {
|
|||
|
||||
class GLContext;
|
||||
class SharedSurface;
|
||||
class ShSurfHandle;
|
||||
class SurfaceFactory;
|
||||
class SurfaceStream;
|
||||
|
||||
class DrawBuffer
|
||||
|
@ -173,8 +175,8 @@ public:
|
|||
return mFactory.get();
|
||||
}
|
||||
|
||||
SharedSurface* Front() const {
|
||||
return mFront->Surf();
|
||||
ShSurfHandle* Front() const {
|
||||
return mFront;
|
||||
}
|
||||
|
||||
SharedSurface* SharedSurf() const {
|
||||
|
|
|
@ -11,6 +11,14 @@
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
IsContextCurrent(GLContext* gl)
|
||||
{
|
||||
return gl->IsCurrent();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ScopedGLState - Wraps glEnable/glDisable. **********************************/
|
||||
|
||||
// Use |newState = true| to enable, |false| to disable.
|
||||
|
@ -483,5 +491,37 @@ ScopedGLDrawState::~ScopedGLDrawState()
|
|||
|
||||
mGL->fUseProgram(boundProgram);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ScopedPackAlignment
|
||||
|
||||
ScopedPackAlignment::ScopedPackAlignment(GLContext* gl, GLint scopedVal)
|
||||
: ScopedGLWrapper<ScopedPackAlignment>(gl)
|
||||
{
|
||||
MOZ_ASSERT(scopedVal == 1 ||
|
||||
scopedVal == 2 ||
|
||||
scopedVal == 4 ||
|
||||
scopedVal == 8);
|
||||
|
||||
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &mOldVal);
|
||||
|
||||
if (scopedVal != mOldVal) {
|
||||
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, scopedVal);
|
||||
} else {
|
||||
// Don't try to re-set it during unwrap.
|
||||
mOldVal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScopedPackAlignment::UnwrapImpl() {
|
||||
// Check that we're not falling out of scope after the current context changed.
|
||||
MOZ_ASSERT(mGL->IsCurrent());
|
||||
|
||||
if (mOldVal) {
|
||||
mGL->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, mOldVal);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -6,13 +6,18 @@
|
|||
#ifndef SCOPEDGLHELPERS_H_
|
||||
#define SCOPEDGLHELPERS_H_
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GLContext;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool IsContextCurrent(GLContext* gl);
|
||||
#endif
|
||||
|
||||
//RAII via CRTP!
|
||||
template <class Derived>
|
||||
struct ScopedGLWrapper
|
||||
|
@ -29,7 +34,7 @@ protected:
|
|||
{
|
||||
MOZ_ASSERT(&ScopedGLWrapper<Derived>::Unwrap == &Derived::Unwrap);
|
||||
MOZ_ASSERT(&Derived::UnwrapImpl);
|
||||
MOZ_ASSERT(mGL->IsCurrent());
|
||||
MOZ_ASSERT(IsContextCurrent(mGL));
|
||||
}
|
||||
|
||||
virtual ~ScopedGLWrapper() {
|
||||
|
@ -338,6 +343,21 @@ struct ScopedGLDrawState {
|
|||
GLContext* const mGL;
|
||||
GLuint packAlign;
|
||||
};
|
||||
|
||||
struct ScopedPackAlignment
|
||||
: public ScopedGLWrapper<ScopedPackAlignment>
|
||||
{
|
||||
friend struct ScopedGLWrapper<ScopedPackAlignment>;
|
||||
|
||||
protected:
|
||||
GLint mOldVal;
|
||||
|
||||
public:
|
||||
ScopedPackAlignment(GLContext* aGL, GLint scopedVal);
|
||||
|
||||
protected:
|
||||
void UnwrapImpl();
|
||||
};
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
|
|
@ -353,5 +353,99 @@ SurfaceFactory::Recycle(UniquePtr<SharedSurface> surf)
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ScopedReadbackFB
|
||||
|
||||
ScopedReadbackFB::ScopedReadbackFB(SharedSurface* src)
|
||||
: mGL(src->mGL)
|
||||
, mAutoFB(mGL)
|
||||
, mTempFB(0)
|
||||
, mTempTex(0)
|
||||
, mSurfToUnlock(nullptr)
|
||||
, mSurfToLock(nullptr)
|
||||
{
|
||||
switch (src->mAttachType) {
|
||||
case AttachmentType::GLRenderbuffer:
|
||||
{
|
||||
mGL->fGenFramebuffers(1, &mTempFB);
|
||||
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mTempFB);
|
||||
|
||||
GLuint rb = src->ProdRenderbuffer();
|
||||
mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
|
||||
LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
LOCAL_GL_RENDERBUFFER, rb);
|
||||
break;
|
||||
}
|
||||
case AttachmentType::GLTexture:
|
||||
{
|
||||
mGL->fGenFramebuffers(1, &mTempFB);
|
||||
mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mTempFB);
|
||||
|
||||
GLuint tex = src->ProdTexture();
|
||||
GLenum texImageTarget = src->ProdTextureTarget();
|
||||
mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
|
||||
LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
texImageTarget, tex, 0);
|
||||
break;
|
||||
}
|
||||
case AttachmentType::Screen:
|
||||
{
|
||||
SharedSurface* origLocked = mGL->GetLockedSurface();
|
||||
if (origLocked != src) {
|
||||
if (origLocked) {
|
||||
mSurfToLock = origLocked;
|
||||
mSurfToLock->UnlockProd();
|
||||
}
|
||||
|
||||
mSurfToUnlock = src;
|
||||
mSurfToUnlock->LockProd();
|
||||
}
|
||||
|
||||
// TODO: This should just be BindFB, but we don't have
|
||||
// the patch for this yet. (bug 1045955)
|
||||
MOZ_ASSERT(mGL->Screen());
|
||||
mGL->Screen()->BindReadFB_Internal(0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unhandled `mAttachType`.");
|
||||
}
|
||||
|
||||
if (src->NeedsIndirectReads()) {
|
||||
mGL->fGenTextures(1, &mTempTex);
|
||||
|
||||
{
|
||||
ScopedBindTexture autoTex(mGL, mTempTex);
|
||||
|
||||
GLenum format = src->mHasAlpha ? LOCAL_GL_RGBA
|
||||
: LOCAL_GL_RGB;
|
||||
auto width = src->mSize.width;
|
||||
auto height = src->mSize.height;
|
||||
mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0, format, 0, 0, width,
|
||||
height, 0);
|
||||
}
|
||||
|
||||
mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
|
||||
LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
LOCAL_GL_TEXTURE_2D, mTempTex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ScopedReadbackFB::~ScopedReadbackFB()
|
||||
{
|
||||
if (mTempFB) {
|
||||
mGL->fDeleteFramebuffers(1, &mTempFB);
|
||||
}
|
||||
if (mTempTex) {
|
||||
mGL->fDeleteTextures(1, &mTempTex);
|
||||
}
|
||||
if (mSurfToUnlock) {
|
||||
mSurfToUnlock->UnlockProd();
|
||||
}
|
||||
if (mSurfToLock) {
|
||||
mSurfToLock->LockProd();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace gfx */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SurfaceTypes.h"
|
||||
|
||||
class nsIThread;
|
||||
|
@ -127,6 +128,10 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool NeedsIndirectReads() const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -234,6 +239,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ScopedReadbackFB
|
||||
{
|
||||
GLContext* const mGL;
|
||||
ScopedBindFramebuffer mAutoFB;
|
||||
GLuint mTempFB;
|
||||
GLuint mTempTex;
|
||||
SharedSurface* mSurfToUnlock;
|
||||
SharedSurface* mSurfToLock;
|
||||
|
||||
public:
|
||||
ScopedReadbackFB(SharedSurface* src);
|
||||
~ScopedReadbackFB();
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ public:
|
|||
return mIOSurf;
|
||||
}
|
||||
|
||||
virtual bool NeedsIndirectReads() const MOZ_OVERRIDE {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
|
||||
GLContext* gl, const gfx::IntSize& size,
|
||||
|
|
|
@ -101,7 +101,8 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
|||
if (mStream) {
|
||||
sharedSurf = mStream->SwapConsumer();
|
||||
} else {
|
||||
sharedSurf = mGLContext->RequestFrame();
|
||||
auto screen = mGLContext->Screen();
|
||||
sharedSurf = screen->Front()->Surf();
|
||||
}
|
||||
|
||||
if (!sharedSurf) {
|
||||
|
|
|
@ -9,10 +9,12 @@
|
|||
#include "CompositorChild.h" // for CompositorChild
|
||||
#include "GLContext.h" // for GLContext
|
||||
#include "GLScreenBuffer.h" // for GLScreenBuffer
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SurfaceStream.h" // for SurfaceStream
|
||||
#include "SurfaceTypes.h" // for SurfaceStreamHandle
|
||||
#include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/layers/GrallocTextureClient.h"
|
||||
|
@ -43,11 +45,18 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
|
|||
return new CanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
#endif
|
||||
if (aType == CanvasClientGLContext) {
|
||||
|
||||
switch (aType) {
|
||||
case CanvasClientTypeShSurf:
|
||||
return new CanvasClientShSurf(aForwarder, aFlags);
|
||||
|
||||
case CanvasClientGLContext:
|
||||
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
|
||||
return new CanvasClientSurfaceStream(aForwarder, aFlags);
|
||||
|
||||
default:
|
||||
return new CanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
return new CanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -149,21 +158,16 @@ void
|
|||
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
aLayer->mGLContext->MakeCurrent();
|
||||
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
|
||||
SurfaceStream* stream = nullptr;
|
||||
|
||||
if (aLayer->mStream) {
|
||||
stream = aLayer->mStream;
|
||||
SurfaceStream* stream = aLayer->mStream;
|
||||
MOZ_ASSERT(stream);
|
||||
|
||||
// Copy our current surface to the current producer surface in our stream, then
|
||||
// call SwapProducer to make a new buffer ready.
|
||||
stream->CopySurfaceToProducer(aLayer->mTextureSurface.get(),
|
||||
aLayer->mFactory.get());
|
||||
stream->SwapProducer(aLayer->mFactory.get(),
|
||||
gfx::IntSize(aSize.width, aSize.height));
|
||||
} else {
|
||||
stream = screen->Stream();
|
||||
}
|
||||
// Copy our current surface to the current producer surface in our stream, then
|
||||
// call SwapProducer to make a new buffer ready.
|
||||
stream->CopySurfaceToProducer(aLayer->mTextureSurface.get(),
|
||||
aLayer->mFactory.get());
|
||||
stream->SwapProducer(aLayer->mFactory.get(),
|
||||
gfx::IntSize(aSize.width, aSize.height));
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
SharedSurface* surf = stream->SwapConsumer();
|
||||
|
@ -211,10 +215,12 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|||
} else {
|
||||
bool bufferCreated = false;
|
||||
if (!mBuffer) {
|
||||
StreamTextureClient* textureClient =
|
||||
new StreamTextureClient(mTextureInfo.mTextureFlags);
|
||||
textureClient->InitWith(stream);
|
||||
mBuffer = textureClient;
|
||||
// We need to dealloc in the client.
|
||||
TextureFlags flags = GetTextureFlags() |
|
||||
TextureFlags::DEALLOCATE_CLIENT;
|
||||
StreamTextureClient* texClient = new StreamTextureClient(flags);
|
||||
texClient->InitWith(stream);
|
||||
mBuffer = texClient;
|
||||
bufferCreated = true;
|
||||
}
|
||||
|
||||
|
@ -232,5 +238,237 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|||
aLayer->Painted();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CanvasClientShSurf::CanvasClientShSurf(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aLayerForwarder, aFlags)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// Accelerated backends
|
||||
|
||||
static TemporaryRef<TextureClient>
|
||||
TexClientFromShSurf(SharedSurface* surf, TextureFlags baseFlags)
|
||||
{
|
||||
TextureFlags flags = baseFlags | TextureFlags::DEALLOCATE_CLIENT;
|
||||
|
||||
switch (surf->mType) {
|
||||
case SharedSurfaceType::Basic:
|
||||
return nullptr;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
case SharedSurfaceType::Gralloc:
|
||||
return GrallocTextureClientOGL::FromShSurf(surf, flags);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return new ShSurfTexClient(flags, surf);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// Readback
|
||||
|
||||
// For formats compatible with R8G8B8A8.
|
||||
static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
|
||||
// [RR, GG, BB, AA]
|
||||
Swap(pixel[0], pixel[2]);
|
||||
}
|
||||
|
||||
class TexClientFactory
|
||||
{
|
||||
ISurfaceAllocator* const mAllocator;
|
||||
const bool mHasAlpha;
|
||||
const gfx::IntSize mSize;
|
||||
const gfx::BackendType mBackendType;
|
||||
const TextureFlags mBaseTexFlags;
|
||||
|
||||
public:
|
||||
TexClientFactory(ISurfaceAllocator* allocator, bool hasAlpha,
|
||||
const gfx::IntSize& size, gfx::BackendType backendType,
|
||||
TextureFlags baseTexFlags)
|
||||
: mAllocator(allocator)
|
||||
, mHasAlpha(hasAlpha)
|
||||
, mSize(size)
|
||||
, mBackendType(backendType)
|
||||
, mBaseTexFlags(baseTexFlags)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
TemporaryRef<BufferTextureClient> Create(gfx::SurfaceFormat format) {
|
||||
return TextureClient::CreateForRawBufferAccess(mAllocator, format,
|
||||
mSize, mBackendType,
|
||||
mBaseTexFlags);
|
||||
}
|
||||
|
||||
public:
|
||||
TemporaryRef<BufferTextureClient> CreateB8G8R8AX8() {
|
||||
gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
|
||||
: gfx::SurfaceFormat::B8G8R8X8;
|
||||
return Create(format);
|
||||
}
|
||||
|
||||
TemporaryRef<BufferTextureClient> CreateR8G8B8AX8() {
|
||||
// For now, assume that all RGBA formats are broken.
|
||||
RefPtr<BufferTextureClient> ret = CreateB8G8R8AX8();
|
||||
|
||||
if (ret) {
|
||||
ret->AddFlags(TextureFlags::RB_SWAPPED);
|
||||
}
|
||||
|
||||
return ret.forget();
|
||||
}
|
||||
};
|
||||
|
||||
static TemporaryRef<TextureClient>
|
||||
TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
||||
TextureFlags baseFlags, LayersBackend layersBackend)
|
||||
{
|
||||
auto backendType = gfx::BackendType::CAIRO;
|
||||
TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
|
||||
baseFlags);
|
||||
|
||||
RefPtr<BufferTextureClient> texClient;
|
||||
|
||||
{
|
||||
gl::ScopedReadbackFB autoReadback(src);
|
||||
|
||||
// We have a source FB, now we need a format.
|
||||
GLenum destFormat = LOCAL_GL_BGRA;
|
||||
GLenum destType = LOCAL_GL_UNSIGNED_BYTE;
|
||||
GLenum readFormat;
|
||||
GLenum readType;
|
||||
|
||||
// We actually don't care if they match, since we can handle
|
||||
// any read{Format,Type} we get.
|
||||
auto gl = src->mGL;
|
||||
GetActualReadFormats(gl, destFormat, destType, &readFormat, &readType);
|
||||
|
||||
MOZ_ASSERT(readFormat == LOCAL_GL_RGBA ||
|
||||
readFormat == LOCAL_GL_BGRA);
|
||||
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
|
||||
|
||||
// With a format and type, we can create texClient.
|
||||
if (readFormat == LOCAL_GL_BGRA &&
|
||||
readType == LOCAL_GL_UNSIGNED_BYTE)
|
||||
{
|
||||
// 0xAARRGGBB
|
||||
// In Lendian: [BB, GG, RR, AA]
|
||||
texClient = factory.CreateB8G8R8AX8();
|
||||
|
||||
} else if (readFormat == LOCAL_GL_RGBA &&
|
||||
readType == LOCAL_GL_UNSIGNED_BYTE)
|
||||
{
|
||||
// [RR, GG, BB, AA]
|
||||
texClient = factory.CreateR8G8B8AX8();
|
||||
} else {
|
||||
MOZ_CRASH("Bad `read{Format,Type}`.");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(texClient);
|
||||
if (!texClient)
|
||||
return nullptr;
|
||||
|
||||
// With a texClient, we can lock for writing.
|
||||
MOZ_ALWAYS_TRUE( texClient->Lock(OpenMode::OPEN_WRITE) );
|
||||
|
||||
uint8_t* lockedBytes = texClient->GetLockedData();
|
||||
|
||||
// ReadPixels from the current FB into lockedBits.
|
||||
auto width = src->mSize.width;
|
||||
auto height = src->mSize.height;
|
||||
|
||||
{
|
||||
ScopedPackAlignment autoAlign(gl, 4);
|
||||
|
||||
gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, lockedBytes);
|
||||
}
|
||||
|
||||
// RB_SWAPPED doesn't work with D3D11. (bug 1051010)
|
||||
// RB_SWAPPED doesn't work with Basic. (bug ???????)
|
||||
bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_D3D11 ||
|
||||
layersBackend == LayersBackend::LAYERS_BASIC;
|
||||
if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
|
||||
layersNeedsManualSwap)
|
||||
{
|
||||
size_t pixels = width * height;
|
||||
uint8_t* itr = lockedBytes;
|
||||
for (size_t i = 0; i < pixels; i++) {
|
||||
SwapRB_R8G8B8A8(itr);
|
||||
itr += 4;
|
||||
}
|
||||
|
||||
texClient->RemoveFlags(TextureFlags::RB_SWAPPED);
|
||||
}
|
||||
|
||||
texClient->Unlock();
|
||||
}
|
||||
|
||||
return texClient.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
void
|
||||
CanvasClientShSurf::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
aLayer->mGLContext->MakeCurrent();
|
||||
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
|
||||
|
||||
if (mFront) {
|
||||
mPrevFront = mFront;
|
||||
mFront = nullptr;
|
||||
}
|
||||
|
||||
mFront = screen->Front();
|
||||
|
||||
if (!mFront)
|
||||
return;
|
||||
|
||||
// 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(surf, flags);
|
||||
if (!newTex) {
|
||||
auto manager = aLayer->ClientManager();
|
||||
auto shadowForwarder = manager->AsShadowForwarder();
|
||||
auto layersBackend = shadowForwarder->GetCompositorBackendType();
|
||||
|
||||
newTex = TexClientFromReadback(surf, forwarder, flags, layersBackend);
|
||||
}
|
||||
MOZ_ASSERT(newTex);
|
||||
|
||||
// Add the new TexClient.
|
||||
MOZ_ALWAYS_TRUE( newTex->InitIPDLActor(forwarder) );
|
||||
MOZ_ASSERT(newTex->GetIPDLActor());
|
||||
|
||||
// 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->UpdatedTexture(this, mFrontTex, nullptr);
|
||||
forwarder->UseTexture(this, mFrontTex);
|
||||
|
||||
aLayer->Painted();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
class ShSurfHandle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
enum CanvasClientType {
|
||||
CanvasClientSurface,
|
||||
CanvasClientGLContext,
|
||||
CanvasClientTypeShSurf,
|
||||
};
|
||||
static TemporaryRef<CanvasClient> CreateCanvasClient(CanvasClientType aType,
|
||||
CompositableForwarder* aFwd,
|
||||
|
@ -138,6 +140,38 @@ private:
|
|||
RefPtr<TextureClient> mBuffer;
|
||||
};
|
||||
|
||||
// Used for GL canvases where we don't need to do any readback, i.e., with a
|
||||
// GL backend.
|
||||
class CanvasClientShSurf : public CanvasClient
|
||||
{
|
||||
private:
|
||||
RefPtr<gl::ShSurfHandle> mFront;
|
||||
RefPtr<gl::ShSurfHandle> mPrevFront;
|
||||
|
||||
RefPtr<TextureClient> mFrontTex;
|
||||
|
||||
public:
|
||||
CanvasClientShSurf(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags);
|
||||
|
||||
virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE {
|
||||
return TextureInfo(CompositableType::IMAGE);
|
||||
}
|
||||
|
||||
virtual void Clear() MOZ_OVERRIDE {
|
||||
mFront = nullptr;
|
||||
mPrevFront = nullptr;
|
||||
mFrontTex = nullptr;
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize,
|
||||
ClientCanvasLayer* aLayer) MOZ_OVERRIDE;
|
||||
|
||||
virtual void OnDetach() MOZ_OVERRIDE {
|
||||
CanvasClientShSurf::Clear();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,9 +70,6 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
}
|
||||
MOZ_ASSERT(caps.alpha == aData.mHasAlpha);
|
||||
|
||||
SurfaceStreamType streamType =
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
|
||||
screen->PreserveBuffer());
|
||||
UniquePtr<SurfaceFactory> factory;
|
||||
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
|
@ -139,7 +136,7 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory");
|
||||
}
|
||||
} else if (factory) {
|
||||
screen->Morph(Move(factory), streamType);
|
||||
screen->Morph(Move(factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +164,6 @@ ClientCanvasLayer::RenderLayer()
|
|||
if (!mGLContext) {
|
||||
// We don't support locking for buffer surfaces currently
|
||||
flags |= TextureFlags::IMMEDIATE_UPLOAD;
|
||||
} else {
|
||||
// GLContext's SurfaceStream handles ownership itself,
|
||||
// and doesn't require layers to do any deallocation.
|
||||
flags |= TextureFlags::DEALLOCATE_CLIENT;
|
||||
}
|
||||
|
||||
if (!mIsAlphaPremultiplied) {
|
||||
|
@ -199,6 +192,18 @@ ClientCanvasLayer::RenderLayer()
|
|||
mCanvasClient->OnTransaction();
|
||||
}
|
||||
|
||||
CanvasClient::CanvasClientType
|
||||
ClientCanvasLayer::GetCanvasClientType()
|
||||
{
|
||||
if (mGLContext) {
|
||||
if (mGLContext->Screen()) {
|
||||
return CanvasClient::CanvasClientTypeShSurf;
|
||||
}
|
||||
return CanvasClient::CanvasClientGLContext;
|
||||
}
|
||||
return CanvasClient::CanvasClientSurface;
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
ClientLayerManager::CreateCanvasLayer()
|
||||
{
|
||||
|
|
|
@ -91,13 +91,7 @@ protected:
|
|||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
CanvasClientType GetCanvasClientType()
|
||||
{
|
||||
if (mGLContext) {
|
||||
return CanvasClient::CanvasClientGLContext;
|
||||
}
|
||||
return CanvasClient::CanvasClientSurface;
|
||||
}
|
||||
CanvasClientType GetCanvasClientType();
|
||||
|
||||
RefPtr<CanvasClient> mCanvasClient;
|
||||
|
||||
|
@ -108,6 +102,7 @@ protected:
|
|||
friend class CanvasClient2D;
|
||||
friend class DeprecatedCanvasClientSurfaceStream;
|
||||
friend class CanvasClientSurfaceStream;
|
||||
friend class CanvasClientShSurf;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
|
@ -792,6 +793,17 @@ BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize,
|
|||
return true;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
BufferTextureClient::GetLockedData() const
|
||||
{
|
||||
MOZ_ASSERT(IsLocked());
|
||||
|
||||
ImageDataSerializer serializer(GetBuffer(), GetBufferSize());
|
||||
MOZ_ASSERT(serializer.IsValid());
|
||||
|
||||
return serializer.GetData();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// StreamTextureClient
|
||||
StreamTextureClient::StreamTextureClient(TextureFlags aFlags)
|
||||
|
@ -848,6 +860,29 @@ StreamTextureClient::IsAllocated() const
|
|||
return mStream != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ShSurfTexClient
|
||||
|
||||
ShSurfTexClient::ShSurfTexClient(TextureFlags aFlags, gl::SharedSurface* surf)
|
||||
: TextureClient(aFlags)
|
||||
, mIsLocked(false)
|
||||
, mSurf(surf)
|
||||
, mGL(mSurf->mGL)
|
||||
{
|
||||
mSurf->Fence();
|
||||
}
|
||||
|
||||
ShSurfTexClient::~ShSurfTexClient()
|
||||
{
|
||||
// the data is owned externally.
|
||||
}
|
||||
|
||||
bool
|
||||
ShSurfTexClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
aOutDescriptor = ShSurfDescriptor((uintptr_t)mSurf);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ class gfxImageSurface;
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class SharedSurface;
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
|
@ -296,6 +297,23 @@ public:
|
|||
*/
|
||||
TextureFlags GetFlags() const { return mFlags; }
|
||||
|
||||
bool HasFlags(TextureFlags aFlags) const
|
||||
{
|
||||
return (mFlags & aFlags) == aFlags;
|
||||
}
|
||||
|
||||
void AddFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
mFlags |= aFlags;
|
||||
}
|
||||
|
||||
void RemoveFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
mFlags &= ~aFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* valid only for TextureFlags::RECYCLE TextureClient.
|
||||
* When called this texture client will grab a strong reference and release
|
||||
|
@ -431,12 +449,6 @@ protected:
|
|||
*/
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
|
||||
|
||||
void AddFlags(TextureFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsSharedWithCompositor());
|
||||
mFlags |= aFlags;
|
||||
}
|
||||
|
||||
ISurfaceAllocator* GetAllocator()
|
||||
{
|
||||
return mAllocator;
|
||||
|
@ -504,6 +516,8 @@ public:
|
|||
|
||||
virtual bool IsLocked() const MOZ_OVERRIDE { return mLocked; }
|
||||
|
||||
uint8_t* GetLockedData() const;
|
||||
|
||||
virtual bool CanExposeDrawTarget() const MOZ_OVERRIDE { return true; }
|
||||
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() MOZ_OVERRIDE;
|
||||
|
@ -665,6 +679,65 @@ protected:
|
|||
RefPtr<gl::GLContext> mGL; // Just for reference holding.
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureClient implementation to share SharedSurfaces.
|
||||
*/
|
||||
class ShSurfTexClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
explicit ShSurfTexClient(TextureFlags aFlags, gl::SharedSurface* surf);
|
||||
|
||||
protected:
|
||||
~ShSurfTexClient();
|
||||
|
||||
public:
|
||||
// Boilerplate start
|
||||
virtual bool IsAllocated() const MOZ_OVERRIDE { return true; }
|
||||
|
||||
virtual bool Lock(OpenMode) MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Unlock() MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; }
|
||||
|
||||
virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_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 MOZ_OVERRIDE {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize,
|
||||
TextureAllocationFlags) MOZ_OVERRIDE {
|
||||
MOZ_CRASH("Should never hit this.");
|
||||
return false;
|
||||
}
|
||||
// Boilerplate end
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
bool mIsLocked;
|
||||
gl::SharedSurface* const mSurf;
|
||||
RefPtr<gl::GLContext> mGL; // Just for reference holding.
|
||||
};
|
||||
|
||||
struct TextureClientAutoUnlock
|
||||
{
|
||||
TextureClient* mTexture;
|
||||
|
|
|
@ -203,6 +203,9 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
|
|||
case SurfaceDescriptor::TSurfaceStreamDescriptor:
|
||||
return new StreamTextureHost(aFlags, aDesc.get_SurfaceStreamDescriptor());
|
||||
|
||||
case SurfaceDescriptor::TShSurfDescriptor:
|
||||
return new ShSurfTexHost(aFlags, aDesc.get_ShSurfDescriptor());
|
||||
|
||||
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
|
||||
if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
|
||||
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
|
||||
|
@ -997,8 +1000,134 @@ StreamTextureHost::GetSize() const
|
|||
MOZ_ASSERT(mTextureSource);
|
||||
return mTextureSource->GetSize();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
static RefPtr<NewTextureSource>
|
||||
ShSurfToTexSource(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<NewTextureSource> texSource;
|
||||
switch (abstractSurf->mType) {
|
||||
#ifdef XP_WIN
|
||||
case gl::SharedSurfaceType::EGLSurfaceANGLE: {
|
||||
auto surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf);
|
||||
HANDLE shareHandle = surf->GetShareHandle();
|
||||
|
||||
MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_D3D11);
|
||||
CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(compositor);
|
||||
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;
|
||||
}
|
||||
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, format, target,
|
||||
surf->mSize);
|
||||
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, format, target,
|
||||
surf->mSize);
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ShSurfTexHost
|
||||
|
||||
ShSurfTexHost::ShSurfTexHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc)
|
||||
: TextureHost(aFlags)
|
||||
, mIsLocked(false)
|
||||
, mSurf((gl::SharedSurface*)aDesc.surf())
|
||||
, mCompositor(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mSurf);
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
ShSurfTexHost::GetFormat() const
|
||||
{
|
||||
MOZ_ASSERT(mTexSource);
|
||||
return mTexSource->GetFormat();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
ShSurfTexHost::GetSize() const
|
||||
{
|
||||
MOZ_ASSERT(mTexSource);
|
||||
return mTexSource->GetSize();
|
||||
}
|
||||
|
||||
void
|
||||
ShSurfTexHost::EnsureTexSource()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
|
||||
if (mTexSource)
|
||||
return;
|
||||
|
||||
mSurf->WaitSync();
|
||||
mTexSource = ShSurfToTexSource(mSurf, mCompositor);
|
||||
MOZ_ASSERT(mTexSource);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
|
|
@ -35,6 +35,7 @@ struct nsIntRect;
|
|||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
class SurfaceStream;
|
||||
}
|
||||
namespace ipc {
|
||||
|
@ -49,6 +50,7 @@ class CompositableBackendSpecificData;
|
|||
class CompositableParentManager;
|
||||
class SurfaceDescriptor;
|
||||
class SurfaceStreamDescriptor;
|
||||
class ShSurfDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureHostOGL;
|
||||
class TextureSourceOGL;
|
||||
|
@ -615,6 +617,68 @@ protected:
|
|||
RefPtr<DataTextureSource> mDataTextureSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureHost for SharedSurfaces
|
||||
*/
|
||||
class ShSurfTexHost : public TextureHost
|
||||
{
|
||||
public:
|
||||
ShSurfTexHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc);
|
||||
|
||||
virtual ~ShSurfTexHost() {};
|
||||
|
||||
virtual void DeallocateDeviceData() MOZ_OVERRIDE {};
|
||||
|
||||
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
|
||||
if (aCompositor == mCompositor)
|
||||
return;
|
||||
|
||||
mTexSource = nullptr;
|
||||
mCompositor = aCompositor;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool Lock() MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
mIsLocked = true;
|
||||
EnsureTexSource();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Unlock() MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE {
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
MOZ_ASSERT(mTexSource);
|
||||
return mTexSource;
|
||||
}
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() { return "ShSurfTexHost"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void EnsureTexSource();
|
||||
|
||||
bool mIsLocked;
|
||||
gl::SharedSurface* const mSurf;
|
||||
Compositor* mCompositor;
|
||||
RefPtr<NewTextureSource> mTexSource;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoLockTextureHost
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -47,9 +47,6 @@ CanvasLayerD3D10::Initialize(const Data& aData)
|
|||
mNeedsYFlip = true;
|
||||
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
SurfaceStreamType streamType =
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
|
||||
screen->PreserveBuffer());
|
||||
|
||||
UniquePtr<SurfaceFactory> factory = nullptr;
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
|
@ -60,7 +57,7 @@ CanvasLayerD3D10::Initialize(const Data& aData)
|
|||
}
|
||||
|
||||
if (factory) {
|
||||
screen->Morph(Move(factory), streamType);
|
||||
screen->Morph(Move(factory));
|
||||
}
|
||||
} else if (aData.mDrawTarget) {
|
||||
mDrawTarget = aData.mDrawTarget;
|
||||
|
|
|
@ -81,6 +81,10 @@ struct SurfaceStreamDescriptor {
|
|||
bool yflip;
|
||||
};
|
||||
|
||||
struct ShSurfDescriptor {
|
||||
uintptr_t surf;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for shmem-backed YCbCr and (flavors of) RGBA textures
|
||||
*/
|
||||
|
@ -109,6 +113,7 @@ union SurfaceDescriptor {
|
|||
SurfaceStreamDescriptor;
|
||||
SurfaceDescriptorMacIOSurface;
|
||||
NewSurfaceDescriptorGralloc;
|
||||
ShSurfDescriptor;
|
||||
null_t;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче