[chromium] Layers with animating transforms should prepaint even if they are not...
[WebKit-https.git] / Source / WebKit / chromium / tests / TiledLayerChromiumTest.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "TiledLayerChromium.h"
28
29 #include "CCAnimationTestCommon.h"
30 #include "CCLayerTreeTestCommon.h"
31 #include "FakeCCLayerTreeHostClient.h"
32 #include "LayerTextureUpdater.h"
33 #include "Region.h"
34 #include "TextureManager.h"
35 #include "WebCompositor.h"
36 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
37 #include "cc/CCTextureUpdater.h"
38 #include "cc/CCTiledLayerImpl.h"
39 #include <gtest/gtest.h>
40
41 using namespace WebCore;
42 using namespace WebKitTests;
43 using namespace WTF;
44
45 #define EXPECT_EQ_RECT(a, b) \
46     EXPECT_EQ(a.x(), b.x()); \
47     EXPECT_EQ(a.y(), b.y()); \
48     EXPECT_EQ(a.width(), b.width()); \
49     EXPECT_EQ(a.height(), b.height());
50
51 namespace {
52
53 class TestCCOcclusionTracker : public CCOcclusionTracker {
54 public:
55     TestCCOcclusionTracker()
56         : CCOcclusionTracker(IntRect(0, 0, 1000, 1000), true)
57         , m_scissorRectInScreen(IntRect(0, 0, 1000, 1000))
58     {
59         // Pretend we have visited a render surface.
60         m_stack.append(StackObject());
61     }
62
63     void setOcclusion(const Region& occlusion) { m_stack.last().occlusionInScreen = occlusion; }
64
65 protected:
66     virtual IntRect layerScissorRectInTargetSurface(const LayerChromium* layer) const { return m_scissorRectInScreen; }
67
68 private:
69     IntRect m_scissorRectInScreen;
70 };
71
72 class FakeTextureAllocator : public TextureAllocator {
73 public:
74     virtual unsigned createTexture(const IntSize&, GC3Denum) { return 1; }
75     virtual void deleteTexture(unsigned, const IntSize&, GC3Denum) { }
76 };
77
78 class FakeTiledLayerChromium;
79
80 class FakeLayerTextureUpdater : public LayerTextureUpdater {
81 public:
82     class Texture : public LayerTextureUpdater::Texture {
83     public:
84         Texture(FakeLayerTextureUpdater* layer, PassOwnPtr<ManagedTexture> texture)
85             : LayerTextureUpdater::Texture(texture)
86             , m_layer(layer)
87         {
88         }
89         virtual ~Texture() { }
90
91         virtual void updateRect(GraphicsContext3D*, TextureAllocator* allocator, const IntRect&, const IntRect&)
92         {
93             if (allocator)
94                 texture()->allocate(allocator);
95             m_layer->updateRect();
96         }
97         virtual void prepareRect(const IntRect&) { m_layer->prepareRect(); }
98
99     private:
100         FakeLayerTextureUpdater* m_layer;
101     };
102
103     FakeLayerTextureUpdater()
104         : m_prepareCount(0)
105         , m_updateCount(0)
106         , m_prepareRectCount(0)
107     {
108     }
109     virtual ~FakeLayerTextureUpdater() { }
110
111     // Sets the rect to invalidate during the next call to prepareToUpdate(). After the next
112     // call to prepareToUpdate() the rect is reset.
113     void setRectToInvalidate(const IntRect&, FakeTiledLayerChromium*);
114
115     // Number of times prepareToUpdate has been invoked.
116     int prepareCount() const { return m_prepareCount; }
117     void clearPrepareCount() { m_prepareCount = 0; }
118
119     // Number of times updateRect has been invoked.
120     int updateCount() const { return m_updateCount; }
121     void clearUpdateCount() { m_updateCount = 0; }
122     void updateRect() { m_updateCount++; }
123
124     // Number of times prepareRect() has been invoked on a texture.
125     int prepareRectCount() const { return m_prepareRectCount; }
126     void clearPrepareRectCount() { m_prepareRectCount = 0; }
127     void prepareRect() { m_prepareRectCount++; }
128
129     void setOpaquePaintRect(const IntRect& opaquePaintRect) { m_opaquePaintRect = opaquePaintRect; }
130
131     // Last rect passed to prepareToUpdate().
132     const IntRect& lastUpdateRect()  const { return m_lastUpdateRect; }
133
134     virtual PassOwnPtr<LayerTextureUpdater::Texture> createTexture(TextureManager* manager) { return adoptPtr(new Texture(this, ManagedTexture::create(manager))); }
135     virtual SampledTexelFormat sampledTexelFormat(GC3Denum) { return SampledTexelFormatRGBA; }
136     virtual void prepareToUpdate(const IntRect& contentRect, const IntSize&, int, float, IntRect* resultingOpaqueRect);
137
138 private:
139     int m_prepareCount;
140     int m_updateCount;
141     int m_prepareRectCount;
142     IntRect m_rectToInvalidate;
143     IntRect m_lastUpdateRect;
144     IntRect m_opaquePaintRect;
145     RefPtr<FakeTiledLayerChromium> m_layer;
146 };
147
148 class FakeCCTiledLayerImpl : public CCTiledLayerImpl {
149 public:
150     explicit FakeCCTiledLayerImpl(int id)
151         : CCTiledLayerImpl(id) { }
152     virtual ~FakeCCTiledLayerImpl() { }
153
154     using CCTiledLayerImpl::hasTileAt;
155     using CCTiledLayerImpl::hasTextureIdForTileAt;
156 };
157
158 class FakeTiledLayerChromium : public TiledLayerChromium {
159 public:
160     explicit FakeTiledLayerChromium(TextureManager* textureManager)
161         : TiledLayerChromium()
162         , m_fakeTextureUpdater(adoptRef(new FakeLayerTextureUpdater))
163         , m_textureManager(textureManager)
164     {
165         setTileSize(tileSize());
166         setTextureFormat(GraphicsContext3D::RGBA);
167         setBorderTexelOption(CCLayerTilingData::NoBorderTexels);
168         setIsDrawable(true); // So that we don't get false positives if any of these tests expect to return false from drawsContent() for other reasons.
169     }
170     virtual ~FakeTiledLayerChromium() { }
171
172     static IntSize tileSize() { return IntSize(100, 100); }
173
174     using TiledLayerChromium::invalidateRect;
175     using TiledLayerChromium::prepareToUpdate;
176     using TiledLayerChromium::prepareToUpdateIdle;
177     using TiledLayerChromium::needsIdlePaint;
178     using TiledLayerChromium::skipsDraw;
179     using TiledLayerChromium::numPaintedTiles;
180     using TiledLayerChromium::idlePaintRect;
181
182     virtual void setNeedsDisplayRect(const FloatRect& rect)
183     {
184         m_lastNeedsDisplayRect = rect;
185         TiledLayerChromium::setNeedsDisplayRect(rect);
186     }
187
188     const FloatRect& lastNeedsDisplayRect() const { return m_lastNeedsDisplayRect; }
189
190     FakeLayerTextureUpdater* fakeLayerTextureUpdater() { return m_fakeTextureUpdater.get(); }
191
192     virtual TextureManager* textureManager() const { return m_textureManager; }
193
194     virtual void paintContentsIfDirty(const CCOcclusionTracker* occlusion)
195     {
196         prepareToUpdate(visibleLayerRect(), occlusion);
197     }
198
199 private:
200     virtual LayerTextureUpdater* textureUpdater() const
201     {
202         return m_fakeTextureUpdater.get();
203     }
204
205     virtual void createTextureUpdaterIfNeeded() { }
206
207     RefPtr<FakeLayerTextureUpdater> m_fakeTextureUpdater;
208     TextureManager* m_textureManager;
209     FloatRect m_lastNeedsDisplayRect;
210 };
211
212 class FakeTiledLayerWithScaledBounds : public FakeTiledLayerChromium {
213 public:
214     explicit FakeTiledLayerWithScaledBounds(TextureManager* textureManager)
215         : FakeTiledLayerChromium(textureManager)
216     {
217     }
218
219     void setContentBounds(const IntSize& contentBounds) { m_forcedContentBounds = contentBounds; }
220     virtual IntSize contentBounds() const { return m_forcedContentBounds; }
221
222     FloatRect updateRect() { return m_updateRect; }
223
224 protected:
225     IntSize m_forcedContentBounds;
226 };
227
228 void FakeLayerTextureUpdater::setRectToInvalidate(const IntRect& rect, FakeTiledLayerChromium* layer)
229 {
230     m_rectToInvalidate = rect;
231     m_layer = layer;
232 }
233
234 void FakeLayerTextureUpdater::prepareToUpdate(const IntRect& contentRect, const IntSize&, int, float, IntRect* resultingOpaqueRect)
235 {
236     m_prepareCount++;
237     m_lastUpdateRect = contentRect;
238     if (!m_rectToInvalidate.isEmpty()) {
239         m_layer->invalidateRect(m_rectToInvalidate);
240         m_rectToInvalidate = IntRect();
241         m_layer = 0;
242     }
243     *resultingOpaqueRect = m_opaquePaintRect;
244 }
245
246 TEST(TiledLayerChromiumTest, pushDirtyTiles)
247 {
248     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
249     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
250     DebugScopedSetImplThread implThread;
251     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
252
253     FakeTextureAllocator textureAllocator;
254     CCTextureUpdater updater(&textureAllocator);
255
256     // The tile size is 100x100, so this invalidates and then paints two tiles.
257     layer->setBounds(IntSize(100, 200));
258     layer->invalidateRect(IntRect(0, 0, 100, 200));
259     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
260     layer->updateCompositorResources(0, updater);
261     layer->pushPropertiesTo(layerImpl.get());
262
263     // We should have both tiles on the impl side.
264     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
265     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
266
267     textureManager->unprotectAllTextures();
268
269     // Invalidates both tiles...
270     layer->invalidateRect(IntRect(0, 0, 100, 200));
271     // ....but then only update one of them.
272     layer->prepareToUpdate(IntRect(0, 0, 100, 100), 0);
273     layer->updateCompositorResources(0, updater);
274     layer->pushPropertiesTo(layerImpl.get());
275
276     // We should only have the first tile since the other tile was invalidated but not painted.
277     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
278     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
279 }
280
281 TEST(TiledLayerChromiumTest, pushOccludedDirtyTiles)
282 {
283     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
284     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
285     DebugScopedSetImplThread implThread;
286     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
287     TestCCOcclusionTracker occluded;
288
289     FakeTextureAllocator textureAllocator;
290     CCTextureUpdater updater(&textureAllocator);
291
292     // The tile size is 100x100, so this invalidates and then paints two tiles.
293     layer->setBounds(IntSize(100, 200));
294     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
295     layer->setVisibleLayerRect(IntRect(0, 0, 100, 200));
296     layer->invalidateRect(IntRect(0, 0, 100, 200));
297     layer->prepareToUpdate(IntRect(0, 0, 100, 200), &occluded);
298     layer->updateCompositorResources(0, updater);
299     layer->pushPropertiesTo(layerImpl.get());
300
301     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
302     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000, 1);
303     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
304
305     // We should have both tiles on the impl side.
306     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
307     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
308
309     textureManager->unprotectAllTextures();
310
311     // Invalidates part of the top tile...
312     layer->invalidateRect(IntRect(0, 0, 50, 50));
313     // ....but the area is occluded.
314     occluded.setOcclusion(IntRect(0, 0, 50, 50));
315     layer->prepareToUpdate(IntRect(0, 0, 100, 100), &occluded);
316     layer->updateCompositorResources(0, updater);
317     layer->pushPropertiesTo(layerImpl.get());
318
319     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
320     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000 + 2500, 1);
321     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
322
323     // We should still have both tiles, as part of the top tile is still unoccluded.
324     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
325     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
326 }
327
328 TEST(TiledLayerChromiumTest, pushDeletedTiles)
329 {
330     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
331     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
332     DebugScopedSetImplThread implThread;
333     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
334
335     FakeTextureAllocator textureAllocator;
336     CCTextureUpdater updater(&textureAllocator);
337
338     // The tile size is 100x100, so this invalidates and then paints two tiles.
339     layer->setBounds(IntSize(100, 200));
340     layer->invalidateRect(IntRect(0, 0, 100, 200));
341     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
342     layer->updateCompositorResources(0, updater);
343     layer->pushPropertiesTo(layerImpl.get());
344
345     // We should have both tiles on the impl side.
346     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
347     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
348
349     textureManager->evictAndDeleteAllTextures(&textureAllocator);
350     textureManager->setMaxMemoryLimitBytes(4*1024*1024);
351     textureManager->setPreferredMemoryLimitBytes(4*1024*1024);
352
353     // This should drop the tiles on the impl thread.
354     layer->pushPropertiesTo(layerImpl.get());
355
356     // We should now have no textures on the impl thread.
357     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
358     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
359
360     // This should recreate and update the deleted textures.
361     layer->prepareToUpdate(IntRect(0, 0, 100, 100), 0);
362     layer->updateCompositorResources(0, updater);
363     layer->pushPropertiesTo(layerImpl.get());
364
365     // We should only have the first tile since the other tile was invalidated but not painted.
366     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
367     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
368 }
369
370 TEST(TiledLayerChromiumTest, pushIdlePaintTiles)
371 {
372     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
373     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
374     DebugScopedSetImplThread implThread;
375     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
376
377     FakeTextureAllocator textureAllocator;
378     CCTextureUpdater updater(&textureAllocator);
379
380     // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center.
381     IntSize contentBounds(500, 500);
382     IntRect contentRect(IntPoint::zero(), contentBounds);
383     IntRect visibleRect(200, 200, 100, 100);
384
385     // This invalidates 25 tiles and then paints one visible tile.
386     layer->setBounds(contentBounds);
387     layer->setVisibleLayerRect(visibleRect);
388     layer->invalidateRect(contentRect);
389     layer->prepareToUpdate(visibleRect, 0);
390
391     // We should need idle-painting for 3x3 tiles in the center.
392     EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
393
394     layer->updateCompositorResources(0, updater);
395     layer->pushPropertiesTo(layerImpl.get());
396
397     // We should have one tile on the impl side.
398     EXPECT_TRUE(layerImpl->hasTileAt(2, 2));
399
400     textureManager->unprotectAllTextures();
401
402     // For the next four updates, we should detect we still need idle painting.
403     for (int i = 0; i < 4; i++) {
404         layer->prepareToUpdate(visibleRect, 0);
405         EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
406         layer->prepareToUpdateIdle(visibleRect, 0);
407         layer->updateCompositorResources(0, updater);
408         layer->pushPropertiesTo(layerImpl.get());
409         textureManager->unprotectAllTextures();
410     }
411
412     // After four passes of idle painting, we should be finished painting
413     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
414
415     // We should have one tile surrounding the visible tile on all sides, but no other tiles.
416     IntRect idlePaintTiles(1, 1, 3, 3);
417     for (int i = 0; i < 5; i++) {
418         for (int j = 0; j < 5; j++) {
419             if (idlePaintTiles.contains(i, j))
420                 EXPECT_TRUE(layerImpl->hasTileAt(i, j));
421             else
422                 EXPECT_FALSE(layerImpl->hasTileAt(i, j));
423         }
424     }
425 }
426
427 TEST(TiledLayerChromiumTest, pushTilesAfterIdlePaintFailed)
428 {
429     OwnPtr<TextureManager> textureManager = TextureManager::create(1024*1024, 1024*1024, 1024);
430     DebugScopedSetImplThread implThread;
431     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
432     OwnPtr<FakeCCTiledLayerImpl> layerImpl1(adoptPtr(new FakeCCTiledLayerImpl(0)));
433     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
434     OwnPtr<FakeCCTiledLayerImpl> layerImpl2(adoptPtr(new FakeCCTiledLayerImpl(0)));
435
436     FakeTextureAllocator textureAllocator;
437     CCTextureUpdater updater(&textureAllocator);
438
439     // For this test we have two layers. layer1 exhausts most texture memory, leaving room for 2 more tiles from
440     // layer2, but not all three tiles. First we paint layer1, and one tile from layer2. Then when we idle paint
441     // layer2, we will fail on the third tile of layer2, and this should not leave the second tile in a bad state.
442
443     // This requires 4*30000 bytes of memory.
444     IntRect layer2Rect(0, 0, 100, 300);
445     layer2->setBounds(layer2Rect.size());
446     layer2->setVisibleLayerRect(layer2Rect);
447     layer2->invalidateRect(layer2Rect);
448
449     // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough for 2 tiles only in the other layer.
450     IntRect layerRect(IntPoint::zero(), IntSize(100, 2400));
451     layer1->setBounds(layerRect.size());
452     layer1->setVisibleLayerRect(layerRect);
453     layer1->invalidateRect(layerRect);
454     layer1->prepareToUpdate(layerRect, 0);
455
456     // Paint a single tile in layer2 so that it will idle paint.
457     layer2->prepareToUpdate(IntRect(0, 0, 100, 100), 0);
458
459     // We should need idle-painting for both remaining tiles in layer2.
460     EXPECT_TRUE(layer2->needsIdlePaint(layer2Rect));
461
462     // Commit the frame over to impl.
463     layer1->updateCompositorResources(0, updater);
464     layer2->updateCompositorResources(0, updater);
465     updater.update(0, 5000);
466     layer1->pushPropertiesTo(layerImpl1.get());
467     layer2->pushPropertiesTo(layerImpl2.get());
468
469     // Now idle paint layer2. We are going to run out of memory though!
470     layer2->prepareToUpdate(IntRect(0, 0, 100, 100), 0);
471     layer2->prepareToUpdateIdle(layer2Rect, 0);
472
473     // Oh well, commit the frame and push.
474     layer1->updateCompositorResources(0, updater);
475     layer2->updateCompositorResources(0, updater);
476     updater.update(0, 5000);
477     layer1->pushPropertiesTo(layerImpl1.get());
478     layer2->pushPropertiesTo(layerImpl2.get());
479
480     // Sanity check, we should have textures for the big layer.
481     EXPECT_TRUE(layerImpl1->hasTextureIdForTileAt(0, 0));
482
483     // We should only have the first tile from layer2 since it failed to idle update.
484     EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
485     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
486     EXPECT_FALSE(layerImpl2->hasTileAt(0, 1));
487     EXPECT_FALSE(layerImpl2->hasTileAt(0, 2));
488
489     // Now if layer2 becomes fully visible, we should be able to paint it and push valid textures.
490     textureManager->unprotectAllTextures();
491
492     layer2->prepareToUpdate(layer2Rect, 0);
493     layer1->prepareToUpdate(IntRect(), 0);
494
495     layer1->updateCompositorResources(0, updater);
496     layer2->updateCompositorResources(0, updater);
497     updater.update(0, 5000);
498     layer1->pushPropertiesTo(layerImpl1.get());
499     layer2->pushPropertiesTo(layerImpl2.get());
500
501     EXPECT_TRUE(layerImpl2->hasTileAt(0, 0));
502     EXPECT_TRUE(layerImpl2->hasTileAt(0, 1));
503     EXPECT_TRUE(layerImpl2->hasTileAt(0, 2));
504     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 0));
505     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 1));
506     EXPECT_TRUE(layerImpl2->hasTextureIdForTileAt(0, 2));
507 }
508
509 TEST(TiledLayerChromiumTest, pushIdlePaintedOccludedTiles)
510 {
511     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
512     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
513     DebugScopedSetImplThread implThread;
514     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
515     TestCCOcclusionTracker occluded;
516
517     FakeTextureAllocator textureAllocator;
518     CCTextureUpdater updater(&textureAllocator);
519
520     // The tile size is 100x100, so this invalidates one occluded tile, culls it during paint, but prepaints it.
521     occluded.setOcclusion(IntRect(0, 0, 100, 100));
522
523     layer->setBounds(IntSize(100, 100));
524     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
525     layer->setVisibleLayerRect(IntRect(0, 0, 100, 100));
526     layer->invalidateRect(IntRect(0, 0, 100, 100));
527     layer->prepareToUpdate(IntRect(0, 0, 100, 100), &occluded);
528     layer->prepareToUpdateIdle(IntRect(0, 0, 100, 100), &occluded);
529     layer->updateCompositorResources(0, updater);
530     layer->pushPropertiesTo(layerImpl.get());
531
532     // We should have the prepainted tile on the impl side.
533     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
534 }
535
536 TEST(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
537 {
538     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
539     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
540     DebugScopedSetImplThread implThread;
541     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
542
543     FakeTextureAllocator textureAllocator;
544     CCTextureUpdater updater(&textureAllocator);
545
546     // The tile size is 100x100, so this invalidates and then paints two tiles.
547     // However, during the paint, we invalidate one of the tiles. This should
548     // not prevent the tile from being pushed.
549     layer->setBounds(IntSize(100, 200));
550     layer->invalidateRect(IntRect(0, 0, 100, 200));
551     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer.get());
552     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
553     layer->updateCompositorResources(0, updater);
554     layer->pushPropertiesTo(layerImpl.get());
555
556     // We should have both tiles on the impl side.
557     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
558     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
559 }
560
561 TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
562 {
563     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
564     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
565     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
566     DebugScopedSetImplThread implThread;
567     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
568     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
569
570     FakeTextureAllocator textureAllocator;
571     CCTextureUpdater updater(&textureAllocator);
572
573     layer1->setBounds(IntSize(100, 200));
574     layer1->invalidateRect(IntRect(0, 0, 100, 200));
575     layer2->setBounds(IntSize(100, 200));
576     layer2->invalidateRect(IntRect(0, 0, 100, 200));
577
578     layer1->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
579
580     // Invalidate a tile on layer1
581     layer2->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer1.get());
582     layer2->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
583
584     layer1->updateCompositorResources(0, updater);
585     layer2->updateCompositorResources(0, updater);
586
587     layer1->pushPropertiesTo(layer1Impl.get());
588     layer2->pushPropertiesTo(layer2Impl.get());
589
590     // We should have both tiles on the impl side for all layers.
591     EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
592     EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
593     EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
594     EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
595 }
596
597 TEST(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer)
598 {
599     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
600     RefPtr<FakeTiledLayerChromium> layer1 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
601     RefPtr<FakeTiledLayerChromium> layer2 = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
602     DebugScopedSetImplThread implThread;
603     OwnPtr<FakeCCTiledLayerImpl> layer1Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
604     OwnPtr<FakeCCTiledLayerImpl> layer2Impl(adoptPtr(new FakeCCTiledLayerImpl(0)));
605
606     FakeTextureAllocator textureAllocator;
607     CCTextureUpdater updater(&textureAllocator);
608
609     layer1->setBounds(IntSize(100, 200));
610     layer1->invalidateRect(IntRect(0, 0, 100, 200));
611     layer2->setBounds(IntSize(100, 200));
612     layer2->invalidateRect(IntRect(0, 0, 100, 200));
613
614     // Invalidate a tile on layer2
615     layer1->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50), layer2.get());
616     layer1->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
617
618     layer2->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
619
620     layer1->updateCompositorResources(0, updater);
621     layer2->updateCompositorResources(0, updater);
622
623     layer1->pushPropertiesTo(layer1Impl.get());
624     layer2->pushPropertiesTo(layer2Impl.get());
625
626     // We should have both tiles on the impl side for all layers.
627     EXPECT_TRUE(layer1Impl->hasTileAt(0, 0));
628     EXPECT_TRUE(layer1Impl->hasTileAt(0, 1));
629     EXPECT_TRUE(layer2Impl->hasTileAt(0, 0));
630     EXPECT_TRUE(layer2Impl->hasTileAt(0, 1));
631 }
632
633 TEST(TiledLayerChromiumTest, idlePaintOutOfMemory)
634 {
635     // The tile size is 100x100. Setup 5x5 tiles with one 1x1 visible tile in the center.
636     IntSize contentBounds(300, 300);
637     IntRect contentRect(IntPoint::zero(), contentBounds);
638     IntRect visibleRect(100, 100, 100, 100);
639
640     // We have enough memory for only the visible rect, so we will run out of memory in first idle paint.
641     int memoryLimit = 4 * 100 * 100; // 2 tiles, 4 bytes per pixel.
642
643     OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit / 2, 1024);
644     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
645     DebugScopedSetImplThread implThread;
646     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
647
648     FakeTextureAllocator textureAllocator;
649     CCTextureUpdater updater(&textureAllocator);
650
651     // This invalidates 9 tiles and then paints one visible tile.
652     layer->setBounds(contentBounds);
653     layer->setVisibleLayerRect(visibleRect);
654     layer->invalidateRect(contentRect);
655     layer->prepareToUpdate(visibleRect, 0);
656
657     // We should need idle-painting for 3x3 tiles surounding visible tile.
658     EXPECT_TRUE(layer->needsIdlePaint(visibleRect));
659
660     layer->updateCompositorResources(0, updater);
661     layer->pushPropertiesTo(layerImpl.get());
662
663     // We should have one tile on the impl side.
664     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
665
666     textureManager->unprotectAllTextures();
667     layer->prepareToUpdate(visibleRect, 0);
668     layer->prepareToUpdateIdle(visibleRect, 0);
669
670     // We shouldn't signal we need another idle paint after we run out of memory.
671     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
672
673     layer->updateCompositorResources(0, updater);
674     layer->pushPropertiesTo(layerImpl.get());
675 }
676
677 TEST(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
678 {
679     OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
680     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
681     DebugScopedSetImplThread implThread;
682     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
683
684     FakeTextureAllocator textureAllocator;
685     CCTextureUpdater updater(&textureAllocator);
686
687     // The layer's bounds are empty.
688     IntRect contentRect;
689
690     layer->setBounds(contentRect.size());
691     layer->setVisibleLayerRect(contentRect);
692     layer->invalidateRect(contentRect);
693     layer->prepareToUpdate(contentRect, 0);
694
695     // Empty layers don't have tiles.
696     EXPECT_EQ(0u, layer->numPaintedTiles());
697
698     // Empty layers don't need prepaint.
699     EXPECT_FALSE(layer->needsIdlePaint(contentRect));
700
701     layer->updateCompositorResources(0, updater);
702     layer->pushPropertiesTo(layerImpl.get());
703
704     // Empty layers don't have tiles.
705     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
706
707     // Non-visible layers don't idle paint.
708     layer->prepareToUpdateIdle(contentRect, 0);
709
710     // Empty layers don't have tiles.
711     EXPECT_EQ(0u, layer->numPaintedTiles());
712
713     layer->updateCompositorResources(0, updater);
714     layer->pushPropertiesTo(layerImpl.get());
715
716     // Empty layers don't have tiles.
717     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
718 }
719
720 TEST(TiledLayerChromiumTest, idlePaintZeroSizedAnimatingLayer)
721 {
722     OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
723     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
724     DebugScopedSetImplThread implThread;
725     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
726
727     FakeTextureAllocator textureAllocator;
728     CCTextureUpdater updater(&textureAllocator);
729
730     // Pretend the layer is animating.
731     layer->setDrawTransformIsAnimating(true);
732
733     // The layer's bounds are empty.
734     IntRect contentRect;
735
736     layer->setBounds(contentRect.size());
737     layer->setVisibleLayerRect(contentRect);
738     layer->invalidateRect(contentRect);
739     layer->prepareToUpdate(contentRect, 0);
740
741     // Empty layers don't have tiles.
742     EXPECT_EQ(0u, layer->numPaintedTiles());
743
744     // Empty layers don't need prepaint.
745     EXPECT_FALSE(layer->needsIdlePaint(contentRect));
746
747     layer->updateCompositorResources(0, updater);
748     layer->pushPropertiesTo(layerImpl.get());
749
750     // Empty layers don't have tiles.
751     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
752
753     // Non-visible layers don't idle paint.
754     layer->prepareToUpdateIdle(contentRect, 0);
755
756     // Empty layers don't have tiles.
757     EXPECT_EQ(0u, layer->numPaintedTiles());
758
759     layer->updateCompositorResources(0, updater);
760     layer->pushPropertiesTo(layerImpl.get());
761
762     // Empty layers don't have tiles.
763     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
764 }
765
766 TEST(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
767 {
768     IntSize contentBounds(100, 100);
769     IntRect contentRect(IntPoint::zero(), contentBounds);
770
771     OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024);
772     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
773     DebugScopedSetImplThread implThread;
774     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
775
776     FakeTextureAllocator textureAllocator;
777     CCTextureUpdater updater(&textureAllocator);
778
779     // Invalidate the layer but make none of it visible, so nothing paints.
780     IntRect visibleRect;
781
782     layer->setBounds(contentBounds);
783     layer->setVisibleLayerRect(visibleRect);
784     layer->invalidateRect(contentRect);
785     layer->prepareToUpdate(visibleRect, 0);
786
787     // Non-visible layers don't need idle paint.
788     EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
789
790     layer->updateCompositorResources(0, updater);
791     layer->pushPropertiesTo(layerImpl.get());
792
793     // We should not have any tiles pushed since the layer is not visible.
794     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
795
796     // Non-visible layers don't idle paint.
797     layer->prepareToUpdateIdle(visibleRect, 0);
798
799     layer->updateCompositorResources(0, updater);
800     layer->pushPropertiesTo(layerImpl.get());
801
802     // We should not have any tiles pushed since the layer is not visible.
803     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
804 }
805
806 static void idlePaintRepeat(int repeatTimes, FakeTiledLayerChromium* layer, FakeCCTiledLayerImpl* layerImpl, CCTextureUpdater& updater, const IntRect& visibleRect)
807 {
808     for (int i = 0; i < repeatTimes; ++i) {
809         layer->prepareToUpdate(visibleRect, 0);
810         layer->prepareToUpdateIdle(visibleRect, 0);
811         layer->updateCompositorResources(0, updater);
812         layer->pushPropertiesTo(layerImpl);
813     }
814 }
815
816 static void testHaveOuterTiles(FakeCCTiledLayerImpl* layerImpl, int width, int height, int have)
817 {
818     for (int i = 0; i < width; ++i) {
819         for (int j = 0; j < height; ++j) {
820             bool hasTile = i < have || j < have || i >= width - have || j >= height - have;
821             EXPECT_EQ(hasTile, layerImpl->hasTileAt(i, j));
822         }
823     }
824 }
825
826 TEST(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers)
827 {
828     OwnPtr<TextureManager> textureManager = TextureManager::create(8000*8000*8, 8000*8000*4, 1024);
829     DebugScopedSetImplThread implThread;
830
831     FakeTextureAllocator textureAllocator;
832     CCTextureUpdater updater(&textureAllocator);
833
834     int tileWidth = FakeTiledLayerChromium::tileSize().width();
835     int tileHeight = FakeTiledLayerChromium::tileSize().height();
836     int width[] = { 1, 2, 3, 4, 9, 10, 0 };
837     int height[] = { 1, 2, 3, 4, 9, 10, 0 };
838
839     for (int j = 0; height[j]; ++j) {
840         for (int i = 0; width[i]; ++i) {
841             RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
842             OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
843
844             // Pretend the layer is animating.
845             layer->setDrawTransformIsAnimating(true);
846
847             IntSize contentBounds(width[i] * tileWidth, height[j] * tileHeight);
848             IntRect contentRect(IntPoint::zero(), contentBounds);
849             IntRect visibleRect;
850
851             layer->setBounds(contentBounds);
852             layer->setVisibleLayerRect(visibleRect);
853             layer->invalidateRect(contentRect);
854
855             // If idlePaintRect gives back a non-empty result then we should paint it. Otherwise,
856             // we shoud paint nothing.
857             bool shouldPrepaint = !layer->idlePaintRect(visibleRect).isEmpty();
858
859             // This paints the layer but there's nothing visible so it's a no-op.
860             layer->prepareToUpdate(visibleRect, 0);
861             layer->updateCompositorResources(0, updater);
862             layer->pushPropertiesTo(layerImpl.get());
863
864             // We should not have any tiles pushed yet since the layer is not visible and we've not prepainted.
865             testHaveOuterTiles(layerImpl.get(), width[i], height[j], 0);
866
867             // Normally we don't allow non-visible layers to pre-paint, but if they are animating then we should.
868             EXPECT_EQ(shouldPrepaint, layer->needsIdlePaint(visibleRect));
869
870             // If the layer is to be prepainted at all, then after four updates we should have the outer row/columns painted.
871             idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect);
872             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
873
874             // We don't currently idle paint past the outermost tiles.
875             EXPECT_FALSE(layer->needsIdlePaint(visibleRect));
876             idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect);
877             testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0);
878         }
879     }
880 }
881
882 TEST(TiledLayerChromiumTest, invalidateFromPrepare)
883 {
884     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
885     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
886     DebugScopedSetImplThread implThread;
887     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
888
889     FakeTextureAllocator textureAllocator;
890     CCTextureUpdater updater(&textureAllocator);
891
892     // The tile size is 100x100, so this invalidates and then paints two tiles.
893     layer->setBounds(IntSize(100, 200));
894     layer->invalidateRect(IntRect(0, 0, 100, 200));
895     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
896     layer->updateCompositorResources(0, updater);
897     layer->pushPropertiesTo(layerImpl.get());
898
899     // We should have both tiles on the impl side.
900     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
901     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
902
903     textureManager->unprotectAllTextures();
904
905     layer->fakeLayerTextureUpdater()->clearPrepareCount();
906     // Invoke prepareToUpdate again. As the layer is valid prepareToUpdate shouldn't be invoked on
907     // the LayerTextureUpdater.
908     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
909     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareCount());
910
911     layer->invalidateRect(IntRect(0, 0, 50, 50));
912     // setRectToInvalidate triggers invalidateRect() being invoked from prepareToUpdate.
913     layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(25, 25, 50, 50), layer.get());
914     layer->fakeLayerTextureUpdater()->clearPrepareCount();
915     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
916     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
917     layer->fakeLayerTextureUpdater()->clearPrepareCount();
918     // The layer should still be invalid as prepareToUpdate invoked invalidate.
919     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
920     EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
921 }
922
923 TEST(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
924 {
925     // The updateRect (that indicates what was actually painted) should be in
926     // layer space, not the content space.
927
928     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
929     RefPtr<FakeTiledLayerWithScaledBounds> layer = adoptRef(new FakeTiledLayerWithScaledBounds(textureManager.get()));
930
931     FakeTextureAllocator textureAllocator;
932     CCTextureUpdater updater(&textureAllocator);
933
934     IntRect layerBounds(0, 0, 300, 200);
935     IntRect contentBounds(0, 0, 200, 250);
936
937     layer->setBounds(layerBounds.size());
938     layer->setContentBounds(contentBounds.size());
939     layer->setVisibleLayerRect(contentBounds);
940
941     // On first update, the updateRect includes all tiles, even beyond the boundaries of the layer.
942     // However, it should still be in layer space, not content space.
943     layer->invalidateRect(contentBounds);
944     layer->prepareToUpdate(contentBounds, 0);
945     layer->updateCompositorResources(0, updater);
946     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 300, 300 * 0.8), layer->updateRect());
947
948     // After the tiles are updated once, another invalidate only needs to update the bounds of the layer.
949     layer->invalidateRect(contentBounds);
950     layer->prepareToUpdate(contentBounds, 0);
951     layer->updateCompositorResources(0, updater);
952     EXPECT_FLOAT_RECT_EQ(FloatRect(layerBounds), layer->updateRect());
953
954     // Partial re-paint should also be represented by the updateRect in layer space, not content space.
955     IntRect partialDamage(30, 100, 10, 10);
956     layer->invalidateRect(partialDamage);
957     layer->prepareToUpdate(contentBounds, 0);
958     layer->updateCompositorResources(0, updater);
959     EXPECT_FLOAT_RECT_EQ(FloatRect(45, 80, 15, 8), layer->updateRect());
960 }
961
962 TEST(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
963 {
964     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
965     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
966     DebugScopedSetImplThread implThread;
967     OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0)));
968
969     FakeTextureAllocator textureAllocator;
970     CCTextureUpdater updater(&textureAllocator);
971
972     // Create a layer with one tile.
973     layer->setBounds(IntSize(100, 100));
974
975     // Invalidate the entire layer.
976     layer->setNeedsDisplay();
977     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
978
979     // Push the tiles to the impl side and check that there is exactly one.
980     layer->prepareToUpdate(IntRect(0, 0, 100, 100), 0);
981     layer->updateCompositorResources(0, updater);
982     layer->pushPropertiesTo(layerImpl.get());
983     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
984     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
985     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
986     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
987
988     // Change the contents scale and verify that the content rectangle requiring painting
989     // is not scaled.
990     layer->setContentsScale(2);
991     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect());
992
993     // The impl side should get 2x2 tiles now.
994     layer->prepareToUpdate(IntRect(0, 0, 200, 200), 0);
995     layer->updateCompositorResources(0, updater);
996     layer->pushPropertiesTo(layerImpl.get());
997     EXPECT_TRUE(layerImpl->hasTileAt(0, 0));
998     EXPECT_TRUE(layerImpl->hasTileAt(0, 1));
999     EXPECT_TRUE(layerImpl->hasTileAt(1, 0));
1000     EXPECT_TRUE(layerImpl->hasTileAt(1, 1));
1001
1002     // Invalidate the entire layer again, but do not paint. All tiles should be gone now from the
1003     // impl side.
1004     layer->setNeedsDisplay();
1005     layer->prepareToUpdate(IntRect(1, 0, 0, 1), 0);
1006     layer->updateCompositorResources(0, updater);
1007     layer->pushPropertiesTo(layerImpl.get());
1008     EXPECT_FALSE(layerImpl->hasTileAt(0, 0));
1009     EXPECT_FALSE(layerImpl->hasTileAt(0, 1));
1010     EXPECT_FALSE(layerImpl->hasTileAt(1, 0));
1011     EXPECT_FALSE(layerImpl->hasTileAt(1, 1));
1012 }
1013
1014 TEST(TiledLayerChromiumTest, skipsDrawGetsReset)
1015 {
1016     // Initialize without threading support.
1017     WebKit::WebCompositor::initialize(0);
1018     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
1019     RefPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, CCSettings());
1020
1021     // Create two 300 x 300 tiled layers.
1022     IntSize contentBounds(300, 300);
1023     IntRect contentRect(IntPoint::zero(), contentBounds);
1024
1025     // We have enough memory for only one of the two layers.
1026     int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
1027     OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit, memoryLimit);
1028
1029     RefPtr<FakeTiledLayerChromium> rootLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1030     RefPtr<FakeTiledLayerChromium> childLayer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1031     rootLayer->addChild(childLayer);
1032
1033     rootLayer->setBounds(contentBounds);
1034     rootLayer->setPosition(FloatPoint(150, 150));
1035     childLayer->setBounds(contentBounds);
1036     childLayer->setPosition(FloatPoint(150, 150));
1037     rootLayer->invalidateRect(contentRect);
1038     childLayer->invalidateRect(contentRect);
1039
1040     FakeTextureAllocator textureAllocator;
1041     CCTextureUpdater updater(&textureAllocator);
1042
1043     ccLayerTreeHost->setRootLayer(rootLayer);
1044     ccLayerTreeHost->setViewportSize(IntSize(300, 300));
1045     textureManager->setMaxMemoryLimitBytes(memoryLimit);
1046     ccLayerTreeHost->updateLayers();
1047     ccLayerTreeHost->updateCompositorResources(ccLayerTreeHost->context(), updater);
1048
1049     // We'll skip the root layer.
1050     EXPECT_TRUE(rootLayer->skipsDraw());
1051     EXPECT_FALSE(childLayer->skipsDraw());
1052
1053     ccLayerTreeHost->commitComplete();
1054     textureManager->unprotectAllTextures(); // CCLayerTreeHost::commitComplete() normally does this, but since we're mocking out the manager we have to do it.
1055
1056     // Remove the child layer.
1057     rootLayer->removeAllChildren();
1058
1059     ccLayerTreeHost->updateLayers();
1060     EXPECT_FALSE(rootLayer->skipsDraw());
1061
1062     ccLayerTreeHost->setRootLayer(0);
1063     ccLayerTreeHost.clear();
1064     WebKit::WebCompositor::shutdown();
1065 }
1066
1067 TEST(TiledLayerChromiumTest, resizeToSmaller)
1068 {
1069     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
1070     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1071
1072     layer->setBounds(IntSize(700, 700));
1073     layer->invalidateRect(IntRect(0, 0, 700, 700));
1074     layer->prepareToUpdate(IntRect(0, 0, 700, 700), 0);
1075
1076     layer->setBounds(IntSize(200, 200));
1077     layer->invalidateRect(IntRect(0, 0, 200, 200));
1078 }
1079
1080 TEST(TiledLayerChromiumTest, partialUpdates)
1081 {
1082     CCSettings settings;
1083     settings.maxPartialTextureUpdates = 4;
1084     // Initialize without threading support.
1085     WebKit::WebCompositor::initialize(0);
1086     FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
1087     RefPtr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeCCLayerTreeHostClient, settings);
1088
1089     // Create one 500 x 300 tiled layer.
1090     IntSize contentBounds(300, 200);
1091     IntRect contentRect(IntPoint::zero(), contentBounds);
1092
1093     OwnPtr<TextureManager> textureManager = TextureManager::create(60*1024*1024, 60*1024*1024, 1024);
1094     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1095     layer->setBounds(contentBounds);
1096     layer->setPosition(FloatPoint(150, 150));
1097     layer->invalidateRect(contentRect);
1098
1099     FakeTextureAllocator textureAllocator;
1100     CCTextureUpdater updater(&textureAllocator);
1101
1102     ccLayerTreeHost->setRootLayer(layer);
1103     ccLayerTreeHost->setViewportSize(IntSize(300, 200));
1104
1105     // Full update of all 6 tiles.
1106     ccLayerTreeHost->updateLayers();
1107     ccLayerTreeHost->updateCompositorResources(ccLayerTreeHost->context(), updater);
1108     updater.update(0, 4);
1109     EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
1110     EXPECT_TRUE(updater.hasMoreUpdates());
1111     layer->fakeLayerTextureUpdater()->clearUpdateCount();
1112     updater.update(0, 4);
1113     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
1114     EXPECT_FALSE(updater.hasMoreUpdates());
1115     layer->fakeLayerTextureUpdater()->clearUpdateCount();
1116     ccLayerTreeHost->commitComplete();
1117
1118     // Full update of 3 tiles and partial update of 3 tiles.
1119     layer->invalidateRect(IntRect(0, 0, 300, 150));
1120     ccLayerTreeHost->updateLayers();
1121     ccLayerTreeHost->updateCompositorResources(ccLayerTreeHost->context(), updater);
1122     updater.update(0, 4);
1123     EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
1124     EXPECT_TRUE(updater.hasMoreUpdates());
1125     layer->fakeLayerTextureUpdater()->clearUpdateCount();
1126     updater.update(0, 4);
1127     EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->updateCount());
1128     EXPECT_FALSE(updater.hasMoreUpdates());
1129     layer->fakeLayerTextureUpdater()->clearUpdateCount();
1130     ccLayerTreeHost->commitComplete();
1131
1132     // Partial update of 6 tiles.
1133     layer->invalidateRect(IntRect(50, 50, 200, 100));
1134     ccLayerTreeHost->updateLayers();
1135     ccLayerTreeHost->updateCompositorResources(ccLayerTreeHost->context(), updater);
1136     updater.update(0, 4);
1137     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->updateCount());
1138     EXPECT_TRUE(updater.hasMoreUpdates());
1139     layer->fakeLayerTextureUpdater()->clearUpdateCount();
1140     updater.update(0, 4);
1141     EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
1142     EXPECT_FALSE(updater.hasMoreUpdates());
1143     layer->fakeLayerTextureUpdater()->clearUpdateCount();
1144     ccLayerTreeHost->commitComplete();
1145
1146     ccLayerTreeHost->setRootLayer(0);
1147     ccLayerTreeHost.clear();
1148     WebKit::WebCompositor::shutdown();
1149 }
1150
1151 TEST(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
1152 {
1153     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1154     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1155
1156     // The tile size is 100x100, so this invalidates and then paints two tiles.
1157     layer->setBounds(IntSize(100, 200));
1158
1159     layer->invalidateRect(IntRect(0, 0, 100, 200));
1160     layer->prepareToUpdate(IntRect(0, 0, 100, 200), 0);
1161     EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1162 }
1163
1164 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
1165 {
1166     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1167     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1168     TestCCOcclusionTracker occluded;
1169
1170     // The tile size is 100x100.
1171
1172     layer->setBounds(IntSize(600, 600));
1173     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1174
1175     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1176     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1177     layer->invalidateRect(IntRect(0, 0, 600, 600));
1178     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1179     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1180
1181     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1182     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 330000, 1);
1183     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000, 1);
1184
1185     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1186
1187     occluded.setOcclusion(IntRect(250, 200, 300, 100));
1188     layer->invalidateRect(IntRect(0, 0, 600, 600));
1189     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1190     EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
1191
1192     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1193     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 330000 + 340000, 1);
1194     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000 + 20000, 1);
1195
1196     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1197
1198     occluded.setOcclusion(IntRect(250, 250, 300, 100));
1199     layer->invalidateRect(IntRect(0, 0, 600, 600));
1200     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1201     EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
1202
1203     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1204     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 330000 + 340000 + 360000, 1);
1205     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000 + 20000, 1);
1206 }
1207
1208 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
1209 {
1210     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1211     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1212     TestCCOcclusionTracker occluded;
1213
1214     // The tile size is 100x100.
1215
1216     layer->setBounds(IntSize(600, 600));
1217     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1218
1219     // The partially occluded tiles (by the 150 occlusion height) are visible beyond the occlusion, so not culled.
1220     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1221     layer->setVisibleLayerRect(IntRect(0, 0, 600, 360));
1222     layer->invalidateRect(IntRect(0, 0, 600, 600));
1223     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1224     EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1225
1226     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1227     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 210000, 1);
1228     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000, 1);
1229
1230     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1231
1232     // Now the visible region stops at the edge of the occlusion so the partly visible tiles become fully occluded.
1233     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1234     layer->setVisibleLayerRect(IntRect(0, 0, 600, 350));
1235     layer->invalidateRect(IntRect(0, 0, 600, 600));
1236     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1237     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1238
1239     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1240     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 210000 + 180000, 1);
1241     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000 + 60000, 1);
1242
1243     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1244
1245     // Now the visible region is even smaller than the occlusion, it should have the same result.
1246     occluded.setOcclusion(IntRect(200, 200, 300, 150));
1247     layer->setVisibleLayerRect(IntRect(0, 0, 600, 340));
1248     layer->invalidateRect(IntRect(0, 0, 600, 600));
1249     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1250     EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1251
1252     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1253     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 210000 + 180000 + 180000, 1);
1254     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000 + 60000 + 60000, 1);
1255
1256 }
1257
1258 TEST(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
1259 {
1260     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1261     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1262     TestCCOcclusionTracker occluded;
1263
1264     // The tile size is 100x100.
1265
1266     layer->setBounds(IntSize(600, 600));
1267     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1268
1269     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1270     layer->setVisibleLayerRect(IntRect(0, 0, 600, 600));
1271     layer->invalidateRect(IntRect(0, 0, 600, 600));
1272     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1273     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1274
1275     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1276     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 330000, 1);
1277     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000, 1);
1278
1279     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1280
1281     // Repaint without marking it dirty.
1282     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1283     EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareRectCount());
1284
1285     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1286     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 330000, 1);
1287     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000, 1);
1288 }
1289
1290 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
1291 {
1292     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1293     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1294     TestCCOcclusionTracker occluded;
1295
1296     // The tile size is 100x100.
1297
1298     // This makes sure the painting works when the occluded region (in screen space)
1299     // is transformed differently than the layer.
1300     layer->setBounds(IntSize(600, 600));
1301     TransformationMatrix screenTransform;
1302     screenTransform.scale(0.5);
1303     layer->setScreenSpaceTransform(screenTransform);
1304     layer->setDrawTransform(screenTransform * TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1305
1306     occluded.setOcclusion(IntRect(100, 100, 150, 50));
1307     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1308     layer->invalidateRect(IntRect(0, 0, 600, 600));
1309     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1310     EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1311
1312     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1313     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 330000, 1);
1314     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 30000, 1);
1315 }
1316
1317 TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
1318 {
1319     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1320     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1321     TestCCOcclusionTracker occluded;
1322
1323     // The tile size is 100x100.
1324
1325     // This makes sure the painting works when the content space is scaled to
1326     // a different layer space. In this case tiles are scaled to be 200x200
1327     // pixels, which means none should be occluded.
1328     layer->setContentsScale(0.5);
1329     layer->setBounds(IntSize(600, 600));
1330     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1331
1332     occluded.setOcclusion(IntRect(200, 200, 300, 100));
1333     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1334     layer->invalidateRect(IntRect(0, 0, 600, 600));
1335     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1336     // The content is half the size of the layer (so the number of tiles is fewer).
1337     // In this case, the content is 300x300, and since the tile size is 100, the
1338     // number of tiles 3x3.
1339     EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
1340
1341     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1342     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 90000, 1);
1343     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1344
1345     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1346
1347     // This makes sure the painting works when the content space is scaled to
1348     // a different layer space. In this case the occluded region catches the
1349     // blown up tiles.
1350     occluded.setOcclusion(IntRect(200, 200, 300, 200));
1351     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1352     layer->invalidateRect(IntRect(0, 0, 600, 600));
1353     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1354     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1355
1356     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1357     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 90000 + 80000, 1);
1358     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 10000, 1);
1359
1360     layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1361
1362     // This makes sure content scaling and transforms work together.
1363     TransformationMatrix screenTransform;
1364     screenTransform.scale(0.5);
1365     layer->setScreenSpaceTransform(screenTransform);
1366     layer->setDrawTransform(screenTransform * TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1367
1368     occluded.setOcclusion(IntRect(100, 100, 150, 100));
1369     layer->setVisibleLayerRect(IntRect(IntPoint(), layer->bounds()));
1370     layer->invalidateRect(IntRect(0, 0, 600, 600));
1371     layer->prepareToUpdate(IntRect(0, 0, 600, 600), &occluded);
1372     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1373
1374     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1375     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 90000 + 80000 + 80000, 1);
1376     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 10000 + 10000, 1);
1377 }
1378
1379 TEST(TiledLayerChromiumTest, opaqueContentsRegion)
1380 {
1381     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1382     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1383     TestCCOcclusionTracker occluded;
1384
1385     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1386
1387     IntRect opaquePaintRect;
1388     Region opaqueContents;
1389
1390     IntRect contentBounds = IntRect(0, 0, 100, 200);
1391     IntRect visibleBounds = IntRect(0, 0, 100, 150);
1392
1393     layer->setBounds(contentBounds.size());
1394     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1395     layer->setVisibleLayerRect(visibleBounds);
1396     layer->setDrawOpacity(1);
1397
1398     // If the layer doesn't paint opaque content, then the opaqueContentsRegion should be empty.
1399     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1400     layer->invalidateRect(contentBounds);
1401     layer->prepareToUpdate(contentBounds, &occluded);
1402     opaqueContents = layer->opaqueContentsRegion();
1403     EXPECT_TRUE(opaqueContents.isEmpty());
1404
1405     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
1406     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1407     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000, 1);
1408     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1409
1410     // opaqueContentsRegion should match the visible part of what is painted opaque.
1411     opaquePaintRect = IntRect(10, 10, 90, 190);
1412     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
1413     layer->invalidateRect(contentBounds);
1414     layer->prepareToUpdate(contentBounds, &occluded);
1415     opaqueContents = layer->opaqueContentsRegion();
1416     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1417     EXPECT_EQ(1u, opaqueContents.rects().size());
1418
1419     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1420     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 17100, 1);
1421     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000 + 20000 - 17100, 1);
1422     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1423
1424     // If we paint again without invalidating, the same stuff should be opaque.
1425     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1426     layer->prepareToUpdate(contentBounds, &occluded);
1427     opaqueContents = layer->opaqueContentsRegion();
1428     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1429     EXPECT_EQ(1u, opaqueContents.rects().size());
1430
1431     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1432     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 17100, 1);
1433     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000 + 20000 - 17100, 1);
1434     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1435
1436     // If we repaint a non-opaque part of the tile, then it shouldn't lose its opaque-ness. And other tiles should
1437     // not be affected.
1438     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1439     layer->invalidateRect(IntRect(0, 0, 1, 1));
1440     layer->prepareToUpdate(contentBounds, &occluded);
1441     opaqueContents = layer->opaqueContentsRegion();
1442     EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
1443     EXPECT_EQ(1u, opaqueContents.rects().size());
1444
1445     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
1446     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 17100, 1);
1447     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000 + 20000 - 17100 + 1, 1);
1448     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1449
1450     // If we repaint an opaque part of the tile, then it should lose its opaque-ness. But other tiles should still
1451     // not be affected.
1452     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1453     layer->invalidateRect(IntRect(10, 10, 1, 1));
1454     layer->prepareToUpdate(contentBounds, &occluded);
1455     opaqueContents = layer->opaqueContentsRegion();
1456     EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
1457     EXPECT_EQ(1u, opaqueContents.rects().size());
1458
1459     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1  + 1, 1);
1460     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 17100, 1);
1461     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1462     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1463 }
1464
1465 TEST(TiledLayerChromiumTest, pixelsPaintedMetrics)
1466 {
1467     OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
1468     RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
1469     TestCCOcclusionTracker occluded;
1470
1471     // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
1472
1473     IntRect opaquePaintRect;
1474     Region opaqueContents;
1475
1476     IntRect contentBounds = IntRect(0, 0, 100, 300);
1477     IntRect visibleBounds = IntRect(0, 0, 100, 300);
1478
1479     layer->setBounds(contentBounds.size());
1480     layer->setDrawTransform(TransformationMatrix(1, 0, 0, 1, layer->bounds().width() / 2.0, layer->bounds().height() / 2.0));
1481     layer->setVisibleLayerRect(visibleBounds);
1482     layer->setDrawOpacity(1);
1483
1484     // Invalidates and paints the whole layer.
1485     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1486     layer->invalidateRect(contentBounds);
1487     layer->prepareToUpdate(contentBounds, &occluded);
1488     opaqueContents = layer->opaqueContentsRegion();
1489     EXPECT_TRUE(opaqueContents.isEmpty());
1490
1491     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
1492     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1493     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 30000, 1);
1494     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1495
1496     // Invalidates an area on the top and bottom tile, which will cause us to paint the tile in the middle,
1497     // even though it is not dirty and will not be uploaded.
1498     layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1499     layer->invalidateRect(IntRect(0, 0, 1, 1));
1500     layer->invalidateRect(IntRect(50, 200, 10, 10));
1501     layer->prepareToUpdate(contentBounds, &occluded);
1502     opaqueContents = layer->opaqueContentsRegion();
1503     EXPECT_TRUE(opaqueContents.isEmpty());
1504
1505     // The middle tile was painted even though not invalidated.
1506     EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1);
1507     // The pixels uploaded will not include the non-invalidated tile in the middle.
1508     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnOpaque(), 0, 1);
1509     EXPECT_NEAR(occluded.overdrawMetrics().pixelsDrawnTranslucent(), 30000 + 1 + 100, 1);
1510     EXPECT_NEAR(occluded.overdrawMetrics().pixelsCulled(), 0, 1);
1511 }
1512
1513 } // namespace