blob: 71e1a0e21c10a88b710ef2194a0d0ee051209418 [file] [log] [blame]
[email protected]7d929c02012-09-20 17:26:571// Copyright 2012 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 "CCDelegatedRendererLayerImpl.h"
8
9#include "CCAppendQuadsData.h"
10#include "CCGeometryTestUtils.h"
11#include "CCLayerTreeHostImpl.h"
12#include "CCQuadSink.h"
13#include "CCRenderPassDrawQuad.h"
14#include "CCRenderPassTestCommon.h"
15#include "CCSingleThreadProxy.h"
16#include "CCSolidColorDrawQuad.h"
17#include "CCSolidColorLayerImpl.h"
18#include "FakeWebCompositorOutputSurface.h"
19#include "FakeWebGraphicsContext3D.h"
20#include "MockCCQuadCuller.h"
21#include <gtest/gtest.h>
22#include <public/WebTransformationMatrix.h>
23
24using WebKit::FakeWebCompositorOutputSurface;
25using WebKit::FakeWebGraphicsContext3D;
26using WebKit::WebTransformationMatrix;
27
28using namespace cc;
29using namespace WebKitTests;
30
31namespace {
32
33class CCDelegatedRendererLayerImplTest : public testing::Test, public CCLayerTreeHostImplClient {
34public:
35 CCDelegatedRendererLayerImplTest()
36 {
37 CCLayerTreeSettings settings;
38 settings.minimumOcclusionTrackingSize = IntSize();
39
40 m_hostImpl = CCLayerTreeHostImpl::create(settings, this);
[email protected]673788a2012-09-22 22:22:1041 m_hostImpl->initializeRenderer(createContext());
[email protected]7d929c02012-09-20 17:26:5742 m_hostImpl->setViewportSize(IntSize(10, 10), IntSize(10, 10));
43 }
44
45 // CCLayerTreeHostImplClient implementation.
46 virtual void didLoseContextOnImplThread() OVERRIDE { }
47 virtual void onSwapBuffersCompleteOnImplThread() OVERRIDE { }
48 virtual void onVSyncParametersChanged(double, double) OVERRIDE { }
49 virtual void onCanDrawStateChanged(bool) OVERRIDE { }
50 virtual void setNeedsRedrawOnImplThread() OVERRIDE { }
51 virtual void setNeedsCommitOnImplThread() OVERRIDE { }
52 virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE { }
53 virtual void releaseContentsTexturesOnImplThread() OVERRIDE { }
54
55protected:
56 PassOwnPtr<CCGraphicsContext> createContext()
57 {
58 return FakeWebCompositorOutputSurface::create(adoptPtr(new FakeWebGraphicsContext3D));
59 }
60
61 DebugScopedSetImplThread m_alwaysImplThread;
62 DebugScopedSetMainThreadBlocked m_alwaysMainThreadBlocked;
63
64 OwnPtr<CCLayerTreeHostImpl> m_hostImpl;
65};
66
67static CCTestRenderPass* addRenderPass(OwnPtrVector<CCRenderPass>& passList, CCRenderPass::Id id, IntRect outputRect, WebTransformationMatrix rootTransform)
68{
69 OwnPtr<CCRenderPass> pass(CCRenderPass::create(id, outputRect, rootTransform));
70 CCTestRenderPass* testPass = static_cast<CCTestRenderPass*>(pass.get());
71 passList.append(pass.release());
72 return testPass;
73}
74
75static CCSolidColorDrawQuad* addQuad(CCTestRenderPass* pass, IntRect rect, SkColor color)
76{
77 MockCCQuadCuller quadSink(pass->quadList(), pass->sharedQuadStateList());
78 CCAppendQuadsData data(pass->id());
79 CCSharedQuadState* sharedState = quadSink.useSharedQuadState(CCSharedQuadState::create(WebTransformationMatrix(), rect, rect, 1, false));
80 OwnPtr<CCSolidColorDrawQuad> quad(CCSolidColorDrawQuad::create(sharedState, rect, color));
81 CCSolidColorDrawQuad* quadPtr = quad.get();
82 quadSink.append(quad.release(), data);
83 return quadPtr;
84}
85
86static void addRenderPassQuad(CCTestRenderPass* toPass, CCTestRenderPass* contributingPass)
87{
88 MockCCQuadCuller quadSink(toPass->quadList(), toPass->sharedQuadStateList());
89 CCAppendQuadsData data(toPass->id());
90 IntRect outputRect = contributingPass->outputRect();
91 CCSharedQuadState* sharedState = quadSink.useSharedQuadState(CCSharedQuadState::create(WebTransformationMatrix(), outputRect, outputRect, 1, false));
92 OwnPtr<CCRenderPassDrawQuad> quad(CCRenderPassDrawQuad::create(sharedState, outputRect, contributingPass->id(), false, 0, outputRect, 0, 0, 0, 0));
93 quadSink.append(quad.release(), data);
94}
95
96class CCDelegatedRendererLayerImplTestSimple : public CCDelegatedRendererLayerImplTest {
97public:
98 CCDelegatedRendererLayerImplTestSimple()
99 : CCDelegatedRendererLayerImplTest()
100 {
101 OwnPtr<CCSolidColorLayerImpl> rootLayer = CCSolidColorLayerImpl::create(1);
102 OwnPtr<CCSolidColorLayerImpl> layerBefore = CCSolidColorLayerImpl::create(2);
103 OwnPtr<CCSolidColorLayerImpl> layerAfter = CCSolidColorLayerImpl::create(3);
104 OwnPtr<CCDelegatedRendererLayerImpl> delegatedRendererLayer = CCDelegatedRendererLayerImpl::create(4);
105
106 m_hostImpl->setViewportSize(IntSize(100, 100), IntSize(100, 100));
107 rootLayer->setBounds(IntSize(100, 100));
108
109 layerBefore->setPosition(IntPoint(20, 20));
110 layerBefore->setBounds(IntSize(14, 14));
111 layerBefore->setContentBounds(IntSize(14, 14));
112 layerBefore->setDrawsContent(true);
113 layerBefore->setForceRenderSurface(true);
114
115 layerAfter->setPosition(IntPoint(5, 5));
116 layerAfter->setBounds(IntSize(15, 15));
117 layerAfter->setContentBounds(IntSize(15, 15));
118 layerAfter->setDrawsContent(true);
119 layerAfter->setForceRenderSurface(true);
120
121 delegatedRendererLayer->setPosition(IntPoint(3, 3));
122 delegatedRendererLayer->setBounds(IntSize(10, 10));
123 delegatedRendererLayer->setContentBounds(IntSize(10, 10));
124 delegatedRendererLayer->setDrawsContent(true);
125 WebTransformationMatrix transform;
126 transform.translate(1, 1);
127 delegatedRendererLayer->setTransform(transform);
128
129 OwnPtrVector<CCRenderPass> delegatedRenderPasses;
130 CCTestRenderPass* pass1 = addRenderPass(delegatedRenderPasses, CCRenderPass::Id(9, 6), IntRect(6, 6, 6, 6), WebTransformationMatrix());
131 addQuad(pass1, IntRect(0, 0, 6, 6), 33u);
132 CCTestRenderPass* pass2 = addRenderPass(delegatedRenderPasses, CCRenderPass::Id(9, 7), IntRect(7, 7, 7, 7), WebTransformationMatrix());
133 addQuad(pass2, IntRect(0, 0, 7, 7), 22u);
134 addRenderPassQuad(pass2, pass1);
135 CCTestRenderPass* pass3 = addRenderPass(delegatedRenderPasses, CCRenderPass::Id(9, 8), IntRect(8, 8, 8, 8), WebTransformationMatrix());
136 addRenderPassQuad(pass3, pass2);
137 delegatedRendererLayer->setRenderPasses(delegatedRenderPasses);
138
139 // The RenderPasses should be taken by the layer.
140 EXPECT_EQ(0u, delegatedRenderPasses.size());
141
142 m_rootLayerPtr = rootLayer.get();
143 m_layerBeforePtr = layerBefore.get();
144 m_layerAfterPtr = layerAfter.get();
145 m_delegatedRendererLayerPtr = delegatedRendererLayer.get();
146
147 // Force the delegated RenderPasses to come before the RenderPass from layerAfter.
148 layerAfter->addChild(delegatedRendererLayer.release());
149 rootLayer->addChild(layerAfter.release());
150
151 // Get the RenderPass generated by layerBefore to come before the delegated RenderPasses.
152 rootLayer->addChild(layerBefore.release());
153
154 m_hostImpl->setRootLayer(rootLayer.release());
155 }
156
157protected:
158 CCSolidColorLayerImpl* m_rootLayerPtr;
159 CCSolidColorLayerImpl* m_layerBeforePtr;
160 CCSolidColorLayerImpl* m_layerAfterPtr;
161 CCDelegatedRendererLayerImpl* m_delegatedRendererLayerPtr;
162};
163
164TEST_F(CCDelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses)
165{
166 CCLayerTreeHostImpl::FrameData frame;
167 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
168 m_hostImpl->drawLayers(frame);
169 m_hostImpl->didDrawAllLayers(frame);
170
171 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes.
172 ASSERT_EQ(5u, frame.renderPasses.size());
173
174 // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame.
175 EXPECT_EQ(4, frame.renderPasses[1]->id().layerId);
176 EXPECT_EQ(1, frame.renderPasses[1]->id().index);
177 EXPECT_EQ(4, frame.renderPasses[2]->id().layerId);
178 EXPECT_EQ(2, frame.renderPasses[2]->id().index);
179 // And all other RenderPasses should be non-delegated.
180 EXPECT_NE(4, frame.renderPasses[0]->id().layerId);
181 EXPECT_EQ(0, frame.renderPasses[0]->id().index);
182 EXPECT_NE(4, frame.renderPasses[3]->id().layerId);
183 EXPECT_EQ(0, frame.renderPasses[3]->id().index);
184 EXPECT_NE(4, frame.renderPasses[4]->id().layerId);
185 EXPECT_EQ(0, frame.renderPasses[4]->id().index);
186
187 // The DelegatedRendererLayer should have added its RenderPasses to the frame in order.
188 EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[1]->outputRect());
189 EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[2]->outputRect());
190}
191
192TEST_F(CCDelegatedRendererLayerImplTestSimple, AddsQuadsToContributingRenderPasses)
193{
194 CCLayerTreeHostImpl::FrameData frame;
195 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
196 m_hostImpl->drawLayers(frame);
197 m_hostImpl->didDrawAllLayers(frame);
198
199 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes.
200 ASSERT_EQ(5u, frame.renderPasses.size());
201
202 // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame.
203 EXPECT_EQ(4, frame.renderPasses[1]->id().layerId);
204 EXPECT_EQ(1, frame.renderPasses[1]->id().index);
205 EXPECT_EQ(4, frame.renderPasses[2]->id().layerId);
206 EXPECT_EQ(2, frame.renderPasses[2]->id().index);
207
208 // The DelegatedRendererLayer should have added copies of its quads to contributing RenderPasses.
209 ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size());
210 EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect());
211
212 // Verify it added the right quads.
213 ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size());
214 EXPECT_RECT_EQ(IntRect(0, 0, 7, 7), frame.renderPasses[2]->quadList()[0]->quadRect());
215 EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[2]->quadList()[1]->quadRect());
216 ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size());
217 EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect());
218}
219
220TEST_F(CCDelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass)
221{
222 CCLayerTreeHostImpl::FrameData frame;
223 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
224 m_hostImpl->drawLayers(frame);
225 m_hostImpl->didDrawAllLayers(frame);
226
227 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes.
228 ASSERT_EQ(5u, frame.renderPasses.size());
229
230 // The layer's target is the RenderPass from m_layerAfter.
231 EXPECT_EQ(CCRenderPass::Id(3, 0), frame.renderPasses[3]->id());
232
233 // The DelegatedRendererLayer should have added copies of quads in its root RenderPass to its target RenderPass.
234 // The m_layerAfter also adds one quad.
235 ASSERT_EQ(2u, frame.renderPasses[3]->quadList().size());
236
237 // Verify it added the right quads.
238 EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[3]->quadList()[0]->quadRect());
239
240 // Its target layer should have a quad as well.
241 EXPECT_RECT_EQ(IntRect(0, 0, 15, 15), frame.renderPasses[3]->quadList()[1]->quadRect());
242}
243
244TEST_F(CCDelegatedRendererLayerImplTestSimple, QuadsFromRootRenderPassAreModifiedForTheTarget)
245{
246 CCLayerTreeHostImpl::FrameData frame;
247 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
248 m_hostImpl->drawLayers(frame);
249 m_hostImpl->didDrawAllLayers(frame);
250
251 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes.
252 ASSERT_EQ(5u, frame.renderPasses.size());
253
254 // The DelegatedRendererLayer is at position 3,3 compared to its target, and has a translation transform of 1,1.
255 // So its root RenderPass' quads should all be transformed by that combined amount.
256 WebTransformationMatrix transform;
257 transform.translate(4, 4);
258 EXPECT_TRANSFORMATION_MATRIX_EQ(transform, frame.renderPasses[3]->quadList()[0]->quadTransform());
259
260 // Quads from non-root RenderPasses should not be shifted though.
261 ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size());
262 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[0]->quadTransform());
263 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[1]->quadTransform());
264 ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size());
265 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[1]->quadList()[0]->quadTransform());
266}
267
268class CCDelegatedRendererLayerImplTestOwnSurface : public CCDelegatedRendererLayerImplTestSimple {
269public:
270 CCDelegatedRendererLayerImplTestOwnSurface()
271 : CCDelegatedRendererLayerImplTestSimple()
272 {
273 m_delegatedRendererLayerPtr->setForceRenderSurface(true);
274 }
275};
276
277TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses)
278{
279 CCLayerTreeHostImpl::FrameData frame;
280 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
281 m_hostImpl->drawLayers(frame);
282 m_hostImpl->didDrawAllLayers(frame);
283
284 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass.
285 ASSERT_EQ(6u, frame.renderPasses.size());
286
287 // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame.
288 EXPECT_EQ(4, frame.renderPasses[1]->id().layerId);
289 EXPECT_EQ(1, frame.renderPasses[1]->id().index);
290 EXPECT_EQ(4, frame.renderPasses[2]->id().layerId);
291 EXPECT_EQ(2, frame.renderPasses[2]->id().index);
292 // The DelegatedRendererLayer should have added a RenderPass for its surface to the frame.
293 EXPECT_EQ(4, frame.renderPasses[1]->id().layerId);
294 EXPECT_EQ(0, frame.renderPasses[3]->id().index);
295 // And all other RenderPasses should be non-delegated.
296 EXPECT_NE(4, frame.renderPasses[0]->id().layerId);
297 EXPECT_EQ(0, frame.renderPasses[0]->id().index);
298 EXPECT_NE(4, frame.renderPasses[4]->id().layerId);
299 EXPECT_EQ(0, frame.renderPasses[4]->id().index);
300 EXPECT_NE(4, frame.renderPasses[5]->id().layerId);
301 EXPECT_EQ(0, frame.renderPasses[5]->id().index);
302
303 // The DelegatedRendererLayer should have added its RenderPasses to the frame in order.
304 EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[1]->outputRect());
305 EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[2]->outputRect());
306}
307
308TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, AddsQuadsToContributingRenderPasses)
309{
310 CCLayerTreeHostImpl::FrameData frame;
311 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
312 m_hostImpl->drawLayers(frame);
313 m_hostImpl->didDrawAllLayers(frame);
314
315 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass.
316 ASSERT_EQ(6u, frame.renderPasses.size());
317
318 // The DelegatedRendererLayer should have added its contributing RenderPasses to the frame.
319 EXPECT_EQ(4, frame.renderPasses[1]->id().layerId);
320 EXPECT_EQ(1, frame.renderPasses[1]->id().index);
321 EXPECT_EQ(4, frame.renderPasses[2]->id().layerId);
322 EXPECT_EQ(2, frame.renderPasses[2]->id().index);
323
324 // The DelegatedRendererLayer should have added copies of its quads to contributing RenderPasses.
325 ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size());
326 EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect());
327
328 // Verify it added the right quads.
329 ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size());
330 EXPECT_RECT_EQ(IntRect(0, 0, 7, 7), frame.renderPasses[2]->quadList()[0]->quadRect());
331 EXPECT_RECT_EQ(IntRect(6, 6, 6, 6), frame.renderPasses[2]->quadList()[1]->quadRect());
332 ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size());
333 EXPECT_RECT_EQ(IntRect(0, 0, 6, 6), frame.renderPasses[1]->quadList()[0]->quadRect());
334}
335
336TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass)
337{
338 CCLayerTreeHostImpl::FrameData frame;
339 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
340 m_hostImpl->drawLayers(frame);
341 m_hostImpl->didDrawAllLayers(frame);
342
343 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass.
344 ASSERT_EQ(6u, frame.renderPasses.size());
345
346 // The layer's target is the RenderPass owned by itself.
347 EXPECT_EQ(CCRenderPass::Id(4, 0), frame.renderPasses[3]->id());
348
349 // The DelegatedRendererLayer should have added copies of quads in its root RenderPass to its target RenderPass.
350 // The m_layerAfter also adds one quad.
351 ASSERT_EQ(1u, frame.renderPasses[3]->quadList().size());
352
353 // Verify it added the right quads.
354 EXPECT_RECT_EQ(IntRect(7, 7, 7, 7), frame.renderPasses[3]->quadList()[0]->quadRect());
355}
356
357TEST_F(CCDelegatedRendererLayerImplTestOwnSurface, QuadsFromRootRenderPassAreNotModifiedForTheTarget)
358{
359 CCLayerTreeHostImpl::FrameData frame;
360 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
361 m_hostImpl->drawLayers(frame);
362 m_hostImpl->didDrawAllLayers(frame);
363
364 // Each non-DelegatedRendererLayer added one RenderPass. The DelegatedRendererLayer added two contributing passes and its owned surface added one pass.
365 ASSERT_EQ(6u, frame.renderPasses.size());
366
367 // Because the DelegatedRendererLayer owns a RenderSurface, its root RenderPass' quads do not need to be
368 // modified at all.
369 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[3]->quadList()[0]->quadTransform());
370
371 // Quads from non-root RenderPasses should not be shifted though.
372 ASSERT_EQ(2u, frame.renderPasses[2]->quadList().size());
373 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[0]->quadTransform());
374 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[2]->quadList()[1]->quadTransform());
375 ASSERT_EQ(1u, frame.renderPasses[1]->quadList().size());
376 EXPECT_TRANSFORMATION_MATRIX_EQ(WebTransformationMatrix(), frame.renderPasses[1]->quadList()[0]->quadTransform());
377}
378
379} // namespace