1 /* vim:set ts=2 sw=2 sts=2 et: */
2 /* Any copyright is dedicated to the Public Domain.
3 * http://creativecommons.org/publicdomain/zero/1.0/
4 */
5
6 #include "TestLayers.h"
7 #include "gtest/gtest.h"
8 #include "gmock/gmock.h"
9 #include "LayerUserData.h"
10 #include "mozilla/layers/LayerMetricsWrapper.h"
11 #include "mozilla/layers/CompositorBridgeParent.h"
12
13 using namespace mozilla;
14 using namespace mozilla::gfx;
15 using namespace mozilla::layers;
16
17 class TestContainerLayer : public ContainerLayer {
18 public:
TestContainerLayer(LayerManager * aManager)19 explicit TestContainerLayer(LayerManager* aManager)
20 : ContainerLayer(aManager, nullptr) {}
21
Name() const22 virtual const char* Name() const { return "TestContainerLayer"; }
23
GetType() const24 virtual LayerType GetType() const { return TYPE_CONTAINER; }
25
ComputeEffectiveTransforms(const Matrix4x4 & aTransformToSurface)26 virtual void ComputeEffectiveTransforms(
27 const Matrix4x4& aTransformToSurface) {
28 DefaultComputeEffectiveTransforms(aTransformToSurface);
29 }
30 };
31
32 class TestPaintedLayer : public PaintedLayer {
33 public:
TestPaintedLayer(LayerManager * aManager)34 explicit TestPaintedLayer(LayerManager* aManager)
35 : PaintedLayer(aManager, nullptr) {}
36
Name() const37 virtual const char* Name() const { return "TestPaintedLayer"; }
38
GetType() const39 virtual LayerType GetType() const { return TYPE_PAINTED; }
40
InvalidateRegion(const nsIntRegion & aRegion)41 virtual void InvalidateRegion(const nsIntRegion& aRegion) { MOZ_CRASH(); }
42 };
43
44 class TestLayerManager : public LayerManager {
45 public:
TestLayerManager()46 TestLayerManager() : LayerManager() {}
47
EndEmptyTransaction(EndTransactionFlags aFlags=END_DEFAULT)48 virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) {
49 return false;
50 }
CreateContainerLayer()51 virtual already_AddRefed<ContainerLayer> CreateContainerLayer() {
52 RefPtr<ContainerLayer> layer = new TestContainerLayer(this);
53 return layer.forget();
54 }
GetBackendName(nsAString & aName)55 virtual void GetBackendName(nsAString& aName) {}
GetBackendType()56 virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_BASIC; }
BeginTransaction(const nsCString &=nsCString ())57 virtual bool BeginTransaction(const nsCString& = nsCString()) { return true; }
CreateImageLayer()58 virtual already_AddRefed<ImageLayer> CreateImageLayer() {
59 MOZ_CRASH("Not implemented.");
60 }
CreatePaintedLayer()61 virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() {
62 RefPtr<PaintedLayer> layer = new TestPaintedLayer(this);
63 return layer.forget();
64 }
CreateColorLayer()65 virtual already_AddRefed<ColorLayer> CreateColorLayer() {
66 MOZ_CRASH("Not implemented.");
67 }
SetRoot(Layer * aLayer)68 virtual void SetRoot(Layer* aLayer) {}
BeginTransactionWithTarget(gfxContext * aTarget,const nsCString &=nsCString ())69 virtual bool BeginTransactionWithTarget(gfxContext* aTarget,
70 const nsCString& = nsCString()) {
71 return true;
72 }
CreateCanvasLayer()73 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() {
74 MOZ_CRASH("Not implemented.");
75 }
EndTransaction(DrawPaintedLayerCallback aCallback,void * aCallbackData,EndTransactionFlags aFlags=END_DEFAULT)76 virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
77 void* aCallbackData,
78 EndTransactionFlags aFlags = END_DEFAULT) {}
GetMaxTextureSize() const79 virtual int32_t GetMaxTextureSize() const { return 0; }
80 };
81
82 class TestUserData : public LayerUserData {
83 public:
84 MOCK_METHOD0(Die, void());
~TestUserData()85 virtual ~TestUserData() { Die(); }
86 };
87
TEST(Layers,LayerConstructor)88 TEST(Layers, LayerConstructor)
89 { TestContainerLayer layer(nullptr); }
90
TEST(Layers,Defaults)91 TEST(Layers, Defaults)
92 {
93 TestContainerLayer layer(nullptr);
94 ASSERT_EQ(1.0, layer.GetOpacity());
95 ASSERT_EQ(1.0f, layer.GetPostXScale());
96 ASSERT_EQ(1.0f, layer.GetPostYScale());
97
98 ASSERT_EQ(nullptr, layer.GetNextSibling());
99 ASSERT_EQ(nullptr, layer.GetPrevSibling());
100 ASSERT_EQ(nullptr, layer.GetFirstChild());
101 ASSERT_EQ(nullptr, layer.GetLastChild());
102 }
103
TEST(Layers,Transform)104 TEST(Layers, Transform)
105 {
106 TestContainerLayer layer(nullptr);
107
108 Matrix4x4 identity;
109 ASSERT_EQ(true, identity.IsIdentity());
110
111 ASSERT_EQ(identity, layer.GetTransform());
112 }
113
TEST(Layers,Type)114 TEST(Layers, Type)
115 {
116 TestContainerLayer layer(nullptr);
117 ASSERT_EQ(nullptr, layer.AsPaintedLayer());
118 ASSERT_EQ(nullptr, layer.AsRefLayer());
119 ASSERT_EQ(nullptr, layer.AsColorLayer());
120 }
121
TEST(Layers,UserData)122 TEST(Layers, UserData)
123 {
124 UniquePtr<TestContainerLayer> layerPtr(new TestContainerLayer(nullptr));
125 TestContainerLayer& layer = *layerPtr;
126
127 void* key1 = (void*)1;
128 void* key2 = (void*)2;
129 void* key3 = (void*)3;
130
131 ASSERT_EQ(nullptr, layer.GetUserData(key1));
132 ASSERT_EQ(nullptr, layer.GetUserData(key2));
133 ASSERT_EQ(nullptr, layer.GetUserData(key3));
134
135 TestUserData* data1 = new TestUserData;
136 TestUserData* data2 = new TestUserData;
137 TestUserData* data3 = new TestUserData;
138
139 layer.SetUserData(key1, data1);
140 layer.SetUserData(key2, data2);
141 layer.SetUserData(key3, data3);
142
143 // Also checking that the user data is returned but not free'd
144 UniquePtr<LayerUserData> d1(layer.RemoveUserData(key1));
145 UniquePtr<LayerUserData> d2(layer.RemoveUserData(key2));
146 UniquePtr<LayerUserData> d3(layer.RemoveUserData(key3));
147 ASSERT_EQ(data1, d1.get());
148 ASSERT_EQ(data2, d2.get());
149 ASSERT_EQ(data3, d3.get());
150
151 layer.SetUserData(key1, d1.release());
152 layer.SetUserData(key2, d2.release());
153 layer.SetUserData(key3, d3.release());
154
155 // Layer has ownership of data1-3, check that they are destroyed
156 EXPECT_CALL(*data1, Die());
157 EXPECT_CALL(*data2, Die());
158 EXPECT_CALL(*data3, Die());
159 }
160
CreateLayer(char aLayerType,LayerManager * aManager)161 static already_AddRefed<Layer> CreateLayer(char aLayerType,
162 LayerManager* aManager) {
163 RefPtr<Layer> layer = nullptr;
164 if (aLayerType == 'c') {
165 layer = aManager->CreateContainerLayer();
166 } else if (aLayerType == 't') {
167 layer = aManager->CreatePaintedLayer();
168 } else if (aLayerType == 'o') {
169 layer = aManager->CreateColorLayer();
170 }
171 return layer.forget();
172 }
173
CreateLayerTree(const char * aLayerTreeDescription,nsIntRegion * aVisibleRegions,const Matrix4x4 * aTransforms,RefPtr<LayerManager> & manager,nsTArray<RefPtr<Layer>> & aLayersOut)174 already_AddRefed<Layer> CreateLayerTree(const char* aLayerTreeDescription,
175 nsIntRegion* aVisibleRegions,
176 const Matrix4x4* aTransforms,
177 RefPtr<LayerManager>& manager,
178 nsTArray<RefPtr<Layer> >& aLayersOut) {
179 aLayersOut.Clear();
180
181 if (!manager) {
182 manager = new TestLayerManager();
183 }
184
185 RefPtr<Layer> rootLayer = nullptr;
186 RefPtr<ContainerLayer> parentContainerLayer = nullptr;
187 RefPtr<Layer> lastLayer = nullptr;
188 int layerNumber = 0;
189 for (size_t i = 0; i < strlen(aLayerTreeDescription); i++) {
190 if (aLayerTreeDescription[i] == '(') {
191 if (!lastLayer) {
192 printf(
193 "Syntax error, likely '(' character isn't preceded by a "
194 "container.\n");
195 MOZ_CRASH();
196 }
197 parentContainerLayer = lastLayer->AsContainerLayer();
198 if (!parentContainerLayer) {
199 printf("Layer before '(' must be a container.\n");
200 MOZ_CRASH();
201 }
202 } else if (aLayerTreeDescription[i] == ')') {
203 parentContainerLayer = parentContainerLayer->GetParent();
204 lastLayer = nullptr;
205 } else {
206 RefPtr<Layer> layer =
207 CreateLayer(aLayerTreeDescription[i], manager.get());
208 if (aVisibleRegions) {
209 layer->SetVisibleRegion(
210 LayerIntRegion::FromUnknownRegion(aVisibleRegions[layerNumber]));
211 layer->SetEventRegions(EventRegions(aVisibleRegions[layerNumber]));
212 }
213 if (aTransforms) {
214 layer->SetBaseTransform(aTransforms[layerNumber]);
215 }
216 aLayersOut.AppendElement(layer);
217 layerNumber++;
218 if (rootLayer && !parentContainerLayer) {
219 MOZ_CRASH();
220 }
221 if (!rootLayer) {
222 rootLayer = layer;
223 }
224 if (parentContainerLayer) {
225 parentContainerLayer->InsertAfter(layer,
226 parentContainerLayer->GetLastChild());
227 layer->SetParent(parentContainerLayer);
228 }
229 lastLayer = layer;
230 }
231 }
232 if (rootLayer) {
233 rootLayer->ComputeEffectiveTransforms(Matrix4x4());
234 manager->SetRoot(rootLayer);
235 if (rootLayer->AsHostLayer()) {
236 // Only perform this for LayerManagerComposite
237 CompositorBridgeParent::SetShadowProperties(rootLayer);
238 }
239 }
240 return rootLayer.forget();
241 }
242
TEST(Layers,LayerTree)243 TEST(Layers, LayerTree)
244 {
245 const char* layerTreeSyntax = "c(c(tt))";
246 nsIntRegion layerVisibleRegion[] = {
247 nsIntRegion(IntRect(0, 0, 100, 100)),
248 nsIntRegion(IntRect(0, 0, 100, 100)),
249 nsIntRegion(IntRect(0, 0, 100, 100)),
250 nsIntRegion(IntRect(10, 10, 20, 20)),
251 };
252 Matrix4x4 transforms[] = {
253 Matrix4x4(),
254 Matrix4x4(),
255 Matrix4x4(),
256 Matrix4x4(),
257 };
258 nsTArray<RefPtr<Layer> > layers;
259
260 RefPtr<LayerManager> lm;
261 RefPtr<Layer> root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion,
262 transforms, lm, layers);
263
264 // B2G g++ doesn't like ASSERT_NE with nullptr directly. It thinks it's
265 // an int.
266 Layer* nullLayer = nullptr;
267 ASSERT_NE(nullLayer, layers[0]->AsContainerLayer());
268 ASSERT_NE(nullLayer, layers[1]->AsContainerLayer());
269 ASSERT_NE(nullLayer, layers[2]->AsPaintedLayer());
270 ASSERT_NE(nullLayer, layers[3]->AsPaintedLayer());
271 }
272
ValidateTreePointers(Layer * aLayer)273 static void ValidateTreePointers(Layer* aLayer) {
274 if (aLayer->GetNextSibling()) {
275 ASSERT_EQ(aLayer, aLayer->GetNextSibling()->GetPrevSibling());
276 } else if (aLayer->GetParent()) {
277 ASSERT_EQ(aLayer, aLayer->GetParent()->GetLastChild());
278 }
279 if (aLayer->GetPrevSibling()) {
280 ASSERT_EQ(aLayer, aLayer->GetPrevSibling()->GetNextSibling());
281 } else if (aLayer->GetParent()) {
282 ASSERT_EQ(aLayer, aLayer->GetParent()->GetFirstChild());
283 }
284 if (aLayer->GetFirstChild()) {
285 ASSERT_EQ(aLayer, aLayer->GetFirstChild()->GetParent());
286 }
287 if (aLayer->GetLastChild()) {
288 ASSERT_EQ(aLayer, aLayer->GetLastChild()->GetParent());
289 }
290 }
291
ValidateTreePointers(nsTArray<RefPtr<Layer>> & aLayers)292 static void ValidateTreePointers(nsTArray<RefPtr<Layer> >& aLayers) {
293 for (uint32_t i = 0; i < aLayers.Length(); i++) {
294 ValidateTreePointers(aLayers[i]);
295 }
296 }
297
TEST(Layers,RepositionChild)298 TEST(Layers, RepositionChild)
299 {
300 const char* layerTreeSyntax = "c(ttt)";
301
302 nsTArray<RefPtr<Layer> > layers;
303 RefPtr<LayerManager> lm;
304 RefPtr<Layer> root =
305 CreateLayerTree(layerTreeSyntax, nullptr, nullptr, lm, layers);
306 ContainerLayer* parent = root->AsContainerLayer();
307 ValidateTreePointers(layers);
308
309 // tree is currently like this (using indexes into layers):
310 // 0
311 // 1 2 3
312 ASSERT_EQ(layers[2], layers[1]->GetNextSibling());
313 ASSERT_EQ(layers[3], layers[2]->GetNextSibling());
314 ASSERT_EQ(nullptr, layers[3]->GetNextSibling());
315
316 parent->RepositionChild(layers[1], layers[3]);
317 ValidateTreePointers(layers);
318
319 // now the tree is like this:
320 // 0
321 // 2 3 1
322 ASSERT_EQ(layers[3], layers[2]->GetNextSibling());
323 ASSERT_EQ(layers[1], layers[3]->GetNextSibling());
324 ASSERT_EQ(nullptr, layers[1]->GetNextSibling());
325
326 parent->RepositionChild(layers[3], layers[2]);
327 ValidateTreePointers(layers);
328
329 // no change
330 ASSERT_EQ(layers[3], layers[2]->GetNextSibling());
331 ASSERT_EQ(layers[1], layers[3]->GetNextSibling());
332 ASSERT_EQ(nullptr, layers[1]->GetNextSibling());
333
334 parent->RepositionChild(layers[3], layers[1]);
335 ValidateTreePointers(layers);
336
337 // 0
338 // 2 1 3
339 ASSERT_EQ(layers[1], layers[2]->GetNextSibling());
340 ASSERT_EQ(layers[3], layers[1]->GetNextSibling());
341 ASSERT_EQ(nullptr, layers[3]->GetNextSibling());
342
343 parent->RepositionChild(layers[3], nullptr);
344 ValidateTreePointers(layers);
345
346 // 0
347 // 3 2 1
348 ASSERT_EQ(layers[2], layers[3]->GetNextSibling());
349 ASSERT_EQ(layers[1], layers[2]->GetNextSibling());
350 ASSERT_EQ(nullptr, layers[1]->GetNextSibling());
351 }
352
353 class LayerMetricsWrapperTester : public ::testing::Test {
354 protected:
SetUp()355 virtual void SetUp() {
356 // This ensures ScrollMetadata::sNullMetadata is initialized.
357 gfxPlatform::GetPlatform();
358 }
359 };
360
TEST_F(LayerMetricsWrapperTester,SimpleTree)361 TEST_F(LayerMetricsWrapperTester, SimpleTree) {
362 nsTArray<RefPtr<Layer> > layers;
363 RefPtr<LayerManager> lm;
364 RefPtr<Layer> root =
365 CreateLayerTree("c(c(c(tt)c(t)))", nullptr, nullptr, lm, layers);
366 LayerMetricsWrapper wrapper(root);
367
368 ASSERT_EQ(root.get(), wrapper.GetLayer());
369 wrapper = wrapper.GetFirstChild();
370 ASSERT_EQ(layers[1].get(), wrapper.GetLayer());
371 ASSERT_FALSE(wrapper.GetNextSibling().IsValid());
372 wrapper = wrapper.GetFirstChild();
373 ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
374 wrapper = wrapper.GetFirstChild();
375 ASSERT_EQ(layers[3].get(), wrapper.GetLayer());
376 ASSERT_FALSE(wrapper.GetFirstChild().IsValid());
377 wrapper = wrapper.GetNextSibling();
378 ASSERT_EQ(layers[4].get(), wrapper.GetLayer());
379 ASSERT_FALSE(wrapper.GetNextSibling().IsValid());
380 wrapper = wrapper.GetParent();
381 ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
382 wrapper = wrapper.GetNextSibling();
383 ASSERT_EQ(layers[5].get(), wrapper.GetLayer());
384 ASSERT_FALSE(wrapper.GetNextSibling().IsValid());
385 wrapper = wrapper.GetLastChild();
386 ASSERT_EQ(layers[6].get(), wrapper.GetLayer());
387 wrapper = wrapper.GetParent();
388 ASSERT_EQ(layers[5].get(), wrapper.GetLayer());
389 LayerMetricsWrapper layer5 = wrapper;
390 wrapper = wrapper.GetPrevSibling();
391 ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
392 wrapper = wrapper.GetParent();
393 ASSERT_EQ(layers[1].get(), wrapper.GetLayer());
394 ASSERT_TRUE(layer5 == wrapper.GetLastChild());
395 LayerMetricsWrapper rootWrapper(root);
396 ASSERT_TRUE(rootWrapper == wrapper.GetParent());
397 }
398
MakeMetadata(ScrollableLayerGuid::ViewID aId)399 static ScrollMetadata MakeMetadata(ScrollableLayerGuid::ViewID aId) {
400 ScrollMetadata metadata;
401 metadata.GetMetrics().SetScrollId(aId);
402 return metadata;
403 }
404
TEST_F(LayerMetricsWrapperTester,MultiFramemetricsTree)405 TEST_F(LayerMetricsWrapperTester, MultiFramemetricsTree) {
406 nsTArray<RefPtr<Layer> > layers;
407 RefPtr<LayerManager> lm;
408 RefPtr<Layer> root =
409 CreateLayerTree("c(c(c(tt)c(t)))", nullptr, nullptr, lm, layers);
410
411 nsTArray<ScrollMetadata> metadata;
412 metadata.InsertElementAt(0,
413 MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID +
414 0)); // topmost of root layer
415 metadata.InsertElementAt(0,
416 MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));
417 metadata.InsertElementAt(
418 0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 1));
419 metadata.InsertElementAt(
420 0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 2));
421 metadata.InsertElementAt(0,
422 MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));
423 metadata.InsertElementAt(
424 0, MakeMetadata(
425 ScrollableLayerGuid::NULL_SCROLL_ID)); // bottom of root layer
426 root->SetScrollMetadata(metadata);
427
428 metadata.Clear();
429 metadata.InsertElementAt(
430 0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 3));
431 layers[1]->SetScrollMetadata(metadata);
432
433 metadata.Clear();
434 metadata.InsertElementAt(0,
435 MakeMetadata(ScrollableLayerGuid::NULL_SCROLL_ID));
436 metadata.InsertElementAt(
437 0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 4));
438 layers[2]->SetScrollMetadata(metadata);
439
440 metadata.Clear();
441 metadata.InsertElementAt(
442 0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 5));
443 layers[4]->SetScrollMetadata(metadata);
444
445 metadata.Clear();
446 metadata.InsertElementAt(
447 0, MakeMetadata(ScrollableLayerGuid::START_SCROLL_ID + 6));
448 layers[5]->SetScrollMetadata(metadata);
449
450 LayerMetricsWrapper wrapper(root, LayerMetricsWrapper::StartAt::TOP);
451 nsTArray<Layer*> expectedLayers;
452 expectedLayers.AppendElement(layers[0].get());
453 expectedLayers.AppendElement(layers[0].get());
454 expectedLayers.AppendElement(layers[0].get());
455 expectedLayers.AppendElement(layers[0].get());
456 expectedLayers.AppendElement(layers[0].get());
457 expectedLayers.AppendElement(layers[0].get());
458 expectedLayers.AppendElement(layers[1].get());
459 expectedLayers.AppendElement(layers[2].get());
460 expectedLayers.AppendElement(layers[2].get());
461 expectedLayers.AppendElement(layers[3].get());
462 nsTArray<ScrollableLayerGuid::ViewID> expectedIds;
463 expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 0);
464 expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
465 expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 1);
466 expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 2);
467 expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
468 expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
469 expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 3);
470 expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
471 expectedIds.AppendElement(ScrollableLayerGuid::START_SCROLL_ID + 4);
472 expectedIds.AppendElement(ScrollableLayerGuid::NULL_SCROLL_ID);
473 for (int i = 0; i < 10; i++) {
474 ASSERT_EQ(expectedLayers[i], wrapper.GetLayer());
475 ASSERT_EQ(expectedIds[i], wrapper.Metrics().GetScrollId());
476 wrapper = wrapper.GetFirstChild();
477 }
478 ASSERT_FALSE(wrapper.IsValid());
479
480 wrapper = LayerMetricsWrapper(root, LayerMetricsWrapper::StartAt::BOTTOM);
481 for (int i = 5; i < 10; i++) {
482 ASSERT_EQ(expectedLayers[i], wrapper.GetLayer());
483 ASSERT_EQ(expectedIds[i], wrapper.Metrics().GetScrollId());
484 wrapper = wrapper.GetFirstChild();
485 }
486 ASSERT_FALSE(wrapper.IsValid());
487
488 wrapper =
489 LayerMetricsWrapper(layers[4], LayerMetricsWrapper::StartAt::BOTTOM);
490 ASSERT_EQ(ScrollableLayerGuid::START_SCROLL_ID + 5,
491 wrapper.Metrics().GetScrollId());
492 wrapper = wrapper.GetParent();
493 ASSERT_EQ(ScrollableLayerGuid::START_SCROLL_ID + 4,
494 wrapper.Metrics().GetScrollId());
495 ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
496 ASSERT_FALSE(wrapper.GetNextSibling().IsValid());
497 wrapper = wrapper.GetParent();
498 ASSERT_EQ(ScrollableLayerGuid::NULL_SCROLL_ID,
499 wrapper.Metrics().GetScrollId());
500 ASSERT_EQ(layers[2].get(), wrapper.GetLayer());
501 wrapper = wrapper.GetNextSibling();
502 ASSERT_EQ(ScrollableLayerGuid::START_SCROLL_ID + 6,
503 wrapper.Metrics().GetScrollId());
504 ASSERT_EQ(layers[5].get(), wrapper.GetLayer());
505 }
506