Home | History | Annotate | Download | only in gpu
      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 "base/command_line.h"
      6 #include "base/run_loop.h"
      7 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
      8 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
      9 #include "content/common/gpu/client/context_provider_command_buffer.h"
     10 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
     11 #include "content/common/gpu/gpu_process_launch_causes.h"
     12 #include "content/public/browser/gpu_data_manager.h"
     13 #include "content/public/common/content_switches.h"
     14 #include "content/public/test/content_browser_test.h"
     15 #include "ui/gl/gl_switches.h"
     16 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
     17 
     18 namespace {
     19 
     20 using content::WebGraphicsContext3DCommandBufferImpl;
     21 
     22 const content::CauseForGpuLaunch kInitCause =
     23     content::
     24         CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
     25 
     26 class ContextTestBase : public content::ContentBrowserTest {
     27  public:
     28   virtual void SetUpOnMainThread() OVERRIDE {
     29     if (!content::BrowserGpuChannelHostFactory::CanUseForTesting())
     30       return;
     31 
     32     if (!content::BrowserGpuChannelHostFactory::instance())
     33       content::BrowserGpuChannelHostFactory::Initialize(true);
     34 
     35     content::BrowserGpuChannelHostFactory* factory =
     36         content::BrowserGpuChannelHostFactory::instance();
     37     CHECK(factory);
     38     bool lose_context_when_out_of_memory = false;
     39     scoped_refptr<content::GpuChannelHost> gpu_channel_host(
     40         factory->EstablishGpuChannelSync(kInitCause));
     41     context_.reset(
     42         WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
     43             gpu_channel_host.get(),
     44             blink::WebGraphicsContext3D::Attributes(),
     45             lose_context_when_out_of_memory,
     46             GURL(),
     47             WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
     48             NULL));
     49     CHECK(context_.get());
     50     context_->makeContextCurrent();
     51     context_support_ = context_->GetContextSupport();
     52     ContentBrowserTest::SetUpOnMainThread();
     53   }
     54 
     55   virtual void TearDownOnMainThread() OVERRIDE {
     56     // Must delete the context first.
     57     context_.reset(NULL);
     58     ContentBrowserTest::TearDownOnMainThread();
     59   }
     60 
     61  protected:
     62   scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> context_;
     63   gpu::ContextSupport* context_support_;
     64 };
     65 
     66 }  // namespace
     67 
     68 // Include the shared tests.
     69 #define CONTEXT_TEST_F IN_PROC_BROWSER_TEST_F
     70 #include "content/common/gpu/client/gpu_context_tests.h"
     71 
     72 namespace content {
     73 
     74 class BrowserGpuChannelHostFactoryTest : public ContentBrowserTest {
     75  public:
     76   virtual void SetUpOnMainThread() OVERRIDE {
     77     if (!BrowserGpuChannelHostFactory::CanUseForTesting())
     78       return;
     79 
     80     // Start all tests without a gpu channel so that the tests exercise a
     81     // consistent codepath.
     82     if (!BrowserGpuChannelHostFactory::instance())
     83       BrowserGpuChannelHostFactory::Initialize(false);
     84 
     85     CHECK(GetFactory());
     86 
     87     ContentBrowserTest::SetUpOnMainThread();
     88   }
     89 
     90   void OnContextLost(const base::Closure callback, int* counter) {
     91     (*counter)++;
     92     callback.Run();
     93   }
     94 
     95  protected:
     96   BrowserGpuChannelHostFactory* GetFactory() {
     97     return BrowserGpuChannelHostFactory::instance();
     98   }
     99 
    100   bool IsChannelEstablished() {
    101     return GetFactory()->GetGpuChannel() != NULL;
    102   }
    103 
    104   void EstablishAndWait() {
    105     base::RunLoop run_loop;
    106     GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
    107     run_loop.Run();
    108   }
    109 
    110   GpuChannelHost* GetGpuChannel() {
    111     return GetFactory()->GetGpuChannel();
    112   }
    113 
    114   static void Signal(bool *event) {
    115     CHECK_EQ(*event, false);
    116     *event = true;
    117   }
    118 
    119   scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext() {
    120     bool lose_context_when_out_of_memory = false;
    121     return make_scoped_ptr(
    122         WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
    123             GetGpuChannel(),
    124             blink::WebGraphicsContext3D::Attributes(),
    125             lose_context_when_out_of_memory,
    126             GURL(),
    127             WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
    128             NULL));
    129   }
    130 };
    131 
    132 // Fails since UI Compositor establishes a GpuChannel.
    133 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, DISABLED_Basic) {
    134   DCHECK(!IsChannelEstablished());
    135   EstablishAndWait();
    136   EXPECT_TRUE(GetGpuChannel() != NULL);
    137 }
    138 
    139 // Fails since UI Compositor establishes a GpuChannel.
    140 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
    141                        DISABLED_EstablishAndTerminate) {
    142   DCHECK(!IsChannelEstablished());
    143   base::RunLoop run_loop;
    144   GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
    145   GetFactory()->Terminate();
    146 
    147   // The callback should still trigger.
    148   run_loop.Run();
    149 }
    150 
    151 // Fails since UI Compositor establishes a GpuChannel.
    152 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
    153                        DISABLED_AlreadyEstablished) {
    154   DCHECK(!IsChannelEstablished());
    155   scoped_refptr<GpuChannelHost> gpu_channel =
    156       GetFactory()->EstablishGpuChannelSync(kInitCause);
    157 
    158   // Expect established callback immediately.
    159   bool event = false;
    160   GetFactory()->EstablishGpuChannel(
    161       kInitCause,
    162       base::Bind(&BrowserGpuChannelHostFactoryTest::Signal, &event));
    163   EXPECT_TRUE(event);
    164   EXPECT_EQ(gpu_channel, GetGpuChannel());
    165 }
    166 
    167 // Fails since UI Compositor establishes a GpuChannel.
    168 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
    169                        DISABLED_CrashAndRecover) {
    170   DCHECK(!IsChannelEstablished());
    171   EstablishAndWait();
    172   scoped_refptr<GpuChannelHost> host = GetGpuChannel();
    173 
    174   scoped_refptr<ContextProviderCommandBuffer> provider =
    175       ContextProviderCommandBuffer::Create(CreateContext(),
    176                                            "BrowserGpuChannelHostFactoryTest");
    177   base::RunLoop run_loop;
    178   int counter = 0;
    179   provider->SetLostContextCallback(
    180       base::Bind(&BrowserGpuChannelHostFactoryTest::OnContextLost,
    181                  base::Unretained(this), run_loop.QuitClosure(), &counter));
    182   EXPECT_TRUE(provider->BindToCurrentThread());
    183   GpuProcessHostUIShim* shim =
    184       GpuProcessHostUIShim::FromID(GetFactory()->GpuProcessHostId());
    185   EXPECT_TRUE(shim != NULL);
    186   shim->SimulateCrash();
    187   run_loop.Run();
    188 
    189   EXPECT_EQ(1, counter);
    190   EXPECT_FALSE(IsChannelEstablished());
    191   EstablishAndWait();
    192   EXPECT_TRUE(IsChannelEstablished());
    193 }
    194 
    195 }  // namespace content
    196