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