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

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

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

Powered by Google App Engine
This is Rietveld 408576698