| Index: cc/layers/texture_layer_unittest.cc
|
| diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
|
| deleted file mode 100644
|
| index b088f6f7a374d840a596b9e711ada9ed663933b6..0000000000000000000000000000000000000000
|
| --- a/cc/layers/texture_layer_unittest.cc
|
| +++ /dev/null
|
| @@ -1,1566 +0,0 @@
|
| -// Copyright 2012 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 "cc/layers/texture_layer.h"
|
| -
|
| -#include <algorithm>
|
| -#include <string>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback.h"
|
| -#include "base/synchronization/waitable_event.h"
|
| -#include "base/threading/thread.h"
|
| -#include "base/time/time.h"
|
| -#include "cc/layers/solid_color_layer.h"
|
| -#include "cc/layers/texture_layer_client.h"
|
| -#include "cc/layers/texture_layer_impl.h"
|
| -#include "cc/output/compositor_frame_ack.h"
|
| -#include "cc/output/context_provider.h"
|
| -#include "cc/resources/returned_resource.h"
|
| -#include "cc/test/fake_impl_proxy.h"
|
| -#include "cc/test/fake_layer_tree_host_client.h"
|
| -#include "cc/test/fake_layer_tree_host_impl.h"
|
| -#include "cc/test/fake_output_surface.h"
|
| -#include "cc/test/layer_test_common.h"
|
| -#include "cc/test/layer_tree_test.h"
|
| -#include "cc/test/test_task_graph_runner.h"
|
| -#include "cc/test/test_web_graphics_context_3d.h"
|
| -#include "cc/trees/blocking_task_runner.h"
|
| -#include "cc/trees/layer_tree_host.h"
|
| -#include "cc/trees/layer_tree_impl.h"
|
| -#include "cc/trees/single_thread_proxy.h"
|
| -#include "gpu/GLES2/gl2extchromium.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using ::testing::Mock;
|
| -using ::testing::_;
|
| -using ::testing::AtLeast;
|
| -using ::testing::AnyNumber;
|
| -using ::testing::InvokeWithoutArgs;
|
| -
|
| -namespace cc {
|
| -namespace {
|
| -
|
| -gpu::Mailbox MailboxFromChar(char value) {
|
| - gpu::Mailbox mailbox;
|
| - memset(mailbox.name, value, sizeof(mailbox.name));
|
| - return mailbox;
|
| -}
|
| -
|
| -class MockLayerTreeHost : public LayerTreeHost {
|
| - public:
|
| - explicit MockLayerTreeHost(FakeLayerTreeHostClient* client)
|
| - : LayerTreeHost(client, nullptr, nullptr, nullptr, LayerTreeSettings()) {
|
| - InitializeSingleThreaded(client,
|
| - base::MessageLoopProxy::current(),
|
| - nullptr);
|
| - }
|
| -
|
| - 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) {}
|
| -
|
| - 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(SharedBitmap* shared_bitmap,
|
| - uint32 sync_point,
|
| - bool lost_resource));
|
| - MOCK_METHOD4(ReleaseImpl,
|
| - void(const gpu::Mailbox& mailbox,
|
| - uint32 sync_point,
|
| - bool lost_resource,
|
| - BlockingTaskRunner* main_thread_task_runner));
|
| - MOCK_METHOD4(ReleaseImpl2,
|
| - void(SharedBitmap* shared_bitmap,
|
| - uint32 sync_point,
|
| - bool lost_resource,
|
| - BlockingTaskRunner* main_thread_task_runner));
|
| -};
|
| -
|
| -struct CommonMailboxObjects {
|
| - explicit CommonMailboxObjects(SharedBitmapManager* manager)
|
| - : mailbox_name1_(MailboxFromChar('1')),
|
| - mailbox_name2_(MailboxFromChar('2')),
|
| - sync_point1_(1),
|
| - sync_point2_(2) {
|
| - release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
|
| - base::Unretained(&mock_callback_),
|
| - mailbox_name1_);
|
| - release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
|
| - base::Unretained(&mock_callback_),
|
| - mailbox_name2_);
|
| - release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
|
| - base::Unretained(&mock_callback_),
|
| - mailbox_name1_);
|
| - release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
|
| - 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);
|
| - shared_bitmap_ = manager->AllocateSharedBitmap(size);
|
| - DCHECK(shared_bitmap_);
|
| - release_mailbox3_ =
|
| - base::Bind(&MockMailboxCallback::Release2,
|
| - base::Unretained(&mock_callback_), shared_bitmap_.get());
|
| - release_mailbox3_impl_ =
|
| - base::Bind(&MockMailboxCallback::ReleaseImpl2,
|
| - base::Unretained(&mock_callback_), shared_bitmap_.get());
|
| - mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
|
| - }
|
| -
|
| - gpu::Mailbox mailbox_name1_;
|
| - gpu::Mailbox mailbox_name2_;
|
| - MockMailboxCallback mock_callback_;
|
| - ReleaseCallback release_mailbox1_;
|
| - ReleaseCallback release_mailbox2_;
|
| - ReleaseCallback release_mailbox3_;
|
| - ReleaseCallbackImpl release_mailbox1_impl_;
|
| - ReleaseCallbackImpl release_mailbox2_impl_;
|
| - ReleaseCallbackImpl release_mailbox3_impl_;
|
| - TextureMailbox mailbox1_;
|
| - TextureMailbox mailbox2_;
|
| - TextureMailbox mailbox3_;
|
| - uint32 sync_point1_;
|
| - uint32 sync_point2_;
|
| - scoped_ptr<SharedBitmap> shared_bitmap_;
|
| -};
|
| -
|
| -class TextureLayerTest : public testing::Test {
|
| - public:
|
| - TextureLayerTest()
|
| - : fake_client_(
|
| - FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
|
| - host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
|
| - test_data_(&shared_bitmap_manager_) {}
|
| -
|
| - protected:
|
| - void SetUp() override {
|
| - 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());
|
| - }
|
| -
|
| - void TearDown() override {
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
|
| -
|
| - layer_tree_host_->SetRootLayer(nullptr);
|
| - layer_tree_host_ = nullptr;
|
| - }
|
| -
|
| - scoped_ptr<MockLayerTreeHost> layer_tree_host_;
|
| - FakeImplProxy proxy_;
|
| - FakeLayerTreeHostClient fake_client_;
|
| - TestSharedBitmapManager shared_bitmap_manager_;
|
| - TestTaskGraphRunner task_graph_runner_;
|
| - FakeLayerTreeHostImpl host_impl_;
|
| - CommonMailboxObjects test_data_;
|
| -};
|
| -
|
| -TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
|
| -
|
| - // Test properties that should call SetNeedsCommit. All properties need to
|
| - // be set to new values in order for SetNeedsCommit to be called.
|
| - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
|
| - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
|
| - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
|
| - gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
|
| - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
|
| - 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));
|
| -}
|
| -
|
| -TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) {
|
| - const gfx::Size layer_bounds(100, 100);
|
| - const gfx::Rect layer_rect(layer_bounds);
|
| - const Region layer_region(layer_rect);
|
| -
|
| - scoped_refptr<TextureLayer> layer = TextureLayer::CreateForMailbox(nullptr);
|
| - layer->SetBounds(layer_bounds);
|
| - layer->draw_properties().visible_content_rect = layer_rect;
|
| - layer->SetBlendBackgroundColor(true);
|
| -
|
| - // Verify initial conditions.
|
| - EXPECT_FALSE(layer->contents_opaque());
|
| - EXPECT_EQ(0u, layer->background_color());
|
| - EXPECT_EQ(Region().ToString(),
|
| - layer->VisibleContentOpaqueRegion().ToString());
|
| -
|
| - // Opaque background.
|
| - layer->SetBackgroundColor(SK_ColorWHITE);
|
| - EXPECT_EQ(layer_region.ToString(),
|
| - layer->VisibleContentOpaqueRegion().ToString());
|
| -
|
| - // Transparent background.
|
| - layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255));
|
| - EXPECT_EQ(Region().ToString(),
|
| - layer->VisibleContentOpaqueRegion().ToString());
|
| -}
|
| -
|
| -TEST_F(TextureLayerTest, RateLimiter) {
|
| - FakeTextureLayerClient client;
|
| - scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(
|
| - &client);
|
| - test_layer->SetIsDrawable(true);
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
|
| - layer_tree_host_->SetRootLayer(test_layer);
|
| -
|
| - // Don't rate limit until we invalidate.
|
| - EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
|
| - test_layer->SetRateLimitContext(true);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -
|
| - // Do rate limit after we invalidate.
|
| - EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
|
| - test_layer->SetNeedsDisplay();
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -
|
| - // Stop rate limiter when we don't want it any more.
|
| - EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
|
| - test_layer->SetRateLimitContext(false);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -
|
| - // Or we clear the client.
|
| - test_layer->SetRateLimitContext(true);
|
| - EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
|
| - test_layer->ClearClient();
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -
|
| - // Reset to a layer with a client, that started the rate limiter.
|
| - test_layer = TextureLayer::CreateForMailbox(
|
| - &client);
|
| - test_layer->SetIsDrawable(true);
|
| - test_layer->SetRateLimitContext(true);
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
|
| - layer_tree_host_->SetRootLayer(test_layer);
|
| - EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| - EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
|
| - test_layer->SetNeedsDisplay();
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -
|
| - // 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(nullptr);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -}
|
| -
|
| -class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
|
| - public:
|
| - using TextureLayer::TextureMailboxHolder::Create;
|
| -
|
| - protected:
|
| - ~TestMailboxHolder() override {}
|
| -};
|
| -
|
| -class TextureLayerWithMailboxTest : public TextureLayerTest {
|
| - protected:
|
| - void TearDown() override {
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name1_,
|
| - test_data_.sync_point1_,
|
| - false)).Times(1);
|
| - TextureLayerTest::TearDown();
|
| - }
|
| -};
|
| -
|
| -TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - ASSERT_TRUE(test_layer.get());
|
| -
|
| - 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_, 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_, SetNeedsCommit()).Times(AtLeast(1));
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name1_,
|
| - test_data_.sync_point1_,
|
| - false))
|
| - .Times(1);
|
| - test_layer->SetTextureMailbox(
|
| - test_data_.mailbox2_,
|
| - SingleReleaseCallback::Create(test_data_.release_mailbox2_));
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name2_,
|
| - test_data_.sync_point2_,
|
| - false))
|
| - .Times(1);
|
| - test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
|
| - test_layer->SetTextureMailbox(
|
| - test_data_.mailbox3_,
|
| - SingleReleaseCallback::Create(test_data_.release_mailbox3_));
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release2(test_data_.shared_bitmap_.get(), 0, false)).Times(1);
|
| - test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // Test destructor.
|
| - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
|
| - test_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallback::Create(test_data_.release_mailbox1_));
|
| -}
|
| -
|
| -TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - ASSERT_TRUE(test_layer.get());
|
| -
|
| - // These use the same gpu::Mailbox, but different sync points.
|
| - TextureMailbox mailbox1(MailboxFromChar('a'), GL_TEXTURE_2D, 1);
|
| - TextureMailbox mailbox2(MailboxFromChar('a'), GL_TEXTURE_2D, 2);
|
| -
|
| - 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_, 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_, SetNeedsCommit()).Times(AtLeast(1));
|
| - test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
|
| - Mock::VerifyAndClearExpectations(layer_tree_host_.get());
|
| -}
|
| -
|
| -class TextureLayerMailboxHolderTest : public TextureLayerTest {
|
| - public:
|
| - TextureLayerMailboxHolderTest()
|
| - : main_thread_("MAIN") {
|
| - main_thread_.Start();
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
|
| - base::Unretained(this)));
|
| - Wait(main_thread_);
|
| - }
|
| -
|
| - void Wait(const base::Thread& thread) {
|
| - bool manual_reset = false;
|
| - bool initially_signaled = false;
|
| - base::WaitableEvent event(manual_reset, initially_signaled);
|
| - thread.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
|
| - event.Wait();
|
| - }
|
| -
|
| - void CreateMainRef() {
|
| - main_ref_ = TestMailboxHolder::Create(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass();
|
| - }
|
| -
|
| - void ReleaseMainRef() { main_ref_ = nullptr; }
|
| -
|
| - void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
|
| - *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
|
| - }
|
| -
|
| - void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
|
| - base::WaitableEvent* wait_for_capture,
|
| - base::WaitableEvent* stop_capture) {
|
| - begin_capture->Wait();
|
| - BlockingTaskRunner::CapturePostTasks capture(
|
| - main_thread_task_runner_.get());
|
| - wait_for_capture->Signal();
|
| - stop_capture->Wait();
|
| - }
|
| -
|
| - protected:
|
| - void InitializeOnMain() {
|
| - main_thread_task_runner_ =
|
| - BlockingTaskRunner::Create(main_thread_.message_loop_proxy());
|
| - }
|
| -
|
| - scoped_ptr<TestMailboxHolder::MainThreadReference>
|
| - main_ref_;
|
| - base::Thread main_thread_;
|
| - scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
|
| -};
|
| -
|
| -TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - ASSERT_TRUE(test_layer.get());
|
| -
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - // The texture layer is attached to compositor1, and passes a reference to its
|
| - // impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor1;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor1));
|
| -
|
| - // Then the texture layer is removed and attached to compositor2, and passes a
|
| - // reference to its impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor2;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor2));
|
| -
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // The compositors both destroy their impl trees before the main thread layer
|
| - // is destroyed.
|
| - compositor1->Run(100, false, main_thread_task_runner_.get());
|
| - compositor2->Run(200, false, main_thread_task_runner_.get());
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // The main thread ref is the last one, so the mailbox is released back to the
|
| - // embedder, with the last sync point provided by the impl trees.
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name1_, 200, false)).Times(1);
|
| -
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
|
| - base::Unretained(this)));
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -}
|
| -
|
| -TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - ASSERT_TRUE(test_layer.get());
|
| -
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - // The texture layer is attached to compositor1, and passes a reference to its
|
| - // impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor1;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor1));
|
| -
|
| - // Then the texture layer is removed and attached to compositor2, and passes a
|
| - // reference to its impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor2;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor2));
|
| -
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // One compositor destroys their impl tree.
|
| - compositor1->Run(100, false, main_thread_task_runner_.get());
|
| -
|
| - // Then the main thread reference is destroyed.
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // The second impl reference is destroyed last, causing the mailbox to be
|
| - // released back to the embedder with the last sync point from the impl tree.
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name1_, 200, true)).Times(1);
|
| -
|
| - compositor2->Run(200, true, main_thread_task_runner_.get());
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -}
|
| -
|
| -TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - ASSERT_TRUE(test_layer.get());
|
| -
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - // The texture layer is attached to compositor1, and passes a reference to its
|
| - // impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor1;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor1));
|
| -
|
| - // Then the texture layer is removed and attached to compositor2, and passes a
|
| - // reference to its impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor2;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor2));
|
| -
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // The main thread reference is destroyed first.
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - // One compositor destroys their impl tree.
|
| - compositor2->Run(200, false, main_thread_task_runner_.get());
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // The second impl reference is destroyed last, causing the mailbox to be
|
| - // released back to the embedder with the last sync point from the impl tree.
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name1_, 100, true)).Times(1);
|
| -
|
| - compositor1->Run(100, true, main_thread_task_runner_.get());
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -}
|
| -
|
| -TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
|
| - scoped_refptr<TextureLayer> test_layer =
|
| - TextureLayer::CreateForMailbox(nullptr);
|
| - ASSERT_TRUE(test_layer.get());
|
| -
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - Wait(main_thread_);
|
| -
|
| - // The texture layer is attached to compositor1, and passes a reference to its
|
| - // impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor1;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor1));
|
| -
|
| - // Then the texture layer is removed and attached to compositor2, and passes a
|
| - // reference to its impl tree.
|
| - scoped_ptr<SingleReleaseCallbackImpl> compositor2;
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
|
| - base::Unretained(this),
|
| - &compositor2));
|
| -
|
| - Wait(main_thread_);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // The main thread reference is destroyed first.
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
|
| - base::Unretained(this)));
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - Release(test_data_.mailbox_name1_, 200, true)).Times(1);
|
| -
|
| - bool manual_reset = false;
|
| - bool initially_signaled = false;
|
| - base::WaitableEvent begin_capture(manual_reset, initially_signaled);
|
| - base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
|
| - base::WaitableEvent stop_capture(manual_reset, initially_signaled);
|
| -
|
| - // Post a task to start capturing tasks on the main thread. This will block
|
| - // the main thread until we signal the |stop_capture| event.
|
| - main_thread_.message_loop()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
|
| - base::Unretained(this),
|
| - &begin_capture,
|
| - &wait_for_capture,
|
| - &stop_capture));
|
| -
|
| - // Before the main thread capturing starts, one compositor destroys their
|
| - // impl reference. Since capturing did not start, this gets post-tasked to
|
| - // the main thread.
|
| - compositor1->Run(100, false, main_thread_task_runner_.get());
|
| -
|
| - // Start capturing on the main thread.
|
| - begin_capture.Signal();
|
| - wait_for_capture.Wait();
|
| -
|
| - // Meanwhile, the second compositor released its impl reference, but this task
|
| - // gets shortcutted directly to the main thread. This means the reference is
|
| - // released before compositor1, whose reference will be released later when
|
| - // the post-task is serviced. But since it was destroyed _on the impl thread_
|
| - // last, its sync point values should be used.
|
| - compositor2->Run(200, true, main_thread_task_runner_.get());
|
| -
|
| - stop_capture.Signal();
|
| - Wait(main_thread_);
|
| -
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -}
|
| -
|
| -class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
|
| - public:
|
| - TextureLayerImplWithMailboxThreadedCallback()
|
| - : callback_count_(0),
|
| - commit_count_(0) {}
|
| -
|
| - // Make sure callback is received on main and doesn't block the impl thread.
|
| - void ReleaseCallback(uint32 sync_point, bool lost_resource) {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| - EXPECT_FALSE(lost_resource);
|
| - ++callback_count_;
|
| - }
|
| -
|
| - void SetMailbox(char mailbox_char) {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
|
| - base::Bind(
|
| - &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
|
| - base::Unretained(this)));
|
| - layer_->SetTextureMailbox(
|
| - TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
|
| - callback.Pass());
|
| - }
|
| -
|
| - void BeginTest() override {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| -
|
| - gfx::Size bounds(100, 100);
|
| - root_ = Layer::Create();
|
| - root_->SetBounds(bounds);
|
| -
|
| - layer_ = TextureLayer::CreateForMailbox(nullptr);
|
| - layer_->SetIsDrawable(true);
|
| - layer_->SetBounds(bounds);
|
| -
|
| - root_->AddChild(layer_);
|
| - layer_tree_host()->SetRootLayer(root_);
|
| - layer_tree_host()->SetViewportSize(bounds);
|
| - SetMailbox('1');
|
| - EXPECT_EQ(0, callback_count_);
|
| -
|
| - // Case #1: change mailbox before the commit. The old mailbox should be
|
| - // released immediately.
|
| - SetMailbox('2');
|
| - EXPECT_EQ(1, callback_count_);
|
| - PostSetNeedsCommitToMainThread();
|
| - }
|
| -
|
| - void DidCommit() override {
|
| - ++commit_count_;
|
| - switch (commit_count_) {
|
| - case 1:
|
| - // Case #2: change mailbox after the commit (and draw), where the
|
| - // layer draws. The old mailbox should be released during the next
|
| - // commit.
|
| - SetMailbox('3');
|
| - EXPECT_EQ(1, callback_count_);
|
| - break;
|
| - case 2:
|
| - EXPECT_EQ(2, callback_count_);
|
| - // Case #3: change mailbox when the layer doesn't draw. The old
|
| - // mailbox should be released during the next commit.
|
| - layer_->SetBounds(gfx::Size());
|
| - SetMailbox('4');
|
| - break;
|
| - case 3:
|
| - EXPECT_EQ(3, callback_count_);
|
| - // Case #4: release mailbox that was committed but never drawn. The
|
| - // old mailbox should be released during the next commit.
|
| - layer_->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - break;
|
| - case 4:
|
| - if (layer_tree_host()->settings().impl_side_painting) {
|
| - // With impl painting, the texture mailbox will still be on the impl
|
| - // thread when the commit finishes, because the layer is not drawble
|
| - // when it has no texture mailbox, and thus does not block the commit
|
| - // on activation. So, we wait for activation.
|
| - // TODO(danakj): fix this. crbug.com/277953
|
| - layer_tree_host()->SetNeedsCommit();
|
| - break;
|
| - } else {
|
| - ++commit_count_;
|
| - }
|
| - case 5:
|
| - EXPECT_EQ(4, callback_count_);
|
| - // Restore a mailbox for the next step.
|
| - SetMailbox('5');
|
| - break;
|
| - case 6:
|
| - // Case #5: remove layer from tree. Callback should *not* be called, the
|
| - // mailbox is returned to the main thread.
|
| - EXPECT_EQ(4, callback_count_);
|
| - layer_->RemoveFromParent();
|
| - break;
|
| - case 7:
|
| - if (layer_tree_host()->settings().impl_side_painting) {
|
| - // With impl painting, the texture mailbox will still be on the impl
|
| - // thread when the commit finishes, because the layer is not around to
|
| - // block the commit on activation anymore. So, we wait for activation.
|
| - // TODO(danakj): fix this. crbug.com/277953
|
| - layer_tree_host()->SetNeedsCommit();
|
| - break;
|
| - } else {
|
| - ++commit_count_;
|
| - }
|
| - case 8:
|
| - EXPECT_EQ(4, callback_count_);
|
| - // Resetting the mailbox will call the callback now.
|
| - layer_->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - EXPECT_EQ(5, callback_count_);
|
| - EndTest();
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| -
|
| - void AfterTest() override {}
|
| -
|
| - private:
|
| - base::ThreadChecker main_thread_;
|
| - int callback_count_;
|
| - int commit_count_;
|
| - scoped_refptr<Layer> root_;
|
| - scoped_refptr<TextureLayer> layer_;
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
|
| - TextureLayerImplWithMailboxThreadedCallback);
|
| -
|
| -
|
| -class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
|
| - protected:
|
| - 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());
|
| - }
|
| -
|
| - void BeginTest() override {
|
| - gfx::Size bounds(100, 100);
|
| - root_ = Layer::Create();
|
| - root_->SetBounds(bounds);
|
| -
|
| - layer_ = TextureLayer::CreateForMailbox(nullptr);
|
| - layer_->SetIsDrawable(true);
|
| - layer_->SetBounds(bounds);
|
| -
|
| - root_->AddChild(layer_);
|
| - layer_tree_host()->SetRootLayer(root_);
|
| - layer_tree_host()->SetViewportSize(bounds);
|
| - SetMailbox('1');
|
| -
|
| - PostSetNeedsCommitToMainThread();
|
| - }
|
| -
|
| - void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
|
| - ++activate_count_;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| - }
|
| -
|
| - void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
|
| - switch (host_impl->active_tree()->source_frame_number()) {
|
| - case 0: {
|
| - // The activate for the 1st mailbox should have happened before now.
|
| - EXPECT_EQ(1, activate_count_);
|
| - break;
|
| - }
|
| - case 1: {
|
| - // The activate for the 2nd mailbox should have happened before now.
|
| - EXPECT_EQ(2, activate_count_);
|
| - break;
|
| - }
|
| - case 2: {
|
| - // The activate to remove the layer should have happened before now.
|
| - EXPECT_EQ(3, activate_count_);
|
| - break;
|
| - }
|
| - case 3: {
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - 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)) {}
|
| -
|
| - void SetUp() override {
|
| - TextureLayerTest::SetUp();
|
| - layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_));
|
| - EXPECT_TRUE(host_impl_.InitializeRenderer(FakeOutputSurface::Create3d()));
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - FakeLayerTreeHostClient fake_client_;
|
| -};
|
| -
|
| -// Test conditions for results of TextureLayerImpl::WillDraw under
|
| -// different configurations of different mailbox, texture_id, and draw_mode.
|
| -TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
|
| - EXPECT_CALL(
|
| - test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
|
| - .Times(AnyNumber());
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - ReleaseImpl2(test_data_.shared_bitmap_.get(), 0, false, _))
|
| - .Times(AnyNumber());
|
| - // Hardware mode.
|
| - {
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| - EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
|
| - }
|
| -
|
| - {
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
|
| - }
|
| -
|
| - {
|
| - // Software resource.
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(
|
| - test_data_.mailbox3_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
|
| - EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
|
| - }
|
| -
|
| - // Software mode.
|
| - {
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| - EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
|
| - }
|
| -
|
| - {
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
|
| - }
|
| -
|
| - {
|
| - // Software resource.
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(
|
| - test_data_.mailbox3_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
|
| - EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
|
| - }
|
| -
|
| - // Resourceless software mode.
|
| - {
|
| - scoped_ptr<TextureLayerImpl> impl_layer =
|
| - TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - impl_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| - 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);
|
| - ASSERT_TRUE(pending_layer);
|
| -
|
| - scoped_ptr<LayerImpl> active_layer(
|
| - pending_layer->CreateLayerImpl(host_impl_.active_tree()));
|
| - ASSERT_TRUE(active_layer);
|
| -
|
| - pending_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| -
|
| - // Test multiple commits without an activation.
|
| - EXPECT_CALL(
|
| - test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
|
| - .Times(1);
|
| - pending_layer->SetTextureMailbox(
|
| - test_data_.mailbox2_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // Test callback after activation.
|
| - pending_layer->PushPropertiesTo(active_layer.get());
|
| - active_layer->DidBecomeActive();
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
|
| - pending_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
|
| - pending_layer->PushPropertiesTo(active_layer.get());
|
| - active_layer->DidBecomeActive();
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // Test resetting the mailbox.
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
|
| - pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
|
| - pending_layer->PushPropertiesTo(active_layer.get());
|
| - active_layer->DidBecomeActive();
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| -
|
| - // Test destructor.
|
| - EXPECT_CALL(
|
| - test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _))
|
| - .Times(1);
|
| - pending_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| -}
|
| -
|
| -TEST_F(TextureLayerImplWithMailboxTest,
|
| - TestDestructorCallbackOnCreatedResource) {
|
| - scoped_ptr<TextureLayerImpl> impl_layer;
|
| - impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
|
| - ASSERT_TRUE(impl_layer);
|
| -
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
|
| - impl_layer->SetTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| - impl_layer->DidBecomeActive();
|
| - EXPECT_TRUE(impl_layer->WillDraw(
|
| - DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
|
| - impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
|
| - impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
|
| -}
|
| -
|
| -TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
|
| - ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
|
| - ResourceProvider::ResourceId id = provider->CreateResourceFromTextureMailbox(
|
| - test_data_.mailbox1_,
|
| - SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
|
| - provider->AllocateForTesting(id);
|
| -
|
| - // Transfer some resources to the parent.
|
| - ResourceProvider::ResourceIdArray resource_ids_to_transfer;
|
| - resource_ids_to_transfer.push_back(id);
|
| - TransferableResourceArray list;
|
| - provider->PrepareSendToParent(resource_ids_to_transfer, &list);
|
| - EXPECT_TRUE(provider->InUseByConsumer(id));
|
| - EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
|
| - provider->DeleteResource(id);
|
| - Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
|
| - EXPECT_CALL(test_data_.mock_callback_,
|
| - ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
|
| - ReturnedResourceArray returned;
|
| - TransferableResource::ReturnResources(list, &returned);
|
| - provider->ReceiveReturnsFromParent(returned);
|
| -}
|
| -
|
| -// Checks that TextureLayer::Update does not cause an extra commit when setting
|
| -// the texture mailbox.
|
| -class TextureLayerNoExtraCommitForMailboxTest
|
| - : public LayerTreeTest,
|
| - public TextureLayerClient {
|
| - public:
|
| - // TextureLayerClient implementation.
|
| - bool PrepareTextureMailbox(
|
| - TextureMailbox* texture_mailbox,
|
| - scoped_ptr<SingleReleaseCallback>* release_callback,
|
| - bool use_shared_memory) override {
|
| - if (layer_tree_host()->source_frame_number() == 1) {
|
| - // Once this has been committed, the mailbox will be released.
|
| - *texture_mailbox = TextureMailbox();
|
| - return true;
|
| - }
|
| -
|
| - *texture_mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
|
| - *release_callback = SingleReleaseCallback::Create(
|
| - base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
|
| - base::Unretained(this)));
|
| - return true;
|
| - }
|
| -
|
| - void MailboxReleased(uint32 sync_point, bool lost_resource) {
|
| - // Source frame number during callback is the same as the source frame
|
| - // on which it was released.
|
| - EXPECT_EQ(1, layer_tree_host()->source_frame_number());
|
| - EndTest();
|
| - }
|
| -
|
| - void SetupTree() override {
|
| - scoped_refptr<Layer> root = Layer::Create();
|
| - root->SetBounds(gfx::Size(10, 10));
|
| - root->SetIsDrawable(true);
|
| -
|
| - texture_layer_ = TextureLayer::CreateForMailbox(this);
|
| - texture_layer_->SetBounds(gfx::Size(10, 10));
|
| - texture_layer_->SetIsDrawable(true);
|
| - root->AddChild(texture_layer_);
|
| -
|
| - layer_tree_host()->SetRootLayer(root);
|
| - LayerTreeTest::SetupTree();
|
| - }
|
| -
|
| - void BeginTest() override { PostSetNeedsCommitToMainThread(); }
|
| -
|
| - void DidCommitAndDrawFrame() override {
|
| - switch (layer_tree_host()->source_frame_number()) {
|
| - case 1:
|
| - EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
|
| - // Invalidate the texture layer to clear the mailbox before
|
| - // ending the test.
|
| - texture_layer_->SetNeedsDisplay();
|
| - break;
|
| - case 2:
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| -
|
| - void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
|
| - ASSERT_TRUE(result);
|
| - DelegatedFrameData* delegated_frame_data =
|
| - output_surface()->last_sent_frame().delegated_frame_data.get();
|
| - if (!delegated_frame_data)
|
| - return;
|
| -
|
| - // Return all resources immediately.
|
| - TransferableResourceArray resources_to_return =
|
| - output_surface()->resources_held_by_parent();
|
| -
|
| - CompositorFrameAck ack;
|
| - for (size_t i = 0; i < resources_to_return.size(); ++i)
|
| - output_surface()->ReturnResource(resources_to_return[i].id, &ack);
|
| - host_impl->ReclaimResources(&ack);
|
| - }
|
| -
|
| - void AfterTest() override {}
|
| -
|
| - private:
|
| - scoped_refptr<TextureLayer> texture_layer_;
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
|
| -
|
| -// Checks that changing a mailbox in the client for a TextureLayer that's
|
| -// invisible correctly works and uses the new mailbox as soon as the layer
|
| -// becomes visible (and returns the old one).
|
| -class TextureLayerChangeInvisibleMailboxTest
|
| - : public LayerTreeTest,
|
| - public TextureLayerClient {
|
| - public:
|
| - TextureLayerChangeInvisibleMailboxTest()
|
| - : mailbox_changed_(true),
|
| - mailbox_returned_(0),
|
| - prepare_called_(0),
|
| - commit_count_(0) {
|
| - mailbox_ = MakeMailbox('1');
|
| - }
|
| -
|
| - // TextureLayerClient implementation.
|
| - bool PrepareTextureMailbox(
|
| - TextureMailbox* mailbox,
|
| - scoped_ptr<SingleReleaseCallback>* release_callback,
|
| - bool use_shared_memory) override {
|
| - ++prepare_called_;
|
| - if (!mailbox_changed_)
|
| - return false;
|
| - *mailbox = mailbox_;
|
| - *release_callback = SingleReleaseCallback::Create(
|
| - base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
|
| - base::Unretained(this)));
|
| - return true;
|
| - }
|
| -
|
| - TextureMailbox MakeMailbox(char name) {
|
| - return TextureMailbox(MailboxFromChar(name), GL_TEXTURE_2D, 0);
|
| - }
|
| -
|
| - void MailboxReleased(uint32 sync_point, bool lost_resource) {
|
| - ++mailbox_returned_;
|
| - }
|
| -
|
| - void SetupTree() override {
|
| - scoped_refptr<Layer> root = Layer::Create();
|
| - root->SetBounds(gfx::Size(10, 10));
|
| - 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::CreateForMailbox(this);
|
| - texture_layer_->SetBounds(gfx::Size(10, 10));
|
| - texture_layer_->SetIsDrawable(true);
|
| - parent_layer_->AddChild(texture_layer_);
|
| -
|
| - layer_tree_host()->SetRootLayer(root);
|
| - LayerTreeTest::SetupTree();
|
| - }
|
| -
|
| - void BeginTest() override { PostSetNeedsCommitToMainThread(); }
|
| -
|
| - 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_);
|
| - // Change the texture.
|
| - mailbox_ = MakeMailbox('2');
|
| - mailbox_changed_ = true;
|
| - texture_layer_->SetNeedsDisplay();
|
| - // Force a change to make sure we draw a frame.
|
| - solid_layer_->SetBackgroundColor(SK_ColorGRAY);
|
| - break;
|
| - case 3:
|
| - // Layer shouldn't have been updated.
|
| - EXPECT_EQ(1, prepare_called_);
|
| - // So the old mailbox isn't returned yet.
|
| - EXPECT_EQ(0, mailbox_returned_);
|
| - // Make layer visible again.
|
| - parent_layer_->SetOpacity(1.f);
|
| - break;
|
| - case 4:
|
| - // Layer should have been updated.
|
| - EXPECT_EQ(2, prepare_called_);
|
| - // So the old mailbox should have been returned already.
|
| - EXPECT_EQ(1, mailbox_returned_);
|
| - texture_layer_->ClearClient();
|
| - break;
|
| - case 5:
|
| - EXPECT_EQ(2, mailbox_returned_);
|
| - EndTest();
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| -
|
| - void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
|
| - ASSERT_TRUE(result);
|
| - DelegatedFrameData* delegated_frame_data =
|
| - output_surface()->last_sent_frame().delegated_frame_data.get();
|
| - if (!delegated_frame_data)
|
| - return;
|
| -
|
| - // Return all resources immediately.
|
| - TransferableResourceArray resources_to_return =
|
| - output_surface()->resources_held_by_parent();
|
| -
|
| - CompositorFrameAck ack;
|
| - for (size_t i = 0; i < resources_to_return.size(); ++i)
|
| - output_surface()->ReturnResource(resources_to_return[i].id, &ack);
|
| - host_impl->ReclaimResources(&ack);
|
| - }
|
| -
|
| - void AfterTest() override {}
|
| -
|
| - private:
|
| - scoped_refptr<SolidColorLayer> solid_layer_;
|
| - scoped_refptr<Layer> parent_layer_;
|
| - scoped_refptr<TextureLayer> texture_layer_;
|
| -
|
| - // Used on the main thread.
|
| - bool mailbox_changed_;
|
| - TextureMailbox mailbox_;
|
| - int mailbox_returned_;
|
| - int prepare_called_;
|
| - int commit_count_;
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
|
| -
|
| -// Test that TextureLayerImpl::ReleaseResources can be called which releases
|
| -// the mailbox back to TextureLayerClient.
|
| -class TextureLayerReleaseResourcesBase
|
| - : public LayerTreeTest,
|
| - public TextureLayerClient {
|
| - public:
|
| - // TextureLayerClient implementation.
|
| - bool PrepareTextureMailbox(
|
| - TextureMailbox* mailbox,
|
| - scoped_ptr<SingleReleaseCallback>* release_callback,
|
| - bool use_shared_memory) override {
|
| - *mailbox = TextureMailbox(MailboxFromChar('1'), GL_TEXTURE_2D, 0);
|
| - *release_callback = SingleReleaseCallback::Create(
|
| - base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
|
| - base::Unretained(this)));
|
| - return true;
|
| - }
|
| -
|
| - void MailboxReleased(unsigned sync_point, bool lost_resource) {
|
| - mailbox_released_ = true;
|
| - }
|
| -
|
| - void SetupTree() override {
|
| - LayerTreeTest::SetupTree();
|
| -
|
| - scoped_refptr<TextureLayer> texture_layer =
|
| - TextureLayer::CreateForMailbox(this);
|
| - texture_layer->SetBounds(gfx::Size(10, 10));
|
| - texture_layer->SetIsDrawable(true);
|
| -
|
| - layer_tree_host()->root_layer()->AddChild(texture_layer);
|
| - }
|
| -
|
| - void BeginTest() override {
|
| - mailbox_released_ = false;
|
| - PostSetNeedsCommitToMainThread();
|
| - }
|
| -
|
| - void DidCommitAndDrawFrame() override { EndTest(); }
|
| -
|
| - void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
|
| -
|
| - private:
|
| - bool mailbox_released_;
|
| -};
|
| -
|
| -class TextureLayerReleaseResourcesAfterCommit
|
| - : public TextureLayerReleaseResourcesBase {
|
| - public:
|
| - void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
|
| - LayerTreeImpl* tree = nullptr;
|
| - tree = host_impl->sync_tree();
|
| - tree->root_layer()->children()[0]->ReleaseResources();
|
| - }
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
|
| -
|
| -class TextureLayerReleaseResourcesAfterActivate
|
| - : public TextureLayerReleaseResourcesBase {
|
| - public:
|
| - void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
|
| - host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
|
| - }
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
|
| -
|
| -class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
|
| - public:
|
| - void ReleaseCallback(uint32 sync_point, bool lost_resource) {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| - EXPECT_FALSE(lost_resource);
|
| - ++callback_count_;
|
| - EndTest();
|
| - }
|
| -
|
| - void SetMailbox(char mailbox_char) {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
|
| - base::Bind(
|
| - &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
|
| - base::Unretained(this)));
|
| - layer_->SetTextureMailbox(
|
| - TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
|
| - callback.Pass());
|
| - }
|
| -
|
| - void SetupTree() override {
|
| - gfx::Size bounds(100, 100);
|
| - root_ = Layer::Create();
|
| - root_->SetBounds(bounds);
|
| -
|
| - layer_ = TextureLayer::CreateForMailbox(nullptr);
|
| - layer_->SetIsDrawable(true);
|
| - layer_->SetBounds(bounds);
|
| -
|
| - root_->AddChild(layer_);
|
| - layer_tree_host()->SetRootLayer(root_);
|
| - layer_tree_host()->SetViewportSize(bounds);
|
| - }
|
| -
|
| - void BeginTest() override {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| -
|
| - callback_count_ = 0;
|
| -
|
| - // Set the mailbox on the main thread.
|
| - SetMailbox('1');
|
| - EXPECT_EQ(0, callback_count_);
|
| -
|
| - PostSetNeedsCommitToMainThread();
|
| - }
|
| -
|
| - void DidCommitAndDrawFrame() override {
|
| - switch (layer_tree_host()->source_frame_number()) {
|
| - case 1:
|
| - // Delete the TextureLayer on the main thread while the mailbox is in
|
| - // the impl tree.
|
| - layer_->RemoveFromParent();
|
| - layer_ = nullptr;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - void AfterTest() override { EXPECT_EQ(1, callback_count_); }
|
| -
|
| - private:
|
| - base::ThreadChecker main_thread_;
|
| - int callback_count_;
|
| - scoped_refptr<Layer> root_;
|
| - scoped_refptr<TextureLayer> layer_;
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
|
| - TextureLayerWithMailboxMainThreadDeleted);
|
| -
|
| -class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
|
| - public:
|
| - void ReleaseCallback(uint32 sync_point, bool lost_resource) {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| - EXPECT_FALSE(lost_resource);
|
| - ++callback_count_;
|
| - EndTest();
|
| - }
|
| -
|
| - void SetMailbox(char mailbox_char) {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
|
| - base::Bind(
|
| - &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
|
| - base::Unretained(this)));
|
| - layer_->SetTextureMailbox(
|
| - TextureMailbox(MailboxFromChar(mailbox_char), GL_TEXTURE_2D, 0),
|
| - callback.Pass());
|
| - }
|
| -
|
| - void SetupTree() override {
|
| - gfx::Size bounds(100, 100);
|
| - root_ = Layer::Create();
|
| - root_->SetBounds(bounds);
|
| -
|
| - layer_ = TextureLayer::CreateForMailbox(nullptr);
|
| - layer_->SetIsDrawable(true);
|
| - layer_->SetBounds(bounds);
|
| -
|
| - root_->AddChild(layer_);
|
| - layer_tree_host()->SetRootLayer(root_);
|
| - layer_tree_host()->SetViewportSize(bounds);
|
| - }
|
| -
|
| - void BeginTest() override {
|
| - EXPECT_EQ(true, main_thread_.CalledOnValidThread());
|
| -
|
| - callback_count_ = 0;
|
| -
|
| - // Set the mailbox on the main thread.
|
| - SetMailbox('1');
|
| - EXPECT_EQ(0, callback_count_);
|
| -
|
| - PostSetNeedsCommitToMainThread();
|
| - }
|
| -
|
| - void DidCommitAndDrawFrame() override {
|
| - switch (layer_tree_host()->source_frame_number()) {
|
| - case 1:
|
| - // Remove the TextureLayer on the main thread while the mailbox is in
|
| - // the impl tree, but don't delete the TextureLayer until after the impl
|
| - // tree side is deleted.
|
| - layer_->RemoveFromParent();
|
| - break;
|
| - case 2:
|
| - layer_ = nullptr;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - void AfterTest() override { EXPECT_EQ(1, callback_count_); }
|
| -
|
| - private:
|
| - base::ThreadChecker main_thread_;
|
| - int callback_count_;
|
| - scoped_refptr<Layer> root_;
|
| - scoped_refptr<TextureLayer> layer_;
|
| -};
|
| -
|
| -SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
|
| - TextureLayerWithMailboxImplThreadDeleted);
|
| -
|
| -} // namespace
|
| -} // namespace cc
|
|
|