Bug 1143575. Route ImageCompositeNotifications to ImageContainers. r=nical

For frame statistics to work properly, we have to notify an ImageContainer
when it has been composited. This requires a few changes, which have
been lumped together in this patch:
-- Create PImageContainer and ImageContainerParent/ImageContainerChild.
-- Add mFrameID and mProducerID everywhere we're passing around images.
-- Route composition notifications from the compositor back to
ImageContainerChild.

--HG--
extra : commitid : 7atVkOgdEhG
extra : rebase_source : caaba6a708ed267368df44609fb047abde9c3ca1
This commit is contained in:
Robert O'Callahan 2015-07-06 15:02:26 +12:00
parent 6111862fcc
commit 68954a66d8
42 changed files with 547 additions and 94 deletions

View File

@ -47,6 +47,7 @@ class RenderFrameChild;
namespace layers {
class APZEventState;
class ImageCompositeNotification;
struct SetTargetAPZCCallback;
struct SetAllowedTouchBehaviorCallback;
}

View File

@ -14,6 +14,7 @@
#include "mozilla/ipc/CrossProcessMutex.h" // for CrossProcessMutex, etc
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild
#include "mozilla/layers/PImageContainerChild.h"
#include "mozilla/layers/ImageClient.h" // for ImageClient
#include "nsISupportsUtils.h" // for NS_IF_ADDREF
#include "YCbCrUtils.h" // for YCbCr conversions
@ -139,27 +140,55 @@ BufferRecycleBin::GetBuffer(uint32_t aSize)
return result;
}
ImageContainer::ImageContainer(ImageContainer::Mode flag)
/**
* The child side of PImageContainer. It's best to avoid ImageContainer filling
* this role since IPDL objects should be associated with a single thread and
* ImageContainer definitely isn't. This object belongs to (and is always
* destroyed on) the ImageBridge thread, except when we need to destroy it
* during shutdown.
* An ImageContainer owns one of these; we have a weak reference to our
* ImageContainer.
*/
class ImageContainerChild : public PImageContainerChild {
public:
explicit ImageContainerChild(ImageContainer* aImageContainer)
: mLock("ImageContainerChild"), mImageContainer(aImageContainer) {}
void ForgetImageContainer()
{
MutexAutoLock lock(mLock);
mImageContainer = nullptr;
}
// This protects mImageContainer. This is always taken before the
// mImageContainer's monitor (when both need to be held).
Mutex mLock;
ImageContainer* mImageContainer;
};
ImageContainer::ImageContainer(Mode flag)
: mReentrantMonitor("ImageContainer.mReentrantMonitor"),
mGenerationCounter(++sGenerationCounter),
mPaintCount(0),
mPreviousImagePainted(false),
mImageFactory(new ImageFactory()),
mRecycleBin(new BufferRecycleBin()),
mImageClient(nullptr)
mImageClient(nullptr),
mIPDLChild(nullptr)
{
if (ImageBridgeChild::IsCreated()) {
// the refcount of this ImageClient is 1. we don't use a RefPtr here because the refcount
// of this class must be done on the ImageBridge thread.
switch(flag) {
switch (flag) {
case SYNCHRONOUS:
break;
case ASYNCHRONOUS:
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE).take();
mIPDLChild = new ImageContainerChild(this);
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE, this).take();
MOZ_ASSERT(mImageClient);
break;
case ASYNCHRONOUS_OVERLAY:
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE_OVERLAY).take();
mIPDLChild = new ImageContainerChild(this);
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE_OVERLAY, this).take();
MOZ_ASSERT(mImageClient);
break;
default:
@ -172,7 +201,8 @@ ImageContainer::ImageContainer(ImageContainer::Mode flag)
ImageContainer::~ImageContainer()
{
if (IsAsync()) {
ImageBridgeChild::DispatchReleaseImageClient(mImageClient);
mIPDLChild->ForgetImageContainer();
ImageBridgeChild::DispatchReleaseImageClient(mImageClient, mIPDLChild);
}
}
@ -187,7 +217,8 @@ ImageContainer::CreateImage(ImageFormat aFormat)
// If this ImageContainer is async but the image type mismatch, fix it here
if (ImageBridgeChild::IsCreated()) {
ImageBridgeChild::DispatchReleaseImageClient(mImageClient);
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(CompositableType::IMAGE_OVERLAY).take();
mImageClient = ImageBridgeChild::GetSingleton()->CreateImageClient(
CompositableType::IMAGE_OVERLAY, this).take();
}
}
}
@ -295,7 +326,10 @@ ImageContainer::GetCurrentImages(nsTArray<OwningImage>* aImages,
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mActiveImage) {
aImages->AppendElement()->mImage = mActiveImage;
OwningImage* img = aImages->AppendElement();
img->mImage = mActiveImage;
img->mFrameID = mGenerationCounter;
img->mProducerID = 0;
}
if (aGenerationCounter) {
*aGenerationCounter = mGenerationCounter;
@ -552,5 +586,24 @@ CairoImage::GetTextureClient(CompositableClient *aClient)
return textureClient;
}
PImageContainerChild*
ImageContainer::GetPImageContainerChild()
{
return mIPDLChild;
}
/* static */ void
ImageContainer::NotifyComposite(const ImageCompositeNotification& aNotification)
{
ImageContainerChild* child =
static_cast<ImageContainerChild*>(aNotification.imageContainerChild());
if (child) {
MutexAutoLock lock(child->mLock);
if (child->mImageContainer) {
child->mImageContainer->NotifyCompositeInternal(aNotification);
}
}
}
} // namespace
} // namespace

View File

@ -98,6 +98,9 @@ namespace mozilla {
namespace layers {
class ImageClient;
class ImageCompositeNotification;
class ImageContainerChild;
class PImageContainerChild;
class SharedPlanarYCbCrImage;
class TextureClient;
class CompositableClient;
@ -285,6 +288,10 @@ public:
explicit ImageContainer(ImageContainer::Mode flag = SYNCHRONOUS);
typedef int32_t FrameID;
typedef int32_t ProducerID;
/**
* Create an Image in one of the given formats.
* Picks the "best" format from the list and creates an Image of that
@ -377,6 +384,8 @@ public:
struct OwningImage {
nsRefPtr<Image> mImage;
TimeStamp mTimeStamp;
FrameID mFrameID;
ProducerID mProducerID;
};
/**
* Copy the current Image list to aImages.
@ -462,6 +471,10 @@ public:
}
}
PImageContainerChild* GetPImageContainerChild();
static void NotifyComposite(const ImageCompositeNotification& aNotification);
private:
typedef mozilla::ReentrantMonitor ReentrantMonitor;
@ -489,6 +502,8 @@ private:
mPaintTime = TimeStamp();
}
void NotifyCompositeInternal(const ImageCompositeNotification& aNotification) {}
nsRefPtr<Image> mActiveImage;
// Updates every time mActiveImage changes
uint32_t mGenerationCounter;
@ -523,6 +538,10 @@ private:
// asynchronusly using the ImageBridge IPDL protocol.
ImageClient* mImageClient;
// Object must be released on the ImageBridge thread. Field is immutable
// after creation of the ImageContainer.
ImageContainerChild* mIPDLChild;
static mozilla::Atomic<uint32_t> sGenerationCounter;
};

View File

@ -20,6 +20,7 @@
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/PLayerChild.h" // for PLayerChild
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/ShadowLayerChild.h"
#include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
#include "mozilla/layers/PersistentBufferProvider.h"
#include "ClientReadbackLayer.h" // for ClientReadbackLayer
@ -601,7 +602,6 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
break;
}
default:
NS_RUNTIMEABORT("not reached");
}

View File

@ -205,7 +205,7 @@ public:
virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) override;
virtual void RunOverfillCallback(const uint32_t aOverfill) override;
virtual void DidComposite(uint64_t aTransactionId);
void DidComposite(uint64_t aTransactionId);
virtual bool SupportsMixBlendModes(EnumSet<gfx::CompositionOp>& aMixBlendModes) override
{

View File

@ -158,12 +158,12 @@ CompositableClient::GetIPDLActor() const
}
bool
CompositableClient::Connect()
CompositableClient::Connect(ImageContainer* aImageContainer)
{
if (!GetForwarder() || GetIPDLActor()) {
return false;
}
GetForwarder()->Connect(this);
GetForwarder()->Connect(this, aImageContainer);
return true;
}

View File

@ -25,6 +25,7 @@ namespace layers {
class CompositableClient;
class BufferTextureClient;
class ImageBridgeChild;
class ImageContainer;
class CompositableForwarder;
class CompositableChild;
class PCompositableChild;
@ -146,7 +147,7 @@ public:
/**
* Establishes the connection with compositor side through IPDL
*/
virtual bool Connect();
virtual bool Connect(ImageContainer* aImageContainer = nullptr);
void Destroy();

View File

@ -249,6 +249,8 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
t->mTextureClient = texture;
t->mTimeStamp = img.mTimeStamp;
t->mPictureRect = image->GetPictureRect();
t->mFrameID = img.mFrameID;
t->mProducerID = img.mProducerID;
Buffer* newBuf = newBuffers.AppendElement();
newBuf->mImageSerial = image->GetSerial();

View File

@ -125,7 +125,7 @@ public:
TextureFlags aFlags);
virtual bool UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags) override;
virtual bool Connect() override { return false; }
virtual bool Connect(ImageContainer* aImageContainer) override { return false; }
virtual TextureInfo GetTextureInfo() const override
{

View File

@ -97,7 +97,7 @@ CanvasLayerComposite::RenderLayer(const IntRect& aClipRect)
RenderWithAllMasks(this, mCompositor, aClipRect,
[&](EffectChain& effectChain, const Rect& clipRect) {
mCompositableHost->Composite(effectChain,
mCompositableHost->Composite(this, effectChain,
GetEffectiveOpacity(),
GetEffectiveTransform(),
GetEffectFilter(),

View File

@ -11,6 +11,7 @@
#include "gfxUtils.h"
#include "ImageHost.h" // for ImageHostBuffered, etc
#include "TiledContentHost.h" // for TiledContentHost
#include "mozilla/layers/ImageContainerParent.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
#include "nsRefPtr.h" // for nsRefPtr
@ -33,14 +34,15 @@ class Compositor;
*
* CompositableParent is owned by the IPDL system. It's deletion is triggered
* by either the CompositableChild's deletion, or by the IPDL communication
* goind down.
* going down.
*/
class CompositableParent : public PCompositableParent
{
public:
CompositableParent(CompositableParentManager* aMgr,
const TextureInfo& aTextureInfo,
uint64_t aID = 0)
uint64_t aID = 0,
PImageContainerParent* aImageContainer = nullptr)
{
MOZ_COUNT_CTOR(CompositableParent);
mHost = CompositableHost::Create(aTextureInfo);
@ -48,6 +50,10 @@ public:
if (aID) {
CompositableMap::Set(aID, this);
}
if (aImageContainer) {
mHost->SetImageContainer(
static_cast<ImageContainerParent*>(aImageContainer));
}
}
~CompositableParent()
@ -87,9 +93,10 @@ CompositableHost::~CompositableHost()
PCompositableParent*
CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr,
const TextureInfo& aTextureInfo,
uint64_t aID)
uint64_t aID,
PImageContainerParent* aImageContainer)
{
return new CompositableParent(aMgr, aTextureInfo, aID);
return new CompositableParent(aMgr, aTextureInfo, aID, aImageContainer);
}
bool

View File

@ -37,7 +37,9 @@ class DataSourceSurface;
namespace layers {
class Layer;
class LayerComposite;
class Compositor;
class ImageContainerParent;
class ThebesBufferData;
class TiledContentHost;
class CompositableParentManager;
@ -75,7 +77,8 @@ public:
virtual void SetCompositor(Compositor* aCompositor);
// composite the contents of this buffer host to the compositor's surface
virtual void Composite(EffectChain& aEffectChain,
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
@ -131,6 +134,8 @@ public:
Layer* GetLayer() const { return mLayer; }
void SetLayer(Layer* aLayer) { mLayer = aLayer; }
virtual void SetImageContainer(ImageContainerParent* aImageContainer) {}
virtual TiledContentHost* AsTiledContentHost() { return nullptr; }
typedef uint32_t AttachFlags;
@ -184,6 +189,8 @@ public:
RefPtr<TextureHost> mTexture;
TimeStamp mTimeStamp;
gfx::IntRect mPictureRect;
int32_t mFrameID;
int32_t mProducerID;
};
virtual void UseTextureHost(const nsTArray<TimedTexture>& aTextures);
virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
@ -202,7 +209,8 @@ public:
static PCompositableParent*
CreateIPDLActor(CompositableParentManager* mgr,
const TextureInfo& textureInfo,
uint64_t asyncID);
uint64_t asyncID,
PImageContainerParent* aImageContainer = nullptr);
static bool DestroyIPDLActor(PCompositableParent* actor);
@ -270,7 +278,7 @@ private:
* is async, we store references to the async compositables in a CompositableMap
* that is accessed only on the compositor thread. During a layer transaction we
* send the message OpAttachAsyncCompositable(ID, PLayer), and on the compositor
* side we lookup the ID in the map and attach the correspondig compositable to
* side we lookup the ID in the map and attach the corresponding compositable to
* the layer.
*
* CompositableMap must be global because the image bridge doesn't have any

View File

@ -35,7 +35,8 @@ ContentHostBase::~ContentHostBase()
}
void
ContentHostTexture::Composite(EffectChain& aEffectChain,
ContentHostTexture::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const Filter& aFilter,

View File

@ -114,7 +114,8 @@ public:
, mLocked(false)
{ }
virtual void Composite(EffectChain& aEffectChain,
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,

View File

@ -4,11 +4,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageHost.h"
#include "LayersLogging.h" // for AppendToString
#include "composite/CompositableHost.h" // for CompositableHost, etc
#include "ipc/IPCMessageUtils.h" // for null_t
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
#include "mozilla/layers/ImageContainerParent.h"
#include "mozilla/layers/LayerManagerComposite.h" // for TexturedEffect, Effect, etc
#include "nsAString.h"
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
#include "nsPrintfCString.h" // for nsPrintfCString
@ -29,11 +32,16 @@ class ISurfaceAllocator;
ImageHost::ImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
, mImageContainer(nullptr)
, mLastFrameID(-1)
, mLastProducerID(-1)
, mLocked(false)
{}
ImageHost::~ImageHost()
{}
{
SetImageContainer(nullptr);
}
void
ImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
@ -54,9 +62,18 @@ ImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
// Create new TimedImage entries and recycle any mTextureSources that match
// our mFrontBuffers.
for (auto& t : aTextures) {
TimedImage& img = *newImages.AppendElement();
for (uint32_t i = 0; i < aTextures.Length(); ++i) {
const TimedTexture& t = aTextures[i];
MOZ_ASSERT(t.mTexture);
if (i + 1 < aTextures.Length() &&
t.mProducerID == mLastProducerID && t.mFrameID < mLastFrameID) {
// Ignore frames before a frame that we already composited. We don't
// ever want to display these frames. This could be important if
// the frame producer adjusts timestamps (e.g. to track the audio clock)
// and the new frame times are earlier.
continue;
}
TimedImage& img = *newImages.AppendElement();
img.mFrontBuffer = t.mTexture;
for (uint32_t i = 0; i < mImages.Length(); ++i) {
if (mImages[i].mFrontBuffer == img.mFrontBuffer) {
@ -67,6 +84,8 @@ ImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
}
img.mTimeStamp = t.mTimeStamp;
img.mPictureRect = t.mPictureRect;
img.mFrameID = t.mFrameID;
img.mProducerID = t.mProducerID;
}
// Recycle any leftover mTextureSources and call PrepareTextureSource on all
// images.
@ -107,8 +126,10 @@ int ImageHost::ChooseImageIndex() const
// Not in a composition, so just return the last image we composited
// (if it's one of the current images).
for (uint32_t i = 0; i < mImages.Length(); ++i) {
// For now there's only one image so we'll cheat until we can do better.
return i;
if (mImages[i].mFrameID == mLastFrameID &&
mImages[i].mProducerID == mLastProducerID) {
return i;
}
}
return -1;
}
@ -158,7 +179,8 @@ void ImageHost::Attach(Layer* aLayer,
}
void
ImageHost::Composite(EffectChain& aEffectChain,
ImageHost::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
@ -210,6 +232,17 @@ ImageHost::Composite(EffectChain& aEffectChain,
return;
}
if (mLastFrameID != img->mFrameID || mLastProducerID != img->mProducerID) {
if (mImageContainer) {
aLayer->GetLayerManager()->
AppendImageCompositeNotification(ImageCompositeNotification(
mImageContainer, nullptr,
img->mTimeStamp, GetCompositor()->GetCompositionTime(),
img->mFrameID, img->mProducerID));
}
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
}
aEffectChain.mPrimaryEffect = effect;
gfx::Rect pictureRect(0, 0, img->mPictureRect.width, img->mPictureRect.height);
BigImageIterator* it = img->mTextureSource->AsBigImageIterator();
@ -391,6 +424,18 @@ ImageHost::GenEffect(const gfx::Filter& aFilter)
GetRenderState());
}
void
ImageHost::SetImageContainer(ImageContainerParent* aImageContainer)
{
if (mImageContainer) {
mImageContainer->mImageHosts.RemoveElement(this);
}
mImageContainer = aImageContainer;
if (mImageContainer) {
mImageContainer->mImageHosts.AppendElement(this);
}
}
#ifdef MOZ_WIDGET_GONK
ImageHostOverlay::ImageHostOverlay(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
@ -402,7 +447,8 @@ ImageHostOverlay::~ImageHostOverlay()
}
void
ImageHostOverlay::Composite(EffectChain& aEffectChain,
ImageHostOverlay::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,

View File

@ -32,6 +32,7 @@ namespace layers {
class Compositor;
struct EffectChain;
class ImageContainerParent;
/**
* ImageHost. Works with ImageClientSingle and ImageClientBuffered
@ -44,7 +45,8 @@ public:
virtual CompositableType GetType() override { return mTextureInfo.mCompositableType; }
virtual void Composite(EffectChain& aEffectChain,
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
@ -63,6 +65,8 @@ public:
virtual void SetCompositor(Compositor* aCompositor) override;
virtual void SetImageContainer(ImageContainerParent* aImageContainer) override;
gfx::IntSize GetImageSize() const override;
virtual LayerRenderState GetRenderState() override;
@ -87,6 +91,8 @@ protected:
CompositableTextureSourceRef mTextureSource;
TimeStamp mTimeStamp;
gfx::IntRect mPictureRect;
int32_t mFrameID;
int32_t mProducerID;
};
/**
@ -99,6 +105,10 @@ protected:
int ChooseImageIndex() const;
nsTArray<TimedImage> mImages;
// Weak reference, will be null if mImageContainer has been destroyed.
ImageContainerParent* mImageContainer;
int32_t mLastFrameID;
int32_t mLastProducerID;
bool mLocked;
};
@ -115,7 +125,8 @@ public:
virtual CompositableType GetType() { return mTextureInfo.mCompositableType; }
virtual void Composite(EffectChain& aEffectChain,
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,

View File

@ -98,7 +98,7 @@ ImageLayerComposite::RenderLayer(const IntRect& aClipRect)
RenderWithAllMasks(this, mCompositor, aClipRect,
[&](EffectChain& effectChain, const Rect& clipRect) {
mImageHost->SetCompositor(mCompositor);
mImageHost->Composite(effectChain,
mImageHost->Composite(this, effectChain,
GetEffectiveOpacity(),
GetEffectiveTransformForBuffer(),
GetEffectFilter(),

View File

@ -19,6 +19,7 @@
#include "mozilla/gfx/Types.h" // for SurfaceFormat
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/Effects.h" // for EffectChain
#include "mozilla/layers/LayersMessages.h"
#include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc
#include "mozilla/Maybe.h" // for Maybe
#include "mozilla/RefPtr.h"
@ -261,6 +262,15 @@ public:
bool AsyncPanZoomEnabled() const override;
void AppendImageCompositeNotification(const ImageCompositeNotification& aNotification)
{
mImageCompositeNotifications.AppendElement(aNotification);
}
void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotification>* aNotifications)
{
aNotifications->MoveElementsFrom(mImageCompositeNotifications);
}
private:
/** Region we're clipping our current drawing to. */
nsIntRegion mClippingRegion;
@ -307,6 +317,8 @@ private:
RefPtr<Compositor> mCompositor;
UniquePtr<LayerProperties> mClonedLayerTreeProperties;
nsTArray<ImageCompositeNotification> mImageCompositeNotifications;
/**
* Context target, nullptr when drawing directly to our swap chain.
*/
@ -368,6 +380,8 @@ public:
virtual void SetLayerManager(LayerManagerComposite* aManager);
LayerManagerComposite* GetLayerManager() const { return mCompositeManager; }
/**
* Perform a first pass over the layer tree to render all of the intermediate
* surfaces that we can. This allows us to avoid framebuffer switches in the

View File

@ -129,7 +129,7 @@ PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect)
[&](EffectChain& effectChain, const Rect& clipRect) {
mBuffer->SetPaintWillResample(MayResample());
mBuffer->Composite(effectChain,
mBuffer->Composite(this, effectChain,
GetEffectiveOpacity(),
GetEffectiveTransform(),
GetEffectFilter(),

View File

@ -362,7 +362,8 @@ TiledLayerBufferComposite::Clear()
}
void
TiledContentHost::Composite(EffectChain& aEffectChain,
TiledContentHost::Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,

View File

@ -235,12 +235,13 @@ public:
bool UseTiledLayerBuffer(ISurfaceAllocator* aAllocator,
const SurfaceDescriptorTiles& aTiledDescriptor);
void Composite(EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr) override;
virtual void Composite(LayerComposite* aLayer,
EffectChain& aEffectChain,
float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter,
const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr) override;
virtual CompositableType GetType() override { return CompositableType::CONTENT_TILED; }

View File

@ -22,6 +22,7 @@ namespace layers {
class CompositableClient;
class AsyncTransactionTracker;
class ImageContainer;
struct TextureFactoryIdentifier;
class SurfaceDescriptor;
class SurfaceDescriptorTiles;
@ -50,7 +51,8 @@ public:
* Setup the IPDL actor for aCompositable to be part of layers
* transactions.
*/
virtual void Connect(CompositableClient* aCompositable) = 0;
virtual void Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer = nullptr) = 0;
/**
* Tell the CompositableHost on the compositor side what TiledLayerBuffer to
@ -129,9 +131,14 @@ public:
}
struct TimedTextureClient {
TimedTextureClient()
: mTextureClient(nullptr), mFrameID(0), mProducerID(0) {}
TextureClient* mTextureClient;
TimeStamp mTimeStamp;
nsIntRect mPictureRect;
int32_t mFrameID;
int32_t mProducerID;
};
/**
* Tell the CompositableHost on the compositor side what textures to use for

View File

@ -180,6 +180,8 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
MOZ_ASSERT(t->mTexture);
t->mTimeStamp = timedTexture.timeStamp();
t->mPictureRect = timedTexture.picture();
t->mFrameID = timedTexture.frameID();
t->mProducerID = timedTexture.producerID();
MOZ_ASSERT(ValidatePictureRect(t->mTexture->GetSize(), t->mPictureRect));
MaybeFence maybeFence = timedTexture.fence();

View File

@ -38,6 +38,7 @@
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/FrameUniformityData.h"
#include "mozilla/layers/ImageBridgeParent.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/PLayerTransactionParent.h"
@ -1842,6 +1843,13 @@ CompositorParent::DidComposite()
unused << SendDidComposite(0, mPendingTransaction);
mPendingTransaction = 0;
}
if (mLayerManager) {
nsTArray<ImageCompositeNotification> notifications;
mLayerManager->ExtractImageCompositeNotifications(&notifications);
if (!notifications.IsEmpty()) {
unused << ImageBridgeParent::NotifyImageComposites(notifications);
}
}
MonitorAutoLock lock(*sIndirectLayerTreesLock);
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();

View File

@ -29,6 +29,7 @@
#include "mozilla/layers/ImageClient.h" // for ImageClient
#include "mozilla/layers/LayersMessages.h" // for CompositableOperation
#include "mozilla/layers/PCompositableChild.h" // for PCompositableChild
#include "mozilla/layers/PImageContainerChild.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "mozilla/mozalloc.h" // for operator new, etc
#include "nsAutoPtr.h" // for nsRefPtr
@ -121,7 +122,8 @@ ImageBridgeChild::UseTextures(CompositableClient* aCompositable,
FenceHandle fence = t.mTextureClient->GetAcquireFenceHandle();
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()),
t.mTimeStamp, t.mPictureRect));
t.mTimeStamp, t.mPictureRect,
t.mFrameID, t.mProducerID));
}
mTxn->AddNoSwapEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
textures));
@ -216,10 +218,12 @@ static void ImageBridgeShutdownStep2(ReentrantMonitor *aBarrier, bool *aDone)
static void CreateImageClientSync(RefPtr<ImageClient>* result,
ReentrantMonitor* barrier,
CompositableType aType,
ImageContainer* aImageContainer,
bool *aDone)
{
ReentrantMonitorAutoEnter autoMon(*barrier);
*result = sImageBridgeChildSingleton->CreateImageClientNow(aType);
*result = sImageBridgeChildSingleton->CreateImageClientNow(
aType, aImageContainer);
*aDone = true;
barrier->NotifyAll();
}
@ -256,19 +260,22 @@ ImageBridgeChild::MarkShutDown()
}
void
ImageBridgeChild::Connect(CompositableClient* aCompositable)
ImageBridgeChild::Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer)
{
MOZ_ASSERT(aCompositable);
MOZ_ASSERT(!mShuttingDown);
uint64_t id = 0;
PCompositableChild* child =
SendPCompositableConstructor(aCompositable->GetTextureInfo(), &id);
SendPCompositableConstructor(aCompositable->GetTextureInfo(),
aImageContainer->GetPImageContainerChild(), &id);
MOZ_ASSERT(child);
aCompositable->InitIPDLActor(child, id);
}
PCompositableChild*
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID)
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo,
PImageContainerChild* aChild, uint64_t* aID)
{
MOZ_ASSERT(!mShuttingDown);
return CompositableClient::CreateIPDLActor();
@ -325,33 +332,43 @@ ConnectImageBridgeInChildProcess(Transport* aTransport,
#endif
}
static void ReleaseImageClientNow(ImageClient* aClient)
static void ReleaseImageClientNow(ImageClient* aClient,
PImageContainerChild* aChild)
{
MOZ_ASSERT(InImageBridgeChildThread());
aClient->Release();
if (aClient) {
aClient->Release();
}
if (aChild) {
aChild->SendAsyncDelete();
}
}
// static
void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient)
void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient,
PImageContainerChild* aChild)
{
if (!aClient) {
if (!aClient && !aChild) {
return;
}
if (!IsCreated()) {
// CompositableClient::Release should normally happen in the ImageBridgeChild
// thread because it usually generate some IPDL messages.
// However, if we take this branch it means that the ImageBridgeChild
// has already shut down, along with the CompositableChild, which means no
// message will be sent and it is safe to run this code from any thread.
MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
aClient->Release();
if (aClient) {
// CompositableClient::Release should normally happen in the ImageBridgeChild
// thread because it usually generate some IPDL messages.
// However, if we take this branch it means that the ImageBridgeChild
// has already shut down, along with the CompositableChild, which means no
// message will be sent and it is safe to run this code from any thread.
MOZ_ASSERT(aClient->GetIPDLActor() == nullptr);
aClient->Release();
}
delete aChild;
return;
}
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
FROM_HERE,
NewRunnableFunction(&ReleaseImageClientNow, aClient));
NewRunnableFunction(&ReleaseImageClientNow, aClient, aChild));
}
static void ReleaseTextureClientNow(TextureClient* aClient)
@ -389,7 +406,6 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine
MOZ_ASSERT(aContainer);
sImageBridgeChildSingleton->BeginTransaction();
aClient->UpdateImage(aContainer, Layer::CONTENT_OPAQUE);
aClient->OnTransaction();
sImageBridgeChildSingleton->EndTransaction();
}
@ -422,7 +438,6 @@ static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
aContainer->ClearCurrentImage();
}
aClient->FlushAllImages(aExceptFront, aWaiter);
aClient->OnTransaction();
sImageBridgeChildSingleton->EndTransaction();
// This decrement is balanced by the increment in FlushAllImages.
// If any AsyncTransactionTrackers were created by FlushAllImages and attached
@ -648,18 +663,20 @@ ImageBridgeChild::IdentifyCompositorTextureHost(const TextureFactoryIdentifier&
}
already_AddRefed<ImageClient>
ImageBridgeChild::CreateImageClient(CompositableType aType)
ImageBridgeChild::CreateImageClient(CompositableType aType,
ImageContainer* aImageContainer)
{
if (InImageBridgeChildThread()) {
return CreateImageClientNow(aType);
return CreateImageClientNow(aType, aImageContainer);
}
ReentrantMonitor barrier("CreateImageClient Lock");
ReentrantMonitorAutoEnter autoMon(barrier);
bool done = false;
RefPtr<ImageClient> result = nullptr;
GetMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction(&CreateImageClientSync,
&result, &barrier, aType, &done));
GetMessageLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&CreateImageClientSync, &result, &barrier, aType,
aImageContainer, &done));
// should stop the thread until the ImageClient has been created on
// the other thread
while (!done) {
@ -669,14 +686,18 @@ ImageBridgeChild::CreateImageClient(CompositableType aType)
}
already_AddRefed<ImageClient>
ImageBridgeChild::CreateImageClientNow(CompositableType aType)
ImageBridgeChild::CreateImageClientNow(CompositableType aType,
ImageContainer* aImageContainer)
{
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
if (aImageContainer) {
SendPImageContainerConstructor(aImageContainer->GetPImageContainerChild());
}
RefPtr<ImageClient> client
= ImageClient::CreateImageClient(aType, this, TextureFlags::NO_FLAGS);
MOZ_ASSERT(client, "failed to create ImageClient");
if (client) {
client->Connect();
client->Connect(aImageContainer);
}
return client.forget();
}
@ -833,6 +854,21 @@ ImageBridgeChild::DeallocPMediaSystemResourceManagerChild(PMediaSystemResourceMa
return true;
}
PImageContainerChild*
ImageBridgeChild::AllocPImageContainerChild()
{
// we always use the "power-user" ctor
NS_RUNTIMEABORT("not reached");
return nullptr;
}
bool
ImageBridgeChild::DeallocPImageContainerChild(PImageContainerChild* actor)
{
delete actor;
return true;
}
bool
ImageBridgeChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages)
{
@ -875,6 +911,15 @@ ImageBridgeChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageDat
return true;
}
bool
ImageBridgeChild::RecvDidComposite(InfallibleTArray<ImageCompositeNotification>&& aNotifications)
{
for (auto& n : aNotifications) {
ImageContainer::NotifyComposite(n);
}
return true;
}
PTextureChild*
ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags)

View File

@ -174,7 +174,8 @@ public:
*/
virtual MessageLoop * GetMessageLoop() const override;
PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID) override;
PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo,
PImageContainerChild* aChild, uint64_t* aID) override;
bool DeallocPCompositableChild(PCompositableChild* aActor) override;
/**
@ -191,17 +192,27 @@ public:
PMediaSystemResourceManagerChild*
AllocPMediaSystemResourceManagerChild() override;
bool
DeallocPMediaSystemResourceManagerChild(PMediaSystemResourceManagerChild* aActor) override;
virtual PImageContainerChild*
AllocPImageContainerChild() override;
virtual bool
DeallocPImageContainerChild(PImageContainerChild* actor) override;
virtual bool
RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
already_AddRefed<ImageClient> CreateImageClient(CompositableType aType);
already_AddRefed<ImageClient> CreateImageClientNow(CompositableType aType);
virtual bool
RecvDidComposite(InfallibleTArray<ImageCompositeNotification>&& aNotifications) override;
static void DispatchReleaseImageClient(ImageClient* aClient);
already_AddRefed<ImageClient> CreateImageClient(CompositableType aType,
ImageContainer* aImageContainer);
already_AddRefed<ImageClient> CreateImageClientNow(CompositableType aType,
ImageContainer* aImageContainer);
static void DispatchReleaseImageClient(ImageClient* aClient,
PImageContainerChild* aChild = nullptr);
static void DispatchReleaseTextureClient(TextureClient* aClient);
static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer);
@ -212,7 +223,8 @@ public:
// CompositableForwarder
virtual void Connect(CompositableClient* aCompositable) override;
virtual void Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer) override;
virtual bool IsImageBridgeChild() const override { return true; }

View File

@ -83,6 +83,12 @@ ImageBridgeParent::~ImageBridgeParent()
new DeleteTask<Transport>(mTransport));
}
nsTArray<PImageContainerParent*> parents;
ManagedPImageContainerParent(parents);
for (PImageContainerParent* p : parents) {
delete p;
}
sImageBridges.erase(OtherPid());
}
@ -236,11 +242,12 @@ static uint64_t GenImageContainerID() {
PCompositableParent*
ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
PImageContainerParent* aImageContainer,
uint64_t* aID)
{
uint64_t id = GenImageContainerID();
*aID = id;
return CompositableHost::CreateIPDLActor(this, aInfo, id);
return CompositableHost::CreateIPDLActor(this, aInfo, id, aImageContainer);
}
bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
@ -275,6 +282,19 @@ ImageBridgeParent::DeallocPMediaSystemResourceManagerParent(PMediaSystemResource
return true;
}
PImageContainerParent*
ImageBridgeParent::AllocPImageContainerParent()
{
return new ImageContainerParent();
}
bool
ImageBridgeParent::DeallocPImageContainerParent(PImageContainerParent* actor)
{
delete actor;
return true;
}
void
ImageBridgeParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
{
@ -287,6 +307,47 @@ ImageBridgeParent::RecvChildAsyncMessages(InfallibleTArray<AsyncChildMessageData
return true;
}
class ProcessIdComparator
{
public:
bool Equals(const ImageCompositeNotification& aA,
const ImageCompositeNotification& aB) const
{
return aA.imageContainerParent()->OtherPid() == aB.imageContainerParent()->OtherPid();
}
bool LessThan(const ImageCompositeNotification& aA,
const ImageCompositeNotification& aB) const
{
return aA.imageContainerParent()->OtherPid() < aB.imageContainerParent()->OtherPid();
}
};
/* static */ bool
ImageBridgeParent::NotifyImageComposites(nsTArray<ImageCompositeNotification>& aNotifications)
{
// Group the notifications by destination process ID and then send the
// notifications in one message per group.
aNotifications.Sort(ProcessIdComparator());
uint32_t i = 0;
bool ok = true;
while (i < aNotifications.Length()) {
nsAutoTArray<ImageCompositeNotification,1> notifications;
notifications.AppendElement(aNotifications[i]);
uint32_t end = i + 1;
ProcessId pid = aNotifications[i].imageContainerParent()->OtherPid();
while (end < aNotifications.Length() &&
aNotifications[end].imageContainerParent()->OtherPid() == pid) {
notifications.AppendElement(aNotifications[end]);
++end;
}
if (!GetInstance(pid)->SendDidComposite(notifications)) {
ok = false;
}
i = end;
}
return ok;
}
MessageLoop * ImageBridgeParent::GetMessageLoop() const {
return mMessageLoop;
}

View File

@ -9,6 +9,7 @@
#include <stddef.h> // for size_t
#include <stdint.h> // for uint32_t, uint64_t
#include "CompositableTransactionParent.h"
#include "ImageContainerParent.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/Attributes.h" // for override
#include "mozilla/ipc/ProtocolUtils.h"
@ -74,6 +75,7 @@ public:
virtual bool IsAsync() const override { return true; }
PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo,
PImageContainerParent* aImageContainer,
uint64_t*) override;
bool DeallocPCompositableParent(PCompositableParent* aActor) override;
@ -83,6 +85,8 @@ public:
PMediaSystemResourceManagerParent* AllocPMediaSystemResourceManagerParent() override;
bool DeallocPMediaSystemResourceManagerParent(PMediaSystemResourceManagerParent* aActor) override;
virtual PImageContainerParent* AllocPImageContainerParent() override;
virtual bool DeallocPImageContainerParent(PImageContainerParent* actor) override;
virtual bool
RecvChildAsyncMessages(InfallibleTArray<AsyncChildMessageData>&& aMessages) override;
@ -139,6 +143,8 @@ public:
static ImageBridgeParent* GetInstance(ProcessId aId);
static bool NotifyImageComposites(nsTArray<ImageCompositeNotification>& aNotifications);
// Overriden from IToplevelProtocol
IToplevelProtocol*
CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,

View File

@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 "ImageContainerParent.h"
#include "nsThreadUtils.h"
#include "mozilla/layers/ImageHost.h"
namespace mozilla {
namespace layers {
ImageContainerParent::~ImageContainerParent()
{
while (!mImageHosts.IsEmpty()) {
mImageHosts[mImageHosts.Length() - 1]->SetImageContainer(nullptr);
}
}
static void SendDeleteAndIgnoreResult(ImageContainerParent* self)
{
unused << PImageContainerParent::Send__delete__(self);
}
bool ImageContainerParent::RecvAsyncDelete()
{
MessageLoop::current()->PostTask(
FROM_HERE, NewRunnableFunction(&SendDeleteAndIgnoreResult, this));
return true;
}
}
}

View File

@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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_layers_ImageContainerParent_h
#define mozilla_layers_ImageContainerParent_h
#include "mozilla/Attributes.h" // for override
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/PImageContainerParent.h"
#include "nsAutoPtr.h" // for nsRefPtr
namespace mozilla {
namespace layers {
class ImageHost;
class ImageContainerParent : public PImageContainerParent
{
public:
ImageContainerParent() {}
~ImageContainerParent();
virtual bool RecvAsyncDelete() override;
nsAutoTArray<ImageHost*,1> mImageHosts;
private:
virtual void ActorDestroy(ActorDestroyReason why) override {}
};
} // namespace layers
} // namespace mozilla
#endif // ifndef mozilla_layers_ImageContainerParent_h

View File

@ -9,6 +9,7 @@
#include "mozilla/layers/CompositableClient.h" // for CompositableChild
#include "mozilla/layers/PCompositableChild.h" // for PCompositableChild
#include "mozilla/layers/PLayerChild.h" // for PLayerChild
#include "mozilla/layers/PImageContainerChild.h"
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsDebug.h" // for NS_RUNTIMEABORT, etc

View File

@ -581,7 +581,6 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
if (!Attach(cast(op.layerParent()), host, true)) {
return false;
}
host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
break;
}

View File

@ -9,6 +9,7 @@ include LayersSurfaces;
include protocol PCompositable;
include protocol PCompositor;
include protocol PLayer;
include protocol PImageContainer;
include protocol PRenderFrame;
include protocol PTexture;
@ -54,7 +55,7 @@ struct TargetConfig {
};
// Create a shadow layer for |layer|
struct OpCreatePaintedLayer { PLayer layer; };
struct OpCreatePaintedLayer { PLayer layer; };
struct OpCreateContainerLayer { PLayer layer; };
struct OpCreateImageLayer { PLayer layer; };
struct OpCreateColorLayer { PLayer layer; };
@ -388,6 +389,8 @@ struct TimedTexture {
MaybeFence fence;
TimeStamp timeStamp;
IntRect picture;
int32_t frameID;
int32_t producerID;
};
/**
@ -473,6 +476,18 @@ struct OpContentBufferSwap {
nsIntRegion frontUpdatedRegion;
};
/**
* An ImageCompositeNotification is sent the first time a particular
* image is composited by an ImageHost.
*/
struct ImageCompositeNotification {
PImageContainer imageContainer;
TimeStamp imageTimeStamp;
TimeStamp firstCompositeTimeStamp;
int32_t frameID;
int32_t producerID;
};
// Unit of a "changeset reply". This is a weird abstraction, probably
// only to be used for buffer swapping.
union EditReply {

View File

@ -7,6 +7,7 @@
include LayersSurfaces;
include LayersMessages;
include protocol PLayer;
include protocol PLayerTransaction;
include "mozilla/GfxMessageUtils.h";
include "nsRegion.h";
@ -42,6 +43,8 @@ child:
// The compositor completed a layers transaction. id is the layers id
// of the child layer tree that was composited (or 0 when notifying
// the root layer tree).
// transactionId is the id of the transaction before this composite, or 0
// if there was no transaction since the last composite.
async DidComposite(uint64_t id, uint64_t transactionId);
// The parent sends the child the requested fill ratio numbers.

View File

@ -6,6 +6,7 @@
include LayersSurfaces;
include LayersMessages;
include protocol PCompositable;
include protocol PImageContainer;
include protocol PLayer;
include protocol PTexture;
include ProtocolTypes;
@ -31,12 +32,14 @@ sync protocol PImageBridge
manages PCompositable;
manages PTexture;
manages PMediaSystemResourceManager;
manages PImageContainer;
child:
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
parent:
async DidComposite(ImageCompositeNotification[] aNotifications);
parent:
async ImageBridgeThreadId(PlatformThreadId aTreahdId);
sync Update(CompositableOperation[] ops) returns (EditReply[] reply);
@ -54,9 +57,11 @@ parent:
// Second step
sync Stop();
sync PCompositable(TextureInfo aInfo) returns (uint64_t id);
sync PCompositable(TextureInfo aInfo,
PImageContainer aImageContainer) returns (uint64_t id);
async PTexture(SurfaceDescriptor aSharedData, TextureFlags aTextureFlags);
async PMediaSystemResourceManager();
async PImageContainer();
async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
};

View File

@ -0,0 +1,33 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 protocol PImageBridge;
namespace mozilla {
namespace layers {
/**
* PImageContainer represents an ImageContainer.
*/
async protocol PImageContainer {
manager PImageBridge;
parent:
/**
* The child effectively owns the parent. When the child should be
* destroyed, it sends an AsyncDelete to the parent but does not die
* because we could still have messages in flight from the compositor
* mentioning the child. The parent handles AsyncDelete by destroying
* itself and sending __delete__ to the child to clean it up.
*/
async AsyncDelete();
child:
async __delete__();
};
} // layers
} // mozilla

View File

@ -25,12 +25,25 @@ ShadowLayerParent::ShadowLayerParent() : mLayer(nullptr)
ShadowLayerParent::~ShadowLayerParent()
{
Disconnect();
}
void
ShadowLayerParent::Disconnect()
{
if (mLayer) {
mLayer->Disconnect();
mLayer = nullptr;
}
}
void
ShadowLayerParent::Bind(Layer* layer)
{
mLayer = layer;
if (mLayer != layer) {
Disconnect();
mLayer = layer;
}
}
void
@ -40,9 +53,7 @@ ShadowLayerParent::Destroy()
// created, but just before the transaction in which Bind() would
// have been called. In that case, we'll ignore shadow-layers
// transactions from there on and never get a layer here.
if (mLayer) {
mLayer->Disconnect();
}
Disconnect();
}
ContainerLayerComposite*
@ -103,15 +114,11 @@ ShadowLayerParent::ActorDestroy(ActorDestroyReason why)
case Deletion:
// See comment near Destroy() above.
if (mLayer) {
mLayer->Disconnect();
}
Disconnect();
break;
case AbnormalShutdown:
if (mLayer) {
mLayer->Disconnect();
}
Disconnect();
break;
case NormalShutdown:

View File

@ -48,6 +48,8 @@ public:
private:
virtual void ActorDestroy(ActorDestroyReason why) override;
void Disconnect();
nsRefPtr<Layer> mLayer;
};

View File

@ -364,7 +364,8 @@ ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable,
FenceHandle fence = t.mTextureClient->GetAcquireFenceHandle();
textures.AppendElement(TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(),
fence.IsValid() ? MaybeFence(fence) : MaybeFence(null_t()),
t.mTimeStamp, t.mPictureRect));
t.mTimeStamp, t.mPictureRect,
t.mFrameID, t.mProducerID));
if ((t.mTextureClient->GetFlags() & TextureFlags::IMMEDIATE_UPLOAD)
&& t.mTextureClient->HasInternalBuffer()) {
@ -767,7 +768,8 @@ ShadowLayerForwarder::PlatformSyncBeforeUpdate()
#endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
void
ShadowLayerForwarder::Connect(CompositableClient* aCompositable)
ShadowLayerForwarder::Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer)
{
#ifdef GFX_COMPOSITOR_LOGGING
printf("ShadowLayerForwarder::Connect(Compositable)\n");

View File

@ -27,6 +27,7 @@ namespace mozilla {
namespace layers {
class EditReply;
class ImageContainer;
class Layer;
class PLayerChild;
class PLayerTransactionChild;
@ -123,7 +124,8 @@ public:
* Setup the IPDL actor for aCompositable to be part of layers
* transactions.
*/
void Connect(CompositableClient* aCompositable) override;
virtual void Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer) override;
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
TextureFlags aFlags) override;

View File

@ -147,9 +147,11 @@ EXPORTS.mozilla.layers += [
'ipc/FenceUtils.h',
'ipc/ImageBridgeChild.h',
'ipc/ImageBridgeParent.h',
'ipc/ImageContainerParent.h',
'ipc/ISurfaceAllocator.h',
'ipc/LayerTransactionChild.h',
'ipc/LayerTransactionParent.h',
'ipc/ShadowLayerChild.h',
'ipc/ShadowLayers.h',
'ipc/ShadowLayersManager.h',
'ipc/SharedBufferManagerChild.h',
@ -303,6 +305,7 @@ UNIFIED_SOURCES += [
'ipc/FenceUtils.cpp',
'ipc/ImageBridgeChild.cpp',
'ipc/ImageBridgeParent.cpp',
'ipc/ImageContainerParent.cpp',
'ipc/ISurfaceAllocator.cpp',
'ipc/LayerTransactionChild.cpp',
'ipc/LayerTransactionParent.cpp',
@ -364,6 +367,7 @@ IPDL_SOURCES = [
'ipc/PCompositable.ipdl',
'ipc/PCompositor.ipdl',
'ipc/PImageBridge.ipdl',
'ipc/PImageContainer.ipdl',
'ipc/PLayer.ipdl',
'ipc/PLayerTransaction.ipdl',
'ipc/PSharedBufferManager.ipdl',

View File

@ -26,7 +26,6 @@ class InputEvent;
namespace layers {
class APZCTreeManager;
class TargetConfig;
class LayerTransactionParent;
struct TextureFactoryIdentifier;
struct ScrollableLayerGuid;
}
@ -42,7 +41,6 @@ class RenderFrameParent : public PRenderFrameParent
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::TargetConfig TargetConfig;
typedef mozilla::layers::LayerTransactionParent LayerTransactionParent;
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
typedef mozilla::layers::TextureFactoryIdentifier TextureFactoryIdentifier;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;