2017-06-09 23:30:00 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2017-10-28 02:10:06 +03:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2017-06-09 23:30:00 +03:00
|
|
|
/* 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 "PaintThread.h"
|
|
|
|
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
#include <algorithm>
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
#include "base/task.h"
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
#include "gfxPlatform.h"
|
2017-10-30 21:48:16 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2017-07-06 01:19:52 +03:00
|
|
|
#include "mozilla/layers/CompositorBridgeChild.h"
|
2017-08-11 07:41:31 +03:00
|
|
|
#include "mozilla/layers/ShadowLayers.h"
|
|
|
|
#include "mozilla/layers/SyncObject.h"
|
2017-06-22 18:36:14 +03:00
|
|
|
#include "mozilla/gfx/2D.h"
|
2017-07-06 01:19:52 +03:00
|
|
|
#include "mozilla/Preferences.h"
|
2019-07-26 04:10:23 +03:00
|
|
|
#include "mozilla/StaticPrefs_layers.h"
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
#include "mozilla/SharedThreadPool.h"
|
2017-06-20 23:35:39 +03:00
|
|
|
#include "mozilla/SyncRunnable.h"
|
2019-09-10 18:20:34 +03:00
|
|
|
#ifdef XP_MACOSX
|
2019-10-06 21:29:55 +03:00
|
|
|
# include "nsCocoaFeatures.h"
|
2019-09-10 18:20:34 +03:00
|
|
|
#endif
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
#include "nsIPropertyBag2.h"
|
2019-09-10 18:20:34 +03:00
|
|
|
#include "nsIThreadManager.h"
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2018-07-01 01:41:59 +03:00
|
|
|
#include "prsystem.h"
|
2017-06-20 23:35:39 +03:00
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
// Uncomment the following line to dispatch sync runnables when
|
|
|
|
// painting so that rasterization happens synchronously from
|
|
|
|
// the perspective of the main thread
|
|
|
|
// #define OMTP_FORCE_SYNC
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
2017-06-20 23:35:39 +03:00
|
|
|
using namespace gfx;
|
|
|
|
|
2018-08-13 20:10:14 +03:00
|
|
|
void PaintTask::DropTextureClients() { mClients.Clear(); }
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
StaticAutoPtr<PaintThread> PaintThread::sSingleton;
|
2017-07-06 01:19:47 +03:00
|
|
|
StaticRefPtr<nsIThread> PaintThread::sThread;
|
|
|
|
PlatformThreadId PaintThread::sThreadId;
|
2017-06-09 23:30:00 +03:00
|
|
|
|
2017-10-30 21:49:58 +03:00
|
|
|
PaintThread::PaintThread() {}
|
|
|
|
|
2017-06-20 23:35:39 +03:00
|
|
|
void PaintThread::Release() {}
|
|
|
|
|
|
|
|
void PaintThread::AddRef() {}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
int32_t PaintThread::CalculatePaintWorkerCount() {
|
2018-07-01 01:41:59 +03:00
|
|
|
int32_t cpuCores = PR_GetNumberOfProcessors();
|
2019-07-22 05:10:14 +03:00
|
|
|
int32_t workerCount = StaticPrefs::layers_omtp_paint_workers_AtStartup();
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
|
2018-01-25 23:12:39 +03:00
|
|
|
// If not manually specified, default to (cpuCores * 3) / 4, and clamp
|
|
|
|
// between 1 and 4. If a user wants more, they can manually specify it
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
if (workerCount < 1) {
|
2018-01-25 23:12:39 +03:00
|
|
|
workerCount = std::min(std::max((cpuCores * 3) / 4, 1), 4);
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return workerCount;
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void PaintThread::Start() {
|
2017-08-17 00:53:15 +03:00
|
|
|
PaintThread::sSingleton = new PaintThread();
|
|
|
|
|
|
|
|
if (!PaintThread::sSingleton->Init()) {
|
|
|
|
gfxCriticalNote << "Unable to start paint thread";
|
|
|
|
PaintThread::sSingleton = nullptr;
|
|
|
|
}
|
2017-06-20 23:35:39 +03:00
|
|
|
}
|
|
|
|
|
2019-09-10 18:20:34 +03:00
|
|
|
static uint32_t GetPaintThreadStackSize() {
|
|
|
|
#ifndef XP_MACOSX
|
|
|
|
return nsIThreadManager::DEFAULT_STACK_SIZE;
|
|
|
|
#else
|
|
|
|
// Workaround bug 1578075 by increasing the stack size of paint threads
|
|
|
|
if (nsCocoaFeatures::OnCatalinaOrLater()) {
|
2019-09-28 00:09:22 +03:00
|
|
|
static const uint32_t kCatalinaPaintThreadStackSize = 512 * 1024;
|
2019-10-06 21:29:55 +03:00
|
|
|
static_assert(
|
|
|
|
kCatalinaPaintThreadStackSize >= nsIThreadManager::DEFAULT_STACK_SIZE,
|
|
|
|
"update default stack size of paint "
|
|
|
|
"workers");
|
2019-09-10 18:20:34 +03:00
|
|
|
return kCatalinaPaintThreadStackSize;
|
|
|
|
}
|
|
|
|
return nsIThreadManager::DEFAULT_STACK_SIZE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
bool PaintThread::Init() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
RefPtr<nsIThread> thread;
|
2019-09-10 18:20:34 +03:00
|
|
|
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread),
|
|
|
|
nullptr, GetPaintThreadStackSize());
|
2017-06-09 23:30:00 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-07-06 01:19:47 +03:00
|
|
|
sThread = thread;
|
2017-06-09 23:30:00 +03:00
|
|
|
|
2018-05-02 17:21:13 +03:00
|
|
|
// Only create paint workers for tiling if we are using tiling or could
|
|
|
|
// expect to dynamically switch to tiling in the future
|
2018-05-15 21:36:11 +03:00
|
|
|
if (gfxPlatform::GetPlatform()->UsesTiling()) {
|
|
|
|
InitPaintWorkers();
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
}
|
|
|
|
|
2017-06-20 23:35:39 +03:00
|
|
|
nsCOMPtr<nsIRunnable> paintInitTask = NewRunnableMethod(
|
2017-06-12 22:34:10 +03:00
|
|
|
"PaintThread::InitOnPaintThread", this, &PaintThread::InitOnPaintThread);
|
2017-07-06 01:19:47 +03:00
|
|
|
SyncRunnable::DispatchToThread(sThread, paintInitTask);
|
2017-06-09 23:30:00 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
void PaintThread::InitOnPaintThread() {
|
|
|
|
MOZ_ASSERT(!NS_IsMainThread());
|
|
|
|
sThreadId = PlatformThread::CurrentId();
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
2018-05-15 21:36:11 +03:00
|
|
|
void PaintThread::InitPaintWorkers() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
int32_t count = PaintThread::CalculatePaintWorkerCount();
|
2018-07-19 20:41:34 +03:00
|
|
|
if (count != 1) {
|
|
|
|
mPaintWorkers =
|
|
|
|
SharedThreadPool::Get(NS_LITERAL_CSTRING("PaintWorker"), count);
|
2019-09-10 18:20:34 +03:00
|
|
|
mPaintWorkers->SetThreadStackSize(GetPaintThreadStackSize());
|
2018-07-19 20:41:34 +03:00
|
|
|
}
|
2018-05-15 21:36:11 +03:00
|
|
|
}
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
void DestroyPaintThread(UniquePtr<PaintThread>&& pt) {
|
|
|
|
MOZ_ASSERT(PaintThread::IsOnPaintThread());
|
|
|
|
pt->ShutdownOnPaintThread();
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
void PaintThread::Shutdown() {
|
2017-07-06 01:19:47 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
UniquePtr<PaintThread> pt(sSingleton.forget());
|
|
|
|
if (!pt) {
|
2017-06-09 23:30:00 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-10-27 23:39:28 +03:00
|
|
|
sThread->Dispatch(NewRunnableFunction("DestroyPaintThreadRunnable",
|
|
|
|
DestroyPaintThread, std::move(pt)));
|
2017-07-06 01:19:47 +03:00
|
|
|
sThread->Shutdown();
|
|
|
|
sThread = nullptr;
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
void PaintThread::ShutdownOnPaintThread() { MOZ_ASSERT(IsOnPaintThread()); }
|
2017-06-09 23:30:00 +03:00
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
PaintThread* PaintThread::Get() { return PaintThread::sSingleton.get(); }
|
2017-08-17 00:53:15 +03:00
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/* static */
|
|
|
|
bool PaintThread::IsOnPaintThread() {
|
2017-07-06 01:19:47 +03:00
|
|
|
return sThreadId == PlatformThread::CurrentId();
|
2017-06-20 23:35:39 +03:00
|
|
|
}
|
|
|
|
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
bool PaintThread::IsOnPaintWorkerThread() {
|
2018-07-19 20:41:34 +03:00
|
|
|
return (mPaintWorkers && mPaintWorkers->IsOnCurrentThread()) ||
|
|
|
|
(sThreadId == PlatformThread::CurrentId());
|
2017-10-26 07:47:17 +03:00
|
|
|
}
|
|
|
|
|
2018-08-13 20:58:25 +03:00
|
|
|
void PaintThread::Dispatch(RefPtr<Runnable>& aRunnable) {
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(aRunnable.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, aRunnable);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-05-15 21:36:11 +03:00
|
|
|
void PaintThread::UpdateRenderMode() {
|
|
|
|
if (!!mPaintWorkers != gfxPlatform::GetPlatform()->UsesTiling()) {
|
|
|
|
if (mPaintWorkers) {
|
|
|
|
mPaintWorkers = nullptr;
|
|
|
|
} else {
|
|
|
|
InitPaintWorkers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-12 18:28:59 +03:00
|
|
|
void PaintThread::QueuePaintTask(UniquePtr<PaintTask>&& aTask) {
|
2018-08-07 20:57:27 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2018-07-24 23:39:35 +03:00
|
|
|
MOZ_ASSERT(aTask);
|
2018-08-07 20:57:27 +03:00
|
|
|
|
2019-06-27 07:48:58 +03:00
|
|
|
if (StaticPrefs::layers_omtp_dump_capture() && aTask->mCapture) {
|
2018-07-24 23:39:35 +03:00
|
|
|
aTask->mCapture->Dump();
|
2018-02-06 07:03:49 +03:00
|
|
|
}
|
|
|
|
|
2018-09-12 18:28:59 +03:00
|
|
|
MOZ_RELEASE_ASSERT(aTask->mCapture->hasOneRef());
|
2017-11-22 03:12:14 +03:00
|
|
|
|
2018-09-12 18:28:59 +03:00
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
|
|
|
cbc->NotifyBeginAsyncPaint(aTask.get());
|
2017-11-22 03:12:14 +03:00
|
|
|
|
|
|
|
RefPtr<PaintThread> self = this;
|
2018-07-24 23:39:35 +03:00
|
|
|
RefPtr<Runnable> task =
|
|
|
|
NS_NewRunnableFunction("PaintThread::AsyncPaintTask",
|
2018-09-12 18:28:59 +03:00
|
|
|
[self, cbc, task = std::move(aTask)]() -> void {
|
|
|
|
self->AsyncPaintTask(cbc, task.get());
|
2017-11-22 03:12:14 +03:00
|
|
|
});
|
|
|
|
|
2018-07-19 20:41:34 +03:00
|
|
|
nsIEventTarget* paintThread =
|
|
|
|
mPaintWorkers ? static_cast<nsIEventTarget*>(mPaintWorkers.get())
|
|
|
|
: static_cast<nsIEventTarget*>(sThread.get());
|
|
|
|
|
2017-11-22 03:12:14 +03:00
|
|
|
#ifndef OMTP_FORCE_SYNC
|
2018-07-19 20:41:34 +03:00
|
|
|
paintThread->Dispatch(task.forget());
|
2017-11-22 03:12:14 +03:00
|
|
|
#else
|
2018-07-19 20:41:34 +03:00
|
|
|
SyncRunnable::DispatchToThread(paintThread, task);
|
2017-11-22 03:12:14 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-07-24 23:39:35 +03:00
|
|
|
void PaintThread::AsyncPaintTask(CompositorBridgeChild* aBridge,
|
|
|
|
PaintTask* aTask) {
|
|
|
|
AUTO_PROFILER_LABEL("PaintThread::AsyncPaintTask", GRAPHICS);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
MOZ_ASSERT(IsOnPaintWorkerThread());
|
2018-07-24 23:39:35 +03:00
|
|
|
MOZ_ASSERT(aTask);
|
2017-11-22 03:12:14 +03:00
|
|
|
|
2018-07-24 23:39:35 +03:00
|
|
|
gfx::DrawTargetCapture* capture = aTask->mCapture;
|
|
|
|
gfx::DrawTarget* target = aTask->mTarget;
|
2018-07-24 22:29:44 +03:00
|
|
|
|
2019-01-23 02:09:28 +03:00
|
|
|
if (target->IsValid()) {
|
|
|
|
// Do not replay to invalid targets. This can happen on device resets and
|
|
|
|
// the browser will ensure the graphics stack is reinitialized on the main
|
|
|
|
// thread.
|
|
|
|
target->DrawCapturedDT(capture, Matrix());
|
|
|
|
target->Flush();
|
|
|
|
}
|
2017-11-22 03:12:14 +03:00
|
|
|
|
2019-06-27 07:48:58 +03:00
|
|
|
if (StaticPrefs::layers_omtp_release_capture_on_main_thread()) {
|
2017-11-22 03:12:14 +03:00
|
|
|
// This should ensure the capture drawtarget, which may hold on to
|
|
|
|
// UnscaledFont objects, gets destroyed on the main thread (See bug
|
|
|
|
// 1404742). This assumes (unflushed) target DrawTargets do not themselves
|
|
|
|
// hold on to UnscaledFonts.
|
2018-07-24 23:39:35 +03:00
|
|
|
NS_ReleaseOnMainThreadSystemGroup("PaintTask::DrawTargetCapture",
|
|
|
|
aTask->mCapture.forget());
|
2017-11-22 03:12:14 +03:00
|
|
|
}
|
|
|
|
|
2018-08-13 20:57:15 +03:00
|
|
|
if (aBridge->NotifyFinishedAsyncWorkerPaint(aTask)) {
|
|
|
|
AsyncEndLayerTransaction(aBridge);
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-13 20:58:25 +03:00
|
|
|
void PaintThread::QueueEndLayerTransaction(SyncObjectClient* aSyncObject) {
|
2017-08-11 07:41:31 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2017-11-14 22:05:55 +03:00
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
|
|
|
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
if (cbc->NotifyBeginAsyncEndLayerTransaction(aSyncObject)) {
|
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
|
|
|
"PaintThread::AsyncEndLayerTransaction",
|
|
|
|
[self, cbc]() -> void { self->AsyncEndLayerTransaction(cbc); });
|
|
|
|
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2017-11-14 22:05:55 +03:00
|
|
|
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
void PaintThread::AsyncEndLayerTransaction(CompositorBridgeChild* aBridge) {
|
2018-08-13 20:57:15 +03:00
|
|
|
MOZ_ASSERT(IsOnPaintWorkerThread());
|
2017-08-11 07:41:31 +03:00
|
|
|
|
Create a PaintWorker thread pool and dispatch tiles to it (bug 1425056, r=bas)
This commit adds a paint worker thread pool to PaintThread, and dispatches
tiled paints to it. The thread pool is only created if tiling is enabled,
and its size is set by 'layers.omtp.paint-workers' and defaults to 1. If
-1 is specified, it will be sized to 'max((cpu_cores * 3) / 4, 1)'.
The one tricky part of dispatching tiled paints to a thread pool is the
AsyncEndLayerTransaction message that must execute once all paints are
finished. Previously, this runnable would be queued after all the paints
had been queued, ensuring it would be run after they had all completed.
With a thread pool, there is no guarantee. Instead this commit, uses
a flag on CompositorBridgeChild to signify whether all of the paints
have been queued ('mOutstandingAsyncEndLayerTransaction'), and after
every tiled paint it is examined to see if that paint was the last
paint, and if it is to run AsyncEndLayerTransaction. In addition,
if the async paints complete before we even mark the end of the
layer transaction, we queue it like normal.
The profiler markers are also complicated by using a thread pool.
I don't know of a great way to keep them working as they are per
thread, so for now I've removed them. I may have been the only
one using them anyway.
MozReview-Commit-ID: 5LIJ9GWSfCn
--HG--
extra : rebase_source : 0c26806f337a1b4b1511945f9c72e787b426c5ba
2017-12-08 10:18:05 +03:00
|
|
|
aBridge->NotifyFinishedAsyncEndLayerTransaction();
|
2017-08-11 07:41:31 +03:00
|
|
|
}
|
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
} // namespace layers
|
2017-06-12 22:34:10 +03:00
|
|
|
} // namespace mozilla
|