073fa1931173035cca6467175d24265c11d2f195
[WebKit-https.git] / Source / WebKit / chromium / tests / TiledLayerChromiumTest.cpp
1 /*
2  * Copyright (C) 2011 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
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "TiledLayerChromium.h"
28
29 #include "CCAnimationTestCommon.h"
30 #include "CCLayerTreeTestCommon.h"
31 #include "CCTiledLayerTestCommon.h"
32 #include "FakeCCLayerTreeHostClient.h"
33 #include "WebCompositor.h"
34 #include "cc/CCOverdrawMetrics.h"
35 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
36 #include <gtest/gtest.h>
37 #include <public/WebTransformationMatrix.h>
38
39 using namespace WebCore;
40 using namespace WebKitTests;
41 using namespace WTF;
42 using WebKit::WebTransformationMatrix;
43
44 #define EXPECT_EQ_RECT(a, b) \
45     EXPECT_EQ(a.x(), b.x()); \
46     EXPECT_EQ(a.y(), b.y()); \
47     EXPECT_EQ(a.width(), b.width()); \
48     EXPECT_EQ(a.height(), b.height());
49
50 namespace {
51
52 class TestCCOcclusionTracker : public CCOcclusionTracker {
53 public:
54     TestCCOcclusionTracker()
55         : CCOcclusionTracker(IntRect(0, 0, 1000, 1000), true)
56         , m_scissorRectInScreen(IntRect(0, 0, 1000, 1000))
57     {
58         // Pretend we have visited a render surface.
59         m_stack.append(StackObject());
60     }
61
62     void setOcclusion(const Region& occlusion) { m_stack.last().occlusionInScreen = occlusion; }
63
64 protected:
65     virtual IntRect layerScissorRectInTargetSurface(const LayerChromium* layer) const { return m_scissorRectInScreen; }
66
67 private:
68     IntRect m_scissorRectInScreen;
69 };
70
71 TEST(TiledLayerChromiumTest, pushDirtyTiles)
72 {
73     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
74     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
75     DebugScopedSetImplThread implThread;
76     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
77
78     CCTextureUpdater updater;
79
80     // The tile size is 100x100, so this invalidates and then paints two tiles.
81     layer->setBounds(IntSize(100, 200));
82     layer->invalidateRect(IntRect(0, 0, 100, 200));
83     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
84     layer->pushPropertiesTo(layerImpl.get());
85
86     // We should have both tiles on the impl side.
87     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
88     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
89
90     textureManager->unprotectAllTextures();
91
92     // Invalidates both tiles...
93     layer->invalidateRect(IntRect(0, 0, 100, 200));
94     // ....but then only update one of them.
95     layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
96     layer->pushPropertiesTo(layerImpl.get());
97
98     // We should only have the first tile since the other tile was invalidated but not painted.
99     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
100     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
101 }
102
103 TEST(TiledLayerChromiumTest, pushOccludedDirtyTiles)
104 {
105     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
106     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
107     DebugScopedSetImplThread implThread;
108     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
109     TestCCOcclusionTracker occluded;
110
111     CCTextureUpdater updater;
112
113     // The tile size is 100x100, so this invalidates and then paints two tiles.
114     layer->setBounds(IntSize(100, 200));
115     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
116     layer->setVisibleLayerRect(IntRect(0, 0, 100, 200));
117     layer->invalidateRect(IntRect(0, 0, 100, 200));
118     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), &occluded);
119     layer->pushPropertiesTo(layerImpl.get());
120
121     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
122     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
123     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
124
125     // We should have both tiles on the impl side.
126     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
127     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
128
129     textureManager->unprotectAllTextures();
130
131     // Invalidates part of the top tile...
132     layer->invalidateRect(IntRect(0, 0, 50, 50));
133     // ....but the area is occluded.
134     occluded.setOcclusion(IntRect(0, 0, 50, 50));
135     layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), &occluded);
136     layer->pushPropertiesTo(layerImpl.get());
137
138     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
139     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 2500, 1);
140     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
141
142     // We should still have both tiles, as part of the top tile is still unoccluded.
143     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
144     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
145 }
146
147 TEST(TiledLayerChromiumTest, pushDeletedTiles)
148 {
149     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
150     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
151     DebugScopedSetImplThread implThread;
152     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
153
154     CCTextureUpdater updater;
155     FakeTextureAllocator allocator;
156
157     // The tile size is 100x100, so this invalidates and then paints two tiles.
158     layer->setBounds(IntSize(100, 200));
159     layer->invalidateRect(IntRect(0, 0, 100, 200));
160     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
161     layer->pushPropertiesTo(layerImpl.get());
162
163     // We should have both tiles on the impl side.
164     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
165     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
166
167     textureManager->evictAndDeleteAllTextures(&allocator);
168     textureManager->setMaxMemoryLimitBytes(4*1024*1024);
169     textureManager->setPreferredMemoryLimitBytes(4*1024*1024);
170
171     // This should drop the tiles on the impl thread.
172     layer->pushPropertiesTo(layerImpl.get());
173
174     // We should now have no textures on the impl thread.
175     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
176     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
177
178     // This should recreate and update the deleted textures.
179     layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
180     layer->pushPropertiesTo(layerImpl.get());
181
182     // We should only have the first tile since the other tile was invalidated but not painted.
183     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
184     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
185 }
186
187 TEST(TiledLayerChromiumTest, pushIdlePaintTiles)
188 {
189     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
190     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
191     DebugScopedSetImplThread implThread;
192     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
193
194     CCTextureUpdater updater;
195
196     // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center.
197     IntSize contentBounds(500, 500);
198     IntRect contentRect(IntPoint::zero(), contentBounds);
199     IntRect visibleRect(200, 200, 100, 100);
200
201     // This invalidates 25 tiles and then paints one visible tile.
202     layer->setBounds(contentBounds);
203     layer->setVisibleLayerRect(visibleRect);
204     layer->invalidateRect(contentRect);
205     layer->updateLayerRect(updater, visibleRect, 0);
206
207     // We should need idle-painting for 3x3 tiles in the center.
208     EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
209
210     layer->pushPropertiesTo(layerImpl.get());
211
212     // We should have one tile on the impl side.
213     EXPECT_TRUE(layerImpl->hasTileAt(2, 2));
214
215     textureManager->unprotectAllTextures();
216
217     // For the next four updates, we should detect we still need idle painting.
218     for (int i = 0; i < 4; i++) {
219         layer->updateLayerRect(updater, visibleRect, 0);
220         EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
221         layer->idleUpdateLayerRect(updater, visibleRect, 0);
222         layer->pushPropertiesTo(layerImpl.get());
223         textureManager->unprotectAllTextures();
224     }
225
226     // After four passes of idle painting, we should be finished painting
227     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
228
229     // We should have one tile surrounding the visible tile on all sides, but no other tiles.
230     IntRect idlePaintTiles(1, 1, 3, 3);
231     for (int i = 0; i < 5; i++) {
232         for (int j = 0; j < 5; j++) {
233             if (idlePaintTiles.contains(i, j))
234                 EXPECT_TRUE(layerImpl->hasTileAt(i, j));
235             else
236                 EXPECT_FALSE(layerImpl->hasTileAt(i, j));
237         }
238     }
239 }
240
241 TEST(TiledLayerChromiumTest, pushTilesAfterIdlePaintFailed)
242 {
243     OwnPtr<TextureManager> textureManager = TextureManager::create(1024*1024, 1024*1024, 1024);
244     DebugScopedSetImplThread implThread;
245     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
246     OwnPtr<FakeCCTiledLayerImpl> layerImpl1(adoptPtr(new FakeCCTiledLayerImpl(0)));
247     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
248     OwnPtr<FakeCCTiledLayerImpl> layerImpl2(adoptPtr(new FakeCCTiledLayerImpl(0)));
249
250     CCTextureUpdater updater;
251     FakeTextureAllocator allocator;
252     FakeTextureCopier copier;
253     FakeTextureUploader uploader;
254
255     // For this test we have two layers. layer1 exhausts most texture memory, leaving room for 2 more tiles from
256     // layer2, but not all three tiles. First we paint layer1, and one tile from layer2. Then when we idle paint
257     // layer2, we will fail on the third tile of layer2, and this should not leave the second tile in a bad state.
258
259     // This requires 4*30000 bytes of memory.
260     IntRect layer2Rect(0, 0, 100, 300);
261     layer2->setBounds(layer2Rect.size());
262     layer2->setVisibleLayerRect(layer2Rect);
263     layer2->invalidateRect(layer2Rect);
264
265     // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough for 2 tiles only in the other layer.
266     IntRect layerRect(IntPoint::zero(), IntSize(100, 2400));
267     layer1->setBounds(layerRect.size());
268     layer1->setVisibleLayerRect(layerRect);
269     layer1->invalidateRect(layerRect);
270     layer1->updateLayerRect(updater, layerRect, 0);
271
272     // Paint a single tile in layer2 so that it will idle paint.
273     layer2->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
274
275     // We should need idle-painting for both remaining tiles in layer2.
276     EXPECT_TRUE(layer2->needsIdlePaint(layer2Rect));
277
278     // Commit the frame over to impl.
279     updater.update(0, &allocator, &copier, &uploader, 5000);
280     layer1->pushPropertiesTo(layerImpl1.get());
281     layer2->pushPropertiesTo(layerImpl2.get());
282
283     // Now idle paint layer2. We are going to run out of memory though!
284     layer2->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
285     layer2->idleUpdateLayerRect(updater, layer2Rect, 0);
286
287     // Oh well, commit the frame and push.
288     updater.update(0, &allocator, &copier, &uploader, 5000);
289     layer1->pushPropertiesTo(layerImpl1.get());
290     layer2->pushPropertiesTo(layerImpl2.get());
291
292     // Sanity check, we should have textures for the big layer.
293     EXPECT_TRUE(layerImpl1->hasTextureIdForTileAt(0, 0));
294
295     // We should only have the first tile from layer2 since it failed to idle update.
296     EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
297     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
298     EXPECT_FALSE(layerImpl2->hasTileAt(0, 1));
299     EXPECT_FALSE(layerImpl2->hasTileAt(0, 2));
300
301     // Now if layer2 becomes fully visible, we should be able to paint it and push valid textures.
302     textureManager->unprotectAllTextures();
303
304     layer2->updateLayerRect(updater, layer2Rect, 0);
305     layer1->updateLayerRect(updater, IntRect(), 0);
306
307     updater.update(0, &allocator, &copier, &uploader, 5000);
308     layer1->pushPropertiesTo(layerImpl1.get());
309     layer2->pushPropertiesTo(layerImpl2.get());
310
311     EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
312     EXPECT_TRUE(layerImpl2->hasTileAt(0, 1));
313     EXPECT_TRUE(layerImpl2->hasTileAt(0, 2));
314     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
315     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 1));
316     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 2));
317 }
318
319 TEST(TiledLayerChromiumTest, pushIdlePaintedOccludedTiles)
320 {
321     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
322     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
323     DebugScopedSetImplThread implThread;
324     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
325     TestCCOcclusionTracker occluded;
326
327     CCTextureUpdater updater;
328
329     // The tile size is 100x100, so this invalidates one occluded tile, culls it during paint, but prepaints it.
330     occluded.setOcclusion(IntRect(0, 0, 100, 100));
331
332     layer->setBounds(IntSize(100, 100));
333     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
334     layer->setVisibleLayerRect(IntRect(0, 0, 100, 100));
335     layer->invalidateRect(IntRect(0, 0, 100, 100));
336     layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), &occluded);
337     layer->idleUpdateLayerRect(updater, IntRect(0, 0, 100, 100), &occluded);
338     layer->pushPropertiesTo(layerImpl.get());
339
340     // We should have the prepainted tile on the impl side.
341     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
342 }
343
344 TEST(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
345 {
346     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
347     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
348     DebugScopedSetImplThread implThread;
349     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
350
351     CCTextureUpdater updater;
352
353     // The tile size is 100x100, so this invalidates and then paints two tiles.
354     // However, during the paint, we invalidate one of the tiles. This should
355     // not prevent the tile from being pushed.
356     layer->setBounds(IntSize(100, 200));
357     layer->invalidateRect(IntRect(0, 0, 100, 200));
358     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer.get());
359     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
360     layer->pushPropertiesTo(layerImpl.get());
361
362     // We should have both tiles on the impl side.
363     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
364     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
365 }
366
367 TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
368 {
369     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
370     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
371     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
372     DebugScopedSetImplThread implThread;
373     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
374     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
375
376     CCTextureUpdater updater;
377
378     layer1->setBounds(IntSize(100, 200));
379     layer1->invalidateRect(IntRect(0, 0, 100, 200));
380     layer2->setBounds(IntSize(100, 200));
381     layer2->invalidateRect(IntRect(0, 0, 100, 200));
382
383     layer1->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
384
385     // Invalidate a tile on layer1
386     layer2->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer1.get());
387     layer2->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
388
389     layer1->pushPropertiesTo(layer1Impl.get());
390     layer2->pushPropertiesTo(layer2Impl.get());
391
392     // We should have both tiles on the impl side for all layers.
393     EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
394     EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
395     EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
396     EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
397 }
398
399 TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer)
400 {
401     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
402     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
403     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
404     DebugScopedSetImplThread implThread;
405     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
406     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
407
408     CCTextureUpdater updater;
409
410     layer1->setBounds(IntSize(100, 200));
411     layer1->invalidateRect(IntRect(0, 0, 100, 200));
412     layer2->setBounds(IntSize(100, 200));
413     layer2->invalidateRect(IntRect(0, 0, 100, 200));
414
415     // Invalidate a tile on layer2
416     layer1->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer2.get());
417     layer1->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
418
419     layer2->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
420
421     layer1->pushPropertiesTo(layer1Impl.get());
422     layer2->pushPropertiesTo(layer2Impl.get());
423
424     // We should have both tiles on the impl side for all layers.
425     EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
426     EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
427     EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
428     EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
429 }
430
431 TEST(TiledLayerChromiumTest, idlePaintOutOfMemory)
432 {
433     // The tile size is 100x100. Setup 5x5 tiles with one 1x1 visible tile in the center.
434     IntSize contentBounds(300, 300);
435     IntRect contentRect(IntPoint::zero(), contentBounds);
436     IntRect visibleRect(100, 100, 100, 100);
437
438     // We have enough memory for only the visible rect, so we will run out of memory in first idle paint.
439     int memoryLimit = 4 * 100 * 100; // 2 tiles, 4 bytes per pixel.
440
441     OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit / 2, 1024);
442     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
443     DebugScopedSetImplThread implThread;
444     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
445
446     CCTextureUpdater updater;
447
448     // This invalidates 9 tiles and then paints one visible tile.
449     layer->setBounds(contentBounds);
450     layer->setVisibleLayerRect(visibleRect);
451     layer->invalidateRect(contentRect);
452     layer->updateLayerRect(updater, visibleRect, 0);
453
454     // We should need idle-painting for 3x3 tiles surounding visible tile.
455     EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
456
457     layer->pushPropertiesTo(layerImpl.get());
458
459     // We should have one tile on the impl side.
460     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
461
462     textureManager->unprotectAllTextures();
463     layer->updateLayerRect(updater, visibleRect, 0);
464     layer->idleUpdateLayerRect(updater, visibleRect, 0);
465
466     // We shouldn't signal we need another idle paint after we run out of memory.
467     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
468
469     layer->pushPropertiesTo(layerImpl.get());
470 }
471
472 TEST(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
473 {
474     OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
475     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
476     DebugScopedSetImplThread implThread;
477     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
478
479     CCTextureUpdater updater;
480
481     // The layer's bounds are empty.
482     IntRect contentRect;
483
484     layer->setBounds(contentRect.size());
485     layer->setVisibleLayerRect(contentRect);
486     layer->invalidateRect(contentRect);
487     layer->updateLayerRect(updater, contentRect, 0);
488
489     // Empty layers don't have tiles.
490     EXPECT_EQ(0u, layer->numPaintedTiles());
491
492     // Empty layers don't need prepaint.
493     EXPECT_FALSE(layer->needsIdlePaint(contentRect));
494
495     layer->pushPropertiesTo(layerImpl.get());
496
497     // Empty layers don't have tiles.
498     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
499
500     // Non-visible layers don't idle paint.
501     layer->idleUpdateLayerRect(updater, contentRect, 0);
502
503     // Empty layers don't have tiles.
504     EXPECT_EQ(0u, layer->numPaintedTiles());
505
506     layer->pushPropertiesTo(layerImpl.get());
507
508     // Empty layers don't have tiles.
509     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
510 }
511
512 TEST(TiledLayerChromiumTest, idlePaintZeroSizedAnimatingLayer)
513 {
514     OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
515     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
516     DebugScopedSetImplThread implThread;
517     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
518
519     CCTextureUpdater updater;
520
521     // Pretend the layer is animating.
522     layer->setDrawTransformIsAnimating(true);
523
524     // The layer's bounds are empty.
525     IntRect contentRect;
526
527     layer->setBounds(contentRect.size());
528     layer->setVisibleLayerRect(contentRect);
529     layer->invalidateRect(contentRect);
530     layer->updateLayerRect(updater, contentRect, 0);
531
532     // Empty layers don't have tiles.
533     EXPECT_EQ(0u, layer->numPaintedTiles());
534
535     // Empty layers don't need prepaint.
536     EXPECT_FALSE(layer->needsIdlePaint(contentRect));
537
538     layer->pushPropertiesTo(layerImpl.get());
539
540     // Empty layers don't have tiles.
541     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
542
543     // Non-visible layers don't idle paint.
544     layer->idleUpdateLayerRect(updater, contentRect, 0);
545
546     // Empty layers don't have tiles.
547     EXPECT_EQ(0u, layer->numPaintedTiles());
548
549     layer->pushPropertiesTo(layerImpl.get());
550
551     // Empty layers don't have tiles.
552     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
553 }
554
555 TEST(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
556 {
557     IntSize contentBounds(100, 100);
558     IntRect contentRect(IntPoint::zero(), contentBounds);
559
560     OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
561     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
562     DebugScopedSetImplThread implThread;
563     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
564
565     CCTextureUpdater updater;
566
567     // Invalidate the layer but make none of it visible, so nothing paints.
568     IntRect visibleRect;
569
570     layer->setBounds(contentBounds);
571     layer->setVisibleLayerRect(visibleRect);
572     layer->invalidateRect(contentRect);
573     layer->updateLayerRect(updater, visibleRect, 0);
574
575     // Non-visible layers don't need idle paint.
576     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
577
578     layer->pushPropertiesTo(layerImpl.get());
579
580     // We should not have any tiles pushed since the layer is not visible.
581     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
582
583     // Non-visible layers don't idle paint.
584     layer->idleUpdateLayerRect(updater, visibleRect, 0);
585
586     layer->pushPropertiesTo(layerImpl.get());
587
588     // We should not have any tiles pushed since the layer is not visible.
589     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
590 }
591
592 static void idlePaintRepeat(int repeatTimes, FakeTiledLayerChromium* layer, FakeCCTiledLayerImpl* layerImpl, CCTextureUpdater& updater, const IntRect& visibleRect)
593 {
594     for (int i = 0; i < repeatTimes; ++i) {
595         layer->updateLayerRect(updater, visibleRect, 0);
596         layer->idleUpdateLayerRect(updater, visibleRect, 0);
597         layer->pushPropertiesTo(layerImpl);
598     }
599 }
600
601 static void testHaveOuterTiles(FakeCCTiledLayerImpl* layerImpl, int width, int height, int have)
602 {
603     for (int i = 0; i < width; ++i) {
604         for (int j = 0; j < height; ++j) {
605             bool hasTile = i < have || j < have || i >= width - have || j >= height - have;
606             EXPECT_EQ(hasTile, layerImpl->hasTileAt(i, j));
607         }
608     }
609 }
610
611 TEST(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers)
612 {
613     OwnPtr<TextureManager> textureManager = TextureManager::create(8000*8000*8, 8000*8000*4, 1024);
614     DebugScopedSetImplThread implThread;
615
616     CCTextureUpdater updater;
617
618     int tileWidth = FakeTiledLayerChromium::tileSize().width();
619     int tileHeight = FakeTiledLayerChromium::tileSize().height();
620     int width[] = { 1, 2, 3, 4, 9, 10, 0 };
621     int height[] = { 1, 2, 3, 4, 9, 10, 0 };
622
623     for (int j = 0; height[j]; ++j) {
624         for (int i = 0; width[i]; ++i) {
625             RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
626             OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
627
628             // Pretend the layer is animating.
629             layer->setDrawTransformIsAnimating(true);
630
631             IntSize contentBounds(width[i] * tileWidth, height[j] * tileHeight);
632             IntRect contentRect(IntPoint::zero(), contentBounds);
633             IntRect visibleRect;
634
635             layer->setBounds(contentBounds);
636             layer->setVisibleLayerRect(visibleRect);
637             layer->invalidateRect(contentRect);
638
639             // If idlePaintRect gives back a non-empty result then we should paint it. Otherwise,
640             // we shoud paint nothing.
641             bool shouldPrepaint = !layer->idlePaintRect(visibleRect).isEmpty();
642
643             // This paints the layer but there's nothing visible so it's a no-op.
644             layer->updateLayerRect(updater, visibleRect, 0);
645             layer->pushPropertiesTo(layerImpl.get());
646
647             // We should not have any tiles pushed yet since the layer is not visible and we've not prepainted.
648             testHaveOuterTiles(layerImpl.get(), width[i], height[j], 0);
649
650             // Normally we don't allow non-visible layers to pre-paint, but if they are animating then we should.
651             EXPECT_EQ(shouldPrepaint, layer->needsIdlePaint(visibleRect));
652
653             // If the layer is to be prepainted at all, then after four updates we should have the outer row/columns painted.
654             idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect);
655             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
656
657             // We don't currently idle paint past the outermost tiles.
658             EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
659             idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect);
660             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
661         }
662     }
663 }
664
665 TEST(TiledLayerChromiumTest, invalidateFromPrepare)
666 {
667     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
668     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
669     DebugScopedSetImplThread implThread;
670     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
671
672     CCTextureUpdater updater;
673     FakeTextureAllocator fakeAllocator;
674     FakeTextureCopier fakeCopier;
675     FakeTextureUploader fakeUploader;
676     RefPtr<GraphicsContext3D> context = createCompositorMockGraphicsContext3D(GraphicsContext3D::Attributes());
677     RefPtr<CCGraphicsContext> ccContext = CCGraphicsContext::create3D(context);
678
679     // The tile size is 100x100, so this invalidates and then paints two tiles.
680     layer->setBounds(IntSize(100, 200));
681     layer->invalidateRect(IntRect(0, 0, 100, 200));
682     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
683     updater.update(ccContext.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
684     layer->pushPropertiesTo(layerImpl.get());
685
686     // We should have both tiles on the impl side.
687     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
688     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
689
690     textureManager->unprotectAllTextures();
691
692     layer->fakeLayerTextureUpdater()->clearPrepareCount();
693     // Invoke updateLayerRect again. As the layer is valid updateLayerRect shouldn't be invoked on
694     // the LayerTextureUpdater.
695     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
696     updater.update(ccContext.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
697     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareCount());
698
699     layer->invalidateRect(IntRect(0, 0, 50, 50));
700     // setRectToInvalidate triggers invalidateRect() being invoked from updateLayerRect.
701     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(25, 25, 50, 50), layer.get());
702     layer->fakeLayerTextureUpdater()->clearPrepareCount();
703     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
704     updater.update(ccContext.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
705     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
706     layer->fakeLayerTextureUpdater()->clearPrepareCount();
707     // The layer should still be invalid as updateLayerRect invoked invalidate.
708     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
709     updater.update(ccContext.get(), &fakeAllocator, &fakeCopier, &fakeUploader, 1000);
710     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
711 }
712
713 TEST(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
714 {
715     // The updateRect (that indicates what was actually painted) should be in
716     // layer space, not the content space.
717
718     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
719     RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get()));
720
721     CCTextureUpdater updater;
722
723     IntRect layerBounds(0, 0, 300, 200);
724     IntRect contentBounds(0, 0, 200, 250);
725
726     layer->setBounds(layerBounds.size());
727     layer->setContentBounds(contentBounds.size());
728     layer->setVisibleLayerRect(contentBounds);
729
730     // On first update, the updateRect includes all tiles, even beyond the boundaries of the layer.
731     // However, it should still be in layer space, not content space.
732     layer->invalidateRect(contentBounds);
733     layer->updateLayerRect(updater, contentBounds, 0);
734     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 300, 300 * 0.8), layer->updateRect());
735
736     // After the tiles are updated once, another invalidate only needs to update the bounds of the layer.
737     layer->invalidateRect(contentBounds);
738     layer->updateLayerRect(updater, contentBounds, 0);
739     EXPECT_FLOAT_RECT_EQ(FloatRect(layerBounds), layer->updateRect());
740
741     // Partial re-paint should also be represented by the updateRect in layer space, not content space.
742     IntRect partialDamage(30, 100, 10, 10);
743     layer->invalidateRect(partialDamage);
744     layer->updateLayerRect(updater, contentBounds, 0);
745     EXPECT_FLOAT_RECT_EQ(FloatRect(45, 80, 15, 8), layer->updateRect());
746 }
747
748 TEST(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
749 {
750     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
751     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
752     DebugScopedSetImplThread implThread;
753     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
754
755     CCTextureUpdater updater;
756
757     // Create a layer with one tile.
758     layer->setBounds(IntSize(100, 100));
759
760     // Invalidate the entire layer.
761     layer->setNeedsDisplay();
762     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
763
764     // Push the tiles to the impl side and check that there is exactly one.
765     layer->updateLayerRect(updater, IntRect(0, 0, 100, 100), 0);
766     layer->pushPropertiesTo(layerImpl.get());
767     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
768     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
769     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
770     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
771
772     // Change the contents scale and verify that the content rectangle requiring painting
773     // is not scaled.
774     layer->setContentsScale(2);
775     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
776
777     // The impl side should get 2x2 tiles now.
778     layer->updateLayerRect(updater, IntRect(0, 0, 200, 200), 0);
779     layer->pushPropertiesTo(layerImpl.get());
780     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
781     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
782     EXPECT_TRUE(layerImpl->hasTileAt(1, 0));
783     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
784
785     // Invalidate the entire layer again, but do not paint. All tiles should be gone now from the
786     // impl side.
787     layer->setNeedsDisplay();
788     layer->updateLayerRect(updater, IntRect(1, 0, 0, 1), 0);
789     layer->pushPropertiesTo(layerImpl.get());
790     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
791     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
792     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
793     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
794 }
795
796 TEST(TiledLayerChromiumTest, skipsDrawGetsReset)
797 {
798     // Initialize without threading support.
799     WebKit::WebCompositor::initialize(0);
800     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
801     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, CCLayerTreeSettings());
802     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
803
804     // Create two 300 x 300 tiled layers.
805     IntSize contentBounds(300, 300);
806     IntRect contentRect(IntPoint::zero(), contentBounds);
807
808     // We have enough memory for only one of the two layers.
809     int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
810     OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit, memoryLimit);
811
812     RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
813     RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
814     rootLayer->addChild(childLayer);
815
816     rootLayer->setBounds(contentBounds);
817     rootLayer->setPosition(FloatPoint(150, 150));
818     childLayer->setBounds(contentBounds);
819     childLayer->setPosition(FloatPoint(150, 150));
820     rootLayer->invalidateRect(contentRect);
821     childLayer->invalidateRect(contentRect);
822
823     CCTextureUpdater updater;
824
825     ccLayerTreeHost->setRootLayer(rootLayer);
826     ccLayerTreeHost->setViewportSize(IntSize(300, 300));
827     textureManager->setMaxMemoryLimitBytes(memoryLimit);
828     ccLayerTreeHost->updateLayers(updater);
829
830     // We'll skip the root layer.
831     EXPECT_TRUE(rootLayer->skipsDraw());
832     EXPECT_FALSE(childLayer->skipsDraw());
833
834     ccLayerTreeHost->commitComplete();
835     textureManager->unprotectAllTextures(); // CCLayerTreeHost::commitComplete() normally does this, but since we're mocking out the manager we have to do it.
836
837     // Remove the child layer.
838     rootLayer->removeAllChildren();
839
840     ccLayerTreeHost->updateLayers(updater);
841     EXPECT_FALSE(rootLayer->skipsDraw());
842
843     ccLayerTreeHost->setRootLayer(0);
844     ccLayerTreeHost.clear();
845     WebKit::WebCompositor::shutdown();
846 }
847
848 TEST(TiledLayerChromiumTest, resizeToSmaller)
849 {
850     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
851     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
852     CCTextureUpdater updater;
853
854     layer->setBounds(IntSize(700, 700));
855     layer->invalidateRect(IntRect(0, 0, 700, 700));
856     layer->updateLayerRect(updater, IntRect(0, 0, 700, 700), 0);
857
858     layer->setBounds(IntSize(200, 200));
859     layer->invalidateRect(IntRect(0, 0, 200, 200));
860 }
861
862 TEST(TiledLayerChromiumTest, hugeLayerUpdateCrash)
863 {
864     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
865     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
866     CCTextureUpdater updater;
867
868     int size = 1 << 30;
869     layer->setBounds(IntSize(size, size));
870     layer->invalidateRect(IntRect(0, 0, size, size));
871
872     // Ensure no crash for bounds where size * size would overflow an int.
873     layer->updateLayerRect(updater, IntRect(0, 0, 700, 700), 0);
874 }
875
876 TEST(TiledLayerChromiumTest, partialUpdates)
877 {
878     // Initialize without threading support.
879     WebKit::WebCompositor::initialize(0);
880
881     CCLayerTreeSettings settings;
882     settings.maxPartialTextureUpdates = 4;
883
884     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
885     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
886     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
887
888     // Create one 500 x 300 tiled layer.
889     IntSize contentBounds(300, 200);
890     IntRect contentRect(IntPoint::zero(), contentBounds);
891
892     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
893     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
894     layer->setBounds(contentBounds);
895     layer->setPosition(FloatPoint(150, 150));
896     layer->invalidateRect(contentRect);
897
898     CCTextureUpdater updater;
899     FakeTextureAllocator allocator;
900     FakeTextureCopier copier;
901     FakeTextureUploader uploader;
902
903     ccLayerTreeHost->setRootLayer(layer);
904     ccLayerTreeHost->setViewportSize(IntSize(300, 200));
905
906     // Full update of all 6 tiles.
907     ccLayerTreeHost->updateLayers(updater);
908     {
909         DebugScopedSetImplThread implThread;
910         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
911         updater.update(0, &allocator, &copier, &uploader, 4);
912         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
913         EXPECT_TRUE(updater.hasMoreUpdates());
914         layer->fakeLayerTextureUpdater()->clearUpdateCount();
915         updater.update(0, &allocator, &copier, &uploader, 4);
916         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
917         EXPECT_FALSE(updater.hasMoreUpdates());
918         layer->fakeLayerTextureUpdater()->clearUpdateCount();
919         layer->pushPropertiesTo(layerImpl.get());
920     }
921     ccLayerTreeHost->commitComplete();
922
923     // Full update of 3 tiles and partial update of 3 tiles.
924     layer->invalidateRect(IntRect(0, 0, 300, 150));
925     ccLayerTreeHost->updateLayers(updater);
926     {
927         DebugScopedSetImplThread implThread;
928         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
929         updater.update(0, &allocator, &copier, &uploader, 4);
930         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
931         EXPECT_TRUE(updater.hasMoreUpdates());
932         layer->fakeLayerTextureUpdater()->clearUpdateCount();
933         updater.update(0, &allocator, &copier, &uploader, 4);
934         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
935         EXPECT_FALSE(updater.hasMoreUpdates());
936         layer->fakeLayerTextureUpdater()->clearUpdateCount();
937         layer->pushPropertiesTo(layerImpl.get());
938     }
939     ccLayerTreeHost->commitComplete();
940
941     // Partial update of 6 tiles.
942     layer->invalidateRect(IntRect(50, 50, 200, 100));
943     {
944         DebugScopedSetImplThread implThread;
945         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
946         ccLayerTreeHost->updateLayers(updater);
947         updater.update(0, &allocator, &copier, &uploader, 4);
948         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
949         EXPECT_TRUE(updater.hasMoreUpdates());
950         layer->fakeLayerTextureUpdater()->clearUpdateCount();
951         updater.update(0, &allocator, &copier, &uploader, 4);
952         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
953         EXPECT_FALSE(updater.hasMoreUpdates());
954         layer->fakeLayerTextureUpdater()->clearUpdateCount();
955         layer->pushPropertiesTo(layerImpl.get());
956     }
957     ccLayerTreeHost->commitComplete();
958
959     // Checkerboard all tiles.
960     layer->invalidateRect(IntRect(0, 0, 300, 200));
961     {
962         DebugScopedSetImplThread implThread;
963         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
964         layer->pushPropertiesTo(layerImpl.get());
965     }
966     ccLayerTreeHost->commitComplete();
967
968     // Partial update of 6 checkerboard tiles.
969     layer->invalidateRect(IntRect(50, 50, 200, 100));
970     {
971         DebugScopedSetImplThread implThread;
972         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
973         ccLayerTreeHost->updateLayers(updater);
974         updater.update(0, &allocator, &copier, &uploader, 4);
975         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
976         EXPECT_TRUE(updater.hasMoreUpdates());
977         layer->fakeLayerTextureUpdater()->clearUpdateCount();
978         updater.update(0, &allocator, &copier, &uploader, 4);
979         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
980         EXPECT_FALSE(updater.hasMoreUpdates());
981         layer->fakeLayerTextureUpdater()->clearUpdateCount();
982         layer->pushPropertiesTo(layerImpl.get());
983     }
984     ccLayerTreeHost->commitComplete();
985
986     // Partial update of 4 tiles.
987     layer->invalidateRect(IntRect(50, 50, 100, 100));
988     {
989         DebugScopedSetImplThread implThread;
990         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
991         ccLayerTreeHost->updateLayers(updater);
992         updater.update(0, &allocator, &copier, &uploader, 4);
993         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
994         EXPECT_FALSE(updater.hasMoreUpdates());
995         layer->fakeLayerTextureUpdater()->clearUpdateCount();
996         layer->pushPropertiesTo(layerImpl.get());
997     }
998     ccLayerTreeHost->commitComplete();
999
1000     ccLayerTreeHost->setRootLayer(0);
1001     ccLayerTreeHost.clear();
1002     WebKit::WebCompositor::shutdown();
1003 }
1004
1005 TEST(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
1006 {
1007     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1008     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1009     CCTextureUpdater updater;
1010
1011     // The tile size is 100x100, so this invalidates and then paints two tiles.
1012     layer->setBounds(IntSize(100, 200));
1013
1014     layer->invalidateRect(IntRect(0, 0, 100, 200));
1015     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
1016     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1017 }
1018
1019 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
1020 {
1021     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1022     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1023     TestCCOcclusionTracker occluded;
1024     CCTextureUpdater updater;
1025
1026     // The tile size is 100x100.
1027
1028     layer->setBounds(IntSize(600, 600));
1029     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1030
1031     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1032     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1033     layer->invalidateRect(IntRect(0, 0, 600, 600));
1034     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1035     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1036
1037     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1038     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1039     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1040
1041     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1042
1043     occluded.setOcclusion(IntRect(250, 200, 300, 100));
1044     layer->invalidateRect(IntRect(0, 0, 600, 600));
1045     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1046     EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1047
1048     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1049     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000, 1);
1050     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1051
1052     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1053
1054     occluded.setOcclusion(IntRect(250, 250, 300, 100));
1055     layer->invalidateRect(IntRect(0, 0, 600, 600));
1056     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1057     EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
1058
1059     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1060     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000 + 360000, 1);
1061     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1062 }
1063
1064 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
1065 {
1066     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1067     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1068     TestCCOcclusionTracker occluded;
1069     CCTextureUpdater updater;
1070
1071     // The tile size is 100x100.
1072
1073     layer->setBounds(IntSize(600, 600));
1074     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1075
1076     // The partially occluded tiles (by the 150 occlusion height) are visible beyond the occlusion, so not culled.
1077     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1078     layer->setVisibleLayerRect(IntRect(0, 0, 600, 360));
1079     layer->invalidateRect(IntRect(0, 0, 600, 600));
1080     layer->updateLayerRect(updater, IntRect(0, 0, 600, 360), &occluded);
1081     EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1082
1083     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1084     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000, 1);
1085     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1086
1087     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1088
1089     // Now the visible region stops at the edge of the occlusion so the partly visible tiles become fully occluded.
1090     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1091     layer->setVisibleLayerRect(IntRect(0, 0, 600, 350));
1092     layer->invalidateRect(IntRect(0, 0, 600, 600));
1093     layer->updateLayerRect(updater, IntRect(0, 0, 600, 350), &occluded);
1094     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1095
1096     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1097     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000, 1);
1098     EXPECT_EQ(3 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1099
1100     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1101
1102     // Now the visible region is even smaller than the occlusion, it should have the same result.
1103     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1104     layer->setVisibleLayerRect(IntRect(0, 0, 600, 340));
1105     layer->invalidateRect(IntRect(0, 0, 600, 600));
1106     layer->updateLayerRect(updater, IntRect(0, 0, 600, 340), &occluded);
1107     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1108
1109     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1110     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000 + 180000, 1);
1111     EXPECT_EQ(3 + 6 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1112
1113 }
1114
1115 TEST(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
1116 {
1117     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1118     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1119     TestCCOcclusionTracker occluded;
1120     CCTextureUpdater updater;
1121
1122     // The tile size is 100x100.
1123
1124     layer->setBounds(IntSize(600, 600));
1125     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1126
1127     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1128     layer->setVisibleLayerRect(IntRect(0, 0, 600, 600));
1129     layer->invalidateRect(IntRect(0, 0, 600, 600));
1130     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1131     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1132
1133     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1134     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1135     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1136
1137     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1138
1139     // Repaint without marking it dirty. The culled tiles remained dirty.
1140     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1141     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareRectCount());
1142
1143     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1144     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1145     EXPECT_EQ(6, occluded.overdrawMetrics().tilesCulledForUpload());
1146 }
1147
1148 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
1149 {
1150     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1151     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1152     TestCCOcclusionTracker occluded;
1153     CCTextureUpdater updater;
1154
1155     // The tile size is 100x100.
1156
1157     // This makes sure the painting works when the occluded region (in screen space)
1158     // is transformed differently than the layer.
1159     layer->setBounds(IntSize(600, 600));
1160     WebTransformationMatrix screenTransform;
1161     screenTransform.scale(0.5);
1162     layer->setScreenSpaceTransform(screenTransform);
1163     layer->setDrawTransform(screenTransform * WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1164
1165     occluded.setOcclusion(IntRect(100, 100, 150, 50));
1166     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1167     layer->invalidateRect(IntRect(0, 0, 600, 600));
1168     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1169     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1170
1171     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1172     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1173     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1174 }
1175
1176 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
1177 {
1178     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1179     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1180     TestCCOcclusionTracker occluded;
1181     CCTextureUpdater updater;
1182
1183     // The tile size is 100x100.
1184
1185     // This makes sure the painting works when the content space is scaled to
1186     // a different layer space. In this case tiles are scaled to be 200x200
1187     // pixels, which means none should be occluded.
1188     layer->setContentsScale(0.5);
1189     layer->setBounds(IntSize(600, 600));
1190     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1191
1192     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1193     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1194     layer->invalidateRect(IntRect(0, 0, 600, 600));
1195     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1196     // The content is half the size of the layer (so the number of tiles is fewer).
1197     // In this case, the content is 300x300, and since the tile size is 100, the
1198     // number of tiles 3x3.
1199     EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
1200
1201     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1202     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000, 1);
1203     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1204
1205     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1206
1207     // This makes sure the painting works when the content space is scaled to
1208     // a different layer space. In this case the occluded region catches the
1209     // blown up tiles.
1210     occluded.setOcclusion(IntRect(200, 200, 300, 200));
1211     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1212     layer->invalidateRect(IntRect(0, 0, 600, 600));
1213     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1214     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1215
1216     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1217     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000, 1);
1218     EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
1219
1220     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1221
1222     // This makes sure content scaling and transforms work together.
1223     WebTransformationMatrix screenTransform;
1224     screenTransform.scale(0.5);
1225     layer->setScreenSpaceTransform(screenTransform);
1226     layer->setDrawTransform(screenTransform * WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1227
1228     occluded.setOcclusion(IntRect(100, 100, 150, 100));
1229     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1230     layer->invalidateRect(IntRect(0, 0, 600, 600));
1231     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1232     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1233
1234     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1235     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000 + 80000, 1);
1236     EXPECT_EQ(1 + 1, occluded.overdrawMetrics().tilesCulledForUpload());
1237 }
1238
1239 TEST(TiledLayerChromiumTest, visibleContentOpaqueRegion)
1240 {
1241     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1242     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1243     TestCCOcclusionTracker occluded;
1244     CCTextureUpdater updater;
1245
1246     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1247
1248     IntRect opaquePaintRect;
1249     Region opaqueContents;
1250
1251     IntRect contentBounds = IntRect(0, 0, 100, 200);
1252     IntRect visibleBounds = IntRect(0, 0, 100, 150);
1253
1254     layer->setBounds(contentBounds.size());
1255     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1256     layer->setVisibleLayerRect(visibleBounds);
1257     layer->setDrawOpacity(1);
1258
1259     // If the layer doesn't paint opaque content, then the visibleContentOpaqueRegion should be empty.
1260     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1261     layer->invalidateRect(contentBounds);
1262     layer->updateLayerRect(updater, contentBounds, &occluded);
1263     opaqueContents = layer->visibleContentOpaqueRegion();
1264     EXPECT_TRUE(opaqueContents.isEmpty());
1265
1266     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
1267     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1268     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
1269     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1270
1271     // visibleContentOpaqueRegion should match the visible part of what is painted opaque.
1272     opaquePaintRect = IntRect(10, 10, 90, 190);
1273     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
1274     layer->invalidateRect(contentBounds);
1275     layer->updateLayerRect(updater, contentBounds, &occluded);
1276     opaqueContents = layer->visibleContentOpaqueRegion();
1277     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1278     EXPECT_EQ(1u, opaqueContents.rects().size());
1279
1280     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1281     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1282     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1283     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1284
1285     // If we paint again without invalidating, the same stuff should be opaque.
1286     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1287     layer->updateLayerRect(updater, contentBounds, &occluded);
1288     opaqueContents = layer->visibleContentOpaqueRegion();
1289     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1290     EXPECT_EQ(1u, opaqueContents.rects().size());
1291
1292     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1293     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1294     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1295     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1296
1297     // If we repaint a non-opaque part of the tile, then it shouldn't lose its opaque-ness. And other tiles should
1298     // not be affected.
1299     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1300     layer->invalidateRect(IntRect(0, 0, 1, 1));
1301     layer->updateLayerRect(updater, contentBounds, &occluded);
1302     opaqueContents = layer->visibleContentOpaqueRegion();
1303     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1304     EXPECT_EQ(1u, opaqueContents.rects().size());
1305
1306     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
1307     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1308     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1, 1);
1309     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1310
1311     // If we repaint an opaque part of the tile, then it should lose its opaque-ness. But other tiles should still
1312     // not be affected.
1313     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1314     layer->invalidateRect(IntRect(10, 10, 1, 1));
1315     layer->updateLayerRect(updater, contentBounds, &occluded);
1316     opaqueContents = layer->visibleContentOpaqueRegion();
1317     EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
1318     EXPECT_EQ(1u, opaqueContents.rects().size());
1319
1320     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1321     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1322     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1323     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1324
1325     // No metrics are recorded in prepaint, so the values should not change from above.
1326     layer->idleUpdateLayerRect(updater, contentBounds, &occluded);
1327     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1328     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1329     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1330     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1331 }
1332
1333 TEST(TiledLayerChromiumTest, pixelsPaintedMetrics)
1334 {
1335     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1336     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1337     TestCCOcclusionTracker occluded;
1338     CCTextureUpdater updater;
1339
1340     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1341
1342     IntRect opaquePaintRect;
1343     Region opaqueContents;
1344
1345     IntRect contentBounds = IntRect(0, 0, 100, 300);
1346     IntRect visibleBounds = IntRect(0, 0, 100, 300);
1347
1348     layer->setBounds(contentBounds.size());
1349     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1350     layer->setVisibleLayerRect(visibleBounds);
1351     layer->setDrawOpacity(1);
1352
1353     // Invalidates and paints the whole layer.
1354     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1355     layer->invalidateRect(contentBounds);
1356     layer->updateLayerRect(updater, contentBounds, &occluded);
1357     opaqueContents = layer->visibleContentOpaqueRegion();
1358     EXPECT_TRUE(opaqueContents.isEmpty());
1359
1360     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
1361     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1362     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000, 1);
1363     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1364
1365     // Invalidates an area on the top and bottom tile, which will cause us to paint the tile in the middle,
1366     // even though it is not dirty and will not be uploaded.
1367     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1368     layer->invalidateRect(IntRect(0, 0, 1, 1));
1369     layer->invalidateRect(IntRect(50, 200, 10, 10));
1370     layer->updateLayerRect(updater, contentBounds, &occluded);
1371     opaqueContents = layer->visibleContentOpaqueRegion();
1372     EXPECT_TRUE(opaqueContents.isEmpty());
1373
1374     // The middle tile was painted even though not invalidated.
1375     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1);
1376     // The pixels uploaded will not include the non-invalidated tile in the middle.
1377     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1378     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000 + 1 + 100, 1);
1379     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1380 }
1381
1382 } // namespace