mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1119158 - Retarget OnDataAvailable to a new I/O thread instead of the image decoding thread pool. r=sworkman
This commit is contained in:
parent
f63da28c3b
commit
29a704eea3
@ -9,8 +9,8 @@
|
|||||||
#include "mozilla/ModuleUtils.h"
|
#include "mozilla/ModuleUtils.h"
|
||||||
#include "nsMimeTypes.h"
|
#include "nsMimeTypes.h"
|
||||||
|
|
||||||
|
#include "DecodePool.h"
|
||||||
#include "ImageFactory.h"
|
#include "ImageFactory.h"
|
||||||
#include "RasterImage.h"
|
|
||||||
#include "ShutdownTracker.h"
|
#include "ShutdownTracker.h"
|
||||||
#include "SurfaceCache.h"
|
#include "SurfaceCache.h"
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ mozilla::image::InitModule()
|
|||||||
|
|
||||||
mozilla::image::ShutdownTracker::Initialize();
|
mozilla::image::ShutdownTracker::Initialize();
|
||||||
mozilla::image::ImageFactory::Initialize();
|
mozilla::image::ImageFactory::Initialize();
|
||||||
mozilla::image::RasterImage::Initialize();
|
mozilla::image::DecodePool::Initialize();
|
||||||
mozilla::image::SurfaceCache::Initialize();
|
mozilla::image::SurfaceCache::Initialize();
|
||||||
imgLoader::GlobalInit();
|
imgLoader::GlobalInit();
|
||||||
sInitialized = true;
|
sInitialized = true;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsIThreadPool.h"
|
#include "nsIThreadPool.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
#include "nsXPCOMCIDInternal.h"
|
#include "nsXPCOMCIDInternal.h"
|
||||||
#include "prsystem.h"
|
#include "prsystem.h"
|
||||||
|
|
||||||
@ -127,35 +128,36 @@ private:
|
|||||||
|
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
|
||||||
class RIDThreadPoolListener MOZ_FINAL : public nsIThreadPoolListener
|
class DecodePoolNuwaListener MOZ_FINAL : public nsIThreadPoolListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSITHREADPOOLLISTENER
|
|
||||||
|
|
||||||
RIDThreadPoolListener() { }
|
|
||||||
|
|
||||||
private:
|
NS_IMETHODIMP OnThreadCreated()
|
||||||
~RIDThreadPoolListener() { }
|
{
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(RIDThreadPoolListener, nsIThreadPoolListener)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
RIDThreadPoolListener::OnThreadCreated()
|
|
||||||
{
|
|
||||||
if (IsNuwaProcess()) {
|
if (IsNuwaProcess()) {
|
||||||
NuwaMarkCurrentThread(static_cast<void(*)(void*)>(nullptr), nullptr);
|
NuwaMarkCurrentThread(static_cast<void(*)(void*)>(nullptr), nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP OnThreadShuttingDown() { return NS_OK; }
|
||||||
RIDThreadPoolListener::OnThreadShuttingDown()
|
|
||||||
|
private:
|
||||||
|
~DecodePoolNuwaListener() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(DecodePoolNuwaListener, nsIThreadPoolListener)
|
||||||
|
|
||||||
|
class RegisterDecodeIOThreadWithNuwaRunnable : public nsRunnable
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD Run()
|
||||||
|
{
|
||||||
|
NuwaMarkCurrentThread(static_cast<void(*)(void*)>(nullptr), nullptr);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
#endif // MOZ_NUWA_PROCESS
|
#endif // MOZ_NUWA_PROCESS
|
||||||
|
|
||||||
|
|
||||||
@ -167,6 +169,13 @@ RIDThreadPoolListener::OnThreadShuttingDown()
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(DecodePool, nsIObserver)
|
NS_IMPL_ISUPPORTS(DecodePool, nsIObserver)
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
DecodePool::Initialize()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
DecodePool::Singleton();
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ DecodePool*
|
/* static */ DecodePool*
|
||||||
DecodePool::Singleton()
|
DecodePool::Singleton()
|
||||||
{
|
{
|
||||||
@ -180,8 +189,9 @@ DecodePool::Singleton()
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecodePool::DecodePool()
|
DecodePool::DecodePool()
|
||||||
: mThreadPoolMutex("Thread Pool")
|
: mMutex("image::DecodePool")
|
||||||
{
|
{
|
||||||
|
// Initialize the thread pool.
|
||||||
mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID);
|
mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID);
|
||||||
MOZ_RELEASE_ASSERT(mThreadPool,
|
MOZ_RELEASE_ASSERT(mThreadPool,
|
||||||
"Should succeed in creating image decoding thread pool");
|
"Should succeed in creating image decoding thread pool");
|
||||||
@ -200,10 +210,22 @@ DecodePool::DecodePool()
|
|||||||
|
|
||||||
#ifdef MOZ_NUWA_PROCESS
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
if (IsNuwaProcess()) {
|
if (IsNuwaProcess()) {
|
||||||
mThreadPool->SetListener(new RIDThreadPoolListener());
|
mThreadPool->SetListener(new DecodePoolNuwaListener());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize the I/O thread.
|
||||||
|
nsresult rv = NS_NewNamedThread("ImageIO", getter_AddRefs(mIOThread));
|
||||||
|
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mIOThread,
|
||||||
|
"Should successfully create image I/O thread");
|
||||||
|
|
||||||
|
#ifdef MOZ_NUWA_PROCESS
|
||||||
|
nsCOMPtr<nsIRunnable> worker = new RegisterDecodeIOThreadWithNuwaRunnable();
|
||||||
|
rv = mIOThread->Dispatch(worker, NS_DISPATCH_NORMAL);
|
||||||
|
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv),
|
||||||
|
"Should register decode IO thread with Nuwa process");
|
||||||
|
#endif
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
||||||
if (obsSvc) {
|
if (obsSvc) {
|
||||||
obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
|
obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
|
||||||
@ -221,17 +243,22 @@ DecodePool::Observe(nsISupports*, const char* aTopic, const char16_t*)
|
|||||||
MOZ_ASSERT(strcmp(aTopic, "xpcom-shutdown-threads") == 0, "Unexpected topic");
|
MOZ_ASSERT(strcmp(aTopic, "xpcom-shutdown-threads") == 0, "Unexpected topic");
|
||||||
|
|
||||||
nsCOMPtr<nsIThreadPool> threadPool;
|
nsCOMPtr<nsIThreadPool> threadPool;
|
||||||
|
nsCOMPtr<nsIThread> ioThread;
|
||||||
|
|
||||||
{
|
{
|
||||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
threadPool = mThreadPool;
|
threadPool.swap(mThreadPool);
|
||||||
mThreadPool = nullptr;
|
ioThread.swap(mIOThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threadPool) {
|
if (threadPool) {
|
||||||
threadPool->Shutdown();
|
threadPool->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ioThread) {
|
||||||
|
ioThread->Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +271,7 @@ DecodePool::AsyncDecode(Decoder* aDecoder)
|
|||||||
|
|
||||||
// Dispatch to the thread pool if it exists. If it doesn't, we're currently
|
// Dispatch to the thread pool if it exists. If it doesn't, we're currently
|
||||||
// shutting down, so it's OK to just drop the job on the floor.
|
// shutting down, so it's OK to just drop the job on the floor.
|
||||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
MutexAutoLock threadPoolLock(mMutex);
|
||||||
if (mThreadPool) {
|
if (mThreadPool) {
|
||||||
mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL);
|
mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
@ -274,11 +301,19 @@ DecodePool::SyncDecodeIfPossible(Decoder* aDecoder)
|
|||||||
already_AddRefed<nsIEventTarget>
|
already_AddRefed<nsIEventTarget>
|
||||||
DecodePool::GetEventTarget()
|
DecodePool::GetEventTarget()
|
||||||
{
|
{
|
||||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
MutexAutoLock threadPoolLock(mMutex);
|
||||||
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(mThreadPool);
|
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(mThreadPool);
|
||||||
return target.forget();
|
return target.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIEventTarget>
|
||||||
|
DecodePool::GetIOEventTarget()
|
||||||
|
{
|
||||||
|
MutexAutoLock threadPoolLock(mMutex);
|
||||||
|
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(mIOThread);
|
||||||
|
return target.forget();
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIRunnable>
|
already_AddRefed<nsIRunnable>
|
||||||
DecodePool::CreateDecodeWorker(Decoder* aDecoder)
|
DecodePool::CreateDecodeWorker(Decoder* aDecoder)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "nsIEventTarget.h"
|
#include "nsIEventTarget.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
|
||||||
|
class nsIThread;
|
||||||
class nsIThreadPool;
|
class nsIThreadPool;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -41,6 +42,10 @@ public:
|
|||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
|
/// Initializes the singleton instance. Should be called from the main thread.
|
||||||
|
static void Initialize();
|
||||||
|
|
||||||
|
/// Returns the singleton instance.
|
||||||
static DecodePool* Singleton();
|
static DecodePool* Singleton();
|
||||||
|
|
||||||
/// Ask the DecodePool to run @aDecoder asynchronously and return immediately.
|
/// Ask the DecodePool to run @aDecoder asynchronously and return immediately.
|
||||||
@ -69,6 +74,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
already_AddRefed<nsIEventTarget> GetEventTarget();
|
already_AddRefed<nsIEventTarget> GetEventTarget();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an event target interface to the DecodePool's I/O thread. Callers
|
||||||
|
* who want to deliver data to workers on the DecodePool can use this event
|
||||||
|
* target.
|
||||||
|
*
|
||||||
|
* @return An nsIEventTarget interface to the thread pool's I/O thread.
|
||||||
|
*/
|
||||||
|
already_AddRefed<nsIEventTarget> GetIOEventTarget();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a worker which can be used to attempt further decoding using the
|
* Creates a worker which can be used to attempt further decoding using the
|
||||||
* provided decoder.
|
* provided decoder.
|
||||||
@ -91,11 +105,10 @@ private:
|
|||||||
|
|
||||||
static StaticRefPtr<DecodePool> sSingleton;
|
static StaticRefPtr<DecodePool> sSingleton;
|
||||||
|
|
||||||
// mThreadPoolMutex protects mThreadPool. For all RasterImages R,
|
// mMutex protects mThreadPool and mIOThread.
|
||||||
// R::mDecodingMonitor must be acquired before mThreadPoolMutex
|
Mutex mMutex;
|
||||||
// if both are acquired; the other order may cause deadlock.
|
|
||||||
Mutex mThreadPoolMutex;
|
|
||||||
nsCOMPtr<nsIThreadPool> mThreadPool;
|
nsCOMPtr<nsIThreadPool> mThreadPool;
|
||||||
|
nsCOMPtr<nsIThread> mIOThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
@ -297,14 +297,6 @@ RasterImage::~RasterImage()
|
|||||||
SurfaceCache::RemoveImage(ImageKey(this));
|
SurfaceCache::RemoveImage(ImageKey(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void
|
|
||||||
RasterImage::Initialize()
|
|
||||||
{
|
|
||||||
// Create our singletons now, so we don't have to worry about what thread
|
|
||||||
// they're created on.
|
|
||||||
DecodePool::Singleton();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
RasterImage::Init(const char* aMimeType,
|
RasterImage::Init(const char* aMimeType,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags)
|
||||||
|
@ -280,8 +280,6 @@ public:
|
|||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Initialize();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
|
void DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
|
||||||
gfxContext* aContext,
|
gfxContext* aContext,
|
||||||
|
@ -699,10 +699,9 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
|
|||||||
nsAutoCString mimeType;
|
nsAutoCString mimeType;
|
||||||
nsresult rv = httpChannel->GetContentType(mimeType);
|
nsresult rv = httpChannel->GetContentType(mimeType);
|
||||||
if (NS_SUCCEEDED(rv) && !mimeType.EqualsLiteral(IMAGE_SVG_XML)) {
|
if (NS_SUCCEEDED(rv) && !mimeType.EqualsLiteral(IMAGE_SVG_XML)) {
|
||||||
// Image object not created until OnDataAvailable, so forward to static
|
// Retarget OnDataAvailable to the DecodePool's IO thread.
|
||||||
// DecodePool directly.
|
|
||||||
nsCOMPtr<nsIEventTarget> target =
|
nsCOMPtr<nsIEventTarget> target =
|
||||||
DecodePool::Singleton()->GetEventTarget();
|
DecodePool::Singleton()->GetIOEventTarget();
|
||||||
rv = retargetable->RetargetDeliveryTo(target);
|
rv = retargetable->RetargetDeliveryTo(target);
|
||||||
}
|
}
|
||||||
PR_LOG(GetImgLog(), PR_LOG_WARNING,
|
PR_LOG(GetImgLog(), PR_LOG_WARNING,
|
||||||
|
Loading…
Reference in New Issue
Block a user