mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
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:
parent
6111862fcc
commit
68954a66d8
@ -47,6 +47,7 @@ class RenderFrameChild;
|
||||
|
||||
namespace layers {
|
||||
class APZEventState;
|
||||
class ImageCompositeNotification;
|
||||
struct SetTargetAPZCCallback;
|
||||
struct SetAllowedTouchBehaviorCallback;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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(¬ifications);
|
||||
if (!notifications.IsEmpty()) {
|
||||
unused << ImageBridgeParent::NotifyImageComposites(notifications);
|
||||
}
|
||||
}
|
||||
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
for (LayerTreeMap::iterator it = sIndirectLayerTrees.begin();
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
37
gfx/layers/ipc/ImageContainerParent.cpp
Normal file
37
gfx/layers/ipc/ImageContainerParent.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
38
gfx/layers/ipc/ImageContainerParent.h
Normal file
38
gfx/layers/ipc/ImageContainerParent.h
Normal 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
|
@ -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
|
||||
|
@ -581,7 +581,6 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray<Edit>&& cset,
|
||||
if (!Attach(cast(op.layerParent()), host, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
|
||||
break;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
};
|
||||
|
33
gfx/layers/ipc/PImageContainer.ipdl
Normal file
33
gfx/layers/ipc/PImageContainer.ipdl
Normal 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
|
@ -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:
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
private:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
void Disconnect();
|
||||
|
||||
nsRefPtr<Layer> mLayer;
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user