Source code
Revision control
Copy as Markdown
Other Tools
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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
#ifndef mozilla_layers_CanvasChild_h
#define mozilla_layers_CanvasChild_h
#include "mozilla/gfx/RecordedEvent.h"
#include "mozilla/ipc/CrossProcessSemaphore.h"
#include "mozilla/layers/PCanvasChild.h"
#include "mozilla/layers/SourceSurfaceSharedData.h"
#include "mozilla/WeakPtr.h"
namespace mozilla {
namespace dom {
class ThreadSafeWorkerRef;
}
namespace gfx {
class DrawTargetRecording;
class SourceSurface;
} // namespace gfx
namespace layers {
class CanvasDrawEventRecorder;
struct RemoteTextureOwnerId;
class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
public:
NS_INLINE_DECL_REFCOUNTING(CanvasChild)
explicit CanvasChild(dom::ThreadSafeWorkerRef* aWorkerRef);
/**
* @returns true if remote canvas has been deactivated due to failure.
*/
static bool Deactivated() { return mDeactivated; }
/**
* Release resources until they are next required.
*/
void ClearCachedResources();
ipc::IPCResult RecvNotifyDeviceChanged();
ipc::IPCResult RecvNotifyDeviceReset(
const nsTArray<RemoteTextureOwnerId>& aOwnerIds);
ipc::IPCResult RecvDeactivate();
ipc::IPCResult RecvBlockCanvas();
ipc::IPCResult RecvNotifyRequiresRefresh(
const RemoteTextureOwnerId aTextureOwnerId);
ipc::IPCResult RecvSnapshotShmem(const RemoteTextureOwnerId aTextureOwnerId,
Handle&& aShmemHandle, uint32_t aShmemSize,
SnapshotShmemResolver&& aResolve);
ipc::IPCResult RecvNotifyTextureDestruction(
const RemoteTextureOwnerId aTextureOwnerId);
/**
* Ensures that the DrawEventRecorder has been created.
*
* @params aTextureType the TextureType to create in the CanvasTranslator.
* @returns true if the recorder was successfully created
*/
bool EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureType aTextureType, TextureType aWebglTextureType);
/**
* Clean up IPDL actor.
*/
void Destroy();
/**
* @returns true if we should be caching data surfaces in the GPU process.
*/
bool ShouldCacheDataSurface() const {
return mTransactionsSinceGetDataSurface < kCacheDataSurfaceThreshold;
}
/**
* Ensures that we have sent a begin transaction event, since the last
* end transaction.
* @returns false on failure to begin transaction
*/
bool EnsureBeginTransaction();
/**
* Send an end transaction event to indicate the end of events for this frame.
*/
void EndTransaction();
/**
* @returns true if the canvas IPC classes have not been used for some time
* and can be cleaned up.
*/
bool ShouldBeCleanedUp() const;
/**
* Create a DrawTargetRecording for a canvas texture.
* @param aTextureOwnerId the id of the new texture
* @param aSize size for the DrawTarget
* @param aFormat SurfaceFormat for the DrawTarget
* @returns newly created DrawTargetRecording
*/
already_AddRefed<gfx::DrawTargetRecording> CreateDrawTarget(
const RemoteTextureOwnerId& aTextureOwnerId, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat);
/**
* Record an event for processing by the CanvasParent's CanvasTranslator.
* @param aEvent the event to record
*/
void RecordEvent(const gfx::RecordedEvent& aEvent);
int64_t CreateCheckpoint();
/**
* Wrap the given surface, so that we can provide a DataSourceSurface if
* required.
* @param aSurface the SourceSurface to wrap
* @param aTextureOwnerId the texture id of the source TextureData
* @returns a SourceSurface that can provide a DataSourceSurface if required
*/
already_AddRefed<gfx::SourceSurface> WrapSurface(
const RefPtr<gfx::SourceSurface>& aSurface,
const RemoteTextureOwnerId aTextureOwnerId);
/**
* The DrawTargetRecording backing the surface has not been modified since the
* previous use, so it is safe to reattach the snapshot for readback.
*/
void AttachSurface(const RefPtr<gfx::SourceSurface>& aSurface);
/**
* The DrawTargetRecording is about to change, so detach the old snapshot.
*/
void DetachSurface(const RefPtr<gfx::SourceSurface>& aSurface,
bool aInvalidate = false);
/**
* Get DataSourceSurface from the translated equivalent version of aSurface in
* the GPU process.
* @param aTextureOwnerId the source TextureData to read from
* @param aSurface the SourceSurface in this process for which we need a
* DataSourceSurface
* @param aDetached whether the surface is old
* @param aMayInvalidate whether the data may be invalidated by future changes
* @returns a DataSourceSurface created from data for aSurface retrieve from
* GPU process
*/
already_AddRefed<gfx::DataSourceSurface> GetDataSurface(
const RemoteTextureOwnerId aTextureOwnerId,
const gfx::SourceSurface* aSurface, bool aDetached, bool& aMayInvalidate);
bool RequiresRefresh(const RemoteTextureOwnerId aTextureOwnerId) const;
void ReturnDataSurfaceShmem(
already_AddRefed<ipc::SharedMemory> aDataSurfaceShmem);
protected:
void ActorDestroy(ActorDestroyReason aWhy) final;
private:
DISALLOW_COPY_AND_ASSIGN(CanvasChild);
~CanvasChild() final;
bool EnsureDataSurfaceShmem(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
static void ReleaseDataShmemHolder(void* aClosure);
void DropFreeBuffersWhenDormant();
static const uint32_t kCacheDataSurfaceThreshold = 10;
static bool mDeactivated;
RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef;
RefPtr<CanvasDrawEventRecorder> mRecorder;
RefPtr<ipc::SharedMemory> mDataSurfaceShmem;
bool mDataSurfaceShmemAvailable = false;
int64_t mLastWriteLockCheckpoint = 0;
uint32_t mTransactionsSinceGetDataSurface = kCacheDataSurfaceThreshold;
struct TextureInfo {
RefPtr<mozilla::ipc::SharedMemory> mSnapshotShmem;
bool mRequiresRefresh = false;
};
std::unordered_map<RemoteTextureOwnerId, TextureInfo,
RemoteTextureOwnerId::HashFn>
mTextureInfo;
bool mIsInTransaction = false;
bool mDormant = false;
bool mBlocked = false;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_CanvasChild_h