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-07-06 01:19:52 +03:00
|
|
|
#include "gfxPrefs.h"
|
2017-10-30 21:48:16 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2018-08-07 20:57:27 +03:00
|
|
|
#include "mozilla/layers/BufferEdgePad.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"
|
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"
|
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"
|
|
|
|
#include "nsServiceManagerUtils.h"
|
2018-07-26 04:40:00 +03:00
|
|
|
#include "nsSystemInfo.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-07 20:57:27 +03:00
|
|
|
bool
|
|
|
|
CapturedBufferState::Copy::CopyBuffer()
|
|
|
|
{
|
|
|
|
if (mSource->Lock(OpenMode::OPEN_READ_ONLY)) {
|
|
|
|
mDestination->UpdateDestinationFrom(*mSource, mBounds);
|
|
|
|
mSource->Unlock();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CapturedBufferState::Unrotate::UnrotateBuffer()
|
|
|
|
{
|
|
|
|
return mBuffer->UnrotateBufferTo(mParameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CapturedBufferState::PrepareBuffer()
|
|
|
|
{
|
|
|
|
return (!mBufferFinalize || mBufferFinalize->CopyBuffer()) &&
|
|
|
|
(!mBufferUnrotate || mBufferUnrotate->UnrotateBuffer()) &&
|
|
|
|
(!mBufferInitialize || mBufferInitialize->CopyBuffer());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
CapturedTiledPaintState::Copy::CopyBuffer()
|
|
|
|
{
|
|
|
|
RefPtr<gfx::SourceSurface> source = mSource->Snapshot();
|
|
|
|
|
|
|
|
// This operation requires the destination draw target to be untranslated,
|
|
|
|
// but the destination will have a transform from being part of a tiled draw
|
|
|
|
// target. However in this case, CopySurface ignores transforms so we don't
|
|
|
|
// need to do anything.
|
|
|
|
mDestination->CopySurface(source,
|
|
|
|
mSourceBounds,
|
|
|
|
mDestinationPoint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapturedTiledPaintState::Clear::ClearBuffer()
|
|
|
|
{
|
|
|
|
// See the comment in CopyBuffer for why we need to temporarily reset
|
|
|
|
// the transform of the draw target.
|
|
|
|
Matrix oldTransform = mTarget->GetTransform();
|
|
|
|
mTarget->SetTransform(Matrix());
|
|
|
|
|
|
|
|
if (mTargetOnWhite) {
|
|
|
|
mTargetOnWhite->SetTransform(Matrix());
|
|
|
|
for (auto iter = mDirtyRegion.RectIter(); !iter.Done(); iter.Next()) {
|
|
|
|
const gfx::Rect drawRect(iter.Get().X(), iter.Get().Y(),
|
|
|
|
iter.Get().Width(), iter.Get().Height());
|
|
|
|
mTarget->FillRect(drawRect, ColorPattern(Color(0.0, 0.0, 0.0, 1.0)));
|
|
|
|
mTargetOnWhite->FillRect(drawRect, ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
|
|
|
}
|
|
|
|
mTargetOnWhite->SetTransform(oldTransform);
|
|
|
|
} else {
|
|
|
|
for (auto iter = mDirtyRegion.RectIter(); !iter.Done(); iter.Next()) {
|
|
|
|
const gfx::Rect drawRect(iter.Get().X(), iter.Get().Y(),
|
|
|
|
iter.Get().Width(), iter.Get().Height());
|
|
|
|
mTarget->ClearRect(drawRect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mTarget->SetTransform(oldTransform);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapturedTiledPaintState::EdgePad::EdgePadBuffer()
|
|
|
|
{
|
|
|
|
PadDrawTargetOutFromRegion(mTarget, mValidRegion);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapturedTiledPaintState::PrePaint()
|
|
|
|
{
|
|
|
|
for (auto& copy : mCopies) {
|
|
|
|
copy.CopyBuffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& clear : mClears) {
|
|
|
|
clear.ClearBuffer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapturedTiledPaintState::Paint()
|
|
|
|
{
|
|
|
|
mTarget->DrawCapturedDT(mCapture, Matrix());
|
|
|
|
mTarget->Flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CapturedTiledPaintState::PostPaint()
|
|
|
|
{
|
|
|
|
if (mEdgePad) {
|
|
|
|
mEdgePad->EdgePadBuffer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/* static */ int32_t
|
|
|
|
PaintThread::CalculatePaintWorkerCount()
|
|
|
|
{
|
2018-07-26 04:40:00 +03:00
|
|
|
int32_t cpuCores = 1;
|
|
|
|
nsCOMPtr<nsIPropertyBag2> systemInfo = do_GetService(NS_SYSTEMINFO_CONTRACTID);
|
|
|
|
if (systemInfo) {
|
|
|
|
nsresult rv = systemInfo->GetPropertyAsInt32(NS_LITERAL_STRING("cpucores"), &cpuCores);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
cpuCores = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
int32_t workerCount = gfxPrefs::LayersOMTPPaintWorkers();
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
/* static */ void
|
|
|
|
PaintThread::Start()
|
2017-06-20 23:35:39 +03:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
|
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 =
|
2017-06-12 22:34:10 +03:00
|
|
|
NewRunnableMethod("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()
|
2017-06-09 23:30:00 +03:00
|
|
|
{
|
2017-08-17 00:53:15 +03:00
|
|
|
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);
|
|
|
|
}
|
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();
|
|
|
|
}
|
|
|
|
|
2017-06-09 23:30:00 +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,
|
2018-05-30 22:15:35 +03:00
|
|
|
std::move(pt)));
|
2017-07-06 01:19:47 +03:00
|
|
|
sThread->Shutdown();
|
|
|
|
sThread = nullptr;
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-07-06 01:19:47 +03:00
|
|
|
PaintThread::ShutdownOnPaintThread()
|
2017-06-09 23:30:00 +03:00
|
|
|
{
|
2017-07-06 01:19:47 +03:00
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
2017-06-09 23:30:00 +03:00
|
|
|
}
|
|
|
|
|
2017-08-17 00:53:15 +03:00
|
|
|
/* static */ PaintThread*
|
|
|
|
PaintThread::Get()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
return PaintThread::sSingleton.get();
|
|
|
|
}
|
|
|
|
|
2017-07-06 01:19:47 +03:00
|
|
|
/* static */ bool
|
2017-06-20 23:35:39 +03:00
|
|
|
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()
|
2017-10-30 21:49:58 +03:00
|
|
|
{
|
2018-07-19 20:41:34 +03:00
|
|
|
return (mPaintWorkers && mPaintWorkers->IsOnCurrentThread()) ||
|
|
|
|
(sThreadId == PlatformThread::CurrentId());
|
2017-10-26 07:47:17 +03:00
|
|
|
}
|
|
|
|
|
2018-05-15 21:36:11 +03:00
|
|
|
void
|
|
|
|
PaintThread::UpdateRenderMode()
|
|
|
|
{
|
|
|
|
if (!!mPaintWorkers != gfxPlatform::GetPlatform()->UsesTiling()) {
|
|
|
|
if (mPaintWorkers) {
|
|
|
|
mPaintWorkers = nullptr;
|
|
|
|
} else {
|
|
|
|
InitPaintWorkers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-22 03:12:14 +03:00
|
|
|
void
|
2018-08-07 20:57:27 +03:00
|
|
|
PaintThread::PrepareBuffer(CapturedBufferState* aState)
|
2017-11-22 03:12:14 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2018-08-07 20:57:27 +03:00
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
// If painting asynchronously, we need to acquire the compositor bridge which
|
|
|
|
// owns the underlying MessageChannel. Otherwise we leave it null and use
|
|
|
|
// synchronous dispatch.
|
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
|
|
|
RefPtr<CapturedBufferState> state(aState);
|
|
|
|
|
|
|
|
cbc->NotifyBeginAsyncPaint(state);
|
2017-11-22 03:12:14 +03:00
|
|
|
|
2018-08-07 20:57:27 +03:00
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PrepareBuffer",
|
|
|
|
[self, cbc, state]() -> void
|
|
|
|
{
|
|
|
|
self->AsyncPrepareBuffer(cbc,
|
|
|
|
state);
|
|
|
|
});
|
|
|
|
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::AsyncPrepareBuffer(CompositorBridgeChild* aBridge,
|
|
|
|
CapturedBufferState* aState)
|
|
|
|
{
|
|
|
|
AUTO_PROFILER_LABEL("PaintThread::AsyncPrepareBuffer", GRAPHICS);
|
|
|
|
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
if (!aState->PrepareBuffer()) {
|
|
|
|
gfxCriticalNote << "Failed to prepare buffers on the paint thread.";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aBridge->NotifyFinishedAsyncWorkerPaint(aState)) {
|
|
|
|
// We need to dispatch this task to ourselves so it runs after
|
|
|
|
// AsyncEndLayer
|
|
|
|
DispatchEndLayerTransaction(aBridge);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::PaintContents(CapturedPaintState* aState,
|
|
|
|
PrepDrawTargetForPaintingCallback aCallback)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
if (gfxPrefs::LayersOMTPDumpCapture() && aState->mCapture) {
|
|
|
|
aState->mCapture->Dump();
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
|
|
|
RefPtr<CapturedPaintState> state(aState);
|
|
|
|
|
|
|
|
cbc->NotifyBeginAsyncPaint(state);
|
|
|
|
|
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
|
|
|
|
[self, cbc, state, aCallback]() -> void
|
|
|
|
{
|
|
|
|
self->AsyncPaintContents(cbc,
|
|
|
|
state,
|
|
|
|
aCallback);
|
|
|
|
});
|
|
|
|
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::AsyncPaintContents(CompositorBridgeChild* aBridge,
|
|
|
|
CapturedPaintState* aState,
|
|
|
|
PrepDrawTargetForPaintingCallback aCallback)
|
|
|
|
{
|
|
|
|
AUTO_PROFILER_LABEL("PaintThread::AsyncPaintContents", GRAPHICS);
|
|
|
|
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
DrawTarget* target = aState->mTargetDual;
|
|
|
|
DrawTargetCapture* capture = aState->mCapture;
|
|
|
|
|
|
|
|
Matrix oldTransform = target->GetTransform();
|
|
|
|
bool oldPermitsSubpixelAA = target->GetPermitSubpixelAA();
|
|
|
|
|
|
|
|
target->SetTransform(capture->GetTransform());
|
|
|
|
target->SetPermitSubpixelAA(capture->GetPermitSubpixelAA());
|
|
|
|
|
|
|
|
if (aCallback(aState)) {
|
|
|
|
// Draw all the things into the actual dest target.
|
|
|
|
target->DrawCapturedDT(capture, Matrix());
|
|
|
|
|
|
|
|
if (!mDrawTargetsToFlush.Contains(target)) {
|
|
|
|
mDrawTargetsToFlush.AppendElement(target);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gfxPrefs::LayersOMTPReleaseCaptureOnMainThread()) {
|
|
|
|
// 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.
|
|
|
|
NS_ReleaseOnMainThreadSystemGroup("CapturePaintState::DrawTargetCapture", aState->mCapture.forget());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
target->SetTransform(oldTransform);
|
|
|
|
target->SetPermitSubpixelAA(oldPermitsSubpixelAA);
|
|
|
|
|
|
|
|
if (aBridge->NotifyFinishedAsyncWorkerPaint(aState)) {
|
|
|
|
// We need to dispatch this task to ourselves so it runs after
|
|
|
|
// AsyncEndLayer
|
|
|
|
DispatchEndLayerTransaction(aBridge);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PaintThread::PaintTiledContents(CapturedTiledPaintState* aState)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aState);
|
|
|
|
|
|
|
|
if (gfxPrefs::LayersOMTPDumpCapture() && aState->mCapture) {
|
|
|
|
aState->mCapture->Dump();
|
2018-02-06 07:03:49 +03:00
|
|
|
}
|
|
|
|
|
2017-11-22 03:12:14 +03:00
|
|
|
RefPtr<CompositorBridgeChild> cbc(CompositorBridgeChild::Get());
|
2018-08-07 20:57:27 +03:00
|
|
|
RefPtr<CapturedTiledPaintState> state(aState);
|
2017-11-22 03:12:14 +03:00
|
|
|
|
2017-12-05 05:23:50 +03:00
|
|
|
cbc->NotifyBeginAsyncPaint(state);
|
2017-11-22 03:12:14 +03:00
|
|
|
|
|
|
|
RefPtr<PaintThread> self = this;
|
2018-08-07 20:57:27 +03:00
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintTiledContents",
|
2017-11-22 03:12:14 +03:00
|
|
|
[self, cbc, state]() -> void
|
|
|
|
{
|
2018-08-07 20:57:27 +03:00
|
|
|
self->AsyncPaintTiledContents(cbc, state);
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-08-07 20:57:27 +03:00
|
|
|
PaintThread::AsyncPaintTiledContents(CompositorBridgeChild* aBridge,
|
|
|
|
CapturedTiledPaintState* aState)
|
2017-11-22 03:12:14 +03:00
|
|
|
{
|
2018-08-07 20:57:27 +03:00
|
|
|
AUTO_PROFILER_LABEL("PaintThread::AsyncPaintTiledContents", GRAPHICS);
|
2018-05-31 21:07:57 +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-08-07 20:57:27 +03:00
|
|
|
MOZ_ASSERT(aState);
|
2017-11-22 03:12:14 +03:00
|
|
|
|
2018-08-07 20:57:27 +03:00
|
|
|
aState->PrePaint();
|
|
|
|
aState->Paint();
|
|
|
|
aState->PostPaint();
|
2017-11-22 03:12:14 +03:00
|
|
|
|
|
|
|
if (gfxPrefs::LayersOMTPReleaseCaptureOnMainThread()) {
|
|
|
|
// 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-08-07 20:57:27 +03:00
|
|
|
NS_ReleaseOnMainThreadSystemGroup("CapturePaintState::DrawTargetCapture", aState->mCapture.forget());
|
2017-11-22 03:12:14 +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
|
|
|
{
|
|
|
|
RefPtr<CompositorBridgeChild> cbc(aBridge);
|
2018-08-07 20:57:27 +03:00
|
|
|
RefPtr<CapturedTiledPaintState> state(aState);
|
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
|
|
|
|
|
|
|
RefPtr<PaintThread> self = this;
|
2018-08-07 20:57:27 +03:00
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::AsyncPaintTiledContentsFinished",
|
|
|
|
[self, cbc, state]() -> void
|
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-07 20:57:27 +03:00
|
|
|
self->AsyncPaintTiledContentsFinished(cbc, state);
|
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
|
|
|
});
|
|
|
|
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-08-07 20:57:27 +03:00
|
|
|
PaintThread::AsyncPaintTiledContentsFinished(CompositorBridgeChild* aBridge,
|
|
|
|
CapturedTiledPaintState* aState)
|
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(IsOnPaintThread());
|
2018-08-07 20:57:27 +03:00
|
|
|
if (aBridge->NotifyFinishedAsyncWorkerPaint(aState)) {
|
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-11-22 03:12:14 +03:00
|
|
|
}
|
|
|
|
|
2018-08-07 20:57:27 +03:00
|
|
|
void
|
|
|
|
PaintThread::EndLayer()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::AsyncEndLayer",
|
|
|
|
[self]() -> void
|
|
|
|
{
|
|
|
|
self->AsyncEndLayer();
|
|
|
|
});
|
|
|
|
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(task.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, task);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-12-01 19:04:46 +03:00
|
|
|
void
|
|
|
|
PaintThread::Dispatch(RefPtr<Runnable>& aRunnable)
|
|
|
|
{
|
|
|
|
#ifndef OMTP_FORCE_SYNC
|
|
|
|
sThread->Dispatch(aRunnable.forget());
|
|
|
|
#else
|
|
|
|
SyncRunnable::DispatchToThread(sThread, aRunnable);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-08-07 20:57:27 +03:00
|
|
|
void
|
|
|
|
PaintThread::AsyncEndLayer()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
|
|
|
|
|
|
|
// Textureclient forces a flush once we "end paint", so
|
|
|
|
// users of this texture expect all the drawing to be complete.
|
|
|
|
// Force a flush now.
|
|
|
|
for (size_t i = 0; i < mDrawTargetsToFlush.Length(); i++) {
|
|
|
|
mDrawTargetsToFlush[i]->Flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
mDrawTargetsToFlush.Clear();
|
|
|
|
}
|
|
|
|
|
2017-08-11 07:41:31 +03:00
|
|
|
void
|
2017-08-17 00:02:13 +03:00
|
|
|
PaintThread::EndLayerTransaction(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)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void
|
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
|
|
|
PaintThread::DispatchEndLayerTransaction(CompositorBridgeChild* aBridge)
|
2017-08-11 07:41:31 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsOnPaintThread());
|
|
|
|
|
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
|
|
|
RefPtr<CompositorBridgeChild> cbc = aBridge;
|
|
|
|
RefPtr<PaintThread> self = this;
|
|
|
|
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::AsyncEndLayerTransaction",
|
|
|
|
[self, cbc]() -> void
|
|
|
|
{
|
|
|
|
self->AsyncEndLayerTransaction(cbc);
|
|
|
|
});
|
2017-10-30 21:49:58 +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
|
|
|
sThread->Dispatch(task.forget());
|
2017-08-11 07:41:31 +03:00
|
|
|
}
|
2017-08-09 18:24:15 +03:00
|
|
|
|
2017-06-09 23:30:00 +03:00
|
|
|
} // namespace layers
|
2017-06-12 22:34:10 +03:00
|
|
|
} // namespace mozilla
|