| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "media/gpu/avda_codec_allocator.h" | 5 #include "media/gpu/avda_codec_allocator.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/time/tick_clock.h" | 13 #include "base/time/tick_clock.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 16 |
| 17 using testing::NiceMock; |
| 18 using testing::_; |
| 19 |
| 16 namespace media { | 20 namespace media { |
| 17 namespace { | 21 namespace { |
| 18 template <typename ReturnType> | 22 template <typename ReturnType> |
| 19 void RunAndSignalTask(base::WaitableEvent* event, | 23 void RunAndSignalTask(base::WaitableEvent* event, |
| 20 ReturnType* return_value, | 24 ReturnType* return_value, |
| 21 const base::Callback<ReturnType(void)>& cb) { | 25 const base::Callback<ReturnType(void)>& cb) { |
| 22 *return_value = cb.Run(); | 26 *return_value = cb.Run(); |
| 23 event->Signal(); | 27 event->Signal(); |
| 24 } | 28 } |
| 25 } | 29 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 40 void Advance(int msec) { | 44 void Advance(int msec) { |
| 41 base::AutoLock auto_lock(lock_); | 45 base::AutoLock auto_lock(lock_); |
| 42 now_ += base::TimeDelta::FromMilliseconds(msec); | 46 now_ += base::TimeDelta::FromMilliseconds(msec); |
| 43 } | 47 } |
| 44 | 48 |
| 45 private: | 49 private: |
| 46 base::Lock lock_; | 50 base::Lock lock_; |
| 47 base::TimeTicks now_; | 51 base::TimeTicks now_; |
| 48 }; | 52 }; |
| 49 | 53 |
| 54 class MockClient : public AVDACodecAllocatorClient { |
| 55 public: |
| 56 MOCK_METHOD1(OnSurfaceAvailable, void(bool success)); |
| 57 MOCK_METHOD0(OnSurfaceDestroyed, void()); |
| 58 |
| 59 // Gmock doesn't let us mock methods taking move-only types. |
| 60 MOCK_METHOD1(OnCodecConfiguredMock, void(VideoCodecBridge* media_codec)); |
| 61 void OnCodecConfigured( |
| 62 std::unique_ptr<VideoCodecBridge> media_codec) override { |
| 63 OnCodecConfiguredMock(media_codec.get()); |
| 64 } |
| 65 }; |
| 66 |
| 50 class AVDACodecAllocatorTest : public testing::Test { | 67 class AVDACodecAllocatorTest : public testing::Test { |
| 51 public: | 68 public: |
| 52 AVDACodecAllocatorTest() : allocator_thread_("AllocatorThread") {} | 69 AVDACodecAllocatorTest() : allocator_thread_("AllocatorThread") {} |
| 53 ~AVDACodecAllocatorTest() override {} | 70 ~AVDACodecAllocatorTest() override {} |
| 54 | 71 |
| 55 protected: | 72 protected: |
| 56 void SetUp() override { | 73 void SetUp() override { |
| 57 // Start the main thread for the allocator. This would normally be the GPU | 74 // Start the main thread for the allocator. This would normally be the GPU |
| 58 // main thread. | 75 // main thread. |
| 59 ASSERT_TRUE(allocator_thread_.Start()); | 76 ASSERT_TRUE(allocator_thread_.Start()); |
| 60 | 77 |
| 61 // AVDACodecAllocator likes to post tasks to the current thread. | 78 // AVDACodecAllocator likes to post tasks to the current thread. |
| 62 | 79 |
| 63 test_information_.reset(new AVDACodecAllocator::TestInformation()); | 80 test_information_.reset(new AVDACodecAllocator::TestInformation()); |
| 64 test_information_->tick_clock_.reset(new MockTickClock()); | 81 test_information_->tick_clock_.reset(new MockTickClock()); |
| 65 test_information_->stop_event_.reset(new base::WaitableEvent( | 82 test_information_->stop_event_.reset(new base::WaitableEvent( |
| 66 base::WaitableEvent::ResetPolicy::AUTOMATIC, | 83 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 67 base::WaitableEvent::InitialState::NOT_SIGNALED)); | 84 base::WaitableEvent::InitialState::NOT_SIGNALED)); |
| 68 | 85 |
| 69 // Allocate the allocator on the appropriate thread. | 86 // Allocate the allocator on the appropriate thread. |
| 70 allocator_ = PostAndWait( | 87 allocator_ = PostAndWait( |
| 71 FROM_HERE, base::Bind( | 88 FROM_HERE, base::Bind( |
| 72 [](AVDACodecAllocator::TestInformation* test_info) { | 89 [](AVDACodecAllocator::TestInformation* test_info) { |
| 73 return new AVDACodecAllocator(test_info); | 90 return new AVDACodecAllocator(test_info); |
| 74 }, | 91 }, |
| 75 test_information_.get())); | 92 test_information_.get())); |
| 93 allocator2_ = new AVDACodecAllocator(test_information_.get()); |
| 76 | 94 |
| 77 // All threads should be stopped | 95 // All threads should be stopped |
| 78 ASSERT_FALSE(IsThreadRunning(AVDACodecAllocator::TaskType::AUTO_CODEC)); | 96 ASSERT_FALSE(IsThreadRunning(TaskType::AUTO_CODEC)); |
| 79 ASSERT_FALSE(IsThreadRunning(AVDACodecAllocator::TaskType::SW_CODEC)); | 97 ASSERT_FALSE(IsThreadRunning(TaskType::SW_CODEC)); |
| 80 | 98 |
| 81 // Register an AVDA instance to start the allocator's threads. | 99 // Register an AVDA instance to start the allocator's threads. |
| 82 ASSERT_TRUE(StartThread(avda1_)); | 100 ASSERT_TRUE(StartThread(avda1_)); |
| 83 | 101 |
| 84 // Assert that at least the AUTO_CODEC thread is started. The other might | 102 // Assert that at least the AUTO_CODEC thread is started. The other might |
| 85 // not be. | 103 // not be. |
| 86 ASSERT_TRUE(IsThreadRunning(AVDACodecAllocator::TaskType::AUTO_CODEC)); | 104 ASSERT_TRUE(IsThreadRunning(TaskType::AUTO_CODEC)); |
| 87 ASSERT_EQ(AVDACodecAllocator::TaskType::AUTO_CODEC, | 105 ASSERT_EQ(TaskType::AUTO_CODEC, TaskTypeForAllocation()); |
| 88 TaskTypeForAllocation()); | |
| 89 } | 106 } |
| 90 | 107 |
| 91 void TearDown() override { | 108 void TearDown() override { |
| 92 // Don't leave any threads hung, or this will hang too. | 109 // Don't leave any threads hung, or this will hang too. |
| 93 // It would be nice if we could let a unique ptr handle this, but the | 110 // It would be nice if we could let a unique ptr handle this, but the |
| 94 // destructor is private. We also have to destroy it on the right thread. | 111 // destructor is private. We also have to destroy it on the right thread. |
| 95 PostAndWait(FROM_HERE, base::Bind( | 112 PostAndWait(FROM_HERE, base::Bind( |
| 96 [](AVDACodecAllocator* allocator) { | 113 [](AVDACodecAllocator* allocator) { |
| 97 delete allocator; | 114 delete allocator; |
| 98 return true; | 115 return true; |
| 99 }, | 116 }, |
| 100 allocator_)); | 117 allocator_)); |
| 101 | 118 |
| 102 allocator_thread_.Stop(); | 119 allocator_thread_.Stop(); |
| 120 delete allocator2_; |
| 103 } | 121 } |
| 104 | 122 |
| 105 protected: | 123 protected: |
| 106 static void WaitUntilRestarted(base::WaitableEvent* about_to_wait_event, | 124 static void WaitUntilRestarted(base::WaitableEvent* about_to_wait_event, |
| 107 base::WaitableEvent* wait_event) { | 125 base::WaitableEvent* wait_event) { |
| 108 // Notify somebody that we've started. | 126 // Notify somebody that we've started. |
| 109 about_to_wait_event->Signal(); | 127 about_to_wait_event->Signal(); |
| 110 wait_event->Wait(); | 128 wait_event->Wait(); |
| 111 } | 129 } |
| 112 | 130 |
| 113 static void SignalImmediately(base::WaitableEvent* event) { event->Signal(); } | 131 static void SignalImmediately(base::WaitableEvent* event) { event->Signal(); } |
| 114 | 132 |
| 115 // Start / stop the threads for |avda| on the right thread. | 133 // Start / stop the threads for |avda| on the right thread. |
| 116 bool StartThread(AndroidVideoDecodeAccelerator* avda) { | 134 bool StartThread(AVDACodecAllocatorClient* avda) { |
| 117 return PostAndWait(FROM_HERE, base::Bind( | 135 return PostAndWait(FROM_HERE, base::Bind( |
| 118 [](AVDACodecAllocator* allocator, | 136 [](AVDACodecAllocator* allocator, |
| 119 AndroidVideoDecodeAccelerator* avda) { | 137 AVDACodecAllocatorClient* avda) { |
| 120 return allocator->StartThread(avda); | 138 return allocator->StartThread(avda); |
| 121 }, | 139 }, |
| 122 allocator_, avda)); | 140 allocator_, avda)); |
| 123 } | 141 } |
| 124 | 142 |
| 125 void StopThread(AndroidVideoDecodeAccelerator* avda) { | 143 void StopThread(AVDACodecAllocatorClient* avda) { |
| 126 // Note that we also wait for the stop event, so that we know that the | 144 // Note that we also wait for the stop event, so that we know that the |
| 127 // stop has completed. It's async with respect to the allocator thread. | 145 // stop has completed. It's async with respect to the allocator thread. |
| 128 PostAndWait(FROM_HERE, base::Bind( | 146 PostAndWait(FROM_HERE, base::Bind( |
| 129 [](AVDACodecAllocator* allocator, | 147 [](AVDACodecAllocator* allocator, |
| 130 AndroidVideoDecodeAccelerator* avda) { | 148 AVDACodecAllocatorClient* avda) { |
| 131 allocator->StopThread(avda); | 149 allocator->StopThread(avda); |
| 132 return true; | 150 return true; |
| 133 }, | 151 }, |
| 134 allocator_, avda)); | 152 allocator_, avda)); |
| 135 // Note that we don't do this on the allocator thread, since that's the | 153 // Note that we don't do this on the allocator thread, since that's the |
| 136 // thread that will signal it. | 154 // thread that will signal it. |
| 137 test_information_->stop_event_->Wait(); | 155 test_information_->stop_event_->Wait(); |
| 138 } | 156 } |
| 139 | 157 |
| 140 // Return the running state of |task_type|, doing the necessary thread hops. | 158 // Return the running state of |task_type|, doing the necessary thread hops. |
| 141 bool IsThreadRunning(AVDACodecAllocator::TaskType task_type) { | 159 bool IsThreadRunning(TaskType task_type) { |
| 142 return PostAndWait( | 160 return PostAndWait( |
| 143 FROM_HERE, | 161 FROM_HERE, |
| 144 base::Bind( | 162 base::Bind( |
| 145 [](AVDACodecAllocator* allocator, | 163 [](AVDACodecAllocator* allocator, TaskType task_type) { |
| 146 AVDACodecAllocator::TaskType task_type) { | |
| 147 return allocator->GetThreadForTesting(task_type).IsRunning(); | 164 return allocator->GetThreadForTesting(task_type).IsRunning(); |
| 148 }, | 165 }, |
| 149 allocator_, task_type)); | 166 allocator_, task_type)); |
| 150 } | 167 } |
| 151 | 168 |
| 152 AVDACodecAllocator::TaskType TaskTypeForAllocation() { | 169 TaskType TaskTypeForAllocation() { |
| 153 return PostAndWait(FROM_HERE, | 170 return PostAndWait(FROM_HERE, |
| 154 base::Bind(&AVDACodecAllocator::TaskTypeForAllocation, | 171 base::Bind(&AVDACodecAllocator::TaskTypeForAllocation, |
| 155 base::Unretained(allocator_))); | 172 base::Unretained(allocator_))); |
| 156 } | 173 } |
| 157 | 174 |
| 158 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerFor( | 175 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerFor( |
| 159 AVDACodecAllocator::TaskType task_type) { | 176 TaskType task_type) { |
| 160 return PostAndWait(FROM_HERE, | 177 return PostAndWait(FROM_HERE, |
| 161 base::Bind(&AVDACodecAllocator::TaskRunnerFor, | 178 base::Bind(&AVDACodecAllocator::TaskRunnerFor, |
| 162 base::Unretained(allocator_), task_type)); | 179 base::Unretained(allocator_), task_type)); |
| 163 } | 180 } |
| 164 | 181 |
| 165 // Post |cb| to the allocator thread, and wait for a response. Note that we | 182 // Post |cb| to the allocator thread, and wait for a response. Note that we |
| 166 // don't have a specialization for void, and void won't work as written. So, | 183 // don't have a specialization for void, and void won't work as written. So, |
| 167 // be sure to return something. | 184 // be sure to return something. |
| 168 template <typename ReturnType> | 185 template <typename ReturnType> |
| 169 ReturnType PostAndWait(const tracked_objects::Location& from_here, | 186 ReturnType PostAndWait(const tracked_objects::Location& from_here, |
| 170 const base::Callback<ReturnType(void)>& cb) { | 187 const base::Callback<ReturnType(void)>& cb) { |
| 171 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, | 188 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, |
| 172 base::WaitableEvent::InitialState::NOT_SIGNALED); | 189 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 173 ReturnType return_value = ReturnType(); | 190 ReturnType return_value = ReturnType(); |
| 174 allocator_thread_.task_runner()->PostTask( | 191 allocator_thread_.task_runner()->PostTask( |
| 175 from_here, | 192 from_here, |
| 176 base::Bind(&RunAndSignalTask<ReturnType>, &event, &return_value, cb)); | 193 base::Bind(&RunAndSignalTask<ReturnType>, &event, &return_value, cb)); |
| 177 event.Wait(); | 194 event.Wait(); |
| 178 return return_value; | 195 return return_value; |
| 179 } | 196 } |
| 180 | 197 |
| 181 base::Thread allocator_thread_; | 198 base::Thread allocator_thread_; |
| 182 | 199 |
| 183 // Test info that we provide to the codec allocator. | 200 // Test info that we provide to the codec allocator. |
| 184 std::unique_ptr<AVDACodecAllocator::TestInformation> test_information_; | 201 std::unique_ptr<AVDACodecAllocator::TestInformation> test_information_; |
| 185 | 202 |
| 186 // Allocator that we own. Would be a unique_ptr, but the destructor is | 203 // Allocators that we own. The first is intialized to be used on the allocator |
| 187 // private. Plus, we need to destruct it from the right thread. | 204 // thread and the second one is initialized on the test thread. Each test |
| 205 // should only be using one of the two. They are not unique_ptrs because the |
| 206 // destructor is private and they need to be destructed on the right thread. |
| 188 AVDACodecAllocator* allocator_ = nullptr; | 207 AVDACodecAllocator* allocator_ = nullptr; |
| 208 AVDACodecAllocator* allocator2_ = nullptr; |
| 189 | 209 |
| 190 AndroidVideoDecodeAccelerator* avda1_ = (AndroidVideoDecodeAccelerator*)0x1; | 210 NiceMock<MockClient> client1_, client2_, client3_; |
| 191 AndroidVideoDecodeAccelerator* avda2_ = (AndroidVideoDecodeAccelerator*)0x2; | 211 NiceMock<MockClient>* avda1_ = &client1_; |
| 212 NiceMock<MockClient>* avda2_ = &client2_; |
| 213 NiceMock<MockClient>* avda3_ = &client3_; |
| 192 }; | 214 }; |
| 193 | 215 |
| 194 TEST_F(AVDACodecAllocatorTest, TestMultiInstance) { | 216 TEST_F(AVDACodecAllocatorTest, TestMultiInstance) { |
| 195 // Add an avda instance. This one must succeed immediately, since the last | 217 // Add an avda instance. This one must succeed immediately, since the last |
| 196 // one is still running. | 218 // one is still running. |
| 197 ASSERT_TRUE(StartThread(avda2_)); | 219 ASSERT_TRUE(StartThread(avda2_)); |
| 198 | 220 |
| 199 // Stop the original avda instance. | 221 // Stop the original avda instance. |
| 200 StopThread(avda1_); | 222 StopThread(avda1_); |
| 201 | 223 |
| 202 // Verify that the AUTO_CODEC thread is still running. | 224 // Verify that the AUTO_CODEC thread is still running. |
| 203 ASSERT_TRUE(IsThreadRunning(AVDACodecAllocator::TaskType::AUTO_CODEC)); | 225 ASSERT_TRUE(IsThreadRunning(TaskType::AUTO_CODEC)); |
| 204 ASSERT_EQ(AVDACodecAllocator::TaskType::AUTO_CODEC, TaskTypeForAllocation()); | 226 ASSERT_EQ(TaskType::AUTO_CODEC, TaskTypeForAllocation()); |
| 205 | 227 |
| 206 // Remove the second instance and wait for it to stop. Remember that it | 228 // Remove the second instance and wait for it to stop. Remember that it |
| 207 // stops after messages have been posted to the thread, so we don't know | 229 // stops after messages have been posted to the thread, so we don't know |
| 208 // how long it will take. | 230 // how long it will take. |
| 209 StopThread(avda2_); | 231 StopThread(avda2_); |
| 210 | 232 |
| 211 // Verify that the threads have stopped. | 233 // Verify that the threads have stopped. |
| 212 ASSERT_FALSE(IsThreadRunning(AVDACodecAllocator::TaskType::AUTO_CODEC)); | 234 ASSERT_FALSE(IsThreadRunning(TaskType::AUTO_CODEC)); |
| 213 ASSERT_FALSE(IsThreadRunning(AVDACodecAllocator::TaskType::SW_CODEC)); | 235 ASSERT_FALSE(IsThreadRunning(TaskType::SW_CODEC)); |
| 214 } | 236 } |
| 215 | 237 |
| 216 TEST_F(AVDACodecAllocatorTest, TestHangThread) { | 238 TEST_F(AVDACodecAllocatorTest, TestHangThread) { |
| 217 ASSERT_EQ(AVDACodecAllocator::TaskType::AUTO_CODEC, TaskTypeForAllocation()); | 239 ASSERT_EQ(TaskType::AUTO_CODEC, TaskTypeForAllocation()); |
| 218 | 240 |
| 219 // Hang the AUTO_CODEC thread. | 241 // Hang the AUTO_CODEC thread. |
| 220 base::WaitableEvent about_to_wait_event( | 242 base::WaitableEvent about_to_wait_event( |
| 221 base::WaitableEvent::ResetPolicy::MANUAL, | 243 base::WaitableEvent::ResetPolicy::MANUAL, |
| 222 base::WaitableEvent::InitialState::NOT_SIGNALED); | 244 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 223 base::WaitableEvent wait_event( | 245 base::WaitableEvent wait_event( |
| 224 base::WaitableEvent::ResetPolicy::MANUAL, | 246 base::WaitableEvent::ResetPolicy::MANUAL, |
| 225 base::WaitableEvent::InitialState::NOT_SIGNALED); | 247 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 226 TaskRunnerFor(AVDACodecAllocator::TaskType::AUTO_CODEC) | 248 TaskRunnerFor(TaskType::AUTO_CODEC) |
| 227 ->PostTask(FROM_HERE, | 249 ->PostTask(FROM_HERE, |
| 228 base::Bind(&AVDACodecAllocatorTest::WaitUntilRestarted, | 250 base::Bind(&AVDACodecAllocatorTest::WaitUntilRestarted, |
| 229 &about_to_wait_event, &wait_event)); | 251 &about_to_wait_event, &wait_event)); |
| 230 // Wait until the task starts, so that |allocator_| starts the hang timer. | 252 // Wait until the task starts, so that |allocator_| starts the hang timer. |
| 231 about_to_wait_event.Wait(); | 253 about_to_wait_event.Wait(); |
| 232 | 254 |
| 233 // Verify that we've failed over after a long time has passed. | 255 // Verify that we've failed over after a long time has passed. |
| 234 static_cast<MockTickClock*>(test_information_->tick_clock_.get()) | 256 static_cast<MockTickClock*>(test_information_->tick_clock_.get()) |
| 235 ->Advance(1000); | 257 ->Advance(1000); |
| 236 // Note that this should return the SW codec task type even if that thread | 258 // Note that this should return the SW codec task type even if that thread |
| 237 // failed to start. TaskRunnerFor() will return the current thread in that | 259 // failed to start. TaskRunnerFor() will return the current thread in that |
| 238 // case too. | 260 // case too. |
| 239 ASSERT_EQ(AVDACodecAllocator::TaskType::SW_CODEC, TaskTypeForAllocation()); | 261 ASSERT_EQ(TaskType::SW_CODEC, TaskTypeForAllocation()); |
| 240 | 262 |
| 241 // Un-hang the thread and wait for it to let another task run. This will | 263 // Un-hang the thread and wait for it to let another task run. This will |
| 242 // notify |allocator_| that the thread is no longer hung. | 264 // notify |allocator_| that the thread is no longer hung. |
| 243 base::WaitableEvent done_waiting_event( | 265 base::WaitableEvent done_waiting_event( |
| 244 base::WaitableEvent::ResetPolicy::MANUAL, | 266 base::WaitableEvent::ResetPolicy::MANUAL, |
| 245 base::WaitableEvent::InitialState::NOT_SIGNALED); | 267 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 246 TaskRunnerFor(AVDACodecAllocator::TaskType::AUTO_CODEC) | 268 TaskRunnerFor(TaskType::AUTO_CODEC) |
| 247 ->PostTask(FROM_HERE, | 269 ->PostTask(FROM_HERE, |
| 248 base::Bind(&AVDACodecAllocatorTest::SignalImmediately, | 270 base::Bind(&AVDACodecAllocatorTest::SignalImmediately, |
| 249 &done_waiting_event)); | 271 &done_waiting_event)); |
| 250 wait_event.Signal(); | 272 wait_event.Signal(); |
| 251 done_waiting_event.Wait(); | 273 done_waiting_event.Wait(); |
| 252 | 274 |
| 253 // Verify that we've un-failed over. | 275 // Verify that we've un-failed over. |
| 254 ASSERT_EQ(AVDACodecAllocator::TaskType::AUTO_CODEC, TaskTypeForAllocation()); | 276 ASSERT_EQ(TaskType::AUTO_CODEC, TaskTypeForAllocation()); |
| 277 } |
| 278 |
| 279 TEST_F(AVDACodecAllocatorTest, AllocatingASurfaceTextureAlwaysSucceeds) { |
| 280 ASSERT_TRUE( |
| 281 allocator2_->AllocateSurface(avda1_, SurfaceManager::kNoSurfaceID)); |
| 282 ASSERT_TRUE( |
| 283 allocator2_->AllocateSurface(avda2_, SurfaceManager::kNoSurfaceID)); |
| 284 } |
| 285 |
| 286 TEST_F(AVDACodecAllocatorTest, AllocatingAnOwnedSurfaceFails) { |
| 287 ASSERT_TRUE(allocator2_->AllocateSurface(avda1_, 1)); |
| 288 ASSERT_FALSE(allocator2_->AllocateSurface(avda2_, 1)); |
| 289 } |
| 290 |
| 291 TEST_F(AVDACodecAllocatorTest, LaterWaitersReplaceEarlierWaiters) { |
| 292 allocator2_->AllocateSurface(avda1_, 1); |
| 293 allocator2_->AllocateSurface(avda2_, 1); |
| 294 EXPECT_CALL(*avda2_, OnSurfaceAvailable(false)); |
| 295 allocator2_->AllocateSurface(avda3_, 1); |
| 296 } |
| 297 |
| 298 TEST_F(AVDACodecAllocatorTest, WaitersBecomeOwnersWhenSurfacesAreReleased) { |
| 299 allocator2_->AllocateSurface(avda1_, 1); |
| 300 allocator2_->AllocateSurface(avda2_, 1); |
| 301 EXPECT_CALL(*avda2_, OnSurfaceAvailable(true)); |
| 302 allocator2_->DeallocateSurface(avda1_, 1); |
| 303 // The surface should still be owned. |
| 304 ASSERT_FALSE(allocator2_->AllocateSurface(avda1_, 1)); |
| 305 } |
| 306 |
| 307 TEST_F(AVDACodecAllocatorTest, DeallocatingUnownedSurfacesIsSafe) { |
| 308 allocator2_->DeallocateSurface(avda1_, 1); |
| 309 allocator2_->DeallocateSurface(avda1_, SurfaceManager::kNoSurfaceID); |
| 310 } |
| 311 |
| 312 TEST_F(AVDACodecAllocatorTest, WaitersAreRemovedIfTheyDeallocate) { |
| 313 allocator2_->AllocateSurface(avda1_, 1); |
| 314 allocator2_->AllocateSurface(avda2_, 1); |
| 315 allocator2_->DeallocateSurface(avda2_, 1); |
| 316 // avda2_ should should not receive a notification. |
| 317 EXPECT_CALL(*avda2_, OnSurfaceAvailable(_)).Times(0); |
| 318 allocator2_->DeallocateSurface(avda1_, 1); |
| 255 } | 319 } |
| 256 | 320 |
| 257 } // namespace media | 321 } // namespace media |
| OLD | NEW |