gecko-dev/gfx/layers/ipc/ImageBridgeChild.h

387 строки
14 KiB
C
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_IMAGEBRIDGECHILD_H
#define MOZILLA_GFX_IMAGEBRIDGECHILD_H
#include <stddef.h> // for size_t
#include <stdint.h> // for uint32_t, uint64_t
#include "mozilla/Attributes.h" // for override
#include "mozilla/Atomics.h"
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
#include "mozilla/RefPtr.h" // for already_AddRefed
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTrackerHolder
#include "mozilla/layers/CanvasClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/PImageBridgeChild.h"
#include "mozilla/Mutex.h"
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsRegion.h" // for nsIntRegion
#include "mozilla/gfx/Rect.h"
class MessageLoop;
namespace base {
class Thread;
} // namespace base
namespace mozilla {
namespace ipc {
class Shmem;
} // namespace ipc
namespace layers {
class AsyncCanvasRenderer;
class AsyncTransactionTracker;
class ImageClient;
class ImageContainer;
class ImageBridgeParent;
class CompositableClient;
struct CompositableTransaction;
class Image;
class TextureClient;
/**
* Returns true if the current thread is the ImageBrdigeChild's thread.
*
* Can be called from any thread.
*/
bool InImageBridgeChildThread();
/**
* The ImageBridge protocol is meant to allow ImageContainers to forward images
* directly to the compositor thread/process without using the main thread.
*
* ImageBridgeChild is a CompositableForwarder just like ShadowLayerForwarder.
* This means it also does transactions with the compositor thread/process,
* except that the transactions are restricted to operations on the Compositables
* and cannot contain messages affecting layers directly.
*
* ImageBridgeChild is also a ISurfaceAllocator. It can be used to allocate or
* deallocate data that is shared with the compositor. The main differerence
* with other ISurfaceAllocators is that some of its overriden methods can be
* invoked from any thread.
*
* There are three important phases in the ImageBridge protocol. These three steps
* can do different things depending if (A) the ImageContainer uses ImageBridge
* or (B) it does not use ImageBridge:
*
* - When an ImageContainer calls its method SetCurrentImage:
* - (A) The image is sent directly to the compositor process through the
* ImageBridge IPDL protocol.
* On the compositor side the image is stored in a global table that associates
* the image with an ID corresponding to the ImageContainer, and a composition is
* triggered.
* - (B) Since it does not have an ImageBridge, the image is not sent yet.
* instead the will be sent to the compositor during the next layer transaction
* (on the main thread).
*
* - During a Layer transaction:
* - (A) The ImageContainer uses ImageBridge. The image is already available to the
* compositor process because it has been sent with SetCurrentImage. Yet, the
* CompositableHost on the compositor side will needs the ID referring to the
* ImageContainer to access the Image. So during the Swap operation that happens
* in the transaction, we swap the container ID rather than the image data.
* - (B) Since the ImageContainer does not use ImageBridge, the image data is swaped.
*
* - During composition:
* - (A) The CompositableHost has an AsyncID, it looks up the ID in the
* global table to see if there is an image. If there is no image, nothing is rendered.
* - (B) The CompositableHost has image data rather than an ID (meaning it is not
* using ImageBridge), then it just composites the image data normally.
*
* This means that there might be a possibility for the ImageBridge to send the first
* frame before the first layer transaction that will pass the container ID to the
* CompositableHost happens. In this (unlikely) case the layer is not composited
* until the layer transaction happens. This means this scenario is not harmful.
*
* Since sending an image through imageBridge triggers compositing, the main thread is
* not used at all (except for the very first transaction that provides the
* CompositableHost with an AsyncID).
*/
class ImageBridgeChild final : public PImageBridgeChild
, public CompositableForwarder
, public ShmemAllocator
{
friend class ImageContainer;
typedef InfallibleTArray<AsyncParentMessageData> AsyncParentMessageArray;
public:
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
/**
* Creates the image bridge with a dedicated thread for ImageBridgeChild.
*
* We may want to use a specifi thread in the future. In this case, use
* CreateWithThread instead.
*/
static void StartUp();
static PImageBridgeChild*
StartUpInChildProcess(Transport* aTransport, ProcessId aOtherProcess);
/**
* Destroys the image bridge by calling DestroyBridge, and destroys the
* ImageBridge's thread.
*
* If you don't want to destroy the thread, call DestroyBridge directly
* instead.
*/
static void ShutDown();
/**
* Creates the ImageBridgeChild manager protocol.
*/
static bool StartUpOnThread(base::Thread* aThread);
/**
* Returns true if the singleton has been created.
*
* Can be called from any thread.
*/
static bool IsCreated();
/**
* Returns true if the singleton's ShutDown() was called.
*
* Can be called from any thread.
*/
static bool IsShutDown()
{
return sIsShutDown;
}
/**
* returns the singleton instance.
*
* can be called from any thread.
*/
static ImageBridgeChild* GetSingleton();
/**
* Dispatches a task to the ImageBridgeChild thread to do the connection
*/
void ConnectAsync(ImageBridgeParent* aParent);
using PImageBridgeChild::SendImageBridgeThreadId;
void SendImageBridgeThreadId();
static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier);
void BeginTransaction();
void EndTransaction();
/**
* Returns the ImageBridgeChild's thread.
*
* Can be called from any thread.
*/
base::Thread * GetThread() const;
/**
* Returns the ImageBridgeChild's message loop.
*
* Can be called from any thread.
*/
virtual MessageLoop * GetMessageLoop() const override;
virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo,
PImageContainerChild* aChild, uint64_t* aID) override;
bool DeallocPCompositableChild(PCompositableChild* aActor) override;
/**
* This must be called by the static function DeleteImageBridgeSync defined
* in ImageBridgeChild.cpp ONLY.
*/
~ImageBridgeChild();
virtual PTextureChild*
AllocPTextureChild(const SurfaceDescriptor& aSharedData, const LayersBackend& aLayersBackend, const TextureFlags& aFlags, const uint64_t& aSerial) override;
virtual bool
DeallocPTextureChild(PTextureChild* actor) override;
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;
virtual bool
RecvDidComposite(InfallibleTArray<ImageCompositeNotification>&& aNotifications) override;
already_AddRefed<ImageClient> CreateImageClient(CompositableType aType,
ImageContainer* aImageContainer);
already_AddRefed<ImageClient> CreateImageClientNow(CompositableType aType,
ImageContainer* aImageContainer);
already_AddRefed<CanvasClient> CreateCanvasClient(CanvasClient::CanvasClientType aType,
TextureFlags aFlag);
already_AddRefed<CanvasClient> CreateCanvasClientNow(CanvasClient::CanvasClientType aType,
TextureFlags aFlag);
static void DispatchReleaseImageClient(ImageClient* aClient,
PImageContainerChild* aChild = nullptr);
static void DispatchReleaseCanvasClient(CanvasClient* aClient);
static void DispatchReleaseTextureClient(TextureClient* aClient);
static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer);
static void UpdateAsyncCanvasRenderer(AsyncCanvasRenderer* aClient);
static void UpdateAsyncCanvasRendererNow(AsyncCanvasRenderer* aClient);
/**
* Flush all Images sent to CompositableHost.
*/
static void FlushAllImages(ImageClient* aClient, ImageContainer* aContainer);
// CompositableForwarder
virtual void Connect(CompositableClient* aCompositable,
ImageContainer* aImageContainer) override;
virtual bool UsesImageBridge() const override { return true; }
/**
* See CompositableForwarder::UseTextures
*/
virtual void UseTextures(CompositableClient* aCompositable,
const nsTArray<TimedTextureClient>& aTextures) override;
virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
TextureClient* aClientOnBlack,
TextureClient* aClientOnWhite) override;
#ifdef MOZ_WIDGET_GONK
virtual void UseOverlaySource(CompositableClient* aCompositable,
const OverlaySource& aOverlay,
const nsIntRect& aPictureRect) override;
#endif
/**
* Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
* Host side's usage is checked via CompositableRef.
*/
void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
/**
* Notify id of Texture When host side end its use. Transaction id is used to
* make sure if there is no newer usage.
*/
void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
void DeliverFence(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle);
void HoldUntilFenceHandleDelivery(TextureClient* aClient, uint64_t aTransactionId);
void DeliverFenceToNonRecycle(uint64_t aTextureId, FenceHandle& aReleaseFenceHandle);
void NotifyNotUsedToNonRecycle(uint64_t aTextureId, uint64_t aTransactionId);
void CancelWaitFenceHandle(TextureClient* aClient);
virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
virtual bool DestroyInTransaction(PTextureChild* aTexture, bool synchronously) override;
virtual bool DestroyInTransaction(PCompositableChild* aCompositable, bool synchronously) override;
virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable,
TextureClient* aTexture) override;
virtual void RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aAsyncTransactionTracker,
CompositableClient* aCompositable,
TextureClient* aTexture) override;
virtual void UseTiledLayerBuffer(CompositableClient* aCompositable,
const SurfaceDescriptorTiles& aTileLayerDescriptor) override
{
NS_RUNTIMEABORT("should not be called");
}
virtual void UpdateTextureRegion(CompositableClient* aCompositable,
const ThebesBufferData& aThebesBufferData,
const nsIntRegion& aUpdatedRegion) override {
NS_RUNTIMEABORT("should not be called");
}
// ISurfaceAllocator
/**
* See ISurfaceAllocator.h
* Can be used from any thread.
* If used outside the ImageBridgeChild thread, it will proxy a synchronous
* call on the ImageBridgeChild thread.
*/
virtual bool AllocUnsafeShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
virtual bool AllocShmem(size_t aSize,
mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
mozilla::ipc::Shmem* aShmem) override;
/**
* See ISurfaceAllocator.h
* Can be used from any thread.
* If used outside the ImageBridgeChild thread, it will proxy a synchronous
* call on the ImageBridgeChild thread.
*/
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial) override;
virtual bool IsSameProcess() const override;
virtual void UpdateFwdTransactionId() override { ++mFwdTransactionId; }
virtual uint64_t GetFwdTransactionId() override { return mFwdTransactionId; }
void MarkShutDown();
void FallbackDestroyActors();
protected:
ImageBridgeChild();
bool DispatchAllocShmemInternal(size_t aSize,
SharedMemory::SharedMemoryType aType,
Shmem* aShmem,
bool aUnsafe);
CompositableTransaction* mTxn;
Atomic<bool> mShuttingDown;
static Atomic<bool> sIsShutDown;
/**
* Transaction id of CompositableForwarder.
* It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction() call.
*/
uint64_t mFwdTransactionId;
/**
* Hold TextureClients refs until end of their usages on host side.
* It defer calling of TextureClient recycle callback.
*/
nsDataHashtable<nsUint64HashKey, RefPtr<TextureClient> > mTexturesWaitingRecycled;
AsyncTransactionTrackersHolder mTrackersHolder;
#ifdef MOZ_WIDGET_GONK
Mutex mWaitingFenceHandleMutex;
nsDataHashtable<nsUint64HashKey, RefPtr<TextureClient> > mTexturesWaitingFenceHandle;
#endif
};
} // namespace layers
} // namespace mozilla
#endif