forked from mirrors/gecko-dev
Bug 1900677 - Add a capability to recycle DataSourceSurface allocated in CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor() if possible r=gfx-reviewers,lsalzman
By default, it is disabled by pref gfx.canvas.remote.recycle-used-data-surface = false. Add a capability to reuse used DataSourceSurface that was previously used for storing converted video data. Add argument gfx::DataSourceSurface* aSurface to TextureHost::GetAsSurface(). aSurface may be used as returned DataSourceSurfacefi the TextureHost supports it. Differential Revision: https://phabricator.services.mozilla.com/D212608
This commit is contained in:
parent
68fdfb66c4
commit
d3bd7ab3f1
18 changed files with 113 additions and 31 deletions
|
|
@ -95,7 +95,8 @@ class DcompSurfaceHandleHost : public TextureHost {
|
|||
|
||||
const char* Name() override { return "DcompSurfaceHandleHost"; }
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ static nsresult CopyFromLockedMacIOSurface(MacIOSurface* aSurface,
|
|||
}
|
||||
|
||||
already_AddRefed<SourceSurface> CreateSourceSurfaceFromMacIOSurface(
|
||||
MacIOSurface* aSurface) {
|
||||
MacIOSurface* aSurface, gfx::DataSourceSurface* aDataSurface) {
|
||||
aSurface->Lock();
|
||||
auto scopeExit = MakeScopeExit([&]() { aSurface->Unlock(); });
|
||||
|
||||
|
|
@ -163,10 +163,21 @@ already_AddRefed<SourceSurface> CreateSourceSurfaceFromMacIOSurface(
|
|||
? SurfaceFormat::B8G8R8X8
|
||||
: SurfaceFormat::B8G8R8A8;
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurface =
|
||||
Factory::CreateDataSourceSurface(size, format);
|
||||
if (NS_WARN_IF(!dataSurface)) {
|
||||
return nullptr;
|
||||
RefPtr<DataSourceSurface> dataSurface;
|
||||
if (aDataSurface) {
|
||||
MOZ_ASSERT(aDataSurface->GetSize() == size);
|
||||
MOZ_ASSERT(aDataSurface->GetFormat() == format);
|
||||
if (aDataSurface->GetSize() == size &&
|
||||
aDataSurface->GetFormat() == format) {
|
||||
dataSurface = aDataSurface;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataSurface) {
|
||||
dataSurface = Factory::CreateDataSourceSurface(size, format);
|
||||
if (NS_WARN_IF(!dataSurface)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::WRITE);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace layers {
|
|||
// Unlike MacIOSurface::GetAsSurface, this also handles IOSurface formats
|
||||
// with multiple planes and does YCbCr to RGB conversion, if necessary.
|
||||
already_AddRefed<gfx::SourceSurface> CreateSourceSurfaceFromMacIOSurface(
|
||||
MacIOSurface* aSurface);
|
||||
MacIOSurface* aSurface, gfx::DataSourceSurface* aDataSurface = nullptr);
|
||||
|
||||
nsresult CreateSurfaceDescriptorBufferFromMacIOSurface(
|
||||
MacIOSurface* aSurface, SurfaceDescriptorBuffer& aSdBuffer,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ class GPUVideoTextureHost : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ class RemoteTextureHostWrapper : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -702,14 +702,15 @@ int32_t BufferTextureHost::GetCbCrStride() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> BufferTextureHost::GetAsSurface() {
|
||||
already_AddRefed<gfx::DataSourceSurface> BufferTextureHost::GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) {
|
||||
RefPtr<gfx::DataSourceSurface> result;
|
||||
if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
|
||||
NS_WARNING("BufferTextureHost: unsupported format!");
|
||||
return nullptr;
|
||||
} else if (mFormat == gfx::SurfaceFormat::YUV) {
|
||||
result = ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(
|
||||
GetBuffer(), mDescriptor.get_YCbCrDescriptor());
|
||||
GetBuffer(), mDescriptor.get_YCbCrDescriptor(), aSurface);
|
||||
if (NS_WARN_IF(!result)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class TextureHostWrapperD3D11;
|
|||
class BigImageIterator {
|
||||
public:
|
||||
virtual void BeginBigImageIteration() = 0;
|
||||
virtual void EndBigImageIteration(){};
|
||||
virtual void EndBigImageIteration() {};
|
||||
virtual gfx::IntRect GetTileRect() = 0;
|
||||
virtual size_t GetTileCount() = 0;
|
||||
virtual bool NextTile() = 0;
|
||||
|
|
@ -498,10 +498,14 @@ class TextureHost : public AtomicRefCountedWithFinalize<TextureHost> {
|
|||
virtual void SetCropRect(nsIntRect aCropRect) {}
|
||||
|
||||
/**
|
||||
* Debug facility.
|
||||
* Return TextureHost's data as DataSourceSurface.
|
||||
*
|
||||
* @param aSurface may be used as returned DataSourceSurface.
|
||||
*
|
||||
* XXX - cool kids use Moz2D. See bug 882113.
|
||||
*/
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() = 0;
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* XXX - Flags should only be set at creation time, this will be removed.
|
||||
|
|
@ -813,7 +817,8 @@ class BufferTextureHost : public TextureHost {
|
|||
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override;
|
||||
|
||||
bool NeedsDeferredDeletion() const override {
|
||||
return TextureHost::NeedsDeferredDeletion() || UseExternalTextures();
|
||||
|
|
|
|||
|
|
@ -921,7 +921,8 @@ bool DXGITextureHostD3D11::LockInternal() {
|
|||
return mIsLocked;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> DXGITextureHostD3D11::GetAsSurface() {
|
||||
already_AddRefed<gfx::DataSourceSurface> DXGITextureHostD3D11::GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) {
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
|
|
|
|||
|
|
@ -358,7 +358,8 @@ class DXGITextureHostD3D11 : public TextureHost {
|
|||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
gfx::ColorRange GetColorRange() const override { return mColorRange; }
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override;
|
||||
|
||||
void CreateRenderTexture(
|
||||
const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
|
@ -427,7 +428,8 @@ class DXGIYCbCrTextureHostD3D11 : public TextureHost {
|
|||
|
||||
gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ class TextureHostWrapperD3D11 : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -865,6 +865,7 @@ void CanvasTranslator::PrepareShmem(int64_t aTextureId) {
|
|||
}
|
||||
|
||||
void CanvasTranslator::ClearCachedResources() {
|
||||
mUsedDataSurfaceForSurfaceDescriptor = nullptr;
|
||||
if (mSharedContext) {
|
||||
// If there are any DrawTargetWebgls, then try to cache their framebuffers
|
||||
// in software surfaces, just in case the GL context is lost. So long as
|
||||
|
|
@ -1153,6 +1154,7 @@ bool CanvasTranslator::PushRemoteTexture(int64_t aTextureId, TextureData* aData,
|
|||
}
|
||||
|
||||
void CanvasTranslator::ClearTextureInfo() {
|
||||
mUsedDataSurfaceForSurfaceDescriptor = nullptr;
|
||||
for (auto const& entry : mTextureInfo) {
|
||||
if (entry.second.mTextureData) {
|
||||
entry.second.mTextureData->Unlock();
|
||||
|
|
@ -1214,6 +1216,36 @@ static bool SDIsSupportedRemoteDecoder(const SurfaceDescriptor& sd) {
|
|||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
CanvasTranslator::GetRecycledDataSurfaceForSurfaceDescriptor(
|
||||
TextureHost* aTextureHost) {
|
||||
if (!StaticPrefs::gfx_canvas_remote_recycle_used_data_surface()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& usedSurf = mUsedDataSurfaceForSurfaceDescriptor;
|
||||
|
||||
bool isYuvVideo = false;
|
||||
if (aTextureHost->AsMacIOSurfaceTextureHost()) {
|
||||
if (aTextureHost->GetFormat() == SurfaceFormat::NV12 ||
|
||||
aTextureHost->GetFormat() == SurfaceFormat::YUV422) {
|
||||
isYuvVideo = true;
|
||||
}
|
||||
} else if (aTextureHost->GetFormat() == gfx::SurfaceFormat::YUV) {
|
||||
isYuvVideo = true;
|
||||
}
|
||||
|
||||
if (isYuvVideo && usedSurf && usedSurf->refCount() == 1 &&
|
||||
usedSurf->GetFormat() == gfx::SurfaceFormat::B8G8R8X8 &&
|
||||
aTextureHost->GetSize() == usedSurf->GetSize()) {
|
||||
// Reuse previously used DataSourceSurface if it is not used and same
|
||||
// size/format.
|
||||
return usedSurf.forget();
|
||||
}
|
||||
usedSurf = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::SourceSurface>
|
||||
CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
|
||||
const SurfaceDescriptor& aDesc) {
|
||||
|
|
@ -1244,11 +1276,19 @@ CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
|
|||
if (subdescType ==
|
||||
RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorMacIOSurface) {
|
||||
MOZ_ASSERT(texture->AsMacIOSurfaceTextureHost());
|
||||
return texture->GetAsSurface();
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> reuseSurf =
|
||||
GetRecycledDataSurfaceForSurfaceDescriptor(texture);
|
||||
RefPtr<gfx::DataSourceSurface> surf = texture->GetAsSurface(reuseSurf);
|
||||
mUsedDataSurfaceForSurfaceDescriptor = surf;
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
if (subdescType == RemoteDecoderVideoSubDescriptor::Tnull_t) {
|
||||
RefPtr<gfx::DataSourceSurface> surf = texture->GetAsSurface();
|
||||
RefPtr<gfx::DataSourceSurface> reuseSurf =
|
||||
GetRecycledDataSurfaceForSurfaceDescriptor(texture);
|
||||
RefPtr<gfx::DataSourceSurface> surf = texture->GetAsSurface(reuseSurf);
|
||||
mUsedDataSurfaceForSurfaceDescriptor = surf;
|
||||
return surf.forget();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace layers {
|
|||
|
||||
class SharedSurfacesHolder;
|
||||
class TextureData;
|
||||
class TextureHost;
|
||||
|
||||
class CanvasTranslator final : public gfx::InlineTranslator,
|
||||
public PCanvasParent {
|
||||
|
|
@ -333,6 +334,9 @@ class CanvasTranslator final : public gfx::InlineTranslator,
|
|||
|
||||
void ClearCachedResources();
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface>
|
||||
GetRecycledDataSurfaceForSurfaceDescriptor(TextureHost* aTextureHost);
|
||||
|
||||
const RefPtr<TaskQueue> mTranslationTaskQueue;
|
||||
const RefPtr<SharedSurfacesHolder> mSharedSurfacesHolder;
|
||||
#if defined(XP_WIN)
|
||||
|
|
@ -396,6 +400,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
|
|||
Atomic<bool> mIPDLClosed{false};
|
||||
bool mIsInTransaction = false;
|
||||
bool mDeviceResetInProgress = false;
|
||||
RefPtr<gfx::DataSourceSurface> mUsedDataSurfaceForSurfaceDescriptor;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ class DMABUFTextureHostOGL : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,9 +34,10 @@ class MacIOSurfaceTextureHostOGL : public TextureHost {
|
|||
gfx::SurfaceFormat GetFormat() const override;
|
||||
gfx::SurfaceFormat GetReadFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
RefPtr<gfx::SourceSurface> surf =
|
||||
CreateSourceSurfaceFromMacIOSurface(GetMacIOSurface());
|
||||
CreateSourceSurfaceFromMacIOSurface(GetMacIOSurface(), aSurface);
|
||||
return surf->GetDataSurface();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -317,7 +317,8 @@ class GLTextureHost : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
@ -396,7 +397,8 @@ class SurfaceTextureHost : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +511,8 @@ class AndroidHardwareBufferTextureHost : public TextureHost {
|
|||
|
||||
void NotifyNotUsed() override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
@ -615,7 +618,8 @@ class EGLImageTextureHost final : public TextureHost {
|
|||
|
||||
gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override {
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override {
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,8 +75,9 @@ void WebRenderTextureHost::UnbindTextureSource() {
|
|||
TextureHost::UnbindTextureSource();
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> WebRenderTextureHost::GetAsSurface() {
|
||||
return mWrappedTextureHost->GetAsSurface();
|
||||
already_AddRefed<gfx::DataSourceSurface> WebRenderTextureHost::GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) {
|
||||
return mWrappedTextureHost->GetAsSurface(aSurface);
|
||||
}
|
||||
|
||||
gfx::ColorDepth WebRenderTextureHost::GetColorDepth() const {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ class WebRenderTextureHost : public TextureHost {
|
|||
// Please check TextureHost::GetReadFormat().
|
||||
gfx::SurfaceFormat GetReadFormat() const override;
|
||||
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface(
|
||||
gfx::DataSourceSurface* aSurface) override;
|
||||
|
||||
gfx::ColorDepth GetColorDepth() const override;
|
||||
gfx::YUVColorSpace GetYUVColorSpace() const override;
|
||||
|
|
|
|||
|
|
@ -5873,6 +5873,11 @@
|
|||
value: true
|
||||
mirror: always
|
||||
|
||||
- name: gfx.canvas.remote.recycle-used-data-surface
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
- name: gfx.canvas.willreadfrequently.enabled
|
||||
type: bool
|
||||
#if defined(XP_WIN)
|
||||
|
|
|
|||
Loading…
Reference in a new issue