Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / tests / ScrollingCoordinatorChromiumTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "core/page/scrolling/ScrollingCoordinator.h"
28
29 #include "core/page/Page.h"
30 #include "core/rendering/RenderPart.h"
31 #include "core/rendering/RenderView.h"
32 #include "core/rendering/compositing/CompositedLayerMapping.h"
33 #include "core/rendering/compositing/RenderLayerCompositor.h"
34 #include "core/testing/URLTestHelpers.h"
35 #include "platform/graphics/GraphicsLayer.h"
36 #include "public/platform/Platform.h"
37 #include "public/platform/WebLayer.h"
38 #include "public/platform/WebLayerPositionConstraint.h"
39 #include "public/platform/WebLayerTreeView.h"
40 #include "public/platform/WebUnitTestSupport.h"
41 #include "public/web/WebSettings.h"
42 #include "public/web/WebViewClient.h"
43 #include "web/WebLocalFrameImpl.h"
44 #include "web/WebViewImpl.h"
45 #include "web/tests/FrameTestHelpers.h"
46 #include <gtest/gtest.h>
47
48 using namespace blink;
49
50 namespace {
51
52 class ScrollingCoordinatorChromiumTest : public testing::Test {
53 public:
54     ScrollingCoordinatorChromiumTest()
55         : m_baseURL("http://www.test.com/")
56     {
57         m_helper.initialize(true, 0, &m_mockWebViewClient, &configureSettings);
58         webViewImpl()->resize(IntSize(320, 240));
59     }
60
61     virtual ~ScrollingCoordinatorChromiumTest()
62     {
63         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
64     }
65
66     void navigateTo(const std::string& url)
67     {
68         FrameTestHelpers::loadFrame(webViewImpl()->mainFrame(), url);
69     }
70
71     void forceFullCompositingUpdate()
72     {
73         webViewImpl()->layout();
74     }
75
76     void registerMockedHttpURLLoad(const std::string& fileName)
77     {
78         URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
79     }
80
81     WebLayer* getRootScrollLayer()
82     {
83         RenderLayerCompositor* compositor = frame()->contentRenderer()->compositor();
84         ASSERT(compositor);
85         ASSERT(compositor->scrollLayer());
86
87         WebLayer* webScrollLayer = compositor->scrollLayer()->platformLayer();
88         return webScrollLayer;
89     }
90
91     WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); }
92     LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->frame(); }
93
94 protected:
95     std::string m_baseURL;
96     FrameTestHelpers::TestWebViewClient m_mockWebViewClient;
97
98 private:
99     static void configureSettings(WebSettings* settings)
100     {
101         settings->setJavaScriptEnabled(true);
102         settings->setAcceleratedCompositingEnabled(true);
103         settings->setPreferCompositingToLCDTextEnabled(true);
104     }
105
106     FrameTestHelpers::WebViewHelper m_helper;
107 };
108
109 class GraphicsLayerForScrollTesting : public GraphicsLayer {
110 public:
111     virtual WebLayer* contentsLayer() const { return GraphicsLayer::contentsLayer(); }
112 };
113
114 TEST_F(ScrollingCoordinatorChromiumTest, fastScrollingByDefault)
115 {
116     navigateTo("about:blank");
117     forceFullCompositingUpdate();
118
119     // Make sure the scrolling coordinator is active.
120     FrameView* frameView = frame()->view();
121     Page* page = frame()->page();
122     ASSERT_TRUE(page->scrollingCoordinator());
123     ASSERT_TRUE(page->scrollingCoordinator()->coordinatesScrollingForFrameView(frameView));
124
125     // Fast scrolling should be enabled by default.
126     WebLayer* rootScrollLayer = getRootScrollLayer();
127     ASSERT_TRUE(rootScrollLayer->scrollable());
128     ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread());
129     ASSERT_FALSE(rootScrollLayer->haveWheelEventHandlers());
130 }
131
132 TEST_F(ScrollingCoordinatorChromiumTest, fastScrollingCanBeDisabledWithSetting)
133 {
134     navigateTo("about:blank");
135     webViewImpl()->settings()->setThreadedScrollingEnabled(false);
136     forceFullCompositingUpdate();
137
138     // Make sure the scrolling coordinator is active.
139     FrameView* frameView = frame()->view();
140     Page* page = frame()->page();
141     ASSERT_TRUE(page->scrollingCoordinator());
142     ASSERT_TRUE(page->scrollingCoordinator()->coordinatesScrollingForFrameView(frameView));
143
144     // Main scrolling should be enabled with the setting override.
145     WebLayer* rootScrollLayer = getRootScrollLayer();
146     ASSERT_TRUE(rootScrollLayer->scrollable());
147     ASSERT_TRUE(rootScrollLayer->shouldScrollOnMainThread());
148 }
149
150 static WebLayer* webLayerFromElement(Element* element)
151 {
152     if (!element)
153         return 0;
154     RenderObject* renderer = element->renderer();
155     if (!renderer || !renderer->isBoxModelObject())
156         return 0;
157     RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
158     if (!layer)
159         return 0;
160     if (!layer->hasCompositedLayerMapping())
161         return 0;
162     CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
163     GraphicsLayer* graphicsLayer = compositedLayerMapping->mainGraphicsLayer();
164     if (!graphicsLayer)
165         return 0;
166     return graphicsLayer->platformLayer();
167 }
168
169 TEST_F(ScrollingCoordinatorChromiumTest, fastScrollingForFixedPosition)
170 {
171     registerMockedHttpURLLoad("fixed-position.html");
172     navigateTo(m_baseURL + "fixed-position.html");
173     forceFullCompositingUpdate();
174
175     // Fixed position should not fall back to main thread scrolling.
176     WebLayer* rootScrollLayer = getRootScrollLayer();
177     ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread());
178
179     Document* document = frame()->document();
180     {
181         Element* element = document->getElementById("div-tl");
182         ASSERT_TRUE(element);
183         WebLayer* layer = webLayerFromElement(element);
184         ASSERT_TRUE(layer);
185         WebLayerPositionConstraint constraint = layer->positionConstraint();
186         ASSERT_TRUE(constraint.isFixedPosition);
187         ASSERT_TRUE(!constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
188     }
189     {
190         Element* element = document->getElementById("div-tr");
191         ASSERT_TRUE(element);
192         WebLayer* layer = webLayerFromElement(element);
193         ASSERT_TRUE(layer);
194         WebLayerPositionConstraint constraint = layer->positionConstraint();
195         ASSERT_TRUE(constraint.isFixedPosition);
196         ASSERT_TRUE(constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
197     }
198     {
199         Element* element = document->getElementById("div-bl");
200         ASSERT_TRUE(element);
201         WebLayer* layer = webLayerFromElement(element);
202         ASSERT_TRUE(layer);
203         WebLayerPositionConstraint constraint = layer->positionConstraint();
204         ASSERT_TRUE(constraint.isFixedPosition);
205         ASSERT_TRUE(!constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
206     }
207     {
208         Element* element = document->getElementById("div-br");
209         ASSERT_TRUE(element);
210         WebLayer* layer = webLayerFromElement(element);
211         ASSERT_TRUE(layer);
212         WebLayerPositionConstraint constraint = layer->positionConstraint();
213         ASSERT_TRUE(constraint.isFixedPosition);
214         ASSERT_TRUE(constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
215     }
216     {
217         Element* element = document->getElementById("span-tl");
218         ASSERT_TRUE(element);
219         WebLayer* layer = webLayerFromElement(element);
220         ASSERT_TRUE(layer);
221         WebLayerPositionConstraint constraint = layer->positionConstraint();
222         ASSERT_TRUE(constraint.isFixedPosition);
223         ASSERT_TRUE(!constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
224     }
225     {
226         Element* element = document->getElementById("span-tr");
227         ASSERT_TRUE(element);
228         WebLayer* layer = webLayerFromElement(element);
229         ASSERT_TRUE(layer);
230         WebLayerPositionConstraint constraint = layer->positionConstraint();
231         ASSERT_TRUE(constraint.isFixedPosition);
232         ASSERT_TRUE(constraint.isFixedToRightEdge && !constraint.isFixedToBottomEdge);
233     }
234     {
235         Element* element = document->getElementById("span-bl");
236         ASSERT_TRUE(element);
237         WebLayer* layer = webLayerFromElement(element);
238         ASSERT_TRUE(layer);
239         WebLayerPositionConstraint constraint = layer->positionConstraint();
240         ASSERT_TRUE(constraint.isFixedPosition);
241         ASSERT_TRUE(!constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
242     }
243     {
244         Element* element = document->getElementById("span-br");
245         ASSERT_TRUE(element);
246         WebLayer* layer = webLayerFromElement(element);
247         ASSERT_TRUE(layer);
248         WebLayerPositionConstraint constraint = layer->positionConstraint();
249         ASSERT_TRUE(constraint.isFixedPosition);
250         ASSERT_TRUE(constraint.isFixedToRightEdge && constraint.isFixedToBottomEdge);
251     }
252 }
253
254 TEST_F(ScrollingCoordinatorChromiumTest, wheelEventHandler)
255 {
256     registerMockedHttpURLLoad("wheel-event-handler.html");
257     navigateTo(m_baseURL + "wheel-event-handler.html");
258     forceFullCompositingUpdate();
259
260     WebLayer* rootScrollLayer = getRootScrollLayer();
261     ASSERT_TRUE(rootScrollLayer->haveWheelEventHandlers());
262 }
263
264 TEST_F(ScrollingCoordinatorChromiumTest, scrollEventHandler)
265 {
266     registerMockedHttpURLLoad("scroll-event-handler.html");
267     navigateTo(m_baseURL + "scroll-event-handler.html");
268     forceFullCompositingUpdate();
269
270     WebLayer* rootScrollLayer = getRootScrollLayer();
271     ASSERT_TRUE(rootScrollLayer->haveScrollEventHandlers());
272 }
273
274 TEST_F(ScrollingCoordinatorChromiumTest, updateEventHandlersDuringTeardown)
275 {
276     registerMockedHttpURLLoad("scroll-event-handler-window.html");
277     navigateTo(m_baseURL + "scroll-event-handler-window.html");
278     forceFullCompositingUpdate();
279
280     // Simulate detaching the document from its DOM window. This should not
281     // cause a crash when the WebViewImpl is closed by the test runner.
282     frame()->document()->prepareForDestruction();
283 }
284
285 TEST_F(ScrollingCoordinatorChromiumTest, clippedBodyTest)
286 {
287     registerMockedHttpURLLoad("clipped-body.html");
288     navigateTo(m_baseURL + "clipped-body.html");
289     forceFullCompositingUpdate();
290
291     WebLayer* rootScrollLayer = getRootScrollLayer();
292     ASSERT_EQ(0u, rootScrollLayer->nonFastScrollableRegion().size());
293 }
294
295 TEST_F(ScrollingCoordinatorChromiumTest, overflowScrolling)
296 {
297     registerMockedHttpURLLoad("overflow-scrolling.html");
298     navigateTo(m_baseURL + "overflow-scrolling.html");
299     forceFullCompositingUpdate();
300
301     // Verify the properties of the accelerated scrolling element starting from the RenderObject
302     // all the way to the WebLayer.
303     Element* scrollableElement = frame()->document()->getElementById("scrollable");
304     ASSERT(scrollableElement);
305
306     RenderObject* renderer = scrollableElement->renderer();
307     ASSERT_TRUE(renderer->isBox());
308     ASSERT_TRUE(renderer->hasLayer());
309
310     RenderBox* box = toRenderBox(renderer);
311     ASSERT_TRUE(box->usesCompositedScrolling());
312     ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());
313
314     CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping();
315     ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
316     ASSERT(compositedLayerMapping->scrollingContentsLayer());
317
318     GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
319     ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());
320
321     WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
322     ASSERT_TRUE(webScrollLayer->scrollable());
323     ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
324     ASSERT_TRUE(webScrollLayer->userScrollableVertical());
325
326 #if OS(ANDROID)
327     // Now verify we've attached impl-side scrollbars onto the scrollbar layers
328     ASSERT_TRUE(compositedLayerMapping->layerForHorizontalScrollbar());
329     ASSERT_TRUE(compositedLayerMapping->layerForHorizontalScrollbar()->hasContentsLayer());
330     ASSERT_TRUE(compositedLayerMapping->layerForVerticalScrollbar());
331     ASSERT_TRUE(compositedLayerMapping->layerForVerticalScrollbar()->hasContentsLayer());
332 #endif
333 }
334
335 TEST_F(ScrollingCoordinatorChromiumTest, overflowHidden)
336 {
337     registerMockedHttpURLLoad("overflow-hidden.html");
338     navigateTo(m_baseURL + "overflow-hidden.html");
339     forceFullCompositingUpdate();
340
341     // Verify the properties of the accelerated scrolling element starting from the RenderObject
342     // all the way to the WebLayer.
343     Element* overflowElement = frame()->document()->getElementById("unscrollable-y");
344     ASSERT(overflowElement);
345
346     RenderObject* renderer = overflowElement->renderer();
347     ASSERT_TRUE(renderer->isBox());
348     ASSERT_TRUE(renderer->hasLayer());
349
350     RenderBox* box = toRenderBox(renderer);
351     ASSERT_TRUE(box->usesCompositedScrolling());
352     ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());
353
354     CompositedLayerMapping* compositedLayerMapping = box->layer()->compositedLayerMapping();
355     ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
356     ASSERT(compositedLayerMapping->scrollingContentsLayer());
357
358     GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
359     ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());
360
361     WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
362     ASSERT_TRUE(webScrollLayer->scrollable());
363     ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
364     ASSERT_FALSE(webScrollLayer->userScrollableVertical());
365
366     overflowElement = frame()->document()->getElementById("unscrollable-x");
367     ASSERT(overflowElement);
368
369     renderer = overflowElement->renderer();
370     ASSERT_TRUE(renderer->isBox());
371     ASSERT_TRUE(renderer->hasLayer());
372
373     box = toRenderBox(renderer);
374     ASSERT_TRUE(box->scrollableArea()->usesCompositedScrolling());
375     ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());
376
377     compositedLayerMapping = box->layer()->compositedLayerMapping();
378     ASSERT_TRUE(compositedLayerMapping->hasScrollingLayer());
379     ASSERT(compositedLayerMapping->scrollingContentsLayer());
380
381     graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
382     ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());
383
384     webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
385     ASSERT_TRUE(webScrollLayer->scrollable());
386     ASSERT_FALSE(webScrollLayer->userScrollableHorizontal());
387     ASSERT_TRUE(webScrollLayer->userScrollableVertical());
388 }
389
390 TEST_F(ScrollingCoordinatorChromiumTest, iframeScrolling)
391 {
392     registerMockedHttpURLLoad("iframe-scrolling.html");
393     registerMockedHttpURLLoad("iframe-scrolling-inner.html");
394     navigateTo(m_baseURL + "iframe-scrolling.html");
395     forceFullCompositingUpdate();
396
397     // Verify the properties of the accelerated scrolling element starting from the RenderObject
398     // all the way to the WebLayer.
399     Element* scrollableFrame = frame()->document()->getElementById("scrollable");
400     ASSERT_TRUE(scrollableFrame);
401
402     RenderObject* renderer = scrollableFrame->renderer();
403     ASSERT_TRUE(renderer);
404     ASSERT_TRUE(renderer->isRenderPart());
405
406     RenderPart* renderPart = toRenderPart(renderer);
407     ASSERT_TRUE(renderPart);
408     ASSERT_TRUE(renderPart->widget());
409     ASSERT_TRUE(renderPart->widget()->isFrameView());
410
411     FrameView* innerFrameView = toFrameView(renderPart->widget());
412     RenderView* innerRenderView = innerFrameView->renderView();
413     ASSERT_TRUE(innerRenderView);
414
415     RenderLayerCompositor* innerCompositor = innerRenderView->compositor();
416     ASSERT_TRUE(innerCompositor->inCompositingMode());
417     ASSERT_TRUE(innerCompositor->scrollLayer());
418
419     GraphicsLayer* scrollLayer = innerCompositor->scrollLayer();
420     ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea());
421
422     WebLayer* webScrollLayer = scrollLayer->platformLayer();
423     ASSERT_TRUE(webScrollLayer->scrollable());
424
425 #if OS(ANDROID)
426     // Now verify we've attached impl-side scrollbars onto the scrollbar layers
427     ASSERT_TRUE(innerCompositor->layerForHorizontalScrollbar());
428     ASSERT_TRUE(innerCompositor->layerForHorizontalScrollbar()->hasContentsLayer());
429     ASSERT_TRUE(innerCompositor->layerForVerticalScrollbar());
430     ASSERT_TRUE(innerCompositor->layerForVerticalScrollbar()->hasContentsLayer());
431 #endif
432 }
433
434 TEST_F(ScrollingCoordinatorChromiumTest, rtlIframe)
435 {
436     registerMockedHttpURLLoad("rtl-iframe.html");
437     registerMockedHttpURLLoad("rtl-iframe-inner.html");
438     navigateTo(m_baseURL + "rtl-iframe.html");
439     forceFullCompositingUpdate();
440
441     // Verify the properties of the accelerated scrolling element starting from the RenderObject
442     // all the way to the WebLayer.
443     Element* scrollableFrame = frame()->document()->getElementById("scrollable");
444     ASSERT_TRUE(scrollableFrame);
445
446     RenderObject* renderer = scrollableFrame->renderer();
447     ASSERT_TRUE(renderer);
448     ASSERT_TRUE(renderer->isRenderPart());
449
450     RenderPart* renderPart = toRenderPart(renderer);
451     ASSERT_TRUE(renderPart);
452     ASSERT_TRUE(renderPart->widget());
453     ASSERT_TRUE(renderPart->widget()->isFrameView());
454
455     FrameView* innerFrameView = toFrameView(renderPart->widget());
456     RenderView* innerRenderView = innerFrameView->renderView();
457     ASSERT_TRUE(innerRenderView);
458
459     RenderLayerCompositor* innerCompositor = innerRenderView->compositor();
460     ASSERT_TRUE(innerCompositor->inCompositingMode());
461     ASSERT_TRUE(innerCompositor->scrollLayer());
462
463     GraphicsLayer* scrollLayer = innerCompositor->scrollLayer();
464     ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea());
465
466     WebLayer* webScrollLayer = scrollLayer->platformLayer();
467     ASSERT_TRUE(webScrollLayer->scrollable());
468
469     int expectedScrollPosition = 958 + (innerFrameView->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
470     ASSERT_EQ(expectedScrollPosition, webScrollLayer->scrollPositionDouble().x);
471 }
472
473 TEST_F(ScrollingCoordinatorChromiumTest, setupScrollbarLayerShouldNotCrash)
474 {
475     registerMockedHttpURLLoad("setup_scrollbar_layer_crash.html");
476     navigateTo(m_baseURL + "setup_scrollbar_layer_crash.html");
477     forceFullCompositingUpdate();
478     // This test document setup an iframe with scrollbars, then switch to
479     // an empty document by javascript.
480 }
481
482 #if OS(MACOSX)
483 TEST_F(ScrollingCoordinatorChromiumTest, DISABLED_setupScrollbarLayerShouldSetScrollLayerOpaque)
484 #else
485 TEST_F(ScrollingCoordinatorChromiumTest, setupScrollbarLayerShouldSetScrollLayerOpaque)
486 #endif
487 {
488     registerMockedHttpURLLoad("wide_document.html");
489     navigateTo(m_baseURL + "wide_document.html");
490     forceFullCompositingUpdate();
491
492     FrameView* frameView = frame()->view();
493     ASSERT_TRUE(frameView);
494
495     GraphicsLayerForScrollTesting* scrollbarGraphicsLayer = static_cast<GraphicsLayerForScrollTesting*>(frameView->layerForHorizontalScrollbar());
496     ASSERT_TRUE(scrollbarGraphicsLayer);
497
498     WebLayer* platformLayer = scrollbarGraphicsLayer->platformLayer();
499     ASSERT_TRUE(platformLayer);
500
501     WebLayer* contentsLayer = scrollbarGraphicsLayer->contentsLayer();
502     ASSERT_TRUE(contentsLayer);
503
504     // After scrollableAreaScrollbarLayerDidChange,
505     // if the main frame's scrollbarLayer is opaque,
506     // contentsLayer should be opaque too.
507     ASSERT_EQ(platformLayer->opaque(), contentsLayer->opaque());
508 }
509
510 } // namespace