[chromium] LayerRendererChromium is not getting visibility messages in single threade...
[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     ccLayerTreeHost->updateLayers(updater, memoryLimit);
828
829     // We'll skip the root layer.
830     EXPECT_TRUE(rootLayer->skipsDraw());
831     EXPECT_FALSE(childLayer->skipsDraw());
832
833     ccLayerTreeHost->commitComplete();
834     textureManager->unprotectAllTextures(); // CCLayerTreeHost::commitComplete() normally does this, but since we're mocking out the manager we have to do it.
835
836     // Remove the child layer.
837     rootLayer->removeAllChildren();
838
839     ccLayerTreeHost->updateLayers(updater, memoryLimit);
840     EXPECT_FALSE(rootLayer->skipsDraw());
841
842     ccLayerTreeHost->setRootLayer(0);
843     ccLayerTreeHost.clear();
844     WebKit::WebCompositor::shutdown();
845 }
846
847 TEST(TiledLayerChromiumTest, resizeToSmaller)
848 {
849     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
850     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
851     CCTextureUpdater updater;
852
853     layer->setBounds(IntSize(700, 700));
854     layer->invalidateRect(IntRect(0, 0, 700, 700));
855     layer->updateLayerRect(updater, IntRect(0, 0, 700, 700), 0);
856
857     layer->setBounds(IntSize(200, 200));
858     layer->invalidateRect(IntRect(0, 0, 200, 200));
859 }
860
861 TEST(TiledLayerChromiumTest, hugeLayerUpdateCrash)
862 {
863     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
864     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
865     CCTextureUpdater updater;
866
867     int size = 1 << 30;
868     layer->setBounds(IntSize(size, size));
869     layer->invalidateRect(IntRect(0, 0, size, size));
870
871     // Ensure no crash for bounds where size * size would overflow an int.
872     layer->updateLayerRect(updater, IntRect(0, 0, 700, 700), 0);
873 }
874
875 TEST(TiledLayerChromiumTest, partialUpdates)
876 {
877     // Initialize without threading support.
878     WebKit::WebCompositor::initialize(0);
879
880     CCLayerTreeSettings settings;
881     settings.maxPartialTextureUpdates = 4;
882
883     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
884     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
885     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
886
887     // Create one 500 x 300 tiled layer.
888     IntSize contentBounds(300, 200);
889     IntRect contentRect(IntPoint::zero(), contentBounds);
890
891     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
892     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
893     layer->setBounds(contentBounds);
894     layer->setPosition(FloatPoint(150, 150));
895     layer->invalidateRect(contentRect);
896
897     CCTextureUpdater updater;
898     FakeTextureAllocator allocator;
899     FakeTextureCopier copier;
900     FakeTextureUploader uploader;
901
902     ccLayerTreeHost->setRootLayer(layer);
903     ccLayerTreeHost->setViewportSize(IntSize(300, 200));
904
905     // Full update of all 6 tiles.
906     ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
907     {
908         DebugScopedSetImplThread implThread;
909         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
910         updater.update(0, &allocator, &copier, &uploader, 4);
911         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
912         EXPECT_TRUE(updater.hasMoreUpdates());
913         layer->fakeLayerTextureUpdater()->clearUpdateCount();
914         updater.update(0, &allocator, &copier, &uploader, 4);
915         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
916         EXPECT_FALSE(updater.hasMoreUpdates());
917         layer->fakeLayerTextureUpdater()->clearUpdateCount();
918         layer->pushPropertiesTo(layerImpl.get());
919     }
920     ccLayerTreeHost->commitComplete();
921
922     // Full update of 3 tiles and partial update of 3 tiles.
923     layer->invalidateRect(IntRect(0, 0, 300, 150));
924     ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
925     {
926         DebugScopedSetImplThread implThread;
927         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
928         updater.update(0, &allocator, &copier, &uploader, 4);
929         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
930         EXPECT_TRUE(updater.hasMoreUpdates());
931         layer->fakeLayerTextureUpdater()->clearUpdateCount();
932         updater.update(0, &allocator, &copier, &uploader, 4);
933         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
934         EXPECT_FALSE(updater.hasMoreUpdates());
935         layer->fakeLayerTextureUpdater()->clearUpdateCount();
936         layer->pushPropertiesTo(layerImpl.get());
937     }
938     ccLayerTreeHost->commitComplete();
939
940     // Partial update of 6 tiles.
941     layer->invalidateRect(IntRect(50, 50, 200, 100));
942     {
943         DebugScopedSetImplThread implThread;
944         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
945         ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
946         updater.update(0, &allocator, &copier, &uploader, 4);
947         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
948         EXPECT_TRUE(updater.hasMoreUpdates());
949         layer->fakeLayerTextureUpdater()->clearUpdateCount();
950         updater.update(0, &allocator, &copier, &uploader, 4);
951         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
952         EXPECT_FALSE(updater.hasMoreUpdates());
953         layer->fakeLayerTextureUpdater()->clearUpdateCount();
954         layer->pushPropertiesTo(layerImpl.get());
955     }
956     ccLayerTreeHost->commitComplete();
957
958     // Checkerboard all tiles.
959     layer->invalidateRect(IntRect(0, 0, 300, 200));
960     {
961         DebugScopedSetImplThread implThread;
962         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
963         layer->pushPropertiesTo(layerImpl.get());
964     }
965     ccLayerTreeHost->commitComplete();
966
967     // Partial update of 6 checkerboard tiles.
968     layer->invalidateRect(IntRect(50, 50, 200, 100));
969     {
970         DebugScopedSetImplThread implThread;
971         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
972         ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
973         updater.update(0, &allocator, &copier, &uploader, 4);
974         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
975         EXPECT_TRUE(updater.hasMoreUpdates());
976         layer->fakeLayerTextureUpdater()->clearUpdateCount();
977         updater.update(0, &allocator, &copier, &uploader, 4);
978         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
979         EXPECT_FALSE(updater.hasMoreUpdates());
980         layer->fakeLayerTextureUpdater()->clearUpdateCount();
981         layer->pushPropertiesTo(layerImpl.get());
982     }
983     ccLayerTreeHost->commitComplete();
984
985     // Partial update of 4 tiles.
986     layer->invalidateRect(IntRect(50, 50, 100, 100));
987     {
988         DebugScopedSetImplThread implThread;
989         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
990         ccLayerTreeHost->updateLayers(updater, std::numeric_limits<size_t>::max());
991         updater.update(0, &allocator, &copier, &uploader, 4);
992         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
993         EXPECT_FALSE(updater.hasMoreUpdates());
994         layer->fakeLayerTextureUpdater()->clearUpdateCount();
995         layer->pushPropertiesTo(layerImpl.get());
996     }
997     ccLayerTreeHost->commitComplete();
998
999     ccLayerTreeHost->setRootLayer(0);
1000     ccLayerTreeHost.clear();
1001     WebKit::WebCompositor::shutdown();
1002 }
1003
1004 TEST(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
1005 {
1006     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1007     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1008     CCTextureUpdater updater;
1009
1010     // The tile size is 100x100, so this invalidates and then paints two tiles.
1011     layer->setBounds(IntSize(100, 200));
1012
1013     layer->invalidateRect(IntRect(0, 0, 100, 200));
1014     layer->updateLayerRect(updater, IntRect(0, 0, 100, 200), 0);
1015     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1016 }
1017
1018 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
1019 {
1020     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1021     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1022     TestCCOcclusionTracker occluded;
1023     CCTextureUpdater updater;
1024
1025     // The tile size is 100x100.
1026
1027     layer->setBounds(IntSize(600, 600));
1028     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1029
1030     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1031     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1032     layer->invalidateRect(IntRect(0, 0, 600, 600));
1033     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1034     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1035
1036     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1037     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1038     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1039
1040     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1041
1042     occluded.setOcclusion(IntRect(250, 200, 300, 100));
1043     layer->invalidateRect(IntRect(0, 0, 600, 600));
1044     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1045     EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1046
1047     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1048     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000, 1);
1049     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1050
1051     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1052
1053     occluded.setOcclusion(IntRect(250, 250, 300, 100));
1054     layer->invalidateRect(IntRect(0, 0, 600, 600));
1055     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1056     EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
1057
1058     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1059     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000 + 360000, 1);
1060     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1061 }
1062
1063 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
1064 {
1065     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1066     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1067     TestCCOcclusionTracker occluded;
1068     CCTextureUpdater updater;
1069
1070     // The tile size is 100x100.
1071
1072     layer->setBounds(IntSize(600, 600));
1073     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1074
1075     // The partially occluded tiles (by the 150 occlusion height) are visible beyond the occlusion, so not culled.
1076     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1077     layer->setVisibleLayerRect(IntRect(0, 0, 600, 360));
1078     layer->invalidateRect(IntRect(0, 0, 600, 600));
1079     layer->updateLayerRect(updater, IntRect(0, 0, 600, 360), &occluded);
1080     EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1081
1082     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1083     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000, 1);
1084     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1085
1086     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1087
1088     // Now the visible region stops at the edge of the occlusion so the partly visible tiles become fully occluded.
1089     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1090     layer->setVisibleLayerRect(IntRect(0, 0, 600, 350));
1091     layer->invalidateRect(IntRect(0, 0, 600, 600));
1092     layer->updateLayerRect(updater, IntRect(0, 0, 600, 350), &occluded);
1093     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1094
1095     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1096     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000, 1);
1097     EXPECT_EQ(3 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1098
1099     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1100
1101     // Now the visible region is even smaller than the occlusion, it should have the same result.
1102     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1103     layer->setVisibleLayerRect(IntRect(0, 0, 600, 340));
1104     layer->invalidateRect(IntRect(0, 0, 600, 600));
1105     layer->updateLayerRect(updater, IntRect(0, 0, 600, 340), &occluded);
1106     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1107
1108     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1109     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000 + 180000, 1);
1110     EXPECT_EQ(3 + 6 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1111
1112 }
1113
1114 TEST(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
1115 {
1116     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1117     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1118     TestCCOcclusionTracker occluded;
1119     CCTextureUpdater updater;
1120
1121     // The tile size is 100x100.
1122
1123     layer->setBounds(IntSize(600, 600));
1124     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1125
1126     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1127     layer->setVisibleLayerRect(IntRect(0, 0, 600, 600));
1128     layer->invalidateRect(IntRect(0, 0, 600, 600));
1129     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1130     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1131
1132     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1133     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1134     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1135
1136     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1137
1138     // Repaint without marking it dirty. The culled tiles remained dirty.
1139     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1140     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareRectCount());
1141
1142     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1143     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1144     EXPECT_EQ(6, occluded.overdrawMetrics().tilesCulledForUpload());
1145 }
1146
1147 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
1148 {
1149     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1150     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1151     TestCCOcclusionTracker occluded;
1152     CCTextureUpdater updater;
1153
1154     // The tile size is 100x100.
1155
1156     // This makes sure the painting works when the occluded region (in screen space)
1157     // is transformed differently than the layer.
1158     layer->setBounds(IntSize(600, 600));
1159     WebTransformationMatrix screenTransform;
1160     screenTransform.scale(0.5);
1161     layer->setScreenSpaceTransform(screenTransform);
1162     layer->setDrawTransform(screenTransform * WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1163
1164     occluded.setOcclusion(IntRect(100, 100, 150, 50));
1165     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1166     layer->invalidateRect(IntRect(0, 0, 600, 600));
1167     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1168     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1169
1170     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1171     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1172     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1173 }
1174
1175 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
1176 {
1177     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1178     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1179     TestCCOcclusionTracker occluded;
1180     CCTextureUpdater updater;
1181
1182     // The tile size is 100x100.
1183
1184     // This makes sure the painting works when the content space is scaled to
1185     // a different layer space. In this case tiles are scaled to be 200x200
1186     // pixels, which means none should be occluded.
1187     layer->setContentsScale(0.5);
1188     layer->setBounds(IntSize(600, 600));
1189     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1190
1191     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1192     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1193     layer->invalidateRect(IntRect(0, 0, 600, 600));
1194     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1195     // The content is half the size of the layer (so the number of tiles is fewer).
1196     // In this case, the content is 300x300, and since the tile size is 100, the
1197     // number of tiles 3x3.
1198     EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
1199
1200     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1201     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000, 1);
1202     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1203
1204     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1205
1206     // This makes sure the painting works when the content space is scaled to
1207     // a different layer space. In this case the occluded region catches the
1208     // blown up tiles.
1209     occluded.setOcclusion(IntRect(200, 200, 300, 200));
1210     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1211     layer->invalidateRect(IntRect(0, 0, 600, 600));
1212     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1213     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1214
1215     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1216     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000, 1);
1217     EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
1218
1219     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1220
1221     // This makes sure content scaling and transforms work together.
1222     WebTransformationMatrix screenTransform;
1223     screenTransform.scale(0.5);
1224     layer->setScreenSpaceTransform(screenTransform);
1225     layer->setDrawTransform(screenTransform * WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1226
1227     occluded.setOcclusion(IntRect(100, 100, 150, 100));
1228     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1229     layer->invalidateRect(IntRect(0, 0, 600, 600));
1230     layer->updateLayerRect(updater, IntRect(0, 0, 600, 600), &occluded);
1231     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1232
1233     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1234     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000 + 80000, 1);
1235     EXPECT_EQ(1 + 1, occluded.overdrawMetrics().tilesCulledForUpload());
1236 }
1237
1238 TEST(TiledLayerChromiumTest, visibleContentOpaqueRegion)
1239 {
1240     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1241     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1242     TestCCOcclusionTracker occluded;
1243     CCTextureUpdater updater;
1244
1245     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1246
1247     IntRect opaquePaintRect;
1248     Region opaqueContents;
1249
1250     IntRect contentBounds = IntRect(0, 0, 100, 200);
1251     IntRect visibleBounds = IntRect(0, 0, 100, 150);
1252
1253     layer->setBounds(contentBounds.size());
1254     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1255     layer->setVisibleLayerRect(visibleBounds);
1256     layer->setDrawOpacity(1);
1257
1258     // If the layer doesn't paint opaque content, then the visibleContentOpaqueRegion should be empty.
1259     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1260     layer->invalidateRect(contentBounds);
1261     layer->updateLayerRect(updater, contentBounds, &occluded);
1262     opaqueContents = layer->visibleContentOpaqueRegion();
1263     EXPECT_TRUE(opaqueContents.isEmpty());
1264
1265     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
1266     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1267     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
1268     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1269
1270     // visibleContentOpaqueRegion should match the visible part of what is painted opaque.
1271     opaquePaintRect = IntRect(10, 10, 90, 190);
1272     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
1273     layer->invalidateRect(contentBounds);
1274     layer->updateLayerRect(updater, contentBounds, &occluded);
1275     opaqueContents = layer->visibleContentOpaqueRegion();
1276     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1277     EXPECT_EQ(1u, opaqueContents.rects().size());
1278
1279     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1280     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1281     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1282     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1283
1284     // If we paint again without invalidating, the same stuff should be opaque.
1285     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1286     layer->updateLayerRect(updater, contentBounds, &occluded);
1287     opaqueContents = layer->visibleContentOpaqueRegion();
1288     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1289     EXPECT_EQ(1u, opaqueContents.rects().size());
1290
1291     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1292     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1293     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1294     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1295
1296     // If we repaint a non-opaque part of the tile, then it shouldn't lose its opaque-ness. And other tiles should
1297     // not be affected.
1298     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1299     layer->invalidateRect(IntRect(0, 0, 1, 1));
1300     layer->updateLayerRect(updater, contentBounds, &occluded);
1301     opaqueContents = layer->visibleContentOpaqueRegion();
1302     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1303     EXPECT_EQ(1u, opaqueContents.rects().size());
1304
1305     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
1306     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1307     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1, 1);
1308     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1309
1310     // If we repaint an opaque part of the tile, then it should lose its opaque-ness. But other tiles should still
1311     // not be affected.
1312     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1313     layer->invalidateRect(IntRect(10, 10, 1, 1));
1314     layer->updateLayerRect(updater, contentBounds, &occluded);
1315     opaqueContents = layer->visibleContentOpaqueRegion();
1316     EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
1317     EXPECT_EQ(1u, opaqueContents.rects().size());
1318
1319     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1320     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1321     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1322     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1323
1324     // No metrics are recorded in prepaint, so the values should not change from above.
1325     layer->idleUpdateLayerRect(updater, contentBounds, &occluded);
1326     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1327     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1328     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1329     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1330 }
1331
1332 TEST(TiledLayerChromiumTest, pixelsPaintedMetrics)
1333 {
1334     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1335     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1336     TestCCOcclusionTracker occluded;
1337     CCTextureUpdater updater;
1338
1339     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1340
1341     IntRect opaquePaintRect;
1342     Region opaqueContents;
1343
1344     IntRect contentBounds = IntRect(0, 0, 100, 300);
1345     IntRect visibleBounds = IntRect(0, 0, 100, 300);
1346
1347     layer->setBounds(contentBounds.size());
1348     layer->setDrawTransform(WebTransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1349     layer->setVisibleLayerRect(visibleBounds);
1350     layer->setDrawOpacity(1);
1351
1352     // Invalidates and paints the whole layer.
1353     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1354     layer->invalidateRect(contentBounds);
1355     layer->updateLayerRect(updater, contentBounds, &occluded);
1356     opaqueContents = layer->visibleContentOpaqueRegion();
1357     EXPECT_TRUE(opaqueContents.isEmpty());
1358
1359     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
1360     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1361     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000, 1);
1362     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1363
1364     // Invalidates an area on the top and bottom tile, which will cause us to paint the tile in the middle,
1365     // even though it is not dirty and will not be uploaded.
1366     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1367     layer->invalidateRect(IntRect(0, 0, 1, 1));
1368     layer->invalidateRect(IntRect(50, 200, 10, 10));
1369     layer->updateLayerRect(updater, contentBounds, &occluded);
1370     opaqueContents = layer->visibleContentOpaqueRegion();
1371     EXPECT_TRUE(opaqueContents.isEmpty());
1372
1373     // The middle tile was painted even though not invalidated.
1374     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1);
1375     // The pixels uploaded will not include the non-invalidated tile in the middle.
1376     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1377     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000 + 1 + 100, 1);
1378     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1379 }
1380
1381 } // namespace