Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/ipc/VsyncBridgeChild.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
#include "VsyncBridgeChild.h"
7
#include "VsyncIOThreadHolder.h"
8
#include "mozilla/dom/ContentChild.h"
9
10
namespace mozilla {
11
namespace gfx {
12
13
VsyncBridgeChild::VsyncBridgeChild(RefPtr<VsyncIOThreadHolder> aThread, const uint64_t& aProcessToken)
14
 : mThread(aThread),
15
   mLoop(nullptr),
16
   mProcessToken(aProcessToken)
17
0
{
18
0
}
19
20
VsyncBridgeChild::~VsyncBridgeChild()
21
0
{
22
0
}
23
24
/* static */ RefPtr<VsyncBridgeChild>
25
VsyncBridgeChild::Create(RefPtr<VsyncIOThreadHolder> aThread,
26
                         const uint64_t& aProcessToken,
27
                         Endpoint<PVsyncBridgeChild>&& aEndpoint)
28
0
{
29
0
  RefPtr<VsyncBridgeChild> child = new VsyncBridgeChild(aThread, aProcessToken);
30
0
31
0
  RefPtr<nsIRunnable> task = NewRunnableMethod<Endpoint<PVsyncBridgeChild>&&>(
32
0
    "gfx::VsyncBridgeChild::Open",
33
0
    child,
34
0
    &VsyncBridgeChild::Open,
35
0
    std::move(aEndpoint));
36
0
  aThread->GetThread()->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL);
37
0
38
0
  return child;
39
0
}
40
41
void
42
VsyncBridgeChild::Open(Endpoint<PVsyncBridgeChild>&& aEndpoint)
43
0
{
44
0
  if (!aEndpoint.Bind(this)) {
45
0
    // The GPU Process Manager might be gone if we receive ActorDestroy very
46
0
    // late in shutdown.
47
0
    if (GPUProcessManager* gpm = GPUProcessManager::Get())
48
0
      gpm->NotifyRemoteActorDestroyed(mProcessToken);
49
0
    return;
50
0
  }
51
0
52
0
  mLoop = MessageLoop::current();
53
0
54
0
  // Last reference is freed in DeallocPVsyncBridgeChild.
55
0
  AddRef();
56
0
}
57
58
class NotifyVsyncTask : public Runnable
59
{
60
public:
61
  NotifyVsyncTask(RefPtr<VsyncBridgeChild> aVsyncBridge,
62
                  TimeStamp aTimeStamp,
63
                  const layers::LayersId& aLayersId)
64
    : Runnable("gfx::NotifyVsyncTask")
65
    , mVsyncBridge(aVsyncBridge)
66
    , mTimeStamp(aTimeStamp)
67
    , mLayersId(aLayersId)
68
0
  {}
69
70
0
  NS_IMETHOD Run() override {
71
0
    mVsyncBridge->NotifyVsyncImpl(mTimeStamp, mLayersId);
72
0
    return NS_OK;
73
0
  }
74
75
private:
76
  RefPtr<VsyncBridgeChild> mVsyncBridge;
77
  TimeStamp mTimeStamp;
78
  layers::LayersId mLayersId;
79
};
80
81
bool
82
VsyncBridgeChild::IsOnVsyncIOThread() const
83
0
{
84
0
  return MessageLoop::current() == mLoop;
85
0
}
86
87
void
88
VsyncBridgeChild::NotifyVsync(TimeStamp aTimeStamp, const layers::LayersId& aLayersId)
89
0
{
90
0
  // This should be on the Vsync thread (not the Vsync I/O thread).
91
0
  MOZ_ASSERT(!IsOnVsyncIOThread());
92
0
93
0
  RefPtr<NotifyVsyncTask> task = new NotifyVsyncTask(this, aTimeStamp, aLayersId);
94
0
  mLoop->PostTask(task.forget());
95
0
}
96
97
void
98
VsyncBridgeChild::NotifyVsyncImpl(TimeStamp aTimeStamp, const layers::LayersId& aLayersId)
99
0
{
100
0
  // This should be on the Vsync I/O thread.
101
0
  MOZ_ASSERT(IsOnVsyncIOThread());
102
0
103
0
  if (!mProcessToken) {
104
0
    return;
105
0
  }
106
0
  SendNotifyVsync(aTimeStamp, aLayersId);
107
0
}
108
109
void
110
VsyncBridgeChild::Close()
111
0
{
112
0
  if (!IsOnVsyncIOThread()) {
113
0
    mLoop->PostTask(NewRunnableMethod(
114
0
      "gfx::VsyncBridgeChild::Close", this, &VsyncBridgeChild::Close));
115
0
    return;
116
0
  }
117
0
118
0
  // We clear mProcessToken when the channel is closed.
119
0
  if (!mProcessToken) {
120
0
    return;
121
0
  }
122
0
123
0
  // Clear the process token so we don't notify the GPUProcessManager. It already
124
0
  // knows we're closed since it manually called Close, and in fact the GPM could
125
0
  // have already been destroyed during shutdown.
126
0
  mProcessToken = 0;
127
0
128
0
  // Close the underlying IPC channel.
129
0
  PVsyncBridgeChild::Close();
130
0
}
131
132
void
133
VsyncBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
134
0
{
135
0
  if (mProcessToken) {
136
0
    GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
137
0
    mProcessToken = 0;
138
0
  }
139
0
}
140
141
void
142
VsyncBridgeChild::DeallocPVsyncBridgeChild()
143
0
{
144
0
  Release();
145
0
}
146
147
void
148
VsyncBridgeChild::ProcessingError(Result aCode, const char* aReason)
149
0
{
150
0
  MOZ_RELEASE_ASSERT(aCode == MsgDropped, "Processing error in VsyncBridgeChild");
151
0
}
152
153
void
154
VsyncBridgeChild::HandleFatalError(const char* aMsg) const
155
0
{
156
0
  dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherPid());
157
0
}
158
159
} // namespace gfx
160
} // namespace mozilla