Index: gpu/command_buffer/service/sync_point_manager_unittest.cc |
diff --git a/gpu/command_buffer/service/sync_point_manager_unittest.cc b/gpu/command_buffer/service/sync_point_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..43212b07a58449294a58e5eebdd3187153c01f14 |
--- /dev/null |
+++ b/gpu/command_buffer/service/sync_point_manager_unittest.cc |
@@ -0,0 +1,384 @@ |
+// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <queue> |
+ |
+#include "base/bind.h" |
+#include "gpu/command_buffer/service/sync_point_manager.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace gpu { |
+ |
+class SyncPointManagerTest : public testing::Test { |
+ public: |
+ SyncPointManagerTest() { |
+ } |
+ |
+ ~SyncPointManagerTest() override {} |
+ |
+ protected: |
+ void SetUp() override { |
+ sync_point_manager_.reset(new SyncPointManager(false)); |
+ } |
+ |
+ void TearDown() override { |
+ sync_point_manager_.reset(); |
+ } |
+ |
+ // Simple static function which can be used to test callbacks. |
+ static void SetIntegerFunction(int* test, int value) { |
+ *test = value; |
+ } |
+ |
+ scoped_ptr<SyncPointManager> sync_point_manager_; |
+}; |
+ |
+struct SyncPointStream { |
+ scoped_refptr<SyncPointOrderData> order_data; |
+ scoped_ptr<SyncPointClient> client; |
+ std::queue<uint32_t> order_numbers; |
+ |
+ SyncPointStream(SyncPointManager* sync_point_manager, |
+ CommandBufferNamespace namespace_id, |
+ uint64_t command_buffer_id) |
+ : order_data(SyncPointOrderData::Create()), |
+ client(sync_point_manager->CreateSyncPointClient(order_data, |
+ namespace_id, |
+ command_buffer_id)) {} |
+ |
+ ~SyncPointStream() { |
+ order_data->Destroy(); |
+ order_data = nullptr; |
+ } |
+ |
+ void AllocateOrderNum(SyncPointManager* sync_point_manager) { |
+ order_numbers.push( |
+ order_data->GenerateUnprocessedOrderNumber(sync_point_manager)); |
+ } |
+ |
+ void BeginProcessing() { |
+ ASSERT_FALSE(order_numbers.empty()); |
+ order_data->BeginProcessingOrderNumber(order_numbers.front()); |
+ } |
+ |
+ void EndProcessing() { |
+ ASSERT_FALSE(order_numbers.empty()); |
+ order_data->FinishProcessingOrderNumber(order_numbers.front()); |
+ order_numbers.pop(); |
+ } |
+}; |
+ |
+TEST_F(SyncPointManagerTest, BasicSyncPointOrderDataTest) { |
+ scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
+ |
+ EXPECT_EQ(0u, order_data->current_order_num()); |
+ EXPECT_EQ(0u, order_data->processed_order_num()); |
+ EXPECT_EQ(0u, order_data->unprocessed_order_num()); |
+ |
+ const uint32_t order_num = |
+ order_data->GenerateUnprocessedOrderNumber(sync_point_manager_.get()); |
+ EXPECT_EQ(1u, order_num); |
+ |
+ EXPECT_EQ(0u, order_data->current_order_num()); |
+ EXPECT_EQ(0u, order_data->processed_order_num()); |
+ EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
+ |
+ order_data->BeginProcessingOrderNumber(order_num); |
+ EXPECT_EQ(order_num, order_data->current_order_num()); |
+ EXPECT_EQ(0u, order_data->processed_order_num()); |
+ EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
+ |
+ order_data->FinishProcessingOrderNumber(order_num); |
+ EXPECT_EQ(order_num, order_data->current_order_num()); |
+ EXPECT_EQ(order_num, order_data->processed_order_num()); |
+ EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
+} |
+ |
+TEST_F(SyncPointManagerTest, SyncPointClientRegistration) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId = 0x123; |
+ |
+ scoped_refptr<SyncPointClientState> empty_state = |
+ sync_point_manager_->GetSyncPointClientState(kNamespaceId, kBufferId); |
+ EXPECT_FALSE(empty_state); |
+ |
+ scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
+ |
+ scoped_ptr<SyncPointClient> client = |
+ sync_point_manager_->CreateSyncPointClient(order_data, |
+ kNamespaceId, |
+ kBufferId); |
+ |
+ EXPECT_EQ(order_data, client->client_state()->order_data()); |
+ EXPECT_EQ(client->client_state(), |
+ sync_point_manager_->GetSyncPointClientState(kNamespaceId, |
+ kBufferId)); |
+} |
+ |
+TEST_F(SyncPointManagerTest, BasicFenceSyncRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId = 0x123; |
+ |
+ scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
+ scoped_ptr<SyncPointClient> client = |
+ sync_point_manager_->CreateSyncPointClient(order_data, |
+ kNamespaceId, |
+ kBufferId); |
+ scoped_refptr<SyncPointClientState> client_state = client->client_state(); |
+ |
+ EXPECT_EQ(0u, client_state->fence_sync_release()); |
+ EXPECT_FALSE(client_state->IsFenceSyncReleased(1)); |
+ |
+ client->ReleaseFenceSync(1); |
+ |
+ EXPECT_EQ(1u, client_state->fence_sync_release()); |
+ EXPECT_TRUE(client_state->IsFenceSyncReleased(1)); |
+} |
+ |
+TEST_F(SyncPointManagerTest, MultipleClientsPerOrderData) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
+ scoped_ptr<SyncPointClient> client1 = |
+ sync_point_manager_->CreateSyncPointClient(order_data, |
+ kNamespaceId, |
+ kBufferId1); |
+ scoped_ptr<SyncPointClient> client2 = |
+ sync_point_manager_->CreateSyncPointClient(order_data, |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ scoped_refptr<SyncPointClientState> client_state1 = client1->client_state(); |
+ scoped_refptr<SyncPointClientState> client_state2 = client2->client_state(); |
+ |
+ client1->ReleaseFenceSync(1); |
+ |
+ EXPECT_TRUE(client_state1->IsFenceSyncReleased(1)); |
+ EXPECT_FALSE(client_state2->IsFenceSyncReleased(1)); |
+} |
+ |
+TEST_F(SyncPointManagerTest, BasicFenceSyncWaitRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ SyncPointStream release_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId1); |
+ SyncPointStream wait_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ |
+ wait_stream.BeginProcessing(); |
+ int test_num = 10; |
+ const bool valid_wait = |
+ wait_stream.client->Wait( |
+ release_stream.client->client_state(), |
+ 1, |
+ base::Bind(&SyncPointManagerTest::SetIntegerFunction, |
+ &test_num, |
+ 123)); |
+ ASSERT_TRUE(valid_wait); |
+ EXPECT_EQ(10, test_num); |
+ |
+ release_stream.BeginProcessing(); |
+ release_stream.client->ReleaseFenceSync(1); |
+ EXPECT_EQ(123, test_num); |
+} |
+ |
+TEST_F(SyncPointManagerTest, OutOfOrderRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ SyncPointStream release_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId1); |
+ SyncPointStream wait_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ // Generate wait order number first. |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ |
+ wait_stream.BeginProcessing(); |
+ int test_num = 10; |
+ const bool valid_wait = |
+ wait_stream.client->Wait( |
+ release_stream.client->client_state(), |
+ 1, |
+ base::Bind(&SyncPointManagerTest::SetIntegerFunction, |
+ &test_num, |
+ 123)); |
+ EXPECT_FALSE(valid_wait); |
+ EXPECT_EQ(10, test_num); |
+} |
+ |
+TEST_F(SyncPointManagerTest, HigherOrderNumberRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ SyncPointStream release_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId1); |
+ SyncPointStream wait_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ // Generate wait order number first. |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ |
+ // Order number was higher but it was actually released. |
+ release_stream.BeginProcessing(); |
+ release_stream.client->ReleaseFenceSync(1); |
+ release_stream.EndProcessing(); |
+ |
+ wait_stream.BeginProcessing(); |
+ int test_num = 10; |
+ const bool valid_wait = |
+ wait_stream.client->Wait( |
+ release_stream.client->client_state(), |
+ 1, |
+ base::Bind(&SyncPointManagerTest::SetIntegerFunction, |
+ &test_num, |
+ 123)); |
+ EXPECT_TRUE(valid_wait); |
+ EXPECT_EQ(123, test_num); |
+} |
+ |
+TEST_F(SyncPointManagerTest, DestroyedClientRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ SyncPointStream release_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId1); |
+ SyncPointStream wait_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ |
+ wait_stream.BeginProcessing(); |
+ int test_num = 10; |
+ const bool valid_wait = |
+ wait_stream.client->Wait( |
+ release_stream.client->client_state(), |
+ 1, |
+ base::Bind(&SyncPointManagerTest::SetIntegerFunction, |
+ &test_num, |
+ 123)); |
+ EXPECT_TRUE(valid_wait); |
+ EXPECT_EQ(10, test_num); |
+ |
+ // Destroying the client should release the wait. |
+ release_stream.client.reset(); |
+ EXPECT_EQ(123, test_num); |
+} |
+ |
+TEST_F(SyncPointManagerTest, NonExistentRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ SyncPointStream release_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId1); |
+ SyncPointStream wait_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ |
+ wait_stream.BeginProcessing(); |
+ int test_num = 10; |
+ const bool valid_wait = |
+ wait_stream.client->Wait( |
+ release_stream.client->client_state(), |
+ 1, |
+ base::Bind(&SyncPointManagerTest::SetIntegerFunction, |
+ &test_num, |
+ 123)); |
+ EXPECT_TRUE(valid_wait); |
+ EXPECT_EQ(10, test_num); |
+ |
+ // No release but finishing the order number should automatically release. |
+ release_stream.BeginProcessing(); |
+ EXPECT_EQ(10, test_num); |
+ release_stream.EndProcessing(); |
+ EXPECT_EQ(123, test_num); |
+} |
+ |
+TEST_F(SyncPointManagerTest, NonExistentOrderNumRelease) { |
+ const CommandBufferNamespace kNamespaceId = |
+ gpu::CommandBufferNamespace::GPU_IO; |
+ const uint64_t kBufferId1 = 0x123; |
+ const uint64_t kBufferId2 = 0x234; |
+ |
+ SyncPointStream release_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId1); |
+ SyncPointStream wait_stream(sync_point_manager_.get(), |
+ kNamespaceId, |
+ kBufferId2); |
+ |
+ // Assign Release stream 1, 4 and assign Wait stream 2, 3. |
piman
2015/10/01 17:58:16
nit: maybe comment that order [3] waits on fence (
David Yen
2015/10/01 18:12:00
What this test is really testing is releases and o
|
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ release_stream.AllocateOrderNum(sync_point_manager_.get()); |
+ |
+ // Have wait with order number 3 to wait on release. |
+ wait_stream.BeginProcessing(); |
+ ASSERT_EQ(2u, wait_stream.order_data->current_order_num()); |
+ wait_stream.EndProcessing(); |
+ wait_stream.BeginProcessing(); |
+ ASSERT_EQ(3u, wait_stream.order_data->current_order_num()); |
+ int test_num = 10; |
+ const bool valid_wait = |
+ wait_stream.client->Wait( |
+ release_stream.client->client_state(), |
+ 1, |
+ base::Bind(&SyncPointManagerTest::SetIntegerFunction, |
+ &test_num, |
+ 123)); |
+ EXPECT_TRUE(valid_wait); |
+ EXPECT_EQ(10, test_num); |
+ |
+ // Release stream should know it should release fence sync by order 3, |
+ // so going through order number 1 should not release it yet. |
+ release_stream.BeginProcessing(); |
+ ASSERT_EQ(1u, release_stream.order_data->current_order_num()); |
+ release_stream.EndProcessing(); |
+ EXPECT_FALSE(release_stream.client->client_state()->IsFenceSyncReleased(1)); |
+ EXPECT_EQ(10, test_num); |
+ |
+ // Beginning order number 4 should immediately release 3. |
piman
2015/10/01 17:58:16
I think I'd like a similar test where there is no
David Yen
2015/10/01 18:12:00
If there is no #4, then this test is the same as t
David Yen
2015/10/01 18:25:43
I've now added a new test "NonExistentRelease2" wh
|
+ release_stream.BeginProcessing(); |
+ ASSERT_EQ(4u, release_stream.order_data->current_order_num()); |
+ EXPECT_TRUE(release_stream.client->client_state()->IsFenceSyncReleased(1)); |
+ EXPECT_EQ(123, test_num); |
+} |
+ |
+} // namespace gpu |
+ |