gecko-dev/image/DecodePool.cpp
Gerald Squelart 2416d881e2 Bug 1691589 - Reduce reliance on GeckoProfiler.h when only labels (and maybe markers) are needed - r=necko-reviewers,geckoview-reviewers,sg,agi,florian
There are no code changes, only #include changes.
It was a fairly mechanical process: Search for all "AUTO_PROFILER_LABEL", and in each file, if only labels are used, convert "GeckoProfiler.h" into "ProfilerLabels.h" (or just add that last one where needed).
In some files, there were also some marker calls but no other profiler-related calls, in these cases "GeckoProfiler.h" was replaced with both "ProfilerLabels.h" and "ProfilerMarkers.h", which still helps in reducing the use of the all-encompassing "GeckoProfiler.h".

Differential Revision: https://phabricator.services.mozilla.com/D104588
2021-02-16 04:44:19 +00:00

194 lines
4.9 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "DecodePool.h"
#include <algorithm>
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Monitor.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/TaskController.h"
#include "mozilla/TimeStamp.h"
#include "nsCOMPtr.h"
#include "nsIObserverService.h"
#include "nsThreadManager.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "prsystem.h"
#include "Decoder.h"
#include "IDecodingTask.h"
#include "RasterImage.h"
#if defined(XP_WIN)
# include <objbase.h>
#endif
using std::max;
using std::min;
namespace mozilla {
namespace image {
///////////////////////////////////////////////////////////////////////////////
// DecodePool implementation.
///////////////////////////////////////////////////////////////////////////////
/* static */
StaticRefPtr<DecodePool> DecodePool::sSingleton;
/* static */
uint32_t DecodePool::sNumCores = 0;
NS_IMPL_ISUPPORTS(DecodePool, nsIObserver)
/* static */
void DecodePool::Initialize() {
MOZ_ASSERT(NS_IsMainThread());
sNumCores = max<int32_t>(PR_GetNumberOfProcessors(), 1);
DecodePool::Singleton();
}
/* static */
DecodePool* DecodePool::Singleton() {
if (!sSingleton) {
MOZ_ASSERT(NS_IsMainThread());
sSingleton = new DecodePool();
ClearOnShutdown(&sSingleton);
}
return sSingleton;
}
/* static */
uint32_t DecodePool::NumberOfCores() { return sNumCores; }
#if defined(XP_WIN)
class IOThreadIniter final : public Runnable {
public:
explicit IOThreadIniter() : Runnable("image::IOThreadIniter") {}
NS_IMETHOD Run() override {
MOZ_ASSERT(!NS_IsMainThread());
CoInitialize(nullptr);
return NS_OK;
}
};
#endif
DecodePool::DecodePool() : mMutex("image::IOThread") {
// Initialize the I/O thread.
#if defined(XP_WIN)
// On Windows we use the io thread to get icons from the system. Any thread
// that makes system calls needs to call CoInitialize. And these system calls
// (SHGetFileInfo) should only be called from one thread at a time, in case
// we ever create more than on io thread.
nsCOMPtr<nsIRunnable> initer = new IOThreadIniter();
nsresult rv = NS_NewNamedThread("ImageIO", getter_AddRefs(mIOThread), initer);
#else
nsresult rv = NS_NewNamedThread("ImageIO", getter_AddRefs(mIOThread));
#endif
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mIOThread,
"Should successfully create image I/O thread");
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) {
obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
}
}
DecodePool::~DecodePool() {
MOZ_ASSERT(NS_IsMainThread(), "Must shut down DecodePool on main thread!");
}
NS_IMETHODIMP
DecodePool::Observe(nsISupports*, const char* aTopic, const char16_t*) {
MOZ_ASSERT(strcmp(aTopic, "xpcom-shutdown-threads") == 0, "Unexpected topic");
mShuttingDown = true;
nsCOMPtr<nsIThread> ioThread;
{
MutexAutoLock lock(mMutex);
ioThread.swap(mIOThread);
}
if (ioThread) {
ioThread->Shutdown();
}
return NS_OK;
}
bool DecodePool::IsShuttingDown() const { return mShuttingDown; }
class DecodingTask final : public Task {
public:
explicit DecodingTask(RefPtr<IDecodingTask>&& aTask)
: Task(false, aTask->Priority() == TaskPriority::eLow
? EventQueuePriority::Normal
: EventQueuePriority::MediumHigh),
mTask(aTask) {}
bool Run() override {
mTask->Run();
return true;
}
private:
RefPtr<IDecodingTask> mTask;
};
void DecodePool::AsyncRun(IDecodingTask* aTask) {
MOZ_ASSERT(aTask);
TaskController::Get()->AddTask(
MakeAndAddRef<DecodingTask>((RefPtr<IDecodingTask>(aTask))));
}
bool DecodePool::SyncRunIfPreferred(IDecodingTask* aTask,
const nsCString& aURI) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aTask);
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("DecodePool::SyncRunIfPreferred",
GRAPHICS, aURI);
if (aTask->ShouldPreferSyncRun()) {
aTask->Run();
return true;
}
AsyncRun(aTask);
return false;
}
void DecodePool::SyncRunIfPossible(IDecodingTask* aTask,
const nsCString& aURI) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aTask);
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("DecodePool::SyncRunIfPossible",
GRAPHICS, aURI);
aTask->Run();
}
already_AddRefed<nsIEventTarget> DecodePool::GetIOEventTarget() {
MutexAutoLock threadPoolLock(mMutex);
nsCOMPtr<nsIEventTarget> target = mIOThread;
return target.forget();
}
} // namespace image
} // namespace mozilla