Bug 912134 - allocate texture per CompositableHost. r=jmuizelaar,bjacob

The fundamental change of approach in this patch is that now the temporary
texture is per-compositable.

Originally, the temporary texture was per-TextureHost. That was too many
temporary textures.  With Nical's work in bug 875211, that switched to having a
temporary texture per compositor only. That's what turned out to be too few.
Now we have one per compositable which is fewer than one per TextureHost,
because e.g. a ContentHost, which is a single Compositable, may have 2
TextureHosts to implement double-buffering.
This commit is contained in:
Sotaro Ikeda 2013-09-12 22:39:26 -04:00
Родитель 7f0a897989
Коммит 59015a6eb6
12 изменённых файлов: 258 добавлений и 56 удалений

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

@ -162,6 +162,9 @@ CompositableHost::RemoveMaskEffect()
}
}
// implemented in TextureHostOGL.cpp
TemporaryRef<CompositableQuirks> CreateCompositableQuirksOGL();
/* static */ TemporaryRef<CompositableHost>
CompositableHost::Create(const TextureInfo& aTextureInfo)
{
@ -169,28 +172,33 @@ CompositableHost::Create(const TextureInfo& aTextureInfo)
switch (aTextureInfo.mCompositableType) {
case COMPOSITABLE_IMAGE:
result = new ImageHost(aTextureInfo);
return result;
break;
case BUFFER_IMAGE_BUFFERED:
result = new DeprecatedImageHostBuffered(aTextureInfo);
return result;
break;
case BUFFER_IMAGE_SINGLE:
result = new DeprecatedImageHostSingle(aTextureInfo);
return result;
break;
case BUFFER_TILED:
result = new TiledContentHost(aTextureInfo);
return result;
break;
case BUFFER_CONTENT:
result = new ContentHostSingleBuffered(aTextureInfo);
return result;
break;
case BUFFER_CONTENT_DIRECT:
result = new ContentHostDoubleBuffered(aTextureInfo);
return result;
break;
case BUFFER_CONTENT_INC:
result = new ContentHostIncremental(aTextureInfo);
return result;
break;
default:
MOZ_CRASH("Unknown CompositableType");
}
if (result) {
RefPtr<CompositableQuirks> quirks = CreateCompositableQuirksOGL();
result->SetCompositableQuirks(quirks);
}
return result;
}
#ifdef MOZ_DUMP_PAINTING

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

@ -57,6 +57,23 @@ class ThebesBufferData;
class TiledLayerComposer;
struct EffectChain;
/**
* A base class for doing CompositableHost and platform dependent task on TextureHost.
*/
class CompositableQuirks : public RefCounted<CompositableQuirks>
{
public:
CompositableQuirks()
{
MOZ_COUNT_CTOR(CompositableQuirks);
}
virtual ~CompositableQuirks()
{
MOZ_COUNT_DTOR(CompositableQuirks);
}
virtual void SetCompositor(Compositor* aCompositor) {}
};
/**
* The compositor-side counterpart to CompositableClient. Responsible for
* updating textures and data about textures from IPC and how textures are
@ -82,6 +99,13 @@ public:
virtual CompositableType GetType() = 0;
virtual CompositableQuirks* GetCompositableQuirks() { return mQuirks; }
virtual void SetCompositableQuirks(CompositableQuirks* aQuirks)
{
mQuirks = aQuirks;
}
// If base class overrides, it should still call the parent implementation
virtual void SetCompositor(Compositor* aCompositor);
@ -268,6 +292,7 @@ protected:
TextureInfo mTextureInfo;
Compositor* mCompositor;
Layer* mLayer;
RefPtr<CompositableQuirks> mQuirks;
RefPtr<TextureHost> mFirstTexture;
bool mAttached;
bool mKeepAttached;

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

@ -274,7 +274,8 @@ ContentHostSingleBuffered::EnsureDeprecatedTextureHost(TextureIdentifier aTextur
*newHost = DeprecatedTextureHost::CreateDeprecatedTextureHost(aSurface.type(),
aTextureInfo.mDeprecatedTextureHostFlags,
aTextureInfo.mTextureFlags);
aTextureInfo.mTextureFlags,
this);
(*newHost)->SetBuffer(new SurfaceDescriptor(aSurface), aAllocator);
Compositor* compositor = GetCompositor();
@ -365,7 +366,8 @@ ContentHostDoubleBuffered::EnsureDeprecatedTextureHost(TextureIdentifier aTextur
{
RefPtr<DeprecatedTextureHost> newHost = DeprecatedTextureHost::CreateDeprecatedTextureHost(aSurface.type(),
aTextureInfo.mDeprecatedTextureHostFlags,
aTextureInfo.mTextureFlags);
aTextureInfo.mTextureFlags,
this);
newHost->SetBuffer(new SurfaceDescriptor(aSurface), aAllocator);
@ -522,7 +524,8 @@ ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental*
RefPtr<DeprecatedTextureHost> newHost =
DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::TShmem,
mTextureInfo.mDeprecatedTextureHostFlags,
mTextureInfo.mTextureFlags);
mTextureInfo.mTextureFlags,
nullptr);
Compositor* compositor = aHost->GetCompositor();
if (compositor) {
newHost->SetCompositor(compositor);
@ -532,7 +535,8 @@ ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental*
newHostOnWhite =
DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::TShmem,
mTextureInfo.mDeprecatedTextureHostFlags,
mTextureInfo.mTextureFlags);
mTextureInfo.mTextureFlags,
nullptr);
Compositor* compositor = aHost->GetCompositor();
if (compositor) {
newHostOnWhite->SetCompositor(compositor);

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

@ -241,7 +241,8 @@ DeprecatedImageHostSingle::MakeDeprecatedTextureHost(TextureIdentifier aTextureI
{
mDeprecatedTextureHost = DeprecatedTextureHost::CreateDeprecatedTextureHost(aSurface.type(),
mTextureInfo.mDeprecatedTextureHostFlags,
mTextureInfo.mTextureFlags);
mTextureInfo.mTextureFlags,
this);
NS_ASSERTION(mDeprecatedTextureHost, "Failed to create texture host");

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

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/TextureHost.h"
#include "CompositableHost.h" // for CompositableHost
#include "LayersLogging.h" // for AppendToString
#include "gfx2DGlue.h" // for ToIntSize
#include "gfxImageSurface.h" // for gfxImageSurface
@ -45,13 +46,21 @@ TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHostD3D11(SurfaceDesc
/* static */ TemporaryRef<DeprecatedTextureHost>
DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
uint32_t aDeprecatedTextureHostFlags,
uint32_t aTextureFlags)
uint32_t aTextureFlags,
CompositableHost* aCompositableHost)
{
switch (Compositor::GetBackend()) {
case LAYERS_OPENGL:
return CreateDeprecatedTextureHostOGL(aDescriptorType,
{
RefPtr<DeprecatedTextureHost> result;
result = CreateDeprecatedTextureHostOGL(aDescriptorType,
aDeprecatedTextureHostFlags,
aTextureFlags);
if (aCompositableHost) {
result->SetCompositableQuirks(aCompositableHost->GetCompositableQuirks());
}
return result;
}
#ifdef XP_WIN
case LAYERS_D3D9:
return CreateDeprecatedTextureHostD3D9(aDescriptorType,
@ -135,6 +144,37 @@ CreateBackendIndependentTextureHost(uint64_t aID,
return result;
}
void TextureHost::SetCompositableQuirks(CompositableQuirks* aQuirks)
{
mQuirks = aQuirks;
}
TextureHost::TextureHost(uint64_t aID,
TextureFlags aFlags)
: mID(aID)
, mNextTexture(nullptr)
, mFlags(aFlags)
{}
TextureHost::~TextureHost()
{
}
void TextureSource::SetCompositableQuirks(CompositableQuirks* aQuirks)
{
mQuirks = aQuirks;
}
TextureSource::TextureSource()
{
MOZ_COUNT_CTOR(TextureSource);
}
TextureSource::~TextureSource()
{
MOZ_COUNT_DTOR(TextureSource);
}
DeprecatedTextureHost::DeprecatedTextureHost()
: mFlags(0)
, mBuffer(nullptr)

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

@ -38,6 +38,8 @@ class Shmem;
namespace layers {
class Compositor;
class CompositableHost;
class CompositableQuirks;
class SurfaceDescriptor;
class ISurfaceAllocator;
class TextureSourceOGL;
@ -77,14 +79,8 @@ public:
class TextureSource : public RefCounted<TextureSource>
{
public:
TextureSource()
{
MOZ_COUNT_CTOR(TextureSource);
}
virtual ~TextureSource()
{
MOZ_COUNT_DTOR(TextureSource);
}
TextureSource();
virtual ~TextureSource();
/**
* Return the size of the texture in texels.
@ -122,9 +118,14 @@ public:
*/
virtual TileIterator* AsTileIterator() { return nullptr; }
virtual void SetCompositableQuirks(CompositableQuirks* aQuirks);
#ifdef MOZ_LAYERS_HAVE_LOG
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
#endif
protected:
RefPtr<CompositableQuirks> mQuirks;
};
@ -264,13 +265,9 @@ class TextureHost : public RefCounted<TextureHost>
{
public:
TextureHost(uint64_t aID,
TextureFlags aFlags)
: mID(aID)
, mNextTexture(nullptr)
, mFlags(aFlags)
{}
TextureFlags aFlags);
virtual ~TextureHost() {}
virtual ~TextureHost();
/**
* Factory method.
@ -389,6 +386,8 @@ public:
return LayerRenderState();
}
virtual void SetCompositableQuirks(CompositableQuirks* aQuirks);
#ifdef MOZ_LAYERS_HAVE_LOG
virtual void PrintInfo(nsACString& aTo, const char* aPrefix)
{
@ -403,6 +402,7 @@ protected:
uint64_t mID;
RefPtr<TextureHost> mNextTexture;
TextureFlags mFlags;
RefPtr<CompositableQuirks> mQuirks;
};
/**
@ -582,7 +582,8 @@ public:
*/
static TemporaryRef<DeprecatedTextureHost> CreateDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
uint32_t aDeprecatedTextureHostFlags,
uint32_t aTextureFlags);
uint32_t aTextureFlags,
CompositableHost* aCompositableHost);
DeprecatedTextureHost();
virtual ~DeprecatedTextureHost();

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

@ -300,7 +300,8 @@ TiledTexture::Validate(gfxReusableSurfaceWrapper* aReusableSurface, Compositor*
// convert placeholder tile to a real tile
mDeprecatedTextureHost = DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::Tnull_t,
TEXTURE_HOST_TILED,
flags);
flags,
nullptr);
mDeprecatedTextureHost->SetCompositor(aCompositor);
flags |= TEXTURE_NEW_TILE;
}

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

@ -239,6 +239,11 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
op.textureFlags());
MOZ_ASSERT(tex.get());
tex->SetCompositor(compositable->GetCompositor());
// set CompositableQuirks
// on gonk, create EGLImage if possible.
// create EGLImage during buffer swap could reduce the graphic driver's task
// during rendering.
tex->SetCompositableQuirks(compositable->GetCompositableQuirks());
compositable->AddTextureHost(tex);
MOZ_ASSERT(compositable->GetTextureHost(op.textureID()) == tex.get());
break;

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

@ -98,6 +98,12 @@ GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor,
MOZ_ASSERT(mGraphicBuffer.get());
}
GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
{
DeallocateDeviceData();
mCompositor = nullptr;
}
void GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit)
{
/*
@ -111,21 +117,13 @@ void GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit)
MOZ_ASSERT(gl());
gl()->MakeCurrent();
GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
mQuirks->SetCompositor(mCompositor);
GLuint tex = static_cast<CompositableQuirksGonkOGL*>(mQuirks.get())->GetTexture();
GLuint textureTarget = GetTextureTarget();
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(textureTarget, tex);
if (!mEGLImage) {
mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
}
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
// XXX - Bug 909356
// This is a temporary fix to a bad lock/unlock race with the camera.
// It is bad for performances so we need to find a better way asap.
DeallocateDeviceData();
}
bool
@ -140,6 +138,16 @@ GrallocTextureSourceOGL::gl() const
return mCompositor ? mCompositor->gl() : nullptr;
}
void
GrallocTextureSourceOGL::SetCompositor(CompositorOGL* aCompositor)
{
if (mCompositor && !aCompositor) {
DeallocateDeviceData();
}
mCompositor = aCompositor;
}
GLenum
GrallocTextureSourceOGL::GetTextureTarget() const
{
@ -158,6 +166,30 @@ GrallocTextureSourceOGL::GetFormat() const {
return mFormat;
}
void
GrallocTextureSourceOGL::SetCompositableQuirks(CompositableQuirks* aQuirks)
{
mQuirks = aQuirks;
if (!mCompositor) {
return;
}
// delete old EGLImage
DeallocateDeviceData();
gl()->MakeCurrent();
mQuirks->SetCompositor(mCompositor);
GLuint tex = static_cast<CompositableQuirksGonkOGL*>(mQuirks.get())->GetTexture();
GLuint textureTarget = GetTextureTarget();
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(textureTarget, tex);
// create new EGLImage
mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
}
gfx::IntSize
GrallocTextureSourceOGL::GetSize() const
{
@ -200,10 +232,6 @@ GrallocTextureHostOGL::GrallocTextureHostOGL(uint64_t aID,
GrallocTextureHostOGL::~GrallocTextureHostOGL()
{
if (mTextureSource) {
mTextureSource->mGraphicBuffer = nullptr;
mTextureSource->SetCompositor(nullptr);
}
mTextureSource = nullptr;
}
@ -282,7 +310,8 @@ GrallocTextureSourceOGL::GetAsSurface() {
MOZ_ASSERT(gl());
gl()->MakeCurrent();
GLuint tex = mCompositor->GetTemporaryTexture(LOCAL_GL_TEXTURE0);
mQuirks->SetCompositor(mCompositor);
GLuint tex = static_cast<CompositableQuirksGonkOGL*>(mQuirks.get())->GetTexture();
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(GetTextureTarget(), tex);
if (!mEGLImage) {
@ -297,5 +326,14 @@ GrallocTextureSourceOGL::GetAsSurface() {
return surf.forget();
}
void
GrallocTextureHostOGL::SetCompositableQuirks(CompositableQuirks* aQuirks)
{
mQuirks = aQuirks;
if (mTextureSource) {
mTextureSource->SetCompositableQuirks(aQuirks);
}
}
} // namepsace layers
} // namepsace mozilla

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

@ -26,6 +26,8 @@ public:
android::GraphicBuffer* aGraphicBuffer,
gfx::SurfaceFormat aFormat);
virtual ~GrallocTextureSourceOGL();
virtual bool IsValid() const MOZ_OVERRIDE;
virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
@ -45,14 +47,13 @@ public:
return LOCAL_GL_CLAMP_TO_EDGE;
}
virtual void SetCompositableQuirks(CompositableQuirks* aQuirks) MOZ_OVERRIDE;
void DeallocateDeviceData();
gl::GLContext* gl() const;
void SetCompositor(CompositorOGL* aCompositor)
{
mCompositor = aCompositor;
}
void SetCompositor(CompositorOGL* aCompositor);
void ForgetBuffer()
{
@ -103,6 +104,8 @@ public:
virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
virtual void SetCompositableQuirks(CompositableQuirks* aQuirks) MOZ_OVERRIDE;
bool IsValid() const;
#ifdef MOZ_LAYERS_HAVE_LOG

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

@ -41,6 +41,16 @@ namespace layers {
class Compositor;
TemporaryRef<CompositableQuirks>
CreateCompositableQuirksOGL()
{
#ifdef MOZ_WIDGET_GONK
return new CompositableQuirksGonkOGL();
#else
return nullptr;
#endif
}
TemporaryRef<DeprecatedTextureHost>
CreateDeprecatedTextureHostOGL(SurfaceDescriptorType aDescriptorType,
uint32_t aDeprecatedTextureHostFlags,
@ -156,6 +166,38 @@ WrapMode(gl::GLContext *aGl, bool aAllowRepeat)
return LOCAL_GL_CLAMP_TO_EDGE;
}
CompositableQuirksGonkOGL::CompositableQuirksGonkOGL()
: mTexture(0)
{
}
CompositableQuirksGonkOGL::~CompositableQuirksGonkOGL()
{
if (mTexture) {
gl()->MakeCurrent();
gl()->fDeleteTextures(1, &mTexture);
}
}
gl::GLContext*
CompositableQuirksGonkOGL::gl() const
{
return mCompositor ? mCompositor->gl() : nullptr;
}
void CompositableQuirksGonkOGL::SetCompositor(Compositor* aCompositor)
{
mCompositor = static_cast<CompositorOGL*>(aCompositor);
}
GLuint CompositableQuirksGonkOGL::GetTexture()
{
if (!mTexture) {
gl()->MakeCurrent();
gl()->fGenTextures(1, &mTexture);
}
return mTexture;
}
bool
TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
TextureFlags aFlags,
@ -1081,8 +1123,20 @@ GrallocDeprecatedTextureHostOGL::SwapTexturesImpl(const SurfaceDescriptor& aImag
mIsRBSwapped);
mTextureTarget = TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
mQuirks->SetCompositor(mCompositor);
GLuint tex = static_cast<CompositableQuirksGonkOGL*>(mQuirks.get())->GetTexture();
// delete old EGLImage
DeleteTextures();
#if 1
gl()->MakeCurrent();
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(mTextureTarget, tex);
// create new EGLImage
// create EGLImage during buffer swap could reduce the graphic driver's task
// during rendering.
mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
#endif
}
@ -1109,14 +1163,11 @@ void GrallocDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit)
MOZ_ASSERT(gl());
gl()->MakeCurrent();
GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
mQuirks->SetCompositor(mCompositor);
GLuint tex = static_cast<CompositableQuirksGonkOGL*>(mQuirks.get())->GetTexture();
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(mTextureTarget, tex);
if (!mEGLImage) {
mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
}
gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
}
@ -1249,7 +1300,8 @@ already_AddRefed<gfxImageSurface>
GrallocDeprecatedTextureHostOGL::GetAsSurface() {
gl()->MakeCurrent();
GLuint tex = mCompositor->GetTemporaryTexture(LOCAL_GL_TEXTURE0);
mQuirks->SetCompositor(mCompositor);
GLuint tex = static_cast<CompositableQuirksGonkOGL*>(mQuirks.get())->GetTexture();
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(mTextureTarget, tex);
if (!mEGLImage) {

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

@ -8,6 +8,7 @@
#include <stddef.h> // for size_t
#include <stdint.h> // for uint64_t
#include "CompositableHost.h"
#include "GLContextTypes.h" // for GLContext
#include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc
#include "GLTextureImage.h" // for TextureImage
@ -53,6 +54,29 @@ class Compositor;
class CompositorOGL;
class TextureImageDeprecatedTextureHostOGL;
/**
* CompositableQuirks implementation for the Gonk OpenGL backend.
* Share a same texture between TextureHosts in the same CompositableHost.
* By shareing the texture among the TextureHosts, number of texture allocations
* can be reduced than texture allocation in every TextureHosts.
* From Bug 912134, use only one texture among all TextureHosts degrade
* the rendering performance.
* CompositableQuirksGonkOGL chooses in a middile of them.
*/
class CompositableQuirksGonkOGL : public CompositableQuirks
{
public:
CompositableQuirksGonkOGL();
virtual ~CompositableQuirksGonkOGL();
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
GLuint GetTexture();
gl::GLContext* gl() const;
protected:
RefPtr<CompositorOGL> mCompositor;
GLuint mTexture;
};
/*
* TextureHost implementations for the OpenGL backend.
*