| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/LayoutTestHelper.h" | 5 #include "core/layout/LayoutTestHelper.h" |
| 6 #include "core/layout/LayoutView.h" | 6 #include "core/layout/LayoutView.h" |
| 7 #include "core/layout/PaintInvalidationState.h" | 7 #include "core/layout/PaintInvalidationState.h" |
| 8 #include "core/paint/PaintLayer.h" |
| 8 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 9 | 10 |
| 10 namespace blink { | 11 namespace blink { |
| 11 | 12 |
| 12 class VisualRectMappingTest : public RenderingTest { | 13 class VisualRectMappingTest : public RenderingTest { |
| 13 public: | 14 public: |
| 14 VisualRectMappingTest() | 15 VisualRectMappingTest() |
| 15 : RenderingTest(SingleChildFrameLoaderClient::create()) {} | 16 : RenderingTest(SingleChildFrameLoaderClient::create()) {} |
| 16 protected: | 17 protected: |
| 17 LayoutView& layoutView() const { return *document().layoutView(); } | 18 LayoutView& layoutView() const { return *document().layoutView(); } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 28 if (layoutView != object) | 29 if (layoutView != object) |
| 29 paintInvalidationStates[0]->updateForChildren(); | 30 paintInvalidationStates[0]->updateForChildren(); |
| 30 for (size_t i = 1; i < paintInvalidationStates.size(); ++i) { | 31 for (size_t i = 1; i < paintInvalidationStates.size(); ++i) { |
| 31 paintInvalidationStates[i].emplace(*paintInvalidationStates[i - 1],
*ancestors[ancestors.size() - i]); | 32 paintInvalidationStates[i].emplace(*paintInvalidationStates[i - 1],
*ancestors[ancestors.size() - i]); |
| 32 if (paintInvalidationStates[i]->m_currentObject != object) | 33 if (paintInvalidationStates[i]->m_currentObject != object) |
| 33 paintInvalidationStates[i]->updateForChildren(); | 34 paintInvalidationStates[i]->updateForChildren(); |
| 34 } | 35 } |
| 35 | 36 |
| 36 const PaintInvalidationState& paintInvalidationState = *paintInvalidatio
nStates.last(); | 37 const PaintInvalidationState& paintInvalidationState = *paintInvalidatio
nStates.last(); |
| 37 ASSERT_EQ(paintInvalidationState.m_currentObject, object); | 38 ASSERT_EQ(paintInvalidationState.m_currentObject, object); |
| 38 ASSERT_EQ(paintInvalidationState.paintInvalidationContainer(), paintInva
lidationContainer); | 39 ASSERT_EQ(&paintInvalidationState.paintInvalidationContainer(), &paintIn
validationContainer); |
| 39 | 40 |
| 40 LayoutRect r = rect; | 41 LayoutRect r = rect; |
| 41 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(r); | 42 paintInvalidationState.mapLocalRectToPaintInvalidationContainer(r); |
| 42 EXPECT_EQ(expectedRect, r); | 43 EXPECT_EQ(expectedRect, r); |
| 43 } | 44 } |
| 44 }; | 45 }; |
| 45 | 46 |
| 46 TEST_F(VisualRectMappingTest, LayoutText) | 47 TEST_F(VisualRectMappingTest, LayoutText) |
| 47 { | 48 { |
| 48 setBodyInnerHTML( | 49 setBodyInnerHTML( |
| 49 "<style>body { margin: 0; }</style>" | 50 "<style>body { margin: 0; }</style>" |
| 50 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'
>" | 51 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'
>" |
| 51 " <span><img style='width: 20px; height: 100px'></span>" | 52 " <span><img style='width: 20px; height: 100px'></span>" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 "<div id='container' style='position: absolute; top: 111px; left: 222px;
" | 228 "<div id='container' style='position: absolute; top: 111px; left: 222px;
" |
| 228 " border: 10px solid red; overflow: hidden; width: 50px; height: 80px
;'>" | 229 " border: 10px solid red; overflow: hidden; width: 50px; height: 80px
;'>" |
| 229 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" | 230 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;
height: 90px'></div>" |
| 230 "</div>"); | 231 "</div>"); |
| 231 | 232 |
| 232 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 233 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 233 EXPECT_EQ(LayoutUnit(0), container->scrollTop()); | 234 EXPECT_EQ(LayoutUnit(0), container->scrollTop()); |
| 234 EXPECT_EQ(LayoutUnit(0), container->scrollLeft()); | 235 EXPECT_EQ(LayoutUnit(0), container->scrollLeft()); |
| 235 container->setScrollTop(LayoutUnit(7)); | 236 container->setScrollTop(LayoutUnit(7)); |
| 236 container->setScrollLeft(LayoutUnit(8)); | 237 container->setScrollLeft(LayoutUnit(8)); |
| 238 document().view()->updateAllLifecyclePhases(); |
| 237 | 239 |
| 238 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 240 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 239 LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidatio
n(); | 241 LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidatio
n(); |
| 240 // 140 = width(100) + box_shadow_offset_x(40) | 242 // 140 = width(100) + box_shadow_offset_x(40) |
| 241 // 110 = height(90) + box_shadow_offset_y(20) | 243 // 110 = height(90) + box_shadow_offset_y(20) |
| 242 EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetOverflowRect); | 244 EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetOverflowRect); |
| 243 LayoutRect rect = targetOverflowRect; | 245 LayoutRect rect = targetOverflowRect; |
| 244 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 246 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| 245 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); | 247 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); |
| 246 | 248 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 " <div style='width: 100px; height: 100px'></div>" | 286 " <div style='width: 100px; height: 100px'></div>" |
| 285 "</div>"); | 287 "</div>"); |
| 286 | 288 |
| 287 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); | 289 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 288 EXPECT_EQ(LayoutUnit(0), container->scrollTop()); | 290 EXPECT_EQ(LayoutUnit(0), container->scrollTop()); |
| 289 // The initial scroll offset is to the left-most because of flipped blocks w
riting mode. | 291 // The initial scroll offset is to the left-most because of flipped blocks w
riting mode. |
| 290 // 150 = total_layout_overflow(100 + 100) - width(50) | 292 // 150 = total_layout_overflow(100 + 100) - width(50) |
| 291 EXPECT_EQ(LayoutUnit(150), container->scrollLeft()); | 293 EXPECT_EQ(LayoutUnit(150), container->scrollLeft()); |
| 292 container->setScrollTop(LayoutUnit(7)); | 294 container->setScrollTop(LayoutUnit(7)); |
| 293 container->setScrollLeft(LayoutUnit(142)); // Scroll to the right by 8 pixel
s. | 295 container->setScrollLeft(LayoutUnit(142)); // Scroll to the right by 8 pixel
s. |
| 296 document().view()->updateAllLifecyclePhases(); |
| 294 | 297 |
| 295 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 298 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 296 LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidatio
n(); | 299 LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidatio
n(); |
| 297 // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the ori
gin) | 300 // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the ori
gin) |
| 298 // 140 = width(100) + box_shadow_offset_x(40) | 301 // 140 = width(100) + box_shadow_offset_x(40) |
| 299 // 110 = height(90) + box_shadow_offset_y(20) | 302 // 110 = height(90) + box_shadow_offset_y(20) |
| 300 EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect); | 303 EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect); |
| 301 | 304 |
| 302 LayoutRect rect = targetOverflowRect; | 305 LayoutRect rect = targetOverflowRect; |
| 303 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 306 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 331 EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect); | 334 EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect); |
| 332 | 335 |
| 333 rect = containerOverflowRect; | 336 rect = containerOverflowRect; |
| 334 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 337 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 335 // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by e
xtra horizontal | 338 // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by e
xtra horizontal |
| 336 // border-widths because of layout error. | 339 // border-widths because of layout error. |
| 337 EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect); | 340 EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect); |
| 338 checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *contain
er, layoutView(), layoutView()); | 341 checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *contain
er, layoutView(), layoutView()); |
| 339 } | 342 } |
| 340 | 343 |
| 344 TEST_F(VisualRectMappingTest, DifferentPaintInvalidaitionContainerForAbsolutePos
ition) |
| 345 { |
| 346 enableCompositing(); |
| 347 document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true); |
| 348 |
| 349 setBodyInnerHTML( |
| 350 "<div id='stacking-context' style='opacity: 0.9; background: blue; will-
change: transform'>" |
| 351 " <div id='scroller' style='overflow: scroll; width: 80px; height: 80
px'>" |
| 352 " <div id='absolute' style='position: absolute; top: 111px; left:
222px; width: 50px; height: 50px; background: green'></div>" |
| 353 " <div id='normal-flow' style='width: 2000px; height: 2000px; bac
kground: yellow'></div>" |
| 354 " </div>" |
| 355 "</div>"); |
| 356 |
| 357 LayoutBlock* scroller = toLayoutBlock(getLayoutObjectByElementId("scroller")
); |
| 358 scroller->setScrollTop(LayoutUnit(77)); |
| 359 scroller->setScrollLeft(LayoutUnit(88)); |
| 360 document().view()->updateAllLifecyclePhases(); |
| 361 |
| 362 LayoutBlock* normalFlow = toLayoutBlock(getLayoutObjectByElementId("normal-f
low")); |
| 363 EXPECT_EQ(scroller, &normalFlow->containerForPaintInvalidation()); |
| 364 |
| 365 LayoutRect normalFlowOverflowRect = normalFlow->localOverflowRectForPaintInv
alidation(); |
| 366 EXPECT_EQ(LayoutRect(0, 0, 2000, 2000), normalFlowOverflowRect); |
| 367 LayoutRect rect = normalFlowOverflowRect; |
| 368 EXPECT_TRUE(normalFlow->mapToVisualRectInAncestorSpace(scroller, rect)); |
| 369 EXPECT_EQ(LayoutRect(-88, -77, 2000, 2000), rect); |
| 370 checkPaintInvalidationStateRectMapping(rect, normalFlowOverflowRect, *normal
Flow, layoutView(), *scroller); |
| 371 |
| 372 LayoutBlock* stackingContext = toLayoutBlock(getLayoutObjectByElementId("sta
cking-context")); |
| 373 LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute")
); |
| 374 EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation()); |
| 375 EXPECT_EQ(stackingContext, absolute->container()); |
| 376 |
| 377 LayoutRect absoluteOverflowRect = absolute->localOverflowRectForPaintInvalid
ation(); |
| 378 EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteOverflowRect); |
| 379 rect = absoluteOverflowRect; |
| 380 EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect))
; |
| 381 EXPECT_EQ(LayoutRect(222, 111, 50, 50), rect); |
| 382 checkPaintInvalidationStateRectMapping(rect, absoluteOverflowRect, *absolute
, layoutView(), *stackingContext); |
| 383 } |
| 384 |
| 385 TEST_F(VisualRectMappingTest, ContainerOfAbsoluteAbovePaintInvalidationContainer
) |
| 386 { |
| 387 enableCompositing(); |
| 388 document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true); |
| 389 |
| 390 setBodyInnerHTML( |
| 391 "<div id='container' style='position: absolute; top: 88px; left: 99px'>" |
| 392 " <div style='height: 222px'></div>" |
| 393 // This div makes stacking-context composited. |
| 394 " <div style='position: absolute; width: 1px; height: 1px; background
:yellow; will-change: transform'></div>" |
| 395 // This stacking context is paintInvalidationContainer of the absolute c
hild, but not a container of it. |
| 396 " <div id='stacking-context' style='opacity: 0.9'>" |
| 397 " <div id='absolute' style='position: absolute; top: 50px; left:
50px; width: 50px; height: 50px; background: green'></div>" |
| 398 " </div>" |
| 399 "</div>"); |
| 400 |
| 401 LayoutBlock* stackingContext = toLayoutBlock(getLayoutObjectByElementId("sta
cking-context")); |
| 402 LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute")
); |
| 403 LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container
")); |
| 404 EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation()); |
| 405 EXPECT_EQ(container, absolute->container()); |
| 406 |
| 407 LayoutRect absoluteOverflowRect = absolute->localOverflowRectForPaintInvalid
ation(); |
| 408 EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteOverflowRect); |
| 409 LayoutRect rect = absoluteOverflowRect; |
| 410 EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect))
; |
| 411 // -172 = top(50) - y_offset_of_stacking_context(222) |
| 412 EXPECT_EQ(LayoutRect(50, -172, 50, 50), rect); |
| 413 checkPaintInvalidationStateRectMapping(rect, absoluteOverflowRect, *absolute
, layoutView(), *stackingContext); |
| 414 } |
| 415 |
| 341 } // namespace blink | 416 } // namespace blink |
| OLD | NEW |