| OLD | NEW |
| (Empty) |
| 1 // 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 #include "CCRendererGL.h" | |
| 7 | |
| 8 #include "CCDrawQuad.h" | |
| 9 #include "CCPrioritizedTextureManager.h" | |
| 10 #include "CCResourceProvider.h" | |
| 11 #include "CCSettings.h" | |
| 12 #include "CCSingleThreadProxy.h" | |
| 13 #include "CCTestCommon.h" | |
| 14 #include "FakeWebCompositorOutputSurface.h" | |
| 15 #include "FakeWebGraphicsContext3D.h" | |
| 16 #include "GraphicsContext3D.h" | |
| 17 #include "WebCompositorInitializer.h" | |
| 18 #include "testing/gmock/include/gmock/gmock.h" | |
| 19 #include "testing/gtest/include/gtest/gtest.h" | |
| 20 #include <public/WebTransformationMatrix.h> | |
| 21 | |
| 22 using namespace cc; | |
| 23 using namespace WebKit; | |
| 24 using namespace WebKitTests; | |
| 25 | |
| 26 class FrameCountingMemoryAllocationSettingContext : public FakeWebGraphicsContex
t3D { | |
| 27 public: | |
| 28 FrameCountingMemoryAllocationSettingContext() : m_frame(0) { } | |
| 29 | |
| 30 // WebGraphicsContext3D methods. | |
| 31 | |
| 32 // This method would normally do a glSwapBuffers under the hood. | |
| 33 virtual void prepareTexture() { m_frame++; } | |
| 34 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAll
ocationChangedCallbackCHROMIUM* callback) { m_memoryAllocationChangedCallback =
callback; } | |
| 35 virtual WebString getString(WebKit::WGC3Denum name) | |
| 36 { | |
| 37 if (name == GraphicsContext3D::EXTENSIONS) | |
| 38 return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_
manager GL_CHROMIUM_discard_framebuffer"); | |
| 39 return WebString(); | |
| 40 } | |
| 41 | |
| 42 // Methods added for test. | |
| 43 int frameCount() { return m_frame; } | |
| 44 void setMemoryAllocation(WebGraphicsMemoryAllocation allocation) | |
| 45 { | |
| 46 ASSERT(CCProxy::isImplThread()); | |
| 47 // In single threaded mode we expect this callback on main thread. | |
| 48 DebugScopedSetMainThread main; | |
| 49 m_memoryAllocationChangedCallback->onMemoryAllocationChanged(allocation)
; | |
| 50 } | |
| 51 | |
| 52 private: | |
| 53 int m_frame; | |
| 54 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* m_memoryAllocationChange
dCallback; | |
| 55 }; | |
| 56 | |
| 57 class FakeCCRendererClient : public CCRendererClient { | |
| 58 public: | |
| 59 FakeCCRendererClient() | |
| 60 : m_setFullRootLayerDamageCount(0) | |
| 61 , m_rootLayer(CCLayerImpl::create(1)) | |
| 62 , m_memoryAllocationLimitBytes(CCPrioritizedTextureManager::defaultMemor
yAllocationLimit()) | |
| 63 { | |
| 64 m_rootLayer->createRenderSurface(); | |
| 65 CCRenderPass::Id renderPassId = m_rootLayer->renderSurface()->renderPass
Id(); | |
| 66 scoped_ptr<CCRenderPass> rootRenderPass = CCRenderPass::create(renderPas
sId, IntRect(), WebTransformationMatrix()); | |
| 67 m_renderPassesInDrawOrder.push_back(rootRenderPass.get()); | |
| 68 m_renderPasses.set(renderPassId, rootRenderPass.Pass()); | |
| 69 } | |
| 70 | |
| 71 // CCRendererClient methods. | |
| 72 virtual const IntSize& deviceViewportSize() const OVERRIDE { static IntSize
fakeSize(1, 1); return fakeSize; } | |
| 73 virtual const CCLayerTreeSettings& settings() const OVERRIDE { static CCLaye
rTreeSettings fakeSettings; return fakeSettings; } | |
| 74 virtual void didLoseContext() OVERRIDE { } | |
| 75 virtual void onSwapBuffersComplete() OVERRIDE { } | |
| 76 virtual void setFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCou
nt++; } | |
| 77 virtual void releaseContentsTextures() OVERRIDE { } | |
| 78 virtual void setMemoryAllocationLimitBytes(size_t bytes) OVERRIDE { m_memory
AllocationLimitBytes = bytes; } | |
| 79 | |
| 80 // Methods added for test. | |
| 81 int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCou
nt; } | |
| 82 | |
| 83 CCRenderPass* rootRenderPass() { return m_renderPassesInDrawOrder.back(); } | |
| 84 const CCRenderPassList& renderPassesInDrawOrder() const { return m_renderPas
sesInDrawOrder; } | |
| 85 const CCRenderPassIdHashMap& renderPasses() const { return m_renderPasses; } | |
| 86 | |
| 87 size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBy
tes; } | |
| 88 | |
| 89 private: | |
| 90 int m_setFullRootLayerDamageCount; | |
| 91 DebugScopedSetImplThread m_implThread; | |
| 92 scoped_ptr<CCLayerImpl> m_rootLayer; | |
| 93 CCRenderPassList m_renderPassesInDrawOrder; | |
| 94 CCRenderPassIdHashMap m_renderPasses; | |
| 95 size_t m_memoryAllocationLimitBytes; | |
| 96 }; | |
| 97 | |
| 98 class FakeCCRendererGL : public CCRendererGL { | |
| 99 public: | |
| 100 FakeCCRendererGL(CCRendererClient* client, CCResourceProvider* resourceProvi
der) : CCRendererGL(client, resourceProvider) { } | |
| 101 | |
| 102 // CCRendererGL methods. | |
| 103 | |
| 104 // Changing visibility to public. | |
| 105 using CCRendererGL::initialize; | |
| 106 using CCRendererGL::isFramebufferDiscarded; | |
| 107 }; | |
| 108 | |
| 109 class CCRendererGLTest : public testing::Test { | |
| 110 protected: | |
| 111 CCRendererGLTest() | |
| 112 : m_suggestHaveBackbufferYes(1, true) | |
| 113 , m_suggestHaveBackbufferNo(1, false) | |
| 114 , m_compositorInitializer(0) | |
| 115 , m_context(FakeWebCompositorOutputSurface::create(adoptPtr(new FrameCou
ntingMemoryAllocationSettingContext()))) | |
| 116 , m_resourceProvider(CCResourceProvider::create(m_context.get())) | |
| 117 , m_renderer(&m_mockClient, m_resourceProvider.get()) | |
| 118 { | |
| 119 } | |
| 120 | |
| 121 virtual void SetUp() | |
| 122 { | |
| 123 m_renderer.initialize(); | |
| 124 } | |
| 125 | |
| 126 void swapBuffers() | |
| 127 { | |
| 128 m_renderer.swapBuffers(); | |
| 129 } | |
| 130 | |
| 131 FrameCountingMemoryAllocationSettingContext* context() { return static_cast<
FrameCountingMemoryAllocationSettingContext*>(m_context->context3D()); } | |
| 132 | |
| 133 WebGraphicsMemoryAllocation m_suggestHaveBackbufferYes; | |
| 134 WebGraphicsMemoryAllocation m_suggestHaveBackbufferNo; | |
| 135 | |
| 136 WebCompositorInitializer m_compositorInitializer; | |
| 137 scoped_ptr<CCGraphicsContext> m_context; | |
| 138 FakeCCRendererClient m_mockClient; | |
| 139 OwnPtr<CCResourceProvider> m_resourceProvider; | |
| 140 FakeCCRendererGL m_renderer; | |
| 141 CCScopedSettings m_scopedSettings; | |
| 142 }; | |
| 143 | |
| 144 // Test CCRendererGL discardFramebuffer functionality: | |
| 145 // Suggest recreating framebuffer when one already exists. | |
| 146 // Expected: it does nothing. | |
| 147 TEST_F(CCRendererGLTest, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing) | |
| 148 { | |
| 149 context()->setMemoryAllocation(m_suggestHaveBackbufferYes); | |
| 150 EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount()); | |
| 151 EXPECT_FALSE(m_renderer.isFramebufferDiscarded()); | |
| 152 | |
| 153 swapBuffers(); | |
| 154 EXPECT_EQ(1, context()->frameCount()); | |
| 155 } | |
| 156 | |
| 157 // Test CCRendererGL discardFramebuffer functionality: | |
| 158 // Suggest discarding framebuffer when one exists and the renderer is not visibl
e. | |
| 159 // Expected: it is discarded and damage tracker is reset. | |
| 160 TEST_F(CCRendererGLTest, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRoot
LayerWhileNotVisible) | |
| 161 { | |
| 162 m_renderer.setVisible(false); | |
| 163 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | |
| 164 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | |
| 165 EXPECT_TRUE(m_renderer.isFramebufferDiscarded()); | |
| 166 } | |
| 167 | |
| 168 // Test CCRendererGL discardFramebuffer functionality: | |
| 169 // Suggest discarding framebuffer when one exists and the renderer is visible. | |
| 170 // Expected: the allocation is ignored. | |
| 171 TEST_F(CCRendererGLTest, SuggestBackbufferNoDoNothingWhenVisible) | |
| 172 { | |
| 173 m_renderer.setVisible(true); | |
| 174 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | |
| 175 EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount()); | |
| 176 EXPECT_FALSE(m_renderer.isFramebufferDiscarded()); | |
| 177 } | |
| 178 | |
| 179 | |
| 180 // Test CCRendererGL discardFramebuffer functionality: | |
| 181 // Suggest discarding framebuffer when one does not exist. | |
| 182 // Expected: it does nothing. | |
| 183 TEST_F(CCRendererGLTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) | |
| 184 { | |
| 185 m_renderer.setVisible(false); | |
| 186 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | |
| 187 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | |
| 188 EXPECT_TRUE(m_renderer.isFramebufferDiscarded()); | |
| 189 | |
| 190 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | |
| 191 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | |
| 192 EXPECT_TRUE(m_renderer.isFramebufferDiscarded()); | |
| 193 } | |
| 194 | |
| 195 // Test CCRendererGL discardFramebuffer functionality: | |
| 196 // Begin drawing a frame while a framebuffer is discarded. | |
| 197 // Expected: will recreate framebuffer. | |
| 198 TEST_F(CCRendererGLTest, DiscardedBackbufferIsRecreatedForScopeDuration) | |
| 199 { | |
| 200 m_renderer.setVisible(false); | |
| 201 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | |
| 202 EXPECT_TRUE(m_renderer.isFramebufferDiscarded()); | |
| 203 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | |
| 204 | |
| 205 m_renderer.setVisible(true); | |
| 206 m_renderer.drawFrame(m_mockClient.renderPassesInDrawOrder(), m_mockClient.re
nderPasses()); | |
| 207 EXPECT_FALSE(m_renderer.isFramebufferDiscarded()); | |
| 208 | |
| 209 swapBuffers(); | |
| 210 EXPECT_EQ(1, context()->frameCount()); | |
| 211 } | |
| 212 | |
| 213 TEST_F(CCRendererGLTest, FramebufferDiscardedAfterReadbackWhenNotVisible) | |
| 214 { | |
| 215 m_renderer.setVisible(false); | |
| 216 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | |
| 217 EXPECT_TRUE(m_renderer.isFramebufferDiscarded()); | |
| 218 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | |
| 219 | |
| 220 char pixels[4]; | |
| 221 m_renderer.drawFrame(m_mockClient.renderPassesInDrawOrder(), m_mockClient.re
nderPasses()); | |
| 222 EXPECT_FALSE(m_renderer.isFramebufferDiscarded()); | |
| 223 | |
| 224 m_renderer.getFramebufferPixels(pixels, IntRect(0, 0, 1, 1)); | |
| 225 EXPECT_TRUE(m_renderer.isFramebufferDiscarded()); | |
| 226 EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount()); | |
| 227 } | |
| 228 | |
| 229 class ForbidSynchronousCallContext : public FakeWebGraphicsContext3D { | |
| 230 public: | |
| 231 ForbidSynchronousCallContext() { } | |
| 232 | |
| 233 virtual bool getActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo&)
{ ADD_FAILURE(); return false; } | |
| 234 virtual bool getActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo&)
{ ADD_FAILURE(); return false; } | |
| 235 virtual void getAttachedShaders(WebGLId program, WGC3Dsizei maxCount, WGC3Ds
izei* count, WebGLId* shaders) { ADD_FAILURE(); } | |
| 236 virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name) {
ADD_FAILURE(); return 0; } | |
| 237 virtual void getBooleanv(WGC3Denum pname, WGC3Dboolean* value) { ADD_FAILURE
(); } | |
| 238 virtual void getBufferParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Din
t* value) { ADD_FAILURE(); } | |
| 239 virtual Attributes getContextAttributes() { ADD_FAILURE(); return m_attrs; } | |
| 240 virtual WGC3Denum getError() { ADD_FAILURE(); return 0; } | |
| 241 virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE();
} | |
| 242 virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, WGC3Denum
attachment, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); } | |
| 243 virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value) | |
| 244 { | |
| 245 if (pname == GraphicsContext3D::MAX_TEXTURE_SIZE) | |
| 246 *value = 1024; // MAX_TEXTURE_SIZE is cached client side, so it's OK
to query. | |
| 247 else | |
| 248 ADD_FAILURE(); | |
| 249 } | |
| 250 | |
| 251 // We allow querying the shader compilation and program link status in debug
mode, but not release. | |
| 252 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value) | |
| 253 { | |
| 254 #ifndef NDEBUG | |
| 255 *value = 1; | |
| 256 #else | |
| 257 ADD_FAILURE(); | |
| 258 #endif | |
| 259 } | |
| 260 | |
| 261 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) | |
| 262 { | |
| 263 #ifndef NDEBUG | |
| 264 *value = 1; | |
| 265 #else | |
| 266 ADD_FAILURE(); | |
| 267 #endif | |
| 268 } | |
| 269 | |
| 270 virtual WebString getString(WGC3Denum name) | |
| 271 { | |
| 272 // We allow querying the extension string. | |
| 273 // FIXME: It'd be better to check that we only do this before starting a
ny other expensive work (like starting a compilation) | |
| 274 if (name != GraphicsContext3D::EXTENSIONS) | |
| 275 ADD_FAILURE(); | |
| 276 return WebString(); | |
| 277 } | |
| 278 | |
| 279 virtual WebString getProgramInfoLog(WebGLId program) { ADD_FAILURE(); return
WebString(); } | |
| 280 virtual void getRenderbufferParameteriv(WGC3Denum target, WGC3Denum pname, W
GC3Dint* value) { ADD_FAILURE(); } | |
| 281 | |
| 282 virtual WebString getShaderInfoLog(WebGLId shader) { ADD_FAILURE(); return W
ebString(); } | |
| 283 virtual void getShaderPrecisionFormat(WGC3Denum shadertype, WGC3Denum precis
iontype, WGC3Dint* range, WGC3Dint* precision) { ADD_FAILURE(); } | |
| 284 virtual WebString getShaderSource(WebGLId shader) { ADD_FAILURE(); return We
bString(); } | |
| 285 virtual void getTexParameterfv(WGC3Denum target, WGC3Denum pname, WGC3Dfloat
* value) { ADD_FAILURE(); } | |
| 286 virtual void getTexParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint*
value) { ADD_FAILURE(); } | |
| 287 virtual void getUniformfv(WebGLId program, WGC3Dint location, WGC3Dfloat* va
lue) { ADD_FAILURE(); } | |
| 288 virtual void getUniformiv(WebGLId program, WGC3Dint location, WGC3Dint* valu
e) { ADD_FAILURE(); } | |
| 289 virtual WGC3Dint getUniformLocation(WebGLId program, const WGC3Dchar* name)
{ ADD_FAILURE(); return 0; } | |
| 290 virtual void getVertexAttribfv(WGC3Duint index, WGC3Denum pname, WGC3Dfloat*
value) { ADD_FAILURE(); } | |
| 291 virtual void getVertexAttribiv(WGC3Duint index, WGC3Denum pname, WGC3Dint* v
alue) { ADD_FAILURE(); } | |
| 292 virtual WGC3Dsizeiptr getVertexAttribOffset(WGC3Duint index, WGC3Denum pname
) { ADD_FAILURE(); return 0; } | |
| 293 }; | |
| 294 | |
| 295 // This test isn't using the same fixture as CCRendererGLTest, and you can't mix
TEST() and TEST_F() with the same name, hence LRC2. | |
| 296 TEST(CCRendererGLTest2, initializationDoesNotMakeSynchronousCalls) | |
| 297 { | |
| 298 CCScopedSettings scopedSettings; | |
| 299 FakeCCRendererClient mockClient; | |
| 300 scoped_ptr<CCGraphicsContext> context(FakeWebCompositorOutputSurface::create
(adoptPtr(new ForbidSynchronousCallContext))); | |
| 301 OwnPtr<CCResourceProvider> resourceProvider(CCResourceProvider::create(conte
xt.get())); | |
| 302 FakeCCRendererGL renderer(&mockClient, resourceProvider.get()); | |
| 303 | |
| 304 EXPECT_TRUE(renderer.initialize()); | |
| 305 } | |
| 306 | |
| 307 class LoseContextOnFirstGetContext : public FakeWebGraphicsContext3D { | |
| 308 public: | |
| 309 LoseContextOnFirstGetContext() | |
| 310 : m_contextLost(false) | |
| 311 { | |
| 312 } | |
| 313 | |
| 314 virtual bool makeContextCurrent() OVERRIDE | |
| 315 { | |
| 316 return !m_contextLost; | |
| 317 } | |
| 318 | |
| 319 virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value)
OVERRIDE | |
| 320 { | |
| 321 m_contextLost = true; | |
| 322 *value = 0; | |
| 323 } | |
| 324 | |
| 325 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) O
VERRIDE | |
| 326 { | |
| 327 m_contextLost = true; | |
| 328 *value = 0; | |
| 329 } | |
| 330 | |
| 331 virtual WGC3Denum getGraphicsResetStatusARB() OVERRIDE | |
| 332 { | |
| 333 return m_contextLost ? 1 : 0; | |
| 334 } | |
| 335 | |
| 336 private: | |
| 337 bool m_contextLost; | |
| 338 }; | |
| 339 | |
| 340 TEST(CCRendererGLTest2, initializationWithQuicklyLostContextDoesNotAssert) | |
| 341 { | |
| 342 CCScopedSettings scopedSettings; | |
| 343 FakeCCRendererClient mockClient; | |
| 344 scoped_ptr<CCGraphicsContext> context(FakeWebCompositorOutputSurface::create
(adoptPtr(new LoseContextOnFirstGetContext))); | |
| 345 OwnPtr<CCResourceProvider> resourceProvider(CCResourceProvider::create(conte
xt.get())); | |
| 346 FakeCCRendererGL renderer(&mockClient, resourceProvider.get()); | |
| 347 | |
| 348 renderer.initialize(); | |
| 349 } | |
| 350 | |
| 351 class ContextThatDoesNotSupportMemoryManagmentExtensions : public FakeWebGraphic
sContext3D { | |
| 352 public: | |
| 353 ContextThatDoesNotSupportMemoryManagmentExtensions() { } | |
| 354 | |
| 355 // WebGraphicsContext3D methods. | |
| 356 | |
| 357 // This method would normally do a glSwapBuffers under the hood. | |
| 358 virtual void prepareTexture() { } | |
| 359 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAll
ocationChangedCallbackCHROMIUM* callback) { } | |
| 360 virtual WebString getString(WebKit::WGC3Denum name) { return WebString(); } | |
| 361 }; | |
| 362 | |
| 363 TEST(CCRendererGLTest2, initializationWithoutGpuMemoryManagerExtensionSupportSho
uldDefaultToNonZeroAllocation) | |
| 364 { | |
| 365 FakeCCRendererClient mockClient; | |
| 366 scoped_ptr<CCGraphicsContext> context(FakeWebCompositorOutputSurface::create
(adoptPtr(new ContextThatDoesNotSupportMemoryManagmentExtensions))); | |
| 367 OwnPtr<CCResourceProvider> resourceProvider(CCResourceProvider::create(conte
xt.get())); | |
| 368 FakeCCRendererGL renderer(&mockClient, resourceProvider.get()); | |
| 369 | |
| 370 renderer.initialize(); | |
| 371 | |
| 372 EXPECT_GT(mockClient.memoryAllocationLimitBytes(), 0ul); | |
| 373 } | |
| 374 | |
| 375 class ClearCountingContext : public FakeWebGraphicsContext3D { | |
| 376 public: | |
| 377 ClearCountingContext() : m_clear(0) { } | |
| 378 | |
| 379 virtual void clear(WGC3Dbitfield) | |
| 380 { | |
| 381 m_clear++; | |
| 382 } | |
| 383 | |
| 384 int clearCount() const { return m_clear; } | |
| 385 | |
| 386 private: | |
| 387 int m_clear; | |
| 388 }; | |
| 389 | |
| 390 TEST(CCRendererGLTest2, opaqueBackground) | |
| 391 { | |
| 392 FakeCCRendererClient mockClient; | |
| 393 scoped_ptr<CCGraphicsContext> ccContext(FakeWebCompositorOutputSurface::crea
te(adoptPtr(new ClearCountingContext))); | |
| 394 ClearCountingContext* context = static_cast<ClearCountingContext*>(ccContext
->context3D()); | |
| 395 OwnPtr<CCResourceProvider> resourceProvider(CCResourceProvider::create(ccCon
text.get())); | |
| 396 FakeCCRendererGL renderer(&mockClient, resourceProvider.get()); | |
| 397 | |
| 398 mockClient.rootRenderPass()->setHasTransparentBackground(false); | |
| 399 | |
| 400 EXPECT_TRUE(renderer.initialize()); | |
| 401 | |
| 402 renderer.drawFrame(mockClient.renderPassesInDrawOrder(), mockClient.renderPa
sses()); | |
| 403 | |
| 404 // On DEBUG builds, render passes with opaque background clear to blue to | |
| 405 // easily see regions that were not drawn on the screen. | |
| 406 #if defined(NDEBUG) | |
| 407 EXPECT_EQ(0, context->clearCount()); | |
| 408 #else | |
| 409 EXPECT_EQ(1, context->clearCount()); | |
| 410 #endif | |
| 411 } | |
| 412 | |
| 413 TEST(CCRendererGLTest2, transparentBackground) | |
| 414 { | |
| 415 FakeCCRendererClient mockClient; | |
| 416 scoped_ptr<CCGraphicsContext> ccContext(FakeWebCompositorOutputSurface::crea
te(adoptPtr(new ClearCountingContext))); | |
| 417 ClearCountingContext* context = static_cast<ClearCountingContext*>(ccContext
->context3D()); | |
| 418 OwnPtr<CCResourceProvider> resourceProvider(CCResourceProvider::create(ccCon
text.get())); | |
| 419 FakeCCRendererGL renderer(&mockClient, resourceProvider.get()); | |
| 420 | |
| 421 mockClient.rootRenderPass()->setHasTransparentBackground(true); | |
| 422 | |
| 423 EXPECT_TRUE(renderer.initialize()); | |
| 424 | |
| 425 renderer.drawFrame(mockClient.renderPassesInDrawOrder(), mockClient.renderPa
sses()); | |
| 426 | |
| 427 EXPECT_EQ(1, context->clearCount()); | |
| 428 } | |
| OLD | NEW |