OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 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 "gpu/command_buffer/service/path_manager.h" |
| 6 |
| 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "gpu/command_buffer/service/gpu_service_test.h" |
| 9 #include "gpu/command_buffer/service/mocks.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include "ui/gl/gl_mock.h" |
| 12 |
| 13 namespace gpu { |
| 14 namespace gles2 { |
| 15 |
| 16 class PathManagerTest : public GpuServiceTest { |
| 17 public: |
| 18 PathManagerTest() {} |
| 19 |
| 20 protected: |
| 21 void SetUp() override { |
| 22 SetUpWithGLVersion("3.0", "GL_NV_path_rendering"); |
| 23 manager_.reset(new PathManager()); |
| 24 } |
| 25 |
| 26 void TearDown() override { |
| 27 manager_->Destroy(true); |
| 28 manager_.reset(); |
| 29 GpuServiceTest::TearDown(); |
| 30 } |
| 31 |
| 32 scoped_ptr<PathManager> manager_; |
| 33 }; |
| 34 |
| 35 TEST_F(PathManagerTest, Basic) { |
| 36 const GLuint kClient1Id = 1; |
| 37 const GLuint kService1Id = 11; |
| 38 const GLuint kClient2Id = 2; |
| 39 GLuint service_id = 0; |
| 40 manager_->CreatePathRange(kClient1Id, kClient1Id, kService1Id); |
| 41 ASSERT_TRUE(manager_->HasPathsInRange(kClient1Id, kClient1Id)); |
| 42 EXPECT_TRUE(manager_->GetPath(kClient1Id, &service_id)); |
| 43 EXPECT_EQ(kService1Id, service_id); |
| 44 |
| 45 // Check we get nothing for a non-existent path. |
| 46 service_id = 123u; |
| 47 ASSERT_FALSE(manager_->HasPathsInRange(kClient2Id, kClient2Id)); |
| 48 EXPECT_FALSE(manager_->GetPath(kClient2Id, &service_id)); |
| 49 EXPECT_EQ(123u, service_id); |
| 50 |
| 51 // Check trying to remove non-existent paths does not crash. |
| 52 manager_->RemovePaths(kClient2Id, kClient2Id); |
| 53 |
| 54 // Check that it gets deleted when the last reference is released. |
| 55 EXPECT_CALL(*gl_, DeletePathsNV(kService1Id, 1)) |
| 56 .Times(1) |
| 57 .RetiresOnSaturation(); |
| 58 |
| 59 // Check we can't get the path after we remove it. |
| 60 manager_->RemovePaths(kClient1Id, kClient1Id); |
| 61 ASSERT_FALSE(manager_->HasPathsInRange(kClient1Id, kClient1Id)); |
| 62 EXPECT_FALSE(manager_->GetPath(kClient1Id, &service_id)); |
| 63 } |
| 64 |
| 65 // Tests that path manager does not merge ranges that contain service ids that |
| 66 // prevent the merging. Path ranges A and B can be merged if |
| 67 // * client ids of B start immediately after the last client id of A |
| 68 // * service ids of B start immediately after the last service id of A |
| 69 // and similarly for the 'before' case. |
| 70 TEST_F(PathManagerTest, NonContiguousServiceIds) { |
| 71 const GLuint kMergeCheckRange = 54; |
| 72 |
| 73 const struct { |
| 74 GLuint first_client_id; |
| 75 GLuint last_client_id; |
| 76 GLuint first_service_id; |
| 77 } kIdRanges[] = {{500, 1000, 900}, {1001, 1155, 1}, {200, 499, 4888}}; |
| 78 for (auto& range : kIdRanges) { |
| 79 manager_->CreatePathRange(range.first_client_id, range.last_client_id, |
| 80 range.first_service_id); |
| 81 ASSERT_TRUE(manager_->HasPathsInRange(range.first_client_id, |
| 82 range.first_client_id)); |
| 83 ASSERT_TRUE( |
| 84 manager_->HasPathsInRange(range.last_client_id, range.last_client_id)); |
| 85 ASSERT_TRUE( |
| 86 manager_->HasPathsInRange(range.first_client_id, range.last_client_id)); |
| 87 GLuint service_id = 0u; |
| 88 EXPECT_TRUE(manager_->GetPath(range.first_client_id + 5u, &service_id)); |
| 89 EXPECT_EQ(range.first_service_id + 5u, service_id); |
| 90 } |
| 91 |
| 92 // Insert a mergeable range last, to check that merges |
| 93 // work. Otherwise the test could succeed because merges were not |
| 94 // working. |
| 95 auto& merge_candidate = kIdRanges[1]; |
| 96 GLuint merge_candidate_range = |
| 97 merge_candidate.last_client_id - merge_candidate.first_client_id + 1; |
| 98 manager_->CreatePathRange( |
| 99 merge_candidate.last_client_id + 1, |
| 100 merge_candidate.last_client_id + kMergeCheckRange, |
| 101 merge_candidate.first_service_id + merge_candidate_range); |
| 102 |
| 103 // We detect that ranges were not merged accidentally by detecting individual |
| 104 // deletes. |
| 105 for (auto& range : kIdRanges) { |
| 106 if (&range == &merge_candidate) |
| 107 continue; |
| 108 GLsizei range_amount = range.last_client_id - range.first_client_id + 1; |
| 109 EXPECT_CALL(*gl_, DeletePathsNV(range.first_service_id, range_amount)) |
| 110 .Times(1) |
| 111 .RetiresOnSaturation(); |
| 112 } |
| 113 |
| 114 // Just a check that merges work. |
| 115 EXPECT_CALL(*gl_, DeletePathsNV(merge_candidate.first_service_id, |
| 116 merge_candidate_range + kMergeCheckRange)) |
| 117 .Times(1) |
| 118 .RetiresOnSaturation(); |
| 119 |
| 120 // Remove all ids. This should cause the expected amount of DeletePathsNV |
| 121 // calls. |
| 122 manager_->RemovePaths(1, std::numeric_limits<GLsizei>::max()); |
| 123 |
| 124 for (auto& range : kIdRanges) { |
| 125 ASSERT_FALSE( |
| 126 manager_->HasPathsInRange(range.first_client_id, range.last_client_id)); |
| 127 } |
| 128 } |
| 129 |
| 130 TEST_F(PathManagerTest, DeleteBigRange) { |
| 131 // Allocates two ranges which in path manager end up merging as one |
| 132 // big range. The range will be too big to fit in one DeletePaths |
| 133 // call. Test that the range is deleted correctly with two calls. |
| 134 const GLuint kFirstClientId1 = 1; |
| 135 const GLsizei kRange1 = std::numeric_limits<GLsizei>::max() - 3; |
| 136 const GLuint kLastClientId1 = kFirstClientId1 + kRange1 - 1; |
| 137 const GLuint kFirstServiceId1 = 77; |
| 138 const GLuint kLastServiceId1 = kFirstServiceId1 + kRange1 - 1; |
| 139 |
| 140 const GLuint kFirstClientId2 = kLastClientId1 + 1; |
| 141 const GLsizei kRange2 = 15; |
| 142 const GLuint kLastClientId2 = kFirstClientId2 + kRange2 - 1; |
| 143 const GLuint kFirstServiceId2 = kLastServiceId1 + 1; |
| 144 |
| 145 const GLsizei kFirstDeleteRange = std::numeric_limits<GLsizei>::max(); |
| 146 const GLsizei kSecondDeleteRange = kRange2 - (kFirstDeleteRange - kRange1); |
| 147 const GLuint kSecondDeleteFirstServiceId = |
| 148 kFirstServiceId1 + kFirstDeleteRange; |
| 149 |
| 150 EXPECT_CALL(*gl_, DeletePathsNV(kFirstServiceId1, |
| 151 std::numeric_limits<GLsizei>::max())) |
| 152 .RetiresOnSaturation(); |
| 153 |
| 154 EXPECT_CALL(*gl_, DeletePathsNV(kSecondDeleteFirstServiceId, |
| 155 kSecondDeleteRange)).RetiresOnSaturation(); |
| 156 |
| 157 manager_->CreatePathRange(kFirstClientId1, kLastClientId1, kFirstServiceId1); |
| 158 manager_->CreatePathRange(kFirstClientId2, kLastClientId2, kFirstServiceId2); |
| 159 manager_->RemovePaths(0, std::numeric_limits<GLuint>::max()); |
| 160 } |
| 161 |
| 162 } // namespace gles2 |
| 163 |
| 164 } // namespace gpu |
OLD | NEW |