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