gecko/gfx/layers/composite/ContentHost.h
Ryan VanderMeulen 469134ec10 Backed out 17 changesets (bug 897452) for OSX crashes on a CLOSED TREE.
Backed out changeset 11ad8608bc27 (bug 897452)
Backed out changeset 6bcc629e76f9 (bug 897452)
Backed out changeset b91c858a43f5 (bug 897452)
Backed out changeset 38ba49ee3e97 (bug 897452)
Backed out changeset ea184ef84762 (bug 897452)
Backed out changeset 686cc5122149 (bug 897452)
Backed out changeset 3685a8018e49 (bug 897452)
Backed out changeset be7ef6240068 (bug 897452)
Backed out changeset f95c20e70947 (bug 897452)
Backed out changeset 4a370d2a1c62 (bug 897452)
Backed out changeset 1222f6ab66d2 (bug 897452)
Backed out changeset 5e9d3c681ee9 (bug 897452)
Backed out changeset 3b9ddce12b7a (bug 897452)
Backed out changeset 7aec6387f3e9 (bug 897452)
Backed out changeset eb1fe464fdaf (bug 897452)
Backed out changeset 07deaa53b6fd (bug 897452)
Backed out changeset ddab7d071d69 (bug 897452)
2013-12-11 14:52:50 -05:00

482 lines
16 KiB
C++

/* -*- 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 GFX_CONTENTHOST_H
#define GFX_CONTENTHOST_H
#include <stdint.h> // for uint32_t
#include <stdio.h> // for FILE
#include "mozilla-config.h" // for MOZ_DUMP_PAINTING
#include "CompositableHost.h" // for CompositableHost, etc
#include "RotatedBuffer.h" // for RotatedContentBuffer, etc
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/gfx/Types.h" // for Filter
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/LayersTypes.h" // for etc
#include "mozilla/layers/TextureHost.h" // for DeprecatedTextureHost
#include "mozilla/mozalloc.h" // for operator delete
#include "nsAutoPtr.h" // for nsAutoPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for nsIntRect
#include "nsRegion.h" // for nsIntRegion
#include "nsTArray.h" // for nsTArray
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
#include "nscore.h" // for nsACString
namespace mozilla {
namespace gfx {
class Matrix4x4;
}
namespace layers {
class Compositor;
class ThebesBufferData;
class TiledLayerComposer;
struct EffectChain;
struct TexturedEffect;
/**
* ContentHosts are used for compositing Thebes layers, always matched by a
* ContentClient of the same type.
*
* ContentHosts support only UpdateThebes(), not Update().
*/
class ContentHost : public CompositableHost
{
public:
// Subclasses should implement this method if they support being used as a
// tiling.
virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; }
virtual void UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack) = 0;
virtual void SetPaintWillResample(bool aResample) { }
protected:
ContentHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
{}
};
/**
* Base class for non-tiled ContentHosts.
*
* Ownership of the SurfaceDescriptor and the resources it represents is passed
* from the ContentClient to the ContentHost when the DeprecatedTextureClient/Hosts are
* created, that is recevied here by SetDeprecatedTextureHosts which assigns one or two
* texture hosts (for single and double buffering) to the ContentHost.
*
* It is the responsibility of the ContentHost to destroy its resources when
* they are recreated or the ContentHost dies.
*/
class ContentHostBase : public ContentHost
{
public:
typedef RotatedContentBuffer::ContentType ContentType;
typedef RotatedContentBuffer::PaintState PaintState;
ContentHostBase(const TextureInfo& aTextureInfo);
virtual ~ContentHostBase();
virtual void Composite(EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr,
TiledLayerProperties* aLayerProperties = nullptr);
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
#ifdef MOZ_DUMP_PAINTING
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
virtual void Dump(FILE* aFile=nullptr,
const char* aPrefix="",
bool aDumpHtml=false) MOZ_OVERRIDE;
#endif
virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE;
virtual TextureHost* GetAsTextureHost() MOZ_OVERRIDE;
virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
virtual void RemoveTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
virtual void OnActorDestroy() MOZ_OVERRIDE;
protected:
virtual nsIntPoint GetOriginOffset()
{
return mBufferRect.TopLeft() - mBufferRotation;
}
bool PaintWillResample() { return mPaintWillResample; }
// These must be called before forgetting mTextureHost or mTextureHostOnWhite
void DestroyTextureHost();
void DestroyTextureHostOnWhite();
nsIntRect mBufferRect;
nsIntPoint mBufferRotation;
RefPtr<TextureHost> mTextureHost;
RefPtr<TextureHost> mTextureHostOnWhite;
bool mPaintWillResample;
bool mInitialised;
};
class DeprecatedContentHostBase : public ContentHost
{
public:
typedef RotatedContentBuffer::ContentType ContentType;
typedef RotatedContentBuffer::PaintState PaintState;
DeprecatedContentHostBase(const TextureInfo& aTextureInfo);
~DeprecatedContentHostBase();
virtual void Composite(EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr,
TiledLayerProperties* aLayerProperties = nullptr);
virtual PaintState BeginPaint(ContentType, uint32_t)
{
NS_RUNTIMEABORT("shouldn't BeginPaint for a shadow layer");
return PaintState();
}
virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
#ifdef MOZ_DUMP_PAINTING
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface();
virtual void Dump(FILE* aFile=nullptr,
const char* aPrefix="",
bool aDumpHtml=false) MOZ_OVERRIDE;
#endif
virtual DeprecatedTextureHost* GetDeprecatedTextureHost() MOZ_OVERRIDE;
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
// The client has destroyed its texture clients and we should destroy our
// texture hosts and SurfaceDescriptors. Note that we don't immediately
// destroy our front buffer so that we can continue to composite.
virtual void DestroyTextures() = 0;
virtual void OnActorDestroy() MOZ_OVERRIDE;
protected:
virtual nsIntPoint GetOriginOffset()
{
return mBufferRect.TopLeft() - mBufferRotation;
}
bool PaintWillResample() { return mPaintWillResample; }
// Destroy the front buffer's texture host. This should only happen when
// we have a new front buffer to use or the ContentHost is going to die.
void DestroyFrontHost();
nsIntRect mBufferRect;
nsIntPoint mBufferRotation;
RefPtr<DeprecatedTextureHost> mDeprecatedTextureHost;
RefPtr<DeprecatedTextureHost> mDeprecatedTextureHostOnWhite;
// When we set a new front buffer DeprecatedTextureHost, we don't want to stomp on
// the old one which might still be used for compositing. So we store it
// here and move it to mDeprecatedTextureHost once we do the first buffer swap.
RefPtr<DeprecatedTextureHost> mNewFrontHost;
RefPtr<DeprecatedTextureHost> mNewFrontHostOnWhite;
bool mPaintWillResample;
bool mInitialised;
};
/**
* Double buffering is implemented by swapping the front and back TextureHosts.
* We assume that whenever we use double buffering, then we have
* render-to-texture and thus no texture upload to do.
*/
class ContentHostDoubleBuffered : public ContentHostBase
{
public:
ContentHostDoubleBuffered(const TextureInfo& aTextureInfo)
: ContentHostBase(aTextureInfo)
{}
virtual ~ContentHostDoubleBuffered() {}
virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_DOUBLE; }
virtual void UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack);
protected:
nsIntRegion mValidRegionForNextBackBuffer;
};
class DeprecatedContentHostDoubleBuffered : public DeprecatedContentHostBase
{
public:
DeprecatedContentHostDoubleBuffered(const TextureInfo& aTextureInfo)
: DeprecatedContentHostBase(aTextureInfo)
{}
~DeprecatedContentHostDoubleBuffered();
virtual CompositableType GetType() { return BUFFER_CONTENT_DIRECT; }
virtual void UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack);
virtual void EnsureDeprecatedTextureHost(TextureIdentifier aTextureId,
const SurfaceDescriptor& aSurface,
ISurfaceAllocator* aAllocator,
const TextureInfo& aTextureInfo) MOZ_OVERRIDE;
virtual void DestroyTextures() MOZ_OVERRIDE;
virtual void OnActorDestroy() MOZ_OVERRIDE;
#ifdef MOZ_DUMP_PAINTING
virtual void Dump(FILE* aFile=nullptr,
const char* aPrefix="",
bool aDumpHtml=false) MOZ_OVERRIDE;
#endif
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
protected:
nsIntRegion mValidRegionForNextBackBuffer;
// Texture host for the back buffer. We never read or write this buffer. We
// only swap it with the front buffer (mDeprecatedTextureHost) when we are told by the
// content thread.
RefPtr<DeprecatedTextureHost> mBackHost;
RefPtr<DeprecatedTextureHost> mBackHostOnWhite;
};
/**
* Single buffered, therefore we must synchronously upload the image from the
* DeprecatedTextureHost in the layers transaction (i.e., in UpdateThebes).
*/
class ContentHostSingleBuffered : public ContentHostBase
{
public:
ContentHostSingleBuffered(const TextureInfo& aTextureInfo)
: ContentHostBase(aTextureInfo)
{}
virtual ~ContentHostSingleBuffered() {}
virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_SINGLE; }
virtual void UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack);
};
class DeprecatedContentHostSingleBuffered : public DeprecatedContentHostBase
{
public:
DeprecatedContentHostSingleBuffered(const TextureInfo& aTextureInfo)
: DeprecatedContentHostBase(aTextureInfo)
{}
virtual ~DeprecatedContentHostSingleBuffered();
virtual CompositableType GetType() { return BUFFER_CONTENT; }
virtual void UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack);
virtual void EnsureDeprecatedTextureHost(TextureIdentifier aTextureId,
const SurfaceDescriptor& aSurface,
ISurfaceAllocator* aAllocator,
const TextureInfo& aTextureInfo) MOZ_OVERRIDE;
virtual void DestroyTextures() MOZ_OVERRIDE;
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
};
/**
* Maintains a host-side only texture, and gets provided with
* surfaces that only cover the changed pixels during an update.
*
* Takes ownership of the passed in update surfaces, and must
* free them once texture upload is complete.
*
* Delays texture uploads until the next composite to
* avoid blocking the main thread.
*/
class ContentHostIncremental : public DeprecatedContentHostBase
{
public:
ContentHostIncremental(const TextureInfo& aTextureInfo)
: DeprecatedContentHostBase(aTextureInfo)
, mDeAllocator(nullptr)
{}
virtual CompositableType GetType() { return BUFFER_CONTENT; }
virtual void EnsureDeprecatedTextureHostIncremental(ISurfaceAllocator* aAllocator,
const TextureInfo& aTextureInfo,
const nsIntRect& aBufferRect) MOZ_OVERRIDE;
virtual void EnsureDeprecatedTextureHost(TextureIdentifier aTextureId,
const SurfaceDescriptor& aSurface,
ISurfaceAllocator* aAllocator,
const TextureInfo& aTextureInfo)
{
NS_RUNTIMEABORT("Shouldn't call this");
}
virtual void UpdateIncremental(TextureIdentifier aTextureId,
SurfaceDescriptor& aSurface,
const nsIntRegion& aUpdated,
const nsIntRect& aBufferRect,
const nsIntPoint& aBufferRotation) MOZ_OVERRIDE;
virtual void UpdateThebes(const ThebesBufferData& aData,
const nsIntRegion& aUpdated,
const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack)
{
NS_RUNTIMEABORT("Shouldn't call this");
}
virtual void Composite(EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr,
TiledLayerProperties* aLayerProperties = nullptr)
{
ProcessTextureUpdates();
DeprecatedContentHostBase::Composite(aEffectChain, aOpacity,
aTransform, aFilter,
aClipRect, aVisibleRegion,
aLayerProperties);
}
virtual void DestroyTextures()
{
mDeprecatedTextureHost = nullptr;
mDeprecatedTextureHostOnWhite = nullptr;
mUpdateList.Clear();
}
private:
void FlushUpdateQueue();
void ProcessTextureUpdates();
class Request
{
public:
Request()
{
MOZ_COUNT_CTOR(ContentHostIncremental::Request);
}
virtual ~Request()
{
MOZ_COUNT_DTOR(ContentHostIncremental::Request);
}
virtual void Execute(ContentHostIncremental *aHost) = 0;
};
class TextureCreationRequest : public Request
{
public:
TextureCreationRequest(const TextureInfo& aTextureInfo,
const nsIntRect& aBufferRect)
: mTextureInfo(aTextureInfo)
, mBufferRect(aBufferRect)
{}
virtual void Execute(ContentHostIncremental *aHost);
private:
TextureInfo mTextureInfo;
nsIntRect mBufferRect;
};
class TextureUpdateRequest : public Request
{
public:
TextureUpdateRequest(ISurfaceAllocator* aDeAllocator,
TextureIdentifier aTextureId,
SurfaceDescriptor& aDescriptor,
const nsIntRegion& aUpdated,
const nsIntRect& aBufferRect,
const nsIntPoint& aBufferRotation)
: mDeAllocator(aDeAllocator)
, mTextureId(aTextureId)
, mDescriptor(aDescriptor)
, mUpdated(aUpdated)
, mBufferRect(aBufferRect)
, mBufferRotation(aBufferRotation)
{}
~TextureUpdateRequest()
{
//TODO: Recycle these?
mDeAllocator->DestroySharedSurface(&mDescriptor);
}
virtual void Execute(ContentHostIncremental *aHost);
private:
enum XSide {
LEFT, RIGHT
};
enum YSide {
TOP, BOTTOM
};
nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const;
RefPtr<ISurfaceAllocator> mDeAllocator;
TextureIdentifier mTextureId;
SurfaceDescriptor mDescriptor;
nsIntRegion mUpdated;
nsIntRect mBufferRect;
nsIntPoint mBufferRotation;
};
nsTArray<nsAutoPtr<Request> > mUpdateList;
RefPtr<ISurfaceAllocator> mDeAllocator;
};
}
}
#endif