Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: gpu/ipc/service/gpu_vsync_provider_unittest_win.cc

Issue 2681033011: Changed GpuVSyncProvider to implement gfx::VSyncProvider (Closed)
Patch Set: Used base::MakeUnique Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/ipc/service/gpu_vsync_provider.h" 5 #include "gpu/ipc/service/gpu_vsync_provider_win.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread.h"
13 #include "gpu/ipc/common/gpu_messages.h"
14 #include "ipc/ipc_channel.h"
15 #include "ipc/ipc_message_macros.h"
16 #include "ipc/message_filter.h"
12 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/base/win/hidden_window.h" 18 #include "ui/base/win/hidden_window.h"
14 19
15 namespace gpu { 20 namespace gpu {
16 21
22 namespace {
23
24 class FakeChannel : public base::Thread, public IPC::Channel {
25 public:
26 explicit FakeChannel(const gfx::VSyncProvider::UpdateVSyncCallback& callback)
27 : base::Thread("io"),
28 callback_(callback),
29 io_done_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
30 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
31
32 ~FakeChannel() override {
33 task_runner()->PostTask(FROM_HERE,
34 base::Bind(&FakeChannel::RemoveFilterOnIOThread,
35 base::Unretained(this)));
36 io_done_event_.Wait();
37 Stop();
38 }
39
40 void SetNeedsVSync(bool needs_vsync) {
41 task_runner()->PostTask(FROM_HERE,
42 base::Bind(&FakeChannel::SetNeedsVSyncOnIOThread,
43 base::Unretained(this), needs_vsync));
44 io_done_event_.Wait();
45 }
46
47 void AddFilter(IPC::MessageFilter* message_filter) {
48 message_filter_ = message_filter;
49
50 // Start the thread.
51 Start();
52
53 task_runner()->PostTask(
54 FROM_HERE,
55 base::Bind(&FakeChannel::AddFilterOnIOThread, base::Unretained(this)));
56 io_done_event_.Wait();
57 }
58
59 // IPC::Channel implementation
60 bool Send(IPC::Message* msg) override {
61 IPC_BEGIN_MESSAGE_MAP(FakeChannel, *msg)
62 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UpdateVSyncParameters,
63 OnUpdateVSyncParameters);
64 IPC_MESSAGE_UNHANDLED(return false)
65 IPC_END_MESSAGE_MAP()
66 return true;
67 }
68
69 bool Connect() override {
70 NOTREACHED();
71 return false;
72 }
73
74 void Close() override { NOTREACHED(); }
75
76 private:
77 void SetNeedsVSyncOnIOThread(bool needs_vsync) {
78 GpuCommandBufferMsg_SetNeedsVSync msg(0, needs_vsync);
79 message_filter_->OnMessageReceived(msg);
80 io_done_event_.Signal();
81 }
82
83 void AddFilterOnIOThread() {
84 message_filter_->OnFilterAdded(this);
85 io_done_event_.Signal();
86 }
87
88 void RemoveFilterOnIOThread() {
89 message_filter_->OnFilterRemoved();
90 io_done_event_.Signal();
91 }
92
93 void OnUpdateVSyncParameters(base::TimeTicks timestamp,
94 base::TimeDelta interval) {
95 callback_.Run(timestamp, interval);
96 }
97
98 gfx::VSyncProvider::UpdateVSyncCallback callback_;
99 base::WaitableEvent io_done_event_;
100
101 scoped_refptr<IPC::MessageFilter> message_filter_;
102
103 DISALLOW_COPY_AND_ASSIGN(FakeChannel);
104 };
105
106 class FakeDelegate : public ImageTransportSurfaceDelegate,
107 public base::SupportsWeakPtr<FakeDelegate> {
108 public:
109 explicit FakeDelegate(FakeChannel* channel) : channel_(channel) {}
110
111 void DidCreateAcceleratedSurfaceChildWindow(
112 SurfaceHandle parent_window,
113 SurfaceHandle child_window) override {}
114 void DidSwapBuffersComplete(SwapBuffersCompleteParams params) override {}
115 const gles2::FeatureInfo* GetFeatureInfo() const override { return nullptr; }
116 void SetLatencyInfoCallback(const LatencyInfoCallback& callback) override {}
117 void UpdateVSyncParameters(base::TimeTicks timebase,
118 base::TimeDelta interval) override {
119 // This shouldn't be called by GpuVSyncProviderWin
120 NOTREACHED();
121 }
122
123 void AddFilter(IPC::MessageFilter* message_filter) override {
124 channel_->AddFilter(message_filter);
125 }
126
127 int32_t GetRouteID() const override { return 0; }
128
129 private:
130 FakeChannel* channel_;
131 DISALLOW_COPY_AND_ASSIGN(FakeDelegate);
132 };
133
134 } // namespace
135
17 class GpuVSyncProviderTest : public testing::Test { 136 class GpuVSyncProviderTest : public testing::Test {
18 public: 137 public:
19 GpuVSyncProviderTest() 138 GpuVSyncProviderTest()
20 : vsync_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, 139 : vsync_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
21 base::WaitableEvent::InitialState::NOT_SIGNALED) {} 140 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
22 ~GpuVSyncProviderTest() override {} 141 ~GpuVSyncProviderTest() override {}
23 142
24 void SetUp() override {} 143 void SetUp() override {
144 channel_.reset(new FakeChannel(
145 base::Bind(&GpuVSyncProviderTest::OnVSync, base::Unretained(this))));
146 delegate_.reset(new FakeDelegate(channel_.get()));
147 provider_.reset(
148 new GpuVSyncProviderWin(delegate_->AsWeakPtr(), ui::GetHiddenWindow()));
149 }
25 150
26 void TearDown() override {} 151 void TearDown() override {
27 152 channel_.reset();
28 void OnVSync(base::TimeTicks timestamp) { 153 delegate_.reset();
29 // This is called on VSync worker thread. 154 provider_.reset();
dcheng 2017/02/14 09:03:17 Are these resets() needed to ensure a particular d
stanisc 2017/02/14 19:56:13 No, it should be OK to not destruct these objects
30 base::AutoLock lock(lock_);
31 if (++vsync_count_ == 3)
32 vsync_event_.Signal();
33 } 155 }
34 156
35 int vsync_count() { 157 int vsync_count() {
36 base::AutoLock lock(lock_); 158 base::AutoLock lock(lock_);
37 return vsync_count_; 159 return vsync_count_;
38 } 160 }
39 161
40 void reset_vsync_count() { 162 void reset_vsync_count() {
41 base::AutoLock lock(lock_); 163 base::AutoLock lock(lock_);
42 vsync_count_ = 0; 164 vsync_count_ = 0;
43 } 165 }
44 166
167 void set_vsync_stop_count(int value) { vsync_stop_count_ = value; }
168
169 void SetNeedsVSync(bool needs_vsync) { channel_->SetNeedsVSync(needs_vsync); }
170
45 protected: 171 protected:
46 base::WaitableEvent vsync_event_; 172 base::WaitableEvent vsync_event_;
47 173
48 private: 174 private:
175 void OnVSync(base::TimeTicks timestamp, base::TimeDelta interval) {
176 // This is called on VSync worker thread.
177 EXPECT_GT(timestamp, previous_vsync_timestamp_);
178 previous_vsync_timestamp_ = timestamp;
179
180 base::AutoLock lock(lock_);
181 if (++vsync_count_ == vsync_stop_count_)
182 vsync_event_.Signal();
183 }
184
49 base::Lock lock_; 185 base::Lock lock_;
50 int vsync_count_ = 0; 186 int vsync_count_ = 0;
187 int vsync_stop_count_ = 0;
188 base::TimeTicks previous_vsync_timestamp_;
189 std::unique_ptr<FakeChannel> channel_;
190 std::unique_ptr<FakeDelegate> delegate_;
191 std::unique_ptr<GpuVSyncProviderWin> provider_;
51 }; 192 };
52 193
194 // Tests that VSync signal production is controlled by SetNeedsVSync.
53 TEST_F(GpuVSyncProviderTest, VSyncSignalTest) { 195 TEST_F(GpuVSyncProviderTest, VSyncSignalTest) {
54 SurfaceHandle window = ui::GetHiddenWindow(); 196 set_vsync_stop_count(3);
55
56 std::unique_ptr<GpuVSyncProvider> provider = GpuVSyncProvider::Create(
57 base::Bind(&GpuVSyncProviderTest::OnVSync, base::Unretained(this)),
58 window);
59 197
60 constexpr base::TimeDelta wait_timeout = 198 constexpr base::TimeDelta wait_timeout =
61 base::TimeDelta::FromMilliseconds(300); 199 base::TimeDelta::FromMilliseconds(300);
62 200
63 // Verify that there are no VSync signals before provider is enabled 201 // Verify that there are no VSync signals before provider is enabled
64 bool wait_result = vsync_event_.TimedWait(wait_timeout); 202 bool wait_result = vsync_event_.TimedWait(wait_timeout);
65 EXPECT_FALSE(wait_result); 203 EXPECT_FALSE(wait_result);
66 EXPECT_EQ(0, vsync_count()); 204 EXPECT_EQ(0, vsync_count());
67 205
68 provider->EnableVSync(true); 206 SetNeedsVSync(true);
69 207
70 vsync_event_.Wait(); 208 vsync_event_.Wait();
71 209
72 provider->EnableVSync(false); 210 SetNeedsVSync(false);
73 211
74 // Verify that VSync callbacks stop coming after disabling. 212 // Verify that VSync callbacks stop coming after disabling.
75 // Please note that it might still be possible for one 213 // Please note that it might still be possible for one
76 // callback to be in flight on VSync worker thread, so |vsync_count_| 214 // callback to be in flight on VSync worker thread, so |vsync_count_|
77 // could still be incremented once, but not enough times to trigger 215 // could still be incremented once, but not enough times to trigger
78 // |vsync_event_|. 216 // |vsync_event_|.
79 reset_vsync_count(); 217 reset_vsync_count();
80 wait_result = vsync_event_.TimedWait(wait_timeout); 218 wait_result = vsync_event_.TimedWait(wait_timeout);
81 EXPECT_FALSE(wait_result); 219 EXPECT_FALSE(wait_result);
82 } 220 }
83 221
222 // Verifies that VSync timestamp is monotonic.
223 TEST_F(GpuVSyncProviderTest, VSyncMonotonicTimestampTest) {
224 set_vsync_stop_count(60);
225 SetNeedsVSync(true);
226 // Make sure this doesn't run for longer than 1 second in case VSync
227 // callbacks are slowed by running multiple tests in parallel.
228 vsync_event_.TimedWait(base::TimeDelta::FromMilliseconds(1000));
229 }
230
84 } // namespace gpu 231 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698