Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: cc/TiledLayerChromiumTest.cpp

Issue 11108020: [cc] Change cc_tests.gyp filenames to Chromium style (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/ThrottledTextureUploaderTest.cpp ('k') | cc/TreeSynchronizerTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6
7 #include "TiledLayerChromium.h"
8
9 #include "BitmapCanvasLayerTextureUpdater.h"
10 #include "CCAnimationTestCommon.h"
11 #include "CCGeometryTestUtils.h"
12 #include "CCOverdrawMetrics.h"
13 #include "CCRenderingStats.h"
14 #include "CCSingleThreadProxy.h" // For DebugScopedSetImplThread
15 #include "CCTextureUpdateController.h"
16 #include "CCTiledLayerTestCommon.h"
17 #include "FakeCCGraphicsContext.h"
18 #include "FakeCCLayerTreeHostClient.h"
19 #include "LayerPainterChromium.h"
20 #include "WebCompositorInitializer.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include <public/WebTransformationMatrix.h>
23
24 using namespace cc;
25 using namespace WebKitTests;
26 using namespace WTF;
27 using WebKit::WebTransformationMatrix;
28
29 namespace {
30
31 class TestCCOcclusionTracker : public CCOcclusionTracker {
32 public:
33 TestCCOcclusionTracker()
34 : CCOcclusionTracker(IntRect(0, 0, 1000, 1000), true)
35 , m_layerClipRectInTarget(IntRect(0, 0, 1000, 1000))
36 {
37 // Pretend we have visited a render surface.
38 m_stack.append(StackObject());
39 }
40
41 void setOcclusion(const Region& occlusion) { m_stack.last().occlusionInScree n = occlusion; }
42
43 protected:
44 virtual IntRect layerClipRectInTarget(const LayerChromium* layer) const OVER RIDE { return m_layerClipRectInTarget; }
45
46 private:
47 IntRect m_layerClipRectInTarget;
48 };
49
50 class TiledLayerChromiumTest : public testing::Test {
51 public:
52 TiledLayerChromiumTest()
53 : m_compositorInitializer(0)
54 , m_context(WebKit::createFakeCCGraphicsContext())
55 , m_queue(adoptPtr(new CCTextureUpdateQueue))
56 , m_textureManager(CCPrioritizedTextureManager::create(60*1024*1024, 102 4, CCRenderer::ContentPool))
57 , m_occlusion(0)
58 {
59 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBloc ked;
60 m_resourceProvider = CCResourceProvider::create(m_context.get());
61 }
62
63 virtual ~TiledLayerChromiumTest()
64 {
65 textureManagerClearAllMemory(m_textureManager.get(), m_resourceProvider. get());
66 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBloc ked;
67 m_resourceProvider.clear();
68 }
69
70 // Helper classes and functions that set the current thread to be the impl t hread
71 // before doing the action that they wrap.
72 class ScopedFakeCCTiledLayerImpl {
73 public:
74 ScopedFakeCCTiledLayerImpl(int id)
75 {
76 DebugScopedSetImplThread implThread;
77 m_layerImpl = new FakeCCTiledLayerImpl(id);
78 }
79 ~ScopedFakeCCTiledLayerImpl()
80 {
81 DebugScopedSetImplThread implThread;
82 delete m_layerImpl;
83 }
84 FakeCCTiledLayerImpl* get()
85 {
86 return m_layerImpl;
87 }
88 FakeCCTiledLayerImpl* operator->()
89 {
90 return m_layerImpl;
91 }
92 private:
93 FakeCCTiledLayerImpl* m_layerImpl;
94 };
95 void textureManagerClearAllMemory(CCPrioritizedTextureManager* textureManage r, CCResourceProvider* resourceProvider)
96 {
97 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBloc ked;
98 textureManager->clearAllMemory(resourceProvider);
99 }
100 void updateTextures()
101 {
102 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBloc ked;
103 ASSERT(m_queue);
104 OwnPtr<CCTextureUpdateController> updateController =
105 CCTextureUpdateController::create(
106 NULL,
107 CCProxy::implThread(),
108 m_queue.release(),
109 m_resourceProvider.get(),
110 &m_uploader);
111 updateController->finalize();
112 m_queue = adoptPtr(new CCTextureUpdateQueue);
113 }
114 void layerPushPropertiesTo(FakeTiledLayerChromium* layer, FakeCCTiledLayerIm pl* layerImpl)
115 {
116 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBloc ked;
117 layer->pushPropertiesTo(layerImpl);
118 }
119 void layerUpdate(FakeTiledLayerChromium* layer, TestCCOcclusionTracker* occl uded)
120 {
121 DebugScopedSetMainThread mainThread;
122 layer->update(*m_queue.get(), occluded, m_stats);
123 }
124
125 bool updateAndPush(FakeTiledLayerChromium* layer1,
126 FakeCCTiledLayerImpl* layerImpl1,
127 FakeTiledLayerChromium* layer2 = 0,
128 FakeCCTiledLayerImpl* layerImpl2 = 0)
129 {
130 // Get textures
131 m_textureManager->clearPriorities();
132 if (layer1)
133 layer1->setTexturePriorities(m_priorityCalculator);
134 if (layer2)
135 layer2->setTexturePriorities(m_priorityCalculator);
136 m_textureManager->prioritizeTextures();
137
138 // Update content
139 if (layer1)
140 layer1->update(*m_queue.get(), m_occlusion, m_stats);
141 if (layer2)
142 layer2->update(*m_queue.get(), m_occlusion, m_stats);
143
144 bool needsUpdate = false;
145 if (layer1)
146 needsUpdate |= layer1->needsIdlePaint();
147 if (layer2)
148 needsUpdate |= layer2->needsIdlePaint();
149
150 // Update textures and push.
151 updateTextures();
152 if (layer1)
153 layerPushPropertiesTo(layer1, layerImpl1);
154 if (layer2)
155 layerPushPropertiesTo(layer2, layerImpl2);
156
157 return needsUpdate;
158 }
159
160 public:
161 WebKitTests::WebCompositorInitializer m_compositorInitializer;
162 scoped_ptr<CCGraphicsContext> m_context;
163 OwnPtr<CCResourceProvider> m_resourceProvider;
164 OwnPtr<CCTextureUpdateQueue> m_queue;
165 CCRenderingStats m_stats;
166 FakeTextureUploader m_uploader;
167 CCPriorityCalculator m_priorityCalculator;
168 scoped_ptr<CCPrioritizedTextureManager> m_textureManager;
169 TestCCOcclusionTracker* m_occlusion;
170 };
171
172 TEST_F(TiledLayerChromiumTest, pushDirtyTiles)
173 {
174 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
175 ScopedFakeCCTiledLayerImpl layerImpl(1);
176
177 // The tile size is 100x100, so this invalidates and then paints two tiles.
178 layer->setBounds(IntSize(100, 200));
179 layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
180 layer->invalidateContentRect(IntRect(0, 0, 100, 200));
181 updateAndPush(layer.get(), layerImpl.get());
182
183 // We should have both tiles on the impl side.
184 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
185 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
186
187 // Invalidates both tiles, but then only update one of them.
188 layer->setBounds(IntSize(100, 200));
189 layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
190 layer->invalidateContentRect(IntRect(0, 0, 100, 200));
191 updateAndPush(layer.get(), layerImpl.get());
192
193 // We should only have the first tile since the other tile was invalidated b ut not painted.
194 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
195 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 1));
196 }
197
198 TEST_F(TiledLayerChromiumTest, pushOccludedDirtyTiles)
199 {
200 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
201 ScopedFakeCCTiledLayerImpl layerImpl(1);
202 TestCCOcclusionTracker occluded;
203 m_occlusion = &occluded;
204
205 // The tile size is 100x100, so this invalidates and then paints two tiles.
206 layer->setBounds(IntSize(100, 200));
207 layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
208 layer->invalidateContentRect(IntRect(0, 0, 100, 200));
209 updateAndPush(layer.get(), layerImpl.get());
210
211 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
212 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1 );
213 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
214
215 // We should have both tiles on the impl side.
216 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
217 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
218
219 // Invalidates part of the top tile...
220 layer->invalidateContentRect(IntRect(0, 0, 50, 50));
221 // ....but the area is occluded.
222 occluded.setOcclusion(IntRect(0, 0, 50, 50));
223 updateAndPush(layer.get(), layerImpl.get());
224
225 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
226 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 2500, 1);
227 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
228
229 // We should still have both tiles, as part of the top tile is still unocclu ded.
230 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
231 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
232 }
233
234 TEST_F(TiledLayerChromiumTest, pushDeletedTiles)
235 {
236 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
237 ScopedFakeCCTiledLayerImpl layerImpl(1);
238
239 // The tile size is 100x100, so this invalidates and then paints two tiles.
240 layer->setBounds(IntSize(100, 200));
241 layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
242 layer->invalidateContentRect(IntRect(0, 0, 100, 200));
243 updateAndPush(layer.get(), layerImpl.get());
244
245 // We should have both tiles on the impl side.
246 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
247 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
248
249 m_textureManager->clearPriorities();
250 textureManagerClearAllMemory(m_textureManager.get(), m_resourceProvider.get( ));
251 m_textureManager->setMaxMemoryLimitBytes(4*1024*1024);
252
253 // This should drop the tiles on the impl thread.
254 layerPushPropertiesTo(layer.get(), layerImpl.get());
255
256 // We should now have no textures on the impl thread.
257 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 0));
258 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 1));
259
260 // This should recreate and update one of the deleted textures.
261 layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
262 updateAndPush(layer.get(), layerImpl.get());
263
264 // We should have one tiles on the impl side.
265 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
266 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 1));
267 }
268
269 TEST_F(TiledLayerChromiumTest, pushIdlePaintTiles)
270 {
271 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
272 ScopedFakeCCTiledLayerImpl layerImpl(1);
273
274 // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the ce nter.
275 // This paints 1 visible of the 25 invalid tiles.
276 layer->setBounds(IntSize(500, 500));
277 layer->setVisibleContentRect(IntRect(200, 200, 100, 100));
278 layer->invalidateContentRect(IntRect(0, 0, 500, 500));
279 bool needsUpdate = updateAndPush(layer.get(), layerImpl.get());
280 // We should need idle-painting for surrounding tiles.
281 EXPECT_TRUE(needsUpdate);
282
283 // We should have one tile on the impl side.
284 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(2, 2));
285
286 // For the next four updates, we should detect we still need idle painting.
287 for (int i = 0; i < 4; i++) {
288 needsUpdate = updateAndPush(layer.get(), layerImpl.get());
289 EXPECT_TRUE(needsUpdate);
290 }
291
292 // We should have one tile surrounding the visible tile on all sides, but no other tiles.
293 IntRect idlePaintTiles(1, 1, 3, 3);
294 for (int i = 0; i < 5; i++) {
295 for (int j = 0; j < 5; j++)
296 EXPECT_EQ(layerImpl->hasResourceIdForTileAt(i, j), idlePaintTiles.co ntains(i, j));
297 }
298
299 // We should always finish painting eventually.
300 for (int i = 0; i < 20; i++)
301 needsUpdate = updateAndPush(layer.get(), layerImpl.get());
302 EXPECT_FALSE(needsUpdate);
303 }
304
305 TEST_F(TiledLayerChromiumTest, pushTilesAfterIdlePaintFailed)
306 {
307 // Start with 2mb of memory, but the test is going to try to use just more t han 1mb, so we reduce to 1mb later.
308 m_textureManager->setMaxMemoryLimitBytes(2 * 1024 * 1024);
309 scoped_refptr<FakeTiledLayerChromium> layer1 = make_scoped_refptr(new FakeTi ledLayerChromium(m_textureManager.get()));
310 ScopedFakeCCTiledLayerImpl layerImpl1(1);
311 scoped_refptr<FakeTiledLayerChromium> layer2 = make_scoped_refptr(new FakeTi ledLayerChromium(m_textureManager.get()));
312 ScopedFakeCCTiledLayerImpl layerImpl2(2);
313
314 // For this test we have two layers. layer1 exhausts most texture memory, le aving room for 2 more tiles from
315 // layer2, but not all three tiles. First we paint layer1, and one tile from layer2. Then when we idle paint
316 // layer2, we will fail on the third tile of layer2, and this should not lea ve the second tile in a bad state.
317
318 // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enou gh for 2 tiles only in the other layer.
319 IntRect layer1Rect(0, 0, 100, 2400);
320
321 // This requires 4*30000 bytes of memory.
322 IntRect layer2Rect(0, 0, 100, 300);
323
324 // Paint a single tile in layer2 so that it will idle paint.
325 layer1->setBounds(layer1Rect.size());
326 layer1->setVisibleContentRect(layer1Rect);
327 layer2->setBounds(layer2Rect.size());
328 layer2->setVisibleContentRect(IntRect(0, 0, 100, 100));
329 bool needsUpdate = updateAndPush(layer1.get(), layerImpl1.get(),
330 layer2.get(), layerImpl2.get());
331 // We should need idle-painting for both remaining tiles in layer2.
332 EXPECT_TRUE(needsUpdate);
333
334 // Reduce our memory limits to 1mb.
335 m_textureManager->setMaxMemoryLimitBytes(1024 * 1024);
336
337 // Now idle paint layer2. We are going to run out of memory though!
338 // Oh well, commit the frame and push.
339 for (int i = 0; i < 4; i++) {
340 needsUpdate = updateAndPush(layer1.get(), layerImpl1.get(),
341 layer2.get(), layerImpl2.get());
342 }
343
344 // Sanity check, we should have textures for the big layer.
345 EXPECT_TRUE(layerImpl1->hasResourceIdForTileAt(0, 0));
346 EXPECT_TRUE(layerImpl1->hasResourceIdForTileAt(0, 23));
347
348 // We should only have the first two tiles from layer2 since
349 // it failed to idle update the last tile.
350 EXPECT_TRUE(layerImpl2->hasResourceIdForTileAt(0, 0));
351 EXPECT_TRUE(layerImpl2->hasResourceIdForTileAt(0, 0));
352 EXPECT_TRUE(layerImpl2->hasResourceIdForTileAt(0, 1));
353 EXPECT_TRUE(layerImpl2->hasResourceIdForTileAt(0, 1));
354
355 EXPECT_FALSE(needsUpdate);
356 EXPECT_FALSE(layerImpl2->hasResourceIdForTileAt(0, 2));
357 }
358
359 TEST_F(TiledLayerChromiumTest, pushIdlePaintedOccludedTiles)
360 {
361 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
362 ScopedFakeCCTiledLayerImpl layerImpl(1);
363 TestCCOcclusionTracker occluded;
364 m_occlusion = &occluded;
365
366 // The tile size is 100x100, so this invalidates one occluded tile, culls it during paint, but prepaints it.
367 occluded.setOcclusion(IntRect(0, 0, 100, 100));
368
369 layer->setBounds(IntSize(100, 100));
370 layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
371 updateAndPush(layer.get(), layerImpl.get());
372
373 // We should have the prepainted tile on the impl side, but culled it during paint.
374 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
375 EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
376 }
377
378 TEST_F(TiledLayerChromiumTest, pushTilesMarkedDirtyDuringPaint)
379 {
380 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
381 ScopedFakeCCTiledLayerImpl layerImpl(1);
382
383 // The tile size is 100x100, so this invalidates and then paints two tiles.
384 // However, during the paint, we invalidate one of the tiles. This should
385 // not prevent the tile from being pushed.
386 layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 50 ), layer.get());
387 layer->setBounds(IntSize(100, 200));
388 layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
389 updateAndPush(layer.get(), layerImpl.get());
390
391 // We should have both tiles on the impl side.
392 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
393 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
394 }
395
396 TEST_F(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnNextLayer)
397 {
398 scoped_refptr<FakeTiledLayerChromium> layer1 = make_scoped_refptr(new FakeTi ledLayerChromium(m_textureManager.get()));
399 scoped_refptr<FakeTiledLayerChromium> layer2 = make_scoped_refptr(new FakeTi ledLayerChromium(m_textureManager.get()));
400 ScopedFakeCCTiledLayerImpl layer1Impl(1);
401 ScopedFakeCCTiledLayerImpl layer2Impl(2);
402
403 // Invalidate a tile on layer1, during update of layer 2.
404 layer2->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 5 0), layer1.get());
405 layer1->setBounds(IntSize(100, 200));
406 layer1->setVisibleContentRect(IntRect(0, 0, 100, 200));
407 layer2->setBounds(IntSize(100, 200));
408 layer2->setVisibleContentRect(IntRect(0, 0, 100, 200));
409 updateAndPush(layer1.get(), layer1Impl.get(),
410 layer2.get(), layer2Impl.get());
411
412 // We should have both tiles on the impl side for all layers.
413 EXPECT_TRUE(layer1Impl->hasResourceIdForTileAt(0, 0));
414 EXPECT_TRUE(layer1Impl->hasResourceIdForTileAt(0, 1));
415 EXPECT_TRUE(layer2Impl->hasResourceIdForTileAt(0, 0));
416 EXPECT_TRUE(layer2Impl->hasResourceIdForTileAt(0, 1));
417 }
418
419 TEST_F(TiledLayerChromiumTest, pushTilesLayerMarkedDirtyDuringPaintOnPreviousLay er)
420 {
421 scoped_refptr<FakeTiledLayerChromium> layer1 = make_scoped_refptr(new FakeTi ledLayerChromium(m_textureManager.get()));
422 scoped_refptr<FakeTiledLayerChromium> layer2 = make_scoped_refptr(new FakeTi ledLayerChromium(m_textureManager.get()));
423 ScopedFakeCCTiledLayerImpl layer1Impl(1);
424 ScopedFakeCCTiledLayerImpl layer2Impl(2);
425
426 layer1->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(0, 50, 100, 5 0), layer2.get());
427 layer1->setBounds(IntSize(100, 200));
428 layer1->setVisibleContentRect(IntRect(0, 0, 100, 200));
429 layer2->setBounds(IntSize(100, 200));
430 layer2->setVisibleContentRect(IntRect(0, 0, 100, 200));
431 updateAndPush(layer1.get(), layer1Impl.get(),
432 layer2.get(), layer2Impl.get());
433
434 // We should have both tiles on the impl side for all layers.
435 EXPECT_TRUE(layer1Impl->hasResourceIdForTileAt(0, 0));
436 EXPECT_TRUE(layer1Impl->hasResourceIdForTileAt(0, 1));
437 EXPECT_TRUE(layer2Impl->hasResourceIdForTileAt(0, 0));
438 EXPECT_TRUE(layer2Impl->hasResourceIdForTileAt(0, 1));
439 }
440
441 TEST_F(TiledLayerChromiumTest, paintSmallAnimatedLayersImmediately)
442 {
443 // Create a CCLayerTreeHost that has the right viewportsize,
444 // so the layer is considered small enough.
445 FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
446 scoped_ptr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeC CLayerTreeHostClient, CCLayerTreeSettings());
447
448 bool runOutOfMemory[2] = {false, true};
449 for (int i = 0; i < 2; i++) {
450 // Create a layer with 4x4 tiles.
451 int layerWidth = 4 * FakeTiledLayerChromium::tileSize().width();
452 int layerHeight = 4 * FakeTiledLayerChromium::tileSize().height();
453 int memoryForLayer = layerWidth * layerHeight * 4;
454 IntSize viewportSize = IntSize(layerWidth, layerHeight);
455 ccLayerTreeHost->setViewportSize(viewportSize, viewportSize);
456
457 // Use 8x4 tiles to run out of memory.
458 if (runOutOfMemory[i])
459 layerWidth *= 2;
460
461 m_textureManager->setMaxMemoryLimitBytes(memoryForLayer);
462
463 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new Fak eTiledLayerChromium(m_textureManager.get()));
464 ScopedFakeCCTiledLayerImpl layerImpl(1);
465
466 // Full size layer with half being visible.
467 IntSize contentBounds(layerWidth, layerHeight);
468 IntRect contentRect(IntPoint::zero(), contentBounds);
469 IntRect visibleRect(IntPoint::zero(), IntSize(layerWidth / 2, layerHeigh t));
470
471 // Pretend the layer is animating.
472 layer->setDrawTransformIsAnimating(true);
473 layer->setBounds(contentBounds);
474 layer->setVisibleContentRect(visibleRect);
475 layer->invalidateContentRect(contentRect);
476 layer->setLayerTreeHost(ccLayerTreeHost.get());
477
478 // The layer should paint it's entire contents on the first paint
479 // if it is close to the viewport size and has the available memory.
480 layer->setTexturePriorities(m_priorityCalculator);
481 m_textureManager->prioritizeTextures();
482 layer->update(*m_queue.get(), 0, m_stats);
483 updateTextures();
484 layerPushPropertiesTo(layer.get(), layerImpl.get());
485
486 // We should have all the tiles for the small animated layer.
487 // We should still have the visible tiles when we didn't
488 // have enough memory for all the tiles.
489 if (!runOutOfMemory[i]) {
490 for (int i = 0; i < 4; ++i) {
491 for (int j = 0; j < 4; ++j)
492 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(i, j));
493 }
494 } else {
495 for (int i = 0; i < 8; ++i) {
496 for (int j = 0; j < 4; ++j)
497 EXPECT_EQ(layerImpl->hasResourceIdForTileAt(i, j), i < 4);
498 }
499 }
500 }
501 }
502
503 TEST_F(TiledLayerChromiumTest, idlePaintOutOfMemory)
504 {
505 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
506 ScopedFakeCCTiledLayerImpl layerImpl(1);
507
508 // We have enough memory for only the visible rect, so we will run out of me mory in first idle paint.
509 int memoryLimit = 4 * 100 * 100; // 1 tiles, 4 bytes per pixel.
510 m_textureManager->setMaxMemoryLimitBytes(memoryLimit);
511
512 // The tile size is 100x100, so this invalidates and then paints two tiles.
513 bool needsUpdate = false;
514 layer->setBounds(IntSize(300, 300));
515 layer->setVisibleContentRect(IntRect(100, 100, 100, 100));
516 for (int i = 0; i < 2; i++)
517 needsUpdate = updateAndPush(layer.get(), layerImpl.get());
518
519 // Idle-painting should see no more priority tiles for painting.
520 EXPECT_FALSE(needsUpdate);
521
522 // We should have one tile on the impl side.
523 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(1, 1));
524 }
525
526 TEST_F(TiledLayerChromiumTest, idlePaintZeroSizedLayer)
527 {
528 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
529 ScopedFakeCCTiledLayerImpl layerImpl(1);
530
531 bool animating[2] = {false, true};
532 for (int i = 0; i < 2; i++) {
533 // Pretend the layer is animating.
534 layer->setDrawTransformIsAnimating(animating[i]);
535
536 // The layer's bounds are empty.
537 // Empty layers don't paint or idle-paint.
538 layer->setBounds(IntSize());
539 layer->setVisibleContentRect(IntRect());
540 bool needsUpdate = updateAndPush(layer.get(), layerImpl.get());
541
542 // Empty layers don't have tiles.
543 EXPECT_EQ(0u, layer->numPaintedTiles());
544
545 // Empty layers don't need prepaint.
546 EXPECT_FALSE(needsUpdate);
547
548 // Empty layers don't have tiles.
549 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 0));
550 }
551 }
552
553 TEST_F(TiledLayerChromiumTest, idlePaintNonVisibleLayers)
554 {
555 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
556 ScopedFakeCCTiledLayerImpl layerImpl(1);
557
558 // Alternate between not visible and visible.
559 IntRect v(0, 0, 100, 100);
560 IntRect nv(0, 0, 0, 0);
561 IntRect visibleRect[10] = {nv, nv, v, v, nv, nv, v, v, nv, nv};
562 bool invalidate[10] = {true, true, true, true, true, true, true, true, fals e, false };
563
564 // We should not have any tiles except for when the layer was visible
565 // or after the layer was visible and we didn't invalidate.
566 bool haveTile[10] = { false, false, true, true, false, false, true, true, tr ue, true };
567
568 for (int i = 0; i < 10; i++) {
569 layer->setBounds(IntSize(100, 100));
570 layer->setVisibleContentRect(visibleRect[i]);
571
572 if (invalidate[i])
573 layer->invalidateContentRect(IntRect(0, 0, 100, 100));
574 bool needsUpdate = updateAndPush(layer.get(), layerImpl.get());
575
576 // We should never signal idle paint, as we painted the entire layer
577 // or the layer was not visible.
578 EXPECT_FALSE(needsUpdate);
579 EXPECT_EQ(layerImpl->hasResourceIdForTileAt(0, 0), haveTile[i]);
580 }
581 }
582
583 TEST_F(TiledLayerChromiumTest, invalidateFromPrepare)
584 {
585 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
586 ScopedFakeCCTiledLayerImpl layerImpl(1);
587
588 // The tile size is 100x100, so this invalidates and then paints two tiles.
589 layer->setBounds(IntSize(100, 200));
590 layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
591 updateAndPush(layer.get(), layerImpl.get());
592
593 // We should have both tiles on the impl side.
594 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
595 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
596
597 layer->fakeLayerTextureUpdater()->clearPrepareCount();
598 // Invoke update again. As the layer is valid update shouldn't be invoked on
599 // the LayerTextureUpdater.
600 updateAndPush(layer.get(), layerImpl.get());
601 EXPECT_EQ(0, layer->fakeLayerTextureUpdater()->prepareCount());
602
603 // setRectToInvalidate triggers invalidateContentRect() being invoked from u pdate.
604 layer->fakeLayerTextureUpdater()->setRectToInvalidate(IntRect(25, 25, 50, 50 ), layer.get());
605 layer->fakeLayerTextureUpdater()->clearPrepareCount();
606 layer->invalidateContentRect(IntRect(0, 0, 50, 50));
607 updateAndPush(layer.get(), layerImpl.get());
608 EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
609 layer->fakeLayerTextureUpdater()->clearPrepareCount();
610
611 // The layer should still be invalid as update invoked invalidate.
612 updateAndPush(layer.get(), layerImpl.get()); // visible
613 EXPECT_EQ(1, layer->fakeLayerTextureUpdater()->prepareCount());
614 }
615
616 TEST_F(TiledLayerChromiumTest, verifyUpdateRectWhenContentBoundsAreScaled)
617 {
618 // The updateRect (that indicates what was actually painted) should be in
619 // layer space, not the content space.
620 scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(new FakeTiledLayerWithScaledBounds(m_textureManager.get()));
621
622 IntRect layerBounds(0, 0, 300, 200);
623 IntRect contentBounds(0, 0, 200, 250);
624
625 layer->setBounds(layerBounds.size());
626 layer->setContentBounds(contentBounds.size());
627 layer->setVisibleContentRect(contentBounds);
628
629 // On first update, the updateRect includes all tiles, even beyond the bound aries of the layer.
630 // However, it should still be in layer space, not content space.
631 layer->invalidateContentRect(contentBounds);
632
633 layer->setTexturePriorities(m_priorityCalculator);
634 m_textureManager->prioritizeTextures();
635 layer->update(*m_queue.get(), 0, m_stats);
636 EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 300, 300 * 0.8), layer->updateRect());
637 updateTextures();
638
639 // After the tiles are updated once, another invalidate only needs to update the bounds of the layer.
640 layer->setTexturePriorities(m_priorityCalculator);
641 m_textureManager->prioritizeTextures();
642 layer->invalidateContentRect(contentBounds);
643 layer->update(*m_queue.get(), 0, m_stats);
644 EXPECT_FLOAT_RECT_EQ(FloatRect(layerBounds), layer->updateRect());
645 updateTextures();
646
647 // Partial re-paint should also be represented by the updateRect in layer sp ace, not content space.
648 IntRect partialDamage(30, 100, 10, 10);
649 layer->invalidateContentRect(partialDamage);
650 layer->setTexturePriorities(m_priorityCalculator);
651 m_textureManager->prioritizeTextures();
652 layer->update(*m_queue.get(), 0, m_stats);
653 EXPECT_FLOAT_RECT_EQ(FloatRect(45, 80, 15, 8), layer->updateRect());
654 }
655
656 TEST_F(TiledLayerChromiumTest, verifyInvalidationWhenContentsScaleChanges)
657 {
658 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
659 ScopedFakeCCTiledLayerImpl layerImpl(1);
660
661 // Create a layer with one tile.
662 layer->setBounds(IntSize(100, 100));
663 layer->setVisibleContentRect(IntRect(0, 0, 100, 100));
664
665 // Invalidate the entire layer.
666 layer->setNeedsDisplay();
667 EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect( ));
668
669 // Push the tiles to the impl side and check that there is exactly one.
670 layer->setTexturePriorities(m_priorityCalculator);
671 m_textureManager->prioritizeTextures();
672 layer->update(*m_queue.get(), 0, m_stats);
673 updateTextures();
674 layerPushPropertiesTo(layer.get(), layerImpl.get());
675 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
676 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 1));
677 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(1, 0));
678 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(1, 1));
679
680 // Change the contents scale and verify that the content rectangle requiring painting
681 // is not scaled.
682 layer->setContentsScale(2);
683 layer->setVisibleContentRect(IntRect(0, 0, 200, 200));
684 EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 100, 100), layer->lastNeedsDisplayRect( ));
685
686 // The impl side should get 2x2 tiles now.
687 layer->setTexturePriorities(m_priorityCalculator);
688 m_textureManager->prioritizeTextures();
689 layer->update(*m_queue.get(), 0, m_stats);
690 updateTextures();
691 layerPushPropertiesTo(layer.get(), layerImpl.get());
692 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 0));
693 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(0, 1));
694 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(1, 0));
695 EXPECT_TRUE(layerImpl->hasResourceIdForTileAt(1, 1));
696
697 // Invalidate the entire layer again, but do not paint. All tiles should be gone now from the
698 // impl side.
699 layer->setNeedsDisplay();
700 layer->setTexturePriorities(m_priorityCalculator);
701 m_textureManager->prioritizeTextures();
702
703 layerPushPropertiesTo(layer.get(), layerImpl.get());
704 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 0));
705 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(0, 1));
706 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(1, 0));
707 EXPECT_FALSE(layerImpl->hasResourceIdForTileAt(1, 1));
708 }
709
710 TEST_F(TiledLayerChromiumTest, skipsDrawGetsReset)
711 {
712 FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
713 scoped_ptr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeC CLayerTreeHostClient, CCLayerTreeSettings());
714 ASSERT_TRUE(ccLayerTreeHost->initializeRendererIfNeeded());
715
716 // Create two 300 x 300 tiled layers.
717 IntSize contentBounds(300, 300);
718 IntRect contentRect(IntPoint::zero(), contentBounds);
719
720 // We have enough memory for only one of the two layers.
721 int memoryLimit = 4 * 300 * 300; // 4 bytes per pixel.
722
723 scoped_refptr<FakeTiledLayerChromium> rootLayer = make_scoped_refptr(new Fak eTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
724 scoped_refptr<FakeTiledLayerChromium> childLayer = make_scoped_refptr(new Fa keTiledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
725 rootLayer->addChild(childLayer);
726
727 rootLayer->setBounds(contentBounds);
728 rootLayer->setVisibleContentRect(contentRect);
729 rootLayer->setPosition(FloatPoint(0, 0));
730 childLayer->setBounds(contentBounds);
731 childLayer->setVisibleContentRect(contentRect);
732 childLayer->setPosition(FloatPoint(0, 0));
733 rootLayer->invalidateContentRect(contentRect);
734 childLayer->invalidateContentRect(contentRect);
735
736 ccLayerTreeHost->setRootLayer(rootLayer);
737 ccLayerTreeHost->setViewportSize(IntSize(300, 300), IntSize(300, 300));
738
739 ccLayerTreeHost->updateLayers(*m_queue.get(), memoryLimit);
740
741 // We'll skip the root layer.
742 EXPECT_TRUE(rootLayer->skipsDraw());
743 EXPECT_FALSE(childLayer->skipsDraw());
744
745 ccLayerTreeHost->commitComplete();
746
747 // Remove the child layer.
748 rootLayer->removeAllChildren();
749
750 ccLayerTreeHost->updateLayers(*m_queue.get(), memoryLimit);
751 EXPECT_FALSE(rootLayer->skipsDraw());
752
753 textureManagerClearAllMemory(ccLayerTreeHost->contentsTextureManager(), m_re sourceProvider.get());
754 ccLayerTreeHost->setRootLayer(0);
755 }
756
757 TEST_F(TiledLayerChromiumTest, resizeToSmaller)
758 {
759 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
760
761 layer->setBounds(IntSize(700, 700));
762 layer->setVisibleContentRect(IntRect(0, 0, 700, 700));
763 layer->invalidateContentRect(IntRect(0, 0, 700, 700));
764
765 layer->setTexturePriorities(m_priorityCalculator);
766 m_textureManager->prioritizeTextures();
767 layer->update(*m_queue.get(), 0, m_stats);
768
769 layer->setBounds(IntSize(200, 200));
770 layer->invalidateContentRect(IntRect(0, 0, 200, 200));
771 }
772
773 TEST_F(TiledLayerChromiumTest, hugeLayerUpdateCrash)
774 {
775 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
776
777 int size = 1 << 30;
778 layer->setBounds(IntSize(size, size));
779 layer->setVisibleContentRect(IntRect(0, 0, 700, 700));
780 layer->invalidateContentRect(IntRect(0, 0, size, size));
781
782 // Ensure no crash for bounds where size * size would overflow an int.
783 layer->setTexturePriorities(m_priorityCalculator);
784 m_textureManager->prioritizeTextures();
785 layer->update(*m_queue.get(), 0, m_stats);
786 }
787
788 TEST_F(TiledLayerChromiumTest, partialUpdates)
789 {
790 CCLayerTreeSettings settings;
791 settings.maxPartialTextureUpdates = 4;
792
793 FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
794 scoped_ptr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeC CLayerTreeHostClient, settings);
795 ASSERT_TRUE(ccLayerTreeHost->initializeRendererIfNeeded());
796
797 // Create one 300 x 200 tiled layer with 3 x 2 tiles.
798 IntSize contentBounds(300, 200);
799 IntRect contentRect(IntPoint::zero(), contentBounds);
800
801 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(ccLayerTreeHost->contentsTextureManager()));
802 layer->setBounds(contentBounds);
803 layer->setPosition(FloatPoint(0, 0));
804 layer->setVisibleContentRect(contentRect);
805 layer->invalidateContentRect(contentRect);
806
807 ccLayerTreeHost->setRootLayer(layer);
808 ccLayerTreeHost->setViewportSize(IntSize(300, 200), IntSize(300, 200));
809
810 // Full update of all 6 tiles.
811 ccLayerTreeHost->updateLayers(
812 *m_queue.get(), std::numeric_limits<size_t>::max());
813 {
814 ScopedFakeCCTiledLayerImpl layerImpl(1);
815 EXPECT_EQ(6, m_queue->fullUploadSize());
816 EXPECT_EQ(0, m_queue->partialUploadSize());
817 updateTextures();
818 EXPECT_EQ(6, layer->fakeLayerTextureUpdater()->updateCount());
819 EXPECT_FALSE(m_queue->hasMoreUpdates());
820 layer->fakeLayerTextureUpdater()->clearUpdateCount();
821 layerPushPropertiesTo(layer.get(), layerImpl.get());
822 }
823 ccLayerTreeHost->commitComplete();
824
825 // Full update of 3 tiles and partial update of 3 tiles.
826 layer->invalidateContentRect(IntRect(0, 0, 300, 150));
827 ccLayerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t>::m ax());
828 {
829 ScopedFakeCCTiledLayerImpl layerImpl(1);
830 EXPECT_EQ(3, m_queue->fullUploadSize());
831 EXPECT_EQ(3, m_queue->partialUploadSize());
832 updateTextures();
833 EXPECT_EQ(6, layer->fakeLayerTextureUpdater()->updateCount());
834 EXPECT_FALSE(m_queue->hasMoreUpdates());
835 layer->fakeLayerTextureUpdater()->clearUpdateCount();
836 layerPushPropertiesTo(layer.get(), layerImpl.get());
837 }
838 ccLayerTreeHost->commitComplete();
839
840 // Partial update of 6 tiles.
841 layer->invalidateContentRect(IntRect(50, 50, 200, 100));
842 {
843 ScopedFakeCCTiledLayerImpl layerImpl(1);
844 ccLayerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t >::max());
845 EXPECT_EQ(2, m_queue->fullUploadSize());
846 EXPECT_EQ(4, m_queue->partialUploadSize());
847 updateTextures();
848 EXPECT_EQ(6, layer->fakeLayerTextureUpdater()->updateCount());
849 EXPECT_FALSE(m_queue->hasMoreUpdates());
850 layer->fakeLayerTextureUpdater()->clearUpdateCount();
851 layerPushPropertiesTo(layer.get(), layerImpl.get());
852 }
853 ccLayerTreeHost->commitComplete();
854
855 // Checkerboard all tiles.
856 layer->invalidateContentRect(IntRect(0, 0, 300, 200));
857 {
858 ScopedFakeCCTiledLayerImpl layerImpl(1);
859 layerPushPropertiesTo(layer.get(), layerImpl.get());
860 }
861 ccLayerTreeHost->commitComplete();
862
863 // Partial update of 6 checkerboard tiles.
864 layer->invalidateContentRect(IntRect(50, 50, 200, 100));
865 {
866 ScopedFakeCCTiledLayerImpl layerImpl(1);
867 ccLayerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t >::max());
868 EXPECT_EQ(6, m_queue->fullUploadSize());
869 EXPECT_EQ(0, m_queue->partialUploadSize());
870 updateTextures();
871 EXPECT_EQ(6, layer->fakeLayerTextureUpdater()->updateCount());
872 EXPECT_FALSE(m_queue->hasMoreUpdates());
873 layer->fakeLayerTextureUpdater()->clearUpdateCount();
874 layerPushPropertiesTo(layer.get(), layerImpl.get());
875 }
876 ccLayerTreeHost->commitComplete();
877
878 // Partial update of 4 tiles.
879 layer->invalidateContentRect(IntRect(50, 50, 100, 100));
880 {
881 ScopedFakeCCTiledLayerImpl layerImpl(1);
882 ccLayerTreeHost->updateLayers(*m_queue.get(), std::numeric_limits<size_t >::max());
883 EXPECT_EQ(0, m_queue->fullUploadSize());
884 EXPECT_EQ(4, m_queue->partialUploadSize());
885 updateTextures();
886 EXPECT_EQ(4, layer->fakeLayerTextureUpdater()->updateCount());
887 EXPECT_FALSE(m_queue->hasMoreUpdates());
888 layer->fakeLayerTextureUpdater()->clearUpdateCount();
889 layerPushPropertiesTo(layer.get(), layerImpl.get());
890 }
891 ccLayerTreeHost->commitComplete();
892
893 textureManagerClearAllMemory(ccLayerTreeHost->contentsTextureManager(), m_re sourceProvider.get());
894 ccLayerTreeHost->setRootLayer(0);
895 }
896
897 TEST_F(TiledLayerChromiumTest, tilesPaintedWithoutOcclusion)
898 {
899 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
900
901 // The tile size is 100x100, so this invalidates and then paints two tiles.
902 layer->setBounds(IntSize(100, 200));
903 layer->setDrawableContentRect(IntRect(0, 0, 100, 200));
904 layer->setVisibleContentRect(IntRect(0, 0, 100, 200));
905 layer->invalidateContentRect(IntRect(0, 0, 100, 200));
906
907 layer->setTexturePriorities(m_priorityCalculator);
908 m_textureManager->prioritizeTextures();
909 layer->update(*m_queue.get(), 0, m_stats);
910 EXPECT_EQ(2, layer->fakeLayerTextureUpdater()->prepareRectCount());
911 }
912
913 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusion)
914 {
915 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
916 TestCCOcclusionTracker occluded;
917
918 // The tile size is 100x100.
919
920 layer->setBounds(IntSize(600, 600));
921
922 occluded.setOcclusion(IntRect(200, 200, 300, 100));
923 layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
924 layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
925 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
926
927 layer->setTexturePriorities(m_priorityCalculator);
928 m_textureManager->prioritizeTextures();
929 layer->update(*m_queue.get(), &occluded, m_stats);
930 EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
931
932 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
933 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
934 EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
935
936 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
937 layer->setTexturePriorities(m_priorityCalculator);
938 m_textureManager->prioritizeTextures();
939
940 occluded.setOcclusion(IntRect(250, 200, 300, 100));
941 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
942 layer->update(*m_queue.get(), &occluded, m_stats);
943 EXPECT_EQ(36-2, layer->fakeLayerTextureUpdater()->prepareRectCount());
944
945 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
946 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000, 1);
947 EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
948
949 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
950 layer->setTexturePriorities(m_priorityCalculator);
951 m_textureManager->prioritizeTextures();
952
953 occluded.setOcclusion(IntRect(250, 250, 300, 100));
954 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
955 layer->update(*m_queue.get(), &occluded, m_stats);
956 EXPECT_EQ(36, layer->fakeLayerTextureUpdater()->prepareRectCount());
957
958 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
959 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000 + 340000 + 360000, 1);
960 EXPECT_EQ(3 + 2, occluded.overdrawMetrics().tilesCulledForUpload());
961 }
962
963 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndVisiblityConstraints)
964 {
965 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
966 TestCCOcclusionTracker occluded;
967
968 // The tile size is 100x100.
969
970 layer->setBounds(IntSize(600, 600));
971
972 // The partially occluded tiles (by the 150 occlusion height) are visible be yond the occlusion, so not culled.
973 occluded.setOcclusion(IntRect(200, 200, 300, 150));
974 layer->setDrawableContentRect(IntRect(0, 0, 600, 360));
975 layer->setVisibleContentRect(IntRect(0, 0, 600, 360));
976 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
977
978 layer->setTexturePriorities(m_priorityCalculator);
979 m_textureManager->prioritizeTextures();
980 layer->update(*m_queue.get(), &occluded, m_stats);
981 EXPECT_EQ(24-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
982
983 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
984 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000, 1);
985 EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
986
987 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
988
989 // Now the visible region stops at the edge of the occlusion so the partly v isible tiles become fully occluded.
990 occluded.setOcclusion(IntRect(200, 200, 300, 150));
991 layer->setDrawableContentRect(IntRect(0, 0, 600, 350));
992 layer->setVisibleContentRect(IntRect(0, 0, 600, 350));
993 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
994 layer->setTexturePriorities(m_priorityCalculator);
995 m_textureManager->prioritizeTextures();
996 layer->update(*m_queue.get(), &occluded, m_stats);
997 EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
998
999 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1000 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000, 1);
1001 EXPECT_EQ(3 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1002
1003 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1004
1005 // Now the visible region is even smaller than the occlusion, it should have the same result.
1006 occluded.setOcclusion(IntRect(200, 200, 300, 150));
1007 layer->setDrawableContentRect(IntRect(0, 0, 600, 340));
1008 layer->setVisibleContentRect(IntRect(0, 0, 600, 340));
1009 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1010 layer->setTexturePriorities(m_priorityCalculator);
1011 m_textureManager->prioritizeTextures();
1012 layer->update(*m_queue.get(), &occluded, m_stats);
1013 EXPECT_EQ(24-6, layer->fakeLayerTextureUpdater()->prepareRectCount());
1014
1015 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1016 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 210000 + 180000 + 180000, 1);
1017 EXPECT_EQ(3 + 6 + 6, occluded.overdrawMetrics().tilesCulledForUpload());
1018
1019 }
1020
1021 TEST_F(TiledLayerChromiumTest, tilesNotPaintedWithoutInvalidation)
1022 {
1023 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
1024 TestCCOcclusionTracker occluded;
1025
1026 // The tile size is 100x100.
1027
1028 layer->setBounds(IntSize(600, 600));
1029
1030 occluded.setOcclusion(IntRect(200, 200, 300, 100));
1031 layer->setDrawableContentRect(IntRect(0, 0, 600, 600));
1032 layer->setVisibleContentRect(IntRect(0, 0, 600, 600));
1033 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1034 layer->setTexturePriorities(m_priorityCalculator);
1035 m_textureManager->prioritizeTextures();
1036 layer->update(*m_queue.get(), &occluded, m_stats);
1037 EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1038 {
1039 updateTextures();
1040 }
1041
1042 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1043 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1044 EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1045
1046 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1047 layer->setTexturePriorities(m_priorityCalculator);
1048 m_textureManager->prioritizeTextures();
1049
1050 // Repaint without marking it dirty. The 3 culled tiles will be pre-painted now.
1051 layer->update(*m_queue.get(), &occluded, m_stats);
1052 EXPECT_EQ(3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1053
1054 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1055 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1056 EXPECT_EQ(6, occluded.overdrawMetrics().tilesCulledForUpload());
1057 }
1058
1059 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndTransforms)
1060 {
1061 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
1062 TestCCOcclusionTracker occluded;
1063
1064 // The tile size is 100x100.
1065
1066 // This makes sure the painting works when the occluded region (in screen sp ace)
1067 // is transformed differently than the layer.
1068 layer->setBounds(IntSize(600, 600));
1069 WebTransformationMatrix screenTransform;
1070 screenTransform.scale(0.5);
1071 layer->setScreenSpaceTransform(screenTransform);
1072 layer->setDrawTransform(screenTransform);
1073
1074 occluded.setOcclusion(IntRect(100, 100, 150, 50));
1075 layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1076 layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1077 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1078 layer->setTexturePriorities(m_priorityCalculator);
1079 m_textureManager->prioritizeTextures();
1080 layer->update(*m_queue.get(), &occluded, m_stats);
1081 EXPECT_EQ(36-3, layer->fakeLayerTextureUpdater()->prepareRectCount());
1082
1083 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1084 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 330000, 1);
1085 EXPECT_EQ(3, occluded.overdrawMetrics().tilesCulledForUpload());
1086 }
1087
1088 TEST_F(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
1089 {
1090 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
1091 TestCCOcclusionTracker occluded;
1092
1093 // The tile size is 100x100.
1094
1095 // This makes sure the painting works when the content space is scaled to
1096 // a different layer space. In this case tiles are scaled to be 200x200
1097 // pixels, which means none should be occluded.
1098 layer->setContentsScale(0.5);
1099 layer->setBounds(IntSize(600, 600));
1100 WebTransformationMatrix drawTransform;
1101 drawTransform.scale(1 / layer->contentsScale());
1102 layer->setDrawTransform(drawTransform);
1103 layer->setScreenSpaceTransform(drawTransform);
1104
1105 occluded.setOcclusion(IntRect(200, 200, 300, 100));
1106 layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1107 layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1108 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1109 layer->setTexturePriorities(m_priorityCalculator);
1110 m_textureManager->prioritizeTextures();
1111 layer->update(*m_queue.get(), &occluded, m_stats);
1112 // The content is half the size of the layer (so the number of tiles is fewe r).
1113 // In this case, the content is 300x300, and since the tile size is 100, the
1114 // number of tiles 3x3.
1115 EXPECT_EQ(9, layer->fakeLayerTextureUpdater()->prepareRectCount());
1116
1117 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1118 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000, 1 );
1119 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1120
1121 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1122
1123 // This makes sure the painting works when the content space is scaled to
1124 // a different layer space. In this case the occluded region catches the
1125 // blown up tiles.
1126 occluded.setOcclusion(IntRect(200, 200, 300, 200));
1127 layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1128 layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1129 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1130 layer->setTexturePriorities(m_priorityCalculator);
1131 m_textureManager->prioritizeTextures();
1132 layer->update(*m_queue.get(), &occluded, m_stats);
1133 EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1134
1135 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1136 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000, 1);
1137 EXPECT_EQ(1, occluded.overdrawMetrics().tilesCulledForUpload());
1138
1139 layer->fakeLayerTextureUpdater()->clearPrepareRectCount();
1140
1141 // This makes sure content scaling and transforms work together.
1142 WebTransformationMatrix screenTransform;
1143 screenTransform.scale(0.5);
1144 layer->setScreenSpaceTransform(screenTransform);
1145 layer->setDrawTransform(screenTransform);
1146
1147 occluded.setOcclusion(IntRect(100, 100, 150, 100));
1148 layer->setDrawableContentRect(IntRect(IntPoint(), layer->contentBounds()));
1149 layer->setVisibleContentRect(IntRect(IntPoint(), layer->contentBounds()));
1150 layer->invalidateContentRect(IntRect(0, 0, 600, 600));
1151 layer->setTexturePriorities(m_priorityCalculator);
1152 m_textureManager->prioritizeTextures();
1153 layer->update(*m_queue.get(), &occluded, m_stats);
1154 EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
1155
1156 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1157 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 90000 + 80000 + 80000, 1);
1158 EXPECT_EQ(1 + 1, occluded.overdrawMetrics().tilesCulledForUpload());
1159 }
1160
1161 TEST_F(TiledLayerChromiumTest, visibleContentOpaqueRegion)
1162 {
1163 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
1164 TestCCOcclusionTracker occluded;
1165
1166 // The tile size is 100x100, so this invalidates and then paints two tiles i n various ways.
1167
1168 IntRect opaquePaintRect;
1169 Region opaqueContents;
1170
1171 IntRect contentBounds = IntRect(0, 0, 100, 200);
1172 IntRect visibleBounds = IntRect(0, 0, 100, 150);
1173
1174 layer->setBounds(contentBounds.size());
1175 layer->setDrawableContentRect(visibleBounds);
1176 layer->setVisibleContentRect(visibleBounds);
1177 layer->setDrawOpacity(1);
1178
1179 layer->setTexturePriorities(m_priorityCalculator);
1180 m_textureManager->prioritizeTextures();
1181
1182 // If the layer doesn't paint opaque content, then the visibleContentOpaqueR egion should be empty.
1183 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1184 layer->invalidateContentRect(contentBounds);
1185 layer->update(*m_queue.get(), &occluded, m_stats);
1186 opaqueContents = layer->visibleContentOpaqueRegion();
1187 EXPECT_TRUE(opaqueContents.isEmpty());
1188
1189 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000, 1);
1190 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1191 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000, 1 );
1192 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1193
1194 // visibleContentOpaqueRegion should match the visible part of what is paint ed opaque.
1195 opaquePaintRect = IntRect(10, 10, 90, 190);
1196 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
1197 layer->invalidateContentRect(contentBounds);
1198 layer->update(*m_queue.get(), &occluded, m_stats);
1199 updateTextures();
1200 opaqueContents = layer->visibleContentOpaqueRegion();
1201 EXPECT_RECT_EQ(intersection(opaquePaintRect, visibleBounds), opaqueContents. bounds());
1202 EXPECT_EQ(1u, opaqueContents.rects().size());
1203
1204 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1205 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1206 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1207 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1208
1209 // If we paint again without invalidating, the same stuff should be opaque.
1210 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1211 layer->update(*m_queue.get(), &occluded, m_stats);
1212 updateTextures();
1213 opaqueContents = layer->visibleContentOpaqueRegion();
1214 EXPECT_RECT_EQ(intersection(opaquePaintRect, visibleBounds), opaqueContents. bounds());
1215 EXPECT_EQ(1u, opaqueContents.rects().size());
1216
1217 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2, 1);
1218 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1219 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100, 1);
1220 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1221
1222 // If we repaint a non-opaque part of the tile, then it shouldn't lose its o paque-ness. And other tiles should
1223 // not be affected.
1224 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1225 layer->invalidateContentRect(IntRect(0, 0, 1, 1));
1226 layer->update(*m_queue.get(), &occluded, m_stats);
1227 updateTextures();
1228 opaqueContents = layer->visibleContentOpaqueRegion();
1229 EXPECT_RECT_EQ(intersection(opaquePaintRect, visibleBounds), opaqueContents. bounds());
1230 EXPECT_EQ(1u, opaqueContents.rects().size());
1231
1232 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1, 1);
1233 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1234 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1, 1);
1235 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1236
1237 // If we repaint an opaque part of the tile, then it should lose its opaque- ness. But other tiles should still
1238 // not be affected.
1239 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1240 layer->invalidateContentRect(IntRect(10, 10, 1, 1));
1241 layer->update(*m_queue.get(), &occluded, m_stats);
1242 updateTextures();
1243 opaqueContents = layer->visibleContentOpaqueRegion();
1244 EXPECT_RECT_EQ(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqu eContents.bounds());
1245 EXPECT_EQ(1u, opaqueContents.rects().size());
1246
1247 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 20000 * 2 + 1 + 1, 1);
1248 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 17100, 1);
1249 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 20000 + 20000 - 17100 + 1 + 1, 1);
1250 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1251 }
1252
1253 TEST_F(TiledLayerChromiumTest, pixelsPaintedMetrics)
1254 {
1255 scoped_refptr<FakeTiledLayerChromium> layer = make_scoped_refptr(new FakeTil edLayerChromium(m_textureManager.get()));
1256 TestCCOcclusionTracker occluded;
1257
1258 // The tile size is 100x100, so this invalidates and then paints two tiles i n various ways.
1259
1260 IntRect opaquePaintRect;
1261 Region opaqueContents;
1262
1263 IntRect contentBounds = IntRect(0, 0, 100, 300);
1264 IntRect visibleBounds = IntRect(0, 0, 100, 300);
1265
1266 layer->setBounds(contentBounds.size());
1267 layer->setDrawableContentRect(visibleBounds);
1268 layer->setVisibleContentRect(visibleBounds);
1269 layer->setDrawOpacity(1);
1270
1271 layer->setTexturePriorities(m_priorityCalculator);
1272 m_textureManager->prioritizeTextures();
1273
1274 // Invalidates and paints the whole layer.
1275 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1276 layer->invalidateContentRect(contentBounds);
1277 layer->update(*m_queue.get(), &occluded, m_stats);
1278 updateTextures();
1279 opaqueContents = layer->visibleContentOpaqueRegion();
1280 EXPECT_TRUE(opaqueContents.isEmpty());
1281
1282 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000, 1);
1283 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1284 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000, 1 );
1285 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1286
1287 // Invalidates an area on the top and bottom tile, which will cause us to pa int the tile in the middle,
1288 // even though it is not dirty and will not be uploaded.
1289 layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
1290 layer->invalidateContentRect(IntRect(0, 0, 1, 1));
1291 layer->invalidateContentRect(IntRect(50, 200, 10, 10));
1292 layer->update(*m_queue.get(), &occluded, m_stats);
1293 updateTextures();
1294 opaqueContents = layer->visibleContentOpaqueRegion();
1295 EXPECT_TRUE(opaqueContents.isEmpty());
1296
1297 // The middle tile was painted even though not invalidated.
1298 EXPECT_NEAR(occluded.overdrawMetrics().pixelsPainted(), 30000 + 60 * 210, 1) ;
1299 // The pixels uploaded will not include the non-invalidated tile in the midd le.
1300 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedOpaque(), 0, 1);
1301 EXPECT_NEAR(occluded.overdrawMetrics().pixelsUploadedTranslucent(), 30000 + 1 + 100, 1);
1302 EXPECT_EQ(0, occluded.overdrawMetrics().tilesCulledForUpload());
1303 }
1304
1305 TEST_F(TiledLayerChromiumTest, dontAllocateContentsWhenTargetSurfaceCantBeAlloca ted)
1306 {
1307 // Tile size is 100x100.
1308 IntRect rootRect(0, 0, 300, 200);
1309 IntRect childRect(0, 0, 300, 100);
1310 IntRect child2Rect(0, 100, 300, 100);
1311
1312 CCLayerTreeSettings settings;
1313 FakeCCLayerTreeHostClient fakeCCLayerTreeHostClient;
1314 scoped_ptr<CCLayerTreeHost> ccLayerTreeHost = CCLayerTreeHost::create(&fakeC CLayerTreeHostClient, settings);
1315 ASSERT_TRUE(ccLayerTreeHost->initializeRendererIfNeeded());
1316
1317 scoped_refptr<FakeTiledLayerChromium> root = make_scoped_refptr(new FakeTile dLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1318 scoped_refptr<LayerChromium> surface = LayerChromium::create();
1319 scoped_refptr<FakeTiledLayerChromium> child = make_scoped_refptr(new FakeTil edLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1320 scoped_refptr<FakeTiledLayerChromium> child2 = make_scoped_refptr(new FakeTi ledLayerChromium(ccLayerTreeHost->contentsTextureManager()));
1321
1322 root->setBounds(rootRect.size());
1323 root->setAnchorPoint(FloatPoint());
1324 root->setDrawableContentRect(rootRect);
1325 root->setVisibleContentRect(rootRect);
1326 root->addChild(surface);
1327
1328 surface->setForceRenderSurface(true);
1329 surface->setAnchorPoint(FloatPoint());
1330 surface->setOpacity(0.5);
1331 surface->addChild(child);
1332 surface->addChild(child2);
1333
1334 child->setBounds(childRect.size());
1335 child->setAnchorPoint(FloatPoint());
1336 child->setPosition(childRect.location());
1337 child->setVisibleContentRect(childRect);
1338 child->setDrawableContentRect(rootRect);
1339
1340 child2->setBounds(child2Rect.size());
1341 child2->setAnchorPoint(FloatPoint());
1342 child2->setPosition(child2Rect.location());
1343 child2->setVisibleContentRect(child2Rect);
1344 child2->setDrawableContentRect(rootRect);
1345
1346 ccLayerTreeHost->setRootLayer(root);
1347 ccLayerTreeHost->setViewportSize(rootRect.size(), rootRect.size());
1348
1349 // With a huge memory limit, all layers should update and push their texture s.
1350 root->invalidateContentRect(rootRect);
1351 child->invalidateContentRect(childRect);
1352 child2->invalidateContentRect(child2Rect);
1353 ccLayerTreeHost->updateLayers(
1354 *m_queue.get(), std::numeric_limits<size_t>::max());
1355 {
1356 updateTextures();
1357 EXPECT_EQ(6, root->fakeLayerTextureUpdater()->updateCount());
1358 EXPECT_EQ(3, child->fakeLayerTextureUpdater()->updateCount());
1359 EXPECT_EQ(3, child2->fakeLayerTextureUpdater()->updateCount());
1360 EXPECT_FALSE(m_queue->hasMoreUpdates());
1361
1362 root->fakeLayerTextureUpdater()->clearUpdateCount();
1363 child->fakeLayerTextureUpdater()->clearUpdateCount();
1364 child2->fakeLayerTextureUpdater()->clearUpdateCount();
1365
1366 ScopedFakeCCTiledLayerImpl rootImpl(root->id());
1367 ScopedFakeCCTiledLayerImpl childImpl(child->id());
1368 ScopedFakeCCTiledLayerImpl child2Impl(child2->id());
1369 layerPushPropertiesTo(root.get(), rootImpl.get());
1370 layerPushPropertiesTo(child.get(), childImpl.get());
1371 layerPushPropertiesTo(child2.get(), child2Impl.get());
1372
1373 for (unsigned i = 0; i < 3; ++i) {
1374 for (unsigned j = 0; j < 2; ++j)
1375 EXPECT_TRUE(rootImpl->hasResourceIdForTileAt(i, j));
1376 EXPECT_TRUE(childImpl->hasResourceIdForTileAt(i, 0));
1377 EXPECT_TRUE(child2Impl->hasResourceIdForTileAt(i, 0));
1378 }
1379 }
1380 ccLayerTreeHost->commitComplete();
1381
1382 // With a memory limit that includes only the root layer (3x2 tiles) and hal f the surface that
1383 // the child layers draw into, the child layers will not be allocated. If th e surface isn't
1384 // accounted for, then one of the children would fit within the memory limit .
1385 root->invalidateContentRect(rootRect);
1386 child->invalidateContentRect(childRect);
1387 child2->invalidateContentRect(child2Rect);
1388 ccLayerTreeHost->updateLayers(
1389 *m_queue.get(), (3 * 2 + 3 * 1) * (100 * 100) * 4);
1390 {
1391 updateTextures();
1392 EXPECT_EQ(6, root->fakeLayerTextureUpdater()->updateCount());
1393 EXPECT_EQ(0, child->fakeLayerTextureUpdater()->updateCount());
1394 EXPECT_EQ(0, child2->fakeLayerTextureUpdater()->updateCount());
1395 EXPECT_FALSE(m_queue->hasMoreUpdates());
1396
1397 root->fakeLayerTextureUpdater()->clearUpdateCount();
1398 child->fakeLayerTextureUpdater()->clearUpdateCount();
1399 child2->fakeLayerTextureUpdater()->clearUpdateCount();
1400
1401 ScopedFakeCCTiledLayerImpl rootImpl(root->id());
1402 ScopedFakeCCTiledLayerImpl childImpl(child->id());
1403 ScopedFakeCCTiledLayerImpl child2Impl(child2->id());
1404 layerPushPropertiesTo(root.get(), rootImpl.get());
1405 layerPushPropertiesTo(child.get(), childImpl.get());
1406 layerPushPropertiesTo(child2.get(), child2Impl.get());
1407
1408 for (unsigned i = 0; i < 3; ++i) {
1409 for (unsigned j = 0; j < 2; ++j)
1410 EXPECT_TRUE(rootImpl->hasResourceIdForTileAt(i, j));
1411 EXPECT_FALSE(childImpl->hasResourceIdForTileAt(i, 0));
1412 EXPECT_FALSE(child2Impl->hasResourceIdForTileAt(i, 0));
1413 }
1414 }
1415 ccLayerTreeHost->commitComplete();
1416
1417 // With a memory limit that includes only half the root layer, no contents w ill be
1418 // allocated. If render surface memory wasn't accounted for, there is enough space
1419 // for one of the children layers, but they draw into a surface that can't b e
1420 // allocated.
1421 root->invalidateContentRect(rootRect);
1422 child->invalidateContentRect(childRect);
1423 child2->invalidateContentRect(child2Rect);
1424 ccLayerTreeHost->updateLayers(
1425 *m_queue.get(), (3 * 1) * (100 * 100) * 4);
1426 {
1427 updateTextures();
1428 EXPECT_EQ(0, root->fakeLayerTextureUpdater()->updateCount());
1429 EXPECT_EQ(0, child->fakeLayerTextureUpdater()->updateCount());
1430 EXPECT_EQ(0, child2->fakeLayerTextureUpdater()->updateCount());
1431 EXPECT_FALSE(m_queue->hasMoreUpdates());
1432
1433 root->fakeLayerTextureUpdater()->clearUpdateCount();
1434 child->fakeLayerTextureUpdater()->clearUpdateCount();
1435 child2->fakeLayerTextureUpdater()->clearUpdateCount();
1436
1437 ScopedFakeCCTiledLayerImpl rootImpl(root->id());
1438 ScopedFakeCCTiledLayerImpl childImpl(child->id());
1439 ScopedFakeCCTiledLayerImpl child2Impl(child2->id());
1440 layerPushPropertiesTo(root.get(), rootImpl.get());
1441 layerPushPropertiesTo(child.get(), childImpl.get());
1442 layerPushPropertiesTo(child2.get(), child2Impl.get());
1443
1444 for (unsigned i = 0; i < 3; ++i) {
1445 for (unsigned j = 0; j < 2; ++j)
1446 EXPECT_FALSE(rootImpl->hasResourceIdForTileAt(i, j));
1447 EXPECT_FALSE(childImpl->hasResourceIdForTileAt(i, 0));
1448 EXPECT_FALSE(child2Impl->hasResourceIdForTileAt(i, 0));
1449 }
1450 }
1451 ccLayerTreeHost->commitComplete();
1452
1453 textureManagerClearAllMemory(ccLayerTreeHost->contentsTextureManager(), m_re sourceProvider.get());
1454 ccLayerTreeHost->setRootLayer(0);
1455 }
1456
1457 class TrackingLayerPainter : public LayerPainterChromium {
1458 public:
1459 static PassOwnPtr<TrackingLayerPainter> create() { return adoptPtr(new Track ingLayerPainter()); }
1460
1461 virtual void paint(SkCanvas*, const IntRect& contentRect, FloatRect&) OVERRI DE
1462 {
1463 m_paintedRect = contentRect;
1464 }
1465
1466 const IntRect& paintedRect() const { return m_paintedRect; }
1467 void resetPaintedRect() { m_paintedRect = IntRect(); }
1468
1469 private:
1470 TrackingLayerPainter() { }
1471
1472 IntRect m_paintedRect;
1473 };
1474
1475 class UpdateTrackingTiledLayerChromium : public FakeTiledLayerChromium {
1476 public:
1477 explicit UpdateTrackingTiledLayerChromium(CCPrioritizedTextureManager* manag er)
1478 : FakeTiledLayerChromium(manager)
1479 {
1480 OwnPtr<TrackingLayerPainter> trackingLayerPainter(TrackingLayerPainter:: create());
1481 m_trackingLayerPainter = trackingLayerPainter.get();
1482 m_layerTextureUpdater = BitmapCanvasLayerTextureUpdater::create(tracking LayerPainter.release());
1483 }
1484
1485 TrackingLayerPainter* trackingLayerPainter() const { return m_trackingLayerP ainter; }
1486
1487 protected:
1488 virtual ~UpdateTrackingTiledLayerChromium() { }
1489
1490 virtual LayerTextureUpdater* textureUpdater() const OVERRIDE { return m_laye rTextureUpdater.get(); }
1491
1492 private:
1493 TrackingLayerPainter* m_trackingLayerPainter;
1494 RefPtr<BitmapCanvasLayerTextureUpdater> m_layerTextureUpdater;
1495 };
1496
1497 TEST_F(TiledLayerChromiumTest, nonIntegerContentsScaleIsNotDistortedDuringPaint)
1498 {
1499 scoped_refptr<UpdateTrackingTiledLayerChromium> layer = make_scoped_refptr(n ew UpdateTrackingTiledLayerChromium(m_textureManager.get()));
1500
1501 IntRect layerRect(0, 0, 30, 31);
1502 layer->setPosition(layerRect.location());
1503 layer->setBounds(layerRect.size());
1504 layer->setContentsScale(1.5);
1505
1506 IntRect contentRect(0, 0, 45, 47);
1507 EXPECT_EQ(contentRect.size(), layer->contentBounds());
1508 layer->setVisibleContentRect(contentRect);
1509 layer->setDrawableContentRect(contentRect);
1510
1511 layer->setTexturePriorities(m_priorityCalculator);
1512 m_textureManager->prioritizeTextures();
1513
1514 // Update the whole tile.
1515 layer->update(*m_queue.get(), 0, m_stats);
1516 layer->trackingLayerPainter()->resetPaintedRect();
1517
1518 EXPECT_RECT_EQ(IntRect(), layer->trackingLayerPainter()->paintedRect());
1519 updateTextures();
1520
1521 // Invalidate the entire layer in content space. When painting, the rect giv en to webkit should match the layer's bounds.
1522 layer->invalidateContentRect(contentRect);
1523 layer->update(*m_queue.get(), 0, m_stats);
1524
1525 EXPECT_RECT_EQ(layerRect, layer->trackingLayerPainter()->paintedRect());
1526 }
1527
1528 TEST_F(TiledLayerChromiumTest, nonIntegerContentsScaleIsNotDistortedDuringInvali dation)
1529 {
1530 scoped_refptr<UpdateTrackingTiledLayerChromium> layer = make_scoped_refptr(n ew UpdateTrackingTiledLayerChromium(m_textureManager.get()));
1531
1532 IntRect layerRect(0, 0, 30, 31);
1533 layer->setPosition(layerRect.location());
1534 layer->setBounds(layerRect.size());
1535 layer->setContentsScale(1.3f);
1536
1537 IntRect contentRect(IntPoint(), layer->contentBounds());
1538 layer->setVisibleContentRect(contentRect);
1539 layer->setDrawableContentRect(contentRect);
1540
1541 layer->setTexturePriorities(m_priorityCalculator);
1542 m_textureManager->prioritizeTextures();
1543
1544 // Update the whole tile.
1545 layer->update(*m_queue.get(), 0, m_stats);
1546 layer->trackingLayerPainter()->resetPaintedRect();
1547
1548 EXPECT_RECT_EQ(IntRect(), layer->trackingLayerPainter()->paintedRect());
1549 updateTextures();
1550
1551 // Invalidate the entire layer in layer space. When painting, the rect given to webkit should match the layer's bounds.
1552 layer->setNeedsDisplayRect(layerRect);
1553 layer->update(*m_queue.get(), 0, m_stats);
1554
1555 EXPECT_RECT_EQ(layerRect, layer->trackingLayerPainter()->paintedRect());
1556 }
1557
1558 } // namespace
OLDNEW
« no previous file with comments | « cc/ThrottledTextureUploaderTest.cpp ('k') | cc/TreeSynchronizerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698