gecko-dev/gfx/ipc/VsyncBridgeChild.cpp
Wes Kocher 4b3d16605a Backed out 18 changesets (bug 792652) for build bustage on linux64 a=backout CLOSED TREE
Backed out changeset 90eaf6aec002 (bug 792652)
Backed out changeset ddd915ab4a48 (bug 792652)
Backed out changeset 95eff6c45cae (bug 792652)
Backed out changeset 75855b5a9ab9 (bug 792652)
Backed out changeset b658ebaad5d7 (bug 792652)
Backed out changeset 2ba36b8ac60c (bug 792652)
Backed out changeset 94fcd3bf3f34 (bug 792652)
Backed out changeset cf9c4164eb43 (bug 792652)
Backed out changeset 59e6d0a4f35b (bug 792652)
Backed out changeset bdf86b8b9c43 (bug 792652)
Backed out changeset 8edf4b247250 (bug 792652)
Backed out changeset 63a3c8e4016e (bug 792652)
Backed out changeset e3e496eab991 (bug 792652)
Backed out changeset 5a1e3136323a (bug 792652)
Backed out changeset dbbe3a8c00e7 (bug 792652)
Backed out changeset 1829d5358808 (bug 792652)
Backed out changeset 004cd692ba6d (bug 792652)
Backed out changeset 92e7fee81fa2 (bug 792652)
2016-11-08 12:05:28 -08:00

156 lines
3.9 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "VsyncBridgeChild.h"
#include "VsyncIOThreadHolder.h"
#include "mozilla/dom/ContentChild.h"
namespace mozilla {
namespace gfx {
VsyncBridgeChild::VsyncBridgeChild(RefPtr<VsyncIOThreadHolder> aThread, const uint64_t& aProcessToken)
: mThread(aThread),
mLoop(nullptr),
mProcessToken(aProcessToken)
{
}
VsyncBridgeChild::~VsyncBridgeChild()
{
}
/* static */ RefPtr<VsyncBridgeChild>
VsyncBridgeChild::Create(RefPtr<VsyncIOThreadHolder> aThread,
const uint64_t& aProcessToken,
Endpoint<PVsyncBridgeChild>&& aEndpoint)
{
RefPtr<VsyncBridgeChild> child = new VsyncBridgeChild(aThread, aProcessToken);
RefPtr<nsIRunnable> task = NewRunnableMethod<Endpoint<PVsyncBridgeChild>&&>(
child, &VsyncBridgeChild::Open, Move(aEndpoint));
aThread->GetThread()->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL);
return child;
}
void
VsyncBridgeChild::Open(Endpoint<PVsyncBridgeChild>&& aEndpoint)
{
if (!aEndpoint.Bind(this)) {
// The GPU Process Manager might be gone if we receive ActorDestroy very
// late in shutdown.
if (GPUProcessManager* gpm = GPUProcessManager::Get())
gpm->NotifyRemoteActorDestroyed(mProcessToken);
return;
}
mLoop = MessageLoop::current();
// Last reference is freed in DeallocPVsyncBridgeChild.
AddRef();
}
class NotifyVsyncTask : public Runnable
{
public:
NotifyVsyncTask(RefPtr<VsyncBridgeChild> aVsyncBridge,
TimeStamp aTimeStamp,
const uint64_t& aLayersId)
: mVsyncBridge(aVsyncBridge),
mTimeStamp(aTimeStamp),
mLayersId(aLayersId)
{}
NS_IMETHOD Run() override {
mVsyncBridge->NotifyVsyncImpl(mTimeStamp, mLayersId);
return NS_OK;
}
private:
RefPtr<VsyncBridgeChild> mVsyncBridge;
TimeStamp mTimeStamp;
uint64_t mLayersId;
};
bool
VsyncBridgeChild::IsOnVsyncIOThread() const
{
return MessageLoop::current() == mLoop;
}
void
VsyncBridgeChild::NotifyVsync(TimeStamp aTimeStamp, const uint64_t& aLayersId)
{
// This should be on the Vsync thread (not the Vsync I/O thread).
MOZ_ASSERT(!IsOnVsyncIOThread());
RefPtr<NotifyVsyncTask> task = new NotifyVsyncTask(this, aTimeStamp, aLayersId);
mLoop->PostTask(task.forget());
}
void
VsyncBridgeChild::NotifyVsyncImpl(TimeStamp aTimeStamp, const uint64_t& aLayersId)
{
// This should be on the Vsync I/O thread.
MOZ_ASSERT(IsOnVsyncIOThread());
if (!mProcessToken) {
return;
}
SendNotifyVsync(aTimeStamp, aLayersId);
}
void
VsyncBridgeChild::Close()
{
if (!IsOnVsyncIOThread()) {
mLoop->PostTask(NewRunnableMethod(this, &VsyncBridgeChild::Close));
return;
}
// We clear mProcessToken when the channel is closed.
if (!mProcessToken) {
return;
}
// Clear the process token so we don't notify the GPUProcessManager. It already
// knows we're closed since it manually called Close, and in fact the GPM could
// have already been destroyed during shutdown.
mProcessToken = 0;
// Close the underlying IPC channel.
PVsyncBridgeChild::Close();
}
void
VsyncBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
{
if (mProcessToken) {
GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
mProcessToken = 0;
}
}
void
VsyncBridgeChild::DeallocPVsyncBridgeChild()
{
Release();
}
void
VsyncBridgeChild::ProcessingError(Result aCode, const char* aReason)
{
MOZ_RELEASE_ASSERT(aCode == MsgDropped, "Processing error in VsyncBridgeChild");
}
void
VsyncBridgeChild::FatalError(const char* const aName, const char* const aMsg) const
{
dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
}
} // namespace gfx
} // namespace mozilla