/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=99: */ /* 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" #include "base/task.h" #include "mozilla/gfx/2D.h" #include "mozilla/SyncRunnable.h" namespace mozilla { namespace layers { using namespace gfx; StaticAutoPtr PaintThread::sSingleton; StaticRefPtr PaintThread::sThread; PlatformThreadId PaintThread::sThreadId; void PaintThread::Release() { } void PaintThread::AddRef() { } void PaintThread::InitOnPaintThread() { MOZ_ASSERT(!NS_IsMainThread()); sThreadId = PlatformThread::CurrentId(); } bool PaintThread::Init() { MOZ_ASSERT(NS_IsMainThread()); RefPtr thread; nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread)); if (NS_FAILED(rv)) { return false; } sThread = thread; nsCOMPtr paintInitTask = NewRunnableMethod("PaintThread::InitOnPaintThread", this, &PaintThread::InitOnPaintThread); SyncRunnable::DispatchToThread(sThread, paintInitTask); return true; } /* static */ void PaintThread::Start() { PaintThread::sSingleton = new PaintThread(); if (!PaintThread::sSingleton->Init()) { gfxCriticalNote << "Unable to start paint thread"; PaintThread::sSingleton = nullptr; } } /* static */ PaintThread* PaintThread::Get() { MOZ_ASSERT(NS_IsMainThread()); return PaintThread::sSingleton.get(); } void DestroyPaintThread(UniquePtr&& pt) { MOZ_ASSERT(PaintThread::IsOnPaintThread()); pt->ShutdownOnPaintThread(); } /* static */ void PaintThread::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); UniquePtr pt(sSingleton.forget()); if (!pt) { return; } sThread->Dispatch(NewRunnableFunction(DestroyPaintThread, Move(pt))); sThread->Shutdown(); sThread = nullptr; } void PaintThread::ShutdownOnPaintThread() { MOZ_ASSERT(IsOnPaintThread()); } /* static */ bool PaintThread::IsOnPaintThread() { 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) { MOZ_ASSERT(NS_IsMainThread()); RefPtr capture(aCapture); RefPtr target(aTarget); RefPtr self = this; RefPtr task = NS_NewRunnableFunction("PaintThread::PaintContents", [self, capture, target]() -> void { self->PaintContentsAsync(capture, target); }); SyncRunnable::DispatchToThread(sThread, task); return; } } // namespace layers } // namespace mozilla