fe8ca8eb0217af523324e20cc74eaf1c53dda8ff
[WebKit-https.git] / Source / WebKit / chromium / tests / CCTiledLayerImplTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCTiledLayerImpl.h"
28
29 #include "CCLayerTestCommon.h"
30 #include "MockCCQuadCuller.h"
31 #include "cc/CCSingleThreadProxy.h"
32 #include "cc/CCTileDrawQuad.h"
33 #include <gmock/gmock.h>
34 #include <gtest/gtest.h>
35
36 using namespace WebCore;
37 using namespace CCLayerTestCommon;
38
39 namespace {
40
41 // Create a default tiled layer with textures for all tiles and a default
42 // visibility of the entire layer size.
43 static PassOwnPtr<CCTiledLayerImpl> createLayer(const IntSize& tileSize, const IntSize& layerSize, CCLayerTilingData::BorderTexelOption borderTexels)
44 {
45     OwnPtr<CCTiledLayerImpl> layer = CCTiledLayerImpl::create(0);
46     OwnPtr<CCLayerTilingData> tiler = CCLayerTilingData::create(tileSize, borderTexels);
47     tiler->setBounds(layerSize);
48     layer->setTilingData(*tiler);
49     layer->setSkipsDraw(false);
50     layer->setVisibleLayerRect(IntRect(IntPoint(), layerSize));
51     layer->setDrawOpacity(1);
52
53     int textureId = 1;
54     for (int i = 0; i < tiler->numTilesX(); ++i)
55         for (int j = 0; j < tiler->numTilesY(); ++j)
56             layer->pushTileProperties(i, j, static_cast<Platform3DObject>(textureId++), IntRect(0, 0, 1, 1));
57
58     return layer.release();
59 }
60
61 TEST(CCTiledLayerImplTest, emptyQuadList)
62 {
63     DebugScopedSetImplThread scopedImplThread;
64
65     const IntSize tileSize(90, 90);
66     const int numTilesX = 8;
67     const int numTilesY = 4;
68     const IntSize layerSize(tileSize.width() * numTilesX, tileSize.height() * numTilesY);
69
70     // Verify default layer does creates quads
71     {
72         OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
73         MockCCQuadCuller quadCuller;
74         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
75         layer->appendQuads(quadCuller, sharedQuadState.get());
76         const unsigned numTiles = numTilesX * numTilesY;
77         EXPECT_EQ(quadCuller.quadList().size(), numTiles);
78     }
79
80     // Layer with empty visible layer rect produces no quads
81     {
82         OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
83         layer->setVisibleLayerRect(IntRect());
84
85         MockCCQuadCuller quadCuller;
86         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
87         layer->appendQuads(quadCuller, sharedQuadState.get());
88         EXPECT_EQ(quadCuller.quadList().size(), 0u);
89     }
90
91     // Layer with non-intersecting visible layer rect produces no quads
92     {
93         OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
94
95         IntRect outsideBounds(IntPoint(-100, -100), IntSize(50, 50));
96         layer->setVisibleLayerRect(outsideBounds);
97
98         MockCCQuadCuller quadCuller;
99         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
100         layer->appendQuads(quadCuller, sharedQuadState.get());
101         EXPECT_EQ(quadCuller.quadList().size(), 0u);
102     }
103
104     // Layer with skips draw produces no quads
105     {
106         OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
107         layer->setSkipsDraw(true);
108
109         MockCCQuadCuller quadCuller;
110         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
111         layer->appendQuads(quadCuller, sharedQuadState.get());
112         EXPECT_EQ(quadCuller.quadList().size(), 0u);
113     }
114 }
115
116 TEST(CCTiledLayerImplTest, checkerboarding)
117 {
118     DebugScopedSetImplThread scopedImplThread;
119
120     const IntSize tileSize(10, 10);
121     const int numTilesX = 2;
122     const int numTilesY = 2;
123     const IntSize layerSize(tileSize.width() * numTilesX, tileSize.height() * numTilesY);
124
125     OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
126     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
127
128     // No checkerboarding
129     {
130         MockCCQuadCuller quadCuller;
131         layer->appendQuads(quadCuller, sharedQuadState.get());
132         EXPECT_EQ(quadCuller.quadList().size(), 4u);
133
134         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
135             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::TiledContent);
136     }
137
138     for (int i = 0; i < numTilesX; ++i)
139         for (int j = 0; j < numTilesY; ++j)
140             layer->pushTileProperties(i, j, static_cast<Platform3DObject>(0), IntRect());
141
142     // All checkerboarding
143     {
144         MockCCQuadCuller quadCuller;
145         layer->appendQuads(quadCuller, sharedQuadState.get());
146         EXPECT_EQ(quadCuller.quadList().size(), 4u);
147         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
148             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::SolidColor);
149     }
150 }
151
152 static PassOwnPtr<CCSharedQuadState> getQuads(CCQuadList& quads, IntSize tileSize, const IntSize& layerSize, CCLayerTilingData::BorderTexelOption borderTexelOption, const IntRect& visibleLayerRect)
153 {
154     OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, borderTexelOption);
155     layer->setVisibleLayerRect(visibleLayerRect);
156     layer->setBounds(layerSize);
157
158     MockCCQuadCuller quadCuller(quads);
159     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
160     layer->appendQuads(quadCuller, sharedQuadState.get());
161     return sharedQuadState.release(); // The shared data must be owned as long as the quad list exists.
162 }
163
164 // Test with both border texels and without.
165 #define WITH_AND_WITHOUT_BORDER_TEST(testFixtureName)       \
166     TEST(CCTiledLayerImplTest, testFixtureName##NoBorders)  \
167     {                                                       \
168         testFixtureName(CCLayerTilingData::NoBorderTexels); \
169     }                                                       \
170     TEST(CCTiledLayerImplTest, testFixtureName##HasBorders) \
171     {                                                       \
172         testFixtureName(CCLayerTilingData::HasBorderTexels);\
173     }
174
175 static void coverageVisibleRectOnTileBoundaries(CCLayerTilingData::BorderTexelOption borders)
176 {
177     DebugScopedSetImplThread scopedImplThread;
178
179     IntSize layerSize(1000, 1000);
180     CCQuadList quads;
181     OwnPtr<CCSharedQuadState> sharedState;
182     sharedState = getQuads(quads, IntSize(100, 100), layerSize, borders, IntRect(IntPoint(), layerSize));
183     verifyQuadsExactlyCoverRect(quads, IntRect(IntPoint(), layerSize));
184 }
185 WITH_AND_WITHOUT_BORDER_TEST(coverageVisibleRectOnTileBoundaries);
186
187 static void coverageVisibleRectIntersectsTiles(CCLayerTilingData::BorderTexelOption borders)
188 {
189     DebugScopedSetImplThread scopedImplThread;
190
191     // This rect intersects the middle 3x3 of the 5x5 tiles.
192     IntPoint topLeft(65, 73);
193     IntPoint bottomRight(182, 198);
194     IntRect visibleLayerRect(topLeft, bottomRight - topLeft);
195
196     IntSize layerSize(250, 250);
197     CCQuadList quads;
198     OwnPtr<CCSharedQuadState> sharedState;
199     sharedState = getQuads(quads, IntSize(50, 50), IntSize(250, 250), CCLayerTilingData::NoBorderTexels, visibleLayerRect);
200     verifyQuadsExactlyCoverRect(quads, visibleLayerRect);
201 }
202 WITH_AND_WITHOUT_BORDER_TEST(coverageVisibleRectIntersectsTiles);
203
204 static void coverageVisibleRectIntersectsBounds(CCLayerTilingData::BorderTexelOption borders)
205 {
206     DebugScopedSetImplThread scopedImplThread;
207
208     IntSize layerSize(220, 210);
209     IntRect visibleLayerRect(IntPoint(), layerSize);
210     CCQuadList quads;
211     OwnPtr<CCSharedQuadState> sharedState;
212     sharedState = getQuads(quads, IntSize(100, 100), layerSize, CCLayerTilingData::NoBorderTexels, visibleLayerRect);
213     verifyQuadsExactlyCoverRect(quads, visibleLayerRect);
214 }
215 WITH_AND_WITHOUT_BORDER_TEST(coverageVisibleRectIntersectsBounds);
216
217 TEST(CCTiledLayerImplTest, textureInfoForLayerNoBorders)
218 {
219     DebugScopedSetImplThread scopedImplThread;
220
221     IntSize tileSize(50, 50);
222     IntSize layerSize(250, 250);
223     CCQuadList quads;
224     OwnPtr<CCSharedQuadState> sharedState;
225     sharedState = getQuads(quads, tileSize, layerSize, CCLayerTilingData::NoBorderTexels, IntRect(IntPoint(), layerSize));
226
227     for (size_t i = 0; i < quads.size(); ++i) {
228         ASSERT_EQ(quads[i]->material(), CCDrawQuad::TiledContent) << quadString << i;
229         CCTileDrawQuad* quad = static_cast<CCTileDrawQuad*>(quads[i].get());
230
231         EXPECT_NE(quad->textureId(), 0u) << quadString << i;
232         EXPECT_EQ(quad->textureOffset(), IntPoint()) << quadString << i;
233         EXPECT_EQ(quad->textureSize(), tileSize) << quadString << i;
234         EXPECT_EQ(IntRect(0, 0, 1, 1), quad->opaqueRect()) << quadString << i;
235     }
236 }
237
238 TEST(CCTiledLayerImplTest, tileOpaqueRectForLayerNoBorders)
239 {
240     DebugScopedSetImplThread scopedImplThread;
241
242     IntSize tileSize(50, 50);
243     IntSize layerSize(250, 250);
244     CCQuadList quads;
245     OwnPtr<CCSharedQuadState> sharedState;
246     sharedState = getQuads(quads, tileSize, layerSize, CCLayerTilingData::NoBorderTexels, IntRect(IntPoint(), layerSize));
247
248     for (size_t i = 0; i < quads.size(); ++i) {
249         ASSERT_EQ(quads[i]->material(), CCDrawQuad::TiledContent) << quadString << i;
250         CCTileDrawQuad* quad = static_cast<CCTileDrawQuad*>(quads[i].get());
251
252         EXPECT_EQ(IntRect(0, 0, 1, 1), quad->opaqueRect()) << quadString << i;
253     }
254 }
255
256 TEST(CCTiledLayerImplTest, backgroundCoversViewport)
257 {
258     DebugScopedSetImplThread scopedImplThread;
259
260     const IntSize tileSize(10, 10);
261     const int numTilesX = 2;
262     const int numTilesY = 2;
263     const unsigned numTiles = numTilesX * numTilesY;
264     const IntSize layerSize(tileSize.width() * numTilesX, tileSize.height() * numTilesY);
265     OwnPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, CCLayerTilingData::NoBorderTexels);
266     layer->setBackgroundColor(Color::gray);
267     layer->setBackgroundCoversViewport(true);
268
269     // No gutter rects
270     {
271         IntRect clipRect = IntRect(IntPoint(), layerSize);
272         layer->setClipRect(clipRect);
273         layer->setVisibleLayerRect(IntRect(IntPoint(), layerSize));
274
275         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
276
277         MockCCQuadCuller quadCuller;
278         layer->appendQuads(quadCuller, sharedQuadState.get());
279         EXPECT_EQ(quadCuller.quadList().size(), numTiles);
280
281         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
282             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::TiledContent);
283     }
284
285     // Empty visible content area (fullscreen gutter rect)
286     {
287         IntRect clipRect = IntRect(100, 100, 100, 100);
288         layer->setClipRect(clipRect);
289         layer->setVisibleLayerRect(IntRect());
290
291         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
292         MockCCQuadCuller quadCuller;
293         layer->appendQuads(quadCuller, sharedQuadState.get());
294
295         for (size_t i = 0; i < quadCuller.quadList().size(); ++i)
296             EXPECT_EQ(quadCuller.quadList()[i]->material(), CCDrawQuad::SolidColor);
297
298         verifyQuadsExactlyCoverRect(quadCuller.quadList(), clipRect);
299     }
300
301     // Content area in middle of clip rect (four surrounding gutter rects)
302     {
303         IntRect clipRect = IntRect(-50, -50, 100, 100);
304         layer->setClipRect(clipRect);
305         layer->setVisibleLayerRect(IntRect(IntPoint(), layerSize));
306
307         OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
308         MockCCQuadCuller quadCuller;
309         layer->appendQuads(quadCuller, sharedQuadState.get());
310
311         unsigned numContentTiles = 0, numGutterTiles = 0;
312         for (size_t i = 0; i < quadCuller.quadList().size(); ++i) {
313             if (quadCuller.quadList()[i]->material() == CCDrawQuad::TiledContent)
314                 numContentTiles++;
315             else if (quadCuller.quadList()[i]->material() == CCDrawQuad::SolidColor)
316                 numGutterTiles++;
317         }
318         EXPECT_EQ(numContentTiles, numTiles);
319         EXPECT_GE(numGutterTiles, 4u);
320
321         verifyQuadsExactlyCoverRect(quadCuller.quadList(), clipRect);
322     }
323 }
324
325 } // namespace