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