Bug 1249273 - Enable BufferTextureHost to recycle a TextureSource that is not marked as owned. r=sotaro

This commit is contained in:
Nicolas Silva 2016-02-25 14:15:34 +01:00
Родитель 6f996f44e4
Коммит e8b70b860b
3 изменённых файлов: 82 добавлений и 4 удалений

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

@ -42,12 +42,12 @@ public:
SurfaceFormat GetFormat() const override
{
return mSurface->GetFormat();
return mSurface ? mSurface->GetFormat() : gfx::SurfaceFormat::UNKNOWN;
}
virtual IntSize GetSize() const override
{
return mSurface->GetSize();
return mSurface ? mSurface->GetSize() : gfx::IntSize(0, 0);
}
virtual bool Update(gfx::DataSourceSurface* aSurface,

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

@ -445,6 +445,9 @@ BufferTextureHost::SetCompositor(Compositor* aCompositor)
it->SetCompositor(aCompositor);
it = it->GetNextSibling();
}
if (mFirstSource && mFirstSource->IsOwnedBy(this)) {
mFirstSource->SetOwner(nullptr);
}
mFirstSource = nullptr;
mCompositor = aCompositor;
}
@ -452,6 +455,17 @@ BufferTextureHost::SetCompositor(Compositor* aCompositor)
void
BufferTextureHost::DeallocateDeviceData()
{
if (mFirstSource && mFirstSource->NumCompositableRefs() > 0) {
return;
}
if (!mFirstSource || !mFirstSource->IsOwnedBy(this)) {
mFirstSource = nullptr;
return;
}
mFirstSource->SetOwner(nullptr);
RefPtr<TextureSource> it = mFirstSource;
while (it) {
it->DeallocateDeviceData();
@ -477,6 +491,40 @@ BufferTextureHost::Unlock()
mLocked = false;
}
void
BufferTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
{
if (mFirstSource && mFirstSource->IsOwnedBy(this)) {
// We are already attached to a TextureSource, nothing to do except tell
// the compositable to use it.
aTexture = mFirstSource.get();
return;
}
// We don't own it, apparently.
mFirstSource = nullptr;
DataTextureSource* texture = aTexture.get() ? aTexture->AsDataTextureSource() : nullptr;
bool compatibleFormats = texture
&& (mFormat == texture->GetFormat()
|| (mFormat == gfx::SurfaceFormat::YUV
&& mCompositor->SupportsEffect(EffectTypes::YCBCR)
&& texture->GetNextSibling())
|| (mFormat == gfx::SurfaceFormat::YUV
&& !mCompositor->SupportsEffect(EffectTypes::YCBCR)
&& texture->GetFormat() == gfx::SurfaceFormat::B8G8R8X8));
bool shouldCreateTexture = !compatibleFormats
|| texture->NumCompositableRefs() > 1
|| texture->HasOwner()
|| texture->GetSize() != mSize;
if (!shouldCreateTexture) {
mFirstSource = texture;
mFirstSource->SetOwner(this);
}
}
bool
BufferTextureHost::BindTextureSource(CompositableTextureSourceRef& aTexture)
{
@ -505,9 +553,17 @@ BufferTextureHost::GetFormat() const
bool
BufferTextureHost::MaybeUpload(nsIntRegion *aRegion)
{
if (mFirstSource && mFirstSource->GetUpdateSerial() == mUpdateSerial) {
auto serial = mFirstSource ? mFirstSource->GetUpdateSerial() : 0;
if (serial == mUpdateSerial) {
return true;
}
if (serial == 0) {
// 0 means the source has no valid content
aRegion = nullptr;
}
if (!Upload(aRegion)) {
return false;
}
@ -552,6 +608,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
}
if (!mFirstSource) {
mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
mFirstSource->SetOwner(this);
}
mFirstSource->Update(surf, aRegion);
return true;
@ -566,6 +623,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
srcU = mCompositor->CreateDataTextureSource(mFlags|TextureFlags::DISALLOW_BIGIMAGE);
srcV = mCompositor->CreateDataTextureSource(mFlags|TextureFlags::DISALLOW_BIGIMAGE);
mFirstSource = srcY;
mFirstSource->SetOwner(this);
srcY->SetNextSibling(srcU);
srcU->SetNextSibling(srcV);
} else {
@ -611,6 +669,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
nsIntRegion* regionToUpdate = aRegion;
if (!mFirstSource) {
mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
mFirstSource->SetOwner(this);
if (mFlags & TextureFlags::COMPONENT_ALPHA) {
// Update the full region the first time for component alpha textures.
regionToUpdate = nullptr;

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

@ -232,7 +232,8 @@ class DataTextureSource : public TextureSource
{
public:
DataTextureSource()
: mUpdateSerial(0)
: mOwner(0)
, mUpdateSerial(0)
{}
virtual const char* Name() const override { return "DataTextureSource"; }
@ -277,7 +278,23 @@ public:
virtual already_AddRefed<gfx::DataSourceSurface> ReadBack() { return nullptr; };
#endif
void SetOwner(TextureHost* aOwner)
{
auto newOwner = (uintptr_t)aOwner;
if (newOwner != mOwner) {
mOwner = newOwner;
SetUpdateSerial(0);
}
}
bool IsOwnedBy(TextureHost* aOwner) const { return mOwner == (uintptr_t)aOwner; }
bool HasOwner() const { return !IsOwnedBy(nullptr); }
private:
// We store mOwner as an integer rather than as a pointer to make it clear
// it is not intended to be dereferenced.
uintptr_t mOwner;
uint32_t mUpdateSerial;
};
@ -592,6 +609,8 @@ public:
virtual void Unlock() override;
virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) override;
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
virtual void DeallocateDeviceData() override;