Upload upstream chromium 120.0.6099.5
[platform/framework/web/chromium-efl.git] / media / renderers / video_resource_updater_unittest.cc
1 // Copyright 2013 The Chromium Authors
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 "media/renderers/video_resource_updater.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include "base/functional/bind.h"
11 #include "base/memory/raw_ptr.h"
12 #include "base/memory/read_only_shared_memory_region.h"
13 #include "base/test/task_environment.h"
14 #include "components/viz/client/client_resource_provider.h"
15 #include "components/viz/client/shared_bitmap_reporter.h"
16 #include "components/viz/common/quads/compositor_render_pass.h"
17 #include "components/viz/common/quads/texture_draw_quad.h"
18 #include "components/viz/common/resources/shared_image_format.h"
19 #include "components/viz/test/fake_output_surface.h"
20 #include "components/viz/test/test_gles2_interface.h"
21 #include "gpu/GLES2/gl2extchromium.h"
22 #include "gpu/command_buffer/common/mailbox.h"
23 #include "media/base/video_frame.h"
24 #include "skia/ext/skcolorspace_primaries.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace media {
28 namespace {
29
30 class FakeSharedBitmapReporter : public viz::SharedBitmapReporter {
31  public:
32   FakeSharedBitmapReporter() = default;
33   ~FakeSharedBitmapReporter() override = default;
34
35   // viz::SharedBitmapReporter implementation.
36   void DidAllocateSharedBitmap(base::ReadOnlySharedMemoryRegion region,
37                                const viz::SharedBitmapId& id) override {
38     DCHECK_EQ(shared_bitmaps_.count(id), 0u);
39     shared_bitmaps_.insert(id);
40   }
41   void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override {
42     DCHECK_EQ(shared_bitmaps_.count(id), 1u);
43     shared_bitmaps_.erase(id);
44   }
45
46   const base::flat_set<viz::SharedBitmapId> shared_bitmaps() const {
47     return shared_bitmaps_;
48   }
49
50  private:
51   base::flat_set<viz::SharedBitmapId> shared_bitmaps_;
52 };
53
54 class UploadCounterGLES2Interface : public viz::TestGLES2Interface {
55  public:
56   void TexSubImage2D(GLenum target,
57                      GLint level,
58                      GLint xoffset,
59                      GLint yoffset,
60                      GLsizei width,
61                      GLsizei height,
62                      GLenum format,
63                      GLenum type,
64                      const void* pixels) override {
65     ++upload_count_;
66     last_upload_ = reinterpret_cast<const uint8_t*>(pixels);
67   }
68
69   int UploadCount() { return upload_count_; }
70   void ResetUploadCount() { upload_count_ = 0; }
71   const uint8_t* last_upload() const { return last_upload_; }
72
73  private:
74   int upload_count_;
75   const uint8_t* last_upload_ = nullptr;
76 };
77
78 class VideoResourceUpdaterTest : public testing::Test {
79  protected:
80   VideoResourceUpdaterTest() {
81     auto gl = std::make_unique<UploadCounterGLES2Interface>();
82
83     gl_ = gl.get();
84
85     context_provider_ = viz::TestContextProvider::Create(std::move(gl));
86     context_provider_->BindToCurrentSequence();
87   }
88
89   // testing::Test implementation.
90   void SetUp() override {
91     testing::Test::SetUp();
92     resource_provider_ = std::make_unique<viz::ClientResourceProvider>();
93   }
94
95   std::unique_ptr<VideoResourceUpdater> CreateUpdaterForHardware(
96       bool use_stream_video_draw_quad = false) {
97     return std::make_unique<VideoResourceUpdater>(
98         context_provider_.get(), nullptr, resource_provider_.get(),
99         use_stream_video_draw_quad, /*use_gpu_memory_buffer_resources=*/false,
100         /*max_resource_size=*/10000);
101   }
102
103   std::unique_ptr<VideoResourceUpdater> CreateUpdaterForSoftware() {
104     return std::make_unique<VideoResourceUpdater>(
105         /*context_provider=*/nullptr, &shared_bitmap_reporter_,
106         resource_provider_.get(), /*use_stream_video_draw_quad=*/false,
107         /*use_gpu_memory_buffer_resources=*/false, /*max_resource_size=*/10000);
108   }
109
110   // Note that the number of pixels needed for |size| must be less than or equal
111   // to the number of pixels needed for size of 100x100.
112   scoped_refptr<VideoFrame> CreateTestYUVVideoFrame(
113       const gfx::Size& size = gfx::Size(10, 10)) {
114     constexpr int kMaxDimension = 100;
115     static uint8_t y_data[kMaxDimension * kMaxDimension] = {0};
116     static uint8_t u_data[kMaxDimension * kMaxDimension / 2] = {0};
117     static uint8_t v_data[kMaxDimension * kMaxDimension / 2] = {0};
118
119     CHECK_LE(size.width() * size.height(), kMaxDimension * kMaxDimension);
120
121     scoped_refptr<VideoFrame> video_frame =
122         VideoFrame::WrapExternalYuvData(PIXEL_FORMAT_I422,   // format
123                                         size,                // coded_size
124                                         gfx::Rect(size),     // visible_rect
125                                         size,                // natural_size
126                                         size.width(),        // y_stride
127                                         size.width() / 2,    // u_stride
128                                         size.width() / 2,    // v_stride
129                                         y_data,              // y_data
130                                         u_data,              // u_data
131                                         v_data,              // v_data
132                                         base::TimeDelta());  // timestamp
133     EXPECT_TRUE(video_frame);
134     return video_frame;
135   }
136
137   scoped_refptr<VideoFrame> CreateWonkyTestYUVVideoFrame() {
138     const int kDimension = 10;
139     const int kYWidth = kDimension + 5;
140     const int kUWidth = (kYWidth + 1) / 2 + 200;
141     const int kVWidth = (kYWidth + 1) / 2 + 1;
142     static uint8_t y_data[kYWidth * kDimension] = {0};
143     static uint8_t u_data[kUWidth * kDimension] = {0};
144     static uint8_t v_data[kVWidth * kDimension] = {0};
145
146     scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalYuvData(
147         PIXEL_FORMAT_I422,                        // format
148         gfx::Size(kYWidth, kDimension),           // coded_size
149         gfx::Rect(2, 0, kDimension, kDimension),  // visible_rect
150         gfx::Size(kDimension, kDimension),        // natural_size
151         -kYWidth,                                 // y_stride (negative)
152         kUWidth,                                  // u_stride
153         kVWidth,                                  // v_stride
154         y_data + kYWidth * (kDimension - 1),      // y_data
155         u_data,                                   // u_data
156         v_data,                                   // v_data
157         base::TimeDelta());                       // timestamp
158     EXPECT_TRUE(video_frame);
159     return video_frame;
160   }
161
162   scoped_refptr<VideoFrame> CreateTestRGBVideoFrame(VideoPixelFormat format) {
163     constexpr int kMaxDimension = 10;
164     constexpr gfx::Size kSize = gfx::Size(kMaxDimension, kMaxDimension);
165     static uint32_t rgb_data[kMaxDimension * kMaxDimension] = {0};
166     scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalData(
167         format,                                // format
168         kSize,                                 // coded_size
169         gfx::Rect(kSize),                      // visible_rect
170         kSize,                                 // natural_size
171         reinterpret_cast<uint8_t*>(rgb_data),  // data,
172         sizeof(rgb_data),                      // data_size
173         base::TimeDelta());                    // timestamp
174     EXPECT_TRUE(video_frame);
175     return video_frame;
176   }
177
178   scoped_refptr<VideoFrame> CreateTestRGBVideoFrameWithVisibleRect(
179       VideoPixelFormat format) {
180     constexpr int kMaxDimension = 5;
181     constexpr gfx::Size kSize = gfx::Size(kMaxDimension, kMaxDimension);
182     constexpr gfx::Rect kVisibleRect = gfx::Rect(2, 1, 3, 3);
183     constexpr uint32_t kPix = 0xFFFFFFFF;
184     static uint32_t rgb_data[kMaxDimension * kMaxDimension] = {
185         0x00, 0x00, 0x00, 0x00, 0x00,  //
186         0x00, 0x00, kPix, kPix, kPix,  //
187         0x00, 0x00, kPix, kPix, kPix,  //
188         0x00, 0x00, kPix, kPix, kPix,  //
189         0x00, 0x00, 0x00, 0x00, 0x00,  //
190     };
191
192     scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalData(
193         format,                                // format
194         kSize,                                 // coded_size
195         kVisibleRect,                          // visible_rect
196         kVisibleRect.size(),                   // natural_size
197         reinterpret_cast<uint8_t*>(rgb_data),  // data,
198         sizeof(rgb_data),                      // data_size
199         base::TimeDelta());                    // timestamp
200     EXPECT_TRUE(video_frame);
201     return video_frame;
202   }
203
204   scoped_refptr<VideoFrame> CreateTestY16VideoFrameWithVisibleRect() {
205     constexpr int kMaxDimension = 5;
206     constexpr gfx::Size kSize = gfx::Size(kMaxDimension, kMaxDimension);
207     constexpr gfx::Rect kVisibleRect = gfx::Rect(2, 1, 3, 3);
208     constexpr uint16_t kPix = 0xFFFF;
209     static uint16_t y16_data[kMaxDimension * kMaxDimension] = {
210         0x00, 0x00, 0x00, 0x00, 0x00,  //
211         0x00, 0x00, kPix, kPix, kPix,  //
212         0x00, 0x00, kPix, kPix, kPix,  //
213         0x00, 0x00, kPix, kPix, kPix,  //
214         0x00, 0x00, 0x00, 0x00, 0x00,  //
215     };
216
217     scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapExternalData(
218         PIXEL_FORMAT_Y16,
219         kSize,                                 // coded_size
220         kVisibleRect,                          // visible_rect
221         kVisibleRect.size(),                   // natural_size
222         reinterpret_cast<uint8_t*>(y16_data),  // data,
223         sizeof(y16_data),                      // data_size
224         base::TimeDelta());                    // timestamp
225     EXPECT_TRUE(video_frame);
226     return video_frame;
227   }
228
229   scoped_refptr<VideoFrame> CreateTestHighBitFrame() {
230     const int kDimension = 10;
231     gfx::Size size(kDimension, kDimension);
232
233     scoped_refptr<VideoFrame> video_frame(
234         VideoFrame::CreateFrame(PIXEL_FORMAT_YUV420P10, size, gfx::Rect(size),
235                                 size, base::TimeDelta()));
236     EXPECT_TRUE(video_frame);
237     return video_frame;
238   }
239
240   scoped_refptr<VideoFrame> CreateNV12TestFrame() {
241     const int kDimension = 10;
242     gfx::Size size(kDimension, kDimension);
243
244     scoped_refptr<VideoFrame> video_frame(VideoFrame::CreateFrame(
245         PIXEL_FORMAT_NV12, size, gfx::Rect(size), size, base::TimeDelta()));
246     EXPECT_TRUE(video_frame);
247     return video_frame;
248   }
249
250   scoped_refptr<VideoFrame> CreateP016TestFrame() {
251     const int kDimension = 10;
252     gfx::Size size(kDimension, kDimension);
253
254     scoped_refptr<VideoFrame> video_frame(VideoFrame::CreateFrame(
255         PIXEL_FORMAT_P016LE, size, gfx::Rect(size), size, base::TimeDelta()));
256     EXPECT_TRUE(video_frame);
257     return video_frame;
258   }
259
260   void SetReleaseSyncToken(const gpu::SyncToken& sync_token) {
261     release_sync_token_ = sync_token;
262   }
263
264   scoped_refptr<VideoFrame> CreateTestHardwareVideoFrame(
265       VideoPixelFormat format,
266       unsigned target) {
267     const int kDimension = 10;
268     gfx::Size size(kDimension, kDimension);
269
270     auto mailbox = gpu::Mailbox::GenerateForSharedImage();
271
272     gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes] = {
273         gpu::MailboxHolder(mailbox, kMailboxSyncToken, target)};
274     scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapNativeTextures(
275         format, mailbox_holders,
276         base::BindOnce(&VideoResourceUpdaterTest::SetReleaseSyncToken,
277                        base::Unretained(this)),
278         size,                // coded_size
279         gfx::Rect(size),     // visible_rect
280         size,                // natural_size
281         base::TimeDelta());  // timestamp
282     EXPECT_TRUE(video_frame);
283     return video_frame;
284   }
285
286   scoped_refptr<VideoFrame> CreateTestRGBAHardwareVideoFrame() {
287     return CreateTestHardwareVideoFrame(PIXEL_FORMAT_ARGB, GL_TEXTURE_2D);
288   }
289
290   scoped_refptr<VideoFrame> CreateTestStreamTextureHardwareVideoFrame(
291       bool needs_copy) {
292     scoped_refptr<VideoFrame> video_frame = CreateTestHardwareVideoFrame(
293         PIXEL_FORMAT_ARGB, GL_TEXTURE_EXTERNAL_OES);
294     video_frame->metadata().copy_required = needs_copy;
295     return video_frame;
296   }
297
298 #if BUILDFLAG(IS_WIN)
299   scoped_refptr<VideoFrame> CreateTestDCompSurfaceVideoFrame() {
300     scoped_refptr<VideoFrame> video_frame = CreateTestHardwareVideoFrame(
301         PIXEL_FORMAT_ARGB, GL_TEXTURE_EXTERNAL_OES);
302     video_frame->metadata().dcomp_surface = true;
303     return video_frame;
304   }
305 #endif
306
307   scoped_refptr<VideoFrame> CreateTestYuvHardwareVideoFrame(
308       VideoPixelFormat format,
309       size_t num_textures,
310       unsigned target) {
311     const int kDimension = 10;
312     gfx::Size size(kDimension, kDimension);
313
314     gpu::MailboxHolder mailbox_holders[VideoFrame::kMaxPlanes];
315     for (size_t i = 0; i < num_textures; ++i) {
316       gpu::Mailbox mailbox;
317       mailbox.name[0] = 50 + 1;
318       mailbox_holders[i] =
319           gpu::MailboxHolder(mailbox, kMailboxSyncToken, target);
320     }
321     scoped_refptr<VideoFrame> video_frame = VideoFrame::WrapNativeTextures(
322         format, mailbox_holders,
323         base::BindOnce(&VideoResourceUpdaterTest::SetReleaseSyncToken,
324                        base::Unretained(this)),
325         size,                // coded_size
326         gfx::Rect(size),     // visible_rect
327         size,                // natural_size
328         base::TimeDelta());  // timestamp
329     EXPECT_TRUE(video_frame);
330     return video_frame;
331   }
332
333   size_t GetSharedImageCount() {
334     return context_provider_->SharedImageInterface()->shared_image_count();
335   }
336
337   static const gpu::SyncToken kMailboxSyncToken;
338
339   // VideoResourceUpdater registers as a MemoryDumpProvider, which requires
340   // a TaskRunner.
341   base::test::SingleThreadTaskEnvironment task_environment_;
342   raw_ptr<UploadCounterGLES2Interface, DanglingUntriaged> gl_;
343   scoped_refptr<viz::TestContextProvider> context_provider_;
344   FakeSharedBitmapReporter shared_bitmap_reporter_;
345   std::unique_ptr<viz::ClientResourceProvider> resource_provider_;
346   gpu::SyncToken release_sync_token_;
347 };
348
349 const gpu::SyncToken VideoResourceUpdaterTest::kMailboxSyncToken =
350     gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
351                    gpu::CommandBufferId::FromUnsafeValue(0x123),
352                    7);
353
354 TEST_F(VideoResourceUpdaterTest, SoftwareFrame) {
355   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
356   scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame();
357
358   VideoFrameExternalResources resources =
359       updater->CreateExternalResourcesFromVideoFrame(video_frame);
360   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
361
362   // Setting to kSharedImageFormat, resources type should not change.
363   video_frame->set_shared_image_format_type(
364       SharedImageFormatType::kSharedImageFormat);
365   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
366   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
367 }
368
369 TEST_F(VideoResourceUpdaterTest, SoftwareFrameNV12) {
370   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
371
372   VideoFrameExternalResources resources =
373       updater->CreateExternalResourcesFromVideoFrame(CreateNV12TestFrame());
374   EXPECT_EQ(VideoFrameResourceType::RGBA, resources.type);
375
376   // Use a different frame for this test since frames with the same unique_id()
377   // expect to use the same resources.
378   scoped_refptr<VideoFrame> video_frame = CreateNV12TestFrame();
379   gl_->set_supports_texture_rg(true);
380   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
381   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
382
383   // Setting to kSharedImageFormat, resources type should not change.
384   video_frame->set_shared_image_format_type(
385       SharedImageFormatType::kSharedImageFormat);
386   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
387   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
388 }
389
390 TEST_F(VideoResourceUpdaterTest, SoftwareFrameP016_NoR16Support) {
391   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
392
393   VideoFrameExternalResources resources =
394       updater->CreateExternalResourcesFromVideoFrame(CreateP016TestFrame());
395   EXPECT_EQ(VideoFrameResourceType::RGBA, resources.type);
396 }
397
398 // Ensure we end up with the right SharedImageFormat for each resource.
399 TEST_F(VideoResourceUpdaterTest, SoftwareFrameRGB) {
400   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
401   for (const auto& fmt : {PIXEL_FORMAT_XBGR, PIXEL_FORMAT_XRGB,
402                           PIXEL_FORMAT_ABGR, PIXEL_FORMAT_ARGB}) {
403     scoped_refptr<VideoFrame> video_frame = CreateTestRGBVideoFrame(fmt);
404     VideoFrameExternalResources resources =
405         updater->CreateExternalResourcesFromVideoFrame(video_frame);
406     EXPECT_EQ(VideoFrameResourceType::RGBA, resources.type);
407 #if BUILDFLAG(IS_MAC)
408     EXPECT_EQ(resources.resources[0].format,
409               viz::SinglePlaneFormat::kBGRA_8888);
410 #else
411     EXPECT_EQ(resources.resources[0].size, video_frame->coded_size());
412
413     if (fmt == PIXEL_FORMAT_XBGR) {
414       EXPECT_EQ(resources.resources[0].format,
415                 viz::SinglePlaneFormat::kRGBA_8888);
416     } else if (fmt == PIXEL_FORMAT_XRGB) {
417       EXPECT_EQ(resources.resources[0].format,
418                 viz::SinglePlaneFormat::kBGRA_8888);
419
420     } else if (fmt == PIXEL_FORMAT_ABGR) {
421       EXPECT_EQ(resources.resources[0].format,
422                 viz::SinglePlaneFormat::kRGBA_8888);
423
424     } else if (fmt == PIXEL_FORMAT_ARGB) {
425       EXPECT_EQ(resources.resources[0].format,
426                 viz::SinglePlaneFormat::kBGRA_8888);
427     }
428 #endif
429   }
430 }
431
432 // Ensure the visible data is where it's supposed to be.
433 TEST_F(VideoResourceUpdaterTest, SoftwareFrameRGBNonOrigin) {
434   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
435   for (const auto& fmt : {PIXEL_FORMAT_XBGR, PIXEL_FORMAT_XRGB,
436                           PIXEL_FORMAT_ABGR, PIXEL_FORMAT_ARGB}) {
437     auto video_frame = CreateTestRGBVideoFrameWithVisibleRect(fmt);
438     VideoFrameExternalResources resources =
439         updater->CreateExternalResourcesFromVideoFrame(video_frame);
440     EXPECT_EQ(VideoFrameResourceType::RGBA, resources.type);
441     EXPECT_EQ(resources.resources[0].size, video_frame->coded_size());
442
443     auto rect = video_frame->visible_rect();
444
445     const auto bytes_per_row = video_frame->row_bytes(VideoFrame::kARGBPlane);
446     const auto bytes_per_element =
447         VideoFrame::BytesPerElement(fmt, VideoFrame::kARGBPlane);
448     auto* dest_pixels = gl_->last_upload() + rect.y() * bytes_per_row +
449                         rect.x() * bytes_per_element;
450     auto* src_pixels = video_frame->visible_data(VideoFrame::kARGBPlane);
451
452     // Pixels are 0xFFFFFFFF, so channel reordering doesn't matter.
453     for (int y = 0; y < rect.height(); ++y) {
454       for (int x = 0; x < rect.width() * bytes_per_element; ++x) {
455         const auto pos = y * bytes_per_row + x;
456         ASSERT_EQ(src_pixels[pos], dest_pixels[pos]);
457       }
458     }
459   }
460 }
461
462 // Ensure the visible data is where it's supposed to be.
463 TEST_F(VideoResourceUpdaterTest, SoftwareFrameY16NonOrigin) {
464   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
465
466   auto video_frame = CreateTestY16VideoFrameWithVisibleRect();
467   VideoFrameExternalResources resources =
468       updater->CreateExternalResourcesFromVideoFrame(video_frame);
469   EXPECT_EQ(VideoFrameResourceType::RGBA, resources.type);
470   EXPECT_EQ(resources.resources[0].size, video_frame->coded_size());
471
472   auto rect = video_frame->visible_rect();
473
474   // Just used for sizing information, channel order doesn't matter.
475   constexpr auto kOutputFormat = PIXEL_FORMAT_ARGB;
476
477   const auto bytes_per_row = VideoFrame::RowBytes(
478       VideoFrame::kARGBPlane, kOutputFormat, video_frame->coded_size().width());
479   const auto bytes_per_element =
480       VideoFrame::BytesPerElement(kOutputFormat, VideoFrame::kARGBPlane);
481   auto* dest_pixels = gl_->last_upload() + rect.y() * bytes_per_row +
482                       rect.x() * bytes_per_element;
483
484   // Pixels are 0xFFFFFFFF, so channel reordering doesn't matter.
485   for (int y = 0; y < rect.height(); ++y) {
486     for (int x = 0; x < rect.width() * bytes_per_element; ++x) {
487       const auto pos = y * bytes_per_row + x;
488       ASSERT_EQ(0xFF, dest_pixels[pos]);
489     }
490   }
491 }
492
493 TEST_F(VideoResourceUpdaterTest, HighBitFrameNoF16) {
494   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
495   scoped_refptr<VideoFrame> video_frame = CreateTestHighBitFrame();
496
497   VideoFrameExternalResources resources =
498       updater->CreateExternalResourcesFromVideoFrame(video_frame);
499   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
500
501   // Setting to kSharedImageFormat, resources type should not change.
502   video_frame->set_shared_image_format_type(
503       SharedImageFormatType::kSharedImageFormat);
504   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
505   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
506 }
507
508 class VideoResourceUpdaterTestWithF16 : public VideoResourceUpdaterTest {
509  public:
510   VideoResourceUpdaterTestWithF16() : VideoResourceUpdaterTest() {
511     gl_->set_support_texture_half_float_linear(true);
512   }
513 };
514
515 TEST_F(VideoResourceUpdaterTestWithF16, HighBitFrame) {
516   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
517   scoped_refptr<VideoFrame> video_frame = CreateTestHighBitFrame();
518
519   VideoFrameExternalResources resources =
520       updater->CreateExternalResourcesFromVideoFrame(video_frame);
521   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
522   EXPECT_NEAR(resources.multiplier, 2.0, 0.1);
523   EXPECT_NEAR(resources.offset, 0.5, 0.1);
524
525   // Create the resource again, to test the path where the
526   // resources are cached.
527   VideoFrameExternalResources resources2 =
528       updater->CreateExternalResourcesFromVideoFrame(video_frame);
529   EXPECT_EQ(VideoFrameResourceType::YUV, resources2.type);
530   EXPECT_NEAR(resources2.multiplier, 2.0, 0.1);
531   EXPECT_NEAR(resources2.offset, 0.5, 0.1);
532 }
533
534 class VideoResourceUpdaterTestWithR16 : public VideoResourceUpdaterTest {
535  public:
536   VideoResourceUpdaterTestWithR16() : VideoResourceUpdaterTest() {
537     auto* sii = context_provider_->SharedImageInterface();
538     auto shared_image_caps = sii->GetCapabilities();
539     shared_image_caps.supports_r16_shared_images = true;
540     sii->SetCapabilities(shared_image_caps);
541
542     gl_->set_support_texture_norm16(true);
543   }
544 };
545
546 TEST_F(VideoResourceUpdaterTestWithR16, SoftwareFrameP016) {
547   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
548
549   VideoFrameExternalResources resources =
550       updater->CreateExternalResourcesFromVideoFrame(CreateP016TestFrame());
551   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
552 }
553
554 TEST_F(VideoResourceUpdaterTestWithR16, HighBitFrame) {
555   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
556   scoped_refptr<VideoFrame> video_frame = CreateTestHighBitFrame();
557
558   VideoFrameExternalResources resources =
559       updater->CreateExternalResourcesFromVideoFrame(video_frame);
560   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
561
562   // Max 10-bit values as read by a sampler.
563   double max_10bit_value = ((1 << 10) - 1) / 65535.0;
564   EXPECT_NEAR(resources.multiplier * max_10bit_value, 1.0, 0.0001);
565   EXPECT_NEAR(resources.offset, 0.0, 0.1);
566
567   // Create the resource again, to test the path where the
568   // resources are cached.
569   VideoFrameExternalResources resources2 =
570       updater->CreateExternalResourcesFromVideoFrame(video_frame);
571   EXPECT_EQ(VideoFrameResourceType::YUV, resources2.type);
572   EXPECT_NEAR(resources2.multiplier * max_10bit_value, 1.0, 0.0001);
573   EXPECT_NEAR(resources2.offset, 0.0, 0.1);
574 }
575
576 TEST_F(VideoResourceUpdaterTest, NV12FrameSoftwareCompositor) {
577   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
578   scoped_refptr<VideoFrame> video_frame = CreateNV12TestFrame();
579
580   VideoFrameExternalResources resources =
581       updater->CreateExternalResourcesFromVideoFrame(video_frame);
582   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
583 }
584
585 TEST_F(VideoResourceUpdaterTest, P016FrameSoftwareCompositor) {
586   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
587   scoped_refptr<VideoFrame> video_frame = CreateP016TestFrame();
588
589   VideoFrameExternalResources resources =
590       updater->CreateExternalResourcesFromVideoFrame(video_frame);
591   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
592 }
593
594 TEST_F(VideoResourceUpdaterTest, HighBitFrameSoftwareCompositor) {
595   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
596   scoped_refptr<VideoFrame> video_frame = CreateTestHighBitFrame();
597
598   VideoFrameExternalResources resources =
599       updater->CreateExternalResourcesFromVideoFrame(video_frame);
600   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
601 }
602
603 TEST_F(VideoResourceUpdaterTest, WonkySoftwareFrame) {
604   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
605   scoped_refptr<VideoFrame> video_frame = CreateWonkyTestYUVVideoFrame();
606
607   VideoFrameExternalResources resources =
608       updater->CreateExternalResourcesFromVideoFrame(video_frame);
609   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
610
611   // Setting to kSharedImageFormat, resources type should not change.
612   video_frame->set_shared_image_format_type(
613       SharedImageFormatType::kSharedImageFormat);
614   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
615   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
616 }
617
618 TEST_F(VideoResourceUpdaterTest, WonkySoftwareFrameSoftwareCompositor) {
619   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
620   scoped_refptr<VideoFrame> video_frame = CreateWonkyTestYUVVideoFrame();
621
622   VideoFrameExternalResources resources =
623       updater->CreateExternalResourcesFromVideoFrame(video_frame);
624   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
625 }
626
627 TEST_F(VideoResourceUpdaterTest, ReuseResource) {
628   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
629   scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame();
630   video_frame->set_timestamp(base::Seconds(1234));
631
632   // Allocate the resources for a YUV video frame.
633   gl_->ResetUploadCount();
634   VideoFrameExternalResources resources =
635       updater->CreateExternalResourcesFromVideoFrame(video_frame);
636   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
637   EXPECT_EQ(3u, resources.resources.size());
638   EXPECT_EQ(3u, resources.release_callbacks.size());
639   // Expect exactly three texture uploads, one for each plane.
640   EXPECT_EQ(3, gl_->UploadCount());
641
642   // Simulate the ResourceProvider releasing the resources back to the video
643   // updater.
644   for (auto& release_callback : resources.release_callbacks)
645     std::move(release_callback).Run(gpu::SyncToken(), false);
646
647   // Allocate resources for the same frame.
648   gl_->ResetUploadCount();
649   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
650   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
651   EXPECT_EQ(3u, resources.resources.size());
652   EXPECT_EQ(3u, resources.release_callbacks.size());
653   // The data should be reused so expect no texture uploads.
654   EXPECT_EQ(0, gl_->UploadCount());
655 }
656
657 TEST_F(VideoResourceUpdaterTest, ReuseResourceNV12) {
658   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
659   scoped_refptr<VideoFrame> video_frame = CreateNV12TestFrame();
660   video_frame->set_timestamp(base::Seconds(1234));
661   gl_->set_supports_texture_rg(true);
662
663   // Allocate the resources for a YUV video frame.
664   gl_->ResetUploadCount();
665   VideoFrameExternalResources resources =
666       updater->CreateExternalResourcesFromVideoFrame(video_frame);
667   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
668   EXPECT_EQ(2u, resources.resources.size());
669   EXPECT_EQ(2u, resources.release_callbacks.size());
670   // Expect exactly three texture uploads, one for each plane.
671   EXPECT_EQ(2, gl_->UploadCount());
672
673   // Simulate the ResourceProvider releasing the resources back to the video
674   // updater.
675   for (auto& release_callback : resources.release_callbacks)
676     std::move(release_callback).Run(gpu::SyncToken(), false);
677
678   // Allocate resources for the same frame.
679   gl_->ResetUploadCount();
680   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
681   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
682   EXPECT_EQ(2u, resources.resources.size());
683   EXPECT_EQ(2u, resources.release_callbacks.size());
684   // The data should be reused so expect no texture uploads.
685   EXPECT_EQ(0, gl_->UploadCount());
686 }
687
688 TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) {
689   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
690   scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame();
691   video_frame->set_timestamp(base::Seconds(1234));
692
693   // Allocate the resources for a YUV video frame.
694   gl_->ResetUploadCount();
695   VideoFrameExternalResources resources =
696       updater->CreateExternalResourcesFromVideoFrame(video_frame);
697   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
698   EXPECT_EQ(3u, resources.resources.size());
699   EXPECT_EQ(3u, resources.release_callbacks.size());
700   // Expect exactly three texture uploads, one for each plane.
701   EXPECT_EQ(3, gl_->UploadCount());
702
703   // Allocate resources for the same frame.
704   gl_->ResetUploadCount();
705   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
706   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
707   EXPECT_EQ(3u, resources.resources.size());
708   EXPECT_EQ(3u, resources.release_callbacks.size());
709   // The data should be reused so expect no texture uploads.
710   EXPECT_EQ(0, gl_->UploadCount());
711 }
712
713 TEST_F(VideoResourceUpdaterTest, SoftwareFrameSoftwareCompositor) {
714   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
715   scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame();
716
717   VideoFrameExternalResources resources =
718       updater->CreateExternalResourcesFromVideoFrame(video_frame);
719   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
720 }
721
722 TEST_F(VideoResourceUpdaterTest, SoftwareFrameRGBSoftwareCompositor) {
723   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
724   for (const auto& fmt : {PIXEL_FORMAT_XBGR, PIXEL_FORMAT_XRGB,
725                           PIXEL_FORMAT_ABGR, PIXEL_FORMAT_ARGB}) {
726     scoped_refptr<VideoFrame> video_frame = CreateTestRGBVideoFrame(fmt);
727     VideoFrameExternalResources resources =
728         updater->CreateExternalResourcesFromVideoFrame(video_frame);
729     EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
730     EXPECT_EQ(resources.resources[0].format,
731               viz::SinglePlaneFormat::kRGBA_8888);
732   }
733 }
734
735 TEST_F(VideoResourceUpdaterTest, ReuseResourceSoftwareCompositor) {
736   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
737   scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame();
738   video_frame->set_timestamp(base::Seconds(1234));
739
740   // Allocate the resources for a software video frame.
741   VideoFrameExternalResources resources =
742       updater->CreateExternalResourcesFromVideoFrame(video_frame);
743   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
744   EXPECT_EQ(1u, resources.resources.size());
745   EXPECT_EQ(1u, resources.release_callbacks.size());
746   // Expect exactly one allocated shared bitmap.
747   EXPECT_EQ(1u, shared_bitmap_reporter_.shared_bitmaps().size());
748   auto shared_bitmaps_copy = shared_bitmap_reporter_.shared_bitmaps();
749
750   // Simulate the ResourceProvider releasing the resource back to the video
751   // updater.
752   std::move(resources.release_callbacks[0]).Run(gpu::SyncToken(), false);
753
754   // Allocate resources for the same frame.
755   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
756   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
757   EXPECT_EQ(1u, resources.resources.size());
758   EXPECT_EQ(1u, resources.release_callbacks.size());
759
760   // Ensure that the same shared bitmap was reused.
761   EXPECT_EQ(shared_bitmap_reporter_.shared_bitmaps(), shared_bitmaps_copy);
762 }
763
764 TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDeleteSoftwareCompositor) {
765   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
766   scoped_refptr<VideoFrame> video_frame = CreateTestYUVVideoFrame();
767   video_frame->set_timestamp(base::Seconds(1234));
768
769   // Allocate the resources for a software video frame.
770   VideoFrameExternalResources resources =
771       updater->CreateExternalResourcesFromVideoFrame(video_frame);
772   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
773   EXPECT_EQ(1u, resources.resources.size());
774   EXPECT_EQ(1u, resources.release_callbacks.size());
775   // Expect exactly one allocated shared bitmap.
776   EXPECT_EQ(1u, shared_bitmap_reporter_.shared_bitmaps().size());
777   auto shared_bitmaps_copy = shared_bitmap_reporter_.shared_bitmaps();
778
779   // Allocate resources for the same frame.
780   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
781   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
782   EXPECT_EQ(1u, resources.resources.size());
783   EXPECT_EQ(1u, resources.release_callbacks.size());
784
785   // Ensure that the same shared bitmap was reused.
786   EXPECT_EQ(shared_bitmap_reporter_.shared_bitmaps(), shared_bitmaps_copy);
787 }
788
789 TEST_F(VideoResourceUpdaterTest, ChangeResourceSizeSoftwareCompositor) {
790   constexpr gfx::Size kSize1(10, 10);
791   constexpr gfx::Size kSize2(20, 20);
792
793   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForSoftware();
794
795   // Allocate the resources for a software video frame.
796   VideoFrameExternalResources resources =
797       updater->CreateExternalResourcesFromVideoFrame(
798           CreateTestYUVVideoFrame(kSize1));
799   // Expect exactly one allocated shared bitmap.
800   EXPECT_EQ(1u, shared_bitmap_reporter_.shared_bitmaps().size());
801   auto shared_bitmaps_copy = shared_bitmap_reporter_.shared_bitmaps();
802
803   // Simulate the ResourceProvider releasing the resource back to the video
804   // updater.
805   std::move(resources.release_callbacks[0]).Run(gpu::SyncToken(), false);
806
807   // Allocate resources for the next frame with a different size.
808   resources = updater->CreateExternalResourcesFromVideoFrame(
809       CreateTestYUVVideoFrame(kSize2));
810
811   // The first resource was released, so it can be reused but it's the wrong
812   // size. We should expect the first shared bitmap to be deleted and a new
813   // shared bitmap to be allocated.
814   EXPECT_EQ(1u, shared_bitmap_reporter_.shared_bitmaps().size());
815   EXPECT_NE(shared_bitmap_reporter_.shared_bitmaps(), shared_bitmaps_copy);
816 }
817
818 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_ResourceFormat) {
819   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
820
821   scoped_refptr<VideoFrame> video_frame = CreateTestRGBAHardwareVideoFrame();
822
823   VideoFrameExternalResources resources =
824       updater->CreateExternalResourcesFromVideoFrame(video_frame);
825   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
826   EXPECT_EQ(1u, resources.resources.size());
827   EXPECT_EQ(1u, resources.release_callbacks.size());
828
829   video_frame = CreateTestYuvHardwareVideoFrame(PIXEL_FORMAT_I420, 3,
830                                                 GL_TEXTURE_RECTANGLE_ARB);
831
832   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
833   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
834   EXPECT_EQ(3u, resources.resources.size());
835   EXPECT_EQ(3u, resources.release_callbacks.size());
836   EXPECT_EQ(viz::SinglePlaneFormat::kR_8, resources.resources[0].format);
837   EXPECT_EQ(viz::SinglePlaneFormat::kR_8, resources.resources[1].format);
838   EXPECT_EQ(viz::SinglePlaneFormat::kR_8, resources.resources[2].format);
839   EXPECT_EQ(resources.resources[0].synchronization_type,
840             viz::TransferableResource::SynchronizationType::kSyncToken);
841   EXPECT_EQ(resources.resources[1].synchronization_type,
842             viz::TransferableResource::SynchronizationType::kSyncToken);
843   EXPECT_EQ(resources.resources[2].synchronization_type,
844             viz::TransferableResource::SynchronizationType::kSyncToken);
845
846   video_frame = CreateTestYuvHardwareVideoFrame(PIXEL_FORMAT_I420, 3,
847                                                 GL_TEXTURE_RECTANGLE_ARB);
848   video_frame->metadata().read_lock_fences_enabled = true;
849
850   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
851   EXPECT_EQ(
852       resources.resources[0].synchronization_type,
853       viz::TransferableResource::SynchronizationType::kGpuCommandsCompleted);
854   EXPECT_EQ(
855       resources.resources[1].synchronization_type,
856       viz::TransferableResource::SynchronizationType::kGpuCommandsCompleted);
857   EXPECT_EQ(
858       resources.resources[2].synchronization_type,
859       viz::TransferableResource::SynchronizationType::kGpuCommandsCompleted);
860 }
861
862 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_SharedImageFormat) {
863   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
864   scoped_refptr<VideoFrame> video_frame = CreateTestYuvHardwareVideoFrame(
865       PIXEL_FORMAT_I420, 1, GL_TEXTURE_RECTANGLE_ARB);
866   // Setting to kSharedImageFormat, resources type should change to RGB.
867   video_frame->set_shared_image_format_type(
868       SharedImageFormatType::kSharedImageFormat);
869   VideoFrameExternalResources resources =
870       updater->CreateExternalResourcesFromVideoFrame(video_frame);
871   EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
872   EXPECT_EQ(1u, resources.resources.size());
873   EXPECT_EQ(1u, resources.release_callbacks.size());
874   EXPECT_EQ(viz::MultiPlaneFormat::kI420, resources.resources[0].format);
875   EXPECT_EQ(resources.resources[0].synchronization_type,
876             viz::TransferableResource::SynchronizationType::kSyncToken);
877
878   video_frame = CreateTestYuvHardwareVideoFrame(PIXEL_FORMAT_I420, 1,
879                                                 GL_TEXTURE_RECTANGLE_ARB);
880   video_frame->set_shared_image_format_type(
881       SharedImageFormatType::kSharedImageFormat);
882   video_frame->metadata().read_lock_fences_enabled = true;
883
884   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
885   EXPECT_EQ(
886       resources.resources[0].synchronization_type,
887       viz::TransferableResource::SynchronizationType::kGpuCommandsCompleted);
888 }
889
890 TEST_F(VideoResourceUpdaterTest,
891        CreateForHardwarePlanes_StreamTexture_CopyToNewTexture) {
892   // Note that |use_stream_video_draw_quad| is true for this test.
893   std::unique_ptr<VideoResourceUpdater> updater =
894       CreateUpdaterForHardware(true);
895   EXPECT_EQ(0u, GetSharedImageCount());
896   scoped_refptr<VideoFrame> video_frame =
897       CreateTestStreamTextureHardwareVideoFrame(/*needs_copy=*/false);
898
899   VideoFrameExternalResources resources =
900       updater->CreateExternalResourcesFromVideoFrame(video_frame);
901   EXPECT_EQ(VideoFrameResourceType::STREAM_TEXTURE, resources.type);
902   EXPECT_EQ(1u, resources.resources.size());
903   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
904             resources.resources[0].mailbox_holder.texture_target);
905   EXPECT_EQ(1u, resources.release_callbacks.size());
906   EXPECT_EQ(0u, GetSharedImageCount());
907
908   // A copied stream texture should return an RGBA resource in a new
909   // GL_TEXTURE_2D texture.
910   video_frame = CreateTestStreamTextureHardwareVideoFrame(/*needs_copy=*/true);
911   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
912   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
913   EXPECT_EQ(1u, resources.resources.size());
914   EXPECT_EQ((GLenum)GL_TEXTURE_2D,
915             resources.resources[0].mailbox_holder.texture_target);
916   EXPECT_EQ(1u, resources.release_callbacks.size());
917   EXPECT_EQ(1u, GetSharedImageCount());
918 }
919
920 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_TextureQuad) {
921   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
922   EXPECT_EQ(0u, GetSharedImageCount());
923   scoped_refptr<VideoFrame> video_frame =
924       CreateTestStreamTextureHardwareVideoFrame(/*needs_copy=*/false);
925
926   VideoFrameExternalResources resources =
927       updater->CreateExternalResourcesFromVideoFrame(video_frame);
928   EXPECT_EQ(VideoFrameResourceType::RGBA_PREMULTIPLIED, resources.type);
929   EXPECT_EQ(1u, resources.resources.size());
930   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
931             resources.resources[0].mailbox_holder.texture_target);
932   EXPECT_EQ(1u, resources.release_callbacks.size());
933   EXPECT_EQ(0u, GetSharedImageCount());
934 }
935
936 #if BUILDFLAG(IS_WIN)
937 // Check that a video frame marked as containing a DComp surface turns into a
938 // texture draw quad that is required for overlay.
939 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_DCompSurface) {
940   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
941   EXPECT_EQ(0u, GetSharedImageCount());
942   scoped_refptr<VideoFrame> video_frame = CreateTestDCompSurfaceVideoFrame();
943
944   VideoFrameExternalResources resources =
945       updater->CreateExternalResourcesFromVideoFrame(video_frame);
946   EXPECT_EQ(VideoFrameResourceType::STREAM_TEXTURE, resources.type);
947   EXPECT_EQ(1u, resources.resources.size());
948   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
949             resources.resources[0].mailbox_holder.texture_target);
950   EXPECT_EQ(1u, resources.release_callbacks.size());
951   EXPECT_EQ(0u, GetSharedImageCount());
952
953   updater->ObtainFrameResources(video_frame);
954
955   std::unique_ptr<viz::CompositorRenderPass> pass =
956       viz::CompositorRenderPass::Create();
957   pass->SetNew(/*pass_id=*/viz::CompositorRenderPassId{1},
958                /*output_rect=*/gfx::Rect(video_frame->coded_size()),
959                /*damage_rect=*/gfx::Rect(),
960                /*transform_to_root_target=*/gfx::Transform());
961   updater->AppendQuads(
962       /*render_pass=*/pass.get(), video_frame,
963       /*transform=*/gfx::Transform(),
964       /*quad_rect=*/gfx::Rect(video_frame->coded_size()),
965       /*visible_quad_rect=*/gfx::Rect(video_frame->coded_size()),
966       gfx::MaskFilterInfo(), /*clip_rect=*/absl::nullopt,
967       /*context_opaque=*/true, /*draw_opacity=*/1.0,
968       /*sorting_context_id=*/0);
969
970   EXPECT_EQ(1u, pass->quad_list.size());
971
972   const viz::TextureDrawQuad* quad =
973       pass->quad_list.ElementAt(0)->DynamicCast<viz::TextureDrawQuad>();
974   EXPECT_NE(nullptr, quad);
975   EXPECT_EQ(true, quad->is_stream_video);
976   EXPECT_EQ(viz::OverlayPriority::kRequired, quad->overlay_priority_hint);
977
978   updater->ReleaseFrameResources();
979 }
980 #endif
981
982 // Passthrough the sync token returned by the compositor if we don't have an
983 // existing release sync token.
984 TEST_F(VideoResourceUpdaterTest, PassReleaseSyncToken) {
985   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
986
987   const gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
988                                   gpu::CommandBufferId::FromUnsafeValue(0x123),
989                                   123);
990
991   {
992     scoped_refptr<VideoFrame> video_frame = CreateTestRGBAHardwareVideoFrame();
993
994     VideoFrameExternalResources resources =
995         updater->CreateExternalResourcesFromVideoFrame(video_frame);
996
997     ASSERT_EQ(resources.release_callbacks.size(), 1u);
998     std::move(resources.release_callbacks[0]).Run(sync_token, false);
999   }
1000
1001   EXPECT_EQ(release_sync_token_, sync_token);
1002 }
1003
1004 // Generate new sync token because video frame has an existing sync token.
1005 TEST_F(VideoResourceUpdaterTest, GenerateReleaseSyncToken) {
1006   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1007
1008   const gpu::SyncToken sync_token1(gpu::CommandBufferNamespace::GPU_IO,
1009                                    gpu::CommandBufferId::FromUnsafeValue(0x123),
1010                                    123);
1011
1012   const gpu::SyncToken sync_token2(gpu::CommandBufferNamespace::GPU_IO,
1013                                    gpu::CommandBufferId::FromUnsafeValue(0x234),
1014                                    234);
1015
1016   {
1017     scoped_refptr<VideoFrame> video_frame = CreateTestRGBAHardwareVideoFrame();
1018
1019     VideoFrameExternalResources resources1 =
1020         updater->CreateExternalResourcesFromVideoFrame(video_frame);
1021     ASSERT_EQ(resources1.release_callbacks.size(), 1u);
1022     std::move(resources1.release_callbacks[0]).Run(sync_token1, false);
1023
1024     VideoFrameExternalResources resources2 =
1025         updater->CreateExternalResourcesFromVideoFrame(video_frame);
1026     ASSERT_EQ(resources2.release_callbacks.size(), 1u);
1027     std::move(resources2.release_callbacks[0]).Run(sync_token2, false);
1028   }
1029
1030   EXPECT_TRUE(release_sync_token_.HasData());
1031   EXPECT_NE(release_sync_token_, sync_token1);
1032   EXPECT_EQ(release_sync_token_, sync_token2);
1033 }
1034
1035 // Pass mailbox sync token as is if no GL operations are performed before frame
1036 // resources are handed off to the compositor.
1037 TEST_F(VideoResourceUpdaterTest, PassMailboxSyncToken) {
1038   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1039
1040   scoped_refptr<VideoFrame> video_frame = CreateTestRGBAHardwareVideoFrame();
1041
1042   VideoFrameExternalResources resources =
1043       updater->CreateExternalResourcesFromVideoFrame(video_frame);
1044
1045   ASSERT_EQ(resources.resources.size(), 1u);
1046   EXPECT_TRUE(resources.resources[0].mailbox_holder.sync_token.HasData());
1047   EXPECT_EQ(resources.resources[0].mailbox_holder.sync_token,
1048             kMailboxSyncToken);
1049 }
1050
1051 // Generate new sync token for compositor when copying the texture.
1052 TEST_F(VideoResourceUpdaterTest, GenerateSyncTokenOnTextureCopy) {
1053   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1054
1055   scoped_refptr<VideoFrame> video_frame =
1056       CreateTestStreamTextureHardwareVideoFrame(/*needs_copy=*/true);
1057
1058   VideoFrameExternalResources resources =
1059       updater->CreateExternalResourcesFromVideoFrame(video_frame);
1060
1061   ASSERT_EQ(resources.resources.size(), 1u);
1062   EXPECT_TRUE(resources.resources[0].mailbox_holder.sync_token.HasData());
1063   EXPECT_NE(resources.resources[0].mailbox_holder.sync_token,
1064             kMailboxSyncToken);
1065 }
1066
1067 // NV12 VideoFrames backed by a single native texture can be sampled out
1068 // by GL as RGB. To use them as HW overlays we need to know the format
1069 // of the underlying buffer, that is YUV_420_BIPLANAR.
1070 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_SingleNV12) {
1071   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1072   EXPECT_EQ(0u, GetSharedImageCount());
1073   scoped_refptr<VideoFrame> video_frame =
1074       CreateTestHardwareVideoFrame(PIXEL_FORMAT_NV12, GL_TEXTURE_EXTERNAL_OES);
1075
1076   VideoFrameExternalResources resources =
1077       updater->CreateExternalResourcesFromVideoFrame(video_frame);
1078   EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
1079   EXPECT_EQ(1u, resources.resources.size());
1080   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
1081             resources.resources[0].mailbox_holder.texture_target);
1082   EXPECT_EQ(viz::LegacyMultiPlaneFormat::kNV12, resources.resources[0].format);
1083   EXPECT_EQ(0u, GetSharedImageCount());
1084 }
1085
1086 TEST_F(VideoResourceUpdaterTest,
1087        CreateForHardwarePlanes_DualNV12_ResourceFormat) {
1088   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1089   EXPECT_EQ(0u, GetSharedImageCount());
1090   scoped_refptr<VideoFrame> video_frame = CreateTestYuvHardwareVideoFrame(
1091       PIXEL_FORMAT_NV12, 2, GL_TEXTURE_EXTERNAL_OES);
1092
1093   VideoFrameExternalResources resources =
1094       updater->CreateExternalResourcesFromVideoFrame(video_frame);
1095   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
1096   EXPECT_EQ(2u, resources.resources.size());
1097   EXPECT_EQ(2u, resources.release_callbacks.size());
1098   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
1099             resources.resources[0].mailbox_holder.texture_target);
1100   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
1101             resources.resources[1].mailbox_holder.texture_target);
1102   // |updater| doesn't set |buffer_format| in this case.
1103   EXPECT_EQ(viz::SinglePlaneFormat::kR_8, resources.resources[0].format);
1104   EXPECT_EQ(viz::SinglePlaneFormat::kRG_88, resources.resources[1].format);
1105
1106   video_frame = CreateTestYuvHardwareVideoFrame(PIXEL_FORMAT_NV12, 2,
1107                                                 GL_TEXTURE_RECTANGLE_ARB);
1108   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
1109   EXPECT_EQ(VideoFrameResourceType::YUV, resources.type);
1110   EXPECT_EQ(2u, resources.resources.size());
1111   EXPECT_EQ((GLenum)GL_TEXTURE_RECTANGLE_ARB,
1112             resources.resources[0].mailbox_holder.texture_target);
1113   EXPECT_EQ((GLenum)GL_TEXTURE_RECTANGLE_ARB,
1114             resources.resources[1].mailbox_holder.texture_target);
1115   EXPECT_EQ(viz::SinglePlaneFormat::kR_8, resources.resources[0].format);
1116   EXPECT_EQ(viz::SinglePlaneFormat::kRG_88, resources.resources[1].format);
1117   EXPECT_EQ(0u, GetSharedImageCount());
1118 }
1119
1120 TEST_F(VideoResourceUpdaterTest,
1121        CreateForHardwarePlanes_DualNV12_SharedImageFormat) {
1122   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1123   EXPECT_EQ(0u, GetSharedImageCount());
1124   scoped_refptr<VideoFrame> video_frame = CreateTestYuvHardwareVideoFrame(
1125       PIXEL_FORMAT_NV12, 1, GL_TEXTURE_RECTANGLE_ARB);
1126   video_frame->set_shared_image_format_type(
1127       SharedImageFormatType::kSharedImageFormat);
1128   VideoFrameExternalResources resources =
1129       updater->CreateExternalResourcesFromVideoFrame(video_frame);
1130   // Setting to kSharedImageFormat, resources type should bo RGB.
1131   EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
1132   EXPECT_EQ(1u, resources.resources.size());
1133   EXPECT_EQ((GLenum)GL_TEXTURE_RECTANGLE_ARB,
1134             resources.resources[0].mailbox_holder.texture_target);
1135   EXPECT_EQ(viz::MultiPlaneFormat::kNV12, resources.resources[0].format);
1136   EXPECT_EQ(0u, GetSharedImageCount());
1137
1138   video_frame = CreateTestYuvHardwareVideoFrame(PIXEL_FORMAT_NV12, 1,
1139                                                 GL_TEXTURE_EXTERNAL_OES);
1140   video_frame->set_shared_image_format_type(
1141       SharedImageFormatType::kSharedImageFormat);
1142
1143   resources = updater->CreateExternalResourcesFromVideoFrame(video_frame);
1144   EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
1145   EXPECT_EQ(1u, resources.resources.size());
1146   EXPECT_EQ(1u, resources.release_callbacks.size());
1147   EXPECT_EQ((GLenum)GL_TEXTURE_EXTERNAL_OES,
1148             resources.resources[0].mailbox_holder.texture_target);
1149   // |updater| doesn't set |buffer_format| in this case.
1150   EXPECT_EQ(viz::MultiPlaneFormat::kNV12, resources.resources[0].format);
1151   EXPECT_EQ(0u, GetSharedImageCount());
1152 }
1153
1154 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes_SingleP016HDR) {
1155   constexpr auto kHDR10ColorSpace = gfx::ColorSpace::CreateHDR10();
1156   gfx::HDRMetadata hdr_metadata{};
1157   hdr_metadata.smpte_st_2086 =
1158       gfx::HdrMetadataSmpteSt2086(SkNamedPrimariesExt::kP3,
1159                                   /*luminance_max=*/1000,
1160                                   /*luminance_min=*/0);
1161   std::unique_ptr<VideoResourceUpdater> updater = CreateUpdaterForHardware();
1162   EXPECT_EQ(0u, GetSharedImageCount());
1163   scoped_refptr<VideoFrame> video_frame = CreateTestHardwareVideoFrame(
1164       PIXEL_FORMAT_P016LE, GL_TEXTURE_EXTERNAL_OES);
1165   video_frame->set_color_space(kHDR10ColorSpace);
1166   video_frame->set_hdr_metadata(hdr_metadata);
1167
1168   VideoFrameExternalResources resources =
1169       updater->CreateExternalResourcesFromVideoFrame(video_frame);
1170   EXPECT_EQ(VideoFrameResourceType::RGB, resources.type);
1171   EXPECT_EQ(1u, resources.resources.size());
1172   EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
1173             resources.resources[0].mailbox_holder.texture_target);
1174   EXPECT_EQ(viz::LegacyMultiPlaneFormat::kP010, resources.resources[0].format);
1175   EXPECT_EQ(kHDR10ColorSpace, resources.resources[0].color_space);
1176   EXPECT_EQ(hdr_metadata, resources.resources[0].hdr_metadata);
1177   EXPECT_EQ(0u, GetSharedImageCount());
1178 }
1179
1180 }  // namespace
1181 }  // namespace media