| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/test/test_simple_task_runner.h" | 8 #include "base/test/test_simple_task_runner.h" |
| 9 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
| 10 #include "gpu/command_buffer/client/gles2_interface_stub.h" | 10 #include "gpu/command_buffer/client/gles2_interface_stub.h" |
| 11 #include "media/base/video_frame.h" | 11 #include "media/base/video_frame.h" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 } // unnamed namespace | 67 } // unnamed namespace |
| 68 | 68 |
| 69 class GpuMemoryBufferVideoFramePoolTest : public ::testing::Test { | 69 class GpuMemoryBufferVideoFramePoolTest : public ::testing::Test { |
| 70 public: | 70 public: |
| 71 GpuMemoryBufferVideoFramePoolTest() {} | 71 GpuMemoryBufferVideoFramePoolTest() {} |
| 72 void SetUp() override { | 72 void SetUp() override { |
| 73 gles2_.reset(new TestGLES2Interface); | 73 gles2_.reset(new TestGLES2Interface); |
| 74 media_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner); | 74 media_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner); |
| 75 copy_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner); | |
| 76 media_task_runner_handle_.reset( | 75 media_task_runner_handle_.reset( |
| 77 new base::ThreadTaskRunnerHandle(media_task_runner_)); | 76 new base::ThreadTaskRunnerHandle(media_task_runner_)); |
| 78 mock_gpu_factories_.reset( | 77 mock_gpu_factories_.reset( |
| 79 new MockGpuVideoAcceleratorFactories(gles2_.get())); | 78 new MockGpuVideoAcceleratorFactories(gles2_.get())); |
| 80 gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool( | 79 gpu_memory_buffer_pool_.reset(new GpuMemoryBufferVideoFramePool( |
| 81 media_task_runner_, copy_task_runner_.get(), | 80 media_task_runner_, mock_gpu_factories_.get())); |
| 82 mock_gpu_factories_.get())); | |
| 83 } | 81 } |
| 84 | 82 |
| 85 void TearDown() override { | 83 void TearDown() override { |
| 86 gpu_memory_buffer_pool_.reset(); | 84 gpu_memory_buffer_pool_.reset(); |
| 87 RunUntilIdle(); | 85 RunUntilIdle(); |
| 88 mock_gpu_factories_.reset(); | 86 mock_gpu_factories_.reset(); |
| 89 } | 87 } |
| 90 | 88 |
| 91 void RunUntilIdle() { | 89 void RunUntilIdle() { |
| 92 media_task_runner_->RunUntilIdle(); | 90 media_task_runner_->RunUntilIdle(); |
| 93 copy_task_runner_->RunUntilIdle(); | |
| 94 media_task_runner_->RunUntilIdle(); | 91 media_task_runner_->RunUntilIdle(); |
| 95 } | 92 } |
| 96 | 93 |
| 97 static scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame( | 94 std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format) { |
| 98 int dimension) { | |
| 99 const int kDimension = 10; | 95 const int kDimension = 10; |
| 100 static uint8_t y_data[kDimension * kDimension] = {0}; | 96 return CreateFrame(format, kDimension); |
| 101 static uint8_t u_data[kDimension * kDimension / 2] = {0}; | 97 } |
| 102 static uint8_t v_data[kDimension * kDimension / 2] = {0}; | 98 |
| 103 | 99 std::unique_ptr<VideoFrameFuture> CreateFrame(VideoPixelFormat format, |
| 104 DCHECK_LE(dimension, kDimension); | 100 int width) { |
| 105 gfx::Size size(dimension, dimension); | 101 gfx::Size coded_size(width, width); |
| 106 | 102 gfx::Rect visible_rect(coded_size); |
| 107 scoped_refptr<VideoFrame> video_frame = | 103 gfx::Size natural_size(coded_size); |
| 108 media::VideoFrame::WrapExternalYuvData( | 104 |
| 109 media::PIXEL_FORMAT_YV12, // format | 105 return gpu_memory_buffer_pool_->CreateFrame( |
| 110 size, // coded_size | 106 format, coded_size, visible_rect, natural_size, kNoTimestamp()); |
| 111 gfx::Rect(size), // visible_rect | 107 } |
| 112 size, // natural_size | 108 |
| 113 size.width(), // y_stride | 109 void CheckPoolSize(size_t size) const { |
| 114 size.width() / 2, // u_stride | 110 EXPECT_EQ(size, gpu_memory_buffer_pool_->GetPoolSizeForTesting()); |
| 115 size.width() / 2, // v_stride | |
| 116 y_data, // y_data | |
| 117 u_data, // u_data | |
| 118 v_data, // v_data | |
| 119 base::TimeDelta()); // timestamp | |
| 120 EXPECT_TRUE(video_frame); | |
| 121 return video_frame; | |
| 122 } | 111 } |
| 123 | 112 |
| 124 protected: | 113 protected: |
| 125 scoped_ptr<MockGpuVideoAcceleratorFactories> mock_gpu_factories_; | 114 scoped_ptr<MockGpuVideoAcceleratorFactories> mock_gpu_factories_; |
| 126 scoped_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_; | 115 scoped_ptr<GpuMemoryBufferVideoFramePool> gpu_memory_buffer_pool_; |
| 127 scoped_refptr<base::TestSimpleTaskRunner> media_task_runner_; | 116 scoped_refptr<base::TestSimpleTaskRunner> media_task_runner_; |
| 128 scoped_refptr<base::TestSimpleTaskRunner> copy_task_runner_; | |
| 129 // GpuMemoryBufferVideoFramePool uses BindToCurrentLoop(), which requires | 117 // GpuMemoryBufferVideoFramePool uses BindToCurrentLoop(), which requires |
| 130 // ThreadTaskRunnerHandle initialization. | 118 // ThreadTaskRunnerHandle initialization. |
| 131 scoped_ptr<base::ThreadTaskRunnerHandle> media_task_runner_handle_; | 119 scoped_ptr<base::ThreadTaskRunnerHandle> media_task_runner_handle_; |
| 132 scoped_ptr<TestGLES2Interface> gles2_; | 120 scoped_ptr<TestGLES2Interface> gles2_; |
| 133 }; | 121 }; |
| 134 | 122 |
| 135 void MaybeCreateHardwareFrameCallback( | 123 TEST_F(GpuMemoryBufferVideoFramePoolTest, FrameInitializedAndZeroed_I420) { |
| 136 scoped_refptr<VideoFrame>* video_frame_output, | 124 VideoPixelFormat format = PIXEL_FORMAT_I420; |
| 137 const scoped_refptr<VideoFrame>& video_frame) { | 125 std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format); |
| 138 *video_frame_output = video_frame; | 126 |
| 139 } | 127 for (size_t i = 0; i < VideoFrame::NumPlanes(format); ++i) |
| 140 | 128 EXPECT_EQ(0, frame_future->data(i)[0]); |
| 141 TEST_F(GpuMemoryBufferVideoFramePoolTest, VideoFrameOutputFormatUnknown) { | 129 |
| 142 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | 130 scoped_refptr<VideoFrame> frame = frame_future->Release(); |
| 143 mock_gpu_factories_->SetVideoFrameOutputFormat(PIXEL_FORMAT_UNKNOWN); | 131 |
| 144 scoped_refptr<VideoFrame> frame; | 132 EXPECT_EQ(format, frame->format()); |
| 145 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 133 EXPECT_EQ(3u, gles2_->gen_textures); |
| 146 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 134 } |
| 147 RunUntilIdle(); | 135 |
| 148 | 136 TEST_F(GpuMemoryBufferVideoFramePoolTest, FrameInitializedAndZeroed_YV12) { |
| 149 EXPECT_EQ(software_frame.get(), frame.get()); | 137 VideoPixelFormat format = PIXEL_FORMAT_YV12; |
| 150 } | 138 std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format); |
| 151 | 139 |
| 152 TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareFrame) { | 140 for (size_t i = 0; i < VideoFrame::NumPlanes(format); ++i) |
| 153 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | 141 EXPECT_EQ(0, frame_future->data(i)[0]); |
| 154 scoped_refptr<VideoFrame> frame; | 142 |
| 155 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 143 scoped_refptr<VideoFrame> frame = frame_future->Release(); |
| 156 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 144 |
| 157 | 145 // I420 VideoFrame covers both PIXEL_FORMAT_I420 and PIXEL_FORMAT_YV12; |
| 158 RunUntilIdle(); | 146 EXPECT_EQ(PIXEL_FORMAT_I420, frame->format()); |
| 159 | 147 EXPECT_EQ(3u, gles2_->gen_textures); |
| 160 EXPECT_NE(software_frame.get(), frame.get()); | 148 } |
| 161 EXPECT_EQ(3u, gles2_->gen_textures); | 149 |
| 150 TEST_F(GpuMemoryBufferVideoFramePoolTest, SimpleFrameReuse) { |
| 151 VideoPixelFormat format = PIXEL_FORMAT_I420; |
| 152 std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format); |
| 153 |
| 154 const uint8_t* old_y_data = frame_future->data(VideoFrame::kYPlane); |
| 155 scoped_refptr<VideoFrame> frame = frame_future->Release(); |
| 156 |
| 157 // Clear frame reference to return the frame to the pool. |
| 158 frame = nullptr; |
| 159 frame_future = nullptr; |
| 160 |
| 161 RunUntilIdle(); |
| 162 |
| 163 // Verify that the next frame from the pool uses the same memory. |
| 164 std::unique_ptr<VideoFrameFuture> new_frame_future = CreateFrame(format); |
| 165 EXPECT_EQ(old_y_data, new_frame_future->data(VideoFrame::kYPlane)); |
| 166 } |
| 167 |
| 168 TEST_F(GpuMemoryBufferVideoFramePoolTest, SimpleFormatChange) { |
| 169 std::unique_ptr<VideoFrameFuture> frame_future1 = |
| 170 CreateFrame(PIXEL_FORMAT_YV12); |
| 171 std::unique_ptr<VideoFrameFuture> frame_future2 = |
| 172 CreateFrame(PIXEL_FORMAT_YV12); |
| 173 |
| 174 scoped_refptr<VideoFrame> frame1 = frame_future1->Release(); |
| 175 scoped_refptr<VideoFrame> frame2 = frame_future2->Release(); |
| 176 |
| 177 // Clear frame references to return the frames to the pool. |
| 178 frame1 = nullptr; |
| 179 frame2 = nullptr; |
| 180 frame_future1 = nullptr; |
| 181 frame_future2 = nullptr; |
| 182 |
| 183 // Verify that both frames are in the pool. |
| 184 CheckPoolSize(2u); |
| 185 RunUntilIdle(); |
| 186 CheckPoolSize(2u); |
| 187 |
| 188 // Verify that requesting a frame with a different format causes the pool |
| 189 // to get drained. |
| 190 std::unique_ptr<VideoFrameFuture> new_frame_future = |
| 191 CreateFrame(PIXEL_FORMAT_I420); |
| 192 CheckPoolSize(1u); |
| 193 } |
| 194 |
| 195 TEST_F(GpuMemoryBufferVideoFramePoolTest, FrameValidAfterPoolDestruction) { |
| 196 std::unique_ptr<VideoFrameFuture> frame_future = |
| 197 CreateFrame(PIXEL_FORMAT_YV12); |
| 198 |
| 199 // Destroy the pool. |
| 200 gpu_memory_buffer_pool_.reset(); |
| 201 |
| 202 RunUntilIdle(); |
| 203 |
| 204 // Write to the Y plane. The memory tools should detect a |
| 205 // use-after-free if the storage was actually removed by pool destruction. |
| 206 memset(frame_future->data(VideoFrame::kYPlane), 0xff, |
| 207 frame_future->stride(VideoFrame::kYPlane)); |
| 162 } | 208 } |
| 163 | 209 |
| 164 TEST_F(GpuMemoryBufferVideoFramePoolTest, ReuseFirstResource) { | 210 TEST_F(GpuMemoryBufferVideoFramePoolTest, ReuseFirstResource) { |
| 165 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | 211 std::unique_ptr<VideoFrameFuture> frame_future1 = |
| 166 scoped_refptr<VideoFrame> frame; | 212 CreateFrame(PIXEL_FORMAT_I420); |
| 167 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 213 scoped_refptr<VideoFrame> frame1 = frame_future1->Release(); |
| 168 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 214 gpu::Mailbox mailbox = frame1->mailbox_holder(0).mailbox; |
| 169 RunUntilIdle(); | 215 const gpu::SyncToken sync_token = frame1->mailbox_holder(0).sync_token; |
| 170 | 216 EXPECT_EQ(3u, gles2_->gen_textures); |
| 171 EXPECT_NE(software_frame.get(), frame.get()); | 217 |
| 172 gpu::Mailbox mailbox = frame->mailbox_holder(0).mailbox; | 218 std::unique_ptr<VideoFrameFuture> frame_future2 = |
| 173 const gpu::SyncToken sync_token = frame->mailbox_holder(0).sync_token; | 219 CreateFrame(PIXEL_FORMAT_I420); |
| 174 EXPECT_EQ(3u, gles2_->gen_textures); | 220 scoped_refptr<VideoFrame> frame2 = frame_future2->Release(); |
| 175 | 221 |
| 176 scoped_refptr<VideoFrame> frame2; | 222 EXPECT_NE(frame1.get(), frame2.get()); |
| 177 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | |
| 178 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame2)); | |
| 179 RunUntilIdle(); | |
| 180 | |
| 181 EXPECT_NE(software_frame.get(), frame2.get()); | |
| 182 EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox); | 223 EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox); |
| 183 EXPECT_EQ(6u, gles2_->gen_textures); | 224 EXPECT_EQ(6u, gles2_->gen_textures); |
| 184 | 225 |
| 185 frame = nullptr; | 226 frame1 = nullptr; |
| 186 frame2 = nullptr; | 227 frame2 = nullptr; |
| 187 RunUntilIdle(); | 228 frame_future1 = nullptr; |
| 188 | 229 frame_future2 = nullptr; |
| 189 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 230 RunUntilIdle(); |
| 190 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 231 |
| 191 RunUntilIdle(); | 232 std::unique_ptr<VideoFrameFuture> new_frame_future = |
| 192 | 233 CreateFrame(PIXEL_FORMAT_I420); |
| 193 EXPECT_NE(software_frame.get(), frame.get()); | 234 scoped_refptr<VideoFrame> new_frame = new_frame_future->Release(); |
| 194 EXPECT_EQ(6u, gles2_->gen_textures); | 235 |
| 195 EXPECT_EQ(frame->mailbox_holder(0).mailbox, mailbox); | 236 EXPECT_EQ(6u, gles2_->gen_textures); |
| 196 EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token); | 237 EXPECT_EQ(new_frame->mailbox_holder(0).mailbox, mailbox); |
| 238 EXPECT_NE(new_frame->mailbox_holder(0).sync_token, sync_token); |
| 197 } | 239 } |
| 198 | 240 |
| 199 TEST_F(GpuMemoryBufferVideoFramePoolTest, DoNotReuseInUse) { | 241 TEST_F(GpuMemoryBufferVideoFramePoolTest, DoNotReuseInUse) { |
| 200 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | 242 std::unique_ptr<VideoFrameFuture> frame_future1 = |
| 201 scoped_refptr<VideoFrame> frame; | 243 CreateFrame(PIXEL_FORMAT_I420); |
| 202 scoped_refptr<VideoFrame> frame2; | 244 scoped_refptr<VideoFrame> frame1 = frame_future1->Release(); |
| 203 | 245 gpu::Mailbox mailbox = frame1->mailbox_holder(0).mailbox; |
| 204 // Allocate a frame. | 246 const gpu::SyncToken sync_token = frame1->mailbox_holder(0).sync_token; |
| 205 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 247 EXPECT_EQ(3u, gles2_->gen_textures); |
| 206 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 248 |
| 207 RunUntilIdle(); | 249 std::unique_ptr<VideoFrameFuture> frame_future2 = |
| 208 EXPECT_NE(software_frame.get(), frame.get()); | 250 CreateFrame(PIXEL_FORMAT_I420); |
| 209 gpu::Mailbox mailbox = frame->mailbox_holder(0).mailbox; | 251 scoped_refptr<VideoFrame> frame2 = frame_future2->Release(); |
| 210 const gpu::SyncToken sync_token = frame->mailbox_holder(0).sync_token; | 252 |
| 211 EXPECT_EQ(3u, gles2_->gen_textures); | 253 EXPECT_NE(frame1.get(), frame2.get()); |
| 212 | |
| 213 // Allocate a second frame. | |
| 214 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | |
| 215 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame2)); | |
| 216 RunUntilIdle(); | |
| 217 EXPECT_NE(software_frame.get(), frame2.get()); | |
| 218 EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox); | 254 EXPECT_NE(mailbox, frame2->mailbox_holder(0).mailbox); |
| 219 EXPECT_EQ(6u, gles2_->gen_textures); | 255 EXPECT_EQ(6u, gles2_->gen_textures); |
| 220 | 256 |
| 221 // Allow the frames to be recycled. | 257 frame1 = nullptr; |
| 222 frame = nullptr; | |
| 223 frame2 = nullptr; | 258 frame2 = nullptr; |
| 259 frame_future1 = nullptr; |
| 260 frame_future2 = nullptr; |
| 224 RunUntilIdle(); | 261 RunUntilIdle(); |
| 225 | 262 |
| 226 // Set all buffers to be in use, so the next hardware frame will require | 263 // Set all buffers to be in use, so the next hardware frame will require |
| 227 // a new allocation. | 264 // a new allocation. |
| 228 mock_gpu_factories_->SetGpuMemoryBuffersInUseByMacOSWindowServer(true); | 265 mock_gpu_factories_->SetGpuMemoryBuffersInUseByMacOSWindowServer(true); |
| 229 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 266 std::unique_ptr<VideoFrameFuture> new_frame_future = |
| 230 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 267 CreateFrame(PIXEL_FORMAT_I420); |
| 231 RunUntilIdle(); | 268 scoped_refptr<VideoFrame> new_frame = new_frame_future->Release(); |
| 232 EXPECT_NE(software_frame.get(), frame.get()); | 269 RunUntilIdle(); |
| 233 EXPECT_EQ(9u, gles2_->gen_textures); | 270 EXPECT_EQ(9u, gles2_->gen_textures); |
| 234 EXPECT_NE(frame->mailbox_holder(0).mailbox, mailbox); | 271 EXPECT_NE(new_frame->mailbox_holder(0).mailbox, mailbox); |
| 235 EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token); | 272 EXPECT_NE(new_frame->mailbox_holder(0).sync_token, sync_token); |
| 236 | 273 |
| 237 // Set the buffers no longer in use, so no new allocations will be made. | 274 // Set the buffers no longer in use, so no new allocations will be made. |
| 238 mock_gpu_factories_->SetGpuMemoryBuffersInUseByMacOSWindowServer(false); | 275 mock_gpu_factories_->SetGpuMemoryBuffersInUseByMacOSWindowServer(false); |
| 239 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 276 std::unique_ptr<VideoFrameFuture> new_frame_future2 = |
| 240 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame2)); | 277 CreateFrame(PIXEL_FORMAT_I420); |
| 241 RunUntilIdle(); | 278 scoped_refptr<VideoFrame> new_frame2 = new_frame_future2->Release(); |
| 242 EXPECT_NE(software_frame.get(), frame2.get()); | 279 RunUntilIdle(); |
| 243 EXPECT_EQ(9u, gles2_->gen_textures); | 280 EXPECT_EQ(9u, gles2_->gen_textures); |
| 244 EXPECT_NE(frame->mailbox_holder(0).mailbox, mailbox); | 281 EXPECT_EQ(new_frame2->mailbox_holder(0).mailbox, mailbox); |
| 245 EXPECT_NE(frame->mailbox_holder(0).sync_token, sync_token); | 282 EXPECT_NE(new_frame2->mailbox_holder(0).sync_token, sync_token); |
| 246 } | 283 } |
| 247 | 284 |
| 248 TEST_F(GpuMemoryBufferVideoFramePoolTest, DropResourceWhenSizeIsDifferent) { | 285 TEST_F(GpuMemoryBufferVideoFramePoolTest, DropResourceWhenSizeIsDifferent) { |
| 249 scoped_refptr<VideoFrame> frame; | 286 VideoPixelFormat format = PIXEL_FORMAT_I420; |
| 250 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 287 std::unique_ptr<VideoFrameFuture> frame_future = CreateFrame(format); |
| 251 CreateTestYUVVideoFrame(10), | 288 scoped_refptr<VideoFrame> frame = frame_future->Release(); |
| 252 base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 289 EXPECT_EQ(3u, gles2_->gen_textures); |
| 253 RunUntilIdle(); | 290 |
| 254 | 291 // Clear frame reference to return the frame to the pool. |
| 255 EXPECT_EQ(3u, gles2_->gen_textures); | |
| 256 | |
| 257 frame = nullptr; | 292 frame = nullptr; |
| 258 RunUntilIdle(); | 293 frame_future = nullptr; |
| 259 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 294 |
| 260 CreateTestYUVVideoFrame(4), | 295 RunUntilIdle(); |
| 261 base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 296 |
| 262 RunUntilIdle(); | 297 std::unique_ptr<VideoFrameFuture> new_frame_future = CreateFrame(format, 32); |
| 298 scoped_refptr<VideoFrame> new_frame = new_frame_future->Release(); |
| 263 EXPECT_EQ(6u, gles2_->gen_textures); | 299 EXPECT_EQ(6u, gles2_->gen_textures); |
| 264 } | 300 } |
| 265 | 301 |
| 266 TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareUYUVFrame) { | 302 TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareUYUVFrame) { |
| 267 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | 303 std::unique_ptr<VideoFrameFuture> frame_future = |
| 268 scoped_refptr<VideoFrame> frame; | 304 CreateFrame(PIXEL_FORMAT_UYVY); |
| 269 mock_gpu_factories_->SetVideoFrameOutputFormat(PIXEL_FORMAT_UYVY); | 305 scoped_refptr<VideoFrame> frame = frame_future->Release(); |
| 270 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 306 |
| 271 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | |
| 272 | |
| 273 RunUntilIdle(); | |
| 274 | |
| 275 EXPECT_NE(software_frame.get(), frame.get()); | |
| 276 EXPECT_EQ(1u, gles2_->gen_textures); | 307 EXPECT_EQ(1u, gles2_->gen_textures); |
| 277 EXPECT_TRUE(frame->metadata()->IsTrue( | 308 EXPECT_TRUE(frame->metadata()->IsTrue( |
| 278 media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); | 309 media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); |
| 279 } | 310 } |
| 280 | 311 |
| 281 TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareNV12Frame) { | 312 TEST_F(GpuMemoryBufferVideoFramePoolTest, CreateOneHardwareNV12Frame) { |
| 282 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | 313 std::unique_ptr<VideoFrameFuture> frame_future = |
| 283 scoped_refptr<VideoFrame> frame; | 314 CreateFrame(PIXEL_FORMAT_NV12); |
| 284 mock_gpu_factories_->SetVideoFrameOutputFormat(PIXEL_FORMAT_NV12); | 315 scoped_refptr<VideoFrame> frame = frame_future->Release(); |
| 285 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 316 |
| 286 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 317 RunUntilIdle(); |
| 287 | 318 |
| 288 RunUntilIdle(); | |
| 289 | |
| 290 EXPECT_NE(software_frame.get(), frame.get()); | |
| 291 EXPECT_EQ(1u, gles2_->gen_textures); | 319 EXPECT_EQ(1u, gles2_->gen_textures); |
| 292 EXPECT_TRUE(frame->metadata()->IsTrue( | 320 EXPECT_TRUE(frame->metadata()->IsTrue( |
| 293 media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); | 321 media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)); |
| 294 } | 322 } |
| 295 | 323 |
| 296 // AllocateGpuMemoryBuffer can return null (e.g: when the GPU process is down). | 324 // CreateFrame can return null (e.g: when the GPU process is down). |
| 297 // This test checks that in that case we don't crash and still create the | |
| 298 // textures. | |
| 299 TEST_F(GpuMemoryBufferVideoFramePoolTest, AllocateGpuMemoryBufferFail) { | 325 TEST_F(GpuMemoryBufferVideoFramePoolTest, AllocateGpuMemoryBufferFail) { |
| 300 scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10); | |
| 301 scoped_refptr<VideoFrame> frame; | |
| 302 mock_gpu_factories_->SetFailToAllocateGpuMemoryBufferForTesting(true); | 326 mock_gpu_factories_->SetFailToAllocateGpuMemoryBufferForTesting(true); |
| 303 gpu_memory_buffer_pool_->MaybeCreateHardwareFrame( | 327 std::unique_ptr<VideoFrameFuture> frame_future = |
| 304 software_frame, base::Bind(MaybeCreateHardwareFrameCallback, &frame)); | 328 CreateFrame(PIXEL_FORMAT_I420); |
| 305 | 329 EXPECT_EQ(nullptr, frame_future.get()); |
| 306 RunUntilIdle(); | 330 |
| 307 | 331 RunUntilIdle(); |
| 308 EXPECT_NE(software_frame.get(), frame.get()); | 332 |
| 309 EXPECT_EQ(3u, gles2_->gen_textures); | 333 EXPECT_EQ(0u, gles2_->gen_textures); |
| 310 } | 334 } |
| 311 | 335 |
| 312 } // namespace media | 336 } // namespace media |
| OLD | NEW |