Home | History | Annotate | Download | only in renderer
      1 // Copyright (c) 2009 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 
      5 #include "content/renderer/paint_aggregator.h"
      6 #include "testing/gtest/include/gtest/gtest.h"
      7 
      8 namespace content {
      9 
     10 TEST(PaintAggregator, InitialState) {
     11   PaintAggregator greg;
     12   EXPECT_FALSE(greg.HasPendingUpdate());
     13 }
     14 
     15 TEST(PaintAggregator, SingleInvalidation) {
     16   PaintAggregator greg;
     17 
     18   gfx::Rect rect(2, 4, 10, 16);
     19   greg.InvalidateRect(rect);
     20 
     21   EXPECT_TRUE(greg.HasPendingUpdate());
     22   PaintAggregator::PendingUpdate update;
     23   greg.PopPendingUpdate(&update);
     24 
     25   EXPECT_TRUE(update.scroll_rect.IsEmpty());
     26   ASSERT_EQ(1U, update.paint_rects.size());
     27 
     28   EXPECT_EQ(rect, update.paint_rects[0]);
     29 }
     30 
     31 TEST(PaintAggregator, DoubleDisjointInvalidation) {
     32   PaintAggregator greg;
     33 
     34   gfx::Rect r1(2, 4, 2, 40);
     35   gfx::Rect r2(4, 2, 40, 2);
     36 
     37   greg.InvalidateRect(r1);
     38   greg.InvalidateRect(r2);
     39 
     40   gfx::Rect expected_bounds = gfx::UnionRects(r1, r2);
     41 
     42   EXPECT_TRUE(greg.HasPendingUpdate());
     43   PaintAggregator::PendingUpdate update;
     44   greg.PopPendingUpdate(&update);
     45 
     46   EXPECT_TRUE(update.scroll_rect.IsEmpty());
     47   EXPECT_EQ(2U, update.paint_rects.size());
     48 
     49   EXPECT_EQ(expected_bounds, update.GetPaintBounds());
     50 }
     51 
     52 TEST(PaintAggregator, DisjointInvalidationsCombined) {
     53   PaintAggregator greg;
     54 
     55   // Make the rectangles such that they don't overlap but cover a very large
     56   // percentage of the area of covered by their union. This is so we're not
     57   // very sensitive to the combining heuristic in the paint aggregator.
     58   gfx::Rect r1(2, 4, 2, 1000);
     59   gfx::Rect r2(5, 2, 2, 1000);
     60 
     61   greg.InvalidateRect(r1);
     62   greg.InvalidateRect(r2);
     63 
     64   gfx::Rect expected_bounds = gfx::UnionRects(r1, r2);
     65 
     66   EXPECT_TRUE(greg.HasPendingUpdate());
     67   PaintAggregator::PendingUpdate update;
     68   greg.PopPendingUpdate(&update);
     69 
     70   EXPECT_TRUE(update.scroll_rect.IsEmpty());
     71   ASSERT_EQ(1U, update.paint_rects.size());
     72 
     73   EXPECT_EQ(expected_bounds, update.paint_rects[0]);
     74 }
     75 
     76 TEST(PaintAggregator, SingleScroll) {
     77   PaintAggregator greg;
     78 
     79   gfx::Rect rect(1, 2, 3, 4);
     80   gfx::Vector2d delta(1, 0);
     81   greg.ScrollRect(delta, rect);
     82 
     83   EXPECT_TRUE(greg.HasPendingUpdate());
     84   PaintAggregator::PendingUpdate update;
     85   greg.PopPendingUpdate(&update);
     86 
     87   EXPECT_TRUE(update.paint_rects.empty());
     88   EXPECT_FALSE(update.scroll_rect.IsEmpty());
     89 
     90   EXPECT_EQ(rect, update.scroll_rect);
     91 
     92   EXPECT_EQ(delta.x(), update.scroll_delta.x());
     93   EXPECT_EQ(delta.y(), update.scroll_delta.y());
     94 
     95   gfx::Rect resulting_damage = update.GetScrollDamage();
     96   gfx::Rect expected_damage(1, 2, 1, 4);
     97   EXPECT_EQ(expected_damage, resulting_damage);
     98 }
     99 
    100 TEST(PaintAggregator, DoubleOverlappingScroll) {
    101   PaintAggregator greg;
    102 
    103   gfx::Rect rect(1, 2, 3, 4);
    104   gfx::Vector2d delta1(1, 0);
    105   gfx::Vector2d delta2(1, 0);
    106   greg.ScrollRect(delta1, rect);
    107   greg.ScrollRect(delta2, rect);
    108 
    109   EXPECT_TRUE(greg.HasPendingUpdate());
    110   PaintAggregator::PendingUpdate update;
    111   greg.PopPendingUpdate(&update);
    112 
    113   EXPECT_TRUE(update.paint_rects.empty());
    114   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    115 
    116   EXPECT_EQ(rect, update.scroll_rect);
    117 
    118   gfx::Vector2d expected_delta = delta1 + delta2;
    119   EXPECT_EQ(expected_delta.ToString(), update.scroll_delta.ToString());
    120 
    121   gfx::Rect resulting_damage = update.GetScrollDamage();
    122   gfx::Rect expected_damage(1, 2, 2, 4);
    123   EXPECT_EQ(expected_damage, resulting_damage);
    124 }
    125 
    126 TEST(PaintAggregator, NegatingScroll) {
    127   PaintAggregator greg;
    128 
    129   // Scroll twice in opposite directions by equal amounts.  The result
    130   // should be no scrolling.
    131 
    132   gfx::Rect rect(1, 2, 3, 4);
    133   gfx::Vector2d delta1(1, 0);
    134   gfx::Vector2d delta2(-1, 0);
    135   greg.ScrollRect(delta1, rect);
    136   greg.ScrollRect(delta2, rect);
    137 
    138   EXPECT_FALSE(greg.HasPendingUpdate());
    139 }
    140 
    141 TEST(PaintAggregator, DiagonalScroll) {
    142   PaintAggregator greg;
    143 
    144   // We don't support optimized diagonal scrolling, so this should result in
    145   // repainting.
    146 
    147   gfx::Rect rect(1, 2, 3, 4);
    148   gfx::Vector2d delta(1, 1);
    149   greg.ScrollRect(delta, rect);
    150 
    151   EXPECT_TRUE(greg.HasPendingUpdate());
    152   PaintAggregator::PendingUpdate update;
    153   greg.PopPendingUpdate(&update);
    154 
    155   EXPECT_TRUE(update.scroll_rect.IsEmpty());
    156   ASSERT_EQ(1U, update.paint_rects.size());
    157 
    158   EXPECT_EQ(rect, update.paint_rects[0]);
    159 }
    160 
    161 TEST(PaintAggregator, ContainedPaintAfterScroll) {
    162   PaintAggregator greg;
    163 
    164   gfx::Rect scroll_rect(0, 0, 10, 10);
    165   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    166 
    167   gfx::Rect paint_rect(4, 4, 2, 2);
    168   greg.InvalidateRect(paint_rect);
    169 
    170   EXPECT_TRUE(greg.HasPendingUpdate());
    171   PaintAggregator::PendingUpdate update;
    172   greg.PopPendingUpdate(&update);
    173 
    174   // expecting a paint rect inside the scroll rect
    175   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    176   EXPECT_EQ(1U, update.paint_rects.size());
    177 
    178   EXPECT_EQ(scroll_rect, update.scroll_rect);
    179   EXPECT_EQ(paint_rect, update.paint_rects[0]);
    180 }
    181 
    182 TEST(PaintAggregator, ContainedPaintBeforeScroll) {
    183   PaintAggregator greg;
    184 
    185   gfx::Rect paint_rect(4, 4, 2, 2);
    186   greg.InvalidateRect(paint_rect);
    187 
    188   gfx::Rect scroll_rect(0, 0, 10, 10);
    189   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    190 
    191   EXPECT_TRUE(greg.HasPendingUpdate());
    192   PaintAggregator::PendingUpdate update;
    193   greg.PopPendingUpdate(&update);
    194 
    195   // Expecting a paint rect inside the scroll rect
    196   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    197   EXPECT_EQ(1U, update.paint_rects.size());
    198 
    199   paint_rect.Offset(2, 0);
    200 
    201   EXPECT_EQ(scroll_rect, update.scroll_rect);
    202   EXPECT_EQ(paint_rect, update.paint_rects[0]);
    203 }
    204 
    205 TEST(PaintAggregator, ContainedPaintsBeforeAndAfterScroll) {
    206   PaintAggregator greg;
    207 
    208   gfx::Rect paint_rect1(4, 4, 2, 2);
    209   greg.InvalidateRect(paint_rect1);
    210 
    211   gfx::Rect scroll_rect(0, 0, 10, 10);
    212   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    213 
    214   gfx::Rect paint_rect2(6, 4, 2, 2);
    215   greg.InvalidateRect(paint_rect2);
    216 
    217   gfx::Rect expected_paint_rect = paint_rect2;
    218 
    219   EXPECT_TRUE(greg.HasPendingUpdate());
    220   PaintAggregator::PendingUpdate update;
    221   greg.PopPendingUpdate(&update);
    222 
    223   // Expecting a paint rect inside the scroll rect
    224   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    225   EXPECT_EQ(1U, update.paint_rects.size());
    226 
    227   EXPECT_EQ(scroll_rect, update.scroll_rect);
    228   EXPECT_EQ(expected_paint_rect, update.paint_rects[0]);
    229 }
    230 
    231 TEST(PaintAggregator, LargeContainedPaintAfterScroll) {
    232   PaintAggregator greg;
    233 
    234   gfx::Rect scroll_rect(0, 0, 10, 10);
    235   greg.ScrollRect(gfx::Vector2d(0, 1), scroll_rect);
    236 
    237   gfx::Rect paint_rect(0, 0, 10, 9);  // Repaint 90%
    238   greg.InvalidateRect(paint_rect);
    239 
    240   EXPECT_TRUE(greg.HasPendingUpdate());
    241   PaintAggregator::PendingUpdate update;
    242   greg.PopPendingUpdate(&update);
    243 
    244   EXPECT_TRUE(update.scroll_rect.IsEmpty());
    245   EXPECT_EQ(1U, update.paint_rects.size());
    246 
    247   EXPECT_EQ(scroll_rect, update.paint_rects[0]);
    248 }
    249 
    250 TEST(PaintAggregator, LargeContainedPaintBeforeScroll) {
    251   PaintAggregator greg;
    252 
    253   gfx::Rect paint_rect(0, 0, 10, 9);  // Repaint 90%
    254   greg.InvalidateRect(paint_rect);
    255 
    256   gfx::Rect scroll_rect(0, 0, 10, 10);
    257   greg.ScrollRect(gfx::Vector2d(0, 1), scroll_rect);
    258 
    259   EXPECT_TRUE(greg.HasPendingUpdate());
    260   PaintAggregator::PendingUpdate update;
    261   greg.PopPendingUpdate(&update);
    262 
    263   EXPECT_TRUE(update.scroll_rect.IsEmpty());
    264   EXPECT_EQ(1U, update.paint_rects.size());
    265 
    266   EXPECT_EQ(scroll_rect, update.paint_rects[0]);
    267 }
    268 
    269 TEST(PaintAggregator, OverlappingPaintBeforeScroll) {
    270   PaintAggregator greg;
    271 
    272   gfx::Rect paint_rect(4, 4, 10, 2);
    273   greg.InvalidateRect(paint_rect);
    274 
    275   gfx::Rect scroll_rect(0, 0, 10, 10);
    276   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    277 
    278   gfx::Rect expected_paint_rect = gfx::UnionRects(scroll_rect, paint_rect);
    279 
    280   EXPECT_TRUE(greg.HasPendingUpdate());
    281   PaintAggregator::PendingUpdate update;
    282   greg.PopPendingUpdate(&update);
    283 
    284   EXPECT_TRUE(update.scroll_rect.IsEmpty());
    285   EXPECT_EQ(1U, update.paint_rects.size());
    286 
    287   EXPECT_EQ(expected_paint_rect, update.paint_rects[0]);
    288 }
    289 
    290 TEST(PaintAggregator, OverlappingPaintAfterScroll) {
    291   PaintAggregator greg;
    292 
    293   gfx::Rect scroll_rect(0, 0, 10, 10);
    294   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    295 
    296   gfx::Rect paint_rect(4, 4, 10, 2);
    297   greg.InvalidateRect(paint_rect);
    298 
    299   gfx::Rect expected_paint_rect = gfx::UnionRects(scroll_rect, paint_rect);
    300 
    301   EXPECT_TRUE(greg.HasPendingUpdate());
    302   PaintAggregator::PendingUpdate update;
    303   greg.PopPendingUpdate(&update);
    304 
    305   EXPECT_TRUE(update.scroll_rect.IsEmpty());
    306   EXPECT_EQ(1U, update.paint_rects.size());
    307 
    308   EXPECT_EQ(expected_paint_rect, update.paint_rects[0]);
    309 }
    310 
    311 TEST(PaintAggregator, DisjointPaintBeforeScroll) {
    312   PaintAggregator greg;
    313 
    314   gfx::Rect paint_rect(4, 4, 10, 2);
    315   greg.InvalidateRect(paint_rect);
    316 
    317   gfx::Rect scroll_rect(0, 0, 2, 10);
    318   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    319 
    320   EXPECT_TRUE(greg.HasPendingUpdate());
    321   PaintAggregator::PendingUpdate update;
    322   greg.PopPendingUpdate(&update);
    323 
    324   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    325   EXPECT_EQ(1U, update.paint_rects.size());
    326 
    327   EXPECT_EQ(paint_rect, update.paint_rects[0]);
    328   EXPECT_EQ(scroll_rect, update.scroll_rect);
    329 }
    330 
    331 TEST(PaintAggregator, DisjointPaintAfterScroll) {
    332   PaintAggregator greg;
    333 
    334   gfx::Rect scroll_rect(0, 0, 2, 10);
    335   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    336 
    337   gfx::Rect paint_rect(4, 4, 10, 2);
    338   greg.InvalidateRect(paint_rect);
    339 
    340   EXPECT_TRUE(greg.HasPendingUpdate());
    341   PaintAggregator::PendingUpdate update;
    342   greg.PopPendingUpdate(&update);
    343 
    344   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    345   EXPECT_EQ(1U, update.paint_rects.size());
    346 
    347   EXPECT_EQ(paint_rect, update.paint_rects[0]);
    348   EXPECT_EQ(scroll_rect, update.scroll_rect);
    349 }
    350 
    351 TEST(PaintAggregator, ContainedPaintTrimmedByScroll) {
    352   PaintAggregator greg;
    353 
    354   gfx::Rect paint_rect(4, 4, 6, 6);
    355   greg.InvalidateRect(paint_rect);
    356 
    357   gfx::Rect scroll_rect(0, 0, 10, 10);
    358   greg.ScrollRect(gfx::Vector2d(2, 0), scroll_rect);
    359 
    360   // The paint rect should have become narrower.
    361   gfx::Rect expected_paint_rect(6, 4, 4, 6);
    362 
    363   EXPECT_TRUE(greg.HasPendingUpdate());
    364   PaintAggregator::PendingUpdate update;
    365   greg.PopPendingUpdate(&update);
    366 
    367   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    368   EXPECT_EQ(1U, update.paint_rects.size());
    369 
    370   EXPECT_EQ(expected_paint_rect, update.paint_rects[0]);
    371   EXPECT_EQ(scroll_rect, update.scroll_rect);
    372 }
    373 
    374 TEST(PaintAggregator, ContainedPaintEliminatedByScroll) {
    375   PaintAggregator greg;
    376 
    377   gfx::Rect paint_rect(4, 4, 6, 6);
    378   greg.InvalidateRect(paint_rect);
    379 
    380   gfx::Rect scroll_rect(0, 0, 10, 10);
    381   greg.ScrollRect(gfx::Vector2d(6, 0), scroll_rect);
    382 
    383   EXPECT_TRUE(greg.HasPendingUpdate());
    384   PaintAggregator::PendingUpdate update;
    385   greg.PopPendingUpdate(&update);
    386 
    387   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    388   EXPECT_TRUE(update.paint_rects.empty());
    389 
    390   EXPECT_EQ(scroll_rect, update.scroll_rect);
    391 }
    392 
    393 TEST(PaintAggregator, ContainedPaintAfterScrollTrimmedByScrollDamage) {
    394   PaintAggregator greg;
    395 
    396   gfx::Rect scroll_rect(0, 0, 10, 10);
    397   greg.ScrollRect(gfx::Vector2d(4, 0), scroll_rect);
    398 
    399   gfx::Rect paint_rect(2, 0, 4, 10);
    400   greg.InvalidateRect(paint_rect);
    401 
    402   gfx::Rect expected_scroll_damage(0, 0, 4, 10);
    403   gfx::Rect expected_paint_rect(4, 0, 2, 10);
    404 
    405   EXPECT_TRUE(greg.HasPendingUpdate());
    406   PaintAggregator::PendingUpdate update;
    407   greg.PopPendingUpdate(&update);
    408 
    409   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    410   EXPECT_EQ(1U, update.paint_rects.size());
    411 
    412   EXPECT_EQ(scroll_rect, update.scroll_rect);
    413   EXPECT_EQ(expected_scroll_damage, update.GetScrollDamage());
    414   EXPECT_EQ(expected_paint_rect, update.paint_rects[0]);
    415 }
    416 
    417 TEST(PaintAggregator, ContainedPaintAfterScrollEliminatedByScrollDamage) {
    418   PaintAggregator greg;
    419 
    420   gfx::Rect scroll_rect(0, 0, 10, 10);
    421   greg.ScrollRect(gfx::Vector2d(4, 0), scroll_rect);
    422 
    423   gfx::Rect paint_rect(2, 0, 2, 10);
    424   greg.InvalidateRect(paint_rect);
    425 
    426   gfx::Rect expected_scroll_damage(0, 0, 4, 10);
    427 
    428   EXPECT_TRUE(greg.HasPendingUpdate());
    429   PaintAggregator::PendingUpdate update;
    430   greg.PopPendingUpdate(&update);
    431 
    432   EXPECT_FALSE(update.scroll_rect.IsEmpty());
    433   EXPECT_TRUE(update.paint_rects.empty());
    434 
    435   EXPECT_EQ(scroll_rect, update.scroll_rect);
    436   EXPECT_EQ(expected_scroll_damage, update.GetScrollDamage());
    437 }
    438 
    439 }  // namespace content
    440