Factor texture methods out of Compositor into a TextureSourceProvider class. (bug 1343814 part 1, r=mattwoodrow)

--HG--
extra : rebase_source : 7e0773b97536f8418f12fa00ac82dd4166b5ab25
This commit is contained in:
David Anderson 2017-03-09 17:35:12 -08:00
Родитель 8b4e18d1e6
Коммит cdc76620a2
8 изменённых файлов: 202 добавлений и 107 удалений

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

@ -48,7 +48,7 @@ Compositor::~Compositor()
void
Compositor::Destroy()
{
ReadUnlockTextures();
TextureSourceProvider::Destroy();
FlushPendingNotifyNotUsed();
mIsDestroyed = true;
}
@ -60,50 +60,6 @@ Compositor::EndFrame()
mLastCompositionEndTime = TimeStamp::Now();
}
void
Compositor::ReadUnlockTextures()
{
for (auto& texture : mUnlockAfterComposition) {
texture->ReadUnlock();
}
mUnlockAfterComposition.Clear();
}
void
Compositor::UnlockAfterComposition(TextureHost* aTexture)
{
mUnlockAfterComposition.AppendElement(aTexture);
}
void
Compositor::NotifyNotUsedAfterComposition(TextureHost* aTextureHost)
{
MOZ_ASSERT(!mIsDestroyed);
mNotifyNotUsedAfterComposition.AppendElement(aTextureHost);
// If Compositor holds many TextureHosts without compositing,
// the TextureHosts should be flushed to reduce memory consumption.
const int thresholdCount = 5;
const double thresholdSec = 2.0f;
if (mNotifyNotUsedAfterComposition.Length() > thresholdCount) {
TimeDuration duration = mLastCompositionEndTime ? TimeStamp::Now() - mLastCompositionEndTime : TimeDuration();
// Check if we could flush
if (duration.ToSeconds() > thresholdSec) {
FlushPendingNotifyNotUsed();
}
}
}
void
Compositor::FlushPendingNotifyNotUsed()
{
for (auto& textureHost : mNotifyNotUsedAfterComposition) {
textureHost->CallNotifyNotUsed();
}
mNotifyNotUsedAfterComposition.Clear();
}
/* static */ void
Compositor::AssertOnCompositorThread()
{
@ -674,5 +630,14 @@ Compositor::SetDispAcquireFence(Layer* aLayer)
{
}
bool
Compositor::NotifyNotUsedAfterComposition(TextureHost* aTextureHost)
{
if (IsDestroyed() || AsBasicCompositor()) {
return false;
}
return TextureSourceProvider::NotifyNotUsedAfterComposition(aTextureHost);
}
} // namespace layers
} // namespace mozilla

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

@ -18,6 +18,7 @@
#include "mozilla/gfx/Triangle.h" // for Triangle, TexturedTriangle
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "mozilla/layers/TextureSourceProvider.h"
#include "mozilla/widget/CompositorWidget.h"
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsRegion.h"
@ -132,7 +133,6 @@ class LayerManagerComposite;
class CompositorOGL;
class CompositorD3D11;
class BasicCompositor;
class TextureHost;
class TextureReadLock;
enum SurfaceInitMode
@ -179,40 +179,21 @@ enum SurfaceInitMode
* The target and viewport methods can be called before any DrawQuad call and
* affect any subsequent DrawQuad calls.
*/
class Compositor
class Compositor : public TextureSourceProvider
{
protected:
virtual ~Compositor();
public:
NS_INLINE_DECL_REFCOUNTING(Compositor)
explicit Compositor(widget::CompositorWidget* aWidget,
CompositorBridgeParent* aParent = nullptr);
virtual already_AddRefed<DataTextureSource> CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) { return nullptr; }
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture) { return nullptr; }
virtual bool Initialize(nsCString* const out_failureReason) = 0;
virtual void Destroy();
virtual void Destroy() override;
bool IsDestroyed() const { return mIsDestroyed; }
virtual void DetachWidget() { mWidget = nullptr; }
/**
* Return true if the effect type is supported.
*
* By default Compositor implementations should support all effects but in
* some rare cases it is not possible to support an effect efficiently.
* This is the case for BasicCompositor with EffectYCbCr.
*/
virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
/**
* Request a texture host identifier that may be used for creating textures
* across process or thread boundaries that are compatible with this
@ -224,7 +205,6 @@ public:
* Properties of the compositor.
*/
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) = 0;
virtual int32_t GetMaxTextureSize() const = 0;
/**
* Set the target for rendering. Results will have been written to aTarget by
@ -472,6 +452,16 @@ public:
virtual CompositorD3D11* AsCompositorD3D11() { return nullptr; }
virtual BasicCompositor* AsBasicCompositor() { return nullptr; }
virtual Compositor* AsCompositor() override {
return this;
}
TimeStamp GetLastCompositionEndTime() const override {
return mLastCompositionEndTime;
}
bool NotifyNotUsedAfterComposition(TextureHost* aTextureHost) override;
/**
* Each Compositor has a unique ID.
* This ID is used to keep references to each Compositor in a map accessed
@ -548,24 +538,6 @@ public:
return mParent;
}
/// Most compositor backends operate asynchronously under the hood. This
/// means that when a layer stops using a texture it is often desirable to
/// wait for the end of the next composition before releasing the texture's
/// ReadLock.
/// This function provides a convenient way to do this delayed unlocking, if
/// the texture itself requires it.
void UnlockAfterComposition(TextureHost* aTexture);
/// Most compositor backends operate asynchronously under the hood. This
/// means that when a layer stops using a texture it is often desirable to
/// wait for the end of the next composition before NotifyNotUsed() call.
/// This function provides a convenient way to do this delayed NotifyNotUsed()
/// call, if the texture itself requires it.
/// See bug 1260611 and bug 1252835
void NotifyNotUsedAfterComposition(TextureHost* aTextureHost);
void FlushPendingNotifyNotUsed();
protected:
void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
const gfx::Rect& aVisibleRect,
@ -575,9 +547,6 @@ protected:
bool ShouldDrawDiagnostics(DiagnosticFlags);
// Should be called at the end of each composition.
void ReadUnlockTextures();
/**
* Given a layer rect, clip, and transform, compute the area of the backdrop that
* needs to be copied for mix-blending. The output transform translates from 0..1
@ -614,16 +583,6 @@ protected:
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect);
/**
* An array of locks that will need to be unlocked after the next composition.
*/
nsTArray<RefPtr<TextureHost>> mUnlockAfterComposition;
/**
* An array of TextureHosts that will need to call NotifyNotUsed() after the next composition.
*/
nsTArray<RefPtr<TextureHost>> mNotifyNotUsedAfterComposition;
/**
* Last Composition end time.
*/

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

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/TextureSourceProvider.h"
#include "mozilla/layers/TextureHost.h"
namespace mozilla {
namespace layers {
TextureSourceProvider::~TextureSourceProvider()
{
ReadUnlockTextures();
}
void
TextureSourceProvider::ReadUnlockTextures()
{
for (auto& texture : mUnlockAfterComposition) {
texture->ReadUnlock();
}
mUnlockAfterComposition.Clear();
}
void
TextureSourceProvider::UnlockAfterComposition(TextureHost* aTexture)
{
mUnlockAfterComposition.AppendElement(aTexture);
}
bool
TextureSourceProvider::NotifyNotUsedAfterComposition(TextureHost* aTextureHost)
{
mNotifyNotUsedAfterComposition.AppendElement(aTextureHost);
// If Compositor holds many TextureHosts without compositing,
// the TextureHosts should be flushed to reduce memory consumption.
const int thresholdCount = 5;
const double thresholdSec = 2.0f;
if (mNotifyNotUsedAfterComposition.Length() > thresholdCount) {
TimeStamp lastCompositionEndTime = GetLastCompositionEndTime();
TimeDuration duration = lastCompositionEndTime ? TimeStamp::Now() - lastCompositionEndTime : TimeDuration();
// Check if we could flush
if (duration.ToSeconds() > thresholdSec) {
FlushPendingNotifyNotUsed();
}
}
return true;
}
void
TextureSourceProvider::FlushPendingNotifyNotUsed()
{
for (auto& textureHost : mNotifyNotUsedAfterComposition) {
textureHost->CallNotifyNotUsed();
}
mNotifyNotUsedAfterComposition.Clear();
}
void
TextureSourceProvider::Destroy()
{
ReadUnlockTextures();
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_gfx_layers_TextureSourceProvider_h
#define mozilla_gfx_layers_TextureSourceProvider_h
#include "nsISupportsImpl.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/layers/CompositorTypes.h"
#include "nsTArray.h"
struct ID3D11Device;
namespace mozilla {
namespace gfx {
class DataSourceSurface;
} // namespace gfx
namespace layers {
class TextureHost;
class DataTextureSource;
class Compositor;
// Provided by a HostLayerManager or Compositor for allocating backend-specific
// texture types.
class TextureSourceProvider
{
public:
NS_INLINE_DECL_REFCOUNTING(TextureSourceProvider)
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) = 0;
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) {
return nullptr;
}
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture) {
return nullptr;
}
virtual TimeStamp GetLastCompositionEndTime() const = 0;
// Return true if the effect type is supported.
//
// By default Compositor implementations should support all effects but in
// some rare cases it is not possible to support an effect efficiently.
// This is the case for BasicCompositor with EffectYCbCr.
virtual bool SupportsEffect(EffectTypes aEffect) { return true; }
/// Most compositor backends operate asynchronously under the hood. This
/// means that when a layer stops using a texture it is often desirable to
/// wait for the end of the next composition before releasing the texture's
/// ReadLock.
/// This function provides a convenient way to do this delayed unlocking, if
/// the texture itself requires it.
void UnlockAfterComposition(TextureHost* aTexture);
/// Most compositor backends operate asynchronously under the hood. This
/// means that when a layer stops using a texture it is often desirable to
/// wait for the end of the next composition before NotifyNotUsed() call.
/// This function provides a convenient way to do this delayed NotifyNotUsed()
/// call, if the texture itself requires it.
/// See bug 1260611 and bug 1252835
///
/// Returns true if notified, false otherwise.
virtual bool NotifyNotUsedAfterComposition(TextureHost* aTextureHost);
// If overridden, make sure to call the base function.
virtual void Destroy();
void FlushPendingNotifyNotUsed();
// If this provider is also a Compositor, return the compositor. Otherwise return
// null.
virtual Compositor* AsCompositor() {
return nullptr;
}
virtual int32_t GetMaxTextureSize() const = 0;
protected:
// Should be called at the end of each composition.
void ReadUnlockTextures();
protected:
virtual ~TextureSourceProvider();
private:
// An array of locks that will need to be unlocked after the next composition.
nsTArray<RefPtr<TextureHost>> mUnlockAfterComposition;
// An array of TextureHosts that will need to call NotifyNotUsed() after the next composition.
nsTArray<RefPtr<TextureHost>> mNotifyNotUsedAfterComposition;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_gfx_layers_TextureSourceProvider_h

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

@ -182,9 +182,7 @@ void ImageHost::Attach(Layer* aLayer,
{
CompositableHost::Attach(aLayer, aCompositor, aFlags);
for (auto& img : mImages) {
if (GetCompositor()) {
img.mTextureHost->SetCompositor(GetCompositor());
}
img.mTextureHost->SetCompositor(aCompositor);
img.mTextureHost->Updated();
}
}

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

@ -341,14 +341,12 @@ TextureHost::NotifyNotUsed()
// - TextureHost has intermediate buffer.
// end of buffer usage.
if (!compositor ||
compositor->IsDestroyed() ||
compositor->AsBasicCompositor() ||
HasIntermediateBuffer()) {
HasIntermediateBuffer() ||
!compositor->NotifyNotUsedAfterComposition(this))
{
static_cast<TextureParent*>(mActor)->NotifyNotUsed(mFwdTransactionId);
return;
}
compositor->NotifyNotUsedAfterComposition(this);
}
void

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

@ -608,6 +608,7 @@ protected:
friend class Compositor;
friend class TextureParent;
friend class TiledLayerBufferComposite;
friend class TextureSourceProvider;
};
/**

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

@ -189,6 +189,7 @@ EXPORTS.mozilla.layers += [
'RenderTrace.h',
'SourceSurfaceSharedData.h',
'SourceSurfaceVolatileData.h',
'TextureSourceProvider.h',
'TextureWrapperImage.h',
'TransactionIdAllocator.h',
'wr/WebRenderBridgeChild.h',
@ -374,6 +375,7 @@ UNIFIED_SOURCES += [
'ShareableCanvasLayer.cpp',
'SourceSurfaceSharedData.cpp',
'SourceSurfaceVolatileData.cpp',
'TextureSourceProvider.cpp',
'TextureWrapperImage.cpp',
'wr/WebRenderBorderLayer.cpp',
'wr/WebRenderBridgeChild.cpp',