Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / tests / PaintAggregatorTest.cpp
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 WebCore;
37 using namespace blink;
38
39 namespace {
40
41 TEST(PaintAggregator, InitialState)
42 {
43     PaintAggregator greg;
44     EXPECT_FALSE(greg.hasPendingUpdate());
45 }
46
47 TEST(PaintAggregator, SingleInvalidation)
48 {
49     PaintAggregator greg;
50
51     IntRect rect(2, 4, 10, 16);
52     greg.invalidateRect(rect);
53
54     EXPECT_TRUE(greg.hasPendingUpdate());
55     PaintAggregator::PendingUpdate update;
56     greg.popPendingUpdate(&update);
57
58     EXPECT_TRUE(update.scrollRect.isEmpty());
59     ASSERT_EQ(1U, update.paintRects.size());
60
61     EXPECT_EQ(rect, update.paintRects[0]);
62 }
63
64 TEST(PaintAggregator, DoubleDisjointInvalidation)
65 {
66     PaintAggregator greg;
67
68     IntRect r1(2, 4, 2, 40);
69     IntRect r2(4, 2, 40, 2);
70
71     greg.invalidateRect(r1);
72     greg.invalidateRect(r2);
73
74     IntRect expectedBounds = unionRect(r1, r2);
75
76     EXPECT_TRUE(greg.hasPendingUpdate());
77     PaintAggregator::PendingUpdate update;
78     greg.popPendingUpdate(&update);
79
80     EXPECT_TRUE(update.scrollRect.isEmpty());
81     EXPECT_EQ(2U, update.paintRects.size());
82
83     EXPECT_EQ(expectedBounds, update.calculatePaintBounds());
84 }
85
86 TEST(PaintAggregator, DisjointInvalidationsCombined)
87 {
88     PaintAggregator greg;
89
90     // Make the rectangles such that they don't overlap but cover a very large
91     // percentage of the area of covered by their union. This is so we're not
92     // very sensitive to the combining heuristic in the paint aggregator.
93     IntRect r1(2, 4, 2, 1000);
94     IntRect r2(5, 2, 2, 1000);
95
96     greg.invalidateRect(r1);
97     greg.invalidateRect(r2);
98
99     IntRect expectedBounds = unionRect(r1, r2);
100
101     EXPECT_TRUE(greg.hasPendingUpdate());
102     PaintAggregator::PendingUpdate update;
103     greg.popPendingUpdate(&update);
104
105     EXPECT_TRUE(update.scrollRect.isEmpty());
106     ASSERT_EQ(1U, update.paintRects.size());
107
108     EXPECT_EQ(expectedBounds, update.paintRects[0]);
109 }
110
111 TEST(PaintAggregator, SingleScroll)
112 {
113     PaintAggregator greg;
114
115     IntRect rect(1, 2, 3, 4);
116     IntPoint delta(1, 0);
117     greg.scrollRect(delta.x(), delta.y(), rect);
118
119     EXPECT_TRUE(greg.hasPendingUpdate());
120     PaintAggregator::PendingUpdate update;
121     greg.popPendingUpdate(&update);
122
123     EXPECT_TRUE(update.paintRects.isEmpty());
124     EXPECT_FALSE(update.scrollRect.isEmpty());
125
126     EXPECT_EQ(rect, update.scrollRect);
127
128     EXPECT_EQ(delta.x(), update.scrollDelta.x());
129     EXPECT_EQ(delta.y(), update.scrollDelta.y());
130
131     IntRect resultingDamage = update.calculateScrollDamage();
132     IntRect expectedDamage(1, 2, 1, 4);
133     EXPECT_EQ(expectedDamage, resultingDamage);
134 }
135
136 TEST(PaintAggregator, DoubleOverlappingScroll)
137 {
138     PaintAggregator greg;
139
140     IntRect rect(1, 2, 3, 4);
141     IntPoint delta1(1, 0);
142     IntPoint delta2(1, 0);
143     greg.scrollRect(delta1.x(), delta1.y(), rect);
144     greg.scrollRect(delta2.x(), delta2.y(), rect);
145
146     EXPECT_TRUE(greg.hasPendingUpdate());
147     PaintAggregator::PendingUpdate update;
148     greg.popPendingUpdate(&update);
149
150     EXPECT_TRUE(update.paintRects.isEmpty());
151     EXPECT_FALSE(update.scrollRect.isEmpty());
152
153     EXPECT_EQ(rect, update.scrollRect);
154
155     IntPoint expectedDelta(delta1.x() + delta2.x(),
156                            delta1.y() + delta2.y());
157     EXPECT_EQ(expectedDelta.x(), update.scrollDelta.x());
158     EXPECT_EQ(expectedDelta.y(), update.scrollDelta.y());
159
160     IntRect resultingDamage = update.calculateScrollDamage();
161     IntRect expectedDamage(1, 2, 2, 4);
162     EXPECT_EQ(expectedDamage, resultingDamage);
163 }
164
165 TEST(PaintAggregator, NegatingScroll)
166 {
167     PaintAggregator greg;
168
169     // Scroll twice in opposite directions by equal amounts. The result
170     // should be no scrolling.
171
172     IntRect rect(1, 2, 3, 4);
173     IntPoint delta1(1, 0);
174     IntPoint delta2(-1, 0);
175     greg.scrollRect(delta1.x(), delta1.y(), rect);
176     greg.scrollRect(delta2.x(), delta2.y(), rect);
177
178     EXPECT_FALSE(greg.hasPendingUpdate());
179 }
180
181 TEST(PaintAggregator, DiagonalScroll)
182 {
183     PaintAggregator greg;
184
185     // We don't support optimized diagonal scrolling, so this should result in
186     // repainting.
187
188     IntRect rect(1, 2, 3, 4);
189     IntPoint delta(1, 1);
190     greg.scrollRect(delta.x(), delta.y(), rect);
191
192     EXPECT_TRUE(greg.hasPendingUpdate());
193     PaintAggregator::PendingUpdate update;
194     greg.popPendingUpdate(&update);
195
196     EXPECT_TRUE(update.scrollRect.isEmpty());
197     ASSERT_EQ(1U, update.paintRects.size());
198
199     EXPECT_EQ(rect, update.paintRects[0]);
200 }
201
202 TEST(PaintAggregator, ContainedPaintAfterScroll)
203 {
204     PaintAggregator greg;
205
206     IntRect scrollRect(0, 0, 10, 10);
207     greg.scrollRect(2, 0, scrollRect);
208
209     IntRect paintRect(4, 4, 2, 2);
210     greg.invalidateRect(paintRect);
211
212     EXPECT_TRUE(greg.hasPendingUpdate());
213     PaintAggregator::PendingUpdate update;
214     greg.popPendingUpdate(&update);
215
216     // expecting a paint rect inside the scroll rect
217     EXPECT_FALSE(update.scrollRect.isEmpty());
218     EXPECT_EQ(1U, update.paintRects.size());
219
220     EXPECT_EQ(scrollRect, update.scrollRect);
221     EXPECT_EQ(paintRect, update.paintRects[0]);
222 }
223
224 TEST(PaintAggregator, ContainedPaintBeforeScroll)
225 {
226     PaintAggregator greg;
227
228     IntRect paintRect(4, 4, 2, 2);
229     greg.invalidateRect(paintRect);
230
231     IntRect scrollRect(0, 0, 10, 10);
232     greg.scrollRect(2, 0, scrollRect);
233
234     EXPECT_TRUE(greg.hasPendingUpdate());
235     PaintAggregator::PendingUpdate update;
236     greg.popPendingUpdate(&update);
237
238     // Expecting a paint rect inside the scroll rect
239     EXPECT_FALSE(update.scrollRect.isEmpty());
240     EXPECT_EQ(1U, update.paintRects.size());
241
242     paintRect.move(2, 0);
243
244     EXPECT_EQ(scrollRect, update.scrollRect);
245     EXPECT_EQ(paintRect, update.paintRects[0]);
246 }
247
248 TEST(PaintAggregator, ContainedPaintsBeforeAndAfterScroll)
249 {
250     PaintAggregator greg;
251
252     IntRect paintRect1(4, 4, 2, 2);
253     greg.invalidateRect(paintRect1);
254
255     IntRect scrollRect(0, 0, 10, 10);
256     greg.scrollRect(2, 0, scrollRect);
257
258     IntRect paintRect2(6, 4, 2, 2);
259     greg.invalidateRect(paintRect2);
260
261     IntRect expectedPaintRect = paintRect2;
262
263     EXPECT_TRUE(greg.hasPendingUpdate());
264     PaintAggregator::PendingUpdate update;
265     greg.popPendingUpdate(&update);
266
267     // Expecting a paint rect inside the scroll rect
268     EXPECT_FALSE(update.scrollRect.isEmpty());
269     EXPECT_EQ(1U, update.paintRects.size());
270
271     EXPECT_EQ(scrollRect, update.scrollRect);
272     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
273 }
274
275 TEST(PaintAggregator, LargeContainedPaintAfterScroll)
276 {
277     PaintAggregator greg;
278
279     IntRect scrollRect(0, 0, 10, 10);
280     greg.scrollRect(0, 1, scrollRect);
281
282     IntRect paintRect(0, 0, 10, 9); // Repaint 90%
283     greg.invalidateRect(paintRect);
284
285     EXPECT_TRUE(greg.hasPendingUpdate());
286     PaintAggregator::PendingUpdate update;
287     greg.popPendingUpdate(&update);
288
289     EXPECT_TRUE(update.scrollRect.isEmpty());
290     EXPECT_EQ(1U, update.paintRects.size());
291
292     EXPECT_EQ(scrollRect, update.paintRects[0]);
293 }
294
295 TEST(PaintAggregator, LargeContainedPaintBeforeScroll)
296 {
297     PaintAggregator greg;
298
299     IntRect paintRect(0, 0, 10, 9); // Repaint 90%
300     greg.invalidateRect(paintRect);
301
302     IntRect scrollRect(0, 0, 10, 10);
303     greg.scrollRect(0, 1, scrollRect);
304
305     EXPECT_TRUE(greg.hasPendingUpdate());
306     PaintAggregator::PendingUpdate update;
307     greg.popPendingUpdate(&update);
308
309     EXPECT_TRUE(update.scrollRect.isEmpty());
310     EXPECT_EQ(1U, update.paintRects.size());
311
312     EXPECT_EQ(scrollRect, update.paintRects[0]);
313 }
314
315 TEST(PaintAggregator, OverlappingPaintBeforeScroll)
316 {
317     PaintAggregator greg;
318
319     IntRect paintRect(4, 4, 10, 2);
320     greg.invalidateRect(paintRect);
321
322     IntRect scrollRect(0, 0, 10, 10);
323     greg.scrollRect(2, 0, scrollRect);
324
325     IntRect expectedPaintRect = unionRect(scrollRect, paintRect);
326
327     EXPECT_TRUE(greg.hasPendingUpdate());
328     PaintAggregator::PendingUpdate update;
329     greg.popPendingUpdate(&update);
330
331     EXPECT_TRUE(update.scrollRect.isEmpty());
332     EXPECT_EQ(1U, update.paintRects.size());
333
334     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
335 }
336
337 TEST(PaintAggregator, OverlappingPaintAfterScroll)
338 {
339     PaintAggregator greg;
340
341     IntRect scrollRect(0, 0, 10, 10);
342     greg.scrollRect(2, 0, scrollRect);
343
344     IntRect paintRect(4, 4, 10, 2);
345     greg.invalidateRect(paintRect);
346
347     IntRect expectedPaintRect = unionRect(scrollRect, paintRect);
348
349     EXPECT_TRUE(greg.hasPendingUpdate());
350     PaintAggregator::PendingUpdate update;
351     greg.popPendingUpdate(&update);
352
353     EXPECT_TRUE(update.scrollRect.isEmpty());
354     EXPECT_EQ(1U, update.paintRects.size());
355
356     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
357 }
358
359 TEST(PaintAggregator, DisjointPaintBeforeScroll)
360 {
361     PaintAggregator greg;
362
363     IntRect paintRect(4, 4, 10, 2);
364     greg.invalidateRect(paintRect);
365
366     IntRect scrollRect(0, 0, 2, 10);
367     greg.scrollRect(2, 0, scrollRect);
368
369     EXPECT_TRUE(greg.hasPendingUpdate());
370     PaintAggregator::PendingUpdate update;
371     greg.popPendingUpdate(&update);
372
373     EXPECT_FALSE(update.scrollRect.isEmpty());
374     EXPECT_EQ(1U, update.paintRects.size());
375
376     EXPECT_EQ(paintRect, update.paintRects[0]);
377     EXPECT_EQ(scrollRect, update.scrollRect);
378 }
379
380 TEST(PaintAggregator, DisjointPaintAfterScroll)
381 {
382     PaintAggregator greg;
383
384     IntRect scrollRect(0, 0, 2, 10);
385     greg.scrollRect(2, 0, scrollRect);
386
387     IntRect paintRect(4, 4, 10, 2);
388     greg.invalidateRect(paintRect);
389
390     EXPECT_TRUE(greg.hasPendingUpdate());
391     PaintAggregator::PendingUpdate update;
392     greg.popPendingUpdate(&update);
393
394     EXPECT_FALSE(update.scrollRect.isEmpty());
395     EXPECT_EQ(1U, update.paintRects.size());
396
397     EXPECT_EQ(paintRect, update.paintRects[0]);
398     EXPECT_EQ(scrollRect, update.scrollRect);
399 }
400
401 TEST(PaintAggregator, ContainedPaintTrimmedByScroll)
402 {
403     PaintAggregator greg;
404
405     IntRect paintRect(4, 4, 6, 6);
406     greg.invalidateRect(paintRect);
407
408     IntRect scrollRect(0, 0, 10, 10);
409     greg.scrollRect(2, 0, scrollRect);
410
411     // The paint rect should have become narrower.
412     IntRect expectedPaintRect(6, 4, 4, 6);
413
414     EXPECT_TRUE(greg.hasPendingUpdate());
415     PaintAggregator::PendingUpdate update;
416     greg.popPendingUpdate(&update);
417
418     EXPECT_FALSE(update.scrollRect.isEmpty());
419     EXPECT_EQ(1U, update.paintRects.size());
420
421     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
422     EXPECT_EQ(scrollRect, update.scrollRect);
423 }
424
425 TEST(PaintAggregator, ContainedPaintEliminatedByScroll)
426 {
427     PaintAggregator greg;
428
429     IntRect paintRect(4, 4, 6, 6);
430     greg.invalidateRect(paintRect);
431
432     IntRect scrollRect(0, 0, 10, 10);
433     greg.scrollRect(6, 0, scrollRect);
434
435     EXPECT_TRUE(greg.hasPendingUpdate());
436     PaintAggregator::PendingUpdate update;
437     greg.popPendingUpdate(&update);
438
439     EXPECT_FALSE(update.scrollRect.isEmpty());
440     EXPECT_TRUE(update.paintRects.isEmpty());
441
442     EXPECT_EQ(scrollRect, update.scrollRect);
443 }
444
445 TEST(PaintAggregator, ContainedPaintAfterScrollTrimmedByScrollDamage)
446 {
447     PaintAggregator greg;
448
449     IntRect scrollRect(0, 0, 10, 10);
450     greg.scrollRect(4, 0, scrollRect);
451
452     IntRect paintRect(2, 0, 4, 10);
453     greg.invalidateRect(paintRect);
454
455     IntRect expectedScrollDamage(0, 0, 4, 10);
456     IntRect expectedPaintRect(4, 0, 2, 10);
457
458     EXPECT_TRUE(greg.hasPendingUpdate());
459     PaintAggregator::PendingUpdate update;
460     greg.popPendingUpdate(&update);
461
462     EXPECT_FALSE(update.scrollRect.isEmpty());
463     EXPECT_EQ(1U, update.paintRects.size());
464
465     EXPECT_EQ(scrollRect, update.scrollRect);
466     EXPECT_EQ(expectedScrollDamage, update.calculateScrollDamage());
467     EXPECT_EQ(expectedPaintRect, update.paintRects[0]);
468 }
469
470 TEST(PaintAggregator, ContainedPaintAfterScrollEliminatedByScrollDamage)
471 {
472     PaintAggregator greg;
473
474     IntRect scrollRect(0, 0, 10, 10);
475     greg.scrollRect(4, 0, scrollRect);
476
477     IntRect paintRect(2, 0, 2, 10);
478     greg.invalidateRect(paintRect);
479
480     IntRect expectedScrollDamage(0, 0, 4, 10);
481
482     EXPECT_TRUE(greg.hasPendingUpdate());
483     PaintAggregator::PendingUpdate update;
484     greg.popPendingUpdate(&update);
485
486     EXPECT_FALSE(update.scrollRect.isEmpty());
487     EXPECT_TRUE(update.paintRects.isEmpty());
488
489     EXPECT_EQ(scrollRect, update.scrollRect);
490     EXPECT_EQ(expectedScrollDamage, update.calculateScrollDamage());
491 }
492
493 } // namespace