Include all dupe types (event when value is zero) in scan stats.
[chromium-blink-merge.git] / cc / resources / video_resource_updater_unittest.cc
blob17095e61ccfd111ccedc0f299298ca35ec310194
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/video_resource_updater.h"
7 #include "base/memory/shared_memory.h"
8 #include "cc/resources/resource_provider.h"
9 #include "cc/test/fake_output_surface.h"
10 #include "cc/test/fake_output_surface_client.h"
11 #include "cc/test/fake_resource_provider.h"
12 #include "cc/test/test_shared_bitmap_manager.h"
13 #include "cc/test/test_web_graphics_context_3d.h"
14 #include "cc/trees/blocking_task_runner.h"
15 #include "gpu/GLES2/gl2extchromium.h"
16 #include "media/base/video_frame.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace cc {
20 namespace {
22 class WebGraphicsContext3DUploadCounter : public TestWebGraphicsContext3D {
23 public:
24 void texSubImage2D(GLenum target,
25 GLint level,
26 GLint xoffset,
27 GLint yoffset,
28 GLsizei width,
29 GLsizei height,
30 GLenum format,
31 GLenum type,
32 const void* pixels) override {
33 ++upload_count_;
36 int UploadCount() { return upload_count_; }
37 void ResetUploadCount() { upload_count_ = 0; }
39 private:
40 int upload_count_;
43 class SharedBitmapManagerAllocationCounter : public TestSharedBitmapManager {
44 public:
45 scoped_ptr<SharedBitmap> AllocateSharedBitmap(
46 const gfx::Size& size) override {
47 ++allocation_count_;
48 return TestSharedBitmapManager::AllocateSharedBitmap(size);
51 int AllocationCount() { return allocation_count_; }
52 void ResetAllocationCount() { allocation_count_ = 0; }
54 private:
55 int allocation_count_;
58 class VideoResourceUpdaterTest : public testing::Test {
59 protected:
60 VideoResourceUpdaterTest() {
61 scoped_ptr<WebGraphicsContext3DUploadCounter> context3d(
62 new WebGraphicsContext3DUploadCounter());
64 context3d_ = context3d.get();
66 output_surface3d_ =
67 FakeOutputSurface::Create3d(context3d.Pass());
68 CHECK(output_surface3d_->BindToClient(&client_));
70 output_surface_software_ = FakeOutputSurface::CreateSoftware(
71 make_scoped_ptr(new SoftwareOutputDevice));
72 CHECK(output_surface_software_->BindToClient(&client_));
74 shared_bitmap_manager_.reset(new SharedBitmapManagerAllocationCounter());
75 resource_provider3d_ = FakeResourceProvider::Create(
76 output_surface3d_.get(), shared_bitmap_manager_.get());
78 resource_provider_software_ = FakeResourceProvider::Create(
79 output_surface_software_.get(), shared_bitmap_manager_.get());
82 scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() {
83 const int kDimension = 10;
84 gfx::Size size(kDimension, kDimension);
85 static uint8 y_data[kDimension * kDimension] = { 0 };
86 static uint8 u_data[kDimension * kDimension / 2] = { 0 };
87 static uint8 v_data[kDimension * kDimension / 2] = { 0 };
89 return media::VideoFrame::WrapExternalYuvData(
90 media::VideoFrame::YV16, // format
91 size, // coded_size
92 gfx::Rect(size), // visible_rect
93 size, // natural_size
94 size.width(), // y_stride
95 size.width() / 2, // u_stride
96 size.width() / 2, // v_stride
97 y_data, // y_data
98 u_data, // u_data
99 v_data, // v_data
100 base::TimeDelta()); // timestamp
103 static void ReleaseMailboxCB(unsigned sync_point) {}
105 scoped_refptr<media::VideoFrame> CreateTestRGBAHardwareVideoFrame() {
106 const int kDimension = 10;
107 gfx::Size size(kDimension, kDimension);
109 gpu::Mailbox mailbox;
110 mailbox.name[0] = 51;
112 const unsigned sync_point = 7;
113 const unsigned target = GL_TEXTURE_2D;
114 return media::VideoFrame::WrapNativeTexture(
115 gpu::MailboxHolder(mailbox, target, sync_point),
116 base::Bind(&ReleaseMailboxCB),
117 size, // coded_size
118 gfx::Rect(size), // visible_rect
119 size, // natural_size
120 base::TimeDelta(), // timestamp
121 false, // allow_overlay
122 true); // has_alpha
125 scoped_refptr<media::VideoFrame> CreateTestYUVHardareVideoFrame() {
126 const int kDimension = 10;
127 gfx::Size size(kDimension, kDimension);
129 const int kPlanesNum = 3;
130 gpu::Mailbox mailbox[kPlanesNum];
131 for (int i = 0; i < kPlanesNum; ++i) {
132 mailbox[i].name[0] = 50 + 1;
134 const unsigned sync_point = 7;
135 const unsigned target = GL_TEXTURE_RECTANGLE_ARB;
136 return media::VideoFrame::WrapYUV420NativeTextures(
137 gpu::MailboxHolder(mailbox[media::VideoFrame::kYPlane], target,
138 sync_point),
139 gpu::MailboxHolder(mailbox[media::VideoFrame::kUPlane], target,
140 sync_point),
141 gpu::MailboxHolder(mailbox[media::VideoFrame::kVPlane], target,
142 sync_point),
143 base::Bind(&ReleaseMailboxCB),
144 size, // coded_size
145 gfx::Rect(size), // visible_rect
146 size, // natural_size
147 base::TimeDelta(), // timestamp
148 false); // allow_overlay
151 WebGraphicsContext3DUploadCounter* context3d_;
152 FakeOutputSurfaceClient client_;
153 scoped_ptr<FakeOutputSurface> output_surface3d_;
154 scoped_ptr<FakeOutputSurface> output_surface_software_;
155 scoped_ptr<SharedBitmapManagerAllocationCounter> shared_bitmap_manager_;
156 scoped_ptr<ResourceProvider> resource_provider3d_;
157 scoped_ptr<ResourceProvider> resource_provider_software_;
160 TEST_F(VideoResourceUpdaterTest, SoftwareFrame) {
161 VideoResourceUpdater updater(output_surface3d_->context_provider(),
162 resource_provider3d_.get());
163 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
165 VideoFrameExternalResources resources =
166 updater.CreateExternalResourcesFromVideoFrame(video_frame);
167 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
170 TEST_F(VideoResourceUpdaterTest, ReuseResource) {
171 VideoResourceUpdater updater(output_surface3d_->context_provider(),
172 resource_provider3d_.get());
173 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
174 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
176 // Allocate the resources for a YUV video frame.
177 context3d_->ResetUploadCount();
178 VideoFrameExternalResources resources =
179 updater.CreateExternalResourcesFromVideoFrame(video_frame);
180 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
181 EXPECT_EQ(size_t(3), resources.mailboxes.size());
182 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
183 EXPECT_EQ(size_t(0), resources.software_resources.size());
184 // Expect exactly three texture uploads, one for each plane.
185 EXPECT_EQ(3, context3d_->UploadCount());
187 // Simulate the ResourceProvider releasing the resources back to the video
188 // updater.
189 for (ReleaseCallbackImpl& release_callback : resources.release_callbacks)
190 release_callback.Run(0, false, nullptr);
192 // Allocate resources for the same frame.
193 context3d_->ResetUploadCount();
194 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
195 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
196 EXPECT_EQ(size_t(3), resources.mailboxes.size());
197 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
198 // The data should be reused so expect no texture uploads.
199 EXPECT_EQ(0, context3d_->UploadCount());
202 TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) {
203 VideoResourceUpdater updater(output_surface3d_->context_provider(),
204 resource_provider3d_.get());
205 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
206 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
208 // Allocate the resources for a YUV video frame.
209 context3d_->ResetUploadCount();
210 VideoFrameExternalResources resources =
211 updater.CreateExternalResourcesFromVideoFrame(video_frame);
212 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
213 EXPECT_EQ(size_t(3), resources.mailboxes.size());
214 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
215 EXPECT_EQ(size_t(0), resources.software_resources.size());
216 // Expect exactly three texture uploads, one for each plane.
217 EXPECT_EQ(3, context3d_->UploadCount());
219 // Allocate resources for the same frame.
220 context3d_->ResetUploadCount();
221 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
222 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
223 EXPECT_EQ(size_t(3), resources.mailboxes.size());
224 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
225 // The data should be reused so expect no texture uploads.
226 EXPECT_EQ(0, context3d_->UploadCount());
229 TEST_F(VideoResourceUpdaterTest, SoftwareFrameSoftwareCompositor) {
230 VideoResourceUpdater updater(nullptr, resource_provider_software_.get());
231 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
233 VideoFrameExternalResources resources =
234 updater.CreateExternalResourcesFromVideoFrame(video_frame);
235 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
238 TEST_F(VideoResourceUpdaterTest, ReuseResourceSoftwareCompositor) {
239 VideoResourceUpdater updater(nullptr, resource_provider_software_.get());
240 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
241 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
243 // Allocate the resources for a software video frame.
244 shared_bitmap_manager_->ResetAllocationCount();
245 VideoFrameExternalResources resources =
246 updater.CreateExternalResourcesFromVideoFrame(video_frame);
247 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
248 EXPECT_EQ(size_t(0), resources.mailboxes.size());
249 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
250 EXPECT_EQ(size_t(1), resources.software_resources.size());
251 // Expect exactly one allocated shared bitmap.
252 EXPECT_EQ(1, shared_bitmap_manager_->AllocationCount());
254 // Simulate the ResourceProvider releasing the resource back to the video
255 // updater.
256 resources.software_release_callback.Run(0, false, nullptr);
258 // Allocate resources for the same frame.
259 shared_bitmap_manager_->ResetAllocationCount();
260 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
261 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
262 EXPECT_EQ(size_t(0), resources.mailboxes.size());
263 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
264 EXPECT_EQ(size_t(1), resources.software_resources.size());
265 // The data should be reused so expect no new allocations.
266 EXPECT_EQ(0, shared_bitmap_manager_->AllocationCount());
269 TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDeleteSoftwareCompositor) {
270 VideoResourceUpdater updater(nullptr, resource_provider_software_.get());
271 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
272 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
274 // Allocate the resources for a software video frame.
275 shared_bitmap_manager_->ResetAllocationCount();
276 VideoFrameExternalResources resources =
277 updater.CreateExternalResourcesFromVideoFrame(video_frame);
278 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
279 EXPECT_EQ(size_t(0), resources.mailboxes.size());
280 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
281 EXPECT_EQ(size_t(1), resources.software_resources.size());
282 // Expect exactly one allocated shared bitmap.
283 EXPECT_EQ(1, shared_bitmap_manager_->AllocationCount());
285 // Allocate resources for the same frame.
286 shared_bitmap_manager_->ResetAllocationCount();
287 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
288 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
289 EXPECT_EQ(size_t(0), resources.mailboxes.size());
290 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
291 EXPECT_EQ(size_t(1), resources.software_resources.size());
292 // The data should be reused so expect no new allocations.
293 EXPECT_EQ(0, shared_bitmap_manager_->AllocationCount());
296 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes) {
297 VideoResourceUpdater updater(output_surface3d_->context_provider(),
298 resource_provider3d_.get());
300 scoped_refptr<media::VideoFrame> video_frame =
301 CreateTestRGBAHardwareVideoFrame();
303 VideoFrameExternalResources resources =
304 updater.CreateExternalResourcesFromVideoFrame(video_frame);
305 EXPECT_EQ(VideoFrameExternalResources::RGBA_RESOURCE, resources.type);
306 EXPECT_EQ(1u, resources.mailboxes.size());
307 EXPECT_EQ(1u, resources.release_callbacks.size());
308 EXPECT_EQ(0u, resources.software_resources.size());
310 video_frame = CreateTestYUVHardareVideoFrame();
312 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
313 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
314 EXPECT_EQ(3u, resources.mailboxes.size());
315 EXPECT_EQ(3u, resources.release_callbacks.size());
316 EXPECT_EQ(0u, resources.software_resources.size());
318 } // namespace
319 } // namespace cc