1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/run_loop.h"
6 #include "base/synchronization/waitable_event.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "content/common/gpu/gpu_channel.h"
9 #include "content/common/gpu/gpu_channel_manager.h"
10 #include "content/common/gpu/gpu_messages.h"
11 #include "content/common/message_router.h"
12 #include "gpu/command_buffer/common/value_state.h"
13 #include "gpu/command_buffer/service/gl_utils.h"
14 #include "gpu/command_buffer/service/sync_point_manager.h"
15 #include "gpu/command_buffer/service/valuebuffer_manager.h"
16 #include "ipc/ipc_sync_channel.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using base::WaitableEvent
;
21 using gpu::gles2::ValuebufferManager
;
22 using gpu::ValueState
;
26 class SimpleWorker
: public Listener
, public Sender
{
28 SimpleWorker(Channel::Mode mode
, const std::string
& thread_name
)
30 ipc_thread_((thread_name
+ "_ipc").c_str()),
31 shutdown_event_(true, false) {
34 ~SimpleWorker() override
{
39 bool Send(Message
* msg
) override
{ return channel_
->Send(msg
); }
41 virtual void Start() {
42 StartThread(&ipc_thread_
, base::MessageLoop::TYPE_IO
);
43 channel_
.reset(CreateChannel());
46 virtual void Shutdown() {
47 WaitableEvent
ipc_done(false, false);
48 ipc_thread_
.task_runner()->PostTask(
49 FROM_HERE
, base::Bind(&SimpleWorker::OnShutdown
, this, &ipc_done
));
58 SyncChannel
* CreateChannel() {
59 scoped_ptr
<SyncChannel
> channel
= SyncChannel::Create(
60 channel_name_
, mode_
, this, ipc_thread_
.task_runner().get(), true,
61 &shutdown_event_
, nullptr);
62 return channel
.release();
65 void OnShutdown(WaitableEvent
* ipc_event
) {
66 base::RunLoop().RunUntilIdle();
70 const base::Thread
& ipc_thread() const { return ipc_thread_
; }
72 WaitableEvent
* shutdown_event() { return &shutdown_event_
; }
74 SyncChannel
* channel() { return channel_
.get(); }
77 bool OnMessageReceived(const Message
& message
) override
{ return false; }
79 void StartThread(base::Thread
* thread
, base::MessageLoop::Type type
) {
80 base::Thread::Options options
;
81 options
.message_loop_type
= type
;
82 thread
->StartWithOptions(options
);
85 std::string channel_name_
;
87 scoped_ptr
<SyncChannel
> channel_
;
88 base::Thread ipc_thread_
;
90 base::WaitableEvent shutdown_event_
;
92 DISALLOW_COPY_AND_ASSIGN(SimpleWorker
);
95 class SimpleServer
: public SimpleWorker
{
97 explicit SimpleServer()
98 : SimpleWorker(Channel::MODE_SERVER
, "simpler_server") { }
105 class SimpleGpuClient
: public IPC::SimpleWorker
{
108 : IPC::SimpleWorker(IPC::Channel::MODE_CLIENT
, "simple_client"),
112 void Start() override
{
113 IPC::SimpleWorker::Start();
114 sync_point_manager_
.reset(new gpu::SyncPointManager(false));
115 gpu_channel_manager_
.reset(new GpuChannelManager(
116 &router_
, NULL
, ipc_thread().task_runner().get(), shutdown_event(),
117 channel(), nullptr, sync_point_manager_
.get(), nullptr));
120 void Shutdown() override
{
121 gpu_channel_manager_
.reset();
122 IPC::SimpleWorker::Shutdown();
125 GpuChannelManager
* gpu_channel_manager() {
126 return gpu_channel_manager_
.get();
130 class SimpleMessageRouter
: public MessageRouter
{
132 explicit SimpleMessageRouter(IPC::Sender
* sender
)
136 bool Send(IPC::Message
* msg
) override
{ return sender_
->Send(msg
); }
139 IPC::Sender
* const sender_
;
142 SimpleMessageRouter router_
;
144 scoped_ptr
<gpu::SyncPointManager
> sync_point_manager_
;
145 scoped_ptr
<GpuChannelManager
> gpu_channel_manager_
;
148 class GpuChannelManagerTest
: public testing::Test
{
150 GpuChannelManagerTest() {}
152 void SetUp() override
{
153 simple_client_
.reset(new SimpleGpuClient());
154 simple_server_
.reset(new IPC::SimpleServer());
155 simple_server_
->Start();
156 simple_client_
->Start();
159 void TearDown() override
{
160 simple_client_
->Shutdown();
161 simple_server_
->Shutdown();
165 scoped_ptr
<SimpleGpuClient
> simple_client_
;
166 scoped_ptr
<IPC::SimpleServer
> simple_server_
;
169 base::MessageLoop message_loop_
;
172 TEST_F(GpuChannelManagerTest
, SecureValueStateForwarding
) {
173 const int kClientId1
= 111;
174 const uint64 kClientTracingId1
= 11111;
175 const int kClientId2
= 222;
176 const uint64 kClientTracingId2
= 22222;
177 ValueState value_state1
;
178 value_state1
.int_value
[0] = 1111;
179 value_state1
.int_value
[1] = 0;
180 value_state1
.int_value
[2] = 0;
181 value_state1
.int_value
[3] = 0;
182 ValueState value_state2
;
183 value_state2
.int_value
[0] = 3333;
184 value_state2
.int_value
[1] = 0;
185 value_state2
.int_value
[2] = 0;
186 value_state2
.int_value
[3] = 0;
188 ASSERT_TRUE(simple_client_
->gpu_channel_manager() != NULL
);
190 // Initialize gpu channels
191 simple_client_
->gpu_channel_manager()->OnMessageReceived(
192 GpuMsg_EstablishChannel(kClientId1
, kClientTracingId1
, false, false));
193 GpuChannel
*channel1
=
194 simple_client_
->gpu_channel_manager()->LookupChannel(kClientId1
);
195 simple_client_
->gpu_channel_manager()->OnMessageReceived(
196 GpuMsg_EstablishChannel(kClientId2
, kClientTracingId2
, false, false));
197 GpuChannel
*channel2
=
198 simple_client_
->gpu_channel_manager()->LookupChannel(kClientId2
);
199 ASSERT_TRUE(channel1
!= NULL
);
200 ASSERT_TRUE(channel2
!= NULL
);
201 ASSERT_NE(channel1
, channel2
);
203 // Make sure value states are only accessible by proper channels
204 simple_client_
->gpu_channel_manager()->OnMessageReceived(
205 GpuMsg_UpdateValueState(
206 kClientId1
, GL_MOUSE_POSITION_CHROMIUM
, value_state1
));
207 simple_client_
->gpu_channel_manager()->OnMessageReceived(
208 GpuMsg_UpdateValueState(
209 kClientId2
, GL_MOUSE_POSITION_CHROMIUM
, value_state2
));
211 const gpu::ValueStateMap
* pending_value_buffer_state1
=
212 channel1
->pending_valuebuffer_state();
213 const gpu::ValueStateMap
* pending_value_buffer_state2
=
214 channel2
->pending_valuebuffer_state();
215 ASSERT_NE(pending_value_buffer_state1
, pending_value_buffer_state2
);
217 const ValueState
* state1
=
218 pending_value_buffer_state1
->GetState(GL_MOUSE_POSITION_CHROMIUM
);
219 const ValueState
* state2
=
220 pending_value_buffer_state2
->GetState(GL_MOUSE_POSITION_CHROMIUM
);
221 ASSERT_NE(state1
, state2
);
223 ASSERT_EQ(state1
->int_value
[0], value_state1
.int_value
[0]);
224 ASSERT_EQ(state2
->int_value
[0], value_state2
.int_value
[0]);
225 ASSERT_NE(state1
->int_value
[0], state2
->int_value
[0]);
228 } // namespace content