Unreviewed, rolling out r125230 and r125238.
[WebKit-https.git] / Source / WebKit / chromium / tests / TiledLayerChromiumTest.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "TiledLayerChromium.h"
28
29 #include "BitmapCanvasLayerTextureUpdater.h"
30 #include "CCAnimationTestCommon.h"
31 #include "CCLayerTreeTestCommon.h"
32 #include "CCTiledLayerTestCommon.h"
33 #include "FakeCCGraphicsContext.h"
34 #include "FakeCCLayerTreeHostClient.h"
35 #include "LayerPainterChromium.h"
36 #include "cc/CCOverdrawMetrics.h"
37 #include "cc/CCRenderingStats.h"
38 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
39 #include "cc/CCTextureUpdateController.h"
40 #include <gtest/gtest.h>
41 #include <public/WebCompositor.h>
42 #include <public/WebTransformationMatrix.h>
43
44 using namespace WebCore;
45 using namespace WebKitTests;
46 using namespace WTF;
47 using WebKit::WebTransformationMatrix;
48
49 #define EXPECT_EQ_RECT(a, b) \
50     EXPECT_EQ(a.x(), b.x()); \
51     EXPECT_EQ(a.y(), b.y()); \
52     EXPECT_EQ(a.width(), b.width()); \
53     EXPECT_EQ(a.height(), b.height());
54
55 namespace {
56
57 class TestCCOcclusionTracker : public CCOcclusionTracker {
58 public:
59     TestCCOcclusionTracker()
60         : CCOcclusionTracker(IntRect(0, 0, 1000, 1000), true)
61         , m_scissorRectInScreen(IntRect(0, 0, 1000, 1000))
62     {
63         // Pretend we have visited a render surface.
64         m_stack.append(StackObject());
65     }
66
67     void setOcclusion(const Region& occlusion) { m_stack.last().occlusionInScreen = occlusion; }
68
69 protected:
70     virtual IntRect layerScissorRectInTargetSurface(const LayerChromium* layer) const { return m_scissorRectInScreen; }
71
72 private:
73     IntRect m_scissorRectInScreen;
74 };
75
76 class TiledLayerChromiumTest : public testing::Test {
77 public:
78     TiledLayerChromiumTest()
79         : m_context(WebKit::createFakeCCGraphicsContext())
80     {
81         DebugScopedSetImplThread implThread;
82         m_resourceProvider = CCResourceProvider::create(m_context.get());
83     }
84
85     virtual ~TiledLayerChromiumTest()
86     {
87         DebugScopedSetImplThread implThread;
88         m_resourceProvider.clear();
89     }
90
91     void updateTextures(int count = 500)
92     {
93         CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, &m_queue, count);
94     }
95 public:
96     OwnPtr<CCGraphicsContext> m_context;
97     OwnPtr<CCResourceProvider> m_resourceProvider;
98     CCTextureUpdateQueue m_queue;
99     CCRenderingStats m_stats;
100     FakeTextureCopier m_copier;
101     FakeTextureUploader m_uploader;
102     CCPriorityCalculator m_priorityCalculator;
103 };
104
105
106
107 TEST_F(TiledLayerChromiumTest, pushDirtyTiles)
108 {
109     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
110     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
111     DebugScopedSetImplThread implThread;
112     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
113
114     // The tile size is 100x100, so this invalidates and then paints two tiles.
115     layer->setBounds(IntSize(100, 200));
116     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
117     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
118
119     layer->setTexturePriorities(m_priorityCalculator);
120     textureManager->prioritizeTextures();
121
122     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
123     updateTextures();
124     layer->pushPropertiesTo(layerImpl.get());
125
126     // We should have both tiles on the impl side.
127     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
128     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
129
130     // Invalidates both tiles...
131     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
132     // ....but then only update one of them.
133     layer->setTexturePriorities(m_priorityCalculator);
134     textureManager->prioritizeTextures();
135     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
136     layer->pushPropertiesTo(layerImpl.get());
137
138     // We should only have the first tile since the other tile was invalidated but not painted.
139     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
140     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
141 }
142
143 TEST_F(TiledLayerChromiumTest, pushOccludedDirtyTiles)
144 {
145     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
146     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
147     DebugScopedSetImplThread implThread;
148     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
149     TestCCOcclusionTracker occluded;
150
151     // The tile size is 100x100, so this invalidates and then paints two tiles.
152     layer->setBounds(IntSize(100, 200));
153     layer->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, idlePaintOutOfMemory)
501 {
502     // The tile size is 100x100. Setup 3x3 tiles with one 1x1 visible tile in the center.
503     IntSize contentBounds(300, 300);
504     IntRect contentRect(IntPoint::zero(), contentBounds);
505     IntRect visibleRect(100, 100, 100, 100);
506
507     // We have enough memory for only the visible rect, so we will run out of memory in first idle paint.
508     int memoryLimit = 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
509
510     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(memoryLimit, 1024, CCRenderer::ContentPool);
511     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
512     DebugScopedSetImplThread implThread;
513     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
514
515     // Invalidates 9 tiles and then paints one visible tile.
516     layer->setBounds(contentBounds);
517     layer->setVisibleContentRect(visibleRect);
518     layer->invalidateContentRect(contentRect);
519
520     layer->setTexturePriorities(m_priorityCalculator);
521     textureManager->prioritizeTextures();
522     layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
523
524     // Idle-painting should see no more priority tiles for painting.
525     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
526
527     updateTextures();
528     layer->pushPropertiesTo(layerImpl.get());
529
530     // We should have one tile on the impl side.
531     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
532
533     layer->setTexturePriorities(m_priorityCalculator);
534     textureManager->prioritizeTextures();
535     layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
536
537     // We shouldn't signal we need another idle paint.
538     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
539 }
540
541 TEST_F(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
542 {
543     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(20000, 1024, CCRenderer::ContentPool);
544     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
545     DebugScopedSetImplThread implThread;
546     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
547
548     bool animating[2] = {false, true};
549     for (int i = 0; i < 2; i++) {
550         // Pretend the layer is animating.
551         layer->setDrawTransformIsAnimating(animating[i]);
552
553         // The layer's bounds are empty.
554         IntRect contentRect;
555
556         layer->setBounds(contentRect.size());
557         layer->setVisibleContentRect(contentRect);
558         layer->invalidateContentRect(contentRect);
559
560         layer->setTexturePriorities(m_priorityCalculator);
561         textureManager->prioritizeTextures();
562
563         // Empty layers don't paint or idle-paint.
564         layer->updateContentRect(m_queue, contentRect, 0, m_stats);
565
566         // Empty layers don't have tiles.
567         EXPECT_EQ(0u, layer->numPaintedTiles());
568
569         // Empty layers don't need prepaint.
570         EXPECT_FALSE(layer->needsIdlePaint(contentRect));
571
572         layer->pushPropertiesTo(layerImpl.get());
573
574         // Empty layers don't have tiles.
575         EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
576     }
577 }
578
579 TEST_F(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
580 {
581     IntSize contentBounds(100, 100);
582     IntRect contentRect(IntPoint::zero(), contentBounds);
583
584     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(20000, 1024, CCRenderer::ContentPool);
585     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
586     DebugScopedSetImplThread implThread;
587     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
588
589     // Invalidate the layer but make none of it visible, so nothing paints.
590     IntRect visibleRect;
591
592     layer->setBounds(contentBounds);
593     layer->setVisibleContentRect(visibleRect);
594     layer->invalidateContentRect(contentRect);
595
596     for (int i = 0; i < 2; i++) {
597         // Paint / idle-paint.
598         layer->setTexturePriorities(m_priorityCalculator);
599         textureManager->prioritizeTextures();
600         layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
601
602         // Non-visible layers don't need idle paint.
603         EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
604
605         layer->pushPropertiesTo(layerImpl.get());
606
607         // We should not have any tiles pushed since the layer is not visible.
608         EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
609     }
610 }
611
612 static void testHaveOuterTiles(FakeCCTiledLayerImpl* layerImpl, int width, int height, int have)
613 {
614     for (int i = 0; i < width; ++i) {
615         for (int j = 0; j < height; ++j) {
616             bool hasTile = i < have || j < have || i >= width - have || j >= height - have;
617             EXPECT_EQ(hasTile, layerImpl->hasTileAt(i, j));
618         }
619     }
620 }
621
622 TEST_F(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers)
623 {
624     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(8000*8000*8, 1024, CCRenderer::ContentPool);
625     DebugScopedSetImplThread implThread;
626
627     int tileWidth = FakeTiledLayerChromium::tileSize().width();
628     int tileHeight = FakeTiledLayerChromium::tileSize().height();
629     int width[] = { 1, 2, 3, 4, 9, 10, 0 };
630     int height[] = { 1, 2, 3, 4, 9, 10, 0 };
631
632     for (int j = 0; height[j]; ++j) {
633         for (int i = 0; width[i]; ++i) {
634             RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
635             OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
636
637             // Pretend the layer is animating.
638             layer->setDrawTransformIsAnimating(true);
639
640             IntSize contentBounds(width[i] * tileWidth, height[j] * tileHeight);
641             IntRect contentRect(IntPoint::zero(), contentBounds);
642             IntRect visibleRect;
643
644             layer->setBounds(contentBounds);
645             layer->setVisibleContentRect(visibleRect);
646             layer->invalidateContentRect(contentRect);
647
648             layer->setTexturePriorities(m_priorityCalculator);
649             textureManager->prioritizeTextures();
650
651             // If idlePaintRect gives back a non-empty result then we should paint it. Otherwise,
652             // we shoud paint nothing.
653             bool shouldPrepaint = !layer->idlePaintRect(visibleRect).isEmpty();
654
655             // Normally we don't allow non-visible layers to pre-paint, but if they are animating then we should.
656             EXPECT_EQ(shouldPrepaint, layer->needsIdlePaint(visibleRect));
657
658             // If the layer is to be prepainted at all, then after four updates we should have the outer row/columns painted.
659             for (int k = 0; k < 4; ++k) {
660                 layer->setTexturePriorities(m_priorityCalculator);
661                 textureManager->prioritizeTextures();
662
663                 layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
664                 updateTextures();
665                 layer->pushPropertiesTo(layerImpl.get());
666             }
667
668             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
669
670             // We don't currently idle paint past the outermost tiles.
671             EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
672             for (int k = 0; k < 4; ++k) {
673                 layer->setTexturePriorities(m_priorityCalculator);
674                 textureManager->prioritizeTextures();
675
676                 layer->updateContentRect(m_queue, visibleRect, 0, m_stats);
677                 updateTextures();
678                 layer->pushPropertiesTo(layerImpl.get());
679             }
680
681             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
682         }
683     }
684 }
685
686 TEST_F(TiledLayerChromiumTest, invalidateFromPrepare)
687 {
688     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
689     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
690     DebugScopedSetImplThread implThread;
691     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
692
693     // The tile size is 100x100, so this invalidates and then paints two tiles.
694     layer->setBounds(IntSize(100, 200));
695     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
696     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
697     layer->setTexturePriorities(m_priorityCalculator);
698     textureManager->prioritizeTextures();
699     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
700     updateTextures(1000);
701     layer->pushPropertiesTo(layerImpl.get());
702
703     // We should have both tiles on the impl side.
704     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
705     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
706
707     layer->fakeLayerTextureUpdater()->clearPrepareCount();
708     // Invoke updateContentRect again. As the layer is valid updateContentRect shouldn't be invoked on
709     // the LayerTextureUpdater.
710     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
711     updateTextures(1000);
712     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareCount());
713
714     layer->invalidateContentRect(IntRect(0, 0, 50, 50));
715     // setRectToInvalidate triggers invalidateContentRect() being invoked from updateContentRect.
716     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(25, 25, 50, 50), layer.get());
717     layer->fakeLayerTextureUpdater()->clearPrepareCount();
718     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
719     updateTextures(1000);
720     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
721     layer->fakeLayerTextureUpdater()->clearPrepareCount();
722     // The layer should still be invalid as updateContentRect invoked invalidate.
723     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
724     updateTextures(1000);
725     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
726 }
727
728 TEST_F(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
729 {
730     // The updateRect (that indicates what was actually painted) should be in
731     // layer space, not the content space.
732
733     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
734     RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get()));
735     DebugScopedSetImplThread implThread;
736
737     IntRect layerBounds(0, 0, 300, 200);
738     IntRect contentBounds(0, 0, 200, 250);
739
740     layer->setBounds(layerBounds.size());
741     layer->setContentBounds(contentBounds.size());
742     layer->setVisibleContentRect(contentBounds);
743
744     // On first update, the updateRect includes all tiles, even beyond the boundaries of the layer.
745     // However, it should still be in layer space, not content space.
746     layer->invalidateContentRect(contentBounds);
747
748     layer->setTexturePriorities(m_priorityCalculator);
749     textureManager->prioritizeTextures();
750     layer->updateContentRect(m_queue, contentBounds, 0, m_stats);
751     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 300, 300 * 0.8), layer->updateRect());
752     updateTextures();
753
754     // After the tiles are updated once, another invalidate only needs to update the bounds of the layer.
755     layer->setTexturePriorities(m_priorityCalculator);
756     textureManager->prioritizeTextures();
757     layer->invalidateContentRect(contentBounds);
758     layer->updateContentRect(m_queue, contentBounds, 0, m_stats);
759     EXPECT_FLOAT_RECT_EQ(FloatRect(layerBounds), layer->updateRect());
760     updateTextures();
761
762     // Partial re-paint should also be represented by the updateRect in layer space, not content space.
763     IntRect partialDamage(30, 100, 10, 10);
764     layer->invalidateContentRect(partialDamage);
765     layer->setTexturePriorities(m_priorityCalculator);
766     textureManager->prioritizeTextures();
767     layer->updateContentRect(m_queue, contentBounds, 0, m_stats);
768     EXPECT_FLOAT_RECT_EQ(FloatRect(45, 80, 15, 8), layer->updateRect());
769 }
770
771 TEST_F(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
772 {
773     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
774     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
775     DebugScopedSetImplThread implThread;
776     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
777
778     // Create a layer with one tile.
779     layer->setBounds(IntSize(100, 100));
780     layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
781
782     // Invalidate the entire layer.
783     layer->setNeedsDisplay();
784     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
785
786     // Push the tiles to the impl side and check that there is exactly one.
787     layer->setTexturePriorities(m_priorityCalculator);
788     textureManager->prioritizeTextures();
789     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 100), 0, m_stats);
790     updateTextures();
791     layer->pushPropertiesTo(layerImpl.get());
792     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
793     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
794     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
795     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
796
797     // Change the contents scale and verify that the content rectangle requiring painting
798     // is not scaled.
799     layer->setContentsScale(2);
800     layer->setVisibleContentRect(IntRect(0, 0, 200, 200));
801     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
802
803     // The impl side should get 2x2 tiles now.
804     layer->setTexturePriorities(m_priorityCalculator);
805     textureManager->prioritizeTextures();
806     layer->updateContentRect(m_queue, IntRect(0, 0, 200, 200), 0, m_stats);
807     updateTextures();
808     layer->pushPropertiesTo(layerImpl.get());
809     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
810     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
811     EXPECT_TRUE(layerImpl->hasTileAt(1, 0));
812     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
813
814     // Invalidate the entire layer again, but do not paint. All tiles should be gone now from the
815     // impl side.
816     layer->setNeedsDisplay();
817     layer->setTexturePriorities(m_priorityCalculator);
818     layer->updateContentRect(m_queue, IntRect(1, 0, 0, 1), 0, m_stats);
819     textureManager->prioritizeTextures();
820
821     layer->pushPropertiesTo(layerImpl.get());
822     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
823     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
824     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
825     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
826 }
827
828 TEST_F(TiledLayerChromiumTest, skipsDrawGetsReset)
829 {
830     // Initialize without threading support.
831     WebKit::WebCompositor::initialize(0);
832     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
833     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, CCLayerTreeSettings());
834     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
835
836     // Create two 300 x 300 tiled layers.
837     IntSize contentBounds(300, 300);
838     IntRect contentRect(IntPoint::zero(), contentBounds);
839
840     // We have enough memory for only one of the two layers.
841     int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
842
843     RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
844     RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
845     rootLayer->addChild(childLayer);
846
847     rootLayer->setBounds(contentBounds);
848     rootLayer->setVisibleContentRect(contentRect);
849     rootLayer->setPosition(FloatPoint(0, 0));
850     childLayer->setBounds(contentBounds);
851     childLayer->setVisibleContentRect(contentRect);
852     childLayer->setPosition(FloatPoint(0, 0));
853     rootLayer->invalidateContentRect(contentRect);
854     childLayer->invalidateContentRect(contentRect);
855
856     ccLayerTreeHost->setRootLayer(rootLayer);
857     ccLayerTreeHost->setViewportSize(IntSize(300, 300), IntSize(300, 300));
858
859     ccLayerTreeHost->updateLayers(m_queue, memoryLimit);
860
861     // We'll skip the root layer.
862     EXPECT_TRUE(rootLayer->skipsDraw());
863     EXPECT_FALSE(childLayer->skipsDraw());
864
865     ccLayerTreeHost->commitComplete();
866
867     // Remove the child layer.
868     rootLayer->removeAllChildren();
869
870     ccLayerTreeHost->updateLayers(m_queue, memoryLimit);
871     EXPECT_FALSE(rootLayer->skipsDraw());
872
873     ccLayerTreeHost->contentsTextureManager()->clearAllMemory(m_resourceProvider.get());
874     ccLayerTreeHost->setRootLayer(0);
875     ccLayerTreeHost.clear();
876     WebKit::WebCompositor::shutdown();
877 }
878
879 TEST_F(TiledLayerChromiumTest, resizeToSmaller)
880 {
881     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(60*1024*1024, 1024, CCRenderer::ContentPool);
882     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
883
884     layer->setBounds(IntSize(700, 700));
885     layer->setVisibleContentRect(IntRect(0, 0, 700, 700));
886     layer->invalidateContentRect(IntRect(0, 0, 700, 700));
887
888     layer->setTexturePriorities(m_priorityCalculator);
889     textureManager->prioritizeTextures();
890     layer->updateContentRect(m_queue, IntRect(0, 0, 700, 700), 0, m_stats);
891
892     layer->setBounds(IntSize(200, 200));
893     layer->invalidateContentRect(IntRect(0, 0, 200, 200));
894 }
895
896 TEST_F(TiledLayerChromiumTest, hugeLayerUpdateCrash)
897 {
898     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(60*1024*1024, 1024, CCRenderer::ContentPool);
899     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
900
901     int size = 1 << 30;
902     layer->setBounds(IntSize(size, size));
903     layer->setVisibleContentRect(IntRect(0, 0, 700, 700));
904     layer->invalidateContentRect(IntRect(0, 0, size, size));
905
906     // Ensure no crash for bounds where size * size would overflow an int.
907     layer->setTexturePriorities(m_priorityCalculator);
908     textureManager->prioritizeTextures();
909     layer->updateContentRect(m_queue, IntRect(0, 0, 700, 700), 0, m_stats);
910 }
911
912 TEST_F(TiledLayerChromiumTest, partialUpdates)
913 {
914     // Initialize without threading support.
915     WebKit::WebCompositor::initialize(0);
916
917     CCLayerTreeSettings settings;
918     settings.maxPartialTextureUpdates = 4;
919
920     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
921     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
922     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
923
924     // Create one 300 x 200 tiled layer with 3 x 2 tiles.
925     IntSize contentBounds(300, 200);
926     IntRect contentRect(IntPoint::zero(), contentBounds);
927
928     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
929     layer->setBounds(contentBounds);
930     layer->setPosition(FloatPoint(0, 0));
931     layer->setVisibleContentRect(contentRect);
932     layer->invalidateContentRect(contentRect);
933
934     ccLayerTreeHost->setRootLayer(layer);
935     ccLayerTreeHost->setViewportSize(IntSize(300, 200), IntSize(300, 200));
936
937     // Full update of all 6 tiles.
938     ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
939     {
940         DebugScopedSetImplThread implThread;
941         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
942         updateTextures(4);
943         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
944         EXPECT_TRUE(m_queue.hasMoreUpdates());
945         layer->fakeLayerTextureUpdater()->clearUpdateCount();
946         updateTextures(4);
947         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
948         EXPECT_FALSE(m_queue.hasMoreUpdates());
949         layer->fakeLayerTextureUpdater()->clearUpdateCount();
950         layer->pushPropertiesTo(layerImpl.get());
951     }
952     ccLayerTreeHost->commitComplete();
953
954     // Full update of 3 tiles and partial update of 3 tiles.
955     layer->invalidateContentRect(IntRect(0, 0, 300, 150));
956     ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
957     {
958         DebugScopedSetImplThread implThread;
959         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
960         updateTextures(4);
961         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
962         EXPECT_TRUE(m_queue.hasMoreUpdates());
963         layer->fakeLayerTextureUpdater()->clearUpdateCount();
964         updateTextures(4);
965         EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
966         EXPECT_FALSE(m_queue.hasMoreUpdates());
967         layer->fakeLayerTextureUpdater()->clearUpdateCount();
968         layer->pushPropertiesTo(layerImpl.get());
969     }
970     ccLayerTreeHost->commitComplete();
971
972     // Partial update of 6 tiles.
973     layer->invalidateContentRect(IntRect(50, 50, 200, 100));
974     {
975         DebugScopedSetImplThread implThread;
976         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
977         ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
978         updateTextures(4);
979         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
980         EXPECT_TRUE(m_queue.hasMoreUpdates());
981         layer->fakeLayerTextureUpdater()->clearUpdateCount();
982         updateTextures(4);
983         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
984         EXPECT_FALSE(m_queue.hasMoreUpdates());
985         layer->fakeLayerTextureUpdater()->clearUpdateCount();
986         layer->pushPropertiesTo(layerImpl.get());
987     }
988     ccLayerTreeHost->commitComplete();
989
990     // Checkerboard all tiles.
991     layer->invalidateContentRect(IntRect(0, 0, 300, 200));
992     {
993         DebugScopedSetImplThread implThread;
994         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
995         layer->pushPropertiesTo(layerImpl.get());
996     }
997     ccLayerTreeHost->commitComplete();
998
999     // Partial update of 6 checkerboard tiles.
1000     layer->invalidateContentRect(IntRect(50, 50, 200, 100));
1001     {
1002         DebugScopedSetImplThread implThread;
1003         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
1004         ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
1005         updateTextures(4);
1006         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
1007         EXPECT_TRUE(m_queue.hasMoreUpdates());
1008         layer->fakeLayerTextureUpdater()->clearUpdateCount();
1009         updateTextures(4);
1010         EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
1011         EXPECT_FALSE(m_queue.hasMoreUpdates());
1012         layer->fakeLayerTextureUpdater()->clearUpdateCount();
1013         layer->pushPropertiesTo(layerImpl.get());
1014     }
1015     ccLayerTreeHost->commitComplete();
1016
1017     // Partial update of 4 tiles.
1018     layer->invalidateContentRect(IntRect(50, 50, 100, 100));
1019     {
1020         DebugScopedSetImplThread implThread;
1021         OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(1)));
1022         ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
1023         updateTextures(4);
1024         EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
1025         EXPECT_FALSE(m_queue.hasMoreUpdates());
1026         layer->fakeLayerTextureUpdater()->clearUpdateCount();
1027         layer->pushPropertiesTo(layerImpl.get());
1028     }
1029     ccLayerTreeHost->commitComplete();
1030
1031     {
1032         DebugScopedSetImplThread implThread;
1033         ccLayerTreeHost->contentsTextureManager()->clearAllMemory(m_resourceProvider.get());
1034     }
1035     ccLayerTreeHost->setRootLayer(0);
1036     ccLayerTreeHost.clear();
1037     WebKit::WebCompositor::shutdown();
1038 }
1039
1040 TEST_F(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
1041 {
1042     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1043     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1044
1045     // The tile size is 100x100, so this invalidates and then paints two tiles.
1046     layer->setBounds(IntSize(100, 200));
1047     layer->setDrawableContentRect(IntRect(0, 0, 100, 200));
1048     layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
1049     layer->invalidateContentRect(IntRect(0, 0, 100, 200));
1050
1051     layer->setTexturePriorities(m_priorityCalculator);
1052     textureManager->prioritizeTextures();
1053     layer->updateContentRect(m_queue, IntRect(0, 0, 100, 200), 0, m_stats);
1054     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1055 }
1056
1057 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
1058 {
1059     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1060     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1061     TestCCOcclusionTracker occluded;
1062
1063     // The tile size is 100x100.
1064
1065     layer->setBounds(IntSize(600, 600));
1066
1067     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1068     layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1069     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1070     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1071
1072     layer->setTexturePriorities(m_priorityCalculator);
1073     textureManager->prioritizeTextures();
1074     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1075     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1076
1077     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1078     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1079     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1080
1081     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1082     layer->setTexturePriorities(m_priorityCalculator);
1083     textureManager->prioritizeTextures();
1084
1085     occluded.setOcclusion(IntRect(250, 200, 300, 100));
1086     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1087     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1088     EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1089
1090     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1091     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000, 1);
1092     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1093
1094     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1095     layer->setTexturePriorities(m_priorityCalculator);
1096     textureManager->prioritizeTextures();
1097
1098     occluded.setOcclusion(IntRect(250, 250, 300, 100));
1099     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1100     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1101     EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
1102
1103     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1104     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000 + 360000, 1);
1105     EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
1106 }
1107
1108 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
1109 {
1110     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1111     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1112     TestCCOcclusionTracker occluded;
1113
1114     // The tile size is 100x100.
1115
1116     layer->setBounds(IntSize(600, 600));
1117
1118     // The partially occluded tiles (by the 150 occlusion height) are visible beyond the occlusion, so not culled.
1119     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1120     layer->setDrawableContentRect(IntRect(0, 0, 600, 360));
1121     layer->setVisibleContentRect(IntRect(0, 0, 600, 360));
1122     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1123
1124     layer->setTexturePriorities(m_priorityCalculator);
1125     textureManager->prioritizeTextures();
1126     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 360), &occluded, m_stats);
1127     EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1128
1129     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1130     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000, 1);
1131     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1132
1133     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1134
1135     // Now the visible region stops at the edge of the occlusion so the partly visible tiles become fully occluded.
1136     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1137     layer->setDrawableContentRect(IntRect(0, 0, 600, 350));
1138     layer->setVisibleContentRect(IntRect(0, 0, 600, 350));
1139     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1140     layer->setTexturePriorities(m_priorityCalculator);
1141     textureManager->prioritizeTextures();
1142     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 350), &occluded, m_stats);
1143     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1144
1145     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1146     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000, 1);
1147     EXPECT_EQ(3 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1148
1149     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1150
1151     // Now the visible region is even smaller than the occlusion, it should have the same result.
1152     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1153     layer->setDrawableContentRect(IntRect(0, 0, 600, 340));
1154     layer->setVisibleContentRect(IntRect(0, 0, 600, 340));
1155     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1156     layer->setTexturePriorities(m_priorityCalculator);
1157     textureManager->prioritizeTextures();
1158     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 340), &occluded, m_stats);
1159     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1160
1161     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1162     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000 + 180000, 1);
1163     EXPECT_EQ(3 + 6 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1164
1165 }
1166
1167 TEST_F(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
1168 {
1169     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1170     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1171     TestCCOcclusionTracker occluded;
1172
1173     // The tile size is 100x100.
1174
1175     layer->setBounds(IntSize(600, 600));
1176
1177     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1178     layer->setDrawableContentRect(IntRect(0, 0, 600, 600));
1179     layer->setVisibleContentRect(IntRect(0, 0, 600, 600));
1180     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1181     layer->setTexturePriorities(m_priorityCalculator);
1182     textureManager->prioritizeTextures();
1183     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1184     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1185     {
1186         DebugScopedSetImplThread implThread;
1187         updateTextures();
1188     }
1189
1190     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1191     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1192     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1193
1194     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1195     layer->setTexturePriorities(m_priorityCalculator);
1196     textureManager->prioritizeTextures();
1197
1198     // Repaint without marking it dirty. The 3 culled tiles will be pre-painted now.
1199     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1200     EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1201
1202     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1203     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1204     EXPECT_EQ(6, occluded.overdrawMetrics().tilesCulledForUpload());
1205 }
1206
1207 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
1208 {
1209     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1210     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1211     TestCCOcclusionTracker occluded;
1212
1213     // The tile size is 100x100.
1214
1215     // This makes sure the painting works when the occluded region (in screen space)
1216     // is transformed differently than the layer.
1217     layer->setBounds(IntSize(600, 600));
1218     WebTransformationMatrix screenTransform;
1219     screenTransform.scale(0.5);
1220     layer->setScreenSpaceTransform(screenTransform);
1221     layer->setDrawTransform(screenTransform);
1222
1223     occluded.setOcclusion(IntRect(100, 100, 150, 50));
1224     layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1225     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1226     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1227     layer->setTexturePriorities(m_priorityCalculator);
1228     textureManager->prioritizeTextures();
1229     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1230     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1231
1232     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1233     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1234     EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1235 }
1236
1237 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
1238 {
1239     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1240     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1241     TestCCOcclusionTracker occluded;
1242
1243     // The tile size is 100x100.
1244
1245     // This makes sure the painting works when the content space is scaled to
1246     // a different layer space. In this case tiles are scaled to be 200x200
1247     // pixels, which means none should be occluded.
1248     layer->setContentsScale(0.5);
1249     layer->setBounds(IntSize(600, 600));
1250     WebTransformationMatrix drawTransform;
1251     drawTransform.scale(1 / layer->contentsScale());
1252     layer->setDrawTransform(drawTransform);
1253     layer->setScreenSpaceTransform(drawTransform);
1254
1255     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1256     layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1257     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1258     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1259     layer->setTexturePriorities(m_priorityCalculator);
1260     textureManager->prioritizeTextures();
1261     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1262     // The content is half the size of the layer (so the number of tiles is fewer).
1263     // In this case, the content is 300x300, and since the tile size is 100, the
1264     // number of tiles 3x3.
1265     EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
1266
1267     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1268     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000, 1);
1269     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1270
1271     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1272
1273     // This makes sure the painting works when the content space is scaled to
1274     // a different layer space. In this case the occluded region catches the
1275     // blown up tiles.
1276     occluded.setOcclusion(IntRect(200, 200, 300, 200));
1277     layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1278     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1279     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1280     layer->setTexturePriorities(m_priorityCalculator);
1281     textureManager->prioritizeTextures();
1282     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1283     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1284
1285     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1286     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000, 1);
1287     EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
1288
1289     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1290
1291     // This makes sure content scaling and transforms work together.
1292     WebTransformationMatrix screenTransform;
1293     screenTransform.scale(0.5);
1294     layer->setScreenSpaceTransform(screenTransform);
1295     layer->setDrawTransform(screenTransform);
1296
1297     occluded.setOcclusion(IntRect(100, 100, 150, 100));
1298     layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1299     layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1300     layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1301     layer->setTexturePriorities(m_priorityCalculator);
1302     textureManager->prioritizeTextures();
1303     layer->updateContentRect(m_queue, IntRect(0, 0, 600, 600), &occluded, m_stats);
1304     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1305
1306     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1307     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000 + 80000, 1);
1308     EXPECT_EQ(1 + 1, occluded.overdrawMetrics().tilesCulledForUpload());
1309 }
1310
1311 TEST_F(TiledLayerChromiumTest, visibleContentOpaqueRegion)
1312 {
1313     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1314     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1315     TestCCOcclusionTracker occluded;
1316     DebugScopedSetImplThread implThread;
1317
1318     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1319
1320     IntRect opaquePaintRect;
1321     Region opaqueContents;
1322
1323     IntRect contentBounds = IntRect(0, 0, 100, 200);
1324     IntRect visibleBounds = IntRect(0, 0, 100, 150);
1325
1326     layer->setBounds(contentBounds.size());
1327     layer->setDrawableContentRect(visibleBounds);
1328     layer->setVisibleContentRect(visibleBounds);
1329     layer->setDrawOpacity(1);
1330
1331     layer->setTexturePriorities(m_priorityCalculator);
1332     textureManager->prioritizeTextures();
1333
1334     // If the layer doesn't paint opaque content, then the visibleContentOpaqueRegion should be empty.
1335     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1336     layer->invalidateContentRect(contentBounds);
1337     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1338     opaqueContents = layer->visibleContentOpaqueRegion();
1339     EXPECT_TRUE(opaqueContents.isEmpty());
1340
1341     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
1342     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1343     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1);
1344     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1345
1346     // visibleContentOpaqueRegion should match the visible part of what is painted opaque.
1347     opaquePaintRect = IntRect(10, 10, 90, 190);
1348     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
1349     layer->invalidateContentRect(contentBounds);
1350     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1351     updateTextures();
1352     opaqueContents = layer->visibleContentOpaqueRegion();
1353     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1354     EXPECT_EQ(1u, opaqueContents.rects().size());
1355
1356     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1357     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1358     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1359     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1360
1361     // If we paint again without invalidating, the same stuff should be opaque.
1362     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1363     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1364     updateTextures();
1365     opaqueContents = layer->visibleContentOpaqueRegion();
1366     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1367     EXPECT_EQ(1u, opaqueContents.rects().size());
1368
1369     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1370     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1371     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1372     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1373
1374     // If we repaint a non-opaque part of the tile, then it shouldn't lose its opaque-ness. And other tiles should
1375     // not be affected.
1376     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1377     layer->invalidateContentRect(IntRect(0, 0, 1, 1));
1378     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1379     updateTextures();
1380     opaqueContents = layer->visibleContentOpaqueRegion();
1381     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1382     EXPECT_EQ(1u, opaqueContents.rects().size());
1383
1384     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
1385     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1386     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1, 1);
1387     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1388
1389     // If we repaint an opaque part of the tile, then it should lose its opaque-ness. But other tiles should still
1390     // not be affected.
1391     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1392     layer->invalidateContentRect(IntRect(10, 10, 1, 1));
1393     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1394     updateTextures();
1395     opaqueContents = layer->visibleContentOpaqueRegion();
1396     EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
1397     EXPECT_EQ(1u, opaqueContents.rects().size());
1398
1399     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1400     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1401     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1402     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1403 }
1404
1405 TEST_F(TiledLayerChromiumTest, pixelsPaintedMetrics)
1406 {
1407     OwnPtr<CCPrioritizedTextureManager> textureManager = CCPrioritizedTextureManager::create(4*1024*1024, 1024, CCRenderer::ContentPool);
1408     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1409     TestCCOcclusionTracker occluded;
1410     DebugScopedSetImplThread implThread;
1411
1412     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1413
1414     IntRect opaquePaintRect;
1415     Region opaqueContents;
1416
1417     IntRect contentBounds = IntRect(0, 0, 100, 300);
1418     IntRect visibleBounds = IntRect(0, 0, 100, 300);
1419
1420     layer->setBounds(contentBounds.size());
1421     layer->setDrawableContentRect(visibleBounds);
1422     layer->setVisibleContentRect(visibleBounds);
1423     layer->setDrawOpacity(1);
1424
1425     layer->setTexturePriorities(m_priorityCalculator);
1426     textureManager->prioritizeTextures();
1427
1428     // Invalidates and paints the whole layer.
1429     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1430     layer->invalidateContentRect(contentBounds);
1431     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1432     updateTextures();
1433     opaqueContents = layer->visibleContentOpaqueRegion();
1434     EXPECT_TRUE(opaqueContents.isEmpty());
1435
1436     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
1437     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1438     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000, 1);
1439     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1440
1441     // Invalidates an area on the top and bottom tile, which will cause us to paint the tile in the middle,
1442     // even though it is not dirty and will not be uploaded.
1443     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1444     layer->invalidateContentRect(IntRect(0, 0, 1, 1));
1445     layer->invalidateContentRect(IntRect(50, 200, 10, 10));
1446     layer->updateContentRect(m_queue, contentBounds, &occluded, m_stats);
1447     updateTextures();
1448     opaqueContents = layer->visibleContentOpaqueRegion();
1449     EXPECT_TRUE(opaqueContents.isEmpty());
1450
1451     // The middle tile was painted even though not invalidated.
1452     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1);
1453     // The pixels uploaded will not include the non-invalidated tile in the middle.
1454     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1455     EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000 + 1 + 100, 1);
1456     EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1457 }
1458
1459 TEST_F(TiledLayerChromiumTest, dontAllocateContentsWhenTargetSurfaceCantBeAllocated)
1460 {
1461     // Initialize without threading support.
1462     WebKit::WebCompositor::initialize(0);
1463
1464     // Tile size is 100x100.
1465     IntRect rootRect(0, 0, 300, 200);
1466     IntRect childRect(0, 0, 300, 100);
1467     IntRect child2Rect(0, 100, 300, 100);
1468
1469     CCLayerTreeSettings settings;
1470     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
1471     OwnPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
1472     ASSERT_TRUE(ccLayerTreeHost->initializeLayerRendererIfNeeded());
1473
1474     RefPtr<FakeTiledLayerChromium> root = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1475     RefPtr<LayerChromium> surface = LayerChromium::create();
1476     RefPtr<FakeTiledLayerChromium> child = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1477     RefPtr<FakeTiledLayerChromium> child2 = adoptRef(new FakeTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1478
1479     root->setBounds(rootRect.size());
1480     root->setAnchorPoint(FloatPoint());
1481     root->setDrawableContentRect(rootRect);
1482     root->setVisibleContentRect(rootRect);
1483     root->addChild(surface);
1484
1485     surface->setForceRenderSurface(true);
1486     surface->setAnchorPoint(FloatPoint());
1487     surface->setOpacity(0.5);
1488     surface->addChild(child);
1489     surface->addChild(child2);
1490
1491     child->setBounds(childRect.size());
1492     child->setAnchorPoint(FloatPoint());
1493     child->setPosition(childRect.location());
1494     child->setVisibleContentRect(childRect);
1495     child->setDrawableContentRect(rootRect);
1496
1497     child2->setBounds(child2Rect.size());
1498     child2->setAnchorPoint(FloatPoint());
1499     child2->setPosition(child2Rect.location());
1500     child2->setVisibleContentRect(child2Rect);
1501     child2->setDrawableContentRect(rootRect);
1502
1503     ccLayerTreeHost->setRootLayer(root);
1504     ccLayerTreeHost->setViewportSize(rootRect.size(), rootRect.size());
1505
1506     // With a huge memory limit, all layers should update and push their textures.
1507     root->invalidateContentRect(rootRect);
1508     child->invalidateContentRect(childRect);
1509     child2->invalidateContentRect(child2Rect);
1510     ccLayerTreeHost->updateLayers(m_queue, std::numeric_limits<size_t>::max());
1511     {
1512         DebugScopedSetImplThread implThread;
1513         updateTextures(1000);
1514         EXPECT_EQ(6, root->fakeLayerTextureUpdater()->updateCount());
1515         EXPECT_EQ(3, child->fakeLayerTextureUpdater()->updateCount());
1516         EXPECT_EQ(3, child2->fakeLayerTextureUpdater()->updateCount());
1517         EXPECT_FALSE(m_queue.hasMoreUpdates());
1518
1519         root->fakeLayerTextureUpdater()->clearUpdateCount();
1520         child->fakeLayerTextureUpdater()->clearUpdateCount();
1521         child2->fakeLayerTextureUpdater()->clearUpdateCount();
1522
1523         OwnPtr<FakeCCTiledLayerImpl> rootImpl(adoptPtr(new FakeCCTiledLayerImpl(root->id())));
1524         OwnPtr<FakeCCTiledLayerImpl> childImpl(adoptPtr(new FakeCCTiledLayerImpl(child->id())));
1525         OwnPtr<FakeCCTiledLayerImpl> child2Impl(adoptPtr(new FakeCCTiledLayerImpl(child2->id())));
1526         root->pushPropertiesTo(rootImpl.get());
1527         child->pushPropertiesTo(childImpl.get());
1528         child2->pushPropertiesTo(child2Impl.get());
1529
1530         for (unsigned i = 0; i < 3; ++i) {
1531             for (unsigned j = 0; j < 2; ++j)
1532                 EXPECT_TRUE(rootImpl->hasTextureIdForTileAt(i, j));
1533             EXPECT_TRUE(childImpl->hasTextureIdForTileAt(i, 0));
1534             EXPECT_TRUE(child2Impl->hasTextureIdForTileAt(i, 0));
1535         }
1536     }
1537     ccLayerTreeHost->commitComplete();
1538
1539     // With a memory limit that includes only the root layer (3x2 tiles) and half the surface that
1540     // the child layers draw into, the child layers will not be allocated. If the surface isn't
1541     // accounted for, then one of the children would fit within the memory limit.
1542     root->invalidateContentRect(rootRect);
1543     child->invalidateContentRect(childRect);
1544     child2->invalidateContentRect(child2Rect);
1545     ccLayerTreeHost->updateLayers(m_queue, (3 * 2 + 3 * 1) * (100 * 100) * 4);
1546     {
1547         DebugScopedSetImplThread implThread;
1548         updateTextures(1000);
1549         EXPECT_EQ(6, root->fakeLayerTextureUpdater()->updateCount());
1550         EXPECT_EQ(0, child->fakeLayerTextureUpdater()->updateCount());
1551         EXPECT_EQ(0, child2->fakeLayerTextureUpdater()->updateCount());
1552         EXPECT_FALSE(m_queue.hasMoreUpdates());
1553
1554         root->fakeLayerTextureUpdater()->clearUpdateCount();
1555         child->fakeLayerTextureUpdater()->clearUpdateCount();
1556         child2->fakeLayerTextureUpdater()->clearUpdateCount();
1557
1558         OwnPtr<FakeCCTiledLayerImpl> rootImpl(adoptPtr(new FakeCCTiledLayerImpl(root->id())));
1559         OwnPtr<FakeCCTiledLayerImpl> childImpl(adoptPtr(new FakeCCTiledLayerImpl(child->id())));
1560         OwnPtr<FakeCCTiledLayerImpl> child2Impl(adoptPtr(new FakeCCTiledLayerImpl(child2->id())));
1561         root->pushPropertiesTo(rootImpl.get());
1562         child->pushPropertiesTo(childImpl.get());
1563         child2->pushPropertiesTo(child2Impl.get());
1564
1565         for (unsigned i = 0; i < 3; ++i) {
1566             for (unsigned j = 0; j < 2; ++j)
1567                 EXPECT_TRUE(rootImpl->hasTextureIdForTileAt(i, j));
1568             EXPECT_FALSE(childImpl->hasTextureIdForTileAt(i, 0));
1569             EXPECT_FALSE(child2Impl->hasTextureIdForTileAt(i, 0));
1570         }
1571     }
1572     ccLayerTreeHost->commitComplete();
1573
1574     // With a memory limit that includes only half the root layer, no contents will be
1575     // allocated. If render surface memory wasn't accounted for, there is enough space
1576     // for one of the children layers, but they draw into a surface that can't be
1577     // allocated.
1578     root->invalidateContentRect(rootRect);
1579     child->invalidateContentRect(childRect);
1580     child2->invalidateContentRect(child2Rect);
1581     ccLayerTreeHost->updateLayers(m_queue, (3 * 1) * (100 * 100) * 4);
1582     {
1583         DebugScopedSetImplThread implThread;
1584         updateTextures(1000);
1585         EXPECT_EQ(0, root->fakeLayerTextureUpdater()->updateCount());
1586         EXPECT_EQ(0, child->fakeLayerTextureUpdater()->updateCount());
1587         EXPECT_EQ(0, child2->fakeLayerTextureUpdater()->updateCount());
1588         EXPECT_FALSE(m_queue.hasMoreUpdates());
1589
1590         root->fakeLayerTextureUpdater()->clearUpdateCount();
1591         child->fakeLayerTextureUpdater()->clearUpdateCount();
1592         child2->fakeLayerTextureUpdater()->clearUpdateCount();
1593
1594         OwnPtr<FakeCCTiledLayerImpl> rootImpl(adoptPtr(new FakeCCTiledLayerImpl(root->id())));
1595         OwnPtr<FakeCCTiledLayerImpl> childImpl(adoptPtr(new FakeCCTiledLayerImpl(child->id())));
1596         OwnPtr<FakeCCTiledLayerImpl> child2Impl(adoptPtr(new FakeCCTiledLayerImpl(child2->id())));
1597         root->pushPropertiesTo(rootImpl.get());
1598         child->pushPropertiesTo(childImpl.get());
1599         child2->pushPropertiesTo(child2Impl.get());
1600
1601         for (unsigned i = 0; i < 3; ++i) {
1602             for (unsigned j = 0; j < 2; ++j)
1603                 EXPECT_FALSE(rootImpl->hasTextureIdForTileAt(i, j));
1604             EXPECT_FALSE(childImpl->hasTextureIdForTileAt(i, 0));
1605             EXPECT_FALSE(child2Impl->hasTextureIdForTileAt(i, 0));
1606         }
1607     }
1608     ccLayerTreeHost->commitComplete();
1609
1610     {
1611         DebugScopedSetImplThread implThread;
1612         ccLayerTreeHost->contentsTextureManager()->clearAllMemory(m_resourceProvider.get());
1613     }
1614     ccLayerTreeHost->setRootLayer(0);
1615     ccLayerTreeHost.clear();
1616     WebKit::WebCompositor::shutdown();
1617 }
1618
1619 class TrackingLayerPainter : public LayerPainterChromium {
1620 public:
1621     static PassOwnPtr<TrackingLayerPainter> create() { return adoptPtr(new TrackingLayerPainter()); }
1622
1623     virtual void paint(SkCanvas*, const IntRect& contentRect, FloatRect&) OVERRIDE
1624     {
1625         m_paintedRect = contentRect;
1626     }
1627
1628     const IntRect& paintedRect() const { return m_paintedRect; }
1629     void resetPaintedRect() { m_paintedRect = IntRect(); }
1630
1631 private:
1632     TrackingLayerPainter() { }
1633
1634     IntRect m_paintedRect;
1635 };
1636
1637 class UpdateTrackingTiledLayerChromium : public FakeTiledLayerChromium {
1638 public:
1639     explicit UpdateTrackingTiledLayerChromium(WebCore::CCPrioritizedTextureManager* manager)
1640         : FakeTiledLayerChromium(manager)
1641     {
1642         OwnPtr<TrackingLayerPainter> trackingLayerPainter(TrackingLayerPainter::create());
1643         m_trackingLayerPainter = trackingLayerPainter.get();
1644         m_layerTextureUpdater = BitmapCanvasLayerTextureUpdater::create(trackingLayerPainter.release());
1645     }
1646     virtual ~UpdateTrackingTiledLayerChromium() { }
1647
1648     TrackingLayerPainter* trackingLayerPainter() const { return m_trackingLayerPainter; }
1649
1650 protected:
1651     virtual WebCore::LayerTextureUpdater* textureUpdater() const OVERRIDE { return m_layerTextureUpdater.get(); }
1652
1653 private:
1654     TrackingLayerPainter* m_trackingLayerPainter;
1655     RefPtr<BitmapCanvasLayerTextureUpdater> m_layerTextureUpdater;
1656 };
1657
1658 TEST_F(TiledLayerChromiumTest, nonIntegerContentsScaleIsNotDistortedDuringPaint)
1659 {
1660     OwnPtr<CCPrioritizedTextureManager> textureManager(CCPrioritizedTextureManager::create(4000000, 4000000, CCRenderer::ContentPool));
1661
1662     RefPtr<UpdateTrackingTiledLayerChromium> layer = adoptRef(new UpdateTrackingTiledLayerChromium(textureManager.get()));
1663
1664     IntRect layerRect(0, 0, 30, 31);
1665     layer->setPosition(layerRect.location());
1666     layer->setBounds(layerRect.size());
1667     layer->setContentsScale(1.5);
1668
1669     IntRect contentRect(0, 0, 45, 47);
1670     EXPECT_EQ(contentRect.size(), layer->contentBounds());
1671     layer->setVisibleContentRect(contentRect);
1672     layer->setDrawableContentRect(contentRect);
1673
1674     layer->setTexturePriorities(m_priorityCalculator);
1675     textureManager->prioritizeTextures();
1676
1677     // Update the whole tile.
1678     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1679     layer->trackingLayerPainter()->resetPaintedRect();
1680
1681     EXPECT_INT_RECT_EQ(IntRect(), layer->trackingLayerPainter()->paintedRect());
1682
1683     {
1684         DebugScopedSetImplThread implThread;
1685         updateTextures();
1686     }
1687
1688     // Invalidate the entire layer in content space. When painting, the rect given to webkit should match the layer's bounds.
1689     layer->invalidateContentRect(contentRect);
1690     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1691
1692     EXPECT_INT_RECT_EQ(layerRect, layer->trackingLayerPainter()->paintedRect());
1693 }
1694
1695 TEST_F(TiledLayerChromiumTest, nonIntegerContentsScaleIsNotDistortedDuringInvalidation)
1696 {
1697     OwnPtr<CCPrioritizedTextureManager> textureManager(CCPrioritizedTextureManager::create(4000000, 4000000, CCRenderer::ContentPool));
1698
1699     RefPtr<UpdateTrackingTiledLayerChromium> layer = adoptRef(new UpdateTrackingTiledLayerChromium(textureManager.get()));
1700
1701     IntRect layerRect(0, 0, 30, 31);
1702     layer->setPosition(layerRect.location());
1703     layer->setBounds(layerRect.size());
1704     layer->setContentsScale(1.3f);
1705
1706     IntRect contentRect(IntPoint(), layer->contentBounds());
1707     layer->setVisibleContentRect(contentRect);
1708     layer->setDrawableContentRect(contentRect);
1709
1710     layer->setTexturePriorities(m_priorityCalculator);
1711     textureManager->prioritizeTextures();
1712
1713     // Update the whole tile.
1714     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1715     layer->trackingLayerPainter()->resetPaintedRect();
1716
1717     EXPECT_INT_RECT_EQ(IntRect(), layer->trackingLayerPainter()->paintedRect());
1718
1719     {
1720         DebugScopedSetImplThread implThread;
1721         updateTextures();
1722     }
1723
1724     // Invalidate the entire layer in layer space. When painting, the rect given to webkit should match the layer's bounds.
1725     layer->setNeedsDisplayRect(layerRect);
1726     layer->updateContentRect(m_queue, contentRect, 0, m_stats);
1727
1728     EXPECT_INT_RECT_EQ(layerRect, layer->trackingLayerPainter()->paintedRect());
1729 }
1730
1731 } // namespace