cc: Make a FakeResourceProvider and use it in tests to construct.
[chromium-blink-merge.git] / cc / resources / video_resource_updater_unittest.cc
blob0ad011a79e9f506a017b5617c0081398e46dd8cb
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,
101 base::Closure()); // no_longer_needed_cb
104 static void ReleaseMailboxCB(unsigned sync_point) {}
106 scoped_refptr<media::VideoFrame> CreateTestRGBAHardwareVideoFrame() {
107 const int kDimension = 10;
108 gfx::Size size(kDimension, kDimension);
110 gpu::Mailbox mailbox;
111 mailbox.name[0] = 51;
113 const unsigned sync_point = 7;
114 const unsigned target = GL_TEXTURE_2D;
115 return media::VideoFrame::WrapNativeTexture(
116 gpu::MailboxHolder(mailbox, target, sync_point),
117 base::Bind(&ReleaseMailboxCB),
118 size, // coded_size
119 gfx::Rect(size), // visible_rect
120 size, // natural_size
121 base::TimeDelta(), // timestamp
122 false, // allow_overlay
123 true); // has_alpha
126 scoped_refptr<media::VideoFrame> CreateTestYUVHardareVideoFrame() {
127 const int kDimension = 10;
128 gfx::Size size(kDimension, kDimension);
130 const int kPlanesNum = 3;
131 gpu::Mailbox mailbox[kPlanesNum];
132 for (int i = 0; i < kPlanesNum; ++i) {
133 mailbox[i].name[0] = 50 + 1;
135 const unsigned sync_point = 7;
136 const unsigned target = GL_TEXTURE_RECTANGLE_ARB;
137 return media::VideoFrame::WrapYUV420NativeTextures(
138 gpu::MailboxHolder(mailbox[media::VideoFrame::kYPlane], target,
139 sync_point),
140 gpu::MailboxHolder(mailbox[media::VideoFrame::kUPlane], target,
141 sync_point),
142 gpu::MailboxHolder(mailbox[media::VideoFrame::kVPlane], target,
143 sync_point),
144 base::Bind(&ReleaseMailboxCB),
145 size, // coded_size
146 gfx::Rect(size), // visible_rect
147 size, // natural_size
148 base::TimeDelta(), // timestamp
149 false); // allow_overlay
152 WebGraphicsContext3DUploadCounter* context3d_;
153 FakeOutputSurfaceClient client_;
154 scoped_ptr<FakeOutputSurface> output_surface3d_;
155 scoped_ptr<FakeOutputSurface> output_surface_software_;
156 scoped_ptr<SharedBitmapManagerAllocationCounter> shared_bitmap_manager_;
157 scoped_ptr<ResourceProvider> resource_provider3d_;
158 scoped_ptr<ResourceProvider> resource_provider_software_;
161 TEST_F(VideoResourceUpdaterTest, SoftwareFrame) {
162 VideoResourceUpdater updater(output_surface3d_->context_provider(),
163 resource_provider3d_.get());
164 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
166 VideoFrameExternalResources resources =
167 updater.CreateExternalResourcesFromVideoFrame(video_frame);
168 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
171 TEST_F(VideoResourceUpdaterTest, ReuseResource) {
172 VideoResourceUpdater updater(output_surface3d_->context_provider(),
173 resource_provider3d_.get());
174 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
175 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
177 // Allocate the resources for a YUV video frame.
178 context3d_->ResetUploadCount();
179 VideoFrameExternalResources resources =
180 updater.CreateExternalResourcesFromVideoFrame(video_frame);
181 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
182 EXPECT_EQ(size_t(3), resources.mailboxes.size());
183 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
184 EXPECT_EQ(size_t(0), resources.software_resources.size());
185 // Expect exactly three texture uploads, one for each plane.
186 EXPECT_EQ(3, context3d_->UploadCount());
188 // Simulate the ResourceProvider releasing the resources back to the video
189 // updater.
190 for (ReleaseCallbackImpl& release_callback : resources.release_callbacks)
191 release_callback.Run(0, false, nullptr);
193 // Allocate resources for the same frame.
194 context3d_->ResetUploadCount();
195 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
196 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
197 EXPECT_EQ(size_t(3), resources.mailboxes.size());
198 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
199 // The data should be reused so expect no texture uploads.
200 EXPECT_EQ(0, context3d_->UploadCount());
203 TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDelete) {
204 VideoResourceUpdater updater(output_surface3d_->context_provider(),
205 resource_provider3d_.get());
206 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
207 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
209 // Allocate the resources for a YUV video frame.
210 context3d_->ResetUploadCount();
211 VideoFrameExternalResources resources =
212 updater.CreateExternalResourcesFromVideoFrame(video_frame);
213 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
214 EXPECT_EQ(size_t(3), resources.mailboxes.size());
215 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
216 EXPECT_EQ(size_t(0), resources.software_resources.size());
217 // Expect exactly three texture uploads, one for each plane.
218 EXPECT_EQ(3, context3d_->UploadCount());
220 // Allocate resources for the same frame.
221 context3d_->ResetUploadCount();
222 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
223 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
224 EXPECT_EQ(size_t(3), resources.mailboxes.size());
225 EXPECT_EQ(size_t(3), resources.release_callbacks.size());
226 // The data should be reused so expect no texture uploads.
227 EXPECT_EQ(0, context3d_->UploadCount());
230 TEST_F(VideoResourceUpdaterTest, SoftwareFrameSoftwareCompositor) {
231 VideoResourceUpdater updater(nullptr, resource_provider_software_.get());
232 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
234 VideoFrameExternalResources resources =
235 updater.CreateExternalResourcesFromVideoFrame(video_frame);
236 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
239 TEST_F(VideoResourceUpdaterTest, ReuseResourceSoftwareCompositor) {
240 VideoResourceUpdater updater(nullptr, resource_provider_software_.get());
241 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
242 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
244 // Allocate the resources for a software video frame.
245 shared_bitmap_manager_->ResetAllocationCount();
246 VideoFrameExternalResources resources =
247 updater.CreateExternalResourcesFromVideoFrame(video_frame);
248 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
249 EXPECT_EQ(size_t(0), resources.mailboxes.size());
250 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
251 EXPECT_EQ(size_t(1), resources.software_resources.size());
252 // Expect exactly one allocated shared bitmap.
253 EXPECT_EQ(1, shared_bitmap_manager_->AllocationCount());
255 // Simulate the ResourceProvider releasing the resource back to the video
256 // updater.
257 resources.software_release_callback.Run(0, false, nullptr);
259 // Allocate resources for the same frame.
260 shared_bitmap_manager_->ResetAllocationCount();
261 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
262 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
263 EXPECT_EQ(size_t(0), resources.mailboxes.size());
264 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
265 EXPECT_EQ(size_t(1), resources.software_resources.size());
266 // The data should be reused so expect no new allocations.
267 EXPECT_EQ(0, shared_bitmap_manager_->AllocationCount());
270 TEST_F(VideoResourceUpdaterTest, ReuseResourceNoDeleteSoftwareCompositor) {
271 VideoResourceUpdater updater(nullptr, resource_provider_software_.get());
272 scoped_refptr<media::VideoFrame> video_frame = CreateTestYUVVideoFrame();
273 video_frame->set_timestamp(base::TimeDelta::FromSeconds(1234));
275 // Allocate the resources for a software video frame.
276 shared_bitmap_manager_->ResetAllocationCount();
277 VideoFrameExternalResources resources =
278 updater.CreateExternalResourcesFromVideoFrame(video_frame);
279 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
280 EXPECT_EQ(size_t(0), resources.mailboxes.size());
281 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
282 EXPECT_EQ(size_t(1), resources.software_resources.size());
283 // Expect exactly one allocated shared bitmap.
284 EXPECT_EQ(1, shared_bitmap_manager_->AllocationCount());
286 // Allocate resources for the same frame.
287 shared_bitmap_manager_->ResetAllocationCount();
288 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
289 EXPECT_EQ(VideoFrameExternalResources::SOFTWARE_RESOURCE, resources.type);
290 EXPECT_EQ(size_t(0), resources.mailboxes.size());
291 EXPECT_EQ(size_t(0), resources.release_callbacks.size());
292 EXPECT_EQ(size_t(1), resources.software_resources.size());
293 // The data should be reused so expect no new allocations.
294 EXPECT_EQ(0, shared_bitmap_manager_->AllocationCount());
297 TEST_F(VideoResourceUpdaterTest, CreateForHardwarePlanes) {
298 VideoResourceUpdater updater(output_surface3d_->context_provider(),
299 resource_provider3d_.get());
301 scoped_refptr<media::VideoFrame> video_frame =
302 CreateTestRGBAHardwareVideoFrame();
304 VideoFrameExternalResources resources =
305 updater.CreateExternalResourcesFromVideoFrame(video_frame);
306 EXPECT_EQ(VideoFrameExternalResources::RGBA_RESOURCE, resources.type);
307 EXPECT_EQ(1u, resources.mailboxes.size());
308 EXPECT_EQ(1u, resources.release_callbacks.size());
309 EXPECT_EQ(0u, resources.software_resources.size());
311 video_frame = CreateTestYUVHardareVideoFrame();
313 resources = updater.CreateExternalResourcesFromVideoFrame(video_frame);
314 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
315 EXPECT_EQ(3u, resources.mailboxes.size());
316 EXPECT_EQ(3u, resources.release_callbacks.size());
317 EXPECT_EQ(0u, resources.software_resources.size());
319 } // namespace
320 } // namespace cc