summaryrefslogtreecommitdiffstats
path: root/gfx/layers/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/ipc')
-rw-r--r--gfx/layers/ipc/CanvasChild.cpp164
-rw-r--r--gfx/layers/ipc/CanvasChild.h20
-rw-r--r--gfx/layers/ipc/CanvasTranslator.cpp32
-rw-r--r--gfx/layers/ipc/CanvasTranslator.h3
-rw-r--r--gfx/layers/ipc/CompositorManagerChild.cpp11
-rw-r--r--gfx/layers/ipc/LayersMessageUtils.h2
-rw-r--r--gfx/layers/ipc/PCanvas.ipdl6
-rw-r--r--gfx/layers/ipc/VideoBridgeParent.cpp5
8 files changed, 185 insertions, 58 deletions
diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp
index 553217d82b..515463cd8e 100644
--- a/gfx/layers/ipc/CanvasChild.cpp
+++ b/gfx/layers/ipc/CanvasChild.cpp
@@ -7,6 +7,9 @@
#include "CanvasChild.h"
#include "MainThreadUtils.h"
+#include "mozilla/dom/WorkerPrivate.h"
+#include "mozilla/dom/WorkerRef.h"
+#include "mozilla/dom/WorkerRunnable.h"
#include "mozilla/gfx/CanvasManagerChild.h"
#include "mozilla/gfx/DrawTargetRecording.h"
#include "mozilla/gfx/Tools.h"
@@ -18,6 +21,7 @@
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/SourceSurfaceSharedData.h"
#include "mozilla/Maybe.h"
+#include "mozilla/Mutex.h"
#include "nsIObserverService.h"
#include "RecordedCanvasEventImpl.h"
@@ -33,9 +37,9 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers {
~RecorderHelpers() override = default;
- bool InitTranslator(TextureType aTextureType, gfx::BackendType aBackendType,
- Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles,
- uint64_t aBufferSize,
+ bool InitTranslator(TextureType aTextureType, TextureType aWebglTextureType,
+ gfx::BackendType aBackendType, Handle&& aReadHandle,
+ nsTArray<Handle>&& aBufferHandles, uint64_t aBufferSize,
CrossProcessSemaphoreHandle&& aReaderSem,
CrossProcessSemaphoreHandle&& aWriterSem) override {
NS_ASSERT_OWNINGTHREAD(RecorderHelpers);
@@ -43,7 +47,7 @@ class RecorderHelpers final : public CanvasDrawEventRecorder::Helpers {
return false;
}
return mCanvasChild->SendInitTranslator(
- aTextureType, aBackendType, std::move(aReadHandle),
+ aTextureType, aWebglTextureType, aBackendType, std::move(aReadHandle),
std::move(aBufferHandles), aBufferSize, std::move(aReaderSem),
std::move(aWriterSem));
}
@@ -165,9 +169,104 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
bool mDetached = false;
};
-CanvasChild::CanvasChild() = default;
+class CanvasDataShmemHolder {
+ public:
+ CanvasDataShmemHolder(ipc::SharedMemoryBasic* aShmem,
+ CanvasChild* aCanvasChild)
+ : mMutex("CanvasChild::DataShmemHolder::mMutex"),
+ mShmem(aShmem),
+ mCanvasChild(aCanvasChild) {}
+
+ bool Init(dom::ThreadSafeWorkerRef* aWorkerRef) {
+ if (!aWorkerRef) {
+ return true;
+ }
-CanvasChild::~CanvasChild() = default;
+ RefPtr<dom::StrongWorkerRef> workerRef = dom::StrongWorkerRef::Create(
+ aWorkerRef->Private(), "CanvasChild::DataShmemHolder",
+ [this]() { DestroyWorker(); });
+ if (NS_WARN_IF(!workerRef)) {
+ return false;
+ }
+
+ MutexAutoLock lock(mMutex);
+ mWorkerRef = new dom::ThreadSafeWorkerRef(workerRef);
+ return true;
+ }
+
+ void Destroy() {
+ class DestroyRunnable final : public dom::WorkerRunnable {
+ public:
+ DestroyRunnable(dom::WorkerPrivate* aWorkerPrivate,
+ CanvasDataShmemHolder* aShmemHolder)
+ : dom::WorkerRunnable(aWorkerPrivate,
+ "CanvasDataShmemHolder::Destroy",
+ dom::WorkerRunnable::WorkerThread),
+ mShmemHolder(aShmemHolder) {}
+
+ bool WorkerRun(JSContext* aCx,
+ dom::WorkerPrivate* aWorkerPrivate) override {
+ mShmemHolder->Destroy();
+ return true;
+ }
+
+ void PostRun(JSContext* aCx, dom::WorkerPrivate* aWorkerPrivate,
+ bool aRunResult) override {}
+
+ bool PreDispatch(dom::WorkerPrivate* aWorkerPrivate) override {
+ return true;
+ }
+
+ void PostDispatch(dom::WorkerPrivate* aWorkerPrivate,
+ bool aDispatchResult) override {}
+
+ private:
+ CanvasDataShmemHolder* mShmemHolder;
+ };
+
+ mMutex.Lock();
+
+ if (mCanvasChild) {
+ if (mWorkerRef) {
+ if (!mWorkerRef->Private()->IsOnCurrentThread()) {
+ auto task = MakeRefPtr<DestroyRunnable>(mWorkerRef->Private(), this);
+ mMutex.Unlock();
+ task->Dispatch();
+ return;
+ }
+ } else if (!NS_IsMainThread()) {
+ mMutex.Unlock();
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "CanvasDataShmemHolder::Destroy", [this]() { Destroy(); }));
+ return;
+ }
+
+ mCanvasChild->ReturnDataSurfaceShmem(mShmem.forget());
+ mCanvasChild = nullptr;
+ mWorkerRef = nullptr;
+ }
+
+ mMutex.Unlock();
+ delete this;
+ }
+
+ void DestroyWorker() {
+ MutexAutoLock lock(mMutex);
+ mCanvasChild = nullptr;
+ mWorkerRef = nullptr;
+ }
+
+ private:
+ Mutex mMutex;
+ RefPtr<ipc::SharedMemoryBasic> mShmem;
+ RefPtr<CanvasChild> mCanvasChild MOZ_GUARDED_BY(mMutex);
+ RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef MOZ_GUARDED_BY(mMutex);
+};
+
+CanvasChild::CanvasChild(dom::ThreadSafeWorkerRef* aWorkerRef)
+ : mWorkerRef(aWorkerRef) {}
+
+CanvasChild::~CanvasChild() { MOZ_ASSERT(!mWorkerRef); }
static void NotifyCanvasDeviceReset() {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
@@ -207,14 +306,15 @@ ipc::IPCResult CanvasChild::RecvBlockCanvas() {
}
void CanvasChild::EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
- TextureType aTextureType) {
+ TextureType aTextureType,
+ TextureType aWebglTextureType) {
NS_ASSERT_OWNINGTHREAD(CanvasChild);
if (!mRecorder) {
gfx::BackendType backendType =
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
- auto recorder = MakeRefPtr<CanvasDrawEventRecorder>();
- if (!recorder->Init(aTextureType, backendType,
+ auto recorder = MakeRefPtr<CanvasDrawEventRecorder>(mWorkerRef);
+ if (!recorder->Init(aTextureType, aWebglTextureType, backendType,
MakeUnique<RecorderHelpers>(this))) {
return;
}
@@ -242,6 +342,8 @@ void CanvasChild::Destroy() {
if (CanSend()) {
Send__delete__(this);
}
+
+ mWorkerRef = nullptr;
}
bool CanvasChild::EnsureBeginTransaction() {
@@ -397,6 +499,10 @@ already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
return nullptr;
}
+ gfx::IntSize ssSize = aSurface->GetSize();
+ gfx::SurfaceFormat ssFormat = aSurface->GetFormat();
+ auto stride = ImageDataSerializer::ComputeRGBStride(ssFormat, ssSize.width);
+
// Shmem is only valid if the surface is the latest snapshot (not detached).
if (!aDetached) {
// If there is a shmem associated with this snapshot id, then we want to try
@@ -411,20 +517,22 @@ already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
if (NS_WARN_IF(!mRecorder->WaitForCheckpoint(checkpoint))) {
return nullptr;
}
- gfx::IntSize size = aSurface->GetSize();
- gfx::SurfaceFormat format = aSurface->GetFormat();
- auto stride = ImageDataSerializer::ComputeRGBStride(format, size.width);
+ auto* closure =
+ new CanvasDataShmemHolder(it->second.mSnapshotShmem, this);
+ if (NS_WARN_IF(!closure->Init(mWorkerRef))) {
+ delete closure;
+ return nullptr;
+ }
RefPtr<gfx::DataSourceSurface> dataSurface =
- gfx::Factory::CreateWrappingDataSourceSurface(shmemPtr, stride, size,
- format);
+ gfx::Factory::CreateWrappingDataSourceSurface(
+ shmemPtr, stride, ssSize, ssFormat, ReleaseDataShmemHolder,
+ closure);
return dataSurface.forget();
}
}
RecordEvent(RecordedPrepareDataForSurface(aSurface));
- gfx::IntSize ssSize = aSurface->GetSize();
- gfx::SurfaceFormat ssFormat = aSurface->GetFormat();
if (!EnsureDataSurfaceShmem(ssSize, ssFormat)) {
return nullptr;
}
@@ -435,15 +543,15 @@ already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
return nullptr;
}
+ auto* closure = new CanvasDataShmemHolder(mDataSurfaceShmem, this);
+ if (NS_WARN_IF(!closure->Init(mWorkerRef))) {
+ delete closure;
+ return nullptr;
+ }
+
mDataSurfaceShmemAvailable = false;
- struct DataShmemHolder {
- RefPtr<ipc::SharedMemoryBasic> shmem;
- RefPtr<CanvasChild> canvasChild;
- };
auto* data = static_cast<uint8_t*>(mDataSurfaceShmem->memory());
- auto* closure = new DataShmemHolder{do_AddRef(mDataSurfaceShmem), this};
- auto stride = ImageDataSerializer::ComputeRGBStride(ssFormat, ssSize.width);
RefPtr<gfx::DataSourceSurface> dataSurface =
gfx::Factory::CreateWrappingDataSourceSurface(
@@ -452,16 +560,8 @@ already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
}
/* static */ void CanvasChild::ReleaseDataShmemHolder(void* aClosure) {
- if (!NS_IsMainThread()) {
- NS_DispatchToMainThread(NS_NewRunnableFunction(
- "CanvasChild::ReleaseDataShmemHolder",
- [aClosure]() { ReleaseDataShmemHolder(aClosure); }));
- return;
- }
-
- auto* shmemHolder = static_cast<DataShmemHolder*>(aClosure);
- shmemHolder->canvasChild->ReturnDataSurfaceShmem(shmemHolder->shmem.forget());
- delete shmemHolder;
+ auto* shmemHolder = static_cast<CanvasDataShmemHolder*>(aClosure);
+ shmemHolder->Destroy();
}
already_AddRefed<gfx::SourceSurface> CanvasChild::WrapSurface(
diff --git a/gfx/layers/ipc/CanvasChild.h b/gfx/layers/ipc/CanvasChild.h
index c99fe50bfb..e22109f406 100644
--- a/gfx/layers/ipc/CanvasChild.h
+++ b/gfx/layers/ipc/CanvasChild.h
@@ -15,6 +15,10 @@
namespace mozilla {
+namespace dom {
+class ThreadSafeWorkerRef;
+}
+
namespace gfx {
class DrawTargetRecording;
class SourceSurface;
@@ -28,7 +32,7 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
public:
NS_INLINE_DECL_REFCOUNTING(CanvasChild)
- CanvasChild();
+ explicit CanvasChild(dom::ThreadSafeWorkerRef* aWorkerRef);
/**
* @returns true if remote canvas has been deactivated due to failure.
@@ -58,7 +62,7 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
* @params aTextureType the TextureType to create in the CanvasTranslator.
*/
void EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
- TextureType aTextureType);
+ TextureType aTextureType, TextureType aWebglTextureType);
/**
* Clean up IPDL actor.
@@ -147,6 +151,9 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
void CleanupTexture(int64_t aTextureId);
+ void ReturnDataSurfaceShmem(
+ already_AddRefed<ipc::SharedMemoryBasic> aDataSurfaceShmem);
+
protected:
void ActorDestroy(ActorDestroyReason aWhy) final;
@@ -157,14 +164,6 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
bool EnsureDataSurfaceShmem(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
- void ReturnDataSurfaceShmem(
- already_AddRefed<ipc::SharedMemoryBasic> aDataSurfaceShmem);
-
- struct DataShmemHolder {
- RefPtr<ipc::SharedMemoryBasic> shmem;
- RefPtr<CanvasChild> canvasChild;
- };
-
static void ReleaseDataShmemHolder(void* aClosure);
void DropFreeBuffersWhenDormant();
@@ -173,6 +172,7 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
static bool mDeactivated;
+ RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef;
RefPtr<CanvasDrawEventRecorder> mRecorder;
RefPtr<ipc::SharedMemoryBasic> mDataSurfaceShmem;
diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp
index 08150d6952..4a184f48d8 100644
--- a/gfx/layers/ipc/CanvasTranslator.cpp
+++ b/gfx/layers/ipc/CanvasTranslator.cpp
@@ -13,6 +13,7 @@
#include "mozilla/gfx/DrawTargetWebgl.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUParent.h"
+#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/layers/BufferTexture.h"
@@ -131,15 +132,17 @@ bool CanvasTranslator::EnsureSharedContextWebgl() {
}
mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
- TextureType aTextureType, gfx::BackendType aBackendType,
- Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles,
- uint64_t aBufferSize, CrossProcessSemaphoreHandle&& aReaderSem,
+ TextureType aTextureType, TextureType aWebglTextureType,
+ gfx::BackendType aBackendType, Handle&& aReadHandle,
+ nsTArray<Handle>&& aBufferHandles, uint64_t aBufferSize,
+ CrossProcessSemaphoreHandle&& aReaderSem,
CrossProcessSemaphoreHandle&& aWriterSem) {
if (mHeaderShmem) {
return IPC_FAIL(this, "RecvInitTranslator called twice.");
}
mTextureType = aTextureType;
+ mWebglTextureType = aWebglTextureType;
mBackendType = aBackendType;
mOtherPid = OtherPid();
@@ -637,7 +640,11 @@ bool CanvasTranslator::HandleExtensionEvent(int32_t aType) {
}
}
-void CanvasTranslator::BeginTransaction() { mIsInTransaction = true; }
+void CanvasTranslator::BeginTransaction() {
+ PROFILER_MARKER_TEXT("CanvasTranslator", GRAPHICS, {},
+ "CanvasTranslator::BeginTransaction"_ns);
+ mIsInTransaction = true;
+}
void CanvasTranslator::Flush() {
#if defined(XP_WIN)
@@ -728,9 +735,15 @@ bool CanvasTranslator::CheckForFreshCanvasDevice(int aLineNumber) {
NotifyDeviceChanged();
}
- RefPtr<Runnable> runnable = NS_NewRunnableFunction(
- "CanvasTranslator NotifyDeviceReset",
- []() { gfx::GPUParent::GetSingleton()->NotifyDeviceReset(); });
+ RefPtr<Runnable> runnable =
+ NS_NewRunnableFunction("CanvasTranslator NotifyDeviceReset", []() {
+ if (XRE_IsGPUProcess()) {
+ gfx::GPUParent::GetSingleton()->NotifyDeviceReset();
+ } else {
+ gfx::GPUProcessManager::Get()->OnInProcessDeviceReset(
+ /* aTrackThreshold */ false);
+ }
+ });
// It is safe to wait here because only the Compositor thread waits on us and
// the main thread doesn't wait on the compositor thread in the GPU process.
@@ -1025,6 +1038,8 @@ bool CanvasTranslator::UnlockTexture(int64_t aTextureId) {
}
bool CanvasTranslator::PresentTexture(int64_t aTextureId, RemoteTextureId aId) {
+ AUTO_PROFILER_MARKER_TEXT("CanvasTranslator", GRAPHICS, {},
+ "CanvasTranslator::PresentTexture"_ns);
auto result = mTextureInfo.find(aTextureId);
if (result == mTextureInfo.end()) {
return false;
@@ -1033,7 +1048,8 @@ bool CanvasTranslator::PresentTexture(int64_t aTextureId, RemoteTextureId aId) {
RemoteTextureOwnerId ownerId = info.mRemoteTextureOwnerId;
if (gfx::DrawTargetWebgl* webgl = info.GetDrawTargetWebgl()) {
EnsureRemoteTextureOwner(ownerId);
- if (webgl->CopyToSwapChain(aId, ownerId, mRemoteTextureOwner)) {
+ if (webgl->CopyToSwapChain(mWebglTextureType, aId, ownerId,
+ mRemoteTextureOwner)) {
return true;
}
if (mSharedContext && mSharedContext->IsContextLost()) {
diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h
index cf87b7ab53..5258e0c529 100644
--- a/gfx/layers/ipc/CanvasTranslator.h
+++ b/gfx/layers/ipc/CanvasTranslator.h
@@ -69,6 +69,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* CanvasEventRingBuffer.
*
* @param aTextureType the TextureType the translator will create
+ * @param aWebglTextureType the TextureType of any WebGL buffers
* @param aBackendType the BackendType for texture data
* @param aHeaderHandle handle for the control header
* @param aBufferHandles handles for the initial buffers for translation
@@ -77,6 +78,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* @param aWriterSem writing blocked semaphore for the CanvasEventRingBuffer
*/
ipc::IPCResult RecvInitTranslator(TextureType aTextureType,
+ TextureType aWebglTextureType,
gfx::BackendType aBackendType,
Handle&& aReadHandle,
nsTArray<Handle>&& aBufferHandles,
@@ -358,6 +360,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
TextureType mTextureType = TextureType::Unknown;
+ TextureType mWebglTextureType = TextureType::Unknown;
UniquePtr<TextureData> mReferenceTextureData;
dom::ContentParentId mContentId;
uint32_t mManagerId;
diff --git a/gfx/layers/ipc/CompositorManagerChild.cpp b/gfx/layers/ipc/CompositorManagerChild.cpp
index 0e553745d3..8d89339373 100644
--- a/gfx/layers/ipc/CompositorManagerChild.cpp
+++ b/gfx/layers/ipc/CompositorManagerChild.cpp
@@ -10,6 +10,7 @@
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/CompositorManagerParent.h"
#include "mozilla/layers/CompositorThread.h"
+#include "mozilla/gfx/CanvasShutdownManager.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/dom/ContentChild.h" // for ContentChild
@@ -67,7 +68,15 @@ bool CompositorManagerChild::Init(Endpoint<PCompositorManagerChild>&& aEndpoint,
sInstance = new CompositorManagerChild(std::move(aEndpoint), aProcessToken,
aNamespace);
sOtherPid = sInstance->OtherPid();
- return sInstance->CanSend();
+ if (!sInstance->CanSend()) {
+ return false;
+ }
+
+ // If there are any canvases waiting on the recreation of the GPUProcess or
+ // CompositorManagerChild, then we need to notify them so that they can
+ // restore their contexts.
+ gfx::CanvasShutdownManager::OnCompositorManagerRestored();
+ return true;
}
/* static */
diff --git a/gfx/layers/ipc/LayersMessageUtils.h b/gfx/layers/ipc/LayersMessageUtils.h
index d869d4ed83..a4e9557ac3 100644
--- a/gfx/layers/ipc/LayersMessageUtils.h
+++ b/gfx/layers/ipc/LayersMessageUtils.h
@@ -520,7 +520,7 @@ template <>
struct ParamTraits<mozilla::ScrollUpdateType>
: public ContiguousEnumSerializerInclusive<
mozilla::ScrollUpdateType, mozilla::ScrollUpdateType::Absolute,
- mozilla::ScrollUpdateType::MergeableAbsolute> {};
+ mozilla::ScrollUpdateType::PureRelative> {};
template <>
struct ParamTraits<mozilla::ScrollMode>
diff --git a/gfx/layers/ipc/PCanvas.ipdl b/gfx/layers/ipc/PCanvas.ipdl
index 5187e61d23..59896b72cf 100644
--- a/gfx/layers/ipc/PCanvas.ipdl
+++ b/gfx/layers/ipc/PCanvas.ipdl
@@ -32,9 +32,9 @@ parent:
* each aBufferHandles' memory and the default size. aReaderSem and aWriterSem
* are handles for the semaphores to handle waiting on either side.
*/
- async InitTranslator(TextureType aTextureType, BackendType aBackendType,
- Handle aHeaderHandle, Handle[] aBufferHandles,
- uint64_t aBufferSize,
+ async InitTranslator(TextureType aTextureType, TextureType aWebglTextureType,
+ BackendType aBackendType, Handle aHeaderHandle,
+ Handle[] aBufferHandles, uint64_t aBufferSize,
CrossProcessSemaphoreHandle aReaderSem,
CrossProcessSemaphoreHandle aWriterSem);
diff --git a/gfx/layers/ipc/VideoBridgeParent.cpp b/gfx/layers/ipc/VideoBridgeParent.cpp
index 6413c27bc1..50f0549e50 100644
--- a/gfx/layers/ipc/VideoBridgeParent.cpp
+++ b/gfx/layers/ipc/VideoBridgeParent.cpp
@@ -17,9 +17,8 @@ namespace mozilla::layers {
using namespace mozilla::ipc;
using namespace mozilla::gfx;
-using VideoBridgeTable =
- EnumeratedArray<VideoBridgeSource, VideoBridgeSource::_Count,
- VideoBridgeParent*>;
+using VideoBridgeTable = EnumeratedArray<VideoBridgeSource, VideoBridgeParent*,
+ size_t(VideoBridgeSource::_Count)>;
static StaticDataMutex<VideoBridgeTable> sVideoBridgeFromProcess(
"VideoBridges");