Refactor PaintThread for async painting. (bug 1377060 part 1, r=mchang)

--HG--
extra : rebase_source : 4a3601108175cc2f091800f123461187282ca31f
This commit is contained in:
David Anderson 2017-07-05 15:19:47 -07:00
Родитель ffb43e0faf
Коммит 6cf29dbc0e
3 изменённых файлов: 68 добавлений и 30 удалений

Просмотреть файл

@ -6,6 +6,7 @@
#include "PaintThread.h"
#include "base/task.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/SyncRunnable.h"
@ -15,6 +16,8 @@ namespace layers {
using namespace gfx;
StaticAutoPtr<PaintThread> PaintThread::sSingleton;
StaticRefPtr<nsIThread> PaintThread::sThread;
PlatformThreadId PaintThread::sThreadId;
void
PaintThread::Release()
@ -30,24 +33,25 @@ void
PaintThread::InitOnPaintThread()
{
MOZ_ASSERT(!NS_IsMainThread());
mThreadId = PlatformThread::CurrentId();
sThreadId = PlatformThread::CurrentId();
}
bool
PaintThread::Init()
{
MOZ_ASSERT(NS_IsMainThread());
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(mThread));
RefPtr<nsIThread> thread;
nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread));
if (NS_FAILED(rv)) {
return false;
}
sThread = thread;
nsCOMPtr<nsIRunnable> paintInitTask =
NewRunnableMethod("PaintThread::InitOnPaintThread",
this, &PaintThread::InitOnPaintThread);
SyncRunnable::DispatchToThread(PaintThread::sSingleton->mThread, paintInitTask);
SyncRunnable::DispatchToThread(sThread, paintInitTask);
return true;
}
@ -69,49 +73,68 @@ PaintThread::Get()
return PaintThread::sSingleton.get();
}
void
DestroyPaintThread(UniquePtr<PaintThread>&& pt)
{
MOZ_ASSERT(PaintThread::IsOnPaintThread());
pt->ShutdownOnPaintThread();
}
/* static */ void
PaintThread::Shutdown()
{
if (!PaintThread::sSingleton) {
MOZ_ASSERT(NS_IsMainThread());
UniquePtr<PaintThread> pt(sSingleton.forget());
if (!pt) {
return;
}
PaintThread::sSingleton->ShutdownImpl();
PaintThread::sSingleton = nullptr;
sThread->Dispatch(NewRunnableFunction(DestroyPaintThread, Move(pt)));
sThread->Shutdown();
sThread = nullptr;
}
void
PaintThread::ShutdownImpl()
PaintThread::ShutdownOnPaintThread()
{
MOZ_ASSERT(NS_IsMainThread());
PaintThread::sSingleton->mThread->AsyncShutdown();
MOZ_ASSERT(IsOnPaintThread());
}
bool
/* static */ bool
PaintThread::IsOnPaintThread()
{
MOZ_ASSERT(mThread);
return PlatformThread::CurrentId() == mThreadId;
return sThreadId == PlatformThread::CurrentId();
}
void
PaintThread::PaintContentsAsync(gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget)
{
MOZ_ASSERT(IsOnPaintThread());
// Draw all the things into the actual dest target.
aTarget->DrawCapturedDT(aCapture, Matrix());
}
void
PaintThread::PaintContents(DrawTargetCapture* aCapture,
DrawTarget* aTarget)
{
if (!IsOnPaintThread()) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> paintTask =
NewRunnableMethod<DrawTargetCapture*, DrawTarget*>("PaintThread::PaintContents",
this,
&PaintThread::PaintContents,
aCapture, aTarget);
MOZ_ASSERT(NS_IsMainThread());
SyncRunnable::DispatchToThread(mThread, paintTask);
return;
}
RefPtr<DrawTargetCapture> capture(aCapture);
RefPtr<DrawTarget> target(aTarget);
// Draw all the things into the actual dest target.
aTarget->DrawCapturedDT(aCapture, Matrix());
RefPtr<PaintThread> self = this;
RefPtr<Runnable> task = NS_NewRunnableFunction("PaintThread::PaintContents",
[self, capture, target]() -> void
{
self->PaintContentsAsync(capture, target);
});
SyncRunnable::DispatchToThread(sThread, task);
return;
}
} // namespace layers

Просмотреть файл

@ -9,6 +9,7 @@
#include "base/platform_thread.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsThreadUtils.h"
namespace mozilla {
@ -21,12 +22,15 @@ namespace layers {
class PaintThread final
{
friend void DestroyPaintThread(UniquePtr<PaintThread>&& aPaintThread);
public:
static void Start();
static void Shutdown();
static PaintThread* Get();
void PaintContents(gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget);
// Sync Runnables need threads to be ref counted,
// But this thread lives through the whole process.
// We're only temporarily using sync runnables so
@ -34,18 +38,22 @@ public:
void Release();
void AddRef();
// Helper for asserts.
static bool IsOnPaintThread();
private:
bool IsOnPaintThread();
bool Init();
void ShutdownImpl();
void ShutdownOnPaintThread();
void InitOnPaintThread();
void PaintContentsAsync(gfx::DrawTargetCapture* aCapture,
gfx::DrawTarget* aTarget);
static StaticAutoPtr<PaintThread> sSingleton;
RefPtr<nsIThread> mThread;
PlatformThreadId mThreadId;
static StaticRefPtr<nsIThread> sThread;
static PlatformThreadId sThreadId;
};
} // namespace layers
} // namespace mozilla
#endif
#endif

Просмотреть файл

@ -67,6 +67,13 @@ public:
T& operator*() const { return *get(); }
T* forget()
{
T* temp = mRawPtr;
mRawPtr = nullptr;
return temp;
}
private:
// Disallow copy constructor, but only in debug mode. We only define
// a default constructor in debug mode (see above); if we declared