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

Side by Side Diff: webkit/compositor_bindings/TiledLayerChromiumTest.cpp

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

Powered by Google App Engine
This is Rietveld 408576698