using ::testing::_;
using ::testing::AtLeast;
using ::testing::AnyNumber;
+using ::testing::InvokeWithoutArgs;
namespace cc {
namespace {
InitializeSingleThreaded(client);
}
- MOCK_METHOD0(AcquireLayerTextures, void());
MOCK_METHOD0(SetNeedsCommit, void());
MOCK_METHOD0(SetNeedsUpdateLayers, void());
MOCK_METHOD0(StartRateLimiter, void());
MOCK_METHOD0(StopRateLimiter, void());
};
+class FakeTextureLayerClient : public TextureLayerClient {
+ public:
+ FakeTextureLayerClient() : mailbox_changed_(true) {}
+
+ virtual bool PrepareTextureMailbox(
+ TextureMailbox* mailbox,
+ scoped_ptr<SingleReleaseCallback>* release_callback,
+ bool use_shared_memory) OVERRIDE {
+ if (!mailbox_changed_)
+ return false;
+
+ *mailbox = mailbox_;
+ *release_callback = release_callback_.Pass();
+ mailbox_changed_ = false;
+ return true;
+ }
+
+ void set_mailbox(const TextureMailbox& mailbox,
+ scoped_ptr<SingleReleaseCallback> release_callback) {
+ mailbox_ = mailbox;
+ release_callback_ = release_callback.Pass();
+ mailbox_changed_ = true;
+ }
+
+ private:
+ TextureMailbox mailbox_;
+ scoped_ptr<SingleReleaseCallback> release_callback_;
+ bool mailbox_changed_;
+ DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
+};
+
+class MockMailboxCallback {
+ public:
+ MOCK_METHOD3(Release,
+ void(const gpu::Mailbox& mailbox,
+ uint32 sync_point,
+ bool lost_resource));
+ MOCK_METHOD3(Release2,
+ void(base::SharedMemory* shared_memory,
+ uint32 sync_point,
+ bool lost_resource));
+};
+
+struct CommonMailboxObjects {
+ CommonMailboxObjects()
+ : mailbox_name1_(MailboxFromChar('1')),
+ mailbox_name2_(MailboxFromChar('2')),
+ sync_point1_(1),
+ sync_point2_(2),
+ shared_memory_(new base::SharedMemory) {
+ release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
+ base::Unretained(&mock_callback_),
+ mailbox_name1_);
+ release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
+ base::Unretained(&mock_callback_),
+ mailbox_name2_);
+ const uint32 arbitrary_target1 = GL_TEXTURE_2D;
+ const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
+ mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
+ mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
+ gfx::Size size(128, 128);
+ EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
+ release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
+ base::Unretained(&mock_callback_),
+ shared_memory_.get());
+ mailbox3_ = TextureMailbox(shared_memory_.get(), size);
+ }
+
+ gpu::Mailbox mailbox_name1_;
+ gpu::Mailbox mailbox_name2_;
+ MockMailboxCallback mock_callback_;
+ ReleaseCallback release_mailbox1_;
+ ReleaseCallback release_mailbox2_;
+ ReleaseCallback release_mailbox3_;
+ TextureMailbox mailbox1_;
+ TextureMailbox mailbox2_;
+ TextureMailbox mailbox3_;
+ uint32 sync_point1_;
+ uint32 sync_point2_;
+ scoped_ptr<base::SharedMemory> shared_memory_;
+};
+
class TextureLayerTest : public testing::Test {
public:
TextureLayerTest()
protected:
virtual void SetUp() {
layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
+ layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
+ Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}
virtual void TearDown() {
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
layer_tree_host_->SetRootLayer(NULL);
FakeLayerTreeHostImpl host_impl_;
};
-TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) {
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
- ASSERT_TRUE(test_layer.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
- layer_tree_host_->SetRootLayer(test_layer);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- test_layer->SetTextureId(1);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- test_layer->SetTextureId(2);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- test_layer->SetTextureId(0);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-}
-
-TEST_F(TextureLayerTest, SyncImplWhenDrawing) {
- gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f);
-
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
- ASSERT_TRUE(test_layer.get());
- scoped_ptr<TextureLayerImpl> impl_layer;
- impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
- ASSERT_TRUE(impl_layer);
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
- layer_tree_host_->SetRootLayer(test_layer);
- test_layer->SetTextureId(1);
- test_layer->SetIsDrawable(true);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
- test_layer->WillModifyTexture();
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1);
- test_layer->SetNeedsDisplayRect(dirty_rect);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
- test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
- test_layer->SetIsDrawable(false);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- // Verify that non-drawable layers don't signal the compositor,
- // except for the first draw after last commit, which must acquire
- // the texture.
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
- test_layer->WillModifyTexture();
- test_layer->SetNeedsDisplayRect(dirty_rect);
- test_layer->PushPropertiesTo(impl_layer.get()); // fake commit
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- // Second draw with layer in non-drawable state: no texture
- // acquisition.
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
- test_layer->WillModifyTexture();
- test_layer->SetNeedsDisplayRect(dirty_rect);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-}
-
-TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
- scoped_refptr<Layer> root_layer = Layer::Create();
- ASSERT_TRUE(root_layer.get());
- scoped_refptr<Layer> child_layer = Layer::Create();
- ASSERT_TRUE(child_layer.get());
- root_layer->AddChild(child_layer);
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
- ASSERT_TRUE(test_layer.get());
- test_layer->SetTextureId(0);
- child_layer->AddChild(test_layer);
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
- layer_tree_host_->SetRootLayer(root_layer);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- test_layer->RemoveFromParent();
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- child_layer->AddChild(test_layer);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- test_layer->SetTextureId(1);
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
- EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
- test_layer->RemoveFromParent();
- Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-}
-
TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
- scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL);
+ scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
// Test properties that should call SetNeedsCommit. All properties need to
0.5f, 0.5f, 0.5f, 0.5f));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
- EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1));
-
- // Calling SetTextureId can call AcquireLayerTextures.
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber());
}
TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
const gfx::Rect layer_rect(layer_bounds);
const Region layer_region(layer_rect);
- scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL);
+ scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(NULL);
layer->SetBounds(layer_bounds);
layer->draw_properties().visible_content_rect = layer_rect;
layer->SetBlendBackgroundColor(true);
layer->VisibleContentOpaqueRegion().ToString());
}
-class FakeTextureLayerClient : public TextureLayerClient {
- public:
- FakeTextureLayerClient() {}
-
- virtual unsigned PrepareTexture() OVERRIDE {
- return 0;
- }
-
- virtual bool PrepareTextureMailbox(
- TextureMailbox* mailbox,
- scoped_ptr<SingleReleaseCallback>* release_callback,
- bool use_shared_memory) OVERRIDE {
- *mailbox = TextureMailbox();
- *release_callback = scoped_ptr<SingleReleaseCallback>();
- return true;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
-};
-
TEST_F(TextureLayerTest, RateLimiter) {
FakeTextureLayerClient client;
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
// Stop rate limiter when we're removed from the tree.
EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
+ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1);
layer_tree_host_->SetRootLayer(NULL);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}
-class MockMailboxCallback {
- public:
- MOCK_METHOD3(Release,
- void(const gpu::Mailbox& mailbox,
- uint32 sync_point,
- bool lost_resource));
- MOCK_METHOD3(Release2,
- void(base::SharedMemory* shared_memory,
- uint32 sync_point,
- bool lost_resource));
-};
-
-struct CommonMailboxObjects {
- CommonMailboxObjects()
- : mailbox_name1_(MailboxFromChar('1')),
- mailbox_name2_(MailboxFromChar('2')),
- sync_point1_(1),
- sync_point2_(2),
- shared_memory_(new base::SharedMemory) {
- release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
- base::Unretained(&mock_callback_),
- mailbox_name1_);
- release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
- base::Unretained(&mock_callback_),
- mailbox_name2_);
- const uint32 arbitrary_target1 = 1;
- const uint32 arbitrary_target2 = 2;
- mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_);
- mailbox2_ = TextureMailbox(mailbox_name2_, arbitrary_target2, sync_point2_);
- gfx::Size size(128, 128);
- EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea()));
- release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2,
- base::Unretained(&mock_callback_),
- shared_memory_.get());
- mailbox3_ = TextureMailbox(shared_memory_.get(), size);
- }
-
- gpu::Mailbox mailbox_name1_;
- gpu::Mailbox mailbox_name2_;
- MockMailboxCallback mock_callback_;
- ReleaseCallback release_mailbox1_;
- ReleaseCallback release_mailbox2_;
- ReleaseCallback release_mailbox3_;
- TextureMailbox mailbox1_;
- TextureMailbox mailbox2_;
- TextureMailbox mailbox3_;
- uint32 sync_point1_;
- uint32 sync_point2_;
- scoped_ptr<base::SharedMemory> shared_memory_;
-};
-
class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
public:
using TextureLayer::TextureMailboxHolder::Create;
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
ASSERT_TRUE(test_layer.get());
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
layer_tree_host_->SetRootLayer(test_layer);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_,
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name2_,
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->SetTextureMailbox(
test_data_.mailbox3_,
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
EXPECT_CALL(test_data_.mock_callback_,
Release2(test_data_.shared_memory_.get(),
TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
layer_tree_host_->SetRootLayer(test_layer);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
// Set the mailbox the first time. It should cause a commit.
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
// Set the mailbox again with a new sync point, as the backing texture has
// been updated. It should cause a new commit.
- EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
TextureLayerImplWithMailboxThreadedCallback);
-class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
- public TextureLayerClient {
+class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
protected:
- TextureLayerNoMailboxIsActivatedDuringCommit()
- : texture_(0u), activate_count_(0) {}
+ TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
+
+ static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
+
+ void SetMailbox(char mailbox_char) {
+ scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
+ base::Bind(
+ &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
+ layer_->SetTextureMailbox(
+ TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
+ callback.Pass());
+ }
virtual void BeginTest() OVERRIDE {
gfx::Size bounds(100, 100);
root_->SetAnchorPoint(gfx::PointF());
root_->SetBounds(bounds);
- layer_ = TextureLayer::Create(this);
+ layer_ = TextureLayer::CreateForMailbox(NULL);
layer_->SetIsDrawable(true);
layer_->SetAnchorPoint(gfx::PointF());
layer_->SetBounds(bounds);
root_->AddChild(layer_);
layer_tree_host()->SetRootLayer(root_);
layer_tree_host()->SetViewportSize(bounds);
+ SetMailbox('1');
PostSetNeedsCommitToMainThread();
}
- virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
- OVERRIDE {
- scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
- texture_ = provider->UnboundTestContext3d()->createExternalTexture();
- return FakeOutputSurface::Create3d(provider);
- }
-
- // TextureLayerClient implementation.
- virtual unsigned PrepareTexture() OVERRIDE {
- return texture_;
- }
- virtual bool PrepareTextureMailbox(
- TextureMailbox* mailbox,
- scoped_ptr<SingleReleaseCallback>* release_callback,
- bool use_shared_memory) OVERRIDE {
- return false;
- }
-
virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
++activate_count_;
}
virtual void DidCommit() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
case 1:
- // The first texture has been activated. Invalidate the layer so it
- // grabs a new texture id from the client.
- layer_->SetNeedsDisplay();
+ // The first mailbox has been activated. Set a new mailbox, and
+ // expect the next commit to finish *after* it is activated.
+ SetMailbox('2');
break;
case 2:
// The second mailbox has been activated. Remove the layer from
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
switch (host_impl->active_tree()->source_frame_number()) {
case 2: {
- // The activate for the 2nd texture should have happened before now.
+ // The activate for the 2nd mailbox should have happened before now.
EXPECT_EQ(2, activate_count_);
break;
}
}
}
+
virtual void AfterTest() OVERRIDE {}
- unsigned texture_;
int activate_count_;
scoped_refptr<Layer> root_;
scoped_refptr<TextureLayer> layer_;
};
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- TextureLayerNoMailboxIsActivatedDuringCommit);
+ TextureLayerMailboxIsActivatedDuringCommit);
-class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
+class TextureLayerImplWithMailboxTest : public TextureLayerTest {
protected:
- TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
+ TextureLayerImplWithMailboxTest()
+ : fake_client_(
+ FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
- static void ReleaseCallback(uint32 sync_point, bool lost_resource) {}
+ virtual void SetUp() {
+ TextureLayerTest::SetUp();
+ layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
+ EXPECT_TRUE(host_impl_.InitializeRenderer(
+ FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
+ }
- void SetMailbox(char mailbox_char) {
- scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
- base::Bind(
- &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
- layer_->SetTextureMailbox(
- TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
- callback.Pass());
- }
-
- virtual void BeginTest() OVERRIDE {
- gfx::Size bounds(100, 100);
- root_ = Layer::Create();
- root_->SetAnchorPoint(gfx::PointF());
- root_->SetBounds(bounds);
-
- layer_ = TextureLayer::CreateForMailbox(NULL);
- layer_->SetIsDrawable(true);
- layer_->SetAnchorPoint(gfx::PointF());
- layer_->SetBounds(bounds);
-
- root_->AddChild(layer_);
- layer_tree_host()->SetRootLayer(root_);
- layer_tree_host()->SetViewportSize(bounds);
- SetMailbox('1');
-
- PostSetNeedsCommitToMainThread();
- }
-
- virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- ++activate_count_;
- }
-
- virtual void DidCommit() OVERRIDE {
- switch (layer_tree_host()->source_frame_number()) {
- case 1:
- // The first mailbox has been activated. Set a new mailbox, and
- // expect the next commit to finish *after* it is activated.
- SetMailbox('2');
- break;
- case 2:
- // The second mailbox has been activated. Remove the layer from
- // the tree to cause another commit/activation. The commit should
- // finish *after* the layer is removed from the active tree.
- layer_->RemoveFromParent();
- break;
- case 3:
- EndTest();
- break;
- }
- }
-
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- switch (host_impl->active_tree()->source_frame_number()) {
- case 2: {
- // The activate for the 2nd mailbox should have happened before now.
- EXPECT_EQ(2, activate_count_);
- break;
- }
- case 3: {
- // The activate to remove the layer should have happened before now.
- EXPECT_EQ(3, activate_count_);
- break;
- }
- }
- }
-
-
- virtual void AfterTest() OVERRIDE {}
-
- int activate_count_;
- scoped_refptr<Layer> root_;
- scoped_refptr<TextureLayer> layer_;
-};
-
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
- TextureLayerMailboxIsActivatedDuringCommit);
-
-class TextureLayerImplWithMailboxTest : public TextureLayerTest {
- protected:
- TextureLayerImplWithMailboxTest()
- : fake_client_(
- FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
-
- virtual void SetUp() {
- TextureLayerTest::SetUp();
- layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
- EXPECT_TRUE(host_impl_.InitializeRenderer(
- FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
- }
-
- bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
- bool will_draw = layer->WillDraw(
- mode, host_impl_.active_tree()->resource_provider());
- if (will_draw)
- layer->DidDraw(host_impl_.active_tree()->resource_provider());
- return will_draw;
+ bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
+ bool will_draw = layer->WillDraw(
+ mode, host_impl_.active_tree()->resource_provider());
+ if (will_draw)
+ layer->DidDraw(host_impl_.active_tree()->resource_provider());
+ return will_draw;
}
CommonMailboxObjects test_data_;
// Hardware mode.
{
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
{
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
{
// Software resource.
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox3_,
EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
}
- {
- scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
- impl_layer->SetDrawsContent(true);
- ContextProvider* context_provider =
- host_impl_.output_surface()->context_provider();
- GLuint texture = 0;
- context_provider->ContextGL()->GenTextures(1, &texture);
- impl_layer->SetTextureId(texture);
- EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
- }
-
- {
- scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
- impl_layer->SetDrawsContent(true);
- impl_layer->SetTextureId(0);
- EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
- }
-
// Software mode.
{
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
{
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
{
// Software resource.
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox3_,
EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
}
- {
- scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
- impl_layer->SetDrawsContent(true);
- ContextProvider* context_provider =
- host_impl_.output_surface()->context_provider();
- GLuint texture = 0;
- context_provider->ContextGL()->GenTextures(1, &texture);
- impl_layer->SetTextureId(texture);
- EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
- }
-
- {
- scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
- impl_layer->SetDrawsContent(true);
- impl_layer->SetTextureId(0);
- EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
- }
-
// Resourceless software mode.
{
scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ TextureLayerImpl::Create(host_impl_.active_tree(), 1);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
}
-
- {
- scoped_ptr<TextureLayerImpl> impl_layer =
- TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
- impl_layer->SetDrawsContent(true);
- ContextProvider* context_provider =
- host_impl_.output_surface()->context_provider();
- GLuint texture = 0;
- context_provider->ContextGL()->GenTextures(1, &texture);
- impl_layer->SetTextureId(texture);
- EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
- }
}
TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
host_impl_.CreatePendingTree();
scoped_ptr<TextureLayerImpl> pending_layer;
- pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true);
+ pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
ASSERT_TRUE(pending_layer);
scoped_ptr<LayerImpl> active_layer(
TEST_F(TextureLayerImplWithMailboxTest,
TestDestructorCallbackOnCreatedResource) {
scoped_ptr<TextureLayerImpl> impl_layer;
- impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
ASSERT_TRUE(impl_layer);
EXPECT_CALL(test_data_.mock_callback_,
provider->ReceiveReturnsFromParent(returned);
}
-// Check that ClearClient correctly clears the state so that the impl side
-// doesn't try to use a texture that could have been destroyed.
-class TextureLayerClientTest
- : public LayerTreeTest,
- public TextureLayerClient {
- public:
- TextureLayerClientTest()
- : texture_(0),
- commit_count_(0),
- expected_used_textures_on_draw_(0),
- expected_used_textures_on_commit_(0) {}
-
- virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
- OVERRIDE {
- scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
- texture_ = provider->UnboundTestContext3d()->createExternalTexture();
- return FakeOutputSurface::Create3d(provider);
- }
-
- virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
-
- virtual bool PrepareTextureMailbox(
- TextureMailbox* mailbox,
- scoped_ptr<SingleReleaseCallback>* release_callback,
- bool use_shared_memory) OVERRIDE {
- return false;
- }
-
- virtual void SetupTree() OVERRIDE {
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(10, 10));
- root->SetAnchorPoint(gfx::PointF());
- root->SetIsDrawable(true);
-
- texture_layer_ = TextureLayer::Create(this);
- texture_layer_->SetBounds(gfx::Size(10, 10));
- texture_layer_->SetAnchorPoint(gfx::PointF());
- texture_layer_->SetIsDrawable(true);
- root->AddChild(texture_layer_);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- {
- base::AutoLock lock(lock_);
- expected_used_textures_on_commit_ = 1;
- }
- }
-
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
-
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- ++commit_count_;
- switch (commit_count_) {
- case 1:
- texture_layer_->ClearClient();
- texture_layer_->SetNeedsDisplay();
- {
- base::AutoLock lock(lock_);
- expected_used_textures_on_commit_ = 0;
- }
- break;
- case 2:
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- base::AutoLock lock(lock_);
- expected_used_textures_on_draw_ = expected_used_textures_on_commit_;
- }
-
- virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
- LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
- ContextForImplThread(host_impl)->ResetUsedTextures();
- return DrawSwapReadbackResult::DRAW_SUCCESS;
- }
-
- virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
- bool result) OVERRIDE {
- ASSERT_TRUE(result);
- EXPECT_EQ(expected_used_textures_on_draw_,
- ContextForImplThread(host_impl)->NumUsedTextures());
- }
-
- virtual void AfterTest() OVERRIDE {}
-
- private:
- TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
- return static_cast<TestContextProvider*>(
- host_impl->output_surface()->context_provider().get())->TestContext3d();
- }
-
- scoped_refptr<TextureLayer> texture_layer_;
- unsigned texture_;
- int commit_count_;
-
- // Used only on thread.
- unsigned expected_used_textures_on_draw_;
-
- // Used on either thread, protected by lock_.
- base::Lock lock_;
- unsigned expected_used_textures_on_commit_;
-};
-
-// The TextureLayerClient does not use mailboxes, so can't use a delegating
-// renderer.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
-
-
-// Checks that changing a texture in the client for a TextureLayer that's
-// invisible correctly works without drawing a deleted texture. See
-// crbug.com/266628
-class TextureLayerChangeInvisibleTest
- : public LayerTreeTest,
- public TextureLayerClient {
- public:
- TextureLayerChangeInvisibleTest()
- : texture_(0u),
- prepare_called_(0),
- commit_count_(0),
- expected_texture_on_draw_(0) {}
-
- virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
- OVERRIDE {
- scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
- texture_ = provider->UnboundTestContext3d()->createExternalTexture();
- return FakeOutputSurface::Create3d(provider);
- }
-
- // TextureLayerClient implementation.
- virtual unsigned PrepareTexture() OVERRIDE {
- ++prepare_called_;
- return texture_;
- }
- virtual bool PrepareTextureMailbox(
- TextureMailbox* mailbox,
- scoped_ptr<SingleReleaseCallback>* release_callback,
- bool use_shared_memory) OVERRIDE {
- return false;
- }
-
- virtual void SetupTree() OVERRIDE {
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(10, 10));
- root->SetAnchorPoint(gfx::PointF());
- root->SetIsDrawable(true);
-
- solid_layer_ = SolidColorLayer::Create();
- solid_layer_->SetBounds(gfx::Size(10, 10));
- solid_layer_->SetIsDrawable(true);
- solid_layer_->SetBackgroundColor(SK_ColorWHITE);
- root->AddChild(solid_layer_);
-
- parent_layer_ = Layer::Create();
- parent_layer_->SetBounds(gfx::Size(10, 10));
- parent_layer_->SetIsDrawable(true);
- root->AddChild(parent_layer_);
-
- texture_layer_ = TextureLayer::Create(this);
- texture_layer_->SetBounds(gfx::Size(10, 10));
- texture_layer_->SetAnchorPoint(gfx::PointF());
- texture_layer_->SetIsDrawable(true);
- parent_layer_->AddChild(texture_layer_);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- }
-
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
-
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- ++commit_count_;
- switch (commit_count_) {
- case 1:
- // We should have updated the layer, committing the texture.
- EXPECT_EQ(1, prepare_called_);
- // Make layer invisible.
- parent_layer_->SetOpacity(0.f);
- break;
- case 2: {
- // Layer shouldn't have been updated.
- EXPECT_EQ(1, prepare_called_);
- texture_layer_->SetNeedsDisplay();
- // Force a change to make sure we draw a frame.
- solid_layer_->SetBackgroundColor(SK_ColorGRAY);
- break;
- }
- case 3:
- EXPECT_EQ(1, prepare_called_);
- // Make layer visible again.
- parent_layer_->SetOpacity(1.f);
- break;
- case 4: {
- // Layer should have been updated.
- EXPECT_EQ(2, prepare_called_);
- texture_layer_->ClearClient();
- texture_ = 0;
- break;
- }
- case 5:
- EndTest();
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-
- virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- ASSERT_TRUE(proxy()->IsMainThreadBlocked());
- // This is the only texture that can be drawn this frame.
- expected_texture_on_draw_ = texture_;
- }
-
- virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
- LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
- ContextForImplThread(host_impl)->ResetUsedTextures();
- return DrawSwapReadbackResult::DRAW_SUCCESS;
- }
-
- virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
- bool result) OVERRIDE {
- ASSERT_TRUE(result);
- TestWebGraphicsContext3D* context = ContextForImplThread(host_impl);
- int used_textures = context->NumUsedTextures();
- switch (host_impl->active_tree()->source_frame_number()) {
- case 0:
- EXPECT_EQ(1, used_textures);
- EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
- break;
- case 1:
- case 2:
- EXPECT_EQ(0, used_textures);
- break;
- case 3:
- EXPECT_EQ(1, used_textures);
- EXPECT_TRUE(context->UsedTexture(expected_texture_on_draw_));
- break;
- default:
- break;
- }
- }
-
- virtual void AfterTest() OVERRIDE {}
-
- private:
- TestWebGraphicsContext3D* ContextForImplThread(LayerTreeHostImpl* host_impl) {
- return static_cast<TestContextProvider*>(
- host_impl->output_surface()->context_provider().get())->TestContext3d();
- }
-
- scoped_refptr<SolidColorLayer> solid_layer_;
- scoped_refptr<Layer> parent_layer_;
- scoped_refptr<TextureLayer> texture_layer_;
-
- // Used on the main thread, and on the impl thread while the main thread is
- // blocked.
- unsigned texture_;
-
- // Used on the main thread.
- int prepare_called_;
- int commit_count_;
-
- // Used on the compositor thread.
- unsigned expected_texture_on_draw_;
-};
-
-// The TextureLayerChangeInvisibleTest does not use mailboxes, so can't use a
-// delegating renderer.
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
-
// Checks that TextureLayer::Update does not cause an extra commit when setting
// the texture mailbox.
class TextureLayerNoExtraCommitForMailboxTest
public TextureLayerClient {
public:
// TextureLayerClient implementation.
- virtual unsigned PrepareTexture() OVERRIDE {
- NOTREACHED();
- return 0;
- }
virtual bool PrepareTextureMailbox(
TextureMailbox* texture_mailbox,
scoped_ptr<SingleReleaseCallback>* release_callback,
for (size_t i = 0; i < resources_to_return.size(); ++i)
output_surface()->ReturnResource(resources_to_return[i].id, &ack);
host_impl->ReclaimResources(&ack);
- host_impl->OnSwapBuffersComplete();
}
virtual void AfterTest() OVERRIDE {}
}
// TextureLayerClient implementation.
- virtual unsigned PrepareTexture() OVERRIDE {
- NOTREACHED();
- return 0;
- }
-
virtual bool PrepareTextureMailbox(
TextureMailbox* mailbox,
scoped_ptr<SingleReleaseCallback>* release_callback,
for (size_t i = 0; i < resources_to_return.size(); ++i)
output_surface()->ReturnResource(resources_to_return[i].id, &ack);
host_impl->ReclaimResources(&ack);
- host_impl->OnSwapBuffersComplete();
}
virtual void AfterTest() OVERRIDE {}
public TextureLayerClient {
public:
// TextureLayerClient implementation.
- virtual unsigned PrepareTexture() OVERRIDE {
- NOTREACHED();
- return 0;
- }
virtual bool PrepareTextureMailbox(
TextureMailbox* mailbox,
scoped_ptr<SingleReleaseCallback>* release_callback,
SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
-// Test recovering from a lost context.
-class TextureLayerLostContextTest
- : public LayerTreeTest,
- public TextureLayerClient {
- public:
- TextureLayerLostContextTest()
- : context_lost_(false),
- draw_count_(0) {}
-
- virtual scoped_ptr<FakeOutputSurface> CreateFakeOutputSurface(bool fallback)
- OVERRIDE {
- return FakeOutputSurface::Create3d();
- }
-
- virtual unsigned PrepareTexture() OVERRIDE {
- if (draw_count_ == 0)
- context_lost_ = true;
- if (context_lost_)
- return 0u;
- return 1u;
- }
-
- virtual bool PrepareTextureMailbox(
- TextureMailbox* mailbox,
- scoped_ptr<SingleReleaseCallback>* release_callback,
- bool use_shared_memory) OVERRIDE {
- return false;
- }
-
- virtual void SetupTree() OVERRIDE {
- scoped_refptr<Layer> root = Layer::Create();
- root->SetBounds(gfx::Size(10, 10));
- root->SetIsDrawable(true);
-
- texture_layer_ = TextureLayer::Create(this);
- texture_layer_->SetBounds(gfx::Size(10, 10));
- texture_layer_->SetIsDrawable(true);
- root->AddChild(texture_layer_);
-
- layer_tree_host()->SetRootLayer(root);
- LayerTreeTest::SetupTree();
- }
-
- virtual void BeginTest() OVERRIDE {
- PostSetNeedsCommitToMainThread();
- }
-
- virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
- LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame_data,
- DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
- LayerImpl* root = host_impl->RootLayer();
- TextureLayerImpl* texture_layer =
- static_cast<TextureLayerImpl*>(root->children()[0]);
- if (++draw_count_ == 1)
- EXPECT_EQ(0u, texture_layer->texture_id());
- else
- EXPECT_EQ(1u, texture_layer->texture_id());
- return DrawSwapReadbackResult::DRAW_SUCCESS;
- }
-
- virtual void DidCommitAndDrawFrame() OVERRIDE {
- EndTest();
- }
-
- virtual void AfterTest() OVERRIDE {}
-
- private:
- scoped_refptr<TextureLayer> texture_layer_;
- bool context_lost_;
- int draw_count_;
-};
-
-SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest);
-
class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
public:
void ReleaseCallback(uint32 sync_point, bool lost_resource) {