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