blob: 7c982c81ad3260b9dcd0b320ba425a2765275e0a [file] [log] [blame]
[email protected]c0dd24c2012-08-30 23:25:271// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cc3cfaa2013-03-18 09:05:525#include "cc/layers/texture_layer.h"
[email protected]c0dd24c2012-08-30 23:25:276
[email protected]b04264f92013-09-13 23:37:297#include <algorithm>
[email protected]de44a152013-01-08 15:28:468#include <string>
9
[email protected]b04264f92013-09-13 23:37:2910#include "base/bind.h"
[email protected]de44a152013-01-08 15:28:4611#include "base/callback.h"
skyostil0fd1dad2015-04-13 20:11:4812#include "base/location.h"
13#include "base/single_thread_task_runner.h"
danakj3c3973b2015-08-25 21:50:1814#include "base/synchronization/lock.h"
[email protected]9794fb32013-08-29 09:49:5915#include "base/synchronization/waitable_event.h"
skyostil0fd1dad2015-04-13 20:11:4816#include "base/thread_task_runner_handle.h"
[email protected]74b43cc2013-08-30 06:29:2717#include "base/threading/thread.h"
18#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2919#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5420#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5221#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2922#include "cc/output/compositor_frame_ack.h"
23#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4524#include "cc/resources/returned_resource.h"
khushalsagarb64b360d2015-10-21 19:25:1625#include "cc/test/fake_impl_task_runner_provider.h"
[email protected]101441ce2012-10-16 01:45:0326#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4527#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3428#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2129#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1030#include "cc/test/layer_tree_test.h"
reveman34b7a1522015-03-23 20:27:4731#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5932#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5933#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0434#include "cc/trees/layer_tree_host.h"
35#include "cc/trees/layer_tree_impl.h"
36#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5437#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1838#include "testing/gmock/include/gmock/gmock.h"
39#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2740
[email protected]c0dd24c2012-08-30 23:25:2741using ::testing::Mock;
42using ::testing::_;
43using ::testing::AtLeast;
44using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0945using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2746
[email protected]ba565742012-11-10 09:29:4847namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2748namespace {
49
[email protected]e0a4d732014-02-15 00:23:2650gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5051 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2652 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5053 return mailbox;
54}
55
[email protected]408b5e22013-03-19 09:48:0956class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1557 public:
danakjcf610582015-06-16 22:48:5658 static scoped_ptr<MockLayerTreeHost> Create(
59 FakeLayerTreeHostClient* client,
60 TaskGraphRunner* task_graph_runner) {
sadrul6780f3da2015-05-11 17:01:5261 LayerTreeHost::InitParams params;
62 params.client = client;
danakjcf610582015-06-16 22:48:5663 params.task_graph_runner = task_graph_runner;
sadrul6780f3da2015-05-11 17:01:5264 LayerTreeSettings settings;
65 params.settings = &settings;
66 return make_scoped_ptr(new MockLayerTreeHost(client, &params));
[email protected]28571b042013-03-14 07:59:1567 }
[email protected]c0dd24c2012-08-30 23:25:2768
[email protected]28571b042013-03-14 07:59:1569 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5070 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5471 MOCK_METHOD0(StartRateLimiter, void());
72 MOCK_METHOD0(StopRateLimiter, void());
sadrul6780f3da2015-05-11 17:01:5273
74 private:
75 MockLayerTreeHost(FakeLayerTreeHostClient* client,
76 LayerTreeHost::InitParams* params)
77 : LayerTreeHost(params) {
78 InitializeSingleThreaded(client, base::ThreadTaskRunnerHandle::Get(),
79 nullptr);
80 }
[email protected]c0dd24c2012-08-30 23:25:2781};
82
[email protected]d72d9e02014-04-03 18:40:0983class FakeTextureLayerClient : public TextureLayerClient {
84 public:
[email protected]17e08432014-04-10 00:41:1185 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0986
dcheng716bedf2014-10-21 09:51:0887 bool PrepareTextureMailbox(
[email protected]d72d9e02014-04-03 18:40:0988 TextureMailbox* mailbox,
89 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:3790 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:0991 if (!mailbox_changed_)
92 return false;
93
94 *mailbox = mailbox_;
danakja04855a2015-11-18 20:39:1095 *release_callback = std::move(release_callback_);
[email protected]d72d9e02014-04-03 18:40:0996 mailbox_changed_ = false;
97 return true;
98 }
99
[email protected]d72d9e02014-04-03 18:40:09100 void set_mailbox(const TextureMailbox& mailbox,
101 scoped_ptr<SingleReleaseCallback> release_callback) {
102 mailbox_ = mailbox;
danakja04855a2015-11-18 20:39:10103 release_callback_ = std::move(release_callback);
[email protected]d72d9e02014-04-03 18:40:09104 mailbox_changed_ = true;
105 }
106
107 private:
[email protected]d72d9e02014-04-03 18:40:09108 TextureMailbox mailbox_;
109 scoped_ptr<SingleReleaseCallback> release_callback_;
110 bool mailbox_changed_;
111 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
112};
113
114class MockMailboxCallback {
115 public:
116 MOCK_METHOD3(Release,
117 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04118 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09119 bool lost_resource));
120 MOCK_METHOD3(Release2,
jbauman9015c8b2014-12-11 00:49:37121 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04122 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09123 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23124 MOCK_METHOD4(ReleaseImpl,
125 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04126 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23127 bool lost_resource,
128 BlockingTaskRunner* main_thread_task_runner));
129 MOCK_METHOD4(ReleaseImpl2,
jbauman9015c8b2014-12-11 00:49:37130 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04131 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23132 bool lost_resource,
133 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09134};
135
136struct CommonMailboxObjects {
jbauman9015c8b2014-12-11 00:49:37137 explicit CommonMailboxObjects(SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09138 : mailbox_name1_(MailboxFromChar('1')),
139 mailbox_name2_(MailboxFromChar('2')),
dyencc16ed4d2015-11-03 20:03:04140 sync_token1_(1),
141 sync_token2_(2) {
[email protected]d72d9e02014-04-03 18:40:09142 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
143 base::Unretained(&mock_callback_),
144 mailbox_name1_);
145 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
146 base::Unretained(&mock_callback_),
147 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23148 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
149 base::Unretained(&mock_callback_),
150 mailbox_name1_);
151 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
152 base::Unretained(&mock_callback_),
153 mailbox_name2_);
[email protected]d72d9e02014-04-03 18:40:09154 const uint32 arbitrary_target1 = GL_TEXTURE_2D;
155 const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
dyencc16ed4d2015-11-03 20:03:04156 mailbox1_ = TextureMailbox(mailbox_name1_, sync_token1_, arbitrary_target1);
157 mailbox2_ = TextureMailbox(mailbox_name2_, sync_token2_, arbitrary_target2);
[email protected]d72d9e02014-04-03 18:40:09158 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37159 shared_bitmap_ = manager->AllocateSharedBitmap(size);
160 DCHECK(shared_bitmap_);
161 release_mailbox3_ =
162 base::Bind(&MockMailboxCallback::Release2,
163 base::Unretained(&mock_callback_), shared_bitmap_.get());
164 release_mailbox3_impl_ =
165 base::Bind(&MockMailboxCallback::ReleaseImpl2,
166 base::Unretained(&mock_callback_), shared_bitmap_.get());
167 mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
[email protected]d72d9e02014-04-03 18:40:09168 }
169
170 gpu::Mailbox mailbox_name1_;
171 gpu::Mailbox mailbox_name2_;
172 MockMailboxCallback mock_callback_;
173 ReleaseCallback release_mailbox1_;
174 ReleaseCallback release_mailbox2_;
175 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23176 ReleaseCallbackImpl release_mailbox1_impl_;
177 ReleaseCallbackImpl release_mailbox2_impl_;
178 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09179 TextureMailbox mailbox1_;
180 TextureMailbox mailbox2_;
181 TextureMailbox mailbox3_;
dyencc16ed4d2015-11-03 20:03:04182 gpu::SyncToken sync_token1_;
183 gpu::SyncToken sync_token2_;
jbauman9015c8b2014-12-11 00:49:37184 scoped_ptr<SharedBitmap> shared_bitmap_;
[email protected]d72d9e02014-04-03 18:40:09185};
186
[email protected]31d4df82013-07-18 10:17:22187class TextureLayerTest : public testing::Test {
188 public:
189 TextureLayerTest()
190 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45191 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
revemand180dfc32015-09-24 00:19:43192 output_surface_(FakeOutputSurface::Create3d()),
khushalsagarb64b360d2015-10-21 19:25:16193 host_impl_(&task_runner_provider_,
194 &shared_bitmap_manager_,
195 &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37196 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22197
198 protected:
dcheng93a52eb2014-12-23 02:14:23199 void SetUp() override {
danakjcf610582015-06-16 22:48:56200 layer_tree_host_ =
201 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
[email protected]d72d9e02014-04-03 18:40:09202 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
203 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
204 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22205 }
206
dcheng93a52eb2014-12-23 02:14:23207 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22208 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22209 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
210
kulkarni.a4015690f12014-10-10 13:50:06211 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48212 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22213 }
214
215 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
khushalsagarb64b360d2015-10-21 19:25:16216 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]31d4df82013-07-18 10:17:22217 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45218 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47219 TestTaskGraphRunner task_graph_runner_;
revemand180dfc32015-09-24 00:19:43220 scoped_ptr<OutputSurface> output_surface_;
[email protected]31d4df82013-07-18 10:17:22221 FakeLayerTreeHostImpl host_impl_;
jbauman9015c8b2014-12-11 00:49:37222 CommonMailboxObjects test_data_;
loysoa6edaaff2015-05-25 03:26:44223 LayerSettings layer_settings_;
[email protected]31d4df82013-07-18 10:17:22224};
225
[email protected]31d4df82013-07-18 10:17:22226TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06227 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44228 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]80d42bd2013-08-30 19:13:45229 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22230
231 // Test properties that should call SetNeedsCommit. All properties need to
232 // be set to new values in order for SetNeedsCommit to be called.
233 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44234 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22235 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
236 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
237 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
238 0.5f, 0.5f, 0.5f, 0.5f));
239 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
240 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22241}
242
[email protected]df41e252014-02-03 23:39:50243class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59244 public:
[email protected]df41e252014-02-03 23:39:50245 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59246
247 protected:
dcheng716bedf2014-10-21 09:51:08248 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59249};
250
[email protected]de44a152013-01-08 15:28:46251class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15252 protected:
dcheng93a52eb2014-12-23 02:14:23253 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15254 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
dyencc16ed4d2015-11-03 20:03:04255 EXPECT_CALL(
256 test_data_.mock_callback_,
257 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
258 .Times(1);
[email protected]28571b042013-03-14 07:59:15259 TextureLayerTest::TearDown();
260 }
[email protected]de44a152013-01-08 15:28:46261};
262
[email protected]28571b042013-03-14 07:59:15263TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06264 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44265 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]22898ed2013-06-01 04:52:30266 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46267
[email protected]28571b042013-03-14 07:59:15268 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
269 layer_tree_host_->SetRootLayer(test_layer);
270 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46271
[email protected]28571b042013-03-14 07:59:15272 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16273 test_layer->SetTextureMailbox(
274 test_data_.mailbox1_,
275 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15276 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46277
[email protected]28571b042013-03-14 07:59:15278 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04279 EXPECT_CALL(
280 test_data_.mock_callback_,
281 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
[email protected]28571b042013-03-14 07:59:15282 .Times(1);
[email protected]9260757f2013-09-17 01:24:16283 test_layer->SetTextureMailbox(
284 test_data_.mailbox2_,
285 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15286 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
287 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46288
[email protected]28571b042013-03-14 07:59:15289 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04290 EXPECT_CALL(
291 test_data_.mock_callback_,
292 Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
[email protected]28571b042013-03-14 07:59:15293 .Times(1);
danakj968153f32014-10-15 22:52:16294 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15295 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
296 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46297
[email protected]80d42bd2013-08-30 19:13:45298 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16299 test_layer->SetTextureMailbox(
300 test_data_.mailbox3_,
301 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51302 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
303 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
304
[email protected]42f40a52013-06-08 04:38:51305 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
306 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04307 Release2(test_data_.shared_bitmap_.get(), _, false))
308 .Times(1);
danakj968153f32014-10-15 22:52:16309 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51310 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
311 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
312
[email protected]28571b042013-03-14 07:59:15313 // Test destructor.
314 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16315 test_layer->SetTextureMailbox(
316 test_data_.mailbox1_,
317 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46318}
319
[email protected]f9e8f452014-03-07 22:09:40320TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
kulkarni.a4015690f12014-10-10 13:50:06321 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44322 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]f9e8f452014-03-07 22:09:40323 ASSERT_TRUE(test_layer.get());
324
325 // These use the same gpu::Mailbox, but different sync points.
dyencc16ed4d2015-11-03 20:03:04326 TextureMailbox mailbox1(MailboxFromChar('a'), gpu::SyncToken(1),
327 GL_TEXTURE_2D);
328 TextureMailbox mailbox2(MailboxFromChar('a'), gpu::SyncToken(2),
329 GL_TEXTURE_2D);
[email protected]f9e8f452014-03-07 22:09:40330
[email protected]f9e8f452014-03-07 22:09:40331 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
332 layer_tree_host_->SetRootLayer(test_layer);
333 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
334
335 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40336 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
337 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
338 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
339
340 // Set the mailbox again with a new sync point, as the backing texture has
341 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40342 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
343 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
344 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
345}
346
[email protected]9794fb32013-08-29 09:49:59347class TextureLayerMailboxHolderTest : public TextureLayerTest {
348 public:
349 TextureLayerMailboxHolderTest()
350 : main_thread_("MAIN") {
351 main_thread_.Start();
skyostil0fd1dad2015-04-13 20:11:48352 main_thread_.message_loop()->task_runner()->PostTask(
353 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
354 base::Unretained(this)));
skyostil3976a3f2014-09-04 22:07:23355 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59356 }
357
358 void Wait(const base::Thread& thread) {
359 bool manual_reset = false;
360 bool initially_signaled = false;
361 base::WaitableEvent event(manual_reset, initially_signaled);
skyostil0fd1dad2015-04-13 20:11:48362 thread.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59363 FROM_HERE,
364 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
365 event.Wait();
366 }
367
368 void CreateMainRef() {
369 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16370 test_data_.mailbox1_,
danakja5a05ba02015-11-20 20:14:21371 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]9794fb32013-08-29 09:49:59372 }
373
danakjf446a072014-09-27 21:55:48374 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59375
skyostil3976a3f2014-09-04 22:07:23376 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59377 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
378 }
379
380 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
381 base::WaitableEvent* wait_for_capture,
382 base::WaitableEvent* stop_capture) {
383 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23384 BlockingTaskRunner::CapturePostTasks capture(
385 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59386 wait_for_capture->Signal();
387 stop_capture->Wait();
388 }
389
390 protected:
skyostil3976a3f2014-09-04 22:07:23391 void InitializeOnMain() {
392 main_thread_task_runner_ =
skyostil0fd1dad2015-04-13 20:11:48393 BlockingTaskRunner::Create(main_thread_.task_runner());
skyostil3976a3f2014-09-04 22:07:23394 }
395
[email protected]9794fb32013-08-29 09:49:59396 scoped_ptr<TestMailboxHolder::MainThreadReference>
397 main_ref_;
398 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23399 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59400};
401
402TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06403 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44404 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59405 ASSERT_TRUE(test_layer.get());
406
skyostil0fd1dad2015-04-13 20:11:48407 main_thread_.message_loop()->task_runner()->PostTask(
408 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
409 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59410
411 Wait(main_thread_);
412
413 // The texture layer is attached to compositor1, and passes a reference to its
414 // impl tree.
skyostil3976a3f2014-09-04 22:07:23415 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48416 main_thread_.message_loop()->task_runner()->PostTask(
417 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
418 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59419
420 // Then the texture layer is removed and attached to compositor2, and passes a
421 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23422 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48423 main_thread_.message_loop()->task_runner()->PostTask(
424 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
425 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59426
427 Wait(main_thread_);
428 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
429
430 // The compositors both destroy their impl trees before the main thread layer
431 // is destroyed.
dyencc16ed4d2015-11-03 20:03:04432 compositor1->Run(gpu::SyncToken(100), false, main_thread_task_runner_.get());
433 compositor2->Run(gpu::SyncToken(200), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59434
435 Wait(main_thread_);
436
437 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
438 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
439
440 // The main thread ref is the last one, so the mailbox is released back to the
441 // embedder, with the last sync point provided by the impl trees.
442 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04443 Release(test_data_.mailbox_name1_, gpu::SyncToken(200), false))
444 .Times(1);
[email protected]9794fb32013-08-29 09:49:59445
skyostil0fd1dad2015-04-13 20:11:48446 main_thread_.message_loop()->task_runner()->PostTask(
447 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
448 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59449 Wait(main_thread_);
450 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
451}
452
453TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06454 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44455 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59456 ASSERT_TRUE(test_layer.get());
457
skyostil0fd1dad2015-04-13 20:11:48458 main_thread_.message_loop()->task_runner()->PostTask(
459 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
460 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59461
462 Wait(main_thread_);
463
464 // The texture layer is attached to compositor1, and passes a reference to its
465 // impl tree.
skyostil3976a3f2014-09-04 22:07:23466 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48467 main_thread_.message_loop()->task_runner()->PostTask(
468 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
469 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59470
471 // Then the texture layer is removed and attached to compositor2, and passes a
472 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23473 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48474 main_thread_.message_loop()->task_runner()->PostTask(
475 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
476 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59477
478 Wait(main_thread_);
479 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
480
481 // One compositor destroys their impl tree.
dyencc16ed4d2015-11-03 20:03:04482 compositor1->Run(gpu::SyncToken(100), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59483
484 // Then the main thread reference is destroyed.
skyostil0fd1dad2015-04-13 20:11:48485 main_thread_.message_loop()->task_runner()->PostTask(
486 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
487 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59488
489 Wait(main_thread_);
490
491 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
492 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
493
494 // The second impl reference is destroyed last, causing the mailbox to be
495 // released back to the embedder with the last sync point from the impl tree.
496 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04497 Release(test_data_.mailbox_name1_, gpu::SyncToken(200), true))
498 .Times(1);
[email protected]9794fb32013-08-29 09:49:59499
dyencc16ed4d2015-11-03 20:03:04500 compositor2->Run(gpu::SyncToken(200), true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59501 Wait(main_thread_);
502 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
503}
504
505TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06506 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44507 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59508 ASSERT_TRUE(test_layer.get());
509
skyostil0fd1dad2015-04-13 20:11:48510 main_thread_.message_loop()->task_runner()->PostTask(
511 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
512 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59513
514 Wait(main_thread_);
515
516 // The texture layer is attached to compositor1, and passes a reference to its
517 // impl tree.
skyostil3976a3f2014-09-04 22:07:23518 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48519 main_thread_.message_loop()->task_runner()->PostTask(
520 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
521 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59522
523 // Then the texture layer is removed and attached to compositor2, and passes a
524 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23525 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48526 main_thread_.message_loop()->task_runner()->PostTask(
527 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
528 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59529
530 Wait(main_thread_);
531 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
532
533 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48534 main_thread_.message_loop()->task_runner()->PostTask(
535 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
536 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59537
538 // One compositor destroys their impl tree.
dyencc16ed4d2015-11-03 20:03:04539 compositor2->Run(gpu::SyncToken(200), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59540
541 Wait(main_thread_);
542
543 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
544 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
545
546 // The second impl reference is destroyed last, causing the mailbox to be
547 // released back to the embedder with the last sync point from the impl tree.
548 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04549 Release(test_data_.mailbox_name1_, gpu::SyncToken(100), true))
550 .Times(1);
[email protected]9794fb32013-08-29 09:49:59551
dyencc16ed4d2015-11-03 20:03:04552 compositor1->Run(gpu::SyncToken(100), true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59553 Wait(main_thread_);
554 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
555}
556
557TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06558 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44559 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59560 ASSERT_TRUE(test_layer.get());
561
skyostil0fd1dad2015-04-13 20:11:48562 main_thread_.message_loop()->task_runner()->PostTask(
563 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
564 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59565
566 Wait(main_thread_);
567
568 // The texture layer is attached to compositor1, and passes a reference to its
569 // impl tree.
skyostil3976a3f2014-09-04 22:07:23570 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48571 main_thread_.message_loop()->task_runner()->PostTask(
572 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
573 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59574
575 // Then the texture layer is removed and attached to compositor2, and passes a
576 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23577 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48578 main_thread_.message_loop()->task_runner()->PostTask(
579 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
580 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59581
582 Wait(main_thread_);
583 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
584
585 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48586 main_thread_.message_loop()->task_runner()->PostTask(
587 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
588 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59589
590 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04591 Release(test_data_.mailbox_name1_, gpu::SyncToken(200), true))
592 .Times(1);
[email protected]9794fb32013-08-29 09:49:59593
594 bool manual_reset = false;
595 bool initially_signaled = false;
596 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
597 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
598 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
599
600 // Post a task to start capturing tasks on the main thread. This will block
601 // the main thread until we signal the |stop_capture| event.
skyostil0fd1dad2015-04-13 20:11:48602 main_thread_.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59603 FROM_HERE,
604 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
skyostil0fd1dad2015-04-13 20:11:48605 base::Unretained(this), &begin_capture, &wait_for_capture,
[email protected]9794fb32013-08-29 09:49:59606 &stop_capture));
607
608 // Before the main thread capturing starts, one compositor destroys their
609 // impl reference. Since capturing did not start, this gets post-tasked to
610 // the main thread.
dyencc16ed4d2015-11-03 20:03:04611 compositor1->Run(gpu::SyncToken(100), false, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59612
613 // Start capturing on the main thread.
614 begin_capture.Signal();
615 wait_for_capture.Wait();
616
617 // Meanwhile, the second compositor released its impl reference, but this task
618 // gets shortcutted directly to the main thread. This means the reference is
619 // released before compositor1, whose reference will be released later when
620 // the post-task is serviced. But since it was destroyed _on the impl thread_
621 // last, its sync point values should be used.
dyencc16ed4d2015-11-03 20:03:04622 compositor2->Run(gpu::SyncToken(200), true, main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59623
624 stop_capture.Signal();
625 Wait(main_thread_);
626
627 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
628}
629
[email protected]e216fef02013-03-20 22:56:10630class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15631 public:
632 TextureLayerImplWithMailboxThreadedCallback()
633 : callback_count_(0),
634 commit_count_(0) {}
635
636 // Make sure callback is received on main and doesn't block the impl thread.
dyencc16ed4d2015-11-03 20:03:04637 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59638 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25639 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15640 ++callback_count_;
641 }
642
643 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59644 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16645 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15646 base::Bind(
647 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
648 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:04649 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
650 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10651 std::move(callback));
[email protected]28571b042013-03-14 07:59:15652 }
653
dcheng716bedf2014-10-21 09:51:08654 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59655 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
656
[email protected]28571b042013-03-14 07:59:15657 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:44658 root_ = Layer::Create(layer_settings());
[email protected]28571b042013-03-14 07:59:15659 root_->SetBounds(bounds);
660
loysoa6edaaff2015-05-25 03:26:44661 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]28571b042013-03-14 07:59:15662 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15663 layer_->SetBounds(bounds);
664
665 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10666 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40667 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15668 SetMailbox('1');
669 EXPECT_EQ(0, callback_count_);
670
671 // Case #1: change mailbox before the commit. The old mailbox should be
672 // released immediately.
673 SetMailbox('2');
674 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10675 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15676 }
677
dcheng716bedf2014-10-21 09:51:08678 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15679 ++commit_count_;
680 switch (commit_count_) {
681 case 1:
682 // Case #2: change mailbox after the commit (and draw), where the
683 // layer draws. The old mailbox should be released during the next
684 // commit.
685 SetMailbox('3');
686 EXPECT_EQ(1, callback_count_);
687 break;
688 case 2:
[email protected]28571b042013-03-14 07:59:15689 EXPECT_EQ(2, callback_count_);
690 // Case #3: change mailbox when the layer doesn't draw. The old
691 // mailbox should be released during the next commit.
692 layer_->SetBounds(gfx::Size());
693 SetMailbox('4');
694 break;
[email protected]9794fb32013-08-29 09:49:59695 case 3:
[email protected]28571b042013-03-14 07:59:15696 EXPECT_EQ(3, callback_count_);
697 // Case #4: release mailbox that was committed but never drawn. The
698 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16699 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15700 break;
[email protected]9794fb32013-08-29 09:49:59701 case 4:
danakj431a1202015-06-17 19:09:33702 // With impl painting, the texture mailbox will still be on the impl
703 // thread when the commit finishes, because the layer is not drawble
704 // when it has no texture mailbox, and thus does not block the commit
705 // on activation. So, we wait for activation.
706 // TODO(danakj): fix this. crbug.com/277953
707 layer_tree_host()->SetNeedsCommit();
708 break;
[email protected]9794fb32013-08-29 09:49:59709 case 5:
[email protected]28571b042013-03-14 07:59:15710 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43711 // Restore a mailbox for the next step.
712 SetMailbox('5');
713 break;
[email protected]9794fb32013-08-29 09:49:59714 case 6:
[email protected]7096acc2013-06-18 21:12:43715 // Case #5: remove layer from tree. Callback should *not* be called, the
716 // mailbox is returned to the main thread.
717 EXPECT_EQ(4, callback_count_);
718 layer_->RemoveFromParent();
719 break;
[email protected]9794fb32013-08-29 09:49:59720 case 7:
danakj431a1202015-06-17 19:09:33721 // With impl painting, the texture mailbox will still be on the impl
722 // thread when the commit finishes, because the layer is not around to
723 // block the commit on activation anymore. So, we wait for activation.
724 // TODO(danakj): fix this. crbug.com/277953
725 layer_tree_host()->SetNeedsCommit();
726 break;
[email protected]9794fb32013-08-29 09:49:59727 case 8:
[email protected]7096acc2013-06-18 21:12:43728 EXPECT_EQ(4, callback_count_);
729 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16730 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43731 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10732 EndTest();
[email protected]28571b042013-03-14 07:59:15733 break;
734 default:
735 NOTREACHED();
736 break;
[email protected]de44a152013-01-08 15:28:46737 }
[email protected]28571b042013-03-14 07:59:15738 }
[email protected]de44a152013-01-08 15:28:46739
dcheng716bedf2014-10-21 09:51:08740 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46741
[email protected]28571b042013-03-14 07:59:15742 private:
[email protected]9794fb32013-08-29 09:49:59743 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15744 int callback_count_;
745 int commit_count_;
746 scoped_refptr<Layer> root_;
747 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46748};
749
[email protected]4145d172013-05-10 16:54:36750SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
751 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46752
[email protected]74b43cc2013-08-30 06:29:27753
[email protected]74b43cc2013-08-30 06:29:27754class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
755 protected:
[email protected]98ea818e2014-01-24 10:22:08756 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27757
dyencc16ed4d2015-11-03 20:03:04758 static void ReleaseCallback(const gpu::SyncToken& sync_token,
759 bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27760
761 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16762 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27763 base::Bind(
764 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
dyencc16ed4d2015-11-03 20:03:04765 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
766 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10767 std::move(callback));
[email protected]74b43cc2013-08-30 06:29:27768 }
769
dcheng716bedf2014-10-21 09:51:08770 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27771 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:44772 root_ = Layer::Create(layer_settings());
[email protected]74b43cc2013-08-30 06:29:27773 root_->SetBounds(bounds);
774
loysoa6edaaff2015-05-25 03:26:44775 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]74b43cc2013-08-30 06:29:27776 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27777 layer_->SetBounds(bounds);
778
779 root_->AddChild(layer_);
780 layer_tree_host()->SetRootLayer(root_);
781 layer_tree_host()->SetViewportSize(bounds);
782 SetMailbox('1');
783
784 PostSetNeedsCommitToMainThread();
785 }
786
dcheng716bedf2014-10-21 09:51:08787 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
danakj3c3973b2015-08-25 21:50:18788 base::AutoLock lock(activate_count_lock_);
[email protected]74b43cc2013-08-30 06:29:27789 ++activate_count_;
790 }
791
dcheng716bedf2014-10-21 09:51:08792 void DidCommit() override {
danakj3c3973b2015-08-25 21:50:18793 // The first frame doesn't cause anything to be returned so it does not
794 // need to wait for activation.
795 if (layer_tree_host()->source_frame_number() > 1) {
796 base::AutoLock lock(activate_count_lock_);
797 // The activate happened before commit is done on the main side.
798 EXPECT_EQ(activate_count_, layer_tree_host()->source_frame_number());
799 }
800
[email protected]98ea818e2014-01-24 10:22:08801 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27802 case 1:
803 // The first mailbox has been activated. Set a new mailbox, and
804 // expect the next commit to finish *after* it is activated.
805 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27806 break;
807 case 2:
808 // The second mailbox has been activated. Remove the layer from
809 // the tree to cause another commit/activation. The commit should
810 // finish *after* the layer is removed from the active tree.
811 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27812 break;
813 case 3:
814 EndTest();
815 break;
816 }
817 }
818
dcheng716bedf2014-10-21 09:51:08819 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
danakj3c3973b2015-08-25 21:50:18820 // The activate didn't happen before commit is done on the impl side (but it
821 // should happen before the main thread is done).
822 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
[email protected]74b43cc2013-08-30 06:29:27823 }
824
dcheng716bedf2014-10-21 09:51:08825 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27826
danakj3c3973b2015-08-25 21:50:18827 base::Lock activate_count_lock_;
[email protected]74b43cc2013-08-30 06:29:27828 int activate_count_;
829 scoped_refptr<Layer> root_;
830 scoped_refptr<TextureLayer> layer_;
831};
832
833SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
834 TextureLayerMailboxIsActivatedDuringCommit);
835
[email protected]de44a152013-01-08 15:28:46836class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15837 protected:
[email protected]408b5e22013-03-19 09:48:09838 TextureLayerImplWithMailboxTest()
839 : fake_client_(
840 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
841
dcheng93a52eb2014-12-23 02:14:23842 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15843 TextureLayerTest::SetUp();
danakjcf610582015-06-16 22:48:56844 layer_tree_host_ =
845 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
sievers71c62dd52015-10-07 01:44:39846 host_impl_.SetVisible(true);
revemand180dfc32015-09-24 00:19:43847 EXPECT_TRUE(host_impl_.InitializeRenderer(output_surface_.get()));
[email protected]28571b042013-03-14 07:59:15848 }
[email protected]de44a152013-01-08 15:28:46849
[email protected]0ec335c42013-07-04 06:17:08850 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
851 bool will_draw = layer->WillDraw(
852 mode, host_impl_.active_tree()->resource_provider());
853 if (will_draw)
854 layer->DidDraw(host_impl_.active_tree()->resource_provider());
855 return will_draw;
856 }
857
[email protected]408b5e22013-03-19 09:48:09858 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46859};
860
[email protected]ffbb2212013-06-02 23:47:59861// Test conditions for results of TextureLayerImpl::WillDraw under
862// different configurations of different mailbox, texture_id, and draw_mode.
863TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23864 EXPECT_CALL(
865 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04866 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08867 .Times(AnyNumber());
dyencc16ed4d2015-11-03 20:03:04868 EXPECT_CALL(
869 test_data_.mock_callback_,
870 ReleaseImpl2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false, _))
[email protected]0ec335c42013-07-04 06:17:08871 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59872 // Hardware mode.
873 {
874 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11875 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16876 impl_layer->SetTextureMailbox(
877 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23878 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08879 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59880 }
881
882 {
883 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11884 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16885 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08886 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
887 }
888
889 {
890 // Software resource.
891 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11892 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16893 impl_layer->SetTextureMailbox(
894 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23895 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10896 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59897 }
898
[email protected]0ec335c42013-07-04 06:17:08899 // Software mode.
900 {
901 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11902 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16903 impl_layer->SetTextureMailbox(
904 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23905 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08906 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
907 }
908
909 {
910 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11911 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16912 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08913 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
914 }
915
916 {
917 // Software resource.
918 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11919 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16920 impl_layer->SetTextureMailbox(
921 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23922 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:08923 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
924 }
925
[email protected]ffbb2212013-06-02 23:47:59926 // Resourceless software mode.
927 {
928 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11929 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16930 impl_layer->SetTextureMailbox(
931 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23932 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08933 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59934 }
[email protected]ffbb2212013-06-02 23:47:59935}
936
[email protected]28571b042013-03-14 07:59:15937TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
938 host_impl_.CreatePendingTree();
939 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11940 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15941 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46942
[email protected]ed511b8d2013-03-25 03:29:29943 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15944 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29945 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46946
[email protected]9260757f2013-09-17 01:24:16947 pending_layer->SetTextureMailbox(
948 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23949 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:15950
[email protected]28571b042013-03-14 07:59:15951 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:23952 EXPECT_CALL(
953 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04954 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15955 .Times(1);
[email protected]9260757f2013-09-17 01:24:16956 pending_layer->SetTextureMailbox(
957 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:23958 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:15959 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15960
[email protected]28571b042013-03-14 07:59:15961 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29962 pending_layer->PushPropertiesTo(active_layer.get());
963 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15964
skyostil3976a3f2014-09-04 22:07:23965 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:16966 pending_layer->SetTextureMailbox(
967 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23968 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:15969 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15970
[email protected]7ba3ca72013-04-11 06:37:25971 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23972 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:29973 pending_layer->PushPropertiesTo(active_layer.get());
974 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15975 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46976
[email protected]28571b042013-03-14 07:59:15977 // Test resetting the mailbox.
[email protected]7ba3ca72013-04-11 06:37:25978 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23979 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
danakj968153f32014-10-15 22:52:16980 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:29981 pending_layer->PushPropertiesTo(active_layer.get());
982 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15983 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46984
[email protected]28571b042013-03-14 07:59:15985 // Test destructor.
skyostil3976a3f2014-09-04 22:07:23986 EXPECT_CALL(
987 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04988 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15989 .Times(1);
[email protected]9260757f2013-09-17 01:24:16990 pending_layer->SetTextureMailbox(
991 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23992 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:46993}
994
[email protected]28571b042013-03-14 07:59:15995TEST_F(TextureLayerImplWithMailboxTest,
996 TestDestructorCallbackOnCreatedResource) {
997 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:11998 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:15999 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461000
[email protected]7ba3ca72013-04-11 06:37:251001 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231002 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161003 impl_layer->SetTextureMailbox(
1004 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231005 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591006 impl_layer->DidBecomeActive();
1007 EXPECT_TRUE(impl_layer->WillDraw(
1008 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151009 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161010 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461011}
1012
[email protected]28571b042013-03-14 07:59:151013TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1014 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
jbaumanbbd425e2015-05-19 00:33:351015 ResourceId id = provider->CreateResourceFromTextureMailbox(
skyostil3976a3f2014-09-04 22:07:231016 test_data_.mailbox1_,
1017 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151018 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461019
[email protected]28571b042013-03-14 07:59:151020 // Transfer some resources to the parent.
1021 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1022 resource_ids_to_transfer.push_back(id);
1023 TransferableResourceArray list;
1024 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1025 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231026 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151027 provider->DeleteResource(id);
1028 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251029 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231030 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451031 ReturnedResourceArray returned;
1032 TransferableResource::ReturnResources(list, &returned);
1033 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461034}
1035
[email protected]4bad8b62013-10-24 01:27:291036// Checks that TextureLayer::Update does not cause an extra commit when setting
1037// the texture mailbox.
1038class TextureLayerNoExtraCommitForMailboxTest
1039 : public LayerTreeTest,
1040 public TextureLayerClient {
1041 public:
[email protected]4bad8b62013-10-24 01:27:291042 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081043 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501044 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291045 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371046 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451047 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461048 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501049 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451050 return true;
1051 }
[email protected]4bad8b62013-10-24 01:27:291052
dyencc16ed4d2015-11-03 20:03:041053 *texture_mailbox =
1054 TextureMailbox(MailboxFromChar('1'), gpu::SyncToken(), GL_TEXTURE_2D);
[email protected]4bad8b62013-10-24 01:27:291055 *release_callback = SingleReleaseCallback::Create(
1056 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1057 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291058 return true;
1059 }
1060
dyencc16ed4d2015-11-03 20:03:041061 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461062 // Source frame number during callback is the same as the source frame
1063 // on which it was released.
1064 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451065 EndTest();
[email protected]4bad8b62013-10-24 01:27:291066 }
1067
dcheng716bedf2014-10-21 09:51:081068 void SetupTree() override {
loysoa6edaaff2015-05-25 03:26:441069 scoped_refptr<Layer> root = Layer::Create(layer_settings());
[email protected]4bad8b62013-10-24 01:27:291070 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291071 root->SetIsDrawable(true);
1072
loysoa6edaaff2015-05-25 03:26:441073 texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]4bad8b62013-10-24 01:27:291074 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291075 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471076 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291077
1078 layer_tree_host()->SetRootLayer(root);
1079 LayerTreeTest::SetupTree();
1080 }
1081
dcheng716bedf2014-10-21 09:51:081082 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291083
dcheng716bedf2014-10-21 09:51:081084 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291085 switch (layer_tree_host()->source_frame_number()) {
1086 case 1:
[email protected]4ea293f72014-08-13 03:03:171087 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451088 // Invalidate the texture layer to clear the mailbox before
1089 // ending the test.
1090 texture_layer_->SetNeedsDisplay();
1091 break;
1092 case 2:
[email protected]4bad8b62013-10-24 01:27:291093 break;
1094 default:
1095 NOTREACHED();
1096 break;
1097 }
1098 }
1099
dcheng716bedf2014-10-21 09:51:081100 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451101 ASSERT_TRUE(result);
1102 DelegatedFrameData* delegated_frame_data =
1103 output_surface()->last_sent_frame().delegated_frame_data.get();
1104 if (!delegated_frame_data)
1105 return;
1106
1107 // Return all resources immediately.
1108 TransferableResourceArray resources_to_return =
1109 output_surface()->resources_held_by_parent();
1110
1111 CompositorFrameAck ack;
1112 for (size_t i = 0; i < resources_to_return.size(); ++i)
1113 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1114 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451115 }
1116
dcheng716bedf2014-10-21 09:51:081117 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291118
1119 private:
[email protected]4bad8b62013-10-24 01:27:291120 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291121};
1122
[email protected]cce34bd2013-12-02 23:24:451123SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291124
[email protected]b04264f92013-09-13 23:37:291125// Checks that changing a mailbox in the client for a TextureLayer that's
1126// invisible correctly works and uses the new mailbox as soon as the layer
1127// becomes visible (and returns the old one).
1128class TextureLayerChangeInvisibleMailboxTest
1129 : public LayerTreeTest,
1130 public TextureLayerClient {
1131 public:
1132 TextureLayerChangeInvisibleMailboxTest()
1133 : mailbox_changed_(true),
1134 mailbox_returned_(0),
1135 prepare_called_(0),
1136 commit_count_(0) {
1137 mailbox_ = MakeMailbox('1');
1138 }
1139
1140 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081141 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011142 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161143 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371144 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291145 ++prepare_called_;
1146 if (!mailbox_changed_)
1147 return false;
1148 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161149 *release_callback = SingleReleaseCallback::Create(
1150 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1151 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291152 return true;
1153 }
1154
1155 TextureMailbox MakeMailbox(char name) {
dyencc16ed4d2015-11-03 20:03:041156 return TextureMailbox(MailboxFromChar(name), gpu::SyncToken(),
1157 GL_TEXTURE_2D);
[email protected]b04264f92013-09-13 23:37:291158 }
1159
dyencc16ed4d2015-11-03 20:03:041160 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291161 ++mailbox_returned_;
1162 }
1163
dcheng716bedf2014-10-21 09:51:081164 void SetupTree() override {
loysoa6edaaff2015-05-25 03:26:441165 scoped_refptr<Layer> root = Layer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291166 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291167 root->SetIsDrawable(true);
1168
loysoa6edaaff2015-05-25 03:26:441169 solid_layer_ = SolidColorLayer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291170 solid_layer_->SetBounds(gfx::Size(10, 10));
1171 solid_layer_->SetIsDrawable(true);
1172 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1173 root->AddChild(solid_layer_);
1174
loysoa6edaaff2015-05-25 03:26:441175 parent_layer_ = Layer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291176 parent_layer_->SetBounds(gfx::Size(10, 10));
1177 parent_layer_->SetIsDrawable(true);
1178 root->AddChild(parent_layer_);
1179
loysoa6edaaff2015-05-25 03:26:441180 texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]b04264f92013-09-13 23:37:291181 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291182 texture_layer_->SetIsDrawable(true);
1183 parent_layer_->AddChild(texture_layer_);
1184
1185 layer_tree_host()->SetRootLayer(root);
1186 LayerTreeTest::SetupTree();
1187 }
1188
dcheng716bedf2014-10-21 09:51:081189 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291190
dcheng716bedf2014-10-21 09:51:081191 void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291192 ++commit_count_;
1193 switch (commit_count_) {
1194 case 1:
1195 // We should have updated the layer, committing the texture.
1196 EXPECT_EQ(1, prepare_called_);
1197 // Make layer invisible.
1198 parent_layer_->SetOpacity(0.f);
1199 break;
1200 case 2:
1201 // Layer shouldn't have been updated.
1202 EXPECT_EQ(1, prepare_called_);
1203 // Change the texture.
1204 mailbox_ = MakeMailbox('2');
1205 mailbox_changed_ = true;
1206 texture_layer_->SetNeedsDisplay();
1207 // Force a change to make sure we draw a frame.
1208 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1209 break;
1210 case 3:
1211 // Layer shouldn't have been updated.
1212 EXPECT_EQ(1, prepare_called_);
1213 // So the old mailbox isn't returned yet.
1214 EXPECT_EQ(0, mailbox_returned_);
1215 // Make layer visible again.
1216 parent_layer_->SetOpacity(1.f);
1217 break;
1218 case 4:
1219 // Layer should have been updated.
1220 EXPECT_EQ(2, prepare_called_);
1221 // So the old mailbox should have been returned already.
1222 EXPECT_EQ(1, mailbox_returned_);
1223 texture_layer_->ClearClient();
1224 break;
1225 case 5:
1226 EXPECT_EQ(2, mailbox_returned_);
1227 EndTest();
1228 break;
1229 default:
1230 NOTREACHED();
1231 break;
1232 }
1233 }
1234
dcheng716bedf2014-10-21 09:51:081235 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]b04264f92013-09-13 23:37:291236 ASSERT_TRUE(result);
1237 DelegatedFrameData* delegated_frame_data =
1238 output_surface()->last_sent_frame().delegated_frame_data.get();
1239 if (!delegated_frame_data)
1240 return;
1241
1242 // Return all resources immediately.
1243 TransferableResourceArray resources_to_return =
1244 output_surface()->resources_held_by_parent();
1245
1246 CompositorFrameAck ack;
1247 for (size_t i = 0; i < resources_to_return.size(); ++i)
1248 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511249 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291250 }
1251
dcheng716bedf2014-10-21 09:51:081252 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291253
1254 private:
1255 scoped_refptr<SolidColorLayer> solid_layer_;
1256 scoped_refptr<Layer> parent_layer_;
1257 scoped_refptr<TextureLayer> texture_layer_;
1258
1259 // Used on the main thread.
1260 bool mailbox_changed_;
1261 TextureMailbox mailbox_;
1262 int mailbox_returned_;
1263 int prepare_called_;
1264 int commit_count_;
1265};
1266
1267SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1268
[email protected]0d7fb302014-01-23 21:30:471269// Test that TextureLayerImpl::ReleaseResources can be called which releases
1270// the mailbox back to TextureLayerClient.
1271class TextureLayerReleaseResourcesBase
1272 : public LayerTreeTest,
1273 public TextureLayerClient {
1274 public:
1275 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081276 bool PrepareTextureMailbox(
[email protected]0d7fb302014-01-23 21:30:471277 TextureMailbox* mailbox,
1278 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371279 bool use_shared_memory) override {
dyencc16ed4d2015-11-03 20:03:041280 *mailbox =
1281 TextureMailbox(MailboxFromChar('1'), gpu::SyncToken(), GL_TEXTURE_2D);
[email protected]0d7fb302014-01-23 21:30:471282 *release_callback = SingleReleaseCallback::Create(
1283 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1284 base::Unretained(this)));
1285 return true;
1286 }
1287
dyencc16ed4d2015-11-03 20:03:041288 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]0d7fb302014-01-23 21:30:471289 mailbox_released_ = true;
1290 }
1291
dcheng716bedf2014-10-21 09:51:081292 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471293 LayerTreeTest::SetupTree();
1294
1295 scoped_refptr<TextureLayer> texture_layer =
loysoa6edaaff2015-05-25 03:26:441296 TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]0d7fb302014-01-23 21:30:471297 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471298 texture_layer->SetIsDrawable(true);
1299
1300 layer_tree_host()->root_layer()->AddChild(texture_layer);
1301 }
1302
dcheng716bedf2014-10-21 09:51:081303 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471304 mailbox_released_ = false;
1305 PostSetNeedsCommitToMainThread();
1306 }
1307
dcheng716bedf2014-10-21 09:51:081308 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471309
dcheng716bedf2014-10-21 09:51:081310 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471311
1312 private:
1313 bool mailbox_released_;
1314};
1315
1316class TextureLayerReleaseResourcesAfterCommit
1317 : public TextureLayerReleaseResourcesBase {
1318 public:
dcheng716bedf2014-10-21 09:51:081319 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061320 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141321 tree = host_impl->sync_tree();
[email protected]0d7fb302014-01-23 21:30:471322 tree->root_layer()->children()[0]->ReleaseResources();
1323 }
1324};
1325
1326SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1327
1328class TextureLayerReleaseResourcesAfterActivate
1329 : public TextureLayerReleaseResourcesBase {
1330 public:
dcheng716bedf2014-10-21 09:51:081331 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471332 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1333 }
1334};
1335
1336SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1337
[email protected]9c2bd822013-07-26 12:30:171338class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1339 public:
dyencc16ed4d2015-11-03 20:03:041340 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591341 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171342 EXPECT_FALSE(lost_resource);
1343 ++callback_count_;
1344 EndTest();
1345 }
1346
1347 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591348 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161349 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171350 base::Bind(
1351 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1352 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:041353 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
1354 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:101355 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171356 }
1357
dcheng716bedf2014-10-21 09:51:081358 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171359 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:441360 root_ = Layer::Create(layer_settings());
[email protected]9c2bd822013-07-26 12:30:171361 root_->SetBounds(bounds);
1362
loysoa6edaaff2015-05-25 03:26:441363 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]9c2bd822013-07-26 12:30:171364 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171365 layer_->SetBounds(bounds);
1366
1367 root_->AddChild(layer_);
1368 layer_tree_host()->SetRootLayer(root_);
1369 layer_tree_host()->SetViewportSize(bounds);
1370 }
1371
dcheng716bedf2014-10-21 09:51:081372 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591373 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1374
[email protected]9c2bd822013-07-26 12:30:171375 callback_count_ = 0;
1376
1377 // Set the mailbox on the main thread.
1378 SetMailbox('1');
1379 EXPECT_EQ(0, callback_count_);
1380
1381 PostSetNeedsCommitToMainThread();
1382 }
1383
dcheng716bedf2014-10-21 09:51:081384 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171385 switch (layer_tree_host()->source_frame_number()) {
1386 case 1:
1387 // Delete the TextureLayer on the main thread while the mailbox is in
1388 // the impl tree.
1389 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061390 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171391 break;
1392 }
1393 }
1394
dcheng716bedf2014-10-21 09:51:081395 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171396
1397 private:
[email protected]9794fb32013-08-29 09:49:591398 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171399 int callback_count_;
1400 scoped_refptr<Layer> root_;
1401 scoped_refptr<TextureLayer> layer_;
1402};
1403
1404SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1405 TextureLayerWithMailboxMainThreadDeleted);
1406
1407class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1408 public:
dyencc16ed4d2015-11-03 20:03:041409 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591410 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171411 EXPECT_FALSE(lost_resource);
1412 ++callback_count_;
1413 EndTest();
1414 }
1415
1416 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591417 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161418 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171419 base::Bind(
1420 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1421 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:041422 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
1423 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:101424 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171425 }
1426
dcheng716bedf2014-10-21 09:51:081427 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171428 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:441429 root_ = Layer::Create(layer_settings());
[email protected]9c2bd822013-07-26 12:30:171430 root_->SetBounds(bounds);
1431
loysoa6edaaff2015-05-25 03:26:441432 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]9c2bd822013-07-26 12:30:171433 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171434 layer_->SetBounds(bounds);
1435
1436 root_->AddChild(layer_);
1437 layer_tree_host()->SetRootLayer(root_);
1438 layer_tree_host()->SetViewportSize(bounds);
1439 }
1440
dcheng716bedf2014-10-21 09:51:081441 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591442 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1443
[email protected]9c2bd822013-07-26 12:30:171444 callback_count_ = 0;
1445
1446 // Set the mailbox on the main thread.
1447 SetMailbox('1');
1448 EXPECT_EQ(0, callback_count_);
1449
1450 PostSetNeedsCommitToMainThread();
1451 }
1452
dcheng716bedf2014-10-21 09:51:081453 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171454 switch (layer_tree_host()->source_frame_number()) {
1455 case 1:
1456 // Remove the TextureLayer on the main thread while the mailbox is in
1457 // the impl tree, but don't delete the TextureLayer until after the impl
1458 // tree side is deleted.
1459 layer_->RemoveFromParent();
1460 break;
1461 case 2:
kulkarni.a4015690f12014-10-10 13:50:061462 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171463 break;
1464 }
1465 }
1466
dcheng716bedf2014-10-21 09:51:081467 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171468
1469 private:
[email protected]9794fb32013-08-29 09:49:591470 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171471 int callback_count_;
1472 scoped_refptr<Layer> root_;
1473 scoped_refptr<TextureLayer> layer_;
1474};
1475
1476SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1477 TextureLayerWithMailboxImplThreadDeleted);
1478
[email protected]ba565742012-11-10 09:29:481479} // namespace
1480} // namespace cc