tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit eb2a93323477f615e166ad8f6f7a765c39250eeb
parent 5caa1ec20270c1185da5f50c0ab1f8a077a00600
Author: Lee Salzman <lsalzman@mozilla.com>
Date:   Mon, 27 Oct 2025 02:55:38 +0000

Bug 1996186 - Remove Remote Canvas. r=aosmond

Remote canvas only works with Direct2D (which has been removed) and has been superceded by Accelerated Canvas2D.
Thus, it is safe to remove remote canvas since it can no longer be enabled.

Differential Revision: https://phabricator.services.mozilla.com/D269928

Diffstat:
Mdom/canvas/test/test_accelerated_canvas_context_loss.html | 5++---
Mgfx/config/gfxFeature.h | 1-
Mgfx/config/gfxVars.h | 1-
Mgfx/ipc/CanvasManagerParent.cpp | 3+--
Mgfx/ipc/CanvasRenderThread.cpp | 109+++++--------------------------------------------------------------------------
Mgfx/ipc/CanvasRenderThread.h | 15+--------------
Mgfx/ipc/GPUParent.cpp | 3+--
Mgfx/layers/RecordedCanvasEventImpl.h | 60+++++++++++++-----------------------------------------------
Mgfx/layers/ipc/CanvasChild.cpp | 8--------
Mgfx/layers/ipc/CanvasChild.h | 2--
Mgfx/layers/ipc/CanvasTranslator.cpp | 221+++++++++++++++----------------------------------------------------------------
Mgfx/layers/ipc/CanvasTranslator.h | 13-------------
Mgfx/layers/ipc/PCanvas.ipdl | 5-----
Mgfx/tests/gtest/TestConfigManager.cpp | 3---
Mgfx/thebes/gfxPlatform.cpp | 43+++----------------------------------------
Mmodules/libpref/init/StaticPrefList.yaml | 29+----------------------------
Mwidget/GfxInfoBase.cpp | 6------
Mwidget/GfxInfoBase.h | 1-
Mwidget/nsIGfxInfo.idl | 1-
19 files changed, 69 insertions(+), 460 deletions(-)

diff --git a/dom/canvas/test/test_accelerated_canvas_context_loss.html b/dom/canvas/test/test_accelerated_canvas_context_loss.html @@ -27,14 +27,13 @@ async function restartGPUProcess() { ); let promise = TestUtils.topicObserved("compositor-reinitialized"); - const remoteCanvas = gfxInfo.usingRemoteCanvas; const acceleratedCanvas = gfxInfo.usingAcceleratedCanvas; - ok(true, "Restarting GPU process, remote canvas " + remoteCanvas + ", accelerated canvas " + acceleratedCanvas); + ok(true, "Restarting GPU process, accelerated canvas " + acceleratedCanvas); gfxInfo.killGPUProcessForTests(); await promise; - return remoteCanvas || acceleratedCanvas; + return acceleratedCanvas; } ok(true, "Not using GPU process"); diff --git a/gfx/config/gfxFeature.h b/gfx/config/gfxFeature.h @@ -53,7 +53,6 @@ namespace gfx { _(H264_HW_DECODE, Feature, "H.264 hardware decoding") \ _(AV1_HW_DECODE, Feature, "AV1 hardware decoding") \ _(HEVC_HW_DECODE, Feature, "HEVC hardware decoding") \ - _(REMOTE_CANVAS, Feature, "Remote canvas") \ _(DMABUF_WEBGL, Feature, "DMABuf for WebGL") \ _(VP8_HW_ENCODE, Feature, "VP8 hardware encoding") \ _(VP9_HW_ENCODE, Feature, "VP9 hardware encoding") \ diff --git a/gfx/config/gfxVars.h b/gfx/config/gfxVars.h @@ -75,7 +75,6 @@ class MOZ_STACK_CLASS gfxVarsCollectUpdates; _(SystemTextRenderingMode, int32_t, 0) \ _(SystemGDIGamma, float, 1.4f) \ _(LayersWindowRecordingPath, nsCString, nsCString()) \ - _(RemoteCanvasEnabled, bool, false) \ _(UseDoubleBufferingWithCompositor, bool, false) \ _(UseGLSwizzle, bool, true) \ _(ForceSubpixelAAWherePossible, bool, false) \ diff --git a/gfx/ipc/CanvasManagerParent.cpp b/gfx/ipc/CanvasManagerParent.cpp @@ -164,8 +164,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvInitialize( already_AddRefed<layers::PCanvasParent> CanvasManagerParent::AllocPCanvasParent() { - if (NS_WARN_IF(!gfx::gfxVars::RemoteCanvasEnabled() && - !gfx::gfxVars::UseAcceleratedCanvas2D())) { + if (NS_WARN_IF(!gfx::gfxVars::UseAcceleratedCanvas2D())) { MOZ_ASSERT_UNREACHABLE("AllocPCanvasParent without remote canvas"); return nullptr; } diff --git a/gfx/ipc/CanvasRenderThread.cpp b/gfx/ipc/CanvasRenderThread.cpp @@ -9,7 +9,6 @@ #include "mozilla/BackgroundHangMonitor.h" #include "mozilla/SharedThreadPool.h" #include "mozilla/StaticPrefs_gfx.h" -#include "mozilla/TaskQueue.h" #include "mozilla/gfx/CanvasManagerParent.h" #include "mozilla/gfx/gfxVars.h" #include "mozilla/layers/CanvasTranslator.h" @@ -32,11 +31,9 @@ static bool sCanvasRenderThreadEverStarted = false; #endif CanvasRenderThread::CanvasRenderThread(nsCOMPtr<nsIThread>&& aThread, - nsCOMPtr<nsIThreadPool>&& aWorkers, bool aCreatedThread) : mMutex("CanvasRenderThread::mMutex"), mThread(std::move(aThread)), - mWorkers(std::move(aWorkers)), mCreatedThread(aCreatedThread) {} CanvasRenderThread::~CanvasRenderThread() = default; @@ -53,36 +50,6 @@ void CanvasRenderThread::Start() { sCanvasRenderThreadEverStarted = true; #endif - // If remote canvas is disabled, then ignore the worker threads setting so as - // not to interfere with Accelerated Canvas2D. - int32_t threadPref = - gfxVars::RemoteCanvasEnabled() - ? StaticPrefs::gfx_canvas_remote_worker_threads_AtStartup() - : 0; - - uint32_t threadLimit; - if (threadPref < 0) { - // Given that the canvas workers are receiving instructions from - // content processes, it probably doesn't make sense to have more than - // half the number of processors doing canvas drawing. We set the - // lower limit to 2, so that even on single processor systems, if - // there is more than one window with canvas drawing, the OS can - // manage the load between them. - threadLimit = std::max(2, PR_GetNumberOfProcessors() / 2); - } else { - threadLimit = uint32_t(threadPref); - } - - // We don't spawn any workers if the user set the limit to 0. Instead we will - // use the CanvasRenderThread virtual thread. - nsCOMPtr<nsIThreadPool> workers; - if (threadLimit > 0) { - workers = SharedThreadPool::Get("CanvasWorkers"_ns, threadLimit); - if (NS_WARN_IF(!workers)) { - return; - } - } - nsCOMPtr<nsIThread> thread; if (!gfxVars::SupportsThreadsafeGL()) { thread = wr::RenderThread::GetRenderThread(); @@ -93,8 +60,8 @@ void CanvasRenderThread::Start() { } if (thread) { - sCanvasRenderThread = new CanvasRenderThread( - std::move(thread), std::move(workers), /* aCreatedThread */ false); + sCanvasRenderThread = + new CanvasRenderThread(std::move(thread), /* aCreatedThread */ false); return; } @@ -139,8 +106,8 @@ void CanvasRenderThread::Start() { return; } - sCanvasRenderThread = new CanvasRenderThread( - std::move(thread), std::move(workers), /* aCreatedThread */ true); + sCanvasRenderThread = + new CanvasRenderThread(std::move(thread), /* aCreatedThread */ true); } // static @@ -160,27 +127,9 @@ void CanvasRenderThread::Shutdown() { // Queue any remaining global cleanup for CanvasTranslator layers::CanvasTranslator::Shutdown(); - // Any task queues that are in the process of shutting down are tracked in - // mPendingShutdownTaskQueues. We need to block on each one until all events - // are flushed so that we can safely teardown RemoteTextureMap afterwards. - while (true) { - RefPtr<TaskQueue> taskQueue; - { - MutexAutoLock lock(sCanvasRenderThread->mMutex); - - auto& pendingQueues = sCanvasRenderThread->mPendingShutdownTaskQueues; - if (pendingQueues.IsEmpty()) { - break; - } - - taskQueue = pendingQueues.PopLastElement(); - } - taskQueue->AwaitShutdownAndIdle(); - } bool createdThread = sCanvasRenderThread->mCreatedThread; nsCOMPtr<nsIThread> oldThread = sCanvasRenderThread->GetCanvasRenderThread(); - nsCOMPtr<nsIThreadPool> oldWorkers = sCanvasRenderThread->mWorkers; // Ensure that we flush the CanvasRenderThread event queue before clearing our // singleton. @@ -192,10 +141,6 @@ void CanvasRenderThread::Shutdown() { // from here on we are to be considered shut down for our consumers. sCanvasRenderThread = nullptr; - if (oldWorkers) { - oldWorkers->Shutdown(); - } - // We do a synchronous shutdown here while spinning the MT event loop, but // only if we created a dedicated CanvasRender thread. if (createdThread) { @@ -213,19 +158,14 @@ bool CanvasRenderThread::IsInCanvasRenderThread() { // It is possible there are no worker threads, and the worker is the same as // the CanvasRenderThread itself. return sCanvasRenderThread && - ((sCanvasRenderThread->mWorkers && - sCanvasRenderThread->mWorkers->IsOnCurrentThread()) || - (!sCanvasRenderThread->mWorkers && - sCanvasRenderThread->mThread == NS_GetCurrentThread())); + sCanvasRenderThread->mThread == NS_GetCurrentThread(); } /* static */ bool CanvasRenderThread::IsInCanvasRenderOrWorkerThread() { // It is possible there are no worker threads, and the worker is the same as // the CanvasRenderThread itself. return sCanvasRenderThread && - (sCanvasRenderThread->mThread == NS_GetCurrentThread() || - (sCanvasRenderThread->mWorkers && - sCanvasRenderThread->mWorkers->IsOnCurrentThread())); + sCanvasRenderThread->mThread == NS_GetCurrentThread(); } // static @@ -237,43 +177,6 @@ already_AddRefed<nsIThread> CanvasRenderThread::GetCanvasRenderThread() { return thread.forget(); } -/* static */ already_AddRefed<TaskQueue> -CanvasRenderThread::CreateWorkerTaskQueue() { - if (!sCanvasRenderThread || !sCanvasRenderThread->mWorkers) { - return nullptr; - } - - return TaskQueue::Create(do_AddRef(sCanvasRenderThread->mWorkers), - "CanvasWorker") - .forget(); -} - -/* static */ void CanvasRenderThread::ShutdownWorkerTaskQueue( - TaskQueue* aTaskQueue) { - MOZ_ASSERT(aTaskQueue); - - aTaskQueue->BeginShutdown(); - - if (!sCanvasRenderThread) { - MOZ_ASSERT_UNREACHABLE("No CanvasRenderThread!"); - return; - } - - MutexAutoLock lock(sCanvasRenderThread->mMutex); - auto& pendingQueues = sCanvasRenderThread->mPendingShutdownTaskQueues; - pendingQueues.AppendElement(aTaskQueue); -} - -/* static */ void CanvasRenderThread::FinishShutdownWorkerTaskQueue( - TaskQueue* aTaskQueue) { - if (!sCanvasRenderThread) { - return; - } - - MutexAutoLock lock(sCanvasRenderThread->mMutex); - sCanvasRenderThread->mPendingShutdownTaskQueues.RemoveElement(aTaskQueue); -} - /* static */ void CanvasRenderThread::Dispatch( already_AddRefed<nsIRunnable> aRunnable) { if (!sCanvasRenderThread) { diff --git a/gfx/ipc/CanvasRenderThread.h b/gfx/ipc/CanvasRenderThread.h @@ -15,10 +15,8 @@ class nsIRunnable; class nsIThread; -class nsIThreadPool; namespace mozilla { -class TaskQueue; namespace gfx { @@ -53,27 +51,16 @@ class CanvasRenderThread final { /// Can be called from any thread, may return nullptr late in shutdown. static already_AddRefed<nsIThread> GetCanvasRenderThread(); - static already_AddRefed<TaskQueue> CreateWorkerTaskQueue(); - - static void ShutdownWorkerTaskQueue(TaskQueue* aTaskQueue); - - static void FinishShutdownWorkerTaskQueue(TaskQueue* aTaskQueue); - static void Dispatch(already_AddRefed<nsIRunnable> aRunnable); private: - CanvasRenderThread(nsCOMPtr<nsIThread>&& aThread, - nsCOMPtr<nsIThreadPool>&& aWorkers, bool aCreatedThread); + CanvasRenderThread(nsCOMPtr<nsIThread>&& aThread, bool aCreatedThread); ~CanvasRenderThread(); Mutex mMutex; nsCOMPtr<nsIThread> const mThread; - nsCOMPtr<nsIThreadPool> const mWorkers; - - nsTArray<RefPtr<TaskQueue>> mPendingShutdownTaskQueues MOZ_GUARDED_BY(mMutex); - // True if mThread points to CanvasRender thread, false if mThread points to // Compositor/Render thread. const bool mCreatedThread; diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp @@ -321,8 +321,7 @@ mozilla::ipc::IPCResult GPUParent::RecvInit( // here that would normally be initialized there. SkGraphics::Init(); - bool useRemoteCanvas = - gfxVars::RemoteCanvasEnabled() || gfxVars::UseAcceleratedCanvas2D(); + bool useRemoteCanvas = gfxVars::UseAcceleratedCanvas2D(); if (useRemoteCanvas) { gfxGradientCache::Init(); } diff --git a/gfx/layers/RecordedCanvasEventImpl.h b/gfx/layers/RecordedCanvasEventImpl.h @@ -36,20 +36,19 @@ const EventType CACHE_DATA_SURFACE = EventType(EventType::LAST + 5); const EventType GET_DATA_FOR_SURFACE = EventType(EventType::LAST + 6); const EventType ADD_SURFACE_ALIAS = EventType(EventType::LAST + 7); const EventType REMOVE_SURFACE_ALIAS = EventType(EventType::LAST + 8); -const EventType DEVICE_CHANGE_ACKNOWLEDGED = EventType(EventType::LAST + 9); -const EventType CANVAS_DRAW_TARGET_CREATION = EventType(EventType::LAST + 10); -const EventType TEXTURE_DESTRUCTION = EventType(EventType::LAST + 11); -const EventType CHECKPOINT = EventType(EventType::LAST + 12); -const EventType PAUSE_TRANSLATION = EventType(EventType::LAST + 13); -const EventType RECYCLE_BUFFER = EventType(EventType::LAST + 14); -const EventType DROP_BUFFER = EventType(EventType::LAST + 15); -const EventType PREPARE_SHMEM = EventType(EventType::LAST + 16); -const EventType PRESENT_TEXTURE = EventType(EventType::LAST + 17); -const EventType DEVICE_RESET_ACKNOWLEDGED = EventType(EventType::LAST + 18); -const EventType AWAIT_TRANSLATION_SYNC = EventType(EventType::LAST + 19); -const EventType RESOLVE_EXTERNAL_SNAPSHOT = EventType(EventType::LAST + 20); -const EventType ADD_EXPORT_SURFACE = EventType(EventType::LAST + 21); -const EventType REMOVE_EXPORT_SURFACE = EventType(EventType::LAST + 22); +const EventType CANVAS_DRAW_TARGET_CREATION = EventType(EventType::LAST + 9); +const EventType TEXTURE_DESTRUCTION = EventType(EventType::LAST + 10); +const EventType CHECKPOINT = EventType(EventType::LAST + 11); +const EventType PAUSE_TRANSLATION = EventType(EventType::LAST + 12); +const EventType RECYCLE_BUFFER = EventType(EventType::LAST + 13); +const EventType DROP_BUFFER = EventType(EventType::LAST + 14); +const EventType PREPARE_SHMEM = EventType(EventType::LAST + 15); +const EventType PRESENT_TEXTURE = EventType(EventType::LAST + 16); +const EventType DEVICE_RESET_ACKNOWLEDGED = EventType(EventType::LAST + 17); +const EventType AWAIT_TRANSLATION_SYNC = EventType(EventType::LAST + 18); +const EventType RESOLVE_EXTERNAL_SNAPSHOT = EventType(EventType::LAST + 19); +const EventType ADD_EXPORT_SURFACE = EventType(EventType::LAST + 20); +const EventType REMOVE_EXPORT_SURFACE = EventType(EventType::LAST + 21); const EventType LAST_CANVAS_EVENT_TYPE = REMOVE_EXPORT_SURFACE; class RecordedCanvasBeginTransaction final @@ -415,38 +414,6 @@ RecordedRemoveSurfaceAlias::RecordedRemoveSurfaceAlias(S& aStream) ReadElement(aStream, mSurfaceAlias); } -class RecordedDeviceChangeAcknowledged final - : public RecordedEventDerived<RecordedDeviceChangeAcknowledged> { - public: - RecordedDeviceChangeAcknowledged() - : RecordedEventDerived(DEVICE_CHANGE_ACKNOWLEDGED) {} - - template <class S> - MOZ_IMPLICIT RecordedDeviceChangeAcknowledged(S& aStream); - - bool PlayCanvasEvent(CanvasTranslator* aTranslator) const; - - template <class S> - void Record(S& aStream) const; - - std::string GetName() const final { - return "RecordedDeviceChangeAcknowledged"; - } -}; - -inline bool RecordedDeviceChangeAcknowledged::PlayCanvasEvent( - CanvasTranslator* aTranslator) const { - aTranslator->DeviceChangeAcknowledged(); - return true; -} - -template <class S> -void RecordedDeviceChangeAcknowledged::Record(S& aStream) const {} - -template <class S> -RecordedDeviceChangeAcknowledged::RecordedDeviceChangeAcknowledged(S& aStream) - : RecordedEventDerived(DEVICE_CHANGE_ACKNOWLEDGED) {} - class RecordedDeviceResetAcknowledged final : public RecordedEventDerived<RecordedDeviceResetAcknowledged> { public: @@ -939,7 +906,6 @@ RecordedRemoveExportSurface::RecordedRemoveExportSurface(S& aStream) f(GET_DATA_FOR_SURFACE, RecordedGetDataForSurface); \ f(ADD_SURFACE_ALIAS, RecordedAddSurfaceAlias); \ f(REMOVE_SURFACE_ALIAS, RecordedRemoveSurfaceAlias); \ - f(DEVICE_CHANGE_ACKNOWLEDGED, RecordedDeviceChangeAcknowledged); \ f(CANVAS_DRAW_TARGET_CREATION, RecordedCanvasDrawTargetCreation); \ f(TEXTURE_DESTRUCTION, RecordedTextureDestruction); \ f(CHECKPOINT, RecordedCheckpoint); \ diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp @@ -343,14 +343,6 @@ static void NotifyCanvasDeviceChanged() { } } -ipc::IPCResult CanvasChild::RecvNotifyDeviceChanged() { - NS_ASSERT_OWNINGTHREAD(CanvasChild); - - NotifyCanvasDeviceChanged(); - mRecorder->RecordEvent(RecordedDeviceChangeAcknowledged()); - return IPC_OK(); -} - ipc::IPCResult CanvasChild::RecvNotifyDeviceReset( const nsTArray<RemoteTextureOwnerId>& aOwnerIds) { NS_ASSERT_OWNINGTHREAD(CanvasChild); diff --git a/gfx/layers/ipc/CanvasChild.h b/gfx/layers/ipc/CanvasChild.h @@ -47,8 +47,6 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr { */ void ClearCachedResources(); - ipc::IPCResult RecvNotifyDeviceChanged(); - ipc::IPCResult RecvNotifyDeviceReset( const nsTArray<RemoteTextureOwnerId>& aOwnerIds); diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp @@ -50,19 +50,6 @@ UniquePtr<TextureData> CanvasTranslator::CreateTextureData( TextureAllocationFlags allocFlags = aClear ? ALLOC_CLEAR_BUFFER : ALLOC_DEFAULT; switch (mTextureType) { -#ifdef XP_WIN - case TextureType::D3D11: { - // Prefer keyed mutex than D3D11Fence if remote canvas is enabled. See Bug - // 1966082 - if (gfx::gfxVars::RemoteCanvasEnabled()) { - allocFlags = - (TextureAllocationFlags)(allocFlags | USE_D3D11_KEYED_MUTEX); - } - textureData = - D3D11TextureData::Create(aSize, aFormat, allocFlags, mDevice); - break; - } -#endif case TextureType::Unknown: textureData = BufferTextureData::Create( aSize, aFormat, gfx::BackendType::SKIA, LayersBackend::LAYERS_WR, @@ -81,8 +68,7 @@ UniquePtr<TextureData> CanvasTranslator::CreateTextureData( CanvasTranslator::CanvasTranslator( layers::SharedSurfacesHolder* aSharedSurfacesHolder, const dom::ContentParentId& aContentId, uint32_t aManagerId) - : mTranslationTaskQueue(gfx::CanvasRenderThread::CreateWorkerTaskQueue()), - mSharedSurfacesHolder(aSharedSurfacesHolder), + : mSharedSurfacesHolder(aSharedSurfacesHolder), #if defined(XP_WIN) mVideoProcessorD3D11("CanvasTranslator::mVideoProcessorD3D11"), #endif @@ -99,17 +85,10 @@ CanvasTranslator::~CanvasTranslator() = default; void CanvasTranslator::DispatchToTaskQueue( already_AddRefed<nsIRunnable> aRunnable) { - if (mTranslationTaskQueue) { - MOZ_ALWAYS_SUCCEEDS(mTranslationTaskQueue->Dispatch(std::move(aRunnable))); - } else { - gfx::CanvasRenderThread::Dispatch(std::move(aRunnable)); - } + gfx::CanvasRenderThread::Dispatch(std::move(aRunnable)); } bool CanvasTranslator::IsInTaskQueue() const { - if (mTranslationTaskQueue) { - return mTranslationTaskQueue->IsCurrentThreadIn(); - } return gfx::CanvasRenderThread::IsInCanvasRenderThread(); } @@ -177,8 +156,9 @@ mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator( mReaderSemaphore.reset(CrossProcessSemaphore::Create(std::move(aReaderSem))); mReaderSemaphore->CloseHandle(); - if (!CheckForFreshCanvasDevice(__LINE__)) { + if (!CreateReferenceTexture()) { gfxCriticalNote << "GFX: CanvasTranslator failed to get device"; + Deactivate(); return IPC_OK(); } @@ -499,24 +479,6 @@ void CanvasTranslator::ActorDestroy(ActorDestroyReason why) { DispatchToTaskQueue(NewRunnableMethod("CanvasTranslator::ClearTextureInfo", this, &CanvasTranslator::ClearTextureInfo)); - - if (mTranslationTaskQueue) { - gfx::CanvasRenderThread::ShutdownWorkerTaskQueue(mTranslationTaskQueue); - return; - } -} - -bool CanvasTranslator::CheckDeactivated() { - if (mDeactivated) { - return true; - } - - if (NS_WARN_IF(!gfx::gfxVars::RemoteCanvasEnabled() && - !gfx::gfxVars::UseAcceleratedCanvas2D())) { - Deactivate(); - } - - return mDeactivated; } void CanvasTranslator::Deactivate() { @@ -735,13 +697,7 @@ bool CanvasTranslator::TranslateRecording() { } if (!success && !HandleExtensionEvent(eventType)) { - if (mDeviceResetInProgress) { - // We've notified the recorder of a device change, so we are expecting - // failures. Log as a warning to prevent crash reporting being flooded. - gfxWarning() << "Failed to play canvas event type: " << eventType; - } else { - gfxCriticalNote << "Failed to play canvas event type: " << eventType; - } + gfxCriticalNote << "Failed to play canvas event type: " << eventType; if (!mCurrentMemReader.good()) { mHeader->readerState = State::Failed; @@ -781,10 +737,7 @@ bool CanvasTranslator::TranslateRecording() { } bool CanvasTranslator::UsePendingCanvasTranslatorEvents() { - // XXX remove !mTranslationTaskQueue check. - return StaticPrefs:: - gfx_canvas_remote_use_canvas_translator_event_AtStartup() && - !mTranslationTaskQueue; + return StaticPrefs::gfx_canvas_remote_use_canvas_translator_event_AtStartup(); } void CanvasTranslator::PostCanvasTranslatorEvents( @@ -925,35 +878,19 @@ void CanvasTranslator::BeginTransaction() { } void CanvasTranslator::Flush() { -#if defined(XP_WIN) - // We can end up without a device, due to a reset and failure to re-create. - if (!mDevice) { - return; - } - - RefPtr<ID3D11DeviceContext> deviceContext; - mDevice->GetImmediateContext(getter_AddRefs(deviceContext)); - deviceContext->Flush(); -#endif } void CanvasTranslator::EndTransaction() { Flush(); - // At the end of a transaction is a good time to check if a new canvas device - // has been created, even if a reset did not occur. - (void)CheckForFreshCanvasDevice(__LINE__); mIsInTransaction = false; } -void CanvasTranslator::DeviceChangeAcknowledged() { - mDeviceResetInProgress = false; +void CanvasTranslator::DeviceResetAcknowledged() { if (mRemoteTextureOwner) { mRemoteTextureOwner->NotifyContextRestored(); } } -void CanvasTranslator::DeviceResetAcknowledged() { DeviceChangeAcknowledged(); } - bool CanvasTranslator::CreateReferenceTexture() { if (mReferenceTextureData) { if (mBaseDT) { @@ -965,96 +902,23 @@ bool CanvasTranslator::CreateReferenceTexture() { mReferenceTextureData = CreateTextureData(gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8, true); if (!mReferenceTextureData) { - Deactivate(); return false; } if (NS_WARN_IF(!mReferenceTextureData->Lock(OpenMode::OPEN_READ_WRITE))) { gfxCriticalNote << "CanvasTranslator::CreateReferenceTexture lock failed"; mReferenceTextureData.reset(); - Deactivate(); return false; } mBaseDT = mReferenceTextureData->BorrowDrawTarget(); - if (!mBaseDT) { - // We might get a null draw target due to a device failure, deactivate and - // return false so that we can recover. - Deactivate(); return false; } return true; } -bool CanvasTranslator::CheckForFreshCanvasDevice(int aLineNumber) { - // If not on D3D11, we are not dependent on a fresh device for DT creation if - // one already exists. - if (mBaseDT && mTextureType != TextureType::D3D11) { - return false; - } - -#if defined(XP_WIN) - // If a new device has already been created, use that one. - RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetCanvasDevice(); - if (device && device != mDevice) { - if (mDevice) { - // We already had a device, notify child of change. - NotifyDeviceChanged(); - } - mDevice = device.forget(); - return CreateReferenceTexture(); - } - - gfx::DeviceResetReason reason = gfx::DeviceResetReason::OTHER; - - if (mDevice) { - const auto d3d11Reason = mDevice->GetDeviceRemovedReason(); - reason = DXGIErrorToDeviceResetReason(d3d11Reason); - if (reason == gfx::DeviceResetReason::OK) { - return false; - } - - gfxCriticalNote << "GFX: CanvasTranslator detected a device reset at " - << aLineNumber; - NotifyDeviceChanged(); - } - - RefPtr<Runnable> runnable = - NS_NewRunnableFunction("CanvasTranslator NotifyDeviceReset", [reason]() { - gfx::GPUProcessManager::GPUProcessManager::NotifyDeviceReset( - reason, gfx::DeviceResetDetectPlace::CANVAS_TRANSLATOR); - }); - - // 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. - SyncRunnable::DispatchToThread(GetMainThreadSerialEventTarget(), runnable, - /*aForceDispatch*/ true); - - mDevice = gfx::DeviceManagerDx::Get()->GetCanvasDevice(); - if (!mDevice) { - // We don't have a canvas device, we need to deactivate. - Deactivate(); - return false; - } -#endif - - return CreateReferenceTexture(); -} - -void CanvasTranslator::NotifyDeviceChanged() { - // Clear out any old recycled texture datas with the wrong device. - if (mRemoteTextureOwner) { - mRemoteTextureOwner->NotifyContextLost(); - mRemoteTextureOwner->ClearRecycledTextures(); - } - mDeviceResetInProgress = true; - gfx::CanvasRenderThread::Dispatch( - NewRunnableMethod("CanvasTranslator::SendNotifyDeviceChanged", this, - &CanvasTranslator::SendNotifyDeviceChanged)); -} - void CanvasTranslator::NotifyDeviceReset(const RemoteTextureOwnerIdSet& aIds) { if (aIds.empty()) { return; @@ -1217,33 +1081,31 @@ static const OpenMode kInitMode = OpenMode::OPEN_READ_WRITE; already_AddRefed<gfx::DrawTarget> CanvasTranslator::CreateFallbackDrawTarget( gfx::ReferencePtr aRefPtr, const RemoteTextureOwnerId aTextureOwnerId, const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) { - RefPtr<gfx::DrawTarget> dt; - do { - UniquePtr<TextureData> textureData = - CreateOrRecycleTextureData(aSize, aFormat); - if (NS_WARN_IF(!textureData)) { - continue; - } + UniquePtr<TextureData> textureData = + CreateOrRecycleTextureData(aSize, aFormat); + if (NS_WARN_IF(!textureData)) { + return nullptr; + } - if (NS_WARN_IF(!textureData->Lock(kInitMode))) { - gfxCriticalNote << "CanvasTranslator::CreateDrawTarget lock failed"; - continue; - } + if (NS_WARN_IF(!textureData->Lock(kInitMode))) { + gfxCriticalNote << "CanvasTranslator::CreateDrawTarget lock failed"; + return nullptr; + } + + RefPtr<gfx::DrawTarget> dt = textureData->BorrowDrawTarget(); + if (NS_WARN_IF(!dt)) { + textureData->Unlock(); + return nullptr; + } + // Recycled buffer contents may be uninitialized. + dt->ClearRect(gfx::Rect(dt->GetRect())); + + TextureInfo& info = mTextureInfo[aTextureOwnerId]; + info.mRefPtr = aRefPtr; + info.mFallbackDrawTarget = dt; + info.mTextureData = std::move(textureData); + info.mTextureLockMode = kInitMode; - dt = textureData->BorrowDrawTarget(); - if (NS_WARN_IF(!dt)) { - textureData->Unlock(); - continue; - } - // Recycled buffer contents may be uninitialized. - dt->ClearRect(gfx::Rect(dt->GetRect())); - - TextureInfo& info = mTextureInfo[aTextureOwnerId]; - info.mRefPtr = aRefPtr; - info.mFallbackDrawTarget = dt; - info.mTextureData = std::move(textureData); - info.mTextureLockMode = kInitMode; - } while (!dt && CheckForFreshCanvasDevice(__LINE__)); return dt.forget(); } @@ -1489,12 +1351,10 @@ bool CanvasTranslator::PushRemoteTexture( const RemoteTextureOwnerId aTextureOwnerId, TextureData* aData, RemoteTextureId aId, RemoteTextureOwnerId aOwnerId) { EnsureRemoteTextureOwner(aOwnerId); - UniquePtr<TextureData> dstData; - if (!mDeviceResetInProgress) { - TextureData::Info info; - aData->FillInfo(info); - dstData = CreateOrRecycleTextureData(info.size, info.format); - } + TextureData::Info info; + aData->FillInfo(info); + UniquePtr<TextureData> dstData = + CreateOrRecycleTextureData(info.size, info.format); bool success = false; // Source data is already locked. if (dstData) { @@ -1558,10 +1418,6 @@ void CanvasTranslator::ClearTextureInfo() { mRemoteTextureOwner->UnregisterAllTextureOwners(); mRemoteTextureOwner = nullptr; } - if (mTranslationTaskQueue) { - gfx::CanvasRenderThread::FinishShutdownWorkerTaskQueue( - mTranslationTaskQueue); - } } already_AddRefed<gfx::SourceSurface> CanvasTranslator::LookupExternalSurface( @@ -1687,8 +1543,13 @@ CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor( // TODO reuse DataSourceSurface if no update. - usedSurf = - textureHostD3D11->GetAsSurfaceWithDevice(mDevice, mVideoProcessorD3D11); + if (RefPtr<ID3D11Device> device = + gfx::DeviceManagerDx::Get()->GetCanvasDevice()) { + usedSurf = textureHostD3D11->GetAsSurfaceWithDevice(device, + mVideoProcessorD3D11); + } else { + usedSurf = nullptr; + } if (!usedSurf) { MOZ_ASSERT_UNREACHABLE("unexpected to be called"); usedDescriptor = Nothing(); diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h @@ -31,7 +31,6 @@ namespace mozilla { using EventType = gfx::RecordedEvent::EventType; -class TaskQueue; class WebGLContext; @@ -153,11 +152,6 @@ class CanvasTranslator final : public gfx::InlineTranslator, void Flush(); /** - * Marks that device change processing in the writing process has finished. - */ - void DeviceChangeAcknowledged(); - - /** * Marks that device reset processing in the writing process has finished. */ void DeviceResetAcknowledged(); @@ -424,8 +418,6 @@ class CanvasTranslator final : public gfx::InlineTranslator, bool ReadPendingEvent(EventType& aEventType); - bool CheckDeactivated(); - void Deactivate(); bool TryDrawTargetWebglFallback(const RemoteTextureOwnerId aTextureOwnerId, @@ -453,8 +445,6 @@ class CanvasTranslator final : public gfx::InlineTranslator, bool HandleExtensionEvent(int32_t aType); bool CreateReferenceTexture(); - bool CheckForFreshCanvasDevice(int aLineNumber); - void NotifyDeviceChanged(); void NotifyDeviceReset(const RemoteTextureOwnerIdSet& aIds); bool EnsureSharedContextWebgl(); @@ -483,10 +473,8 @@ class CanvasTranslator final : public gfx::InlineTranslator, void NotifyTextureDestruction(const RemoteTextureOwnerId aTextureOwnerId); - const RefPtr<TaskQueue> mTranslationTaskQueue; const RefPtr<SharedSurfacesHolder> mSharedSurfacesHolder; #if defined(XP_WIN) - RefPtr<ID3D11Device> mDevice; DataMutex<RefPtr<VideoProcessorD3D11>> mVideoProcessorD3D11; #endif static StaticRefPtr<gfx::SharedContextWebgl> sSharedContext; @@ -578,7 +566,6 @@ class CanvasTranslator final : public gfx::InlineTranslator, Atomic<bool> mBlocked{false}; Atomic<bool> mIPDLClosed{false}; bool mIsInTransaction = false; - bool mDeviceResetInProgress = false; RefPtr<gfx::DataSourceSurface> mUsedDataSurfaceForSurfaceDescriptor; RefPtr<gfx::DataSourceSurfaceWrapper> mUsedWrapperForSurfaceDescriptor; diff --git a/gfx/layers/ipc/PCanvas.ipdl b/gfx/layers/ipc/PCanvas.ipdl @@ -76,11 +76,6 @@ parent: child: /** - * Notify that the canvas device used by the translator has changed. - */ - async NotifyDeviceChanged(); - - /** * Notify that the canvas device used by the translator has been reset. */ async NotifyDeviceReset(RemoteTextureOwnerId[] aOwners); diff --git a/gfx/tests/gtest/TestConfigManager.cpp b/gfx/tests/gtest/TestConfigManager.cpp @@ -162,9 +162,6 @@ class MockGfxInfo final : public nsIGfxInfo { NS_IMETHOD GetUsingGPUProcess(bool* aOutValue) override { return NS_ERROR_NOT_IMPLEMENTED; } - NS_IMETHOD GetUsingRemoteCanvas(bool* aOutValue) override { - return NS_ERROR_NOT_IMPLEMENTED; - } NS_IMETHOD GetUsingAcceleratedCanvas(bool* aOutValue) override { return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp @@ -1234,8 +1234,7 @@ bool gfxPlatform::IsHeadless() { /* static */ bool gfxPlatform::UseRemoteCanvas() { - return XRE_IsContentProcess() && (gfx::gfxVars::RemoteCanvasEnabled() || - gfx::gfxVars::UseAcceleratedCanvas2D()); + return XRE_IsContentProcess() && gfx::gfxVars::UseAcceleratedCanvas2D(); } /* static */ @@ -2466,23 +2465,6 @@ void gfxPlatform::InitAcceleration() { if (XRE_IsParentProcess()) { InitGPUProcessPrefs(); - - FeatureState& feature = gfxConfig::GetFeature(Feature::REMOTE_CANVAS); - feature.SetDefault(StaticPrefs::gfx_canvas_remote_AtStartup(), - FeatureStatus::Disabled, "Disabled via pref"); - - if (!gfxConfig::IsEnabled(Feature::GPU_PROCESS) && - !StaticPrefs::gfx_canvas_remote_allow_in_parent_AtStartup()) { - feature.Disable(FeatureStatus::UnavailableNoGpuProcess, - "Disabled without GPU process", - "FEATURE_REMOTE_CANVAS_NO_GPU_PROCESS"_ns); - } - - gfxConfig::ForceDisable(Feature::REMOTE_CANVAS, FeatureStatus::Blocked, - "Remote Canvas not supported", - "FEATURE_REMOTE_CANVAS_NOT_SUPPORTED"_ns); - - gfxVars::SetRemoteCanvasEnabled(feature.IsEnabled()); } } @@ -3422,11 +3404,6 @@ static void AcceleratedCanvas2DPrefChangeCallback(const char*, void*) { feature.Disable(FeatureStatus::Blocklisted, message.get(), failureId); } - if (gfxVars::RemoteCanvasEnabled()) { - feature.ForceDisable(FeatureStatus::Failed, "Disabled by Remote Canvas", - "FEATURE_FAILURE_DISABLED_BY_REMOTE_CANVAS"_ns); - } - gfxVars::SetUseAcceleratedCanvas2D(feature.IsEnabled()); } @@ -4006,12 +3983,10 @@ bool gfxPlatform::FallbackFromAcceleration(FeatureStatus aStatus, return true; } - if ((gfxVars::RemoteCanvasEnabled() && - !StaticPrefs::dom_webgpu_allow_in_parent_AtStartup()) || - (gfxVars::UseAcceleratedCanvas2D() && + if ((gfxVars::UseAcceleratedCanvas2D() && !StaticPrefs::gfx_canvas_accelerated_allow_in_parent_AtStartup()) || (gfxVars::AllowWebGPU() && - !StaticPrefs::gfx_canvas_remote_allow_in_parent_AtStartup()) || + !StaticPrefs::dom_webgpu_allow_in_parent_AtStartup()) || (kIsAndroid && gfxVars::AllowWebglOop())) { // Because content has a lot of control over inputs to remote canvas, we // try to disable it as part of our final fallback step before disabling @@ -4058,12 +4033,6 @@ void gfxPlatform::DisableAllCanvasForFallback(FeatureStatus aStatus, gfxVars::SetAllowWebGPU(false); } - if (gfxVars::RemoteCanvasEnabled() && - !StaticPrefs::gfx_canvas_remote_allow_in_parent_AtStartup()) { - gfxConfig::Disable(Feature::REMOTE_CANVAS, aStatus, aMessage, aFailureId); - gfxVars::SetRemoteCanvasEnabled(false); - } - if (kIsAndroid) { // On android, enable out-of-process WebGL only when GPU process exists. gfxVars::SetAllowWebglOop(false); @@ -4089,12 +4058,6 @@ void gfxPlatform::DisableGPUProcess() { } /* static */ void gfxPlatform::DisableRemoteCanvas() { - if (gfxVars::RemoteCanvasEnabled()) { - gfxConfig::ForceDisable(Feature::REMOTE_CANVAS, FeatureStatus::Failed, - "Disabled by runtime error", - "FEATURE_REMOTE_CANVAS_RUNTIME_ERROR"_ns); - gfxVars::SetRemoteCanvasEnabled(false); - } if (gfxVars::UseAcceleratedCanvas2D()) { gfxConfig::ForceDisable(Feature::ACCELERATED_CANVAS2D, FeatureStatus::Failed, "Disabled by runtime error", diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml @@ -6788,39 +6788,12 @@ value: 0x7fff mirror: always -- name: gfx.canvas.remote - type: bool -#if defined(XP_WIN) - value: true -#else - value: false -#endif - mirror: once - -- name: gfx.canvas.remote.allow-in-parent - type: bool - value: false - mirror: once - # Whether OffscreenCanvas can use remote canvas - name: gfx.canvas.remote.allow-offscreen type: RelaxedAtomicBool value: true mirror: always -# How many worker threads spawned for remote canvas -# -1 - Calculate based on processor cores -# 0 - No worker threads spawned, will do work on CanvasRenderThread -# >0 - Create worker thread pool with given size -- name: gfx.canvas.remote.worker-threads - type: int32_t -#if defined(XP_WIN) - value: -1 -#else - value: 0 -#endif - mirror: once - # Default size of the shmem buffers used for recording - name: gfx.canvas.remote.default-buffer-size type: RelaxedAtomicUint32 @@ -6864,7 +6837,7 @@ - name: gfx.canvas.remote.use-draw-image-fast-path-d3d type: RelaxedAtomicBool - value: true + value: false mirror: always - name: gfx.canvas.remote.recycle-used-data-surface diff --git a/widget/GfxInfoBase.cpp b/widget/GfxInfoBase.cpp @@ -1954,12 +1954,6 @@ GfxInfoBase::GetUsingGPUProcess(bool* aOutValue) { } NS_IMETHODIMP -GfxInfoBase::GetUsingRemoteCanvas(bool* aOutValue) { - *aOutValue = gfx::gfxVars::RemoteCanvasEnabled(); - return NS_OK; -} - -NS_IMETHODIMP GfxInfoBase::GetUsingAcceleratedCanvas(bool* aOutValue) { *aOutValue = gfx::gfxVars::UseAcceleratedCanvas2D(); return NS_OK; diff --git a/widget/GfxInfoBase.h b/widget/GfxInfoBase.h @@ -78,7 +78,6 @@ class GfxInfoBase : public nsIGfxInfo, NS_IMETHOD GetAzureCanvasBackend(nsAString& aBackend) override; NS_IMETHOD GetAzureContentBackend(nsAString& aBackend) override; NS_IMETHOD GetUsingGPUProcess(bool* aOutValue) override; - NS_IMETHOD GetUsingRemoteCanvas(bool* aOutValue) override; NS_IMETHOD GetUsingAcceleratedCanvas(bool* aOutValue) override; NS_IMETHOD GetIsHeadless(bool* aIsHeadless) override; NS_IMETHOD GetTargetFrameRate(uint32_t* aTargetFrameRate) override; diff --git a/widget/nsIGfxInfo.idl b/widget/nsIGfxInfo.idl @@ -18,7 +18,6 @@ interface nsIGfxInfo : nsISupports readonly attribute AString AzureCanvasBackend; readonly attribute AString AzureContentBackend; readonly attribute boolean usingGPUProcess; - readonly attribute boolean usingRemoteCanvas; readonly attribute boolean usingAcceleratedCanvas; readonly attribute boolean hasBattery; readonly attribute AString DWriteVersion;