blob: e337baa9ae724e6b03f09530cc8994fd1b24ed92 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/macros.h"
#include "cc/layers/video_frame_provider_client_impl.h"
#include "cc/layers/video_layer_impl.h"
#include "cc/output/begin_frame_args.h"
#include "cc/test/fake_video_frame_provider.h"
#include "cc/test/layer_test_common.h"
#include "media/base/video_frame.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
namespace cc {
// NOTE: We cannot use DebugScopedSetImplThreadAndMainThreadBlocked in these
// tests because it gets destroyed before the VideoLayerImpl is destroyed. This
// causes a DCHECK in VideoLayerImpl's destructor to fail.
static void DebugSetImplThreadAndMainThreadBlocked(
TaskRunnerProvider* task_runner_provider) {
#if DCHECK_IS_ON()
task_runner_provider->SetCurrentThreadIsImplThread(true);
task_runner_provider->SetMainThreadBlocked(true);
#endif
}
class VideoFrameProviderClientImplTest : public testing::Test,
public VideoFrameControllerClient {
public:
VideoFrameProviderClientImplTest()
: client_impl_(VideoFrameProviderClientImpl::Create(&provider_, this)),
video_layer_impl_(nullptr),
test_frame_(media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_YV12,
gfx::Size(10, 10),
gfx::Rect(10, 10),
gfx::Size(10, 10),
base::TimeDelta())) {
DebugSetImplThreadAndMainThreadBlocked(impl_.task_runner_provider());
}
~VideoFrameProviderClientImplTest() {
if (!client_impl_->Stopped()) {
client_impl_->Stop();
DCHECK(client_impl_->Stopped());
DCHECK(!client_impl_->ActiveVideoLayer());
}
provider_.SetVideoFrameProviderClient(nullptr);
}
void StartRendering() {
EXPECT_CALL(*this, AddVideoFrameController(_));
client_impl_->StartRendering();
}
void StopRendering() {
EXPECT_CALL(*this, RemoveVideoFrameController(_));
client_impl_->StopRendering();
}
void StartRenderingAndRenderFrame() {
EXPECT_FALSE(client_impl_->HasCurrentFrame());
provider_.set_frame(test_frame_);
EXPECT_TRUE(client_impl_->HasCurrentFrame());
// Start rendering and verify SetNeedsRedraw() was called for the new frame.
StartRendering();
EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
client_impl_->OnBeginFrame(BeginFrameArgs());
EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
}
void CreateActiveVideoLayer() {
gfx::Size layer_size(100, 100);
video_layer_impl_ = impl_.AddChildToRoot<VideoLayerImpl>(
&provider_, media::VIDEO_ROTATION_0);
video_layer_impl_->SetBounds(layer_size);
video_layer_impl_->SetDrawsContent(true);
client_impl_->SetActiveVideoLayer(video_layer_impl_);
ASSERT_TRUE(client_impl_->ActiveVideoLayer());
}
MOCK_METHOD1(AddVideoFrameController, void(VideoFrameController*));
MOCK_METHOD1(RemoveVideoFrameController, void(VideoFrameController*));
protected:
FakeVideoFrameProvider provider_;
LayerTestCommon::LayerImplTest impl_;
scoped_refptr<VideoFrameProviderClientImpl> client_impl_;
VideoLayerImpl* video_layer_impl_;
scoped_refptr<media::VideoFrame> test_frame_;
private:
DISALLOW_COPY_AND_ASSIGN(VideoFrameProviderClientImplTest);
};
TEST_F(VideoFrameProviderClientImplTest, StartStopRendering) {
StartRendering();
StopRendering();
}
TEST_F(VideoFrameProviderClientImplTest, StopUsingProvider) {
ASSERT_TRUE(client_impl_->get_provider_for_testing());
StartRendering();
EXPECT_CALL(*this, RemoveVideoFrameController(_));
client_impl_->StopUsingProvider();
ASSERT_FALSE(client_impl_->get_provider_for_testing());
}
TEST_F(VideoFrameProviderClientImplTest, FrameAcquisition) {
CreateActiveVideoLayer();
StartRenderingAndRenderFrame();
// Verify GetCurrentFrame() and PutCurrentFrame() work correctly.
EXPECT_EQ(test_frame_, client_impl_->AcquireLockAndCurrentFrame());
EXPECT_EQ(0, provider_.put_current_frame_count());
client_impl_->PutCurrentFrame();
EXPECT_EQ(1, provider_.put_current_frame_count());
client_impl_->ReleaseLock();
StopRendering();
}
TEST_F(VideoFrameProviderClientImplTest, DidReceiveFrame) {
CreateActiveVideoLayer();
EXPECT_EQ(gfx::Rect(), video_layer_impl_->update_rect());
client_impl_->DidReceiveFrame();
EXPECT_NE(gfx::Rect(), video_layer_impl_->update_rect());
}
TEST_F(VideoFrameProviderClientImplTest, DidDrawFrameIssuesPutCurrentFrame) {
CreateActiveVideoLayer();
StartRenderingAndRenderFrame();
EXPECT_EQ(0, provider_.put_current_frame_count());
client_impl_->DidDrawFrame();
EXPECT_EQ(1, provider_.put_current_frame_count());
StopRendering();
}
TEST_F(VideoFrameProviderClientImplTest, StreamTextureMatrix) {
const float kIdentityMatrix[] = {
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
0.0,
0.0,
0.0,
0.0,
1.0,
};
EXPECT_FALSE(client_impl_->StreamTextureMatrix().IsIdentity());
client_impl_->DidUpdateMatrix(kIdentityMatrix);
EXPECT_TRUE(client_impl_->StreamTextureMatrix().IsIdentity());
}
} // namespace cc