зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1249273
- Enable BufferTextureHost to recycle a TextureSource that is not marked as owned. r=sotaro
This commit is contained in:
Родитель
6f996f44e4
Коммит
e8b70b860b
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче