1 // Copyright 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.
4 
5 #include <stdint.h>
6 
7 #include "base/bind.h"
8 #include "gpu/command_buffer/client/client_test_helper.h"
9 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
10 #include "gpu/command_buffer/service/gpu_service_test.h"
11 #include "gpu/command_buffer/service/gpu_tracer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/gl/gl_context.h"
14 #include "ui/gl/gl_mock.h"
15 #include "ui/gl/gpu_timing.h"
16 #include "ui/gl/gpu_timing_fake.h"
17 
18 namespace gpu {
19 namespace gles2 {
20 namespace {
21 
22 using ::testing::_;
23 using ::testing::AtMost;
24 using ::testing::Exactly;
25 using ::testing::Invoke;
26 using ::testing::Return;
27 
28 int64_t g_fakeCPUTime = 0;
FakeCpuTime()29 int64_t FakeCpuTime() {
30   return g_fakeCPUTime;
31 }
32 
33 class MockOutputter : public Outputter {
34  public:
35   MockOutputter() = default;
36   ~MockOutputter() override = default;
37 
38   MOCK_METHOD5(TraceDevice,
39                void(GpuTracerSource source,
40                     const std::string& category,
41                     const std::string& name,
42                     int64_t start_time,
43                     int64_t end_time));
44   MOCK_METHOD3(TraceServiceBegin,
45                void(GpuTracerSource source,
46                     const std::string& category, const std::string& name));
47   MOCK_METHOD3(TraceServiceEnd,
48                void(GpuTracerSource source,
49                     const std::string& category, const std::string& name));
50 };
51 
52 class GPUTracerTester : public GPUTracer {
53  public:
GPUTracerTester(GLES2Decoder * decoder)54   explicit GPUTracerTester(GLES2Decoder* decoder)
55       : GPUTracer(decoder), tracing_enabled_(0) {
56     gpu_timing_client_->SetCpuTimeForTesting(base::BindRepeating(&FakeCpuTime));
57 
58     // Force tracing to be dependent on our mock variable here.
59     gpu_trace_srv_category_ = &tracing_enabled_;
60     gpu_trace_dev_category_ = &tracing_enabled_;
61   }
62 
63   ~GPUTracerTester() override = default;
64 
SetTracingEnabled(bool enabled)65   void SetTracingEnabled(bool enabled) {
66     tracing_enabled_ = enabled ? 1 : 0;
67   }
68 
69  private:
70   unsigned char tracing_enabled_;
71 };
72 
73 class BaseGpuTest : public GpuServiceTest {
74  public:
BaseGpuTest(gl::GPUTiming::TimerType test_timer_type)75   explicit BaseGpuTest(gl::GPUTiming::TimerType test_timer_type)
76       : test_timer_type_(test_timer_type) {}
77 
78  protected:
SetUp()79   void SetUp() override {
80     g_fakeCPUTime = 0;
81     const char* gl_version = "3.2";
82     const char* extensions = "";
83     if (GetTimerType() == gl::GPUTiming::kTimerTypeEXT) {
84       gl_version = "2.1";
85       extensions = "GL_EXT_timer_query";
86     } else if (GetTimerType() == gl::GPUTiming::kTimerTypeDisjoint) {
87       gl_version = "OpenGL ES 3.0";
88       extensions = "GL_EXT_disjoint_timer_query";
89     } else if (GetTimerType() == gl::GPUTiming::kTimerTypeARB) {
90       // TODO(sievers): The tracer should not depend on ARB_occlusion_query.
91       // Try merge Query APIs (core, ARB, EXT) into a single binding each.
92       extensions = "GL_ARB_timer_query GL_ARB_occlusion_query";
93     }
94     GpuServiceTest::SetUpWithGLVersion(gl_version, extensions);
95 
96     // Disjoint check should only be called by kTracerTypeDisjointTimer type.
97     if (GetTimerType() == gl::GPUTiming::kTimerTypeDisjoint)
98       gl_fake_queries_.ExpectDisjointCalls(*gl_);
99     else
100       gl_fake_queries_.ExpectNoDisjointCalls(*gl_);
101 
102     gpu_timing_client_ = GetGLContext()->CreateGPUTimingClient();
103     gpu_timing_client_->SetCpuTimeForTesting(base::BindRepeating(&FakeCpuTime));
104     gl_fake_queries_.Reset();
105   }
106 
TearDown()107   void TearDown() override {
108     gpu_timing_client_ = nullptr;
109     gl_fake_queries_.Reset();
110     GpuServiceTest::TearDown();
111   }
112 
ExpectTraceQueryMocks()113   void ExpectTraceQueryMocks() {
114     if (gpu_timing_client_->IsAvailable()) {
115       // Delegate query APIs used by GPUTrace to a GlFakeQueries
116       const bool elapsed = (GetTimerType() == gl::GPUTiming::kTimerTypeEXT);
117       gl_fake_queries_.ExpectGPUTimerQuery(*gl_, elapsed);
118     }
119   }
120 
ExpectOutputterBeginMocks(MockOutputter * outputter,GpuTracerSource source,const std::string & category,const std::string & name)121   void ExpectOutputterBeginMocks(MockOutputter* outputter,
122                                  GpuTracerSource source,
123                                  const std::string& category,
124                                  const std::string& name) {
125     EXPECT_CALL(*outputter,
126                 TraceServiceBegin(source, category, name));
127   }
128 
ExpectOutputterEndMocks(MockOutputter * outputter,GpuTracerSource source,const std::string & category,const std::string & name,int64_t expect_start_time,int64_t expect_end_time,bool trace_service,bool trace_device)129   void ExpectOutputterEndMocks(MockOutputter* outputter,
130                                GpuTracerSource source,
131                                const std::string& category,
132                                const std::string& name,
133                                int64_t expect_start_time,
134                                int64_t expect_end_time,
135                                bool trace_service,
136                                bool trace_device) {
137     if (trace_service) {
138       EXPECT_CALL(*outputter,
139                   TraceServiceEnd(source, category, name));
140     }
141 
142     if (trace_device) {
143       EXPECT_CALL(*outputter,
144                   TraceDevice(source, category, name,
145                               expect_start_time, expect_end_time))
146           .Times(Exactly(1));
147     } else {
148       EXPECT_CALL(*outputter, TraceDevice(source, category, name,
149                                           expect_start_time, expect_end_time))
150           .Times(Exactly(0));
151     }
152   }
153 
ExpectDisjointOutputMocks(MockOutputter * outputter,int64_t expect_start_time,int64_t expect_end_time)154   void ExpectDisjointOutputMocks(MockOutputter* outputter,
155                                  int64_t expect_start_time,
156                                  int64_t expect_end_time) {
157     EXPECT_CALL(*outputter,
158                 TraceDevice(kTraceDisjoint, "DisjointEvent", _,
159                             expect_start_time, expect_end_time))
160           .Times(Exactly(1));
161   }
162 
ExpectNoDisjointOutputMocks(MockOutputter * outputter)163   void ExpectNoDisjointOutputMocks(MockOutputter* outputter) {
164     EXPECT_CALL(*outputter,
165                 TraceDevice(kTraceDisjoint, "DisjointEvent", _, _, _))
166           .Times(Exactly(0));
167   }
168 
ExpectOutputterMocks(MockOutputter * outputter,bool tracing_service,bool tracing_device,GpuTracerSource source,const std::string & category,const std::string & name,int64_t expect_start_time,int64_t expect_end_time)169   void ExpectOutputterMocks(MockOutputter* outputter,
170                             bool tracing_service,
171                             bool tracing_device,
172                             GpuTracerSource source,
173                             const std::string& category,
174                             const std::string& name,
175                             int64_t expect_start_time,
176                             int64_t expect_end_time) {
177     if (tracing_service)
178       ExpectOutputterBeginMocks(outputter, source, category, name);
179     const bool valid_timer = tracing_device &&
180                              gpu_timing_client_->IsAvailable();
181     ExpectOutputterEndMocks(outputter, source, category, name,
182                             expect_start_time, expect_end_time,
183                             tracing_service, valid_timer);
184   }
185 
ExpectTracerOffsetQueryMocks()186   void ExpectTracerOffsetQueryMocks() {
187     if (GetTimerType() != gl::GPUTiming::kTimerTypeARB) {
188       gl_fake_queries_.ExpectNoOffsetCalculationQuery(*gl_);
189     } else {
190       gl_fake_queries_.ExpectOffsetCalculationQuery(*gl_);
191     }
192   }
193 
GetTimerType()194   gl::GPUTiming::TimerType GetTimerType() { return test_timer_type_; }
195 
196   gl::GPUTiming::TimerType test_timer_type_;
197   gl::GPUTimingFake gl_fake_queries_;
198 
199   scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
200   MockOutputter outputter_;
201 };
202 
203 // Test GPUTrace calls all the correct gl calls.
204 class BaseGpuTraceTest : public BaseGpuTest {
205  public:
BaseGpuTraceTest(gl::GPUTiming::TimerType test_timer_type)206   explicit BaseGpuTraceTest(gl::GPUTiming::TimerType test_timer_type)
207       : BaseGpuTest(test_timer_type) {}
208 
DoTraceTest(bool tracing_service,bool tracing_device)209   void DoTraceTest(bool tracing_service, bool tracing_device) {
210     // Expected results
211     const GpuTracerSource tracer_source = kTraceCHROMIUM;
212     const std::string category_name("trace_category");
213     const std::string trace_name("trace_test");
214     const int64_t offset_time = 3231;
215     const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
216     const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
217     const int64_t expect_start_time =
218         (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
219         offset_time;
220     const int64_t expect_end_time =
221         (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
222 
223     ExpectOutputterMocks(&outputter_, tracing_service, tracing_device,
224                          tracer_source, category_name, trace_name,
225                          expect_start_time, expect_end_time);
226 
227     if (tracing_device)
228       ExpectTraceQueryMocks();
229 
230     scoped_refptr<GPUTrace> trace = new GPUTrace(
231         &outputter_, gpu_timing_client_.get(), tracer_source, category_name,
232         trace_name, tracing_service, tracing_device);
233 
234     gl_fake_queries_.SetCurrentGLTime(start_timestamp);
235     g_fakeCPUTime = expect_start_time;
236     trace->Start();
237 
238     // Shouldn't be available before End() call
239     gl_fake_queries_.SetCurrentGLTime(end_timestamp);
240     g_fakeCPUTime = expect_end_time;
241     if (tracing_device)
242       EXPECT_FALSE(trace->IsAvailable());
243 
244     trace->End();
245 
246     // Shouldn't be available until the queries complete
247     gl_fake_queries_.SetCurrentGLTime(end_timestamp -
248                                       base::Time::kNanosecondsPerMicrosecond);
249     g_fakeCPUTime = expect_end_time - 1;
250     if (tracing_device)
251       EXPECT_FALSE(trace->IsAvailable());
252 
253     // Now it should be available
254     gl_fake_queries_.SetCurrentGLTime(end_timestamp);
255     g_fakeCPUTime = expect_end_time;
256     EXPECT_TRUE(trace->IsAvailable());
257 
258     // Process should output expected Trace results to MockOutputter
259     trace->Process();
260 
261     // Destroy trace after we are done.
262     trace->Destroy(true);
263   }
264 };
265 
266 class GpuARBTimerTraceTest : public BaseGpuTraceTest {
267  public:
GpuARBTimerTraceTest()268   GpuARBTimerTraceTest() : BaseGpuTraceTest(gl::GPUTiming::kTimerTypeARB) {}
269 };
270 
271 class GpuDisjointTimerTraceTest : public BaseGpuTraceTest {
272  public:
GpuDisjointTimerTraceTest()273   GpuDisjointTimerTraceTest()
274       : BaseGpuTraceTest(gl::GPUTiming::kTimerTypeDisjoint) {}
275 };
276 
TEST_F(GpuARBTimerTraceTest,ARBTimerTraceTestOff)277 TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestOff) {
278   DoTraceTest(false, false);
279 }
280 
TEST_F(GpuARBTimerTraceTest,ARBTimerTraceTestServiceOnly)281 TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestServiceOnly) {
282   DoTraceTest(true, false);
283 }
284 
TEST_F(GpuARBTimerTraceTest,ARBTimerTraceTestDeviceOnly)285 TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestDeviceOnly) {
286   DoTraceTest(false, true);
287 }
288 
TEST_F(GpuARBTimerTraceTest,ARBTimerTraceTestBothOn)289 TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTestBothOn) {
290   DoTraceTest(true, true);
291 }
292 
TEST_F(GpuDisjointTimerTraceTest,DisjointTimerTraceTestOff)293 TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestOff) {
294   DoTraceTest(false, false);
295 }
296 
TEST_F(GpuDisjointTimerTraceTest,DisjointTimerTraceTestServiceOnly)297 TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestServiceOnly) {
298   DoTraceTest(true, false);
299 }
300 
TEST_F(GpuDisjointTimerTraceTest,DisjointTimerTraceTestDeviceOnly)301 TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestDeviceOnly) {
302   DoTraceTest(false, true);
303 }
304 
TEST_F(GpuDisjointTimerTraceTest,DisjointTimerTraceTestBothOn)305 TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTestBothOn) {
306   DoTraceTest(true, true);
307 }
308 
309 // Test GPUTracer calls all the correct gl calls.
310 class BaseGpuTracerTest : public BaseGpuTest {
311  public:
BaseGpuTracerTest(gl::GPUTiming::TimerType test_timer_type)312   explicit BaseGpuTracerTest(gl::GPUTiming::TimerType test_timer_type)
313       : BaseGpuTest(test_timer_type) {}
314 
DoBasicTracerTest()315   void DoBasicTracerTest() {
316     ExpectTracerOffsetQueryMocks();
317 
318     FakeCommandBufferServiceBase command_buffer_service;
319     FakeDecoderClient client;
320     MockOutputter outputter;
321     MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
322     EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
323     GPUTracerTester tracer(&decoder);
324     tracer.SetTracingEnabled(true);
325 
326     ASSERT_TRUE(tracer.BeginDecoding());
327     ASSERT_TRUE(tracer.EndDecoding());
328   }
329 
DoDisabledTracingTest()330   void DoDisabledTracingTest() {
331     ExpectTracerOffsetQueryMocks();
332 
333     const GpuTracerSource source = static_cast<GpuTracerSource>(0);
334 
335     FakeCommandBufferServiceBase command_buffer_service;
336     FakeDecoderClient client;
337     MockOutputter outputter;
338     MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
339     EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
340     GPUTracerTester tracer(&decoder);
341     tracer.SetTracingEnabled(false);
342 
343     ASSERT_TRUE(tracer.BeginDecoding());
344     ASSERT_TRUE(tracer.Begin("disabled_category", "disabled_name", source));
345     ASSERT_TRUE(tracer.End(source));
346     ASSERT_TRUE(tracer.EndDecoding());
347   }
348 
DoTracerMarkersTest()349   void DoTracerMarkersTest() {
350     ExpectTracerOffsetQueryMocks();
351     gl_fake_queries_.ExpectGetErrorCalls(*gl_);
352 
353     const std::string category_name("trace_category");
354     const std::string trace_name("trace_test");
355     const int64_t offset_time = 3231;
356     const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
357     const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
358     const int64_t expect_start_time =
359         (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
360         offset_time;
361     const int64_t expect_end_time =
362         (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
363 
364     FakeCommandBufferServiceBase command_buffer_service;
365     FakeDecoderClient client;
366     MockOutputter outputter;
367     MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
368     EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
369     GPUTracerTester tracer(&decoder);
370     tracer.SetTracingEnabled(true);
371 
372     gl_fake_queries_.SetCurrentGLTime(start_timestamp);
373     g_fakeCPUTime = expect_start_time;
374 
375     ASSERT_TRUE(tracer.BeginDecoding());
376 
377     ExpectTraceQueryMocks();
378 
379     // This will test multiple marker sources which overlap one another.
380     for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
381       // Set times so each source has a different time.
382       gl_fake_queries_.SetCurrentGLTime(
383           start_timestamp +
384           (i * base::Time::kNanosecondsPerMicrosecond));
385       g_fakeCPUTime = expect_start_time + i;
386 
387       // Each trace name should be different to differentiate.
388       const char num_char = static_cast<char>('0' + i);
389       std::string source_category = category_name + num_char;
390       std::string source_trace_name = trace_name + num_char;
391 
392       const GpuTracerSource source = static_cast<GpuTracerSource>(i);
393       ExpectOutputterBeginMocks(&outputter, source, source_category,
394                                 source_trace_name);
395       ASSERT_TRUE(tracer.Begin(source_category, source_trace_name, source));
396     }
397     for (int i = 0; i < NUM_TRACER_SOURCES; ++i) {
398       // Set times so each source has a different time.
399       gl_fake_queries_.SetCurrentGLTime(
400           end_timestamp +
401           (i * base::Time::kNanosecondsPerMicrosecond));
402       g_fakeCPUTime = expect_end_time + i;
403 
404       // Each trace name should be different to differentiate.
405       const char num_char = static_cast<char>('0' + i);
406       std::string source_category = category_name + num_char;
407       std::string source_trace_name = trace_name + num_char;
408 
409       const bool valid_timer = gpu_timing_client_->IsAvailable();
410       const GpuTracerSource source = static_cast<GpuTracerSource>(i);
411       ExpectOutputterEndMocks(&outputter, source, source_category,
412                               source_trace_name, expect_start_time + i,
413                               expect_end_time + i, true, valid_timer);
414       // Check if the current category/name are correct for this source.
415       ASSERT_EQ(source_category, tracer.CurrentCategory(source));
416       ASSERT_EQ(source_trace_name, tracer.CurrentName(source));
417 
418       ASSERT_TRUE(tracer.End(source));
419     }
420     ASSERT_TRUE(tracer.EndDecoding());
421     tracer.ProcessTraces();
422   }
423 
DoOngoingTracerMarkerTest()424   void DoOngoingTracerMarkerTest() {
425     ExpectTracerOffsetQueryMocks();
426     gl_fake_queries_.ExpectGetErrorCalls(*gl_);
427 
428     const std::string category_name("trace_category");
429     const std::string trace_name("trace_test");
430     const GpuTracerSource source = static_cast<GpuTracerSource>(0);
431     const int64_t offset_time = 3231;
432     const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
433     const int64_t expect_start_time =
434         (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
435         offset_time;
436     const bool valid_timer = gpu_timing_client_->IsAvailable();
437 
438     FakeCommandBufferServiceBase command_buffer_service;
439     FakeDecoderClient client;
440     MockOutputter outputter;
441     MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
442     EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
443     GPUTracerTester tracer(&decoder);
444 
445     // Create trace marker while traces are disabled.
446     gl_fake_queries_.SetCurrentGLTime(start_timestamp);
447     g_fakeCPUTime = expect_start_time;
448 
449     tracer.SetTracingEnabled(false);
450     ASSERT_TRUE(tracer.BeginDecoding());
451     ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));
452     ASSERT_TRUE(tracer.EndDecoding());
453 
454     // Enable traces now.
455     tracer.SetTracingEnabled(true);
456     ExpectTraceQueryMocks();
457 
458     // trace should happen when decoding begins, at time start+1.
459     gl_fake_queries_.SetCurrentGLTime(
460         start_timestamp +
461         (1 * base::Time::kNanosecondsPerMicrosecond));
462     g_fakeCPUTime = expect_start_time + 1;
463     ASSERT_TRUE(tracer.BeginDecoding());
464 
465     // End decoding at time start+2.
466     ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
467                             expect_start_time + 1, expect_start_time + 2, true,
468                             valid_timer);
469     gl_fake_queries_.SetCurrentGLTime(
470         start_timestamp +
471         (2 * base::Time::kNanosecondsPerMicrosecond));
472     g_fakeCPUTime = expect_start_time + 2;
473     ASSERT_TRUE(tracer.EndDecoding());
474 
475     // Begin decoding again at time start+3.
476     gl_fake_queries_.SetCurrentGLTime(
477         start_timestamp +
478         (3 * base::Time::kNanosecondsPerMicrosecond));
479     g_fakeCPUTime = expect_start_time + 3;
480     ASSERT_TRUE(tracer.BeginDecoding());
481 
482     // End trace at time start+4
483     gl_fake_queries_.SetCurrentGLTime(
484         start_timestamp +
485         (4 * base::Time::kNanosecondsPerMicrosecond));
486     g_fakeCPUTime = expect_start_time + 4;
487     ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
488                             expect_start_time + 3, expect_start_time + 4, true,
489                             valid_timer);
490     ASSERT_TRUE(tracer.End(source));
491 
492     // Increment time before we end decoding to test trace does not stop here.
493     gl_fake_queries_.SetCurrentGLTime(
494         start_timestamp +
495         (5 * base::Time::kNanosecondsPerMicrosecond));
496     g_fakeCPUTime = expect_start_time + 5;
497     ASSERT_TRUE(tracer.EndDecoding());
498     tracer.ProcessTraces();
499   }
500 
DoDisjointTest()501   void DoDisjointTest() {
502     // Cause a disjoint in a middle of a trace and expect no output calls.
503     ExpectTracerOffsetQueryMocks();
504     gl_fake_queries_.ExpectGetErrorCalls(*gl_);
505 
506     const std::string category_name("trace_category");
507     const std::string trace_name("trace_test");
508     const GpuTracerSource source = static_cast<GpuTracerSource>(0);
509     const int64_t offset_time = 3231;
510     const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
511     const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
512     const int64_t expect_start_time =
513         (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
514         offset_time;
515     const int64_t expect_end_time =
516         (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
517 
518     FakeCommandBufferServiceBase command_buffer_service;
519     FakeDecoderClient client;
520     MockOutputter outputter;
521     MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
522     EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
523     GPUTracerTester tracer(&decoder);
524     tracer.SetTracingEnabled(true);
525 
526     gl_fake_queries_.SetCurrentGLTime(start_timestamp);
527     g_fakeCPUTime = expect_start_time;
528 
529     ASSERT_TRUE(tracer.BeginDecoding());
530 
531     ExpectTraceQueryMocks();
532 
533     ExpectOutputterBeginMocks(&outputter, source, category_name, trace_name);
534     ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));
535 
536     gl_fake_queries_.SetCurrentGLTime(end_timestamp);
537     g_fakeCPUTime = expect_end_time;
538 
539     // Create GPUTimingClient to make sure disjoint value is correct. This
540     // should not interfere with the tracer's disjoint value.
541     scoped_refptr<gl::GPUTimingClient> disjoint_client =
542         GetGLContext()->CreateGPUTimingClient();
543 
544     // We assert here based on the disjoint_client because if disjoints are not
545     // working properly there is no point testing the tracer output.
546     ASSERT_FALSE(disjoint_client->CheckAndResetTimerErrors());
547     gl_fake_queries_.SetDisjoint();
548     ASSERT_TRUE(disjoint_client->CheckAndResetTimerErrors());
549 
550     ExpectDisjointOutputMocks(&outputter, expect_start_time, expect_end_time);
551 
552     ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
553                             expect_start_time, expect_end_time, true, false);
554 
555     ASSERT_TRUE(tracer.End(source));
556     ASSERT_TRUE(tracer.EndDecoding());
557     tracer.ProcessTraces();
558   }
559 
DoOutsideDisjointTest()560   void DoOutsideDisjointTest() {
561     ExpectTracerOffsetQueryMocks();
562     gl_fake_queries_.ExpectGetErrorCalls(*gl_);
563 
564     const std::string category_name("trace_category");
565     const std::string trace_name("trace_test");
566     const GpuTracerSource source = static_cast<GpuTracerSource>(0);
567     const int64_t offset_time = 3231;
568     const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond;
569     const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond;
570     const int64_t expect_start_time =
571         (start_timestamp / base::Time::kNanosecondsPerMicrosecond) +
572         offset_time;
573     const int64_t expect_end_time =
574         (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time;
575 
576     FakeCommandBufferServiceBase command_buffer_service;
577     FakeDecoderClient client;
578     MockOutputter outputter;
579     MockGLES2Decoder decoder(&client, &command_buffer_service, &outputter);
580     EXPECT_CALL(decoder, GetGLContext()).WillOnce(Return(GetGLContext()));
581     EXPECT_CALL(decoder, MakeCurrent()).WillRepeatedly(Return(true));
582     GPUTracerTester tracer(&decoder);
583 
584     // Start a trace before tracing is enabled.
585     tracer.SetTracingEnabled(false);
586     ASSERT_TRUE(tracer.BeginDecoding());
587     ASSERT_TRUE(tracer.Begin(category_name, trace_name, source));
588     ASSERT_TRUE(tracer.EndDecoding());
589 
590     // Enabling traces now, trace should be ongoing.
591     tracer.SetTracingEnabled(true);
592     gl_fake_queries_.SetCurrentGLTime(start_timestamp);
593     g_fakeCPUTime = expect_start_time;
594 
595     // Disjoints before we start tracing anything should not do anything.
596     ExpectNoDisjointOutputMocks(&outputter);
597     gl_fake_queries_.SetDisjoint();
598 
599     ExpectTraceQueryMocks();
600     ExpectOutputterBeginMocks(&outputter, source, category_name, trace_name);
601     ASSERT_TRUE(tracer.BeginDecoding());
602 
603     // Set times so each source has a different time.
604     gl_fake_queries_.SetCurrentGLTime(end_timestamp);
605     g_fakeCPUTime = expect_end_time;
606 
607     ExpectOutputterEndMocks(&outputter, source, category_name, trace_name,
608                             expect_start_time, expect_end_time, true, true);
609 
610     ASSERT_TRUE(tracer.End(source));
611     ASSERT_TRUE(tracer.EndDecoding());
612     tracer.ProcessTraces();
613   }
614 };
615 
616 class InvalidTimerTracerTest : public BaseGpuTracerTest {
617  public:
InvalidTimerTracerTest()618   InvalidTimerTracerTest()
619       : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeInvalid) {}
620 };
621 
622 class GpuEXTTimerTracerTest : public BaseGpuTracerTest {
623  public:
GpuEXTTimerTracerTest()624   GpuEXTTimerTracerTest() : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeEXT) {}
625 };
626 
627 class GpuARBTimerTracerTest : public BaseGpuTracerTest {
628  public:
GpuARBTimerTracerTest()629   GpuARBTimerTracerTest() : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeARB) {}
630 };
631 
632 class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
633  public:
GpuDisjointTimerTracerTest()634   GpuDisjointTimerTracerTest()
635       : BaseGpuTracerTest(gl::GPUTiming::kTimerTypeDisjoint) {}
636 };
637 
TEST_F(InvalidTimerTracerTest,InvalidTimerBasicTracerTest)638 TEST_F(InvalidTimerTracerTest, InvalidTimerBasicTracerTest) {
639   DoBasicTracerTest();
640 }
641 
TEST_F(GpuEXTTimerTracerTest,EXTTimerBasicTracerTest)642 TEST_F(GpuEXTTimerTracerTest, EXTTimerBasicTracerTest) {
643   DoBasicTracerTest();
644 }
645 
TEST_F(GpuARBTimerTracerTest,ARBTimerBasicTracerTest)646 TEST_F(GpuARBTimerTracerTest, ARBTimerBasicTracerTest) {
647   DoBasicTracerTest();
648 }
649 
TEST_F(GpuDisjointTimerTracerTest,DisjointTimerBasicTracerTest)650 TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerTest) {
651   DoBasicTracerTest();
652 }
653 
TEST_F(InvalidTimerTracerTest,InvalidTimerDisabledTest)654 TEST_F(InvalidTimerTracerTest, InvalidTimerDisabledTest) {
655   DoDisabledTracingTest();
656 }
657 
TEST_F(GpuEXTTimerTracerTest,EXTTimerDisabledTest)658 TEST_F(GpuEXTTimerTracerTest, EXTTimerDisabledTest) {
659   DoDisabledTracingTest();
660 }
661 
TEST_F(GpuARBTimerTracerTest,ARBTimerDisabledTest)662 TEST_F(GpuARBTimerTracerTest, ARBTimerDisabledTest) {
663   DoDisabledTracingTest();
664 }
665 
TEST_F(GpuDisjointTimerTracerTest,DisjointTimerDisabledTest)666 TEST_F(GpuDisjointTimerTracerTest, DisjointTimerDisabledTest) {
667   DoDisabledTracingTest();
668 }
669 
TEST_F(InvalidTimerTracerTest,InvalidTimerTracerMarkersTest)670 TEST_F(InvalidTimerTracerTest, InvalidTimerTracerMarkersTest) {
671   DoTracerMarkersTest();
672 }
673 
TEST_F(GpuEXTTimerTracerTest,EXTTimerTracerMarkersTest)674 TEST_F(GpuEXTTimerTracerTest, EXTTimerTracerMarkersTest) {
675   DoTracerMarkersTest();
676 }
677 
TEST_F(GpuARBTimerTracerTest,ARBTimerTracerMarkersTest)678 TEST_F(GpuARBTimerTracerTest, ARBTimerTracerMarkersTest) {
679   DoTracerMarkersTest();
680 }
681 
TEST_F(GpuDisjointTimerTracerTest,DisjointTimerBasicTracerMarkersTest)682 TEST_F(GpuDisjointTimerTracerTest, DisjointTimerBasicTracerMarkersTest) {
683   DoTracerMarkersTest();
684 }
685 
TEST_F(InvalidTimerTracerTest,InvalidTimerOngoingTracerMarkersTest)686 TEST_F(InvalidTimerTracerTest, InvalidTimerOngoingTracerMarkersTest) {
687   DoOngoingTracerMarkerTest();
688 }
689 
TEST_F(GpuEXTTimerTracerTest,EXTTimerOngoingTracerMarkersTest)690 TEST_F(GpuEXTTimerTracerTest, EXTTimerOngoingTracerMarkersTest) {
691   DoOngoingTracerMarkerTest();
692 }
693 
TEST_F(GpuARBTimerTracerTest,ARBTimerBasicOngoingTracerMarkersTest)694 TEST_F(GpuARBTimerTracerTest, ARBTimerBasicOngoingTracerMarkersTest) {
695   DoOngoingTracerMarkerTest();
696 }
697 
TEST_F(GpuDisjointTimerTracerTest,DisjointTimerOngoingTracerMarkersTest)698 TEST_F(GpuDisjointTimerTracerTest, DisjointTimerOngoingTracerMarkersTest) {
699   DoOngoingTracerMarkerTest();
700 }
701 
TEST_F(GpuDisjointTimerTracerTest,DisjointTimerDisjointTraceTest)702 TEST_F(GpuDisjointTimerTracerTest, DisjointTimerDisjointTraceTest) {
703   DoDisjointTest();
704 }
705 
TEST_F(GpuDisjointTimerTracerTest,NonrelevantDisjointTraceTest)706 TEST_F(GpuDisjointTimerTracerTest, NonrelevantDisjointTraceTest) {
707   DoOutsideDisjointTest();
708 }
709 
710 class GPUTracerTest : public GpuServiceTest {
711  protected:
SetUp()712   void SetUp() override {
713     g_fakeCPUTime = 0;
714     GpuServiceTest::SetUpWithGLVersion("3.2", "");
715     decoder_.reset(
716         new MockGLES2Decoder(&client_, &command_buffer_service_, &outputter_));
717     EXPECT_CALL(*decoder_, GetGLContext())
718         .Times(AtMost(1))
719         .WillRepeatedly(Return(GetGLContext()));
720     tracer_tester_.reset(new GPUTracerTester(decoder_.get()));
721   }
722 
TearDown()723   void TearDown() override {
724     tracer_tester_ = nullptr;
725     decoder_ = nullptr;
726     GpuServiceTest::TearDown();
727   }
728 
729   FakeCommandBufferServiceBase command_buffer_service_;
730   FakeDecoderClient client_;
731   MockOutputter outputter_;
732   std::unique_ptr<MockGLES2Decoder> decoder_;
733   std::unique_ptr<GPUTracerTester> tracer_tester_;
734 };
735 
TEST_F(GPUTracerTest,IsTracingTest)736 TEST_F(GPUTracerTest, IsTracingTest) {
737   EXPECT_FALSE(tracer_tester_->IsTracing());
738   tracer_tester_->SetTracingEnabled(true);
739   EXPECT_TRUE(tracer_tester_->IsTracing());
740 }
741 // Test basic functionality of the GPUTracerTester.
TEST_F(GPUTracerTest,DecodeTest)742 TEST_F(GPUTracerTest, DecodeTest) {
743   ASSERT_TRUE(tracer_tester_->BeginDecoding());
744   EXPECT_FALSE(tracer_tester_->BeginDecoding());
745   ASSERT_TRUE(tracer_tester_->EndDecoding());
746   EXPECT_FALSE(tracer_tester_->EndDecoding());
747 }
748 
TEST_F(GPUTracerTest,TraceDuringDecodeTest)749 TEST_F(GPUTracerTest, TraceDuringDecodeTest) {
750   const std::string category_name("trace_category");
751   const std::string trace_name("trace_test");
752 
753   EXPECT_FALSE(
754       tracer_tester_->Begin(category_name, trace_name, kTraceCHROMIUM));
755 
756   ASSERT_TRUE(tracer_tester_->BeginDecoding());
757   EXPECT_TRUE(
758       tracer_tester_->Begin(category_name, trace_name, kTraceCHROMIUM));
759   ASSERT_TRUE(tracer_tester_->EndDecoding());
760 }
761 
TEST_F(GpuDisjointTimerTracerTest,MultipleClientsDisjointTest)762 TEST_F(GpuDisjointTimerTracerTest, MultipleClientsDisjointTest) {
763   scoped_refptr<gl::GPUTimingClient> client1 =
764       GetGLContext()->CreateGPUTimingClient();
765   scoped_refptr<gl::GPUTimingClient> client2 =
766       GetGLContext()->CreateGPUTimingClient();
767 
768   // Test both clients are initialized as no errors.
769   ASSERT_FALSE(client1->CheckAndResetTimerErrors());
770   ASSERT_FALSE(client2->CheckAndResetTimerErrors());
771 
772   // Issue a disjoint.
773   gl_fake_queries_.SetDisjoint();
774 
775   ASSERT_TRUE(client1->CheckAndResetTimerErrors());
776   ASSERT_TRUE(client2->CheckAndResetTimerErrors());
777 
778   // Test both are now reset.
779   ASSERT_FALSE(client1->CheckAndResetTimerErrors());
780   ASSERT_FALSE(client2->CheckAndResetTimerErrors());
781 
782   // Issue a disjoint.
783   gl_fake_queries_.SetDisjoint();
784 
785   // Test new client disjoint value is cleared.
786   scoped_refptr<gl::GPUTimingClient> client3 =
787       GetGLContext()->CreateGPUTimingClient();
788   ASSERT_TRUE(client1->CheckAndResetTimerErrors());
789   ASSERT_TRUE(client2->CheckAndResetTimerErrors());
790   ASSERT_FALSE(client3->CheckAndResetTimerErrors());
791 }
792 
793 }  // namespace
794 }  // namespace gles2
795 }  // namespace gpu
796