Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: media/gpu/avda_codec_allocator_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698