blob: 45e59769cf00356671e9b83edeaf884d9d6f4031 [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
avi02a4d172015-12-21 06:14:367#include <stddef.h>
8#include <stdint.h>
9
[email protected]b04264f92013-09-13 23:37:2910#include <algorithm>
[email protected]de44a152013-01-08 15:28:4611#include <string>
12
[email protected]b04264f92013-09-13 23:37:2913#include "base/bind.h"
[email protected]de44a152013-01-08 15:28:4614#include "base/callback.h"
skyostil0fd1dad2015-04-13 20:11:4815#include "base/location.h"
avi02a4d172015-12-21 06:14:3616#include "base/macros.h"
skyostil0fd1dad2015-04-13 20:11:4817#include "base/single_thread_task_runner.h"
danakj3c3973b2015-08-25 21:50:1818#include "base/synchronization/lock.h"
[email protected]9794fb32013-08-29 09:49:5919#include "base/synchronization/waitable_event.h"
skyostil0fd1dad2015-04-13 20:11:4820#include "base/thread_task_runner_handle.h"
[email protected]74b43cc2013-08-30 06:29:2721#include "base/threading/thread.h"
22#include "base/time/time.h"
[email protected]b04264f92013-09-13 23:37:2923#include "cc/layers/solid_color_layer.h"
[email protected]97d519fb2013-03-29 02:27:5424#include "cc/layers/texture_layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5225#include "cc/layers/texture_layer_impl.h"
[email protected]b04264f92013-09-13 23:37:2926#include "cc/output/compositor_frame_ack.h"
27#include "cc/output/context_provider.h"
[email protected]e00bab022013-08-19 00:42:4528#include "cc/resources/returned_resource.h"
khushalsagarb64b360d2015-10-21 19:25:1629#include "cc/test/fake_impl_task_runner_provider.h"
[email protected]101441ce2012-10-16 01:45:0330#include "cc/test/fake_layer_tree_host_client.h"
[email protected]586d51ed2012-12-07 20:31:4531#include "cc/test/fake_layer_tree_host_impl.h"
[email protected]199b715e2013-08-13 05:18:3432#include "cc/test/fake_output_surface.h"
[email protected]06d68d02013-04-19 18:46:2133#include "cc/test/layer_test_common.h"
[email protected]e216fef02013-03-20 22:56:1034#include "cc/test/layer_tree_test.h"
reveman34b7a1522015-03-23 20:27:4735#include "cc/test/test_task_graph_runner.h"
[email protected]c2610b9f2013-10-31 06:54:5936#include "cc/test/test_web_graphics_context_3d.h"
[email protected]9794fb32013-08-29 09:49:5937#include "cc/trees/blocking_task_runner.h"
[email protected]556fd292013-03-18 08:03:0438#include "cc/trees/layer_tree_host.h"
39#include "cc/trees/layer_tree_impl.h"
40#include "cc/trees/single_thread_proxy.h"
[email protected]0bf5a202013-07-10 14:50:5441#include "gpu/GLES2/gl2extchromium.h"
[email protected]7f0c53db2012-10-02 00:23:1842#include "testing/gmock/include/gmock/gmock.h"
43#include "testing/gtest/include/gtest/gtest.h"
[email protected]c0dd24c2012-08-30 23:25:2744
[email protected]c0dd24c2012-08-30 23:25:2745using ::testing::Mock;
46using ::testing::_;
47using ::testing::AtLeast;
48using ::testing::AnyNumber;
[email protected]d72d9e02014-04-03 18:40:0949using ::testing::InvokeWithoutArgs;
[email protected]c0dd24c2012-08-30 23:25:2750
[email protected]ba565742012-11-10 09:29:4851namespace cc {
[email protected]c0dd24c2012-08-30 23:25:2752namespace {
53
[email protected]e0a4d732014-02-15 00:23:2654gpu::Mailbox MailboxFromChar(char value) {
[email protected]df41e252014-02-03 23:39:5055 gpu::Mailbox mailbox;
[email protected]e0a4d732014-02-15 00:23:2656 memset(mailbox.name, value, sizeof(mailbox.name));
[email protected]df41e252014-02-03 23:39:5057 return mailbox;
58}
59
dyen398dd0142016-01-21 22:05:5660gpu::SyncToken SyncTokenFromUInt(uint32_t value) {
lukasza2573ce7d2016-02-16 19:17:2261 return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, 0,
62 gpu::CommandBufferId::FromUnsafeValue(0x123), value);
dyen398dd0142016-01-21 22:05:5663}
64
[email protected]408b5e22013-03-19 09:48:0965class MockLayerTreeHost : public LayerTreeHost {
[email protected]28571b042013-03-14 07:59:1566 public:
danakjcf610582015-06-16 22:48:5667 static scoped_ptr<MockLayerTreeHost> Create(
68 FakeLayerTreeHostClient* client,
69 TaskGraphRunner* task_graph_runner) {
sadrul6780f3da2015-05-11 17:01:5270 LayerTreeHost::InitParams params;
71 params.client = client;
danakjcf610582015-06-16 22:48:5672 params.task_graph_runner = task_graph_runner;
sadrul6780f3da2015-05-11 17:01:5273 LayerTreeSettings settings;
74 params.settings = &settings;
75 return make_scoped_ptr(new MockLayerTreeHost(client, &params));
[email protected]28571b042013-03-14 07:59:1576 }
[email protected]c0dd24c2012-08-30 23:25:2777
[email protected]28571b042013-03-14 07:59:1578 MOCK_METHOD0(SetNeedsCommit, void());
[email protected]3519b872013-07-30 07:17:5079 MOCK_METHOD0(SetNeedsUpdateLayers, void());
[email protected]aeeb3372013-11-05 14:05:5480 MOCK_METHOD0(StartRateLimiter, void());
81 MOCK_METHOD0(StopRateLimiter, void());
sadrul6780f3da2015-05-11 17:01:5282
83 private:
84 MockLayerTreeHost(FakeLayerTreeHostClient* client,
85 LayerTreeHost::InitParams* params)
khushalsagare0a38d42016-01-29 01:15:0686 : LayerTreeHost(params, CompositorMode::SINGLE_THREADED) {
sadrul6780f3da2015-05-11 17:01:5287 InitializeSingleThreaded(client, base::ThreadTaskRunnerHandle::Get(),
88 nullptr);
89 }
[email protected]c0dd24c2012-08-30 23:25:2790};
91
[email protected]d72d9e02014-04-03 18:40:0992class FakeTextureLayerClient : public TextureLayerClient {
93 public:
[email protected]17e08432014-04-10 00:41:1194 FakeTextureLayerClient() : mailbox_changed_(true) {}
[email protected]d72d9e02014-04-03 18:40:0995
dcheng716bedf2014-10-21 09:51:0896 bool PrepareTextureMailbox(
[email protected]d72d9e02014-04-03 18:40:0997 TextureMailbox* mailbox,
98 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:3799 bool use_shared_memory) override {
[email protected]d72d9e02014-04-03 18:40:09100 if (!mailbox_changed_)
101 return false;
102
103 *mailbox = mailbox_;
danakja04855a2015-11-18 20:39:10104 *release_callback = std::move(release_callback_);
[email protected]d72d9e02014-04-03 18:40:09105 mailbox_changed_ = false;
106 return true;
107 }
108
[email protected]d72d9e02014-04-03 18:40:09109 void set_mailbox(const TextureMailbox& mailbox,
110 scoped_ptr<SingleReleaseCallback> release_callback) {
111 mailbox_ = mailbox;
danakja04855a2015-11-18 20:39:10112 release_callback_ = std::move(release_callback);
[email protected]d72d9e02014-04-03 18:40:09113 mailbox_changed_ = true;
114 }
115
116 private:
[email protected]d72d9e02014-04-03 18:40:09117 TextureMailbox mailbox_;
118 scoped_ptr<SingleReleaseCallback> release_callback_;
119 bool mailbox_changed_;
120 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient);
121};
122
123class MockMailboxCallback {
124 public:
125 MOCK_METHOD3(Release,
126 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04127 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09128 bool lost_resource));
129 MOCK_METHOD3(Release2,
jbauman9015c8b2014-12-11 00:49:37130 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04131 const gpu::SyncToken& sync_token,
[email protected]d72d9e02014-04-03 18:40:09132 bool lost_resource));
skyostil3976a3f2014-09-04 22:07:23133 MOCK_METHOD4(ReleaseImpl,
134 void(const gpu::Mailbox& mailbox,
dyencc16ed4d2015-11-03 20:03:04135 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23136 bool lost_resource,
137 BlockingTaskRunner* main_thread_task_runner));
138 MOCK_METHOD4(ReleaseImpl2,
jbauman9015c8b2014-12-11 00:49:37139 void(SharedBitmap* shared_bitmap,
dyencc16ed4d2015-11-03 20:03:04140 const gpu::SyncToken& sync_token,
skyostil3976a3f2014-09-04 22:07:23141 bool lost_resource,
142 BlockingTaskRunner* main_thread_task_runner));
[email protected]d72d9e02014-04-03 18:40:09143};
144
145struct CommonMailboxObjects {
jbauman9015c8b2014-12-11 00:49:37146 explicit CommonMailboxObjects(SharedBitmapManager* manager)
[email protected]d72d9e02014-04-03 18:40:09147 : mailbox_name1_(MailboxFromChar('1')),
148 mailbox_name2_(MailboxFromChar('2')),
lukasza2573ce7d2016-02-16 19:17:22149 sync_token1_(gpu::CommandBufferNamespace::GPU_IO,
150 123,
151 gpu::CommandBufferId::FromUnsafeValue(0x234),
152 1),
153 sync_token2_(gpu::CommandBufferNamespace::GPU_IO,
154 123,
155 gpu::CommandBufferId::FromUnsafeValue(0x234),
156 2) {
[email protected]d72d9e02014-04-03 18:40:09157 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release,
158 base::Unretained(&mock_callback_),
159 mailbox_name1_);
160 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release,
161 base::Unretained(&mock_callback_),
162 mailbox_name2_);
skyostil3976a3f2014-09-04 22:07:23163 release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
164 base::Unretained(&mock_callback_),
165 mailbox_name1_);
166 release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl,
167 base::Unretained(&mock_callback_),
168 mailbox_name2_);
avi02a4d172015-12-21 06:14:36169 const uint32_t arbitrary_target1 = GL_TEXTURE_2D;
170 const uint32_t arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES;
dyencc16ed4d2015-11-03 20:03:04171 mailbox1_ = TextureMailbox(mailbox_name1_, sync_token1_, arbitrary_target1);
172 mailbox2_ = TextureMailbox(mailbox_name2_, sync_token2_, arbitrary_target2);
[email protected]d72d9e02014-04-03 18:40:09173 gfx::Size size(128, 128);
jbauman9015c8b2014-12-11 00:49:37174 shared_bitmap_ = manager->AllocateSharedBitmap(size);
175 DCHECK(shared_bitmap_);
176 release_mailbox3_ =
177 base::Bind(&MockMailboxCallback::Release2,
178 base::Unretained(&mock_callback_), shared_bitmap_.get());
179 release_mailbox3_impl_ =
180 base::Bind(&MockMailboxCallback::ReleaseImpl2,
181 base::Unretained(&mock_callback_), shared_bitmap_.get());
182 mailbox3_ = TextureMailbox(shared_bitmap_.get(), size);
[email protected]d72d9e02014-04-03 18:40:09183 }
184
185 gpu::Mailbox mailbox_name1_;
186 gpu::Mailbox mailbox_name2_;
187 MockMailboxCallback mock_callback_;
188 ReleaseCallback release_mailbox1_;
189 ReleaseCallback release_mailbox2_;
190 ReleaseCallback release_mailbox3_;
skyostil3976a3f2014-09-04 22:07:23191 ReleaseCallbackImpl release_mailbox1_impl_;
192 ReleaseCallbackImpl release_mailbox2_impl_;
193 ReleaseCallbackImpl release_mailbox3_impl_;
[email protected]d72d9e02014-04-03 18:40:09194 TextureMailbox mailbox1_;
195 TextureMailbox mailbox2_;
196 TextureMailbox mailbox3_;
dyencc16ed4d2015-11-03 20:03:04197 gpu::SyncToken sync_token1_;
198 gpu::SyncToken sync_token2_;
jbauman9015c8b2014-12-11 00:49:37199 scoped_ptr<SharedBitmap> shared_bitmap_;
[email protected]d72d9e02014-04-03 18:40:09200};
201
[email protected]31d4df82013-07-18 10:17:22202class TextureLayerTest : public testing::Test {
203 public:
204 TextureLayerTest()
205 : fake_client_(
[email protected]4e2eb352014-03-20 17:25:45206 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)),
revemand180dfc32015-09-24 00:19:43207 output_surface_(FakeOutputSurface::Create3d()),
khushalsagarb64b360d2015-10-21 19:25:16208 host_impl_(&task_runner_provider_,
209 &shared_bitmap_manager_,
210 &task_graph_runner_),
jbauman9015c8b2014-12-11 00:49:37211 test_data_(&shared_bitmap_manager_) {}
[email protected]31d4df82013-07-18 10:17:22212
213 protected:
dcheng93a52eb2014-12-23 02:14:23214 void SetUp() override {
danakjcf610582015-06-16 22:48:56215 layer_tree_host_ =
216 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
[email protected]d72d9e02014-04-03 18:40:09217 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
218 layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
219 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22220 }
221
dcheng93a52eb2014-12-23 02:14:23222 void TearDown() override {
[email protected]31d4df82013-07-18 10:17:22223 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]31d4df82013-07-18 10:17:22224 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
225
kulkarni.a4015690f12014-10-10 13:50:06226 layer_tree_host_->SetRootLayer(nullptr);
danakjf446a072014-09-27 21:55:48227 layer_tree_host_ = nullptr;
[email protected]31d4df82013-07-18 10:17:22228 }
229
230 scoped_ptr<MockLayerTreeHost> layer_tree_host_;
khushalsagarb64b360d2015-10-21 19:25:16231 FakeImplTaskRunnerProvider task_runner_provider_;
[email protected]31d4df82013-07-18 10:17:22232 FakeLayerTreeHostClient fake_client_;
[email protected]4e2eb352014-03-20 17:25:45233 TestSharedBitmapManager shared_bitmap_manager_;
reveman34b7a1522015-03-23 20:27:47234 TestTaskGraphRunner task_graph_runner_;
revemand180dfc32015-09-24 00:19:43235 scoped_ptr<OutputSurface> output_surface_;
[email protected]31d4df82013-07-18 10:17:22236 FakeLayerTreeHostImpl host_impl_;
jbauman9015c8b2014-12-11 00:49:37237 CommonMailboxObjects test_data_;
loysoa6edaaff2015-05-25 03:26:44238 LayerSettings layer_settings_;
[email protected]31d4df82013-07-18 10:17:22239};
240
[email protected]31d4df82013-07-18 10:17:22241TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) {
kulkarni.a4015690f12014-10-10 13:50:06242 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44243 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]80d42bd2013-08-30 19:13:45244 EXPECT_SET_NEEDS_COMMIT(1, layer_tree_host_->SetRootLayer(test_layer));
[email protected]31d4df82013-07-18 10:17:22245
246 // Test properties that should call SetNeedsCommit. All properties need to
247 // be set to new values in order for SetNeedsCommit to be called.
248 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false));
jackhou10c9af42014-12-04 05:24:44249 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNearestNeighbor(true));
[email protected]31d4df82013-07-18 10:17:22250 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV(
251 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f)));
252 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity(
253 0.5f, 0.5f, 0.5f, 0.5f));
254 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false));
255 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true));
[email protected]31d4df82013-07-18 10:17:22256}
257
[email protected]df41e252014-02-03 23:39:50258class TestMailboxHolder : public TextureLayer::TextureMailboxHolder {
[email protected]9794fb32013-08-29 09:49:59259 public:
[email protected]df41e252014-02-03 23:39:50260 using TextureLayer::TextureMailboxHolder::Create;
[email protected]9794fb32013-08-29 09:49:59261
262 protected:
dcheng716bedf2014-10-21 09:51:08263 ~TestMailboxHolder() override {}
[email protected]9794fb32013-08-29 09:49:59264};
265
[email protected]de44a152013-01-08 15:28:46266class TextureLayerWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15267 protected:
dcheng93a52eb2014-12-23 02:14:23268 void TearDown() override {
[email protected]28571b042013-03-14 07:59:15269 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
dyencc16ed4d2015-11-03 20:03:04270 EXPECT_CALL(
271 test_data_.mock_callback_,
272 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
273 .Times(1);
[email protected]28571b042013-03-14 07:59:15274 TextureLayerTest::TearDown();
275 }
[email protected]de44a152013-01-08 15:28:46276};
277
[email protected]28571b042013-03-14 07:59:15278TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) {
kulkarni.a4015690f12014-10-10 13:50:06279 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44280 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]22898ed2013-06-01 04:52:30281 ASSERT_TRUE(test_layer.get());
[email protected]de44a152013-01-08 15:28:46282
[email protected]28571b042013-03-14 07:59:15283 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
284 layer_tree_host_->SetRootLayer(test_layer);
285 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46286
[email protected]28571b042013-03-14 07:59:15287 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16288 test_layer->SetTextureMailbox(
289 test_data_.mailbox1_,
290 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]28571b042013-03-14 07:59:15291 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
[email protected]de44a152013-01-08 15:28:46292
[email protected]28571b042013-03-14 07:59:15293 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04294 EXPECT_CALL(
295 test_data_.mock_callback_,
296 Release(test_data_.mailbox_name1_, test_data_.sync_token1_, false))
[email protected]28571b042013-03-14 07:59:15297 .Times(1);
[email protected]9260757f2013-09-17 01:24:16298 test_layer->SetTextureMailbox(
299 test_data_.mailbox2_,
300 SingleReleaseCallback::Create(test_data_.release_mailbox2_));
[email protected]28571b042013-03-14 07:59:15301 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
302 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46303
[email protected]28571b042013-03-14 07:59:15304 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
dyencc16ed4d2015-11-03 20:03:04305 EXPECT_CALL(
306 test_data_.mock_callback_,
307 Release(test_data_.mailbox_name2_, test_data_.sync_token2_, false))
[email protected]28571b042013-03-14 07:59:15308 .Times(1);
danakj968153f32014-10-15 22:52:16309 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15310 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
311 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46312
[email protected]80d42bd2013-08-30 19:13:45313 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16314 test_layer->SetTextureMailbox(
315 test_data_.mailbox3_,
316 SingleReleaseCallback::Create(test_data_.release_mailbox3_));
[email protected]42f40a52013-06-08 04:38:51317 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
318 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
319
[email protected]42f40a52013-06-08 04:38:51320 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
321 EXPECT_CALL(test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04322 Release2(test_data_.shared_bitmap_.get(), _, false))
323 .Times(1);
danakj968153f32014-10-15 22:52:16324 test_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]42f40a52013-06-08 04:38:51325 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
326 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
327
[email protected]28571b042013-03-14 07:59:15328 // Test destructor.
329 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
[email protected]9260757f2013-09-17 01:24:16330 test_layer->SetTextureMailbox(
331 test_data_.mailbox1_,
332 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]de44a152013-01-08 15:28:46333}
334
[email protected]f9e8f452014-03-07 22:09:40335TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
kulkarni.a4015690f12014-10-10 13:50:06336 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44337 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]f9e8f452014-03-07 22:09:40338 ASSERT_TRUE(test_layer.get());
339
340 // These use the same gpu::Mailbox, but different sync points.
dyen398dd0142016-01-21 22:05:56341 TextureMailbox mailbox1(MailboxFromChar('a'), SyncTokenFromUInt(1),
dyencc16ed4d2015-11-03 20:03:04342 GL_TEXTURE_2D);
dyen398dd0142016-01-21 22:05:56343 TextureMailbox mailbox2(MailboxFromChar('a'), SyncTokenFromUInt(2),
dyencc16ed4d2015-11-03 20:03:04344 GL_TEXTURE_2D);
[email protected]f9e8f452014-03-07 22:09:40345
[email protected]f9e8f452014-03-07 22:09:40346 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
347 layer_tree_host_->SetRootLayer(test_layer);
348 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
349
350 // Set the mailbox the first time. It should cause a commit.
[email protected]f9e8f452014-03-07 22:09:40351 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
352 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
353 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
354
355 // Set the mailbox again with a new sync point, as the backing texture has
356 // been updated. It should cause a new commit.
[email protected]f9e8f452014-03-07 22:09:40357 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
358 test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
359 Mock::VerifyAndClearExpectations(layer_tree_host_.get());
360}
361
[email protected]9794fb32013-08-29 09:49:59362class TextureLayerMailboxHolderTest : public TextureLayerTest {
363 public:
364 TextureLayerMailboxHolderTest()
365 : main_thread_("MAIN") {
366 main_thread_.Start();
skyostil0fd1dad2015-04-13 20:11:48367 main_thread_.message_loop()->task_runner()->PostTask(
368 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain,
369 base::Unretained(this)));
skyostil3976a3f2014-09-04 22:07:23370 Wait(main_thread_);
[email protected]9794fb32013-08-29 09:49:59371 }
372
373 void Wait(const base::Thread& thread) {
374 bool manual_reset = false;
375 bool initially_signaled = false;
376 base::WaitableEvent event(manual_reset, initially_signaled);
skyostil0fd1dad2015-04-13 20:11:48377 thread.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59378 FROM_HERE,
379 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
380 event.Wait();
381 }
382
383 void CreateMainRef() {
384 main_ref_ = TestMailboxHolder::Create(
[email protected]9260757f2013-09-17 01:24:16385 test_data_.mailbox1_,
danakja5a05ba02015-11-20 20:14:21386 SingleReleaseCallback::Create(test_data_.release_mailbox1_));
[email protected]9794fb32013-08-29 09:49:59387 }
388
danakjf446a072014-09-27 21:55:48389 void ReleaseMainRef() { main_ref_ = nullptr; }
[email protected]9794fb32013-08-29 09:49:59390
skyostil3976a3f2014-09-04 22:07:23391 void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) {
[email protected]9794fb32013-08-29 09:49:59392 *impl_ref = main_ref_->holder()->GetCallbackForImplThread();
393 }
394
395 void CapturePostTasksAndWait(base::WaitableEvent* begin_capture,
396 base::WaitableEvent* wait_for_capture,
397 base::WaitableEvent* stop_capture) {
398 begin_capture->Wait();
skyostil3976a3f2014-09-04 22:07:23399 BlockingTaskRunner::CapturePostTasks capture(
400 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59401 wait_for_capture->Signal();
402 stop_capture->Wait();
403 }
404
405 protected:
skyostil3976a3f2014-09-04 22:07:23406 void InitializeOnMain() {
407 main_thread_task_runner_ =
skyostil0fd1dad2015-04-13 20:11:48408 BlockingTaskRunner::Create(main_thread_.task_runner());
skyostil3976a3f2014-09-04 22:07:23409 }
410
[email protected]9794fb32013-08-29 09:49:59411 scoped_ptr<TestMailboxHolder::MainThreadReference>
412 main_ref_;
413 base::Thread main_thread_;
skyostil3976a3f2014-09-04 22:07:23414 scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
[email protected]9794fb32013-08-29 09:49:59415};
416
417TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) {
kulkarni.a4015690f12014-10-10 13:50:06418 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44419 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59420 ASSERT_TRUE(test_layer.get());
421
skyostil0fd1dad2015-04-13 20:11:48422 main_thread_.message_loop()->task_runner()->PostTask(
423 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
424 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59425
426 Wait(main_thread_);
427
428 // The texture layer is attached to compositor1, and passes a reference to its
429 // impl tree.
skyostil3976a3f2014-09-04 22:07:23430 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48431 main_thread_.message_loop()->task_runner()->PostTask(
432 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
433 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59434
435 // Then the texture layer is removed and attached to compositor2, and passes a
436 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23437 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48438 main_thread_.message_loop()->task_runner()->PostTask(
439 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
440 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59441
442 Wait(main_thread_);
443 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
444
445 // The compositors both destroy their impl trees before the main thread layer
446 // is destroyed.
dyen398dd0142016-01-21 22:05:56447 compositor1->Run(SyncTokenFromUInt(100), false,
448 main_thread_task_runner_.get());
449 compositor2->Run(SyncTokenFromUInt(200), false,
450 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59451
452 Wait(main_thread_);
453
454 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
455 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
456
457 // The main thread ref is the last one, so the mailbox is released back to the
458 // embedder, with the last sync point provided by the impl trees.
459 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56460 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), false))
dyencc16ed4d2015-11-03 20:03:04461 .Times(1);
[email protected]9794fb32013-08-29 09:49:59462
skyostil0fd1dad2015-04-13 20:11:48463 main_thread_.message_loop()->task_runner()->PostTask(
464 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
465 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59466 Wait(main_thread_);
467 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
468}
469
470TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) {
kulkarni.a4015690f12014-10-10 13:50:06471 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44472 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59473 ASSERT_TRUE(test_layer.get());
474
skyostil0fd1dad2015-04-13 20:11:48475 main_thread_.message_loop()->task_runner()->PostTask(
476 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
477 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59478
479 Wait(main_thread_);
480
481 // The texture layer is attached to compositor1, and passes a reference to its
482 // impl tree.
skyostil3976a3f2014-09-04 22:07:23483 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48484 main_thread_.message_loop()->task_runner()->PostTask(
485 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
486 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59487
488 // Then the texture layer is removed and attached to compositor2, and passes a
489 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23490 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48491 main_thread_.message_loop()->task_runner()->PostTask(
492 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
493 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59494
495 Wait(main_thread_);
496 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
497
498 // One compositor destroys their impl tree.
dyen398dd0142016-01-21 22:05:56499 compositor1->Run(SyncTokenFromUInt(100), false,
500 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59501
502 // Then the main thread reference is destroyed.
skyostil0fd1dad2015-04-13 20:11:48503 main_thread_.message_loop()->task_runner()->PostTask(
504 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
505 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59506
507 Wait(main_thread_);
508
509 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
510 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
511
512 // The second impl reference is destroyed last, causing the mailbox to be
513 // released back to the embedder with the last sync point from the impl tree.
514 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56515 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
dyencc16ed4d2015-11-03 20:03:04516 .Times(1);
[email protected]9794fb32013-08-29 09:49:59517
dyen398dd0142016-01-21 22:05:56518 compositor2->Run(SyncTokenFromUInt(200), true,
519 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59520 Wait(main_thread_);
521 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
522}
523
524TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) {
kulkarni.a4015690f12014-10-10 13:50:06525 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44526 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59527 ASSERT_TRUE(test_layer.get());
528
skyostil0fd1dad2015-04-13 20:11:48529 main_thread_.message_loop()->task_runner()->PostTask(
530 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
531 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59532
533 Wait(main_thread_);
534
535 // The texture layer is attached to compositor1, and passes a reference to its
536 // impl tree.
skyostil3976a3f2014-09-04 22:07:23537 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48538 main_thread_.message_loop()->task_runner()->PostTask(
539 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
540 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59541
542 // Then the texture layer is removed and attached to compositor2, and passes a
543 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23544 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48545 main_thread_.message_loop()->task_runner()->PostTask(
546 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
547 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59548
549 Wait(main_thread_);
550 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
551
552 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48553 main_thread_.message_loop()->task_runner()->PostTask(
554 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
555 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59556
557 // One compositor destroys their impl tree.
dyen398dd0142016-01-21 22:05:56558 compositor2->Run(SyncTokenFromUInt(200), false,
559 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59560
561 Wait(main_thread_);
562
563 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0);
564 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
565
566 // The second impl reference is destroyed last, causing the mailbox to be
567 // released back to the embedder with the last sync point from the impl tree.
568 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56569 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(100), true))
dyencc16ed4d2015-11-03 20:03:04570 .Times(1);
[email protected]9794fb32013-08-29 09:49:59571
dyen398dd0142016-01-21 22:05:56572 compositor1->Run(SyncTokenFromUInt(100), true,
573 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59574 Wait(main_thread_);
575 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
576}
577
578TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) {
kulkarni.a4015690f12014-10-10 13:50:06579 scoped_refptr<TextureLayer> test_layer =
loysoa6edaaff2015-05-25 03:26:44580 TextureLayer::CreateForMailbox(layer_settings_, nullptr);
[email protected]9794fb32013-08-29 09:49:59581 ASSERT_TRUE(test_layer.get());
582
skyostil0fd1dad2015-04-13 20:11:48583 main_thread_.message_loop()->task_runner()->PostTask(
584 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateMainRef,
585 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59586
587 Wait(main_thread_);
588
589 // The texture layer is attached to compositor1, and passes a reference to its
590 // impl tree.
skyostil3976a3f2014-09-04 22:07:23591 scoped_ptr<SingleReleaseCallbackImpl> compositor1;
skyostil0fd1dad2015-04-13 20:11:48592 main_thread_.message_loop()->task_runner()->PostTask(
593 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
594 base::Unretained(this), &compositor1));
[email protected]9794fb32013-08-29 09:49:59595
596 // Then the texture layer is removed and attached to compositor2, and passes a
597 // reference to its impl tree.
skyostil3976a3f2014-09-04 22:07:23598 scoped_ptr<SingleReleaseCallbackImpl> compositor2;
skyostil0fd1dad2015-04-13 20:11:48599 main_thread_.message_loop()->task_runner()->PostTask(
600 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef,
601 base::Unretained(this), &compositor2));
[email protected]9794fb32013-08-29 09:49:59602
603 Wait(main_thread_);
604 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
605
606 // The main thread reference is destroyed first.
skyostil0fd1dad2015-04-13 20:11:48607 main_thread_.message_loop()->task_runner()->PostTask(
608 FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::ReleaseMainRef,
609 base::Unretained(this)));
[email protected]9794fb32013-08-29 09:49:59610
611 EXPECT_CALL(test_data_.mock_callback_,
dyen398dd0142016-01-21 22:05:56612 Release(test_data_.mailbox_name1_, SyncTokenFromUInt(200), true))
dyencc16ed4d2015-11-03 20:03:04613 .Times(1);
[email protected]9794fb32013-08-29 09:49:59614
615 bool manual_reset = false;
616 bool initially_signaled = false;
617 base::WaitableEvent begin_capture(manual_reset, initially_signaled);
618 base::WaitableEvent wait_for_capture(manual_reset, initially_signaled);
619 base::WaitableEvent stop_capture(manual_reset, initially_signaled);
620
621 // Post a task to start capturing tasks on the main thread. This will block
622 // the main thread until we signal the |stop_capture| event.
skyostil0fd1dad2015-04-13 20:11:48623 main_thread_.message_loop()->task_runner()->PostTask(
[email protected]9794fb32013-08-29 09:49:59624 FROM_HERE,
625 base::Bind(&TextureLayerMailboxHolderTest::CapturePostTasksAndWait,
skyostil0fd1dad2015-04-13 20:11:48626 base::Unretained(this), &begin_capture, &wait_for_capture,
[email protected]9794fb32013-08-29 09:49:59627 &stop_capture));
628
629 // Before the main thread capturing starts, one compositor destroys their
630 // impl reference. Since capturing did not start, this gets post-tasked to
631 // the main thread.
dyen398dd0142016-01-21 22:05:56632 compositor1->Run(SyncTokenFromUInt(100), false,
633 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59634
635 // Start capturing on the main thread.
636 begin_capture.Signal();
637 wait_for_capture.Wait();
638
639 // Meanwhile, the second compositor released its impl reference, but this task
640 // gets shortcutted directly to the main thread. This means the reference is
641 // released before compositor1, whose reference will be released later when
642 // the post-task is serviced. But since it was destroyed _on the impl thread_
643 // last, its sync point values should be used.
dyen398dd0142016-01-21 22:05:56644 compositor2->Run(SyncTokenFromUInt(200), true,
645 main_thread_task_runner_.get());
[email protected]9794fb32013-08-29 09:49:59646
647 stop_capture.Signal();
648 Wait(main_thread_);
649
650 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
651}
652
[email protected]e216fef02013-03-20 22:56:10653class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest {
[email protected]28571b042013-03-14 07:59:15654 public:
655 TextureLayerImplWithMailboxThreadedCallback()
656 : callback_count_(0),
657 commit_count_(0) {}
658
659 // Make sure callback is received on main and doesn't block the impl thread.
dyencc16ed4d2015-11-03 20:03:04660 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:59661 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]7ba3ca72013-04-11 06:37:25662 EXPECT_FALSE(lost_resource);
[email protected]28571b042013-03-14 07:59:15663 ++callback_count_;
664 }
665
666 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:59667 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:16668 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]28571b042013-03-14 07:59:15669 base::Bind(
670 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback,
671 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:04672 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
673 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10674 std::move(callback));
[email protected]28571b042013-03-14 07:59:15675 }
676
dcheng716bedf2014-10-21 09:51:08677 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:59678 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
679
[email protected]28571b042013-03-14 07:59:15680 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:44681 root_ = Layer::Create(layer_settings());
[email protected]28571b042013-03-14 07:59:15682 root_->SetBounds(bounds);
683
loysoa6edaaff2015-05-25 03:26:44684 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]28571b042013-03-14 07:59:15685 layer_->SetIsDrawable(true);
[email protected]28571b042013-03-14 07:59:15686 layer_->SetBounds(bounds);
687
688 root_->AddChild(layer_);
[email protected]e216fef02013-03-20 22:56:10689 layer_tree_host()->SetRootLayer(root_);
[email protected]18ce59702013-04-09 04:58:40690 layer_tree_host()->SetViewportSize(bounds);
[email protected]28571b042013-03-14 07:59:15691 SetMailbox('1');
692 EXPECT_EQ(0, callback_count_);
693
694 // Case #1: change mailbox before the commit. The old mailbox should be
695 // released immediately.
696 SetMailbox('2');
697 EXPECT_EQ(1, callback_count_);
[email protected]e216fef02013-03-20 22:56:10698 PostSetNeedsCommitToMainThread();
[email protected]28571b042013-03-14 07:59:15699 }
700
dcheng716bedf2014-10-21 09:51:08701 void DidCommit() override {
[email protected]28571b042013-03-14 07:59:15702 ++commit_count_;
703 switch (commit_count_) {
704 case 1:
705 // Case #2: change mailbox after the commit (and draw), where the
706 // layer draws. The old mailbox should be released during the next
707 // commit.
708 SetMailbox('3');
709 EXPECT_EQ(1, callback_count_);
710 break;
711 case 2:
[email protected]28571b042013-03-14 07:59:15712 EXPECT_EQ(2, callback_count_);
713 // Case #3: change mailbox when the layer doesn't draw. The old
714 // mailbox should be released during the next commit.
715 layer_->SetBounds(gfx::Size());
716 SetMailbox('4');
717 break;
[email protected]9794fb32013-08-29 09:49:59718 case 3:
[email protected]28571b042013-03-14 07:59:15719 EXPECT_EQ(3, callback_count_);
720 // Case #4: release mailbox that was committed but never drawn. The
721 // old mailbox should be released during the next commit.
danakj968153f32014-10-15 22:52:16722 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]28571b042013-03-14 07:59:15723 break;
[email protected]9794fb32013-08-29 09:49:59724 case 4:
danakj431a1202015-06-17 19:09:33725 // With impl painting, the texture mailbox will still be on the impl
726 // thread when the commit finishes, because the layer is not drawble
727 // when it has no texture mailbox, and thus does not block the commit
728 // on activation. So, we wait for activation.
729 // TODO(danakj): fix this. crbug.com/277953
730 layer_tree_host()->SetNeedsCommit();
731 break;
[email protected]9794fb32013-08-29 09:49:59732 case 5:
[email protected]28571b042013-03-14 07:59:15733 EXPECT_EQ(4, callback_count_);
[email protected]7096acc2013-06-18 21:12:43734 // Restore a mailbox for the next step.
735 SetMailbox('5');
736 break;
[email protected]9794fb32013-08-29 09:49:59737 case 6:
[email protected]7096acc2013-06-18 21:12:43738 // Case #5: remove layer from tree. Callback should *not* be called, the
739 // mailbox is returned to the main thread.
740 EXPECT_EQ(4, callback_count_);
741 layer_->RemoveFromParent();
742 break;
[email protected]9794fb32013-08-29 09:49:59743 case 7:
danakj431a1202015-06-17 19:09:33744 // With impl painting, the texture mailbox will still be on the impl
745 // thread when the commit finishes, because the layer is not around to
746 // block the commit on activation anymore. So, we wait for activation.
747 // TODO(danakj): fix this. crbug.com/277953
748 layer_tree_host()->SetNeedsCommit();
749 break;
[email protected]9794fb32013-08-29 09:49:59750 case 8:
[email protected]7096acc2013-06-18 21:12:43751 EXPECT_EQ(4, callback_count_);
752 // Resetting the mailbox will call the callback now.
danakj968153f32014-10-15 22:52:16753 layer_->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]7096acc2013-06-18 21:12:43754 EXPECT_EQ(5, callback_count_);
[email protected]e216fef02013-03-20 22:56:10755 EndTest();
[email protected]28571b042013-03-14 07:59:15756 break;
757 default:
758 NOTREACHED();
759 break;
[email protected]de44a152013-01-08 15:28:46760 }
[email protected]28571b042013-03-14 07:59:15761 }
[email protected]de44a152013-01-08 15:28:46762
dcheng716bedf2014-10-21 09:51:08763 void AfterTest() override {}
[email protected]de44a152013-01-08 15:28:46764
[email protected]28571b042013-03-14 07:59:15765 private:
[email protected]9794fb32013-08-29 09:49:59766 base::ThreadChecker main_thread_;
[email protected]28571b042013-03-14 07:59:15767 int callback_count_;
768 int commit_count_;
769 scoped_refptr<Layer> root_;
770 scoped_refptr<TextureLayer> layer_;
[email protected]de44a152013-01-08 15:28:46771};
772
[email protected]4145d172013-05-10 16:54:36773SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
774 TextureLayerImplWithMailboxThreadedCallback);
[email protected]de44a152013-01-08 15:28:46775
[email protected]74b43cc2013-08-30 06:29:27776
[email protected]74b43cc2013-08-30 06:29:27777class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest {
778 protected:
[email protected]98ea818e2014-01-24 10:22:08779 TextureLayerMailboxIsActivatedDuringCommit() : activate_count_(0) {}
[email protected]74b43cc2013-08-30 06:29:27780
dyencc16ed4d2015-11-03 20:03:04781 static void ReleaseCallback(const gpu::SyncToken& sync_token,
782 bool lost_resource) {}
[email protected]74b43cc2013-08-30 06:29:27783
784 void SetMailbox(char mailbox_char) {
[email protected]9260757f2013-09-17 01:24:16785 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]74b43cc2013-08-30 06:29:27786 base::Bind(
787 &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback));
dyencc16ed4d2015-11-03 20:03:04788 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
789 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:10790 std::move(callback));
[email protected]74b43cc2013-08-30 06:29:27791 }
792
dcheng716bedf2014-10-21 09:51:08793 void BeginTest() override {
[email protected]74b43cc2013-08-30 06:29:27794 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:44795 root_ = Layer::Create(layer_settings());
[email protected]74b43cc2013-08-30 06:29:27796 root_->SetBounds(bounds);
797
loysoa6edaaff2015-05-25 03:26:44798 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]74b43cc2013-08-30 06:29:27799 layer_->SetIsDrawable(true);
[email protected]74b43cc2013-08-30 06:29:27800 layer_->SetBounds(bounds);
801
802 root_->AddChild(layer_);
803 layer_tree_host()->SetRootLayer(root_);
804 layer_tree_host()->SetViewportSize(bounds);
805 SetMailbox('1');
806
807 PostSetNeedsCommitToMainThread();
808 }
809
dcheng716bedf2014-10-21 09:51:08810 void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
danakj3c3973b2015-08-25 21:50:18811 base::AutoLock lock(activate_count_lock_);
[email protected]74b43cc2013-08-30 06:29:27812 ++activate_count_;
813 }
814
dcheng716bedf2014-10-21 09:51:08815 void DidCommit() override {
danakj3c3973b2015-08-25 21:50:18816 // The first frame doesn't cause anything to be returned so it does not
817 // need to wait for activation.
818 if (layer_tree_host()->source_frame_number() > 1) {
819 base::AutoLock lock(activate_count_lock_);
820 // The activate happened before commit is done on the main side.
821 EXPECT_EQ(activate_count_, layer_tree_host()->source_frame_number());
822 }
823
[email protected]98ea818e2014-01-24 10:22:08824 switch (layer_tree_host()->source_frame_number()) {
[email protected]74b43cc2013-08-30 06:29:27825 case 1:
826 // The first mailbox has been activated. Set a new mailbox, and
827 // expect the next commit to finish *after* it is activated.
828 SetMailbox('2');
[email protected]74b43cc2013-08-30 06:29:27829 break;
830 case 2:
831 // The second mailbox has been activated. Remove the layer from
832 // the tree to cause another commit/activation. The commit should
833 // finish *after* the layer is removed from the active tree.
834 layer_->RemoveFromParent();
[email protected]74b43cc2013-08-30 06:29:27835 break;
836 case 3:
837 EndTest();
838 break;
839 }
840 }
841
dcheng716bedf2014-10-21 09:51:08842 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
danakj3c3973b2015-08-25 21:50:18843 // The activate didn't happen before commit is done on the impl side (but it
844 // should happen before the main thread is done).
845 EXPECT_EQ(activate_count_, host_impl->sync_tree()->source_frame_number());
[email protected]74b43cc2013-08-30 06:29:27846 }
847
dcheng716bedf2014-10-21 09:51:08848 void AfterTest() override {}
[email protected]74b43cc2013-08-30 06:29:27849
danakj3c3973b2015-08-25 21:50:18850 base::Lock activate_count_lock_;
[email protected]74b43cc2013-08-30 06:29:27851 int activate_count_;
852 scoped_refptr<Layer> root_;
853 scoped_refptr<TextureLayer> layer_;
854};
855
856SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
857 TextureLayerMailboxIsActivatedDuringCommit);
858
[email protected]de44a152013-01-08 15:28:46859class TextureLayerImplWithMailboxTest : public TextureLayerTest {
[email protected]28571b042013-03-14 07:59:15860 protected:
[email protected]408b5e22013-03-19 09:48:09861 TextureLayerImplWithMailboxTest()
862 : fake_client_(
863 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
864
dcheng93a52eb2014-12-23 02:14:23865 void SetUp() override {
[email protected]28571b042013-03-14 07:59:15866 TextureLayerTest::SetUp();
danakjcf610582015-06-16 22:48:56867 layer_tree_host_ =
868 MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_);
sievers71c62dd52015-10-07 01:44:39869 host_impl_.SetVisible(true);
revemand180dfc32015-09-24 00:19:43870 EXPECT_TRUE(host_impl_.InitializeRenderer(output_surface_.get()));
[email protected]28571b042013-03-14 07:59:15871 }
[email protected]de44a152013-01-08 15:28:46872
[email protected]0ec335c42013-07-04 06:17:08873 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) {
874 bool will_draw = layer->WillDraw(
875 mode, host_impl_.active_tree()->resource_provider());
876 if (will_draw)
877 layer->DidDraw(host_impl_.active_tree()->resource_provider());
878 return will_draw;
879 }
880
[email protected]408b5e22013-03-19 09:48:09881 FakeLayerTreeHostClient fake_client_;
[email protected]de44a152013-01-08 15:28:46882};
883
[email protected]ffbb2212013-06-02 23:47:59884// Test conditions for results of TextureLayerImpl::WillDraw under
885// different configurations of different mailbox, texture_id, and draw_mode.
886TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
skyostil3976a3f2014-09-04 22:07:23887 EXPECT_CALL(
888 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04889 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]0ec335c42013-07-04 06:17:08890 .Times(AnyNumber());
dyencc16ed4d2015-11-03 20:03:04891 EXPECT_CALL(
892 test_data_.mock_callback_,
893 ReleaseImpl2(test_data_.shared_bitmap_.get(), gpu::SyncToken(), false, _))
[email protected]0ec335c42013-07-04 06:17:08894 .Times(AnyNumber());
[email protected]ffbb2212013-06-02 23:47:59895 // Hardware mode.
896 {
897 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11898 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16899 impl_layer->SetTextureMailbox(
900 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23901 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08902 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59903 }
904
905 {
906 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11907 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16908 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08909 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
910 }
911
912 {
913 // Software resource.
914 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11915 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16916 impl_layer->SetTextureMailbox(
917 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23918 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]3e44d7a2013-07-30 00:03:10919 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
[email protected]ffbb2212013-06-02 23:47:59920 }
921
[email protected]0ec335c42013-07-04 06:17:08922 // Software mode.
923 {
924 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11925 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16926 impl_layer->SetTextureMailbox(
927 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23928 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08929 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
930 }
931
932 {
933 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11934 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
danakj968153f32014-10-15 22:52:16935 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]0ec335c42013-07-04 06:17:08936 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
937 }
938
939 {
940 // Software resource.
941 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11942 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16943 impl_layer->SetTextureMailbox(
944 test_data_.mailbox3_,
skyostil3976a3f2014-09-04 22:07:23945 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_));
[email protected]0ec335c42013-07-04 06:17:08946 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
947 }
948
[email protected]ffbb2212013-06-02 23:47:59949 // Resourceless software mode.
950 {
951 scoped_ptr<TextureLayerImpl> impl_layer =
[email protected]17e08432014-04-10 00:41:11952 TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]9260757f2013-09-17 01:24:16953 impl_layer->SetTextureMailbox(
954 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23955 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]0ec335c42013-07-04 06:17:08956 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE));
[email protected]ffbb2212013-06-02 23:47:59957 }
[email protected]ffbb2212013-06-02 23:47:59958}
959
[email protected]28571b042013-03-14 07:59:15960TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) {
961 host_impl_.CreatePendingTree();
962 scoped_ptr<TextureLayerImpl> pending_layer;
[email protected]17e08432014-04-10 00:41:11963 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1);
[email protected]28571b042013-03-14 07:59:15964 ASSERT_TRUE(pending_layer);
[email protected]de44a152013-01-08 15:28:46965
[email protected]ed511b8d2013-03-25 03:29:29966 scoped_ptr<LayerImpl> active_layer(
[email protected]28571b042013-03-14 07:59:15967 pending_layer->CreateLayerImpl(host_impl_.active_tree()));
[email protected]ed511b8d2013-03-25 03:29:29968 ASSERT_TRUE(active_layer);
[email protected]de44a152013-01-08 15:28:46969
[email protected]9260757f2013-09-17 01:24:16970 pending_layer->SetTextureMailbox(
971 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23972 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]421e84f2013-02-22 03:27:15973
[email protected]28571b042013-03-14 07:59:15974 // Test multiple commits without an activation.
skyostil3976a3f2014-09-04 22:07:23975 EXPECT_CALL(
976 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:04977 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:15978 .Times(1);
[email protected]9260757f2013-09-17 01:24:16979 pending_layer->SetTextureMailbox(
980 test_data_.mailbox2_,
skyostil3976a3f2014-09-04 22:07:23981 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_));
[email protected]28571b042013-03-14 07:59:15982 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15983
[email protected]28571b042013-03-14 07:59:15984 // Test callback after activation.
[email protected]ed511b8d2013-03-25 03:29:29985 pending_layer->PushPropertiesTo(active_layer.get());
986 active_layer->DidBecomeActive();
[email protected]421e84f2013-02-22 03:27:15987
skyostil3976a3f2014-09-04 22:07:23988 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]9260757f2013-09-17 01:24:16989 pending_layer->SetTextureMailbox(
990 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:23991 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:15992 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]421e84f2013-02-22 03:27:15993
[email protected]7ba3ca72013-04-11 06:37:25994 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:23995 ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1);
[email protected]ed511b8d2013-03-25 03:29:29996 pending_layer->PushPropertiesTo(active_layer.get());
997 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:15998 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:46999
[email protected]28571b042013-03-14 07:59:151000 // Test resetting the mailbox.
[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);
danakj968153f32014-10-15 22:52:161003 pending_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]ed511b8d2013-03-25 03:29:291004 pending_layer->PushPropertiesTo(active_layer.get());
1005 active_layer->DidBecomeActive();
[email protected]28571b042013-03-14 07:59:151006 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]de44a152013-01-08 15:28:461007
[email protected]28571b042013-03-14 07:59:151008 // Test destructor.
skyostil3976a3f2014-09-04 22:07:231009 EXPECT_CALL(
1010 test_data_.mock_callback_,
dyencc16ed4d2015-11-03 20:03:041011 ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_token1_, false, _))
[email protected]28571b042013-03-14 07:59:151012 .Times(1);
[email protected]9260757f2013-09-17 01:24:161013 pending_layer->SetTextureMailbox(
1014 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231015 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]de44a152013-01-08 15:28:461016}
1017
[email protected]28571b042013-03-14 07:59:151018TEST_F(TextureLayerImplWithMailboxTest,
1019 TestDestructorCallbackOnCreatedResource) {
1020 scoped_ptr<TextureLayerImpl> impl_layer;
[email protected]17e08432014-04-10 00:41:111021 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1);
[email protected]28571b042013-03-14 07:59:151022 ASSERT_TRUE(impl_layer);
[email protected]de44a152013-01-08 15:28:461023
[email protected]7ba3ca72013-04-11 06:37:251024 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231025 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]9260757f2013-09-17 01:24:161026 impl_layer->SetTextureMailbox(
1027 test_data_.mailbox1_,
skyostil3976a3f2014-09-04 22:07:231028 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]ffbb2212013-06-02 23:47:591029 impl_layer->DidBecomeActive();
1030 EXPECT_TRUE(impl_layer->WillDraw(
1031 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
[email protected]28571b042013-03-14 07:59:151032 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider());
danakj968153f32014-10-15 22:52:161033 impl_layer->SetTextureMailbox(TextureMailbox(), nullptr);
[email protected]de44a152013-01-08 15:28:461034}
1035
[email protected]28571b042013-03-14 07:59:151036TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) {
1037 ResourceProvider* provider = host_impl_.active_tree()->resource_provider();
jbaumanbbd425e2015-05-19 00:33:351038 ResourceId id = provider->CreateResourceFromTextureMailbox(
skyostil3976a3f2014-09-04 22:07:231039 test_data_.mailbox1_,
1040 SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_));
[email protected]28571b042013-03-14 07:59:151041 provider->AllocateForTesting(id);
[email protected]de44a152013-01-08 15:28:461042
[email protected]28571b042013-03-14 07:59:151043 // Transfer some resources to the parent.
1044 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
1045 resource_ids_to_transfer.push_back(id);
1046 TransferableResourceArray list;
1047 provider->PrepareSendToParent(resource_ids_to_transfer, &list);
1048 EXPECT_TRUE(provider->InUseByConsumer(id));
skyostil3976a3f2014-09-04 22:07:231049 EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0);
[email protected]28571b042013-03-14 07:59:151050 provider->DeleteResource(id);
1051 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_);
[email protected]7ba3ca72013-04-11 06:37:251052 EXPECT_CALL(test_data_.mock_callback_,
skyostil3976a3f2014-09-04 22:07:231053 ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1);
[email protected]e00bab022013-08-19 00:42:451054 ReturnedResourceArray returned;
1055 TransferableResource::ReturnResources(list, &returned);
1056 provider->ReceiveReturnsFromParent(returned);
[email protected]de44a152013-01-08 15:28:461057}
1058
[email protected]4bad8b62013-10-24 01:27:291059// Checks that TextureLayer::Update does not cause an extra commit when setting
1060// the texture mailbox.
1061class TextureLayerNoExtraCommitForMailboxTest
1062 : public LayerTreeTest,
1063 public TextureLayerClient {
1064 public:
[email protected]4bad8b62013-10-24 01:27:291065 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081066 bool PrepareTextureMailbox(
[email protected]df41e252014-02-03 23:39:501067 TextureMailbox* texture_mailbox,
[email protected]4bad8b62013-10-24 01:27:291068 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371069 bool use_shared_memory) override {
[email protected]cce34bd2013-12-02 23:24:451070 if (layer_tree_host()->source_frame_number() == 1) {
[email protected]9f35bd22014-06-03 15:25:461071 // Once this has been committed, the mailbox will be released.
[email protected]df41e252014-02-03 23:39:501072 *texture_mailbox = TextureMailbox();
[email protected]cce34bd2013-12-02 23:24:451073 return true;
1074 }
[email protected]4bad8b62013-10-24 01:27:291075
dyencc16ed4d2015-11-03 20:03:041076 *texture_mailbox =
1077 TextureMailbox(MailboxFromChar('1'), gpu::SyncToken(), GL_TEXTURE_2D);
[email protected]4bad8b62013-10-24 01:27:291078 *release_callback = SingleReleaseCallback::Create(
1079 base::Bind(&TextureLayerNoExtraCommitForMailboxTest::MailboxReleased,
1080 base::Unretained(this)));
[email protected]4bad8b62013-10-24 01:27:291081 return true;
1082 }
1083
dyencc16ed4d2015-11-03 20:03:041084 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9f35bd22014-06-03 15:25:461085 // Source frame number during callback is the same as the source frame
1086 // on which it was released.
1087 EXPECT_EQ(1, layer_tree_host()->source_frame_number());
[email protected]cce34bd2013-12-02 23:24:451088 EndTest();
[email protected]4bad8b62013-10-24 01:27:291089 }
1090
dcheng716bedf2014-10-21 09:51:081091 void SetupTree() override {
loysoa6edaaff2015-05-25 03:26:441092 scoped_refptr<Layer> root = Layer::Create(layer_settings());
[email protected]4bad8b62013-10-24 01:27:291093 root->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291094 root->SetIsDrawable(true);
1095
loysoa6edaaff2015-05-25 03:26:441096 texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]4bad8b62013-10-24 01:27:291097 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]4bad8b62013-10-24 01:27:291098 texture_layer_->SetIsDrawable(true);
[email protected]0d7fb302014-01-23 21:30:471099 root->AddChild(texture_layer_);
[email protected]4bad8b62013-10-24 01:27:291100
1101 layer_tree_host()->SetRootLayer(root);
1102 LayerTreeTest::SetupTree();
1103 }
1104
dcheng716bedf2014-10-21 09:51:081105 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]4bad8b62013-10-24 01:27:291106
dcheng716bedf2014-10-21 09:51:081107 void DidCommitAndDrawFrame() override {
[email protected]4bad8b62013-10-24 01:27:291108 switch (layer_tree_host()->source_frame_number()) {
1109 case 1:
[email protected]4ea293f72014-08-13 03:03:171110 EXPECT_FALSE(proxy()->MainFrameWillHappenForTesting());
[email protected]cce34bd2013-12-02 23:24:451111 // Invalidate the texture layer to clear the mailbox before
1112 // ending the test.
1113 texture_layer_->SetNeedsDisplay();
1114 break;
1115 case 2:
[email protected]4bad8b62013-10-24 01:27:291116 break;
1117 default:
1118 NOTREACHED();
1119 break;
1120 }
1121 }
1122
dcheng716bedf2014-10-21 09:51:081123 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]cce34bd2013-12-02 23:24:451124 ASSERT_TRUE(result);
1125 DelegatedFrameData* delegated_frame_data =
1126 output_surface()->last_sent_frame().delegated_frame_data.get();
1127 if (!delegated_frame_data)
1128 return;
1129
1130 // Return all resources immediately.
1131 TransferableResourceArray resources_to_return =
1132 output_surface()->resources_held_by_parent();
1133
1134 CompositorFrameAck ack;
1135 for (size_t i = 0; i < resources_to_return.size(); ++i)
1136 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
1137 host_impl->ReclaimResources(&ack);
[email protected]cce34bd2013-12-02 23:24:451138 }
1139
dcheng716bedf2014-10-21 09:51:081140 void AfterTest() override {}
[email protected]4bad8b62013-10-24 01:27:291141
1142 private:
[email protected]4bad8b62013-10-24 01:27:291143 scoped_refptr<TextureLayer> texture_layer_;
[email protected]4bad8b62013-10-24 01:27:291144};
1145
[email protected]cce34bd2013-12-02 23:24:451146SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerNoExtraCommitForMailboxTest);
[email protected]4bad8b62013-10-24 01:27:291147
[email protected]b04264f92013-09-13 23:37:291148// Checks that changing a mailbox in the client for a TextureLayer that's
1149// invisible correctly works and uses the new mailbox as soon as the layer
1150// becomes visible (and returns the old one).
1151class TextureLayerChangeInvisibleMailboxTest
1152 : public LayerTreeTest,
1153 public TextureLayerClient {
1154 public:
1155 TextureLayerChangeInvisibleMailboxTest()
1156 : mailbox_changed_(true),
1157 mailbox_returned_(0),
1158 prepare_called_(0),
1159 commit_count_(0) {
1160 mailbox_ = MakeMailbox('1');
1161 }
1162
1163 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081164 bool PrepareTextureMailbox(
[email protected]e51444a2013-12-10 23:05:011165 TextureMailbox* mailbox,
[email protected]9260757f2013-09-17 01:24:161166 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371167 bool use_shared_memory) override {
[email protected]b04264f92013-09-13 23:37:291168 ++prepare_called_;
1169 if (!mailbox_changed_)
1170 return false;
1171 *mailbox = mailbox_;
[email protected]9260757f2013-09-17 01:24:161172 *release_callback = SingleReleaseCallback::Create(
1173 base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased,
1174 base::Unretained(this)));
[email protected]b04264f92013-09-13 23:37:291175 return true;
1176 }
1177
1178 TextureMailbox MakeMailbox(char name) {
dyencc16ed4d2015-11-03 20:03:041179 return TextureMailbox(MailboxFromChar(name), gpu::SyncToken(),
1180 GL_TEXTURE_2D);
[email protected]b04264f92013-09-13 23:37:291181 }
1182
dyencc16ed4d2015-11-03 20:03:041183 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]b04264f92013-09-13 23:37:291184 ++mailbox_returned_;
1185 }
1186
dcheng716bedf2014-10-21 09:51:081187 void SetupTree() override {
loysoa6edaaff2015-05-25 03:26:441188 scoped_refptr<Layer> root = Layer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291189 root->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291190 root->SetIsDrawable(true);
1191
loysoa6edaaff2015-05-25 03:26:441192 solid_layer_ = SolidColorLayer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291193 solid_layer_->SetBounds(gfx::Size(10, 10));
1194 solid_layer_->SetIsDrawable(true);
1195 solid_layer_->SetBackgroundColor(SK_ColorWHITE);
1196 root->AddChild(solid_layer_);
1197
loysoa6edaaff2015-05-25 03:26:441198 parent_layer_ = Layer::Create(layer_settings());
[email protected]b04264f92013-09-13 23:37:291199 parent_layer_->SetBounds(gfx::Size(10, 10));
1200 parent_layer_->SetIsDrawable(true);
1201 root->AddChild(parent_layer_);
1202
loysoa6edaaff2015-05-25 03:26:441203 texture_layer_ = TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]b04264f92013-09-13 23:37:291204 texture_layer_->SetBounds(gfx::Size(10, 10));
[email protected]b04264f92013-09-13 23:37:291205 texture_layer_->SetIsDrawable(true);
1206 parent_layer_->AddChild(texture_layer_);
1207
1208 layer_tree_host()->SetRootLayer(root);
1209 LayerTreeTest::SetupTree();
1210 }
1211
dcheng716bedf2014-10-21 09:51:081212 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
[email protected]b04264f92013-09-13 23:37:291213
dcheng716bedf2014-10-21 09:51:081214 void DidCommitAndDrawFrame() override {
[email protected]b04264f92013-09-13 23:37:291215 ++commit_count_;
1216 switch (commit_count_) {
1217 case 1:
1218 // We should have updated the layer, committing the texture.
1219 EXPECT_EQ(1, prepare_called_);
1220 // Make layer invisible.
1221 parent_layer_->SetOpacity(0.f);
1222 break;
1223 case 2:
1224 // Layer shouldn't have been updated.
1225 EXPECT_EQ(1, prepare_called_);
1226 // Change the texture.
1227 mailbox_ = MakeMailbox('2');
1228 mailbox_changed_ = true;
1229 texture_layer_->SetNeedsDisplay();
1230 // Force a change to make sure we draw a frame.
1231 solid_layer_->SetBackgroundColor(SK_ColorGRAY);
1232 break;
1233 case 3:
1234 // Layer shouldn't have been updated.
1235 EXPECT_EQ(1, prepare_called_);
1236 // So the old mailbox isn't returned yet.
1237 EXPECT_EQ(0, mailbox_returned_);
1238 // Make layer visible again.
1239 parent_layer_->SetOpacity(1.f);
1240 break;
1241 case 4:
1242 // Layer should have been updated.
1243 EXPECT_EQ(2, prepare_called_);
1244 // So the old mailbox should have been returned already.
1245 EXPECT_EQ(1, mailbox_returned_);
1246 texture_layer_->ClearClient();
1247 break;
1248 case 5:
1249 EXPECT_EQ(2, mailbox_returned_);
1250 EndTest();
1251 break;
1252 default:
1253 NOTREACHED();
1254 break;
1255 }
1256 }
1257
dcheng716bedf2014-10-21 09:51:081258 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
[email protected]b04264f92013-09-13 23:37:291259 ASSERT_TRUE(result);
1260 DelegatedFrameData* delegated_frame_data =
1261 output_surface()->last_sent_frame().delegated_frame_data.get();
1262 if (!delegated_frame_data)
1263 return;
1264
1265 // Return all resources immediately.
1266 TransferableResourceArray resources_to_return =
1267 output_surface()->resources_held_by_parent();
1268
1269 CompositorFrameAck ack;
1270 for (size_t i = 0; i < resources_to_return.size(); ++i)
1271 output_surface()->ReturnResource(resources_to_return[i].id, &ack);
[email protected]a7335e0b2013-09-18 09:34:511272 host_impl->ReclaimResources(&ack);
[email protected]b04264f92013-09-13 23:37:291273 }
1274
dcheng716bedf2014-10-21 09:51:081275 void AfterTest() override {}
[email protected]b04264f92013-09-13 23:37:291276
1277 private:
1278 scoped_refptr<SolidColorLayer> solid_layer_;
1279 scoped_refptr<Layer> parent_layer_;
1280 scoped_refptr<TextureLayer> texture_layer_;
1281
1282 // Used on the main thread.
1283 bool mailbox_changed_;
1284 TextureMailbox mailbox_;
1285 int mailbox_returned_;
1286 int prepare_called_;
1287 int commit_count_;
1288};
1289
1290SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest);
1291
[email protected]0d7fb302014-01-23 21:30:471292// Test that TextureLayerImpl::ReleaseResources can be called which releases
1293// the mailbox back to TextureLayerClient.
1294class TextureLayerReleaseResourcesBase
1295 : public LayerTreeTest,
1296 public TextureLayerClient {
1297 public:
1298 // TextureLayerClient implementation.
dcheng716bedf2014-10-21 09:51:081299 bool PrepareTextureMailbox(
[email protected]0d7fb302014-01-23 21:30:471300 TextureMailbox* mailbox,
1301 scoped_ptr<SingleReleaseCallback>* release_callback,
mostynbf68776d82014-10-06 18:07:371302 bool use_shared_memory) override {
dyencc16ed4d2015-11-03 20:03:041303 *mailbox =
1304 TextureMailbox(MailboxFromChar('1'), gpu::SyncToken(), GL_TEXTURE_2D);
[email protected]0d7fb302014-01-23 21:30:471305 *release_callback = SingleReleaseCallback::Create(
1306 base::Bind(&TextureLayerReleaseResourcesBase::MailboxReleased,
1307 base::Unretained(this)));
1308 return true;
1309 }
1310
dyencc16ed4d2015-11-03 20:03:041311 void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]0d7fb302014-01-23 21:30:471312 mailbox_released_ = true;
1313 }
1314
dcheng716bedf2014-10-21 09:51:081315 void SetupTree() override {
[email protected]0d7fb302014-01-23 21:30:471316 LayerTreeTest::SetupTree();
1317
1318 scoped_refptr<TextureLayer> texture_layer =
loysoa6edaaff2015-05-25 03:26:441319 TextureLayer::CreateForMailbox(layer_settings(), this);
[email protected]0d7fb302014-01-23 21:30:471320 texture_layer->SetBounds(gfx::Size(10, 10));
[email protected]0d7fb302014-01-23 21:30:471321 texture_layer->SetIsDrawable(true);
1322
1323 layer_tree_host()->root_layer()->AddChild(texture_layer);
1324 }
1325
dcheng716bedf2014-10-21 09:51:081326 void BeginTest() override {
[email protected]0d7fb302014-01-23 21:30:471327 mailbox_released_ = false;
1328 PostSetNeedsCommitToMainThread();
1329 }
1330
dcheng716bedf2014-10-21 09:51:081331 void DidCommitAndDrawFrame() override { EndTest(); }
[email protected]0d7fb302014-01-23 21:30:471332
dcheng716bedf2014-10-21 09:51:081333 void AfterTest() override { EXPECT_TRUE(mailbox_released_); }
[email protected]0d7fb302014-01-23 21:30:471334
1335 private:
1336 bool mailbox_released_;
1337};
1338
1339class TextureLayerReleaseResourcesAfterCommit
1340 : public TextureLayerReleaseResourcesBase {
1341 public:
dcheng716bedf2014-10-21 09:51:081342 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
kulkarni.a4015690f12014-10-10 13:50:061343 LayerTreeImpl* tree = nullptr;
danakj009cdfdf2015-02-17 22:35:141344 tree = host_impl->sync_tree();
[email protected]0d7fb302014-01-23 21:30:471345 tree->root_layer()->children()[0]->ReleaseResources();
1346 }
1347};
1348
1349SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterCommit);
1350
1351class TextureLayerReleaseResourcesAfterActivate
1352 : public TextureLayerReleaseResourcesBase {
1353 public:
dcheng716bedf2014-10-21 09:51:081354 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
[email protected]0d7fb302014-01-23 21:30:471355 host_impl->active_tree()->root_layer()->children()[0]->ReleaseResources();
1356 }
1357};
1358
1359SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerReleaseResourcesAfterActivate);
1360
[email protected]9c2bd822013-07-26 12:30:171361class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest {
1362 public:
dyencc16ed4d2015-11-03 20:03:041363 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591364 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171365 EXPECT_FALSE(lost_resource);
1366 ++callback_count_;
1367 EndTest();
1368 }
1369
1370 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591371 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161372 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171373 base::Bind(
1374 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback,
1375 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:041376 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
1377 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:101378 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171379 }
1380
dcheng716bedf2014-10-21 09:51:081381 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171382 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:441383 root_ = Layer::Create(layer_settings());
[email protected]9c2bd822013-07-26 12:30:171384 root_->SetBounds(bounds);
1385
loysoa6edaaff2015-05-25 03:26:441386 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]9c2bd822013-07-26 12:30:171387 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171388 layer_->SetBounds(bounds);
1389
1390 root_->AddChild(layer_);
1391 layer_tree_host()->SetRootLayer(root_);
1392 layer_tree_host()->SetViewportSize(bounds);
1393 }
1394
dcheng716bedf2014-10-21 09:51:081395 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591396 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1397
[email protected]9c2bd822013-07-26 12:30:171398 callback_count_ = 0;
1399
1400 // Set the mailbox on the main thread.
1401 SetMailbox('1');
1402 EXPECT_EQ(0, callback_count_);
1403
1404 PostSetNeedsCommitToMainThread();
1405 }
1406
dcheng716bedf2014-10-21 09:51:081407 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171408 switch (layer_tree_host()->source_frame_number()) {
1409 case 1:
1410 // Delete the TextureLayer on the main thread while the mailbox is in
1411 // the impl tree.
1412 layer_->RemoveFromParent();
kulkarni.a4015690f12014-10-10 13:50:061413 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171414 break;
1415 }
1416 }
1417
dcheng716bedf2014-10-21 09:51:081418 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171419
1420 private:
[email protected]9794fb32013-08-29 09:49:591421 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171422 int callback_count_;
1423 scoped_refptr<Layer> root_;
1424 scoped_refptr<TextureLayer> layer_;
1425};
1426
1427SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1428 TextureLayerWithMailboxMainThreadDeleted);
1429
1430class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest {
1431 public:
dyencc16ed4d2015-11-03 20:03:041432 void ReleaseCallback(const gpu::SyncToken& sync_token, bool lost_resource) {
[email protected]9794fb32013-08-29 09:49:591433 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9c2bd822013-07-26 12:30:171434 EXPECT_FALSE(lost_resource);
1435 ++callback_count_;
1436 EndTest();
1437 }
1438
1439 void SetMailbox(char mailbox_char) {
[email protected]9794fb32013-08-29 09:49:591440 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
[email protected]9260757f2013-09-17 01:24:161441 scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create(
[email protected]9c2bd822013-07-26 12:30:171442 base::Bind(
1443 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback,
1444 base::Unretained(this)));
dyencc16ed4d2015-11-03 20:03:041445 layer_->SetTextureMailbox(TextureMailbox(MailboxFromChar(mailbox_char),
1446 gpu::SyncToken(), GL_TEXTURE_2D),
danakja04855a2015-11-18 20:39:101447 std::move(callback));
[email protected]9c2bd822013-07-26 12:30:171448 }
1449
dcheng716bedf2014-10-21 09:51:081450 void SetupTree() override {
[email protected]9c2bd822013-07-26 12:30:171451 gfx::Size bounds(100, 100);
loysoa6edaaff2015-05-25 03:26:441452 root_ = Layer::Create(layer_settings());
[email protected]9c2bd822013-07-26 12:30:171453 root_->SetBounds(bounds);
1454
loysoa6edaaff2015-05-25 03:26:441455 layer_ = TextureLayer::CreateForMailbox(layer_settings(), nullptr);
[email protected]9c2bd822013-07-26 12:30:171456 layer_->SetIsDrawable(true);
[email protected]9c2bd822013-07-26 12:30:171457 layer_->SetBounds(bounds);
1458
1459 root_->AddChild(layer_);
1460 layer_tree_host()->SetRootLayer(root_);
1461 layer_tree_host()->SetViewportSize(bounds);
1462 }
1463
dcheng716bedf2014-10-21 09:51:081464 void BeginTest() override {
[email protected]9794fb32013-08-29 09:49:591465 EXPECT_EQ(true, main_thread_.CalledOnValidThread());
1466
[email protected]9c2bd822013-07-26 12:30:171467 callback_count_ = 0;
1468
1469 // Set the mailbox on the main thread.
1470 SetMailbox('1');
1471 EXPECT_EQ(0, callback_count_);
1472
1473 PostSetNeedsCommitToMainThread();
1474 }
1475
dcheng716bedf2014-10-21 09:51:081476 void DidCommitAndDrawFrame() override {
[email protected]9c2bd822013-07-26 12:30:171477 switch (layer_tree_host()->source_frame_number()) {
1478 case 1:
1479 // Remove the TextureLayer on the main thread while the mailbox is in
1480 // the impl tree, but don't delete the TextureLayer until after the impl
1481 // tree side is deleted.
1482 layer_->RemoveFromParent();
1483 break;
1484 case 2:
kulkarni.a4015690f12014-10-10 13:50:061485 layer_ = nullptr;
[email protected]9c2bd822013-07-26 12:30:171486 break;
1487 }
1488 }
1489
dcheng716bedf2014-10-21 09:51:081490 void AfterTest() override { EXPECT_EQ(1, callback_count_); }
[email protected]9c2bd822013-07-26 12:30:171491
1492 private:
[email protected]9794fb32013-08-29 09:49:591493 base::ThreadChecker main_thread_;
[email protected]9c2bd822013-07-26 12:30:171494 int callback_count_;
1495 scoped_refptr<Layer> root_;
1496 scoped_refptr<TextureLayer> layer_;
1497};
1498
1499SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(
1500 TextureLayerWithMailboxImplThreadDeleted);
1501
[email protected]ba565742012-11-10 09:29:481502} // namespace
1503} // namespace cc