[chromium] Clean up includes in compositor unit tests
[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 "BitmapCanvasLayerTextureUpdater.h"
30 #include "CCAnimationTestCommon.h"
31 #include "CCLayerTreeTestCommon.h"
32 #include "CCTiledLayerTestCommon.h"
33 #include "FakeCCGraphicsContext.h"
34 #include "FakeCCLayerTreeHostClient.h"
35 #include "LayerPainterChromium.h"
36 #include "cc/CCOverdrawMetrics.h"
37 #include "cc/CCRenderingStats.h"
38 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
39 #include "cc/CCTextureUpdateController.h"
40 #include <gtest/gtest.h>
41 #include <public/WebCompositor.h>
42 #include <public/WebTransformationMatrix.h>
43
44 using namespace WebCore;
45 using namespace WebKitTests;
46 using namespace WTF;
47 using WebKit::WebTransformationMatrix;
48
49 #define EXPECT_EQ_RECT(a, b) \
50     EXPECT_EQ(a.x(), b.x()); \
51     EXPECT_EQ(a.y(), b.y()); \
52     EXPECT_EQ(a.width(), b.width()); \
53     EXPECT_EQ(a.height(), b.height());
54
55 namespace {
56
57 class TestCCOcclusionTracker : public CCOcclusionTracker {
58 public:
59     TestCCOcclusionTracker()
60         : CCOcclusionTracker(IntRect(0, 0, 1000, 1000), true)
61         , m_scissorRectInScreen(IntRect(0, 0, 1000, 1000))
62     {
63         // Pretend we have visited a render surface.
64         m_stack.append(StackObject());
65     }
66
67     void setOcclusion(const Region& occlusion) { m_stack.last().occlusionInScreen = occlusion; }
68
69 protected:
70     virtual IntRect layerScissorRectInTargetSurface(const LayerChromium* layer) const { return m_scissorRectInScreen; }
71
72 private:
73     IntRect m_scissorRectInScreen;
74 };
75
76 class TiledLayerChromiumTest : public testing::Test {
77 public:
78     TiledLayerChromiumTest()
79         : m_context(WebKit::createFakeCCGraphicsContext())
80     {
81         DebugScopedSetImplThread implThread;
82         m_resourceProvider = CCResourceProvider::create(m_context.get());
83     }
84
85     virtual ~TiledLayerChromiumTest()
86     {
87         DebugScopedSetImplThread implThread;
88         m_resourceProvider.clear();
89     }
90
91     void updateTextures(int count = 500)
92     {
93         CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, &m_queue, count);
94     }
95 public:
96     OwnPtr<CCGraphicsContext> m_context;
97     OwnPtr<CCResourceProvider> m_resourceProvider;
98     CCTextureUpdateQueue m_queue;
99     CCRenderingStats m_stats;
100     FakeTextureCopier m_copier;
101     FakeTextureUploader m_uploader;
102     CCPriorityCalculator m_priorityCalculator;
103 };
104
105
106
107 TEST_F(TiledLayerChromiumTest, pushDirtyTiles)
108 {
109     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
110     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
111     DebugScopedSetImplThread implThread;
112     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
113
114     // The tile size is 100x100, so this invalidates and then paints two tiles.
115     layer->setBounds(IntSize(100, 200));
116     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
117     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
118
119     layer->setTexturePriorities(m_priorityCalculator);
120     textureManager->prioritizeTextures();
121
122     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
123     updateTextures();
124     layer->pushPropertiesTo(layerImpl.get());
125
126     // We should have both tiles on the impl side.
127     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
128     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
129
130     // Invalidates both tiles...
131     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
132     // ....but then only update one of them.
133     layer->setTexturePriorities(m_priorityCalculator);
134     textureManager->prioritizeTextures();
135     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
136     layer->pushPropertiesTo(layerImpl.get());
137
138     // We should only have the first tile since the other tile was invalidated but not painted.
139     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
140     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
141 }
142
143 TEST_F(TiledLayerChromiumTest, pushOccludedDirtyTiles)
144 {
145     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
146     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
147     DebugScopedSetImplThread implThread;
148     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
149     TestCCOcclusionTracker occluded;
150
151     // The tile size is 100x100, so this invalidates and then paints two tiles.
152     layer->setBounds(IntSize(100, 200));
153     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
154     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
155
156     layer->setTexturePriorities(m_priorityCalculator);
157     textureManager->prioritizeTextures();
158
159     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), &occluded, m_stats);
160     updateTextures();
161     layer->pushPropertiesTo(layerImpl.get());
162
163     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
164     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
165     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
166
167     // We should have both tiles on the impl side.
168     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
169     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
170
171     // Invalidates part of the top tile...
172     layer->invalidateContentRect(IntRect(0, 0, 50, 50));
173     // ....but the area is occluded.
174     occluded.setOcclusion(IntRect(0, 0, 50, 50));
175     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), &occluded, m_stats);
176     updateTextures();
177     layer->pushPropertiesTo(layerImpl.get());
178
179     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
180     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 2500, 1);
181     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
182
183     // We should still have both tiles, as part of the top tile is still unoccluded.
184     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
185     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
186 }
187
188 TEST_F(TiledLayerChromiumTest, pushDeletedTiles)
189 {
190     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
191     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
192     DebugScopedSetImplThread implThread;
193     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
194
195     // The tile size is 100x100, so this invalidates and then paints two tiles.
196     layer->setBounds(IntSize(100, 200));
197     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
198     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
199
200     layer->setTexturePriorities(m_priorityCalculator);
201     textureManager->prioritizeTextures();
202
203     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
204     updateTextures();
205     layer->pushPropertiesTo(layerImpl.get());
206
207     // We should have both tiles on the impl side.
208     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
209     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
210
211     textureManager->clearPriorities();
212     textureManager->clearAllMemory(m_resourceProvider.get());
213     textureManager->setMaxMemoryLimitBytes(4*1024*1024);
214
215     // This should drop the tiles on the impl thread.
216     layer->pushPropertiesTo(layerImpl.get());
217
218     // We should now have no textures on the impl thread.
219     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
220     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
221
222     // This should recreate and update the deleted textures.
223     layer->setTexturePriorities(m_priorityCalculator);
224     textureManager->prioritizeTextures();
225     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
226     updateTextures();
227     layer->pushPropertiesTo(layerImpl.get());
228
229     // We should only have the first tile since the other tile was invalidated but not painted.
230     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
231     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
232 }
233
234 TEST_F(TiledLayerChromiumTest, pushIdlePaintTiles)
235 {
236     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
237     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
238     DebugScopedSetImplThread implThread;
239     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
240
241     // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center.
242     IntSize contentBounds(500, 500);
243     IntRect contentRect(IntPoint::zero(), contentBounds);
244     IntRect visibleRect(200, 200, 100, 100);
245
246     // This invalidates 25 tiles and then paints one visible tile.
247     layer->setBounds(contentBounds);
248     layer->setVisibleContentRect(visibleRect);
249     layer->invalidateContentRect(contentRect);
250
251     layer->setTexturePriorities(m_priorityCalculator);
252     textureManager->prioritizeTextures();
253
254     layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
255     updateTextures();
256
257     // We should need idle-painting for 3x3 tiles in the center.
258     EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
259
260     layer->pushPropertiesTo(layerImpl.get());
261
262     // We should have one tile on the impl side.
263     EXPECT_TRUE(layerImpl->hasTileAt(2, 2));
264
265     // For the next four updates, we should detect we still need idle painting.
266     for (int i = 0; i < 4; i++) {
267         layer->setTexturePriorities(m_priorityCalculator);
268         textureManager->prioritizeTextures();
269
270         layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
271         EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
272         updateTextures();
273         layer->pushPropertiesTo(layerImpl.get());
274     }
275
276     // After four passes of idle painting, we should be finished painting
277     // EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
278
279     // We should have one tile surrounding the visible tile on all sides, but no other tiles.
280     IntRect idlePaintTiles(1, 1, 3, 3);
281     for (int i = 0; i < 5; i++) {
282         for (int j = 0; j < 5; j++) {
283             if (idlePaintTiles.contains(i, j))
284                 EXPECT_TRUE(layerImpl->hasTileAt(i, j));
285             else
286                 EXPECT_FALSE(layerImpl->hasTileAt(i, j));
287         }
288     }
289 }
290
291 TEST_F(TiledLayerChromiumTest, pushTilesAfterIdlePaintFailed)
292 {
293     // Start with 2mb of memory, but the test is going to try to use just more than 1mb, so we reduce to 1mb later.
294     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(2*1024*1024, 1024, CCRenderer::ContentPool);
295     DebugScopedSetImplThread implThread;
296     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
297     OwnPtr<FakeCCTiledLayerImpl> layerImpl1(adoptPtr(new FakeCCTiledLayerImpl(1)));
298     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
299     OwnPtr<FakeCCTiledLayerImpl> layerImpl2(adoptPtr(new FakeCCTiledLayerImpl(2)));
300
301     // For this test we have two layers. layer1 exhausts most texture memory, leaving room for 2 more tiles from
302     // layer2, but not all three tiles. First we paint layer1, and one tile from layer2. Then when we idle paint
303     // layer2, we will fail on the third tile of layer2, and this should not leave the second tile in a bad state.
304
305     // This requires 4*30000 bytes of memory.
306     IntRect layer2Rect(0, 0, 100, 300);
307     layer2->setBounds(layer2Rect.size());
308     layer2->setVisibleContentRect(layer2Rect);
309     layer2->invalidateContentRect(layer2Rect);
310
311     // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough for 2 tiles only in the other layer.
312     IntRect layerRect(IntPoint::zero(), IntSize(100, 2400));
313     layer1->setBounds(layerRect.size());
314     layer1->setVisibleContentRect(layerRect);
315     layer1->invalidateContentRect(layerRect);
316
317     // Paint a single tile in layer2 so that it will idle paint.
318     layer2->setTexturePriorities(m_priorityCalculator);
319     layer1->setTexturePriorities(m_priorityCalculator);
320     textureManager->prioritizeTextures();
321     layer1->updateContentRect(m_queue, layerRect, 0, m_stats);
322     layer2->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
323
324     // We should need idle-painting for both remaining tiles in layer2.
325     EXPECT_TRUE(layer2->needsIdlePaint(layer2Rect));
326
327     // Commit the frame over to impl.
328     updateTextures();
329     layer1->pushPropertiesTo(layerImpl1.get());
330     layer2->pushPropertiesTo(layerImpl2.get());
331
332     // Reduce our memory limits to 1mb.
333     textureManager->setMaxMemoryLimitBytes(1024 * 1024);
334
335     // Now idle paint layer2. We are going to run out of memory though!
336     layer2->setTexturePriorities(m_priorityCalculator);
337     layer1->setTexturePriorities(m_priorityCalculator);
338     textureManager->prioritizeTextures();
339     layer2->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
340
341     // Oh well, commit the frame and push.
342     updateTextures();
343     layer1->pushPropertiesTo(layerImpl1.get());
344     layer2->pushPropertiesTo(layerImpl2.get());
345
346     // Sanity check, we should have textures for the big layer.
347     EXPECT_TRUE(layerImpl1->hasTextureIdForTileAt(0, 0));
348
349     // We should only have the first tile from layer2 since it failed to idle update.
350     EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
351     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
352     EXPECT_FALSE(layerImpl2->hasTileAt(0, 1));
353     EXPECT_FALSE(layerImpl2->hasTileAt(0, 2));
354
355     // Now if layer2 becomes fully visible, we should be able to paint it and push valid textures.
356     layer2->setTexturePriorities(m_priorityCalculator);
357     layer1->setTexturePriorities(m_priorityCalculator);
358     textureManager->prioritizeTextures();
359     layer2->updateContentRect(m_queue, layer2Rect, 0, m_stats);
360     layer1->updateContentRect(m_queue, layerRect, 0, m_stats);
361
362     updateTextures();
363     layer1->pushPropertiesTo(layerImpl1.get());
364     layer2->pushPropertiesTo(layerImpl2.get());
365
366     EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
367     EXPECT_TRUE(layerImpl2->hasTileAt(0, 1));
368     EXPECT_TRUE(layerImpl2->hasTileAt(0, 2));
369     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
370     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 1));
371     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 2));
372 }
373
374 TEST_F(TiledLayerChromiumTest, pushIdlePaintedOccludedTiles)
375 {
376     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
377     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
378     DebugScopedSetImplThread implThread;
379     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
380     TestCCOcclusionTracker occluded;
381
382     // The tile size is 100x100, so this invalidates one occluded tile, culls it during paint, but prepaints it.
383     occluded.setOcclusion(IntRect(0, 0, 100, 100));
384
385     layer->setBounds(IntSize(100, 100));
386     layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
387     layer->invalidateContentRect(IntRect(0, 0, 100, 100));
388
389     layer->setTexturePriorities(m_priorityCalculator);
390     textureManager->prioritizeTextures();
391     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), &occluded, m_stats);
392     updateTextures();
393     layer->pushPropertiesTo(layerImpl.get());
394
395     // We should have the prepainted tile on the impl side.
396     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
397 }
398
399 TEST_F(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
400 {
401     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
402     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
403     DebugScopedSetImplThread implThread;
404     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
405
406     // The tile size is 100x100, so this invalidates and then paints two tiles.
407     // However, during the paint, we invalidate one of the tiles. This should
408     // not prevent the tile from being pushed.
409     layer->setBounds(IntSize(100, 200));
410     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
411     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
412     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer.get());
413
414     layer->setTexturePriorities(m_priorityCalculator);
415     textureManager->prioritizeTextures();
416     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
417     updateTextures();
418     layer->pushPropertiesTo(layerImpl.get());
419
420     // We should have both tiles on the impl side.
421     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
422     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
423 }
424
425 TEST_F(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
426 {
427     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
428     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
429     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
430     DebugScopedSetImplThread implThread;
431     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(1)));
432     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(2)));
433
434     layer1->setBounds(IntSize(100, 200));
435     layer1->setVisibleContentRect(IntRect(0, 0, 100, 200));
436     layer1->invalidateContentRect(IntRect(0, 0, 100, 200));
437
438     layer2->setBounds(IntSize(100, 200));
439     layer2->setVisibleContentRect(IntRect(0, 0, 100, 200));
440     layer2->invalidateContentRect(IntRect(0, 0, 100, 200));
441
442     layer1->setTexturePriorities(m_priorityCalculator);
443     layer2->setTexturePriorities(m_priorityCalculator);
444     textureManager->prioritizeTextures();
445
446     layer1->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
447
448     // Invalidate a tile on layer1
449     layer2->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer1.get());
450     layer2->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
451
452     updateTextures();
453     layer1->pushPropertiesTo(layer1Impl.get());
454     layer2->pushPropertiesTo(layer2Impl.get());
455
456     // We should have both tiles on the impl side for all layers.
457     EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
458     EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
459     EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
460     EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
461 }
462
463 TEST_F(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer)
464 {
465     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
466     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
467     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
468     DebugScopedSetImplThread implThread;
469     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(1)));
470     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(2)));
471
472     layer1->setBounds(IntSize(100, 200));
473     layer1->setVisibleContentRect(IntRect(0, 0, 100, 200));
474     layer1->invalidateContentRect(IntRect(0, 0, 100, 200));
475
476     layer2->setBounds(IntSize(100, 200));
477     layer2->setVisibleContentRect(IntRect(0, 0, 100, 200));
478     layer2->invalidateContentRect(IntRect(0, 0, 100, 200));
479
480     layer1->setTexturePriorities(m_priorityCalculator);
481     layer2->setTexturePriorities(m_priorityCalculator);
482     textureManager->prioritizeTextures();
483
484     // Invalidate a tile on layer2
485     layer1->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer2.get());
486     layer1->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
487     layer2->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
488     updateTextures();
489     layer1->pushPropertiesTo(layer1Impl.get());
490     layer2->pushPropertiesTo(layer2Impl.get());
491
492     // We should have both tiles on the impl side for all layers.
493     EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
494     EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
495     EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
496     EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
497 }
498
499 TEST_F(TiledLayerChromiumTest, idlePaintOutOfMemory)
500 {
501     // The tile size is 100x100. Setup 3x3 tiles with one 1x1 visible tile in the center.
502     IntSize contentBounds(300, 300);
503     IntRect contentRect(IntPoint::zero(), contentBounds);
504     IntRect visibleRect(100, 100, 100, 100);
505
506     // We have enough memory for only the visible rect, so we will run out of memory in first idle paint.
507     int memoryLimit = 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
508
509     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(memoryLimit, 1024, CCRenderer::ContentPool);
510     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
511     DebugScopedSetImplThread implThread;
512     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
513
514     // Invalidates 9 tiles and then paints one visible tile.
515     layer->setBounds(contentBounds);
516     layer->setVisibleContentRect(visibleRect);
517     layer->invalidateContentRect(contentRect);
518
519     layer->setTexturePriorities(m_priorityCalculator);
520     textureManager->prioritizeTextures();
521     layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
522
523     // Idle-painting should see no more priority tiles for painting.
524     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
525
526     updateTextures();
527     layer->pushPropertiesTo(layerImpl.get());
528
529     // We should have one tile on the impl side.
530     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
531
532     layer->setTexturePriorities(m_priorityCalculator);
533     textureManager->prioritizeTextures();
534     layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
535
536     // We shouldn't signal we need another idle paint.
537     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
538 }
539
540 TEST_F(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
541 {
542     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(20000, 1024, CCRenderer::ContentPool);
543     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
544     DebugScopedSetImplThread implThread;
545     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
546
547     bool animating[2] = {false, true};
548     for (int i = 0; i < 2; i++) {
549         // Pretend the layer is animating.
550         layer->setDrawTransformIsAnimating(animating[i]);
551
552         // The layer's bounds are empty.
553         IntRect contentRect;
554
555         layer->setBounds(contentRect.size());
556         layer->setVisibleContentRect(contentRect);
557         layer->invalidateContentRect(contentRect);
558
559         layer->setTexturePriorities(m_priorityCalculator);
560         textureManager->prioritizeTextures();
561
562         // Empty layers don't paint or idle-paint.
563         layer->updateContentRect(m_queue, contentRect, 0, m_stats);
564
565         // Empty layers don't have tiles.
566         EXPECT_EQ(0u, layer->numPaintedTiles());
567
568         // Empty layers don't need prepaint.
569         EXPECT_FALSE(layer->needsIdlePaint(contentRect));
570
571         layer->pushPropertiesTo(layerImpl.get());
572
573         // Empty layers don't have tiles.
574         EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
575     }
576 }
577
578 TEST_F(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
579 {
580     IntSize contentBounds(100, 100);
581     IntRect contentRect(IntPoint::zero(), contentBounds);
582
583     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(20000, 1024, CCRenderer::ContentPool);
584     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
585     DebugScopedSetImplThread implThread;
586     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
587
588     // Invalidate the layer but make none of it visible, so nothing paints.
589     IntRect visibleRect;
590
591     layer->setBounds(contentBounds);
592     layer->setVisibleContentRect(visibleRect);
593     layer->invalidateContentRect(contentRect);
594
595     for (int i = 0; i < 2; i++) {
596         // Paint / idle-paint.
597         layer->setTexturePriorities(m_priorityCalculator);
598         textureManager->prioritizeTextures();
599         layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
600
601         // Non-visible layers don't need idle paint.
602         EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
603
604         layer->pushPropertiesTo(layerImpl.get());
605
606         // We should not have any tiles pushed since the layer is not visible.
607         EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
608     }
609 }
610
611 static void testHaveOuterTiles(FakeCCTiledLayerImpl* layerImpl, int width, int height, int have)
612 {
613     for (int i = 0; i < width; ++i) {
614         for (int j = 0; j < height; ++j) {
615             bool hasTile = i < have || j < have || i >= width - have || j >= height - have;
616             EXPECT_EQ(hasTile, layerImpl->hasTileAt(i, j));
617         }
618     }
619 }
620
621 TEST_F(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers)
622 {
623     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(8000*8000*8, 1024, CCRenderer::ContentPool);
624     DebugScopedSetImplThread implThread;
625
626     int tileWidth = FakeTiledLayerChromium::tileSize().width();
627     int tileHeight = FakeTiledLayerChromium::tileSize().height();
628     int width[] = { 1, 2, 3, 4, 9, 10, 0 };
629     int height[] = { 1, 2, 3, 4, 9, 10, 0 };
630
631     for (int j = 0; height[j]; ++j) {
632         for (int i = 0; width[i]; ++i) {
633             RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
634             OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
635
636             // Pretend the layer is animating.
637             layer->setDrawTransformIsAnimating(true);
638
639             IntSize contentBounds(width[i] * tileWidth, height[j] * tileHeight);
640             IntRect contentRect(IntPoint::zero(), contentBounds);
641             IntRect visibleRect;
642
643             layer->setBounds(contentBounds);
644             layer->setVisibleContentRect(visibleRect);
645             layer->invalidateContentRect(contentRect);
646
647             layer->setTexturePriorities(m_priorityCalculator);
648             textureManager->prioritizeTextures();
649
650             // If idlePaintRect gives back a non-empty result then we should paint it. Otherwise,
651             // we shoud paint nothing.
652             bool shouldPrepaint = !layer->idlePaintRect(visibleRect).isEmpty();
653
654             // Normally we don't allow non-visible layers to pre-paint, but if they are animating then we should.
655             EXPECT_EQ(shouldPrepaint, layer->needsIdlePaint(visibleRect));
656
657             // If the layer is to be prepainted at all, then after four updates we should have the outer row/columns painted.
658             for (int k = 0; k < 4; ++k) {
659                 layer->setTexturePriorities(m_priorityCalculator);
660                 textureManager->prioritizeTextures();
661
662                 layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
663                 updateTextures();
664                 layer->pushPropertiesTo(layerImpl.get());
665             }
666
667             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
668
669             // We don't currently idle paint past the outermost tiles.
670             EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
671             for (int k = 0; k < 4; ++k) {
672                 layer->setTexturePriorities(m_priorityCalculator);
673                 textureManager->prioritizeTextures();
674
675                 layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
676                 updateTextures();
677                 layer->pushPropertiesTo(layerImpl.get());
678             }
679
680             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
681         }
682     }
683 }
684
685 TEST_F(TiledLayerChromiumTest, invalidateFromPrepare)
686 {
687     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
688     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
689     DebugScopedSetImplThread implThread;
690     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
691
692     // The tile size is 100x100, so this invalidates and then paints two tiles.
693     layer->setBounds(IntSize(100, 200));
694     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
695     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
696     layer->setTexturePriorities(m_priorityCalculator);
697     textureManager->prioritizeTextures();
698     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
699     updateTextures(1000);
700     layer->pushPropertiesTo(layerImpl.get());
701
702     // We should have both tiles on the impl side.
703     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
704     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
705
706     layer->fakeLayerTextureUpdater()->clearPrepareCount();
707     // Invoke updateContentRect again. As the layer is valid updateContentRect shouldn't be invoked on
708     // the LayerTextureUpdater.
709     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
710     updateTextures(1000);
711     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareCount());
712
713     layer->invalidateContentRect(IntRect(0, 0, 50, 50));
714     // setRectToInvalidate triggers invalidateContentRect() being invoked from updateContentRect.
715     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(25, 25, 50, 50), layer.get());
716     layer->fakeLayerTextureUpdater()->clearPrepareCount();
717     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
718     updateTextures(1000);
719     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
720     layer->fakeLayerTextureUpdater()->clearPrepareCount();
721     // The layer should still be invalid as updateContentRect invoked invalidate.
722     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
723     updateTextures(1000);
724     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
725 }
726
727 TEST_F(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
728 {
729     // The updateRect (that indicates what was actually painted) should be in
730     // layer space, not the content space.
731
732     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
733     RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get()));
734     DebugScopedSetImplThread implThread;
735
736     IntRect layerBounds(0, 0, 300, 200);
737     IntRect contentBounds(0, 0, 200, 250);
738
739     layer->setBounds(layerBounds.size());
740     layer->setContentBounds(contentBounds.size());
741     layer->setVisibleContentRect(contentBounds);
742
743     // On first update, the updateRect includes all tiles, even beyond the boundaries of the layer.
744     // However, it should still be in layer space, not content space.
745     layer->invalidateContentRect(contentBounds);
746
747     layer->setTexturePriorities(m_priorityCalculator);
748     textureManager->prioritizeTextures();
749     layer->updateContentRect(m_queue, contentBounds, 0, m_stats);
750     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 300, 300 * 0.8), layer->updateRect());
751     updateTextures();
752
753     // After the tiles are updated once, another invalidate only needs to update the bounds of the layer.
754     layer->setTexturePriorities(m_priorityCalculator);
755     textureManager->prioritizeTextures();
756     layer->invalidateContentRect(contentBounds);
757     layer->updateContentRect(m_queue, contentBounds, 0, m_stats);
758     EXPECT_FLOAT_RECT_EQ(FloatRect(layerBounds), layer->updateRect());
759     updateTextures();
760
761     // Partial re-paint should also be represented by the updateRect in layer space, not content space.
762     IntRect partialDamage(30, 100, 10, 10);
763     layer->invalidateContentRect(partialDamage);
764     layer->setTexturePriorities(m_priorityCalculator);
765     textureManager->prioritizeTextures();
766     layer->updateContentRect(m_queue, contentBounds, 0, m_stats);
767     EXPECT_FLOAT_RECT_EQ(FloatRect(45, 80, 15, 8), layer->updateRect());
768 }
769
770 TEST_F(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
771 {
772     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
773     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
774     DebugScopedSetImplThread implThread;
775     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
776
777     // Create a layer with one tile.
778     layer->setBounds(IntSize(100, 100));
779     layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
780
781     // Invalidate the entire layer.
782     layer->setNeedsDisplay();
783     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
784
785     // Push the tiles to the impl side and check that there is exactly one.
786     layer->setTexturePriorities(m_priorityCalculator);
787     textureManager->prioritizeTextures();
788     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
789     updateTextures();
790     layer->pushPropertiesTo(layerImpl.get());
791     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
792     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
793     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
794     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
795
796     // Change the contents scale and verify that the content rectangle requiring painting
797     // is not scaled.
798     layer->setContentsScale(2);
799     layer->setVisibleContentRect(IntRect(0, 0, 200, 200));
800     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
801
802     // The impl side should get 2x2 tiles now.
803     layer->setTexturePriorities(m_priorityCalculator);
804     textureManager->prioritizeTextures();
805     layer->updateContentRect(m_queue, IntRect(0, 0, 200, 200), 0, m_stats);
806     updateTextures();
807     layer->pushPropertiesTo(layerImpl.get());
808     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
809     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
810     EXPECT_TRUE(layerImpl->hasTileAt(1, 0));
811     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
812
813     // Invalidate the entire layer again, but do not paint. All tiles should be gone now from the
814     // impl side.
815     layer->setNeedsDisplay();
816     layer->setTexturePriorities(m_priorityCalculator);
817     layer->updateContentRect(m_queue, IntRect(1, 0, 0, 1), 0, m_stats);
818     textureManager->prioritizeTextures();
819
820     layer->pushPropertiesTo(layerImpl.get());
821     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
822     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
823     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
824     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
825 }
826
827 TEST_F(TiledLayerChromiumTest, skipsDrawGetsReset)
828 {
829     // Initialize without threading support.
830     WebKit::WebCompositor::initialize(0);
831     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
832     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, CCLayerTreeSettings());
833     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
834
835     // Create two 300 x 300 tiled layers.
836     IntSize contentBounds(300, 300);
837     IntRect contentRect(IntPoint::zero(), contentBounds);
838
839     // We have enough memory for only one of the two layers.
840     int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
841
842     RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
843     RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
844     rootLayer->addChild(childLayer);
845
846     rootLayer->setBounds(contentBounds);
847     rootLayer->setVisibleContentRect(contentRect);
848     rootLayer->setPosition(FloatPoint(0, 0));
849     childLayer->setBounds(contentBounds);
850     childLayer->setVisibleContentRect(contentRect);
851     childLayer->setPosition(FloatPoint(0, 0));
852     rootLayer->invalidateContentRect(contentRect);
853     childLayer->invalidateContentRect(contentRect);
854
855     ccLayerTreeHost->setRootLayer(rootLayer);
856     ccLayerTreeHost->setViewportSize(IntSize(300, 300), IntSize(300, 300));
857
858     ccLayerTreeHost->updateLayers(m_queue, memoryLimit);
859
860     // We'll skip the root layer.
861     EXPECT_TRUE(rootLayer->skipsDraw());
862     EXPECT_FALSE(childLayer->skipsDraw());
863
864     ccLayerTreeHost->commitComplete();
865
866     // Remove the child layer.
867     rootLayer->removeAllChildren();
868
869     ccLayerTreeHost->updateLayers(m_queue, memoryLimit);
870     EXPECT_FALSE(rootLayer->skipsDraw());
871
872     ccLayerTreeHost->contentsTextureManager()->clearAllMemory(m_resourceProvider.get());
873     ccLayerTreeHost->setRootLayer(0);
874     ccLayerTreeHost.clear();
875     WebKit::WebCompositor::shutdown();
876 }
877
878 TEST_F(TiledLayerChromiumTest, resizeToSmaller)
879 {
880     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(60*1024*1024, 1024, CCRenderer::ContentPool);
881     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
882
883     layer->setBounds(IntSize(700, 700));
884     layer->setVisibleContentRect(IntRect(0, 0, 700, 700));
885     layer->invalidateContentRect(IntRect(0, 0, 700, 700));
886
887     layer->setTexturePriorities(m_priorityCalculator);
888     textureManager->prioritizeTextures();
889     layer->updateContentRect(m_queue, IntRect(0, 0, 700, 700), 0, m_stats);
890
891     layer->setBounds(IntSize(200, 200));
892     layer->invalidateContentRect(IntRect(0, 0, 200, 200));
893 }
894
895 TEST_F(TiledLayerChromiumTest, hugeLayerUpdateCrash)
896 {
897     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(60*1024*1024, 1024, CCRenderer::ContentPool);
898     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
899
900     int size = 1 << 30;
901     layer->setBounds(IntSize(size, size));
902     layer->setVisibleContentRect(IntRect(0, 0, 700, 700));
903     layer->invalidateContentRect(IntRect(0, 0, size, size));
904
905     // Ensure no crash for bounds where size * size would overflow an int.
906     layer->setTexturePriorities(m_priorityCalculator);
907     textureManager->prioritizeTextures();
908     layer->updateContentRect(m_queue, IntRect(0, 0, 700, 700), 0, m_stats);
909 }
910
911 TEST_F(TiledLayerChromiumTest, partialUpdates)
912 {
913     // Initialize without threading support.
914     WebKit::WebCompositor::initialize(0);
915
916     CCLayerTreeSettings settings;
917     settings.maxPartialTextureUpdates = 4;
918
919     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
920     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
921     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
922
923     // Create one 300 x 200 tiled layer with 3 x 2 tiles.
924     IntSize contentBounds(300, 200);
925     IntRect contentRect(IntPoint::zero(), contentBounds);
926
927     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
928     layer->setBounds(contentBounds);
929     layer->setPosition(FloatPoint(0, 0));
930     layer->setVisibleContentRect(contentRect);
931     layer->invalidateContentRect(contentRect);
932
933     ccLayerTreeHost->setRootLayer(layer);
934     ccLayerTreeHost->setViewportSize(IntSize(300, 200), IntSize(300, 200));
935
936     // Full update of all 6 tiles.
937     ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
938     {
939         DebugScopedSetImplThread implThread;
940         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
941         updateTextures(4);
942         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
943         EXPECT_TRUE(m_queue.hasMoreUpdates());
944         layer->fakeLayerTextureUpdater()->clearUpdateCount();
945         updateTextures(4);
946         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
947         EXPECT_FALSE(m_queue.hasMoreUpdates());
948         layer->fakeLayerTextureUpdater()->clearUpdateCount();
949         layer->pushPropertiesTo(layerImpl.get());
950     }
951     ccLayerTreeHost->commitComplete();
952
953     // Full update of 3 tiles and partial update of 3 tiles.
954     layer->invalidateContentRect(IntRect(0, 0, 300, 150));
955     ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
956     {
957         DebugScopedSetImplThread implThread;
958         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
959         updateTextures(4);
960         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
961         EXPECT_TRUE(m_queue.hasMoreUpdates());
962         layer->fakeLayerTextureUpdater()->clearUpdateCount();
963         updateTextures(4);
964         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
965         EXPECT_FALSE(m_queue.hasMoreUpdates());
966         layer->fakeLayerTextureUpdater()->clearUpdateCount();
967         layer->pushPropertiesTo(layerImpl.get());
968     }
969     ccLayerTreeHost->commitComplete();
970
971     // Partial update of 6 tiles.
972     layer->invalidateContentRect(IntRect(50, 50, 200, 100));
973     {
974         DebugScopedSetImplThread implThread;
975         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
976         ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
977         updateTextures(4);
978         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
979         EXPECT_TRUE(m_queue.hasMoreUpdates());
980         layer->fakeLayerTextureUpdater()->clearUpdateCount();
981         updateTextures(4);
982         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
983         EXPECT_FALSE(m_queue.hasMoreUpdates());
984         layer->fakeLayerTextureUpdater()->clearUpdateCount();
985         layer->pushPropertiesTo(layerImpl.get());
986     }
987     ccLayerTreeHost->commitComplete();
988
989     // Checkerboard all tiles.
990     layer->invalidateContentRect(IntRect(0, 0, 300, 200));
991     {
992         DebugScopedSetImplThread implThread;
993         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
994         layer->pushPropertiesTo(layerImpl.get());
995     }
996     ccLayerTreeHost->commitComplete();
997
998     // Partial update of 6 checkerboard tiles.
999     layer->invalidateContentRect(IntRect(50, 50, 200, 100));
1000     {
1001         DebugScopedSetImplThread implThread;
1002         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
1003         ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
1004         updateTextures(4);
1005         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
1006         EXPECT_TRUE(m_queue.hasMoreUpdates());
1007         layer->fakeLayerTextureUpdater()->clearUpdateCount();
1008         updateTextures(4);
1009         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
1010         EXPECT_FALSE(m_queue.hasMoreUpdates());
1011         layer->fakeLayerTextureUpdater()->clearUpdateCount();
1012         layer->pushPropertiesTo(layerImpl.get());
1013     }
1014     ccLayerTreeHost->commitComplete();
1015
1016     // Partial update of 4 tiles.
1017     layer->invalidateContentRect(IntRect(50, 50, 100, 100));
1018     {
1019         DebugScopedSetImplThread implThread;
1020         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
1021         ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
1022         updateTextures(4);
1023         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
1024         EXPECT_FALSE(m_queue.hasMoreUpdates());
1025         layer->fakeLayerTextureUpdater()->clearUpdateCount();
1026         layer->pushPropertiesTo(layerImpl.get());
1027     }
1028     ccLayerTreeHost->commitComplete();
1029
1030     {
1031         DebugScopedSetImplThread implThread;
1032         ccLayerTreeHost->contentsTextureManager()->clearAllMemory(m_resourceProvider.get());
1033     }
1034     ccLayerTreeHost->setRootLayer(0);
1035     ccLayerTreeHost.clear();
1036     WebKit::WebCompositor::shutdown();
1037 }
1038
1039 TEST_F(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
1040 {
1041     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1042     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1043
1044     // The tile size is 100x100, so this invalidates and then paints two tiles.
1045     layer->setBounds(IntSize(100, 200));
1046     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
1047     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
1048
1049     layer->setTexturePriorities(m_priorityCalculator);
1050     textureManager->prioritizeTextures();
1051     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
1052     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1053 }
1054
1055 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
1056 {
1057     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1058     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1059     TestCCOcclusionTracker occluded;
1060
1061     // The tile size is 100x100.
1062
1063     layer->setBounds(IntSize(600, 600));
1064
1065     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1066     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1067     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1068
1069     layer->setTexturePriorities(m_priorityCalculator);
1070     textureManager->prioritizeTextures();
1071     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1072     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1073
1074     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1075     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1076     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1077
1078     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1079
1080     occluded.setOcclusion(IntRect(250, 200, 300, 100));
1081     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1082     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1083     EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1084
1085     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1086     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000, 1);
1087     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1088
1089     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1090
1091     occluded.setOcclusion(IntRect(250, 250, 300, 100));
1092     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1093     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1094     EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
1095
1096     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1097     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000 + 360000, 1);
1098     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1099 }
1100
1101 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
1102 {
1103     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1104     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1105     TestCCOcclusionTracker occluded;
1106
1107     // The tile size is 100x100.
1108
1109     layer->setBounds(IntSize(600, 600));
1110
1111     // The partially occluded tiles (by the 150 occlusion height) are visible beyond the occlusion, so not culled.
1112     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1113     layer->setVisibleContentRect(IntRect(0, 0, 600, 360));
1114     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1115
1116     layer->setTexturePriorities(m_priorityCalculator);
1117     textureManager->prioritizeTextures();
1118     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 360), &occluded, m_stats);
1119     EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1120
1121     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1122     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000, 1);
1123     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1124
1125     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1126
1127     // Now the visible region stops at the edge of the occlusion so the partly visible tiles become fully occluded.
1128     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1129     layer->setVisibleContentRect(IntRect(0, 0, 600, 350));
1130     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1131     layer->setTexturePriorities(m_priorityCalculator);
1132     textureManager->prioritizeTextures();
1133     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 350), &occluded, m_stats);
1134     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1135
1136     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1137     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000, 1);
1138     EXPECT_EQ(3 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1139
1140     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1141
1142     // Now the visible region is even smaller than the occlusion, it should have the same result.
1143     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1144     layer->setVisibleContentRect(IntRect(0, 0, 600, 340));
1145     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1146     layer->setTexturePriorities(m_priorityCalculator);
1147     textureManager->prioritizeTextures();
1148     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 340), &occluded, m_stats);
1149     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1150
1151     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1152     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000 + 180000, 1);
1153     EXPECT_EQ(3 + 6 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1154
1155 }
1156
1157 TEST_F(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
1158 {
1159     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1160     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1161     TestCCOcclusionTracker occluded;
1162
1163     // The tile size is 100x100.
1164
1165     layer->setBounds(IntSize(600, 600));
1166
1167     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1168     layer->setVisibleContentRect(IntRect(0, 0, 600, 600));
1169     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1170     layer->setTexturePriorities(m_priorityCalculator);
1171     textureManager->prioritizeTextures();
1172     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1173     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1174     {
1175         DebugScopedSetImplThread implThread;
1176         updateTextures();
1177     }
1178
1179     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1180     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1181     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1182
1183     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1184
1185     // Repaint without marking it dirty. The 3 culled tiles will be pre-painted now.
1186     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1187     EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1188
1189     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1190     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1191     EXPECT_EQ(6, occluded.overdrawMetrics().tilesCulledForUpload());
1192 }
1193
1194 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
1195 {
1196     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1197     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1198     TestCCOcclusionTracker occluded;
1199
1200     // The tile size is 100x100.
1201
1202     // This makes sure the painting works when the occluded region (in screen space)
1203     // is transformed differently than the layer.
1204     layer->setBounds(IntSize(600, 600));
1205     WebTransformationMatrix screenTransform;
1206     screenTransform.scale(0.5);
1207     layer->setScreenSpaceTransform(screenTransform);
1208     layer->setDrawTransform(screenTransform);
1209
1210     occluded.setOcclusion(IntRect(100, 100, 150, 50));
1211     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1212     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1213     layer->setTexturePriorities(m_priorityCalculator);
1214     textureManager->prioritizeTextures();
1215     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1216     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1217
1218     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1219     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1220     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1221 }
1222
1223 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
1224 {
1225     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1226     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1227     TestCCOcclusionTracker occluded;
1228
1229     // The tile size is 100x100.
1230
1231     // This makes sure the painting works when the content space is scaled to
1232     // a different layer space. In this case tiles are scaled to be 200x200
1233     // pixels, which means none should be occluded.
1234     layer->setContentsScale(0.5);
1235     layer->setBounds(IntSize(600, 600));
1236     WebTransformationMatrix drawTransform;
1237     drawTransform.scale(1 / layer->contentsScale());
1238     layer->setDrawTransform(drawTransform);
1239     layer->setScreenSpaceTransform(drawTransform);
1240
1241     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1242     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1243     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1244     layer->setTexturePriorities(m_priorityCalculator);
1245     textureManager->prioritizeTextures();
1246     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1247     // The content is half the size of the layer (so the number of tiles is fewer).
1248     // In this case, the content is 300x300, and since the tile size is 100, the
1249     // number of tiles 3x3.
1250     EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
1251
1252     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1253     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000, 1);
1254     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1255
1256     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1257
1258     // This makes sure the painting works when the content space is scaled to
1259     // a different layer space. In this case the occluded region catches the
1260     // blown up tiles.
1261     occluded.setOcclusion(IntRect(200, 200, 300, 200));
1262     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1263     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1264     layer->setTexturePriorities(m_priorityCalculator);
1265     textureManager->prioritizeTextures();
1266     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1267     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1268
1269     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1270     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000, 1);
1271     EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
1272
1273     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1274
1275     // This makes sure content scaling and transforms work together.
1276     WebTransformationMatrix screenTransform;
1277     screenTransform.scale(0.5);
1278     layer->setScreenSpaceTransform(screenTransform);
1279     layer->setDrawTransform(screenTransform);
1280
1281     occluded.setOcclusion(IntRect(100, 100, 150, 100));
1282     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1283     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1284     layer->setTexturePriorities(m_priorityCalculator);
1285     textureManager->prioritizeTextures();
1286     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1287     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1288
1289     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1290     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000 + 80000, 1);
1291     EXPECT_EQ(1 + 1, occluded.overdrawMetrics().tilesCulledForUpload());
1292 }
1293
1294 TEST_F(TiledLayerChromiumTest, visibleContentOpaqueRegion)
1295 {
1296     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1297     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1298     TestCCOcclusionTracker occluded;
1299     DebugScopedSetImplThread implThread;
1300
1301     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1302
1303     IntRect opaquePaintRect;
1304     Region opaqueContents;
1305
1306     IntRect contentBounds = IntRect(0, 0, 100, 200);
1307     IntRect visibleBounds = IntRect(0, 0, 100, 150);
1308
1309     layer->setBounds(contentBounds.size());
1310     layer->setVisibleContentRect(visibleBounds);
1311     layer->setDrawOpacity(1);
1312
1313     layer->setTexturePriorities(m_priorityCalculator);
1314     textureManager->prioritizeTextures();
1315
1316     // If the layer doesn't paint opaque content, then the visibleContentOpaqueRegion should be empty.
1317     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1318     layer->invalidateContentRect(contentBounds);
1319     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1320     opaqueContents = layer->visibleContentOpaqueRegion();
1321     EXPECT_TRUE(opaqueContents.isEmpty());
1322
1323     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
1324     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1325     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
1326     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1327
1328     // visibleContentOpaqueRegion should match the visible part of what is painted opaque.
1329     opaquePaintRect = IntRect(10, 10, 90, 190);
1330     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
1331     layer->invalidateContentRect(contentBounds);
1332     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1333     updateTextures();
1334     opaqueContents = layer->visibleContentOpaqueRegion();
1335     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1336     EXPECT_EQ(1u, opaqueContents.rects().size());
1337
1338     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1339     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1340     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1341     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1342
1343     // If we paint again without invalidating, the same stuff should be opaque.
1344     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1345     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1346     updateTextures();
1347     opaqueContents = layer->visibleContentOpaqueRegion();
1348     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1349     EXPECT_EQ(1u, opaqueContents.rects().size());
1350
1351     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1352     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1353     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1354     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1355
1356     // If we repaint a non-opaque part of the tile, then it shouldn't lose its opaque-ness. And other tiles should
1357     // not be affected.
1358     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1359     layer->invalidateContentRect(IntRect(0, 0, 1, 1));
1360     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1361     updateTextures();
1362     opaqueContents = layer->visibleContentOpaqueRegion();
1363     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1364     EXPECT_EQ(1u, opaqueContents.rects().size());
1365
1366     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
1367     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1368     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1, 1);
1369     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1370
1371     // If we repaint an opaque part of the tile, then it should lose its opaque-ness. But other tiles should still
1372     // not be affected.
1373     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1374     layer->invalidateContentRect(IntRect(10, 10, 1, 1));
1375     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1376     updateTextures();
1377     opaqueContents = layer->visibleContentOpaqueRegion();
1378     EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
1379     EXPECT_EQ(1u, opaqueContents.rects().size());
1380
1381     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1382     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1383     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1384     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1385 }
1386
1387 TEST_F(TiledLayerChromiumTest, pixelsPaintedMetrics)
1388 {
1389     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1390     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1391     TestCCOcclusionTracker occluded;
1392     DebugScopedSetImplThread implThread;
1393
1394     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1395
1396     IntRect opaquePaintRect;
1397     Region opaqueContents;
1398
1399     IntRect contentBounds = IntRect(0, 0, 100, 300);
1400     IntRect visibleBounds = IntRect(0, 0, 100, 300);
1401
1402     layer->setBounds(contentBounds.size());
1403     layer->setVisibleContentRect(visibleBounds);
1404     layer->setDrawOpacity(1);
1405
1406     layer->setTexturePriorities(m_priorityCalculator);
1407     textureManager->prioritizeTextures();
1408
1409     // Invalidates and paints the whole layer.
1410     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1411     layer->invalidateContentRect(contentBounds);
1412     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1413     updateTextures();
1414     opaqueContents = layer->visibleContentOpaqueRegion();
1415     EXPECT_TRUE(opaqueContents.isEmpty());
1416
1417     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
1418     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1419     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000, 1);
1420     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1421
1422     // Invalidates an area on the top and bottom tile, which will cause us to paint the tile in the middle,
1423     // even though it is not dirty and will not be uploaded.
1424     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1425     layer->invalidateContentRect(IntRect(0, 0, 1, 1));
1426     layer->invalidateContentRect(IntRect(50, 200, 10, 10));
1427     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1428     updateTextures();
1429     opaqueContents = layer->visibleContentOpaqueRegion();
1430     EXPECT_TRUE(opaqueContents.isEmpty());
1431
1432     // The middle tile was painted even though not invalidated.
1433     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1);
1434     // The pixels uploaded will not include the non-invalidated tile in the middle.
1435     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1436     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000 + 1 + 100, 1);
1437     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1438 }
1439
1440 TEST_F(TiledLayerChromiumTest, dontAllocateContentsWhenTargetSurfaceCantBeAllocated)
1441 {
1442     // Initialize without threading support.
1443     WebKit::WebCompositor::initialize(0);
1444
1445     // Tile size is 100x100.
1446     IntRect rootRect(0, 0, 300, 200);
1447     IntRect childRect(0, 0, 300, 100);
1448     IntRect child2Rect(0, 100, 300, 100);
1449
1450     CCLayerTreeSettings settings;
1451     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
1452     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
1453     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
1454
1455     RefPtr<FakeTiledLayerChromium> root = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1456     RefPtr<LayerChromium> surface = LayerChromium::create();
1457     RefPtr<FakeTiledLayerChromium> child = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1458     RefPtr<FakeTiledLayerChromium> child2 = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1459
1460     root->setBounds(rootRect.size());
1461     root->setAnchorPoint(FloatPoint());
1462     root->setVisibleContentRect(rootRect);
1463     root->addChild(surface);
1464
1465     surface->setForceRenderSurface(true);
1466     surface->setAnchorPoint(FloatPoint());
1467     surface->setOpacity(0.5);
1468     surface->addChild(child);
1469     surface->addChild(child2);
1470
1471     child->setBounds(childRect.size());
1472     child->setAnchorPoint(FloatPoint());
1473     child->setPosition(childRect.location());
1474     child->setVisibleContentRect(childRect);
1475
1476     child2->setBounds(child2Rect.size());
1477     child2->setAnchorPoint(FloatPoint());
1478     child2->setPosition(child2Rect.location());
1479     child2->setVisibleContentRect(child2Rect);
1480
1481     ccLayerTreeHost->setRootLayer(root);
1482     ccLayerTreeHost->setViewportSize(rootRect.size(), rootRect.size());
1483
1484     // With a huge memory limit, all layers should update and push their textures.
1485     root->invalidateContentRect(rootRect);
1486     child->invalidateContentRect(childRect);
1487     child2->invalidateContentRect(child2Rect);
1488     ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
1489     {
1490         DebugScopedSetImplThread implThread;
1491         updateTextures(1000);
1492         EXPECT_EQ(6, root->fakeLayerTextureUpdater()->updateCount());
1493         EXPECT_EQ(3, child->fakeLayerTextureUpdater()->updateCount());
1494         EXPECT_EQ(3, child2->fakeLayerTextureUpdater()->updateCount());
1495         EXPECT_FALSE(m_queue.hasMoreUpdates());
1496
1497         root->fakeLayerTextureUpdater()->clearUpdateCount();
1498         child->fakeLayerTextureUpdater()->clearUpdateCount();
1499         child2->fakeLayerTextureUpdater()->clearUpdateCount();
1500
1501         OwnPtr<FakeCCTiledLayerImpl> rootImpl(adoptPtr(new FakeCCTiledLayerImpl(root->id())));
1502         OwnPtr<FakeCCTiledLayerImpl> childImpl(adoptPtr(new FakeCCTiledLayerImpl(child->id())));
1503         OwnPtr<FakeCCTiledLayerImpl> child2Impl(adoptPtr(new FakeCCTiledLayerImpl(child2->id())));
1504         root->pushPropertiesTo(rootImpl.get());
1505         child->pushPropertiesTo(childImpl.get());
1506         child2->pushPropertiesTo(child2Impl.get());
1507
1508         for (unsigned i = 0; i < 3; ++i) {
1509             for (unsigned j = 0; j < 2; ++j)
1510                 EXPECT_TRUE(rootImpl->hasTextureIdForTileAt(i, j));
1511             EXPECT_TRUE(childImpl->hasTextureIdForTileAt(i, 0));
1512             EXPECT_TRUE(child2Impl->hasTextureIdForTileAt(i, 0));
1513         }
1514     }
1515     ccLayerTreeHost->commitComplete();
1516
1517     // With a memory limit that includes only the root layer (3x2 tiles) and half the surface that
1518     // the child layers draw into, the child layers will not be allocated. If the surface isn't
1519     // accounted for, then one of the children would fit within the memory limit.
1520     root->invalidateContentRect(rootRect);
1521     child->invalidateContentRect(childRect);
1522     child2->invalidateContentRect(child2Rect);
1523     ccLayerTreeHost->updateLayers(m_queue, (3 * 2 + 3 * 1) * (100 * 100) * 4);
1524     {
1525         DebugScopedSetImplThread implThread;
1526         updateTextures(1000);
1527         EXPECT_EQ(6, root->fakeLayerTextureUpdater()->updateCount());
1528         EXPECT_EQ(0, child->fakeLayerTextureUpdater()->updateCount());
1529         EXPECT_EQ(0, child2->fakeLayerTextureUpdater()->updateCount());
1530         EXPECT_FALSE(m_queue.hasMoreUpdates());
1531
1532         root->fakeLayerTextureUpdater()->clearUpdateCount();
1533         child->fakeLayerTextureUpdater()->clearUpdateCount();
1534         child2->fakeLayerTextureUpdater()->clearUpdateCount();
1535
1536         OwnPtr<FakeCCTiledLayerImpl> rootImpl(adoptPtr(new FakeCCTiledLayerImpl(root->id())));
1537         OwnPtr<FakeCCTiledLayerImpl> childImpl(adoptPtr(new FakeCCTiledLayerImpl(child->id())));
1538         OwnPtr<FakeCCTiledLayerImpl> child2Impl(adoptPtr(new FakeCCTiledLayerImpl(child2->id())));
1539         root->pushPropertiesTo(rootImpl.get());
1540         child->pushPropertiesTo(childImpl.get());
1541         child2->pushPropertiesTo(child2Impl.get());
1542
1543         for (unsigned i = 0; i < 3; ++i) {
1544             for (unsigned j = 0; j < 2; ++j)
1545                 EXPECT_TRUE(rootImpl->hasTextureIdForTileAt(i, j));
1546             EXPECT_FALSE(childImpl->hasTextureIdForTileAt(i, 0));
1547             EXPECT_FALSE(child2Impl->hasTextureIdForTileAt(i, 0));
1548         }
1549     }
1550     ccLayerTreeHost->commitComplete();
1551
1552     // With a memory limit that includes only half the root layer, no contents will be
1553     // allocated. If render surface memory wasn't accounted for, there is enough space
1554     // for one of the children layers, but they draw into a surface that can't be
1555     // allocated.
1556     root->invalidateContentRect(rootRect);
1557     child->invalidateContentRect(childRect);
1558     child2->invalidateContentRect(child2Rect);
1559     ccLayerTreeHost->updateLayers(m_queue, (3 * 1) * (100 * 100) * 4);
1560     {
1561         DebugScopedSetImplThread implThread;
1562         updateTextures(1000);
1563         EXPECT_EQ(0, root->fakeLayerTextureUpdater()->updateCount());
1564         EXPECT_EQ(0, child->fakeLayerTextureUpdater()->updateCount());
1565         EXPECT_EQ(0, child2->fakeLayerTextureUpdater()->updateCount());
1566         EXPECT_FALSE(m_queue.hasMoreUpdates());
1567
1568         root->fakeLayerTextureUpdater()->clearUpdateCount();
1569         child->fakeLayerTextureUpdater()->clearUpdateCount();
1570         child2->fakeLayerTextureUpdater()->clearUpdateCount();
1571
1572         OwnPtr<FakeCCTiledLayerImpl> rootImpl(adoptPtr(new FakeCCTiledLayerImpl(root->id())));
1573         OwnPtr<FakeCCTiledLayerImpl> childImpl(adoptPtr(new FakeCCTiledLayerImpl(child->id())));
1574         OwnPtr<FakeCCTiledLayerImpl> child2Impl(adoptPtr(new FakeCCTiledLayerImpl(child2->id())));
1575         root->pushPropertiesTo(rootImpl.get());
1576         child->pushPropertiesTo(childImpl.get());
1577         child2->pushPropertiesTo(child2Impl.get());
1578
1579         for (unsigned i = 0; i < 3; ++i) {
1580             for (unsigned j = 0; j < 2; ++j)
1581                 EXPECT_FALSE(rootImpl->hasTextureIdForTileAt(i, j));
1582             EXPECT_FALSE(childImpl->hasTextureIdForTileAt(i, 0));
1583             EXPECT_FALSE(child2Impl->hasTextureIdForTileAt(i, 0));
1584         }
1585     }
1586     ccLayerTreeHost->commitComplete();
1587
1588     {
1589         DebugScopedSetImplThread implThread;
1590         ccLayerTreeHost->contentsTextureManager()->clearAllMemory(m_resourceProvider.get());
1591     }
1592     ccLayerTreeHost->setRootLayer(0);
1593     ccLayerTreeHost.clear();
1594     WebKit::WebCompositor::shutdown();
1595 }
1596
1597 class TrackingLayerPainter : public LayerPainterChromium {
1598 public:
1599     static PassOwnPtr<TrackingLayerPainter> create() { return adoptPtr(new TrackingLayerPainter()); }
1600
1601     virtual void paint(SkCanvas*, const IntRect& contentRect, FloatRect&) OVERRIDE
1602     {
1603         m_paintedRect = contentRect;
1604     }
1605
1606     const IntRect& paintedRect() const { return m_paintedRect; }
1607     void resetPaintedRect() { m_paintedRect = IntRect(); }
1608
1609 private:
1610     TrackingLayerPainter() { }
1611
1612     IntRect m_paintedRect;
1613 };
1614
1615 class UpdateTrackingTiledLayerChromium : public FakeTiledLayerChromium {
1616 public:
1617     explicit UpdateTrackingTiledLayerChromium(WebCore::CCPrioritizedTextureManager* manager)
1618         : FakeTiledLayerChromium(manager)
1619     {
1620         OwnPtr<TrackingLayerPainter> trackingLayerPainter(TrackingLayerPainter::create());
1621         m_trackingLayerPainter = trackingLayerPainter.get();
1622         m_layerTextureUpdater = BitmapCanvasLayerTextureUpdater::create(trackingLayerPainter.release());
1623     }
1624     virtual ~UpdateTrackingTiledLayerChromium() { }
1625
1626     TrackingLayerPainter* trackingLayerPainter() const { return m_trackingLayerPainter; }
1627
1628 protected:
1629     virtual WebCore::LayerTextureUpdater* textureUpdater() const OVERRIDE { return m_layerTextureUpdater.get(); }
1630
1631 private:
1632     TrackingLayerPainter* m_trackingLayerPainter;
1633     RefPtr<BitmapCanvasLayerTextureUpdater> m_layerTextureUpdater;
1634 };
1635
1636 TEST_F(TiledLayerChromiumTest, nonIntegerContentsScaleIsNotDistortedDuringPaint)
1637 {
1638     OwnPtr<CCPrioritizedTextureManager> textureManager(CCPrioritizedTextureManager::create(4000000, 4000000, CCRenderer::ContentPool));
1639
1640     RefPtr<UpdateTrackingTiledLayerChromium> layer = adoptRef(new UpdateTrackingTiledLayerChromium(textureManager.get()));
1641
1642     IntRect layerRect(0, 0, 30, 31);
1643     layer->setPosition(layerRect.location());
1644     layer->setBounds(layerRect.size());
1645     layer->setContentsScale(1.5);
1646
1647     IntRect contentRect(0, 0, 45, 47);
1648     EXPECT_EQ(contentRect.size(), layer->contentBounds());
1649     layer->setVisibleContentRect(contentRect);
1650
1651     layer->setTexturePriorities(m_priorityCalculator);
1652     textureManager->prioritizeTextures();
1653
1654     // Update the whole tile.
1655     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1656     layer->trackingLayerPainter()->resetPaintedRect();
1657
1658     EXPECT_INT_RECT_EQ(IntRect(), layer->trackingLayerPainter()->paintedRect());
1659
1660     {
1661         DebugScopedSetImplThread implThread;
1662         updateTextures();
1663     }
1664
1665     // Invalidate the entire layer in content space. When painting, the rect given to webkit should match the layer's bounds.
1666     layer->invalidateContentRect(contentRect);
1667     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1668
1669     EXPECT_INT_RECT_EQ(layerRect, layer->trackingLayerPainter()->paintedRect());
1670 }
1671
1672 TEST_F(TiledLayerChromiumTest, nonIntegerContentsScaleIsNotDistortedDuringInvalidation)
1673 {
1674     OwnPtr<CCPrioritizedTextureManager> textureManager(CCPrioritizedTextureManager::create(4000000, 4000000, CCRenderer::ContentPool));
1675
1676     RefPtr<UpdateTrackingTiledLayerChromium> layer = adoptRef(new UpdateTrackingTiledLayerChromium(textureManager.get()));
1677
1678     IntRect layerRect(0, 0, 30, 31);
1679     layer->setPosition(layerRect.location());
1680     layer->setBounds(layerRect.size());
1681     layer->setContentsScale(1.3f);
1682
1683     IntRect contentRect(IntPoint(), layer->contentBounds());
1684     layer->setVisibleContentRect(contentRect);
1685
1686     layer->setTexturePriorities(m_priorityCalculator);
1687     textureManager->prioritizeTextures();
1688
1689     // Update the whole tile.
1690     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1691     layer->trackingLayerPainter()->resetPaintedRect();
1692
1693     EXPECT_INT_RECT_EQ(IntRect(), layer->trackingLayerPainter()->paintedRect());
1694
1695     {
1696         DebugScopedSetImplThread implThread;
1697         updateTextures();
1698     }
1699
1700     // Invalidate the entire layer in layer space. When painting, the rect given to webkit should match the layer's bounds.
1701     layer->setNeedsDisplayRect(layerRect);
1702     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1703
1704     EXPECT_INT_RECT_EQ(layerRect, layer->trackingLayerPainter()->paintedRect());
1705 }
1706
1707 } // namespace