зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1250500 - Avoid copying BufferTextureHost when possible. r=sotaro
This commit is contained in:
Родитель
2b9dadff72
Коммит
9e20942d69
|
@ -6,10 +6,15 @@
|
|||
#include "BufferTexture.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/fallible.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include "gfxPlatformGtk.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -83,6 +88,24 @@ protected:
|
|||
mozilla::ipc::Shmem mShmem;
|
||||
};
|
||||
|
||||
static bool UsingX11Compositor()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
return gfxPlatformGtk::GetPlatform()->UseXRender();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ComputeHasIntermediateBuffer(gfx::SurfaceFormat aFormat,
|
||||
LayersBackend aLayersBackend)
|
||||
{
|
||||
return aLayersBackend != LayersBackend::LAYERS_BASIC
|
||||
|| UsingX11Compositor()
|
||||
|| aFormat == gfx::SurfaceFormat::UNKNOWN
|
||||
|| aFormat == gfx::SurfaceFormat::YUV
|
||||
|| aFormat == gfx::SurfaceFormat::NV12;
|
||||
}
|
||||
|
||||
BufferTextureData*
|
||||
BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
|
||||
|
@ -90,9 +113,11 @@ BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
|||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
if (!aAllocator || aAllocator->IsSameProcess()) {
|
||||
return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags, aAllocFlags, aAllocator);
|
||||
return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags,
|
||||
aAllocFlags, aAllocator);
|
||||
} else {
|
||||
return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags, aAllocFlags, aAllocator);
|
||||
return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags,
|
||||
aAllocFlags, aAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,6 +204,16 @@ BufferTextureData::GetFormat() const
|
|||
return ImageDataSerializer::FormatFromBufferDescriptor(mDescriptor);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BufferTextureData::HasInternalBuffer() const
|
||||
{
|
||||
if (mDescriptor.type() == BufferDescriptor::TYCbCrDescriptor) {
|
||||
return true;
|
||||
}
|
||||
return mDescriptor.get_RGBDescriptor().hasInternalBuffer();
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureData::SupportsMoz2D() const
|
||||
{
|
||||
|
@ -385,7 +420,7 @@ MemoryTextureData*
|
|||
MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ISurfaceAllocator*)
|
||||
ISurfaceAllocator* aAllocator)
|
||||
{
|
||||
// Should have used CreateForYCbCr.
|
||||
MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
|
||||
|
@ -405,9 +440,14 @@ MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto fwd = aAllocator ? aAllocator->AsCompositableForwarder() : nullptr;
|
||||
bool hasInternalBuffer = fwd ? ComputeHasIntermediateBuffer(aFormat,
|
||||
fwd->GetCompositorBackendType())
|
||||
: true;
|
||||
|
||||
GfxMemoryImageReporter::DidAlloc(buf);
|
||||
|
||||
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat);
|
||||
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasInternalBuffer);
|
||||
|
||||
return new MemoryTextureData(descriptor, aMoz2DBackend, buf, bufSize);
|
||||
}
|
||||
|
@ -477,7 +517,12 @@ ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat);
|
||||
auto fwd = aAllocator->AsCompositableForwarder();
|
||||
bool hasInternalBuffer = fwd ? ComputeHasIntermediateBuffer(aFormat,
|
||||
fwd->GetCompositorBackendType())
|
||||
: true;
|
||||
|
||||
BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasInternalBuffer);
|
||||
|
||||
return new ShmemTextureData(descriptor, aMoz2DBackend, shm);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
virtual bool SupportsMoz2D() const override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
virtual bool HasInternalBuffer() const override;
|
||||
|
||||
// use TextureClient's default implementation
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
|
|
@ -112,6 +112,7 @@ namespace mozilla {
|
|||
namespace gfx {
|
||||
class Matrix;
|
||||
class DrawTarget;
|
||||
class DataSourceSurface;
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
|
@ -192,6 +193,10 @@ public:
|
|||
}
|
||||
|
||||
virtual already_AddRefed<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) { return nullptr; }
|
||||
|
||||
virtual bool Initialize() = 0;
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
|
|
|
@ -36,6 +36,18 @@ class DataTextureSourceBasic : public DataTextureSource
|
|||
public:
|
||||
virtual const char* Name() const override { return "DataTextureSourceBasic"; }
|
||||
|
||||
explicit DataTextureSourceBasic(DataSourceSurface* aSurface)
|
||||
: mSurface(aSurface)
|
||||
, mWrappingExistingData(!!aSurface)
|
||||
{}
|
||||
|
||||
virtual DataTextureSource* AsDataTextureSource() override
|
||||
{
|
||||
// If the texture wraps someone else's memory we'd rather not use it as
|
||||
// a DataTextureSource per say (that is call Update on it).
|
||||
return mWrappingExistingData ? nullptr : this;
|
||||
}
|
||||
|
||||
virtual TextureSourceBasic* AsSourceBasic() override { return this; }
|
||||
|
||||
virtual gfx::SourceSurface* GetSurface(DrawTarget* aTarget) override { return mSurface; }
|
||||
|
@ -54,6 +66,10 @@ public:
|
|||
nsIntRegion* aDestRegion = nullptr,
|
||||
gfx::IntPoint* aSrcOffset = nullptr) override
|
||||
{
|
||||
MOZ_ASSERT(!mWrappingExistingData);
|
||||
if (mWrappingExistingData) {
|
||||
return false;
|
||||
}
|
||||
mSurface = aSurface;
|
||||
return true;
|
||||
}
|
||||
|
@ -66,6 +82,7 @@ public:
|
|||
|
||||
public:
|
||||
RefPtr<gfx::DataSourceSurface> mSurface;
|
||||
bool mWrappingExistingData;
|
||||
};
|
||||
|
||||
BasicCompositor::BasicCompositor(nsIWidget *aWidget)
|
||||
|
@ -182,7 +199,14 @@ BasicCompositor::CreateRenderTargetForWindow(const IntRect& aRect, SurfaceInitMo
|
|||
already_AddRefed<DataTextureSource>
|
||||
BasicCompositor::CreateDataTextureSource(TextureFlags aFlags)
|
||||
{
|
||||
RefPtr<DataTextureSource> result = new DataTextureSourceBasic();
|
||||
RefPtr<DataTextureSource> result = new DataTextureSourceBasic(nullptr);
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DataTextureSource>
|
||||
BasicCompositor::CreateDataTextureSourceAround(DataSourceSurface* aSurface)
|
||||
{
|
||||
RefPtr<DataTextureSource> result = new DataTextureSourceBasic(aSurface);
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,9 @@ public:
|
|||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) override;
|
||||
|
||||
virtual bool SupportsEffect(EffectTypes aEffect) override;
|
||||
|
||||
virtual void SetRenderTarget(CompositingRenderTarget *aSource) override
|
||||
|
|
|
@ -52,6 +52,9 @@ public:
|
|||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) override { return nullptr; }
|
||||
|
||||
virtual void EndFrame() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -395,12 +395,14 @@ BufferTextureHost::BufferTextureHost(const BufferDescriptor& aDesc,
|
|||
const YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
|
||||
mSize = ycbcr.ySize();
|
||||
mFormat = gfx::SurfaceFormat::YUV;
|
||||
mHasInternalBuffer = true;
|
||||
break;
|
||||
}
|
||||
case BufferDescriptor::TRGBDescriptor: {
|
||||
const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
|
||||
mSize = rgb.size();
|
||||
mFormat = rgb.format();
|
||||
mHasInternalBuffer = rgb.hasInternalBuffer();
|
||||
break;
|
||||
}
|
||||
default: MOZ_CRASH();
|
||||
|
@ -491,9 +493,42 @@ BufferTextureHost::Unlock()
|
|||
mLocked = false;
|
||||
}
|
||||
|
||||
bool
|
||||
BufferTextureHost::EnsureWrappingTextureSource()
|
||||
{
|
||||
MOZ_ASSERT(!mHasInternalBuffer);
|
||||
MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV);
|
||||
|
||||
if (mFirstSource) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mCompositor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> surf =
|
||||
gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
|
||||
ImageDataSerializer::ComputeRGBStride(mFormat, mSize.width), mSize, mFormat);
|
||||
|
||||
if (!surf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mFirstSource = mCompositor->CreateDataTextureSourceAround(surf);
|
||||
mFirstSource->SetUpdateSerial(mUpdateSerial);
|
||||
mFirstSource->SetOwner(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BufferTextureHost::PrepareTextureSource(CompositableTextureSourceRef& aTexture)
|
||||
{
|
||||
if (!mHasInternalBuffer) {
|
||||
EnsureWrappingTextureSource();
|
||||
}
|
||||
|
||||
if (mFirstSource && mFirstSource->IsOwnedBy(this)) {
|
||||
// We are already attached to a TextureSource, nothing to do except tell
|
||||
// the compositable to use it.
|
||||
|
@ -594,6 +629,10 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
|
|||
// attached to a layer.
|
||||
return false;
|
||||
}
|
||||
if (!mHasInternalBuffer && EnsureWrappingTextureSource()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
|
||||
NS_WARNING("BufferTextureHost: unsupported format!");
|
||||
return false;
|
||||
|
|
|
@ -630,11 +630,12 @@ public:
|
|||
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
virtual bool HasInternalBuffer() const override { return mHasInternalBuffer; }
|
||||
|
||||
protected:
|
||||
bool Upload(nsIntRegion *aRegion = nullptr);
|
||||
bool MaybeUpload(nsIntRegion *aRegion = nullptr);
|
||||
bool EnsureWrappingTextureSource();
|
||||
|
||||
virtual void UpdatedInternal(const nsIntRegion* aRegion = nullptr) override;
|
||||
|
||||
|
@ -647,6 +648,7 @@ protected:
|
|||
uint32_t mUpdateSerial;
|
||||
bool mLocked;
|
||||
bool mNeedsFullUpdate;
|
||||
bool mHasInternalBuffer;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -172,6 +172,8 @@ public:
|
|||
|
||||
SyncObject* GetSyncObject() { return mSyncObject; }
|
||||
|
||||
virtual CompositableForwarder* AsCompositableForwarder() override { return this; }
|
||||
|
||||
protected:
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
nsTArray<RefPtr<TextureClient> > mTexturesToRemove;
|
||||
|
|
|
@ -147,7 +147,11 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize,
|
|||
bufferDesc = shmem;
|
||||
}
|
||||
|
||||
*aBuffer = SurfaceDescriptorBuffer(RGBDescriptor(aSize, format), bufferDesc);
|
||||
// Use an intermediate buffer by default. Skipping the intermediate buffer is
|
||||
// only possible in certain configurations so let's keep it simple here for now.
|
||||
const bool hasIntermediateBuffer = true;
|
||||
*aBuffer = SurfaceDescriptorBuffer(RGBDescriptor(aSize, format, hasIntermediateBuffer),
|
||||
bufferDesc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class DataSourceSurface;
|
|||
namespace layers {
|
||||
|
||||
class MaybeMagicGrallocBufferHandle;
|
||||
class CompositableForwarder;
|
||||
|
||||
enum BufferCapabilities {
|
||||
DEFAULT_BUFFER_CAPS = 0,
|
||||
|
@ -160,6 +161,7 @@ public:
|
|||
// Returns true if aSurface wraps a Shmem.
|
||||
static bool IsShmem(SurfaceDescriptor* aSurface);
|
||||
|
||||
virtual CompositableForwarder* AsCompositableForwarder() { return nullptr; }
|
||||
protected:
|
||||
|
||||
virtual bool IsOnCompositorSide() const = 0;
|
||||
|
|
|
@ -101,6 +101,7 @@ struct SurfaceDescriptorGralloc {
|
|||
struct RGBDescriptor {
|
||||
IntSize size;
|
||||
SurfaceFormat format;
|
||||
bool hasInternalBuffer;
|
||||
};
|
||||
|
||||
struct YCbCrDescriptor {
|
||||
|
|
Загрузка…
Ссылка в новой задаче