Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/ipc/VsyncParent.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
7
#include "VsyncParent.h"
8
9
#include "BackgroundParent.h"
10
#include "BackgroundParentImpl.h"
11
#include "gfxPlatform.h"
12
#include "mozilla/Unused.h"
13
#include "nsIThread.h"
14
#include "nsThreadUtils.h"
15
#include "VsyncSource.h"
16
17
namespace mozilla {
18
19
using namespace ipc;
20
21
namespace layout {
22
23
/*static*/ already_AddRefed<VsyncParent>
24
VsyncParent::Create()
25
0
{
26
0
  AssertIsOnBackgroundThread();
27
0
  RefPtr<gfx::VsyncSource> vsyncSource = gfxPlatform::GetPlatform()->GetHardwareVsync();
28
0
  RefPtr<VsyncParent> vsyncParent = new VsyncParent();
29
0
  vsyncParent->mVsyncDispatcher = vsyncSource->GetRefreshTimerVsyncDispatcher();
30
0
  return vsyncParent.forget();
31
0
}
32
33
VsyncParent::VsyncParent()
34
  : mObservingVsync(false)
35
  , mDestroyed(false)
36
  , mBackgroundThread(NS_GetCurrentThread())
37
0
{
38
0
  MOZ_ASSERT(mBackgroundThread);
39
0
  AssertIsOnBackgroundThread();
40
0
}
41
42
VsyncParent::~VsyncParent()
43
0
{
44
0
  // Since we use NS_INLINE_DECL_THREADSAFE_REFCOUNTING, we can't make sure
45
0
  // VsyncParent is always released on the background thread.
46
0
}
47
48
bool
49
VsyncParent::NotifyVsync(TimeStamp aTimeStamp)
50
0
{
51
0
  // Called on hardware vsync thread. We should post to current ipc thread.
52
0
  MOZ_ASSERT(!IsOnBackgroundThread());
53
0
  nsCOMPtr<nsIRunnable> vsyncEvent =
54
0
    NewRunnableMethod<TimeStamp>("layout::VsyncParent::DispatchVsyncEvent",
55
0
                                 this,
56
0
                                 &VsyncParent::DispatchVsyncEvent,
57
0
                                 aTimeStamp);
58
0
  MOZ_ALWAYS_SUCCEEDS(mBackgroundThread->Dispatch(vsyncEvent, NS_DISPATCH_NORMAL));
59
0
  return true;
60
0
}
61
62
void
63
VsyncParent::DispatchVsyncEvent(TimeStamp aTimeStamp)
64
0
{
65
0
  AssertIsOnBackgroundThread();
66
0
67
0
  // If we call NotifyVsync() when we handle ActorDestroy() message, we might
68
0
  // still call DispatchVsyncEvent().
69
0
  // Similarly, we might also receive RecvUnobserveVsync() when call
70
0
  // NotifyVsync(). We use mObservingVsync and mDestroyed flags to skip this
71
0
  // notification.
72
0
  if (mObservingVsync && !mDestroyed) {
73
0
    Unused << SendNotify(aTimeStamp);
74
0
  }
75
0
}
76
77
mozilla::ipc::IPCResult
78
VsyncParent::RecvRequestVsyncRate()
79
0
{
80
0
  AssertIsOnBackgroundThread();
81
0
  TimeDuration vsyncRate = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
82
0
  Unused << SendVsyncRate(vsyncRate.ToMilliseconds());
83
0
  return IPC_OK();
84
0
}
85
86
mozilla::ipc::IPCResult
87
VsyncParent::RecvObserve()
88
0
{
89
0
  AssertIsOnBackgroundThread();
90
0
  if (!mObservingVsync) {
91
0
    mVsyncDispatcher->AddChildRefreshTimer(this);
92
0
    mObservingVsync = true;
93
0
    return IPC_OK();
94
0
  }
95
0
  return IPC_FAIL_NO_REASON(this);
96
0
}
97
98
mozilla::ipc::IPCResult
99
VsyncParent::RecvUnobserve()
100
0
{
101
0
  AssertIsOnBackgroundThread();
102
0
  if (mObservingVsync) {
103
0
    mVsyncDispatcher->RemoveChildRefreshTimer(this);
104
0
    mObservingVsync = false;
105
0
    return IPC_OK();
106
0
  }
107
0
  return IPC_FAIL_NO_REASON(this);
108
0
}
109
110
void
111
VsyncParent::ActorDestroy(ActorDestroyReason aReason)
112
0
{
113
0
  MOZ_ASSERT(!mDestroyed);
114
0
  AssertIsOnBackgroundThread();
115
0
  if (mObservingVsync) {
116
0
    mVsyncDispatcher->RemoveChildRefreshTimer(this);
117
0
  }
118
0
  mVsyncDispatcher = nullptr;
119
0
  mDestroyed = true;
120
0
}
121
122
} // namespace layout
123
} // namespace mozilla