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