Home | History | Annotate | Download | only in output
      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