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

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

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

Powered by Google App Engine
This is Rietveld 408576698