1 // Copyright 2013 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 "cc/output/output_surface.h" 6 7 #include "base/test/test_simple_task_runner.h" 8 #include "cc/output/managed_memory_policy.h" 9 #include "cc/output/output_surface_client.h" 10 #include "cc/output/software_output_device.h" 11 #include "cc/test/begin_frame_args_test.h" 12 #include "cc/test/fake_output_surface.h" 13 #include "cc/test/fake_output_surface_client.h" 14 #include "cc/test/scheduler_test_common.h" 15 #include "cc/test/test_context_provider.h" 16 #include "cc/test/test_web_graphics_context_3d.h" 17 #include "gpu/GLES2/gl2extchromium.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "ui/gfx/frame_time.h" 20 21 namespace cc { 22 namespace { 23 24 class TestOutputSurface : public OutputSurface { 25 public: 26 explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider) 27 : OutputSurface(context_provider) {} 28 29 explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) 30 : OutputSurface(software_device.Pass()) {} 31 32 TestOutputSurface(scoped_refptr<ContextProvider> context_provider, 33 scoped_ptr<SoftwareOutputDevice> software_device) 34 : OutputSurface(context_provider, software_device.Pass()) {} 35 36 bool InitializeNewContext3d( 37 scoped_refptr<ContextProvider> new_context_provider) { 38 return InitializeAndSetContext3d(new_context_provider); 39 } 40 41 using OutputSurface::ReleaseGL; 42 43 void CommitVSyncParametersForTesting(base::TimeTicks timebase, 44 base::TimeDelta interval) { 45 CommitVSyncParameters(timebase, interval); 46 } 47 48 void BeginFrameForTesting() { 49 client_->BeginFrame(CreateExpiredBeginFrameArgsForTesting()); 50 } 51 52 void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); } 53 54 void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); } 55 56 protected: 57 }; 58 59 class TestSoftwareOutputDevice : public SoftwareOutputDevice { 60 public: 61 TestSoftwareOutputDevice(); 62 virtual ~TestSoftwareOutputDevice(); 63 64 // Overriden from cc:SoftwareOutputDevice 65 virtual void DiscardBackbuffer() OVERRIDE; 66 virtual void EnsureBackbuffer() OVERRIDE; 67 68 int discard_backbuffer_count() { return discard_backbuffer_count_; } 69 int ensure_backbuffer_count() { return ensure_backbuffer_count_; } 70 71 private: 72 int discard_backbuffer_count_; 73 int ensure_backbuffer_count_; 74 }; 75 76 TestSoftwareOutputDevice::TestSoftwareOutputDevice() 77 : discard_backbuffer_count_(0), ensure_backbuffer_count_(0) {} 78 79 TestSoftwareOutputDevice::~TestSoftwareOutputDevice() {} 80 81 void TestSoftwareOutputDevice::DiscardBackbuffer() { 82 SoftwareOutputDevice::DiscardBackbuffer(); 83 discard_backbuffer_count_++; 84 } 85 86 void TestSoftwareOutputDevice::EnsureBackbuffer() { 87 SoftwareOutputDevice::EnsureBackbuffer(); 88 ensure_backbuffer_count_++; 89 } 90 91 TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) { 92 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(); 93 TestOutputSurface output_surface(provider); 94 EXPECT_FALSE(output_surface.HasClient()); 95 96 FakeOutputSurfaceClient client; 97 EXPECT_TRUE(output_surface.BindToClient(&client)); 98 EXPECT_TRUE(output_surface.HasClient()); 99 EXPECT_FALSE(client.deferred_initialize_called()); 100 101 // Verify DidLoseOutputSurface callback is hooked up correctly. 102 EXPECT_FALSE(client.did_lose_output_surface_called()); 103 output_surface.context_provider()->ContextGL()->LoseContextCHROMIUM( 104 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); 105 output_surface.context_provider()->ContextGL()->Flush(); 106 EXPECT_TRUE(client.did_lose_output_surface_called()); 107 } 108 109 TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientFailure) { 110 scoped_refptr<TestContextProvider> context_provider = 111 TestContextProvider::Create(); 112 113 // Lose the context so BindToClient fails. 114 context_provider->UnboundTestContext3d()->set_context_lost(true); 115 116 TestOutputSurface output_surface(context_provider); 117 EXPECT_FALSE(output_surface.HasClient()); 118 119 FakeOutputSurfaceClient client; 120 EXPECT_FALSE(output_surface.BindToClient(&client)); 121 EXPECT_FALSE(output_surface.HasClient()); 122 } 123 124 class OutputSurfaceTestInitializeNewContext3d : public ::testing::Test { 125 public: 126 OutputSurfaceTestInitializeNewContext3d() 127 : context_provider_(TestContextProvider::Create()), 128 output_surface_( 129 scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice)), 130 client_(&output_surface_) {} 131 132 protected: 133 void BindOutputSurface() { 134 EXPECT_TRUE(output_surface_.BindToClient(&client_)); 135 EXPECT_TRUE(output_surface_.HasClient()); 136 } 137 138 void InitializeNewContextExpectFail() { 139 EXPECT_FALSE(output_surface_.InitializeNewContext3d(context_provider_)); 140 EXPECT_TRUE(output_surface_.HasClient()); 141 142 EXPECT_FALSE(output_surface_.context_provider()); 143 EXPECT_TRUE(output_surface_.software_device()); 144 } 145 146 scoped_refptr<TestContextProvider> context_provider_; 147 TestOutputSurface output_surface_; 148 FakeOutputSurfaceClient client_; 149 }; 150 151 TEST_F(OutputSurfaceTestInitializeNewContext3d, Success) { 152 BindOutputSurface(); 153 EXPECT_FALSE(client_.deferred_initialize_called()); 154 155 EXPECT_TRUE(output_surface_.InitializeNewContext3d(context_provider_)); 156 EXPECT_TRUE(client_.deferred_initialize_called()); 157 EXPECT_EQ(context_provider_, output_surface_.context_provider()); 158 159 EXPECT_FALSE(client_.did_lose_output_surface_called()); 160 context_provider_->ContextGL()->LoseContextCHROMIUM( 161 GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); 162 context_provider_->ContextGL()->Flush(); 163 EXPECT_TRUE(client_.did_lose_output_surface_called()); 164 165 output_surface_.ReleaseGL(); 166 EXPECT_FALSE(output_surface_.context_provider()); 167 } 168 169 TEST_F(OutputSurfaceTestInitializeNewContext3d, Context3dMakeCurrentFails) { 170 BindOutputSurface(); 171 172 context_provider_->UnboundTestContext3d()->set_context_lost(true); 173 InitializeNewContextExpectFail(); 174 } 175 176 TEST(OutputSurfaceTest, MemoryAllocation) { 177 scoped_refptr<TestContextProvider> context_provider = 178 TestContextProvider::Create(); 179 180 TestOutputSurface output_surface(context_provider); 181 182 FakeOutputSurfaceClient client; 183 EXPECT_TRUE(output_surface.BindToClient(&client)); 184 185 ManagedMemoryPolicy policy(0); 186 policy.bytes_limit_when_visible = 1234; 187 policy.priority_cutoff_when_visible = 188 gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY; 189 190 context_provider->SetMemoryAllocation(policy); 191 EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible); 192 EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY, 193 client.memory_policy().priority_cutoff_when_visible); 194 195 policy.priority_cutoff_when_visible = 196 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING; 197 context_provider->SetMemoryAllocation(policy); 198 EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 199 client.memory_policy().priority_cutoff_when_visible); 200 201 // 0 bytes limit should be ignored. 202 policy.bytes_limit_when_visible = 0; 203 context_provider->SetMemoryAllocation(policy); 204 EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible); 205 } 206 207 TEST(OutputSurfaceTest, SoftwareOutputDeviceBackbufferManagement) { 208 TestSoftwareOutputDevice* software_output_device = 209 new TestSoftwareOutputDevice(); 210 211 // TestOutputSurface now owns software_output_device and has responsibility to 212 // free it. 213 scoped_ptr<TestSoftwareOutputDevice> p(software_output_device); 214 TestOutputSurface output_surface(p.PassAs<SoftwareOutputDevice>()); 215 216 EXPECT_EQ(0, software_output_device->ensure_backbuffer_count()); 217 EXPECT_EQ(0, software_output_device->discard_backbuffer_count()); 218 219 output_surface.EnsureBackbuffer(); 220 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count()); 221 EXPECT_EQ(0, software_output_device->discard_backbuffer_count()); 222 output_surface.DiscardBackbuffer(); 223 224 EXPECT_EQ(1, software_output_device->ensure_backbuffer_count()); 225 EXPECT_EQ(1, software_output_device->discard_backbuffer_count()); 226 } 227 228 } // namespace 229 } // namespace cc 230