This source file includes following definitions.
- MailboxFromChar
- mailbox_changed_
- PrepareTexture
- PrepareTextureMailbox
- set_texture
- set_mailbox
- host_impl_
- SetUp
- TearDown
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TearDown
- TEST_F
- TEST_F
- Wait
- CreateMainRef
- ReleaseMainRef
- CreateImplRef
- CapturePostTasksAndWait
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- commit_count_
- ReleaseCallback
- SetMailbox
- BeginTest
- DidCommit
- AfterTest
- activate_count_
- BeginTest
- CreateFakeOutputSurface
- PrepareTexture
- PrepareTextureMailbox
- WillActivateTreeOnThread
- DidCommit
- CommitCompleteOnThread
- AfterTest
- ReleaseCallback
- SetMailbox
- BeginTest
- WillActivateTreeOnThread
- DidCommit
- CommitCompleteOnThread
- AfterTest
- SetUp
- WillDraw
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- expected_used_textures_on_commit_
- CreateFakeOutputSurface
- PrepareTexture
- PrepareTextureMailbox
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- BeginCommitOnThread
- PrepareToDrawOnThread
- SwapBuffersOnThread
- AfterTest
- ContextForImplThread
- expected_texture_on_draw_
- CreateFakeOutputSurface
- PrepareTexture
- PrepareTextureMailbox
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- BeginCommitOnThread
- PrepareToDrawOnThread
- SwapBuffersOnThread
- AfterTest
- ContextForImplThread
- PrepareTexture
- PrepareTextureMailbox
- MailboxReleased
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- AfterTest
- commit_count_
- PrepareTexture
- PrepareTextureMailbox
- MakeMailbox
- MailboxReleased
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- SwapBuffersOnThread
- AfterTest
- PrepareTexture
- PrepareTextureMailbox
- MailboxReleased
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- AfterTest
- CommitCompleteOnThread
- DidActivateTreeOnThread
- draw_count_
- CreateFakeOutputSurface
- PrepareTexture
- PrepareTextureMailbox
- SetupTree
- BeginTest
- PrepareToDrawOnThread
- DidCommitAndDrawFrame
- AfterTest
- ReleaseCallback
- SetMailbox
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- AfterTest
- ReleaseCallback
- SetMailbox
- SetupTree
- BeginTest
- DidCommitAndDrawFrame
- AfterTest
#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_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, NULL, LayerTreeSettings()) {
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() : texture_(0), mailbox_changed_(true) {}
virtual unsigned PrepareTexture() OVERRIDE { return texture_; }
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_texture(unsigned texture) { texture_ = texture; }
void set_mailbox(const TextureMailbox& mailbox,
scoped_ptr<SingleReleaseCallback> release_callback) {
mailbox_ = mailbox;
release_callback_ = release_callback.Pass();
mailbox_changed_ = true;
}
private:
unsigned texture_;
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()
: fake_client_(
FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
host_impl_(&proxy_, &shared_bitmap_manager_) {}
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);
layer_tree_host_.reset();
}
scoped_ptr<MockLayerTreeHost> layer_tree_host_;
FakeImplProxy proxy_;
FakeLayerTreeHostClient fake_client_;
TestSharedBitmapManager shared_bitmap_manager_;
FakeLayerTreeHostImpl host_impl_;
};
TEST_F(TextureLayerTest, SyncImplWhenClearingTexture) {
scoped_ptr<TestWebGraphicsContext3D> context(
TestWebGraphicsContext3D::Create());
FakeTextureLayerClient client;
scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(&client);
ASSERT_TRUE(test_layer.get());
test_layer->SetIsDrawable(true);
test_layer->SetBounds(gfx::Size(10, 10));
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_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(0);
test_layer->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
client.set_texture(context->createTexture());
test_layer->SetNeedsDisplay();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
layer_tree_host_->Composite(base::TimeTicks());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1));
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0);
test_layer->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
test_layer->SetNeedsDisplay();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
layer_tree_host_->Composite(base::TimeTicks());
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->SetIsDrawable(false);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
layer_tree_host_->Composite(base::TimeTicks());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}
TEST_F(TextureLayerTest, SyncImplWhenClearingMailbox) {
CommonMailboxObjects mailboxes;
FakeTextureLayerClient client;
scoped_refptr<TextureLayer> test_layer =
TextureLayer::CreateForMailbox(&client);
ASSERT_TRUE(test_layer.get());
test_layer->SetIsDrawable(true);
test_layer->SetBounds(gfx::Size(10, 10));
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_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->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
client.set_mailbox(
mailboxes.mailbox1_,
SingleReleaseCallback::Create(mailboxes.release_mailbox1_));
EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
test_layer->SetNeedsDisplay();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
layer_tree_host_->Composite(base::TimeTicks());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(mailboxes.mock_callback_,
Release(mailboxes.mailbox_name1_, _, false));
layer_tree_host_->Composite(base::TimeTicks());
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
client.set_mailbox(
mailboxes.mailbox2_,
SingleReleaseCallback::Create(mailboxes.release_mailbox2_));
EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(AtLeast(1));
test_layer->SetNeedsDisplay();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
layer_tree_host_->Composite(base::TimeTicks());
EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
test_layer->SetIsDrawable(false);
layer_tree_host_->Composite(base::TimeTicks());
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->ClearTexture();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(mailboxes.mock_callback_,
Release(mailboxes.mailbox_name2_, _, false));
layer_tree_host_->Composite(base::TimeTicks());
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
}
TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) {
scoped_ptr<TestWebGraphicsContext3D> context(
TestWebGraphicsContext3D::Create());
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);
FakeTextureLayerClient client;
scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(&client);
test_layer->SetIsDrawable(true);
test_layer->SetBounds(gfx::Size(10, 10));
ASSERT_TRUE(test_layer.get());
child_layer->AddChild(test_layer);
EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0);
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_, SetNeedsUpdateLayers()).Times(AtLeast(1));
client.set_texture(context->createTexture());
test_layer->SetNeedsDisplay();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
layer_tree_host_->Composite(base::TimeTicks());
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);
EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
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::Create(NULL);
layer->SetBounds(layer_bounds);
layer->draw_properties().visible_content_rect = layer_rect;
layer->SetBlendBackgroundColor(true);
EXPECT_FALSE(layer->contents_opaque());
EXPECT_EQ(0u, layer->background_color());
EXPECT_EQ(Region().ToString(),
layer->VisibleContentOpaqueRegion().ToString());
layer->SetBackgroundColor(SK_ColorWHITE);
EXPECT_EQ(layer_region.ToString(),
layer->VisibleContentOpaqueRegion().ToString());
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);
EXPECT_CALL(*layer_tree_host_, StartRateLimiter()).Times(0);
test_layer->SetRateLimitContext(true);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, StartRateLimiter());
test_layer->SetNeedsDisplay();
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
EXPECT_CALL(*layer_tree_host_, StopRateLimiter());
test_layer->SetRateLimitContext(false);
Mock::VerifyAndClearExpectations(layer_tree_host_.get());
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());
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());
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 TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
public:
using TextureLayer::TextureMailboxHolder::Create;
protected:
virtual ~TestMailboxHolder() {}
};
class TextureLayerWithMailboxTest : public TextureLayerTest {
protected:
virtual void TearDown() {
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();
}
CommonMailboxObjects test_data_;
};
TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
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_,
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_, AcquireLayerTextures()).Times(0);
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(),
scoped_ptr<SingleReleaseCallback>());
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_,
SingleReleaseCallback::Create(test_data_.release_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(),
0, false))
.Times(1);
test_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
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_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
}
TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
ASSERT_TRUE(test_layer.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());
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());
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());
}
class TextureLayerMailboxHolderTest : public TextureLayerTest {
public:
TextureLayerMailboxHolderTest()
: main_thread_("MAIN") {
main_thread_.Start();
}
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_.reset();
}
void CreateImplRef(scoped_ptr<SingleReleaseCallback>* 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;
wait_for_capture->Signal();
stop_capture->Wait();
}
protected:
scoped_ptr<TestMailboxHolder::MainThreadReference>
main_ref_;
base::Thread main_thread_;
CommonMailboxObjects test_data_;
};
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
base::Unretained(this)));
Wait(main_thread_);
scoped_ptr<SingleReleaseCallback> compositor1;
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
base::Unretained(this),
&compositor1));
scoped_ptr<SingleReleaseCallback> 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_);
compositor1->Run(100, false);
compositor2->Run(200, false);
Wait(main_thread_);
EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
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(NULL);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
base::Unretained(this)));
Wait(main_thread_);
scoped_ptr<SingleReleaseCallback> compositor1;
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
base::Unretained(this),
&compositor1));
scoped_ptr<SingleReleaseCallback> 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_);
compositor1->Run(100, false);
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_);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_, 200, true)).Times(1);
compositor2->Run(200, true);
Wait(main_thread_);
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
}
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
base::Unretained(this)));
Wait(main_thread_);
scoped_ptr<SingleReleaseCallback> compositor1;
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
base::Unretained(this),
&compositor1));
scoped_ptr<SingleReleaseCallback> 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_);
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
base::Unretained(this)));
compositor2->Run(200, false);
Wait(main_thread_);
EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_, 100, true)).Times(1);
compositor1->Run(100, true);
Wait(main_thread_);
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
}
TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL);
ASSERT_TRUE(test_layer.get());
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
base::Unretained(this)));
Wait(main_thread_);
scoped_ptr<SingleReleaseCallback> compositor1;
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
base::Unretained(this),
&compositor1));
scoped_ptr<SingleReleaseCallback> 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_);
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);
main_thread_.message_loop()->PostTask(
FROM_HERE,
base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
base::Unretained(this),
&begin_capture,
&wait_for_capture,
&stop_capture));
compositor1->Run(100, false);
begin_capture.Signal();
wait_for_capture.Wait();
compositor2->Run(200, true);
stop_capture.Signal();
Wait(main_thread_);
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
}
class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
public:
TextureLayerImplWithMailboxThreadedCallback()
: callback_count_(0),
commit_count_(0) {}
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());
}
virtual void BeginTest() OVERRIDE {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
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');
EXPECT_EQ(0, callback_count_);
SetMailbox('2');
EXPECT_EQ(1, callback_count_);
PostSetNeedsCommitToMainThread();
}
virtual void DidCommit() OVERRIDE {
++commit_count_;
switch (commit_count_) {
case 1:
SetMailbox('3');
EXPECT_EQ(1, callback_count_);
break;
case 2:
EXPECT_EQ(2, callback_count_);
layer_->SetBounds(gfx::Size());
SetMailbox('4');
break;
case 3:
EXPECT_EQ(3, callback_count_);
layer_->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
break;
case 4:
if (layer_tree_host()->settings().impl_side_painting) {
layer_tree_host()->SetNeedsCommit();
break;
} else {
++commit_count_;
}
case 5:
EXPECT_EQ(4, callback_count_);
SetMailbox('5');
break;
case 6:
EXPECT_EQ(4, callback_count_);
layer_->RemoveFromParent();
break;
case 7:
if (layer_tree_host()->settings().impl_side_painting) {
layer_tree_host()->SetNeedsCommit();
break;
} else {
++commit_count_;
}
case 8:
EXPECT_EQ(4, callback_count_);
layer_->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
EXPECT_EQ(5, callback_count_);
EndTest();
break;
default:
NOTREACHED();
break;
}
}
virtual 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 TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest,
public TextureLayerClient {
protected:
TextureLayerNoMailboxIsActivatedDuringCommit()
: texture_(0u), activate_count_(0) {}
virtual void BeginTest() OVERRIDE {
gfx::Size bounds(100, 100);
root_ = Layer::Create();
root_->SetAnchorPoint(gfx::PointF());
root_->SetBounds(bounds);
layer_ = TextureLayer::Create(this);
layer_->SetIsDrawable(true);
layer_->SetAnchorPoint(gfx::PointF());
layer_->SetBounds(bounds);
root_->AddChild(layer_);
layer_tree_host()->SetRootLayer(root_);
layer_tree_host()->SetViewportSize(bounds);
PostSetNeedsCommitToMainThread();
}
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 WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
++activate_count_;
}
virtual void DidCommit() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
case 1:
layer_->SetNeedsDisplay();
break;
case 2:
layer_->RemoveFromParent();
break;
case 3:
EndTest();
break;
}
}
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
switch (host_impl->active_tree()->source_frame_number()) {
case 2: {
EXPECT_EQ(2, activate_count_);
break;
}
case 3: {
EXPECT_EQ(3, 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);
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());
}
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:
SetMailbox('2');
break;
case 2:
layer_->RemoveFromParent();
break;
case 3:
EndTest();
break;
}
}
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
switch (host_impl->active_tree()->source_frame_number()) {
case 2: {
EXPECT_EQ(2, activate_count_);
break;
}
case 3: {
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;
}
CommonMailboxObjects test_data_;
FakeLayerTreeHostClient fake_client_;
};
TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_,
test_data_.sync_point1_,
false))
.Times(AnyNumber());
EXPECT_CALL(test_data_.mock_callback_,
Release2(test_data_.shared_memory_.get(), 0, false))
.Times(AnyNumber());
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
}
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
}
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox3_,
SingleReleaseCallback::Create(test_data_.release_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));
}
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
}
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
}
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox3_,
SingleReleaseCallback::Create(test_data_.release_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));
}
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
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);
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_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_,
test_data_.sync_point1_,
false))
.Times(1);
pending_layer->SetTextureMailbox(
test_data_.mailbox2_,
SingleReleaseCallback::Create(test_data_.release_mailbox2_));
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
pending_layer->PushPropertiesTo(active_layer.get());
active_layer->DidBecomeActive();
EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
pending_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name2_, _, false))
.Times(1);
pending_layer->PushPropertiesTo(active_layer.get());
active_layer->DidBecomeActive();
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_, _, false))
.Times(1);
pending_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
pending_layer->PushPropertiesTo(active_layer.get());
active_layer->DidBecomeActive();
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_,
test_data_.sync_point1_,
false))
.Times(1);
pending_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
}
TEST_F(TextureLayerImplWithMailboxTest,
TestDestructorCallbackOnCreatedResource) {
scoped_ptr<TextureLayerImpl> impl_layer;
impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
ASSERT_TRUE(impl_layer);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_, _, false))
.Times(1);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
impl_layer->SetDrawsContent(true);
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(),
scoped_ptr<SingleReleaseCallback>());
}
TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
ResourceProvider::ResourceId id =
provider->CreateResourceFromTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
provider->AllocateForTesting(id);
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_, Release(_, _, _)).Times(0);
provider->DeleteResource(id);
Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
EXPECT_CALL(test_data_.mock_callback_,
Release(test_data_.mailbox_name1_, _, false))
.Times(1);
ReturnedResourceArray returned;
TransferableResource::ReturnResources(list, &returned);
provider->ReceiveReturnsFromParent(returned);
}
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_;
unsigned expected_used_textures_on_draw_;
base::Lock lock_;
unsigned expected_used_textures_on_commit_;
};
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest);
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);
}
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:
EXPECT_EQ(1, prepare_called_);
parent_layer_->SetOpacity(0.f);
break;
case 2: {
EXPECT_EQ(1, prepare_called_);
texture_layer_->SetNeedsDisplay();
solid_layer_->SetBackgroundColor(SK_ColorGRAY);
break;
}
case 3:
EXPECT_EQ(1, prepare_called_);
parent_layer_->SetOpacity(1.f);
break;
case 4: {
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());
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_;
unsigned texture_;
int prepare_called_;
int commit_count_;
unsigned expected_texture_on_draw_;
};
SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerChangeInvisibleTest);
class TextureLayerNoExtraCommitForMailboxTest
: public LayerTreeTest,
public TextureLayerClient {
public:
virtual unsigned PrepareTexture() OVERRIDE {
NOTREACHED();
return 0;
}
virtual bool PrepareTextureMailbox(
TextureMailbox* texture_mailbox,
scoped_ptr<SingleReleaseCallback>* release_callback,
bool use_shared_memory) OVERRIDE {
if (layer_tree_host()->source_frame_number() == 1) {
*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) {
EXPECT_EQ(2, layer_tree_host()->source_frame_number());
EndTest();
}
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::CreateForMailbox(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();
}
virtual void BeginTest() OVERRIDE {
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
case 1:
EXPECT_FALSE(proxy()->CommitPendingForTesting());
texture_layer_->SetNeedsDisplay();
break;
case 2:
break;
default:
NOTREACHED();
break;
}
}
virtual 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;
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);
host_impl->OnSwapBuffersComplete();
}
virtual void AfterTest() OVERRIDE {}
private:
scoped_refptr<TextureLayer> texture_layer_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
class TextureLayerChangeInvisibleMailboxTest
: public LayerTreeTest,
public TextureLayerClient {
public:
TextureLayerChangeInvisibleMailboxTest()
: mailbox_changed_(true),
mailbox_returned_(0),
prepare_called_(0),
commit_count_(0) {
mailbox_ = MakeMailbox('1');
}
virtual unsigned PrepareTexture() OVERRIDE {
NOTREACHED();
return 0;
}
virtual 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_;
}
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::CreateForMailbox(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:
EXPECT_EQ(1, prepare_called_);
parent_layer_->SetOpacity(0.f);
break;
case 2:
EXPECT_EQ(1, prepare_called_);
mailbox_ = MakeMailbox('2');
mailbox_changed_ = true;
texture_layer_->SetNeedsDisplay();
solid_layer_->SetBackgroundColor(SK_ColorGRAY);
break;
case 3:
EXPECT_EQ(1, prepare_called_);
EXPECT_EQ(0, mailbox_returned_);
parent_layer_->SetOpacity(1.f);
break;
case 4:
EXPECT_EQ(2, prepare_called_);
EXPECT_EQ(1, mailbox_returned_);
texture_layer_->ClearClient();
break;
case 5:
EXPECT_EQ(2, mailbox_returned_);
EndTest();
break;
default:
NOTREACHED();
break;
}
}
virtual 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;
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);
host_impl->OnSwapBuffersComplete();
}
virtual void AfterTest() OVERRIDE {}
private:
scoped_refptr<SolidColorLayer> solid_layer_;
scoped_refptr<Layer> parent_layer_;
scoped_refptr<TextureLayer> texture_layer_;
bool mailbox_changed_;
TextureMailbox mailbox_;
int mailbox_returned_;
int prepare_called_;
int commit_count_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
class TextureLayerReleaseResourcesBase
: public LayerTreeTest,
public TextureLayerClient {
public:
virtual unsigned PrepareTexture() OVERRIDE {
NOTREACHED();
return 0;
}
virtual 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;
}
virtual void SetupTree() OVERRIDE {
LayerTreeTest::SetupTree();
scoped_refptr<TextureLayer> texture_layer =
TextureLayer::CreateForMailbox(this);
texture_layer->SetBounds(gfx::Size(10, 10));
texture_layer->SetAnchorPoint(gfx::PointF());
texture_layer->SetIsDrawable(true);
layer_tree_host()->root_layer()->AddChild(texture_layer);
}
virtual void BeginTest() OVERRIDE {
mailbox_released_ = false;
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
EndTest();
}
virtual void AfterTest() OVERRIDE {
EXPECT_TRUE(mailbox_released_);
}
private:
bool mailbox_released_;
};
class TextureLayerReleaseResourcesAfterCommit
: public TextureLayerReleaseResourcesBase {
public:
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
LayerTreeImpl* tree = NULL;
if (host_impl->settings().impl_side_painting)
tree = host_impl->pending_tree();
else
tree = host_impl->active_tree();
tree->root_layer()->children()[0]->ReleaseResources();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
class TextureLayerReleaseResourcesAfterActivate
: public TextureLayerReleaseResourcesBase {
public:
virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
}
};
SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
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) {
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());
}
virtual void SetupTree() 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);
}
virtual void BeginTest() OVERRIDE {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
callback_count_ = 0;
SetMailbox('1');
EXPECT_EQ(0, callback_count_);
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
case 1:
layer_->RemoveFromParent();
layer_ = NULL;
break;
}
}
virtual 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());
}
virtual void SetupTree() 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);
}
virtual void BeginTest() OVERRIDE {
EXPECT_EQ(true, main_thread_.CalledOnValidThread());
callback_count_ = 0;
SetMailbox('1');
EXPECT_EQ(0, callback_count_);
PostSetNeedsCommitToMainThread();
}
virtual void DidCommitAndDrawFrame() OVERRIDE {
switch (layer_tree_host()->source_frame_number()) {
case 1:
layer_->RemoveFromParent();
break;
case 2:
layer_ = NULL;
break;
}
}
virtual 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);
}
}