Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2010 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "web/painting/PaintAggregator.h"
     33 
     34 #include <gtest/gtest.h>
     35 
     36 using namespace blink;
     37 
     38 namespace {
     39 
     40 TEST(PaintAggregator, InitialState)
     41 {
     42     PaintAggregator greg;
     43     EXPECT_FALSE(greg.hasPendingUpdate());
     44 }
     45 
     46 TEST(PaintAggregator, SingleInvalidation)
     47 {
     48     PaintAggregator greg;
     49 
     50     IntRect rect(2, 4, 10, 16);
     51     greg.invalidateRect(rect);
     52 
     53     EXPECT_TRUE(greg.hasPendingUpdate());
     54     PaintAggregator::PendingUpdate update;
     55     greg.popPendingUpdate(&update);
     56 
     57     EXPECT_TRUE(update.scrollRect.isEmpty());
     58     ASSERT_EQ(1U, update.paintRects.size());
     59 
     60     EXPECT_EQ(rect, update.paintRects[0]);
     61 }
     62 
     63 TEST(PaintAggregator, DoubleDisjointInvalidation)
     64 {
     65     PaintAggregator greg;
     66 
     67     IntRect r1(2, 4, 2, 40);
     68     IntRect r2(4, 2, 40, 2);
     69 
     70     greg.invalidateRect(r1);
     71     greg.invalidateRect(r2);
     72 
     73     IntRect expectedBounds = unionRect(r1, r2);
     74 
     75     EXPECT_TRUE(greg.hasPendingUpdate());
     76     PaintAggregator::PendingUpdate update;
     77     greg.popPendingUpdate(&update);
     78 
     79     EXPECT_TRUE(update.scrollRect.isEmpty());
     80     EXPECT_EQ(2U, update.paintRects.size());
     81 
     82     EXPECT_EQ(expectedBounds, update.calculatePaintBounds());
     83 }
     84 
     85 TEST(PaintAggregator, DisjointInvalidationsCombined)
     86 {
     87     PaintAggregator greg;
     88 
     89     // Make the rectangles such that they don't overlap but cover a very large
     90     // percentage of the area of covered by their union. This is so we're not
     91     // very sensitive to the combining heuristic in the paint aggregator.
     92     IntRect r1(2, 4, 2, 1000);
     93     IntRect r2(5, 2, 2, 1000);
     94 
     95     greg.invalidateRect(r1);
     96     greg.invalidateRect(r2);
     97 
     98     IntRect expectedBounds = unionRect(r1, r2);
     99 
    100     EXPECT_TRUE(greg.hasPendingUpdate());
    101     PaintAggregator::PendingUpdate update;
    102     greg.popPendingUpdate(&update);
    103 
    104     EXPECT_TRUE(update.scrollRect.isEmpty());
    105     ASSERT_EQ(1U, update.paintRects.size());
    106 
    107     EXPECT_EQ(expectedBounds, update.paintRects[0]);
    108 }
    109 
    110 TEST(PaintAggregator, SingleScroll)
    111 {
    112     PaintAggregator greg;
    113 
    114     IntRect rect(1, 2, 3, 4);
    115     IntPoint delta(1, 0);
    116     greg.scrollRect(delta.x(), delta.y(), rect);
    117 
    118     EXPECT_TRUE(greg.hasPendingUpdate());
    119     PaintAggregator::PendingUpdate update;
    120     greg.popPendingUpdate(&update);
    121 
    122     EXPECT_TRUE(update.paintRects.isEmpty());
    123     EXPECT_FALSE(update.scrollRect.isEmpty());
    124 
    125     EXPECT_EQ(rect, update.scrollRect);
    126 
    127     EXPECT_EQ(delta.x(), update.scrollDelta.x());
    128     EXPECT_EQ(delta.y(), update.scrollDelta.y());
    129 
    130     IntRect resultingDamage = update.calculateScrollDamage();
    131     IntRect expectedDamage(1, 2, 1, 4);
    132     EXPECT_EQ(expectedDamage, resultingDamage);
    133 }
    134 
    135 TEST(PaintAggregator, DoubleOverlappingScroll)
    136 {
    137     PaintAggregator greg;
    138 
    139     IntRect rect(1, 2, 3, 4);
    140     IntPoint delta1(1, 0);
    141     IntPoint delta2(1, 0);
    142     greg.scrollRect(delta1.x(), delta1.y(), rect);
    143     greg.scrollRect(delta2.x(), delta2.y(), rect);
    144 
    145     EXPECT_TRUE(greg.hasPendingUpdate());
    146     PaintAggregator::PendingUpdate update;
    147     greg.popPendingUpdate(&update);
    148 
    149     EXPECT_TRUE(update.paintRects.isEmpty());
    150     EXPECT_FALSE(update.scrollRect.isEmpty());
    151 
    152     EXPECT_EQ(rect, update.scrollRect);
    153 
    154     IntPoint expectedDelta(delta1.x() + delta2.x(),
    155                            delta1.y() + delta2.y());
    156     EXPECT_EQ(expectedDelta.x(), update.scrollDelta.x());
    157     EXPECT_EQ(expectedDelta.y(), update.scrollDelta.y());
    158 
    159     IntRect resultingDamage = update.calculateScrollDamage();
    160     IntRect expectedDamage(1, 2, 2, 4);
    161     EXPECT_EQ(expectedDamage, resultingDamage);
    162 }
    163 
    164 TEST(PaintAggregator, NegatingScroll)
    165 {
    166     PaintAggregator greg;
    167 
    168     // Scroll twice in opposite directions by equal amounts. The result
    169     // should be no scrolling.
    170 
    171     IntRect rect(1, 2, 3, 4);
    172     IntPoint delta1(1, 0);
    173     IntPoint delta2(-1, 0);
    174     greg.scrollRect(delta1.x(), delta1.y(), rect);
    175     greg.scrollRect(delta2.x(), delta2.y(), rect);
    176 
    177     EXPECT_FALSE(greg.hasPendingUpdate());
    178 }
    179 
    180 TEST(PaintAggregator, DiagonalScroll)
    181 {
    182     PaintAggregator greg;
    183 
    184     // We don't support optimized diagonal scrolling, so this should result in
    185     // repainting.
    186 
    187     IntRect rect(1, 2, 3, 4);
    188     IntPoint delta(1, 1);
    189     greg.scrollRect(delta.x(), delta.y(), rect);
    190 
    191     EXPECT_TRUE(greg.hasPendingUpdate());
    192     PaintAggregator::PendingUpdate update;
    193     greg.popPendingUpdate(&update);
    194 
    195     EXPECT_TRUE(update.scrollRect.isEmpty());
    196     ASSERT_EQ(1U, update.paintRects.size());
    197 
    198     EXPECT_EQ(rect, update.paintRects[0]);
    199 }
    200 
    201 TEST(PaintAggregator, ContainedPaintAfterScroll)
    202 {
    203     PaintAggregator greg;
    204 
    205     IntRect scrollRect(0, 0, 10, 10);
    206     greg.scrollRect(2, 0, scrollRect);
    207 
    208     IntRect paintRect(4, 4, 2, 2);
    209     greg.invalidateRect(paintRect);
    210 
    211     EXPECT_TRUE(greg.hasPendingUpdate());
    212     PaintAggregator::PendingUpdate update;
    213     greg.popPendingUpdate(&update);
    214 
    215     // expecting a paint rect inside the scroll rect
    216     EXPECT_FALSE(update.scrollRect.isEmpty());
    217     EXPECT_EQ(1U, update.paintRects.size());
    218 
    219     EXPECT_EQ(scrollRect, update.scrollRect);
    220     EXPECT_EQ(paintRect, update.paintRects[0]);
    221 }
    222 
    223 TEST(PaintAggregator, ContainedPaintBeforeScroll)
    224 {
    225     PaintAggregator greg;
    226 
    227     IntRect paintRect(4, 4, 2, 2);
    228     greg.invalidateRect(paintRect);
    229 
    230     IntRect scrollRect(0, 0, 10, 10);
    231     greg.scrollRect(2, 0, scrollRect);
    232 
    233     EXPECT_TRUE(greg.hasPendingUpdate());
    234     PaintAggregator::PendingUpdate update;
    235     greg.popPendingUpdate(&update);
    236 
    237     // Expecting a paint rect inside the scroll rect
    238     EXPECT_FALSE(update.scrollRect.isEmpty());
    239     EXPECT_EQ(1U, update.paintRects.size());
    240 
    241     paintRect.move(2, 0);
    242 
    243     EXPECT_EQ(scrollRect, update.scrollRect);
    244     EXPECT_EQ(paintRect, update.paintRects[0]);
    245 }
    246 
    247 TEST(PaintAggregator, ContainedPaintsBeforeAndAfterScroll)
    248 {
    249     PaintAggregator greg;
    250 
    251     IntRect paintRect1(4, 4, 2, 2);
    252     greg.invalidateRect(paintRect1);
    253 
    254     IntRect scrollRect(0, 0, 10, 10);
    255     greg.scrollRect(2, 0, scrollRect);
    256 
    257     IntRect paintRect2(6, 4, 2, 2);
    258     greg.invalidateRect(paintRect2);
    259 
    260     IntRect expectedPaintRect = paintRect2;
    261 
    262     EXPECT_TRUE(greg.hasPendingUpdate());
    263     PaintAggregator::PendingUpdate update;
    264     greg.popPendingUpdate(&update);
    265 
    266     // Expecting a paint rect inside the scroll rect
    267     EXPECT_FALSE(update.scrollRect.isEmpty());
    268     EXPECT_EQ(1U, update.paintRects.size());
    269 
    270     EXPECT_EQ(scrollRect, update.scrollRect);
    271     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
    272 }
    273 
    274 TEST(PaintAggregator, LargeContainedPaintAfterScroll)
    275 {
    276     PaintAggregator greg;
    277 
    278     IntRect scrollRect(0, 0, 10, 10);
    279     greg.scrollRect(0, 1, scrollRect);
    280 
    281     IntRect paintRect(0, 0, 10, 9); // Repaint 90%
    282     greg.invalidateRect(paintRect);
    283 
    284     EXPECT_TRUE(greg.hasPendingUpdate());
    285     PaintAggregator::PendingUpdate update;
    286     greg.popPendingUpdate(&update);
    287 
    288     EXPECT_TRUE(update.scrollRect.isEmpty());
    289     EXPECT_EQ(1U, update.paintRects.size());
    290 
    291     EXPECT_EQ(scrollRect, update.paintRects[0]);
    292 }
    293 
    294 TEST(PaintAggregator, LargeContainedPaintBeforeScroll)
    295 {
    296     PaintAggregator greg;
    297 
    298     IntRect paintRect(0, 0, 10, 9); // Repaint 90%
    299     greg.invalidateRect(paintRect);
    300 
    301     IntRect scrollRect(0, 0, 10, 10);
    302     greg.scrollRect(0, 1, scrollRect);
    303 
    304     EXPECT_TRUE(greg.hasPendingUpdate());
    305     PaintAggregator::PendingUpdate update;
    306     greg.popPendingUpdate(&update);
    307 
    308     EXPECT_TRUE(update.scrollRect.isEmpty());
    309     EXPECT_EQ(1U, update.paintRects.size());
    310 
    311     EXPECT_EQ(scrollRect, update.paintRects[0]);
    312 }
    313 
    314 TEST(PaintAggregator, OverlappingPaintBeforeScroll)
    315 {
    316     PaintAggregator greg;
    317 
    318     IntRect paintRect(4, 4, 10, 2);
    319     greg.invalidateRect(paintRect);
    320 
    321     IntRect scrollRect(0, 0, 10, 10);
    322     greg.scrollRect(2, 0, scrollRect);
    323 
    324     IntRect expectedPaintRect = unionRect(scrollRect, paintRect);
    325 
    326     EXPECT_TRUE(greg.hasPendingUpdate());
    327     PaintAggregator::PendingUpdate update;
    328     greg.popPendingUpdate(&update);
    329 
    330     EXPECT_TRUE(update.scrollRect.isEmpty());
    331     EXPECT_EQ(1U, update.paintRects.size());
    332 
    333     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
    334 }
    335 
    336 TEST(PaintAggregator, OverlappingPaintAfterScroll)
    337 {
    338     PaintAggregator greg;
    339 
    340     IntRect scrollRect(0, 0, 10, 10);
    341     greg.scrollRect(2, 0, scrollRect);
    342 
    343     IntRect paintRect(4, 4, 10, 2);
    344     greg.invalidateRect(paintRect);
    345 
    346     IntRect expectedPaintRect = unionRect(scrollRect, paintRect);
    347 
    348     EXPECT_TRUE(greg.hasPendingUpdate());
    349     PaintAggregator::PendingUpdate update;
    350     greg.popPendingUpdate(&update);
    351 
    352     EXPECT_TRUE(update.scrollRect.isEmpty());
    353     EXPECT_EQ(1U, update.paintRects.size());
    354 
    355     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
    356 }
    357 
    358 TEST(PaintAggregator, DisjointPaintBeforeScroll)
    359 {
    360     PaintAggregator greg;
    361 
    362     IntRect paintRect(4, 4, 10, 2);
    363     greg.invalidateRect(paintRect);
    364 
    365     IntRect scrollRect(0, 0, 2, 10);
    366     greg.scrollRect(2, 0, scrollRect);
    367 
    368     EXPECT_TRUE(greg.hasPendingUpdate());
    369     PaintAggregator::PendingUpdate update;
    370     greg.popPendingUpdate(&update);
    371 
    372     EXPECT_FALSE(update.scrollRect.isEmpty());
    373     EXPECT_EQ(1U, update.paintRects.size());
    374 
    375     EXPECT_EQ(paintRect, update.paintRects[0]);
    376     EXPECT_EQ(scrollRect, update.scrollRect);
    377 }
    378 
    379 TEST(PaintAggregator, DisjointPaintAfterScroll)
    380 {
    381     PaintAggregator greg;
    382 
    383     IntRect scrollRect(0, 0, 2, 10);
    384     greg.scrollRect(2, 0, scrollRect);
    385 
    386     IntRect paintRect(4, 4, 10, 2);
    387     greg.invalidateRect(paintRect);
    388 
    389     EXPECT_TRUE(greg.hasPendingUpdate());
    390     PaintAggregator::PendingUpdate update;
    391     greg.popPendingUpdate(&update);
    392 
    393     EXPECT_FALSE(update.scrollRect.isEmpty());
    394     EXPECT_EQ(1U, update.paintRects.size());
    395 
    396     EXPECT_EQ(paintRect, update.paintRects[0]);
    397     EXPECT_EQ(scrollRect, update.scrollRect);
    398 }
    399 
    400 TEST(PaintAggregator, ContainedPaintTrimmedByScroll)
    401 {
    402     PaintAggregator greg;
    403 
    404     IntRect paintRect(4, 4, 6, 6);
    405     greg.invalidateRect(paintRect);
    406 
    407     IntRect scrollRect(0, 0, 10, 10);
    408     greg.scrollRect(2, 0, scrollRect);
    409 
    410     // The paint rect should have become narrower.
    411     IntRect expectedPaintRect(6, 4, 4, 6);
    412 
    413     EXPECT_TRUE(greg.hasPendingUpdate());
    414     PaintAggregator::PendingUpdate update;
    415     greg.popPendingUpdate(&update);
    416 
    417     EXPECT_FALSE(update.scrollRect.isEmpty());
    418     EXPECT_EQ(1U, update.paintRects.size());
    419 
    420     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
    421     EXPECT_EQ(scrollRect, update.scrollRect);
    422 }
    423 
    424 TEST(PaintAggregator, ContainedPaintEliminatedByScroll)
    425 {
    426     PaintAggregator greg;
    427 
    428     IntRect paintRect(4, 4, 6, 6);
    429     greg.invalidateRect(paintRect);
    430 
    431     IntRect scrollRect(0, 0, 10, 10);
    432     greg.scrollRect(6, 0, scrollRect);
    433 
    434     EXPECT_TRUE(greg.hasPendingUpdate());
    435     PaintAggregator::PendingUpdate update;
    436     greg.popPendingUpdate(&update);
    437 
    438     EXPECT_FALSE(update.scrollRect.isEmpty());
    439     EXPECT_TRUE(update.paintRects.isEmpty());
    440 
    441     EXPECT_EQ(scrollRect, update.scrollRect);
    442 }
    443 
    444 TEST(PaintAggregator, ContainedPaintAfterScrollTrimmedByScrollDamage)
    445 {
    446     PaintAggregator greg;
    447 
    448     IntRect scrollRect(0, 0, 10, 10);
    449     greg.scrollRect(4, 0, scrollRect);
    450 
    451     IntRect paintRect(2, 0, 4, 10);
    452     greg.invalidateRect(paintRect);
    453 
    454     IntRect expectedScrollDamage(0, 0, 4, 10);
    455     IntRect expectedPaintRect(4, 0, 2, 10);
    456 
    457     EXPECT_TRUE(greg.hasPendingUpdate());
    458     PaintAggregator::PendingUpdate update;
    459     greg.popPendingUpdate(&update);
    460 
    461     EXPECT_FALSE(update.scrollRect.isEmpty());
    462     EXPECT_EQ(1U, update.paintRects.size());
    463 
    464     EXPECT_EQ(scrollRect, update.scrollRect);
    465     EXPECT_EQ(expectedScrollDamage, update.calculateScrollDamage());
    466     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
    467 }
    468 
    469 TEST(PaintAggregator, ContainedPaintAfterScrollEliminatedByScrollDamage)
    470 {
    471     PaintAggregator greg;
    472 
    473     IntRect scrollRect(0, 0, 10, 10);
    474     greg.scrollRect(4, 0, scrollRect);
    475 
    476     IntRect paintRect(2, 0, 2, 10);
    477     greg.invalidateRect(paintRect);
    478 
    479     IntRect expectedScrollDamage(0, 0, 4, 10);
    480 
    481     EXPECT_TRUE(greg.hasPendingUpdate());
    482     PaintAggregator::PendingUpdate update;
    483     greg.popPendingUpdate(&update);
    484 
    485     EXPECT_FALSE(update.scrollRect.isEmpty());
    486     EXPECT_TRUE(update.paintRects.isEmpty());
    487 
    488     EXPECT_EQ(scrollRect, update.scrollRect);
    489     EXPECT_EQ(expectedScrollDamage, update.calculateScrollDamage());
    490 }
    491 
    492 } // namespace
    493