зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
8b4e18d1e6
Коммит
cdc76620a2
|
@ -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',
|
||||
|
|
Загрузка…
Ссылка в новой задаче