Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef mozilla_layers_APZThreadUtils_h
7 : #define mozilla_layers_APZThreadUtils_h
8 :
9 : #include "base/message_loop.h"
10 : #include "nsINamed.h"
11 : #include "nsITimer.h"
12 :
13 : namespace mozilla {
14 :
15 : class Runnable;
16 :
17 : namespace layers {
18 :
19 : class APZThreadUtils
20 : {
21 : public:
22 : /**
23 : * In the gtest environment everything runs on one thread, so we
24 : * shouldn't assert that we're on a particular thread. This enables
25 : * that behaviour.
26 : */
27 : static void SetThreadAssertionsEnabled(bool aEnabled);
28 : static bool GetThreadAssertionsEnabled();
29 :
30 : /**
31 : * Set the controller thread.
32 : */
33 : static void SetControllerThread(MessageLoop* aLoop);
34 :
35 : /**
36 : * This can be used to assert that the current thread is the
37 : * controller/UI thread (on which input events are received).
38 : * This does nothing if thread assertions are disabled.
39 : */
40 : static void AssertOnControllerThread();
41 :
42 : /**
43 : * This can be used to assert that the current thread is the
44 : * compositor thread (which applies the async transform).
45 : * This does nothing if thread assertions are disabled.
46 : */
47 : static void AssertOnCompositorThread();
48 :
49 : /**
50 : * Run the given task on the APZ "controller thread" for this platform. If
51 : * this function is called from the controller thread itself then the task is
52 : * run immediately without getting queued.
53 : */
54 : static void RunOnControllerThread(already_AddRefed<Runnable> aTask);
55 :
56 : /**
57 : * Returns true if currently on APZ "controller thread".
58 : */
59 : static bool IsControllerThread();
60 : };
61 :
62 : // A base class for GenericNamedTimerCallback<Function>.
63 : // This is necessary because NS_IMPL_ISUPPORTS doesn't work for a class
64 : // template.
65 5 : class GenericNamedTimerCallbackBase : public nsITimerCallback,
66 : public nsINamed
67 : {
68 : public:
69 : NS_DECL_THREADSAFE_ISUPPORTS
70 :
71 : protected:
72 4 : virtual ~GenericNamedTimerCallbackBase() {}
73 : };
74 :
75 : // An nsITimerCallback implementation with nsINamed that can be used with any
76 : // function object that's callable with no arguments.
77 : template <typename Function>
78 12 : class GenericNamedTimerCallback final : public GenericNamedTimerCallbackBase
79 : {
80 : public:
81 5 : explicit GenericNamedTimerCallback(const Function& aFunction,
82 : const char* aName)
83 : : mFunction(aFunction)
84 5 : , mName(aName)
85 : {
86 5 : }
87 :
88 0 : NS_IMETHOD Notify(nsITimer*) override
89 : {
90 0 : mFunction();
91 0 : return NS_OK;
92 : }
93 :
94 0 : NS_IMETHOD GetName(nsACString& aName) override
95 : {
96 0 : aName = mName;
97 0 : return NS_OK;
98 : }
99 :
100 0 : NS_IMETHOD SetName(const char * aName) override
101 : {
102 0 : mName.Assign(aName);
103 0 : return NS_OK;
104 : }
105 :
106 : private:
107 : Function mFunction;
108 : nsCString mName;
109 : };
110 :
111 : // Convenience function for constructing a GenericNamedTimerCallback.
112 : // Returns a raw pointer, suitable for passing directly as an argument to
113 : // nsITimer::InitWithCallback(). The intention is to enable the following
114 : // terse inline usage:
115 : // timer->InitWithCallback(NewNamedTimerCallback([](){ ... }, name), delay);
116 : template <typename Function>
117 : GenericNamedTimerCallback<Function>*
118 5 : NewNamedTimerCallback(const Function& aFunction,
119 : const char* aName)
120 : {
121 5 : return new GenericNamedTimerCallback<Function>(aFunction, aName);
122 : }
123 :
124 : } // namespace layers
125 : } // namespace mozilla
126 :
127 : #endif /* mozilla_layers_APZThreadUtils_h */
|