[go: nahoru, domu]

blob: 828b0fc67113e95f476f9afbf50f735558aecba7 [file] [log] [blame]
Avi Drissmand387f0922022-09-14 20:51:311// Copyright 2021 The Chromium Authors
Christopher Cameron746d2cd2021-06-25 04:42:132// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "media/video/renderable_gpu_memory_buffer_video_frame_pool.h"
6
Avi Drissmand70f89a2023-01-11 23:52:557#include "base/functional/callback_helpers.h"
Christopher Cameron746d2cd2021-06-25 04:42:138#include "base/memory/weak_ptr.h"
Ben Wagnerb1142562021-12-15 10:44:129#include "base/task/thread_pool.h"
10#include "base/test/bind.h"
Colin Blundelle62aefe2023-06-09 12:32:4811#include "base/test/scoped_feature_list.h"
Christopher Cameron746d2cd2021-06-25 04:42:1312#include "base/test/task_environment.h"
Colin Blundelle62aefe2023-06-09 12:32:4813#include "components/viz/common/resources/shared_image_format.h"
Mingjing Zhangbc0f0c72024-02-07 08:26:1814#include "components/viz/common/resources/shared_image_format_utils.h"
Mingjing Zhang38dff4f2024-01-08 21:08:2615#include "gpu/command_buffer/client/client_shared_image.h"
Colin Blundelle62aefe2023-06-09 12:32:4816#include "gpu/config/gpu_finch_features.h"
17#include "media/base/media_switches.h"
Christopher Cameron746d2cd2021-06-25 04:42:1318#include "media/base/video_frame.h"
19#include "media/video/fake_gpu_memory_buffer.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23using ::testing::_;
24
25namespace media {
26
27namespace {
28
29class FakeContext : public RenderableGpuMemoryBufferVideoFramePool::Context {
30 public:
31 FakeContext() : weak_factory_(this) {}
32 ~FakeContext() override = default;
33
34 std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
35 const gfx::Size& size,
36 gfx::BufferFormat format,
37 gfx::BufferUsage usage) override {
38 DoCreateGpuMemoryBuffer(size, format);
39 return std::make_unique<FakeGpuMemoryBuffer>(size, format);
40 }
Mingjing Zhang38dff4f2024-01-08 21:08:2641 scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
42 gfx::GpuMemoryBuffer* gpu_memory_buffer,
43 const viz::SharedImageFormat& si_format,
44 const gfx::ColorSpace& color_space,
45 GrSurfaceOrigin surface_origin,
46 SkAlphaType alpha_type,
47 uint32_t usage,
48 gpu::SyncToken& sync_token) override {
Colin Blundelle62aefe2023-06-09 12:32:4849 DoCreateSharedImage(si_format, gpu_memory_buffer->GetSize(), color_space,
50 surface_origin, alpha_type, usage,
51 gpu_memory_buffer->CloneHandle());
Mingjing Zhang38dff4f2024-01-08 21:08:2652 return base::MakeRefCounted<gpu::ClientSharedImage>(
Mingjing Zhangbc0f0c72024-02-07 08:26:1853 gpu::Mailbox::GenerateForSharedImage(),
54 gpu::ClientSharedImage::Metadata(
55 si_format, gpu_memory_buffer->GetSize(), color_space,
56 surface_origin, alpha_type, usage),
Mingjing Zhang4baa91a2024-02-15 20:12:5957 sync_token, nullptr);
Colin Blundelle62aefe2023-06-09 12:32:4858 }
Mingjing Zhang38dff4f2024-01-08 21:08:2659 scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
60 gfx::GpuMemoryBuffer* gpu_memory_buffer,
61 gfx::BufferPlane plane,
62 const gfx::ColorSpace& color_space,
63 GrSurfaceOrigin surface_origin,
64 SkAlphaType alpha_type,
65 uint32_t usage,
66 gpu::SyncToken& sync_token) override {
Christopher Cameron746d2cd2021-06-25 04:42:1367 DoCreateSharedImage(gpu_memory_buffer, plane, color_space, surface_origin,
68 alpha_type, usage);
Mingjing Zhang38dff4f2024-01-08 21:08:2669 return base::MakeRefCounted<gpu::ClientSharedImage>(
Mingjing Zhangbc0f0c72024-02-07 08:26:1870 gpu::Mailbox::GenerateForSharedImage(),
71 gpu::ClientSharedImage::Metadata(viz::GetSinglePlaneSharedImageFormat(
72 gpu_memory_buffer->GetFormat()),
73 gpu_memory_buffer->GetSize(),
74 color_space, surface_origin,
75 alpha_type, usage),
Mingjing Zhang4baa91a2024-02-15 20:12:5976 sync_token, nullptr);
Christopher Cameron746d2cd2021-06-25 04:42:1377 }
78
79 MOCK_METHOD2(DoCreateGpuMemoryBuffer,
80 void(const gfx::Size& size, gfx::BufferFormat format));
Colin Blundelle62aefe2023-06-09 12:32:4881 MOCK_METHOD7(DoCreateSharedImage,
82 void(viz::SharedImageFormat format,
83 const gfx::Size& size,
84 const gfx::ColorSpace& color_space,
85 GrSurfaceOrigin surface_origin,
86 SkAlphaType alpha_type,
87 uint32_t usage,
88 gfx::GpuMemoryBufferHandle buffer_handle));
Christopher Cameron746d2cd2021-06-25 04:42:1389 MOCK_METHOD6(DoCreateSharedImage,
90 void(gfx::GpuMemoryBuffer* gpu_memory_buffer,
91 gfx::BufferPlane plane,
92 const gfx::ColorSpace& color_space,
93 GrSurfaceOrigin surface_origin,
94 SkAlphaType alpha_type,
95 uint32_t usage));
96 MOCK_METHOD2(DestroySharedImage,
97 void(const gpu::SyncToken& sync_token,
Mingjing Zhang38dff4f2024-01-08 21:08:2698 scoped_refptr<gpu::ClientSharedImage> shared_image));
Christopher Cameron746d2cd2021-06-25 04:42:1399
100 base::WeakPtr<FakeContext> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
101
102 private:
103 base::WeakPtrFactory<FakeContext> weak_factory_;
104};
105
Colin Blundelle62aefe2023-06-09 12:32:48106class RenderableGpuMemoryBufferVideoFramePoolTest
107 : public testing::TestWithParam<bool> {
108 public:
109 RenderableGpuMemoryBufferVideoFramePoolTest() {
110 if (GetParam()) {
111 scoped_feature_list_.InitWithFeatures(
Saifuddin Hitawala0fddfcf2023-10-06 19:02:12112 {kUseMultiPlaneFormatForHardwareVideo}, {});
Colin Blundelle62aefe2023-06-09 12:32:48113 } else {
114 scoped_feature_list_.InitWithFeatures(
Saifuddin Hitawala0fddfcf2023-10-06 19:02:12115 {}, {kUseMultiPlaneFormatForHardwareVideo});
Colin Blundelle62aefe2023-06-09 12:32:48116 }
117 }
118
119 protected:
120 void VerifySharedImageCreation(FakeContext* context) {
Colin Blundelle62aefe2023-06-09 12:32:48121 if (GetParam()) {
122 EXPECT_CALL(*context, DoCreateSharedImage(viz::MultiPlaneFormat::kNV12, _,
123 _, _, _, _, _));
124 return;
125 }
Colin Blundelle62aefe2023-06-09 12:32:48126 EXPECT_CALL(*context,
127 DoCreateSharedImage(_, gfx::BufferPlane::Y, _, _, _, _));
128 EXPECT_CALL(*context,
129 DoCreateSharedImage(_, gfx::BufferPlane::UV, _, _, _, _));
130 }
131
132 int NumSharedImagesPerFrame() {
Colin Blundelle62aefe2023-06-09 12:32:48133 if (GetParam()) {
134 return 1;
135 }
Colin Blundelle62aefe2023-06-09 12:32:48136 return 2;
137 }
138
139 base::test::ScopedFeatureList scoped_feature_list_;
140};
141
142TEST_P(RenderableGpuMemoryBufferVideoFramePoolTest, SimpleLifetimes) {
Christopher Cameron746d2cd2021-06-25 04:42:13143 base::test::SingleThreadTaskEnvironment task_environment;
144 const gfx::BufferFormat format = gfx::BufferFormat::YUV_420_BIPLANAR;
145 const gfx::Size size0(128, 256);
Christopher Cameronc59fe512021-10-19 23:06:54146 const gfx::ColorSpace color_space0 = gfx::ColorSpace::CreateREC709();
Christopher Cameron746d2cd2021-06-25 04:42:13147
148 base::WeakPtr<FakeContext> context;
149 std::unique_ptr<RenderableGpuMemoryBufferVideoFramePool> pool;
150 {
151 auto context_strong = std::make_unique<FakeContext>();
152 context = context_strong->GetWeakPtr();
153 pool = RenderableGpuMemoryBufferVideoFramePool::Create(
154 std::move(context_strong));
155 }
156
157 // Create a new frame.
158 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format));
Colin Blundelle62aefe2023-06-09 12:32:48159 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54160 auto video_frame0 = pool->MaybeCreateVideoFrame(size0, color_space0);
Christopher Cameron746d2cd2021-06-25 04:42:13161 video_frame0 = nullptr;
162 task_environment.RunUntilIdle();
163
164 // Expect the frame to be reused.
165 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format)).Times(0);
166 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _)).Times(0);
Colin Blundelle62aefe2023-06-09 12:32:48167 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _, _)).Times(0);
Christopher Cameronc59fe512021-10-19 23:06:54168 auto video_frame1 = pool->MaybeCreateVideoFrame(size0, color_space0);
Christopher Cameron746d2cd2021-06-25 04:42:13169
170 // Expect a new frame to be created.
171 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format));
Colin Blundelle62aefe2023-06-09 12:32:48172 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54173 auto video_frame2 = pool->MaybeCreateVideoFrame(size0, color_space0);
Christopher Cameron746d2cd2021-06-25 04:42:13174
175 // Expect a new frame to be created.
176 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format));
Colin Blundelle62aefe2023-06-09 12:32:48177 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54178 auto video_frame3 = pool->MaybeCreateVideoFrame(size0, color_space0);
Christopher Cameron746d2cd2021-06-25 04:42:13179
180 // Freeing two frames will not result in any frames being destroyed, because
181 // we allow unused 2 frames to exist.
182 video_frame1 = nullptr;
183 video_frame2 = nullptr;
184 task_environment.RunUntilIdle();
185
186 // Freeing the third frame will result in one of the frames being destroyed.
Colin Blundelle62aefe2023-06-09 12:32:48187 EXPECT_CALL(*context, DestroySharedImage(_, _))
188 .Times(NumSharedImagesPerFrame());
Christopher Cameron746d2cd2021-06-25 04:42:13189 video_frame3 = nullptr;
190 task_environment.RunUntilIdle();
191
192 // Destroying the pool will result in the remaining two frames being
193 // destroyed.
194 EXPECT_TRUE(!!context);
Colin Blundelle62aefe2023-06-09 12:32:48195 EXPECT_CALL(*context, DestroySharedImage(_, _))
196 .Times(NumSharedImagesPerFrame() * 2);
Christopher Cameron746d2cd2021-06-25 04:42:13197 pool.reset();
198 task_environment.RunUntilIdle();
199 EXPECT_FALSE(!!context);
200}
201
Colin Blundelle62aefe2023-06-09 12:32:48202TEST_P(RenderableGpuMemoryBufferVideoFramePoolTest, FrameFreedAfterPool) {
Christopher Cameron746d2cd2021-06-25 04:42:13203 base::test::SingleThreadTaskEnvironment task_environment;
204 const gfx::BufferFormat format = gfx::BufferFormat::YUV_420_BIPLANAR;
205 const gfx::Size size0(128, 256);
Christopher Cameronc59fe512021-10-19 23:06:54206 const gfx::ColorSpace color_space0 = gfx::ColorSpace::CreateREC709();
Christopher Cameron746d2cd2021-06-25 04:42:13207
208 base::WeakPtr<FakeContext> context;
209 std::unique_ptr<RenderableGpuMemoryBufferVideoFramePool> pool;
210 {
211 auto context_strong = std::make_unique<FakeContext>();
212 context = context_strong->GetWeakPtr();
213 pool = RenderableGpuMemoryBufferVideoFramePool::Create(
214 std::move(context_strong));
215 }
216
217 // Create a new frame.
218 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format));
Colin Blundelle62aefe2023-06-09 12:32:48219 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54220 auto video_frame0 = pool->MaybeCreateVideoFrame(size0, color_space0);
Christopher Cameron746d2cd2021-06-25 04:42:13221 task_environment.RunUntilIdle();
222
223 // If the pool is destroyed, but a frame still exists, the context will not
224 // be destroyed.
225 pool.reset();
226 task_environment.RunUntilIdle();
227 EXPECT_TRUE(context);
228
229 // Destroy the frame. Still nothing will happen, because its destruction will
230 // happen after a posted task is run.
231 video_frame0 = nullptr;
232
233 // The shared images will be destroyed once the posted task is run.
Colin Blundelle62aefe2023-06-09 12:32:48234 EXPECT_CALL(*context, DestroySharedImage(_, _))
235 .Times(NumSharedImagesPerFrame());
Christopher Cameron746d2cd2021-06-25 04:42:13236 task_environment.RunUntilIdle();
237 EXPECT_FALSE(!!context);
238}
239
Colin Blundelle62aefe2023-06-09 12:32:48240TEST_P(RenderableGpuMemoryBufferVideoFramePoolTest, CrossThread) {
Ben Wagnerb1142562021-12-15 10:44:12241 base::test::TaskEnvironment task_environment{
242 base::test::TaskEnvironment::TimeSource::MOCK_TIME};
243 const gfx::Size size0(128, 256);
244 const gfx::ColorSpace color_space0 = gfx::ColorSpace::CreateREC709();
245
246 // Create a pool on the main thread.
247 auto pool = RenderableGpuMemoryBufferVideoFramePool::Create(
248 std::make_unique<FakeContext>());
249
250 base::ThreadPool::CreateSequencedTaskRunner({})->PostTaskAndReplyWithResult(
251 FROM_HERE,
252 // Create a frame on another thread.
253 base::BindLambdaForTesting(
254 [&]() { return pool->MaybeCreateVideoFrame(size0, color_space0); }),
255 // Destroy the video frame on the main thread.
256 base::BindLambdaForTesting(
257 [&](scoped_refptr<VideoFrame> video_frame0) {}));
258 task_environment.RunUntilIdle();
259
260 // Destroy the pool.
261 pool = nullptr;
262 task_environment.RunUntilIdle();
263}
264
Colin Blundelle62aefe2023-06-09 12:32:48265TEST_P(RenderableGpuMemoryBufferVideoFramePoolTest,
266 VideoFramesDestroyedConcurrently) {
Ben Wagnerbe1f0472021-12-15 10:52:08267 base::test::TaskEnvironment task_environment{
268 base::test::TaskEnvironment::TimeSource::MOCK_TIME};
269 const gfx::BufferFormat format = gfx::BufferFormat::YUV_420_BIPLANAR;
270 const gfx::Size size0(128, 256);
271 const gfx::ColorSpace color_space0 = gfx::ColorSpace::CreateREC709();
272
273 // Create a pool and several frames on the main thread.
274 base::WeakPtr<FakeContext> context;
275 std::unique_ptr<RenderableGpuMemoryBufferVideoFramePool> pool;
276 {
277 auto context_strong = std::make_unique<FakeContext>();
278 context = context_strong->GetWeakPtr();
279 pool = RenderableGpuMemoryBufferVideoFramePool::Create(
280 std::move(context_strong));
281 }
282
283 std::vector<scoped_refptr<VideoFrame>> frames;
284 static constexpr int kNumFrames = 3;
285 for (int i = 0; i < kNumFrames; i++) {
286 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format));
Colin Blundelle62aefe2023-06-09 12:32:48287 VerifySharedImageCreation(context.get());
Ben Wagnerbe1f0472021-12-15 10:52:08288 frames.emplace_back(pool->MaybeCreateVideoFrame(size0, color_space0));
289 }
290 task_environment.RunUntilIdle();
291
292 // Expect all frames to be destroyed eventually.
Colin Blundelle62aefe2023-06-09 12:32:48293 EXPECT_CALL(*context, DestroySharedImage(_, _))
294 .Times(kNumFrames * NumSharedImagesPerFrame());
Ben Wagnerbe1f0472021-12-15 10:52:08295
296 // Destroy frames on separate threads. TSAN will tell us if there's a problem.
297 for (int i = 0; i < kNumFrames; i++) {
298 base::ThreadPool::CreateSequencedTaskRunner({})->PostTask(
Paul Semel4c1e3e82022-10-24 09:20:54299 FROM_HERE, base::DoNothingWithBoundArgs(std::move(frames[i])));
Ben Wagnerbe1f0472021-12-15 10:52:08300 }
301
302 pool.reset();
303 task_environment.RunUntilIdle();
304 EXPECT_FALSE(!!context);
305}
306
Colin Blundelle62aefe2023-06-09 12:32:48307TEST_P(RenderableGpuMemoryBufferVideoFramePoolTest, ConcurrentCreateDestroy) {
Ben Wagnerbe1f0472021-12-15 10:52:08308 base::test::TaskEnvironment task_environment{
309 base::test::TaskEnvironment::TimeSource::MOCK_TIME};
310 const gfx::Size size0(128, 256);
311 const gfx::ColorSpace color_space0 = gfx::ColorSpace::CreateREC709();
312
313 // Create a pool on the main thread.
314 auto pool = RenderableGpuMemoryBufferVideoFramePool::Create(
315 std::make_unique<FakeContext>());
316
317 // Create a frame on the main thread.
318 auto video_frame0 = pool->MaybeCreateVideoFrame(size0, color_space0);
319 task_environment.RunUntilIdle();
320
321 // Destroy the frame on another thread. TSAN will tell us if there's a
322 // problem.
323 base::ThreadPool::CreateSequencedTaskRunner({})->PostTask(
Paul Semel4c1e3e82022-10-24 09:20:54324 FROM_HERE, base::DoNothingWithBoundArgs(std::move(video_frame0)));
Ben Wagnerbe1f0472021-12-15 10:52:08325
326 // Create another frame on the main thread.
327 auto video_frame1 = pool->MaybeCreateVideoFrame(size0, color_space0);
328 task_environment.RunUntilIdle();
329
330 video_frame1 = nullptr;
331 pool.reset();
332 task_environment.RunUntilIdle();
333}
334
Colin Blundelle62aefe2023-06-09 12:32:48335TEST_P(RenderableGpuMemoryBufferVideoFramePoolTest, RespectSizeAndColorSpace) {
Christopher Cameronc59fe512021-10-19 23:06:54336 base::test::SingleThreadTaskEnvironment task_environment;
337 const gfx::BufferFormat format = gfx::BufferFormat::YUV_420_BIPLANAR;
338 const gfx::Size size0(128, 256);
339 const gfx::ColorSpace color_space0 = gfx::ColorSpace::CreateREC709();
340 const gfx::Size size1(256, 256);
341 const gfx::ColorSpace color_space1 = gfx::ColorSpace::CreateREC601();
342
343 base::WeakPtr<FakeContext> context;
344 std::unique_ptr<RenderableGpuMemoryBufferVideoFramePool> pool;
345 {
346 auto context_strong = std::make_unique<FakeContext>();
347 context = context_strong->GetWeakPtr();
348 pool = RenderableGpuMemoryBufferVideoFramePool::Create(
349 std::move(context_strong));
350 }
351
352 // Create a new frame.
353 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size0, format)).Times(1);
Colin Blundelle62aefe2023-06-09 12:32:48354 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54355 auto video_frame0 = pool->MaybeCreateVideoFrame(size0, color_space0);
356 video_frame0 = nullptr;
357 task_environment.RunUntilIdle();
358
359 // Expect the frame to be reused.
360 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(_, _)).Times(0);
361 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _)).Times(0);
Colin Blundelle62aefe2023-06-09 12:32:48362 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _, _)).Times(0);
Christopher Cameronc59fe512021-10-19 23:06:54363 video_frame0 = pool->MaybeCreateVideoFrame(size0, color_space0);
364 video_frame0 = nullptr;
365 task_environment.RunUntilIdle();
366
367 // Change the size, expect a new frame to be created (and the previous frame
368 // to be destroyed).
Colin Blundelle62aefe2023-06-09 12:32:48369 EXPECT_CALL(*context, DestroySharedImage(_, _))
370 .Times(NumSharedImagesPerFrame());
Christopher Cameronc59fe512021-10-19 23:06:54371 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size1, format));
Colin Blundelle62aefe2023-06-09 12:32:48372 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54373 video_frame0 = pool->MaybeCreateVideoFrame(size1, color_space0);
374 video_frame0 = nullptr;
375 task_environment.RunUntilIdle();
376
377 // Expect that frame to be reused.
378 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(_, _)).Times(0);
379 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _)).Times(0);
Colin Blundelle62aefe2023-06-09 12:32:48380 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _, _)).Times(0);
Christopher Cameronc59fe512021-10-19 23:06:54381 video_frame0 = pool->MaybeCreateVideoFrame(size1, color_space0);
382 video_frame0 = nullptr;
383 task_environment.RunUntilIdle();
384
385 // Change the color space, expect a new frame to be created (and the previous
386 // frame to be destroyed).
Colin Blundelle62aefe2023-06-09 12:32:48387 EXPECT_CALL(*context, DestroySharedImage(_, _))
388 .Times(NumSharedImagesPerFrame());
Christopher Cameronc59fe512021-10-19 23:06:54389 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(size1, format));
Colin Blundelle62aefe2023-06-09 12:32:48390 VerifySharedImageCreation(context.get());
Christopher Cameronc59fe512021-10-19 23:06:54391 video_frame0 = pool->MaybeCreateVideoFrame(size1, color_space1);
392 video_frame0 = nullptr;
393 task_environment.RunUntilIdle();
394
395 // Expect that frame to be reused.
396 EXPECT_CALL(*context, DoCreateGpuMemoryBuffer(_, _)).Times(0);
397 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _)).Times(0);
Colin Blundelle62aefe2023-06-09 12:32:48398 EXPECT_CALL(*context, DoCreateSharedImage(_, _, _, _, _, _, _)).Times(0);
Christopher Cameronc59fe512021-10-19 23:06:54399 video_frame0 = pool->MaybeCreateVideoFrame(size1, color_space1);
400 video_frame0 = nullptr;
401 task_environment.RunUntilIdle();
402
Colin Blundelle62aefe2023-06-09 12:32:48403 EXPECT_CALL(*context, DestroySharedImage(_, _))
404 .Times(NumSharedImagesPerFrame());
Christopher Cameronc59fe512021-10-19 23:06:54405 pool.reset();
406 task_environment.RunUntilIdle();
407 EXPECT_FALSE(!!context);
408}
409
Colin Blundelle62aefe2023-06-09 12:32:48410INSTANTIATE_TEST_SUITE_P(All,
411 RenderableGpuMemoryBufferVideoFramePoolTest,
412 testing::Bool());
413
Christopher Cameron746d2cd2021-06-25 04:42:13414} // namespace
415
416} // namespace media