summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/browser/aura/gpu_process_transport_factory.cc29
-rw-r--r--content/browser/browser_main_loop.cc32
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.cc248
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.h58
-rw-r--r--content/browser/gpu/gpu_ipc_browsertests.cc147
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc43
-rw-r--r--content/browser/renderer_host/image_transport_factory_android.cc46
-rw-r--r--content/common/gpu/client/context_provider_command_buffer_browsertest.cc18
-rw-r--r--content/common/gpu/client/gpu_channel_host.h1
-rw-r--r--content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc109
-rw-r--r--content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h45
-rw-r--r--content/renderer/render_thread_impl.cc15
-rw-r--r--content/renderer/render_thread_impl.h3
-rw-r--r--content/renderer/render_widget.cc38
-rw-r--r--content/renderer/renderer_webkitplatformsupport_impl.cc7
15 files changed, 542 insertions, 297 deletions
diff --git a/content/browser/aura/gpu_process_transport_factory.cc b/content/browser/aura/gpu_process_transport_factory.cc
index 2d09b24..6e2acfc 100644
--- a/content/browser/aura/gpu_process_transport_factory.cc
+++ b/content/browser/aura/gpu_process_transport_factory.cc
@@ -221,12 +221,15 @@ scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
data = CreatePerCompositorData(compositor);
scoped_refptr<ContextProviderCommandBuffer> context_provider;
+ base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client_weak_ptr;
+ if (data->swap_client)
+ swap_client_weak_ptr = data->swap_client->AsWeakPtr();
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kUIEnableSoftwareCompositing)) {
context_provider = ContextProviderCommandBuffer::Create(
GpuProcessTransportFactory::CreateContextCommon(
- data->swap_client->AsWeakPtr(),
+ swap_client_weak_ptr,
data->surface_id),
"Compositor");
}
@@ -448,7 +451,8 @@ void GpuProcessTransportFactory::OnLostContext(ui::Compositor* compositor) {
// Prevent callbacks from other contexts in the same share group from
// calling us again.
- data->swap_client.reset(new CompositorSwapClient(compositor, this));
+ if (data->swap_client.get())
+ data->swap_client.reset(new CompositorSwapClient(compositor, this));
compositor->OnSwapBuffersAborted();
}
@@ -462,7 +466,8 @@ GpuProcessTransportFactory::CreatePerCompositorData(
PerCompositorData* data = new PerCompositorData;
data->surface_id = tracker->AddSurfaceForNativeWidget(widget);
- data->swap_client.reset(new CompositorSwapClient(compositor, this));
+ if (!ui::Compositor::WasInitializedWithThread())
+ data->swap_client.reset(new CompositorSwapClient(compositor, this));
#if defined(OS_WIN)
if (GpuDataManagerImpl::GetInstance()->IsUsingAcceleratedSurface())
data->accelerated_surface.reset(new AcceleratedSurface(widget));
@@ -488,19 +493,21 @@ GpuProcessTransportFactory::CreateContextCommon(
attrs.stencil = false;
attrs.antialias = false;
attrs.noAutomaticFlushes = true;
- GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance();
+ scoped_refptr<GpuChannelHost> gpu_channel_host(
+ BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
+ if (!gpu_channel_host)
+ return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
new WebGraphicsContext3DCommandBufferImpl(
surface_id,
url,
- factory,
- swap_client));
- if (!context->InitializeWithDefaultBufferSizes(
- attrs,
- false,
- CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE))
- return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
+ gpu_channel_host.get(),
+ swap_client,
+ attrs,
+ false,
+ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits()));
return context.Pass();
}
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index f8c8a1c..adccbd4 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -853,7 +853,8 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
// it.
{
TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:GPUChannelFactory");
- BrowserGpuChannelHostFactory::Terminate();
+ if (BrowserGpuChannelHostFactory::instance())
+ BrowserGpuChannelHostFactory::Terminate();
}
// Must happen after the I/O thread is shutdown since this class lives on the
@@ -910,9 +911,26 @@ int BrowserMainLoop::BrowserThreadsStarted() {
#if !defined(OS_IOS)
HistogramSynchronizer::GetInstance();
- BrowserGpuChannelHostFactory::Initialize();
+ // Initialize the GpuDataManager before we set up the MessageLoops because
+ // otherwise we'll trigger the assertion about doing IO on the UI thread.
+ GpuDataManagerImpl::GetInstance()->Initialize();
+
+ bool always_uses_gpu = IsForceCompositingModeEnabled();
+ bool established_gpu_channel = false;
+#if defined(USE_AURA) || defined(OS_ANDROID)
+ established_gpu_channel =
+ !parsed_command_line_.HasSwitch(switches::kDisableGpuProcessPrelaunch) ||
+ parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
+ parsed_command_line_.HasSwitch(switches::kInProcessGPU);
#if defined(USE_AURA)
+ if (GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
+ BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
+ else
+ always_uses_gpu = false;
ImageTransportFactory::Initialize();
+#elif defined(OS_ANDROID)
+ BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
+#endif
#endif
#if defined(OS_LINUX)
@@ -935,10 +953,6 @@ int BrowserMainLoop::BrowserThreadsStarted() {
media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
}
- // Initialize the GpuDataManager before we set up the MessageLoops because
- // otherwise we'll trigger the assertion about doing IO on the UI thread.
- GpuDataManagerImpl::GetInstance()->Initialize();
-
{
TRACE_EVENT0("startup",
"BrowserMainLoop::BrowserThreadsStarted:InitSpeechRecognition");
@@ -969,12 +983,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// When running the GPU thread in-process, avoid optimistically starting it
// since creating the GPU thread races against creation of the one-and-only
// ChildProcess instance which is created by the renderer thread.
- bool always_uses_gpu = IsForceCompositingModeEnabled();
-#if defined(USE_AURA)
- if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
- always_uses_gpu = false;
-#endif
if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
+ !established_gpu_channel &&
always_uses_gpu &&
!parsed_command_line_.HasSwitch(switches::kDisableGpuProcessPrelaunch) &&
!parsed_command_line_.HasSwitch(switches::kSingleProcess) &&
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index 7bc6fca..8de6d11 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -5,6 +5,7 @@
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "base/bind.h"
+#include "base/debug/trace_event.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
@@ -20,7 +21,7 @@ namespace content {
BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL;
BrowserGpuChannelHostFactory::CreateRequest::CreateRequest()
- : event(false, false),
+ : event(true, false),
gpu_host_id(0),
route_id(MSG_ROUTING_NONE) {
}
@@ -29,32 +30,137 @@ BrowserGpuChannelHostFactory::CreateRequest::~CreateRequest() {
}
BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest(
- CauseForGpuLaunch cause)
- : event(false, false),
- cause_for_gpu_launch(cause),
- gpu_host_id(0),
- reused_gpu_process(true) {
+ CauseForGpuLaunch cause,
+ int gpu_client_id,
+ int gpu_host_id)
+ : event_(false, false),
+ cause_for_gpu_launch_(cause),
+ gpu_client_id_(gpu_client_id),
+ gpu_host_id_(gpu_host_id),
+ reused_gpu_process_(false),
+ finished_(false),
+ main_loop_(base::MessageLoopProxy::current()) {
+ scoped_refptr<base::MessageLoopProxy> loop =
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
+ loop->PostTask(
+ FROM_HERE,
+ base::Bind(&BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO,
+ this));
}
BrowserGpuChannelHostFactory::EstablishRequest::~EstablishRequest() {
}
-void BrowserGpuChannelHostFactory::Initialize() {
- instance_ = new BrowserGpuChannelHostFactory();
+void BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO() {
+ GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
+ if (!host) {
+ host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ cause_for_gpu_launch_);
+ if (!host) {
+ FinishOnIO();
+ return;
+ }
+ gpu_host_id_ = host->host_id();
+ reused_gpu_process_ = false;
+ } else {
+ if (reused_gpu_process_) {
+ // We come here if we retried to establish the channel because of a
+ // failure in ChannelEstablishedOnIO, but we ended up with the same
+ // process ID, meaning the failure was not because of a channel error,
+ // but another reason. So fail now.
+ FinishOnIO();
+ return;
+ }
+ reused_gpu_process_ = true;
+ }
+
+ host->EstablishGpuChannel(
+ gpu_client_id_,
+ true,
+ base::Bind(
+ &BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO,
+ this));
+}
+
+void BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO(
+ const IPC::ChannelHandle& channel_handle,
+ const gpu::GPUInfo& gpu_info) {
+ if (channel_handle.name.empty() && reused_gpu_process_) {
+ // We failed after re-using the GPU process, but it may have died in the
+ // mean time. Retry to have a chance to create a fresh GPU process.
+ EstablishOnIO();
+ } else {
+ channel_handle_ = channel_handle;
+ gpu_info_ = gpu_info;
+ FinishOnIO();
+ }
+}
+
+void BrowserGpuChannelHostFactory::EstablishRequest::FinishOnIO() {
+ event_.Signal();
+ main_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&BrowserGpuChannelHostFactory::EstablishRequest::FinishOnMain,
+ this));
+}
+
+void BrowserGpuChannelHostFactory::EstablishRequest::FinishOnMain() {
+ if (!finished_) {
+ BrowserGpuChannelHostFactory* factory =
+ BrowserGpuChannelHostFactory::instance();
+ factory->GpuChannelEstablished();
+ finished_ = true;
+ }
+}
+
+void BrowserGpuChannelHostFactory::EstablishRequest::Wait() {
+ DCHECK(main_loop_->BelongsToCurrentThread());
+ {
+ // We're blocking the UI thread, which is generally undesirable.
+ // In this case we need to wait for this before we can show any UI
+ // /anyway/, so it won't cause additional jank.
+ // TODO(piman): Make this asynchronous (http://crbug.com/125248).
+ TRACE_EVENT0("browser",
+ "BrowserGpuChannelHostFactory::EstablishGpuChannelSync");
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ event_.Wait();
+ }
+ FinishOnMain();
+}
+
+void BrowserGpuChannelHostFactory::EstablishRequest::Cancel() {
+ DCHECK(main_loop_->BelongsToCurrentThread());
+ finished_ = true;
+}
+
+void BrowserGpuChannelHostFactory::Initialize(bool establish_gpu_channel) {
+ DCHECK(!instance_);
+ instance_ = new BrowserGpuChannelHostFactory(establish_gpu_channel);
}
void BrowserGpuChannelHostFactory::Terminate() {
+ DCHECK(instance_);
delete instance_;
instance_ = NULL;
}
-BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
+BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory(
+ bool establish_gpu_channel)
: gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
shutdown_event_(new base::WaitableEvent(true, false)),
gpu_host_id_(0) {
+ if (establish_gpu_channel) {
+ pending_request_ = new EstablishRequest(
+ CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP, gpu_client_id_, gpu_host_id_);
+ }
}
BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
+ DCHECK(IsMainThread());
+ if (pending_request_)
+ pending_request_->Cancel();
+ for (size_t n = 0; n < established_callbacks_.size(); n++)
+ established_callbacks_[n].Run();
shutdown_event_->Signal();
}
@@ -126,6 +232,8 @@ int32 BrowserGpuChannelHostFactory::CreateViewCommandBuffer(
// In this case we need to wait for this before we can show any UI /anyway/,
// so it won't cause additional jank.
// TODO(piman): Make this asynchronous (http://crbug.com/125248).
+ TRACE_EVENT0("browser",
+ "BrowserGpuChannelHostFactory::CreateViewCommandBuffer");
base::ThreadRestrictions::ScopedAllowWait allow_wait;
request.event.Wait();
return request.route_id;
@@ -197,91 +305,65 @@ void BrowserGpuChannelHostFactory::DeleteImage(
sync_point));
}
-void BrowserGpuChannelHostFactory::EstablishGpuChannelOnIO(
- EstablishRequest* request) {
- GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
- if (!host) {
- host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
- request->cause_for_gpu_launch);
- if (!host) {
- request->event.Signal();
- return;
- }
- gpu_host_id_ = host->host_id();
- request->reused_gpu_process = false;
- } else {
- if (host->host_id() == request->gpu_host_id) {
- // We come here if we retried to establish the channel because of a
- // failure in GpuChannelEstablishedOnIO, but we ended up with the same
- // process ID, meaning the failure was not because of a channel error, but
- // another reason. So fail now.
- request->event.Signal();
- return;
- }
- request->reused_gpu_process = true;
- }
- request->gpu_host_id = gpu_host_id_;
+GpuChannelHost* BrowserGpuChannelHostFactory::EstablishGpuChannelSync(
+ CauseForGpuLaunch cause_for_gpu_launch) {
+ EstablishGpuChannel(cause_for_gpu_launch, base::Closure());
- host->EstablishGpuChannel(
- gpu_client_id_,
- true,
- base::Bind(&BrowserGpuChannelHostFactory::GpuChannelEstablishedOnIO,
- base::Unretained(this),
- request));
-}
+ if (pending_request_)
+ pending_request_->Wait();
-void BrowserGpuChannelHostFactory::GpuChannelEstablishedOnIO(
- EstablishRequest* request,
- const IPC::ChannelHandle& channel_handle,
- const gpu::GPUInfo& gpu_info) {
- if (channel_handle.name.empty() && request->reused_gpu_process) {
- // We failed after re-using the GPU process, but it may have died in the
- // mean time. Retry to have a chance to create a fresh GPU process.
- EstablishGpuChannelOnIO(request);
- } else {
- request->channel_handle = channel_handle;
- request->gpu_info = gpu_info;
- request->event.Signal();
- }
+ return gpu_channel_.get();
}
-GpuChannelHost* BrowserGpuChannelHostFactory::EstablishGpuChannelSync(
- CauseForGpuLaunch cause_for_gpu_launch) {
- if (gpu_channel_.get()) {
+void BrowserGpuChannelHostFactory::EstablishGpuChannel(
+ CauseForGpuLaunch cause_for_gpu_launch,
+ const base::Closure& callback) {
+ if (gpu_channel_.get() && gpu_channel_->IsLost()) {
+ DCHECK(!pending_request_);
// Recreate the channel if it has been lost.
- if (gpu_channel_->IsLost())
- gpu_channel_ = NULL;
- else
- return gpu_channel_.get();
+ gpu_channel_ = NULL;
}
- // Ensure initialization on the main thread.
- GpuDataManagerImpl::GetInstance();
- EstablishRequest request(cause_for_gpu_launch);
- GetIOLoopProxy()->PostTask(
- FROM_HERE,
- base::Bind(
- &BrowserGpuChannelHostFactory::EstablishGpuChannelOnIO,
- base::Unretained(this),
- &request));
+ if (!gpu_channel_ && !pending_request_) {
+ // We should only get here if the context was lost.
+ pending_request_ = new EstablishRequest(
+ cause_for_gpu_launch, gpu_client_id_, gpu_host_id_);
+ }
- {
- // We're blocking the UI thread, which is generally undesirable.
- // In this case we need to wait for this before we can show any UI /anyway/,
- // so it won't cause additional jank.
- // TODO(piman): Make this asynchronous (http://crbug.com/125248).
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
- request.event.Wait();
+ if (!callback.is_null()) {
+ if (gpu_channel_)
+ callback.Run();
+ else
+ established_callbacks_.push_back(callback);
}
+}
- if (request.channel_handle.name.empty())
- return NULL;
+GpuChannelHost* BrowserGpuChannelHostFactory::GetGpuChannel() {
+ if (gpu_channel_ && !gpu_channel_->IsLost())
+ return gpu_channel_;
- GetContentClient()->SetGpuInfo(request.gpu_info);
- gpu_channel_ = GpuChannelHost::Create(
- this, request.gpu_host_id, gpu_client_id_,
- request.gpu_info, request.channel_handle);
- return gpu_channel_.get();
+ return NULL;
+}
+
+void BrowserGpuChannelHostFactory::GpuChannelEstablished() {
+ DCHECK(IsMainThread());
+ DCHECK(pending_request_);
+ if (pending_request_->channel_handle().name.empty())
+ return;
+
+ GetContentClient()->SetGpuInfo(pending_request_->gpu_info());
+ gpu_channel_ = GpuChannelHost::Create(this,
+ pending_request_->gpu_host_id(),
+ gpu_client_id_,
+ pending_request_->gpu_info(),
+ pending_request_->channel_handle());
+ gpu_host_id_ = pending_request_->gpu_host_id();
+ pending_request_ = NULL;
+
+ for (size_t n = 0; n < established_callbacks_.size(); n++)
+ established_callbacks_[n].Run();
+
+ established_callbacks_.clear();
}
// static
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index ca31183..1944155 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_GPU_BROWSER_GPU_CHANNEL_HOST_FACTORY_H_
#define CONTENT_BROWSER_GPU_BROWSER_GPU_CHANNEL_HOST_FACTORY_H_
+#include <vector>
+
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process.h"
@@ -17,7 +19,7 @@ namespace content {
class CONTENT_EXPORT BrowserGpuChannelHostFactory
: public GpuChannelHostFactory {
public:
- static void Initialize();
+ static void Initialize(bool establish_gpu_channel);
static void Terminate();
static BrowserGpuChannelHostFactory* instance() { return instance_; }
@@ -36,8 +38,6 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
int32 image_id,
const CreateImageCallback& callback) OVERRIDE;
virtual void DeleteImage(int32 image_idu, int32 sync_point) OVERRIDE;
- virtual GpuChannelHost* EstablishGpuChannelSync(
- CauseForGpuLaunch cause_for_gpu_launch) OVERRIDE;
// Specify a task runner and callback to be used for a set of messages. The
// callback will be set up on the current GpuProcessHost, identified by
@@ -48,6 +48,11 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
const base::Callback<void(const IPC::Message&)>& handler,
base::TaskRunner* target_task_runner);
int GpuProcessHostId() { return gpu_host_id_; }
+ GpuChannelHost* EstablishGpuChannelSync(
+ CauseForGpuLaunch cause_for_gpu_launch);
+ void EstablishGpuChannel(CauseForGpuLaunch cause_for_gpu_launch,
+ const base::Closure& callback);
+ GpuChannelHost* GetGpuChannel();
private:
struct CreateRequest {
@@ -58,20 +63,42 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
int32 route_id;
};
- struct EstablishRequest {
- explicit EstablishRequest(CauseForGpuLaunch);
+ class EstablishRequest : public base::RefCountedThreadSafe<EstablishRequest> {
+ public:
+ explicit EstablishRequest(CauseForGpuLaunch cause,
+ int gpu_client_id,
+ int gpu_host_id);
+ void Wait();
+ void Cancel();
+
+ int gpu_host_id() { return gpu_host_id_; }
+ IPC::ChannelHandle& channel_handle() { return channel_handle_; }
+ gpu::GPUInfo gpu_info() { return gpu_info_; }
+
+ private:
+ friend class base::RefCountedThreadSafe<EstablishRequest>;
~EstablishRequest();
- base::WaitableEvent event;
- CauseForGpuLaunch cause_for_gpu_launch;
- int gpu_host_id;
- bool reused_gpu_process;
- IPC::ChannelHandle channel_handle;
- gpu::GPUInfo gpu_info;
+ void EstablishOnIO();
+ void OnEstablishedOnIO(const IPC::ChannelHandle& channel_handle,
+ const gpu::GPUInfo& gpu_info);
+ void FinishOnIO();
+ void FinishOnMain();
+
+ base::WaitableEvent event_;
+ CauseForGpuLaunch cause_for_gpu_launch_;
+ int gpu_client_id_;
+ int gpu_host_id_;
+ bool reused_gpu_process_;
+ IPC::ChannelHandle channel_handle_;
+ gpu::GPUInfo gpu_info_;
+ bool finished_;
+ scoped_refptr<base::MessageLoopProxy> main_loop_;
};
- BrowserGpuChannelHostFactory();
+ explicit BrowserGpuChannelHostFactory(bool establish_gpu_channel);
virtual ~BrowserGpuChannelHostFactory();
+ void GpuChannelEstablished();
void CreateViewCommandBufferOnIO(
CreateRequest* request,
int32 surface_id,
@@ -86,11 +113,6 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
static void OnImageCreated(
const CreateImageCallback& callback, const gfx::Size size);
void DeleteImageOnIO(int32 image_id, int32 sync_point);
- void EstablishGpuChannelOnIO(EstablishRequest* request);
- void GpuChannelEstablishedOnIO(
- EstablishRequest* request,
- const IPC::ChannelHandle& channel_handle,
- const gpu::GPUInfo& gpu_info);
static void AddFilterOnIO(
int gpu_host_id,
scoped_refptr<IPC::ChannelProxy::MessageFilter> filter);
@@ -99,6 +121,8 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
scoped_ptr<base::WaitableEvent> shutdown_event_;
scoped_refptr<GpuChannelHost> gpu_channel_;
int gpu_host_id_;
+ scoped_refptr<EstablishRequest> pending_request_;
+ std::vector<base::Closure> established_callbacks_;
static BrowserGpuChannelHostFactory* instance_;
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc
index 0ee93db..3fda855 100644
--- a/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -3,8 +3,13 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/run_loop.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "content/browser/gpu/gpu_process_host_ui_shim.h"
+#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/test/content_browser_test.h"
#include "ui/gl/gl_switches.h"
@@ -15,10 +20,19 @@ namespace {
class ContextTestBase : public content::ContentBrowserTest {
public:
virtual void SetUpOnMainThread() OVERRIDE {
- CHECK(content::BrowserGpuChannelHostFactory::instance());
+ if (!content::BrowserGpuChannelHostFactory::instance())
+ content::BrowserGpuChannelHostFactory::Initialize(true);
+
+ content::BrowserGpuChannelHostFactory* factory =
+ content::BrowserGpuChannelHostFactory::instance();
+ CHECK(factory);
+ scoped_refptr<content::GpuChannelHost> gpu_channel_host(
+ factory->EstablishGpuChannelSync(
+ content::
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
context_.reset(
content::WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- content::BrowserGpuChannelHostFactory::instance(),
+ gpu_channel_host.get(),
WebKit::WebGraphicsContext3D::Attributes(),
GURL()));
CHECK(context_.get());
@@ -38,6 +52,133 @@ class ContextTestBase : public content::ContentBrowserTest {
} // namespace
-// Include the actual tests.
+// Include the shared tests.
#define CONTEXT_TEST_F IN_PROC_BROWSER_TEST_F
#include "content/common/gpu/client/gpu_context_tests.h"
+
+namespace content {
+
+class BrowserGpuChannelHostFactoryTest : public ContextTestBase {
+ public:
+ virtual void SetUpOnMainThread() OVERRIDE {
+ // Start all tests without a gpu channel so that the tests exercise a
+ // consistent codepath.
+ if (!content::BrowserGpuChannelHostFactory::instance())
+ content::BrowserGpuChannelHostFactory::Initialize(false);
+
+ CHECK(GetFactory());
+
+ ContentBrowserTest::SetUpOnMainThread();
+ }
+
+ virtual void TearDownOnMainThread() OVERRIDE {
+ ContextTestBase::TearDownOnMainThread();
+ }
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ // Start all tests without a gpu channel so that the tests exercise a
+ // consistent codepath.
+ command_line->AppendSwitch(switches::kDisableGpuProcessPrelaunch);
+ }
+
+ void OnContextLost(const base::Closure callback, int* counter) {
+ (*counter)++;
+ callback.Run();
+ }
+
+ protected:
+ BrowserGpuChannelHostFactory* GetFactory() {
+ return BrowserGpuChannelHostFactory::instance();
+ }
+
+ bool IsChannelEstablished() {
+ return GetFactory()->GetGpuChannel() != NULL;
+ }
+
+ void EstablishAndWait() {
+ base::RunLoop run_loop;
+ GetFactory()->EstablishGpuChannel(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
+ run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ GpuChannelHost* GetGpuChannel() {
+ return GetFactory()->GetGpuChannel();
+ }
+
+ static void Signal(bool *event) {
+ CHECK_EQ(*event, false);
+ *event = true;
+ }
+
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext() {
+ return make_scoped_ptr(
+ WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
+ GetGpuChannel(),
+ WebKit::WebGraphicsContext3D::Attributes(),
+ GURL()));
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, Basic) {
+ DCHECK(!IsChannelEstablished());
+ EstablishAndWait();
+ EXPECT_TRUE(GetGpuChannel() != NULL);
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
+ EstablishAndTerminate) {
+ DCHECK(!IsChannelEstablished());
+ base::RunLoop run_loop;
+ GetFactory()->EstablishGpuChannel(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
+ run_loop.QuitClosure());
+ GetFactory()->Terminate();
+
+ // The callback should still trigger.
+ run_loop.Run();
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, AlreadyEstablished) {
+ DCHECK(!IsChannelEstablished());
+ scoped_refptr<GpuChannelHost> gpu_channel =
+ GetFactory()->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
+
+ // Expect established callback immediately.
+ bool event = false;
+ GetFactory()->EstablishGpuChannel(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
+ base::Bind(&BrowserGpuChannelHostFactoryTest::Signal, &event));
+ EXPECT_TRUE(event);
+ EXPECT_EQ(gpu_channel, GetGpuChannel());
+}
+
+IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CrashAndRecover) {
+ DCHECK(!IsChannelEstablished());
+ EstablishAndWait();
+ scoped_refptr<GpuChannelHost> host = GetGpuChannel();
+
+ scoped_refptr<ContextProviderCommandBuffer> provider =
+ ContextProviderCommandBuffer::Create(CreateContext(),
+ "BrowserGpuChannelHostFactoryTest");
+ base::RunLoop run_loop;
+ int counter = 0;
+ provider->SetLostContextCallback(
+ base::Bind(&BrowserGpuChannelHostFactoryTest::OnContextLost,
+ base::Unretained(this), run_loop.QuitClosure(), &counter));
+ EXPECT_TRUE(provider->BindToCurrentThread());
+ GpuProcessHostUIShim* shim =
+ GpuProcessHostUIShim::FromID(GetFactory()->GpuProcessHostId());
+ EXPECT_TRUE(shim != NULL);
+ shim->SimulateCrash();
+ run_loop.Run();
+
+ EXPECT_EQ(1, counter);
+ EXPECT_FALSE(IsChannelEstablished());
+ EstablishAndWait();
+ EXPECT_TRUE(IsChannelEstablished());
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index da0c00f..f0d1ed9 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -358,34 +358,35 @@ CreateGpuProcessViewContext(
const WebKit::WebGraphicsContext3D::Attributes attributes,
int surface_id,
base::WeakPtr<CompositorImpl> compositor_impl) {
- GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance();
+ BrowserGpuChannelHostFactory* factory =
+ BrowserGpuChannelHostFactory::instance();
+ scoped_refptr<GpuChannelHost> gpu_channel_host(factory->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
+ if (!gpu_channel_host)
+ return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
+
GURL url("chrome://gpu/Compositor::createContext3D");
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
- new WebGraphicsContext3DCommandBufferImpl(surface_id,
- url,
- factory,
- compositor_impl));
static const size_t kBytesPerPixel = 4;
gfx::DeviceDisplayInfo display_info;
size_t full_screen_texture_size_in_bytes =
display_info.GetDisplayHeight() *
display_info.GetDisplayWidth() *
kBytesPerPixel;
- if (!context->Initialize(
- attributes,
- false,
- CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
- 64 * 1024, // command buffer size
- 64 * 1024, // start transfer buffer size
- 64 * 1024, // min transfer buffer size
- std::min(3 * full_screen_texture_size_in_bytes,
- kDefaultMaxTransferBufferSize),
- 2 * 1024 * 1024 // mapped memory limit
- )) {
- LOG(ERROR) << "Failed to create 3D context for compositor.";
- return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
- }
- return context.Pass();
+ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
+ limits.command_buffer_size = 64 * 1024;
+ limits.start_transfer_buffer_size = 64 * 1024;
+ limits.min_transfer_buffer_size = 64 * 1024;
+ limits.max_transfer_buffer_size = std::min(
+ 3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize);
+ limits.mapped_memory_reclaim_limit = 2 * 1024 * 1024;
+ return make_scoped_ptr(
+ new WebGraphicsContext3DCommandBufferImpl(surface_id,
+ url,
+ gpu_channel_host.get(),
+ compositor_impl,
+ attributes,
+ false,
+ limits));
}
scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
diff --git a/content/browser/renderer_host/image_transport_factory_android.cc b/content/browser/renderer_host/image_transport_factory_android.cc
index acfe2a0..9807366 100644
--- a/content/browser/renderer_host/image_transport_factory_android.cc
+++ b/content/browser/renderer_host/image_transport_factory_android.cc
@@ -56,34 +56,38 @@ class CmdBufferImageTransportFactory : public ImageTransportFactoryAndroid {
};
CmdBufferImageTransportFactory::CmdBufferImageTransportFactory() {
+ BrowserGpuChannelHostFactory* factory =
+ BrowserGpuChannelHostFactory::instance();
+ scoped_refptr<GpuChannelHost> gpu_channel_host(factory->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
+ DCHECK(gpu_channel_host);
+
WebKit::WebGraphicsContext3D::Attributes attrs;
attrs.shareResources = true;
- GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance();
GURL url("chrome://gpu/ImageTransportFactoryAndroid");
base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client;
- context_.reset(new WebGraphicsContext3DCommandBufferImpl(0, // offscreen
- url,
- factory,
- swap_client));
static const size_t kBytesPerPixel = 4;
gfx::DeviceDisplayInfo display_info;
- size_t full_screen_texture_size_in_bytes =
- display_info.GetDisplayHeight() *
- display_info.GetDisplayWidth() *
- kBytesPerPixel;
+ size_t full_screen_texture_size_in_bytes = display_info.GetDisplayHeight() *
+ display_info.GetDisplayWidth() *
+ kBytesPerPixel;
+ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
+ limits.command_buffer_size = 64 * 1024;
+ limits.start_transfer_buffer_size = 64 * 1024;
+ limits.min_transfer_buffer_size = 64 * 1024;
+ limits.max_transfer_buffer_size = std::min(
+ 3 * full_screen_texture_size_in_bytes, kDefaultMaxTransferBufferSize);
+ limits.mapped_memory_reclaim_limit =
+ WebGraphicsContext3DCommandBufferImpl::kNoLimit;
+ context_.reset(
+ new WebGraphicsContext3DCommandBufferImpl(0, // offscreen
+ url,
+ gpu_channel_host.get(),
+ swap_client,
+ attrs,
+ false,
+ limits));
context_->setContextLostCallback(context_lost_listener_.get());
- context_->Initialize(
- attrs,
- false,
- CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
- 64 * 1024, // command buffer size
- 64 * 1024, // starting buffer size
- 64 * 1024, // min buffer size
- std::min(3 * full_screen_texture_size_in_bytes,
- kDefaultMaxTransferBufferSize),
- WebGraphicsContext3DCommandBufferImpl::kNoLimit
- );
-
if (context_->makeContextCurrent())
context_->pushGroupMarkerEXT(
base::StringPrintf("CmdBufferImageTransportFactory-%p",
diff --git a/content/common/gpu/client/context_provider_command_buffer_browsertest.cc b/content/common/gpu/client/context_provider_command_buffer_browsertest.cc
index fd68aa4..e58e5d8 100644
--- a/content/common/gpu/client/context_provider_command_buffer_browsertest.cc
+++ b/content/common/gpu/client/context_provider_command_buffer_browsertest.cc
@@ -12,11 +12,27 @@ namespace content {
namespace {
class ContextProviderCommandBufferBrowserTest : public ContentBrowserTest {
+ public:
+ virtual void SetUpOnMainThread() OVERRIDE {
+ if (!GetFactory())
+ BrowserGpuChannelHostFactory::Initialize(true);
+
+ CHECK(GetFactory());
+ ContentBrowserTest::SetUpOnMainThread();
+ }
+
protected:
+ BrowserGpuChannelHostFactory* GetFactory() {
+ return BrowserGpuChannelHostFactory::instance();
+ }
+
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext3d() {
+ scoped_refptr<GpuChannelHost> gpu_channel_host(
+ GetFactory()->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- BrowserGpuChannelHostFactory::instance(),
+ gpu_channel_host.get(),
WebKit::WebGraphicsContext3D::Attributes(),
GURL("chrome://gpu/ContextProviderCommandBufferTest")));
return context.Pass();
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index 5efa98d..d6e7ef3 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -71,7 +71,6 @@ class CONTENT_EXPORT GpuChannelHostFactory {
virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
virtual int32 CreateViewCommandBuffer(
int32 surface_id, const GPUCreateCommandBufferConfig& init_params) = 0;
- virtual GpuChannelHost* EstablishGpuChannelSync(CauseForGpuLaunch) = 0;
virtual void CreateImage(
gfx::PluginWindowHandle window,
int32 image_id,
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
index c46c688..2087def 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
@@ -25,7 +25,6 @@
#include "base/synchronization/lock.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/gpu_memory_allocation.h"
-#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "gpu/GLES2/gl2extchromium.h"
@@ -213,16 +212,25 @@ void WebGraphicsContext3DErrorMessageCallback::OnErrorMessage(
graphics_context_->OnErrorMessage(msg, id);
}
+WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits()
+ : command_buffer_size(kDefaultCommandBufferSize),
+ start_transfer_buffer_size(kDefaultStartTransferBufferSize),
+ min_transfer_buffer_size(kDefaultMinTransferBufferSize),
+ max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
+ mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {}
+
WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
int surface_id,
const GURL& active_url,
- GpuChannelHostFactory* factory,
- const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client)
+ GpuChannelHost* host,
+ const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client,
+ const Attributes& attributes,
+ bool bind_generates_resources,
+ const SharedMemoryLimits& limits)
: initialize_failed_(false),
- factory_(factory),
visible_(false),
free_command_buffer_when_invisible_(false),
- host_(NULL),
+ host_(host),
surface_id_(surface_id),
active_url_(active_url),
swap_client_(swap_client),
@@ -230,18 +238,16 @@ WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
context_lost_reason_(GL_NO_ERROR),
error_message_callback_(0),
swapbuffers_complete_callback_(0),
- gpu_preference_(gfx::PreferIntegratedGpu),
+ attributes_(attributes),
+ gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu
+ : gfx::PreferIntegratedGpu),
weak_ptr_factory_(this),
initialized_(false),
gl_(NULL),
frame_number_(0),
- bind_generates_resources_(false),
+ bind_generates_resources_(bind_generates_resources),
use_echo_for_swap_ack_(true),
- command_buffer_size_(0),
- start_transfer_buffer_size_(0),
- min_transfer_buffer_size_(0),
- max_transfer_buffer_size_(0),
- mapped_memory_limit_(gpu::gles2::GLES2Implementation::kNoLimit),
+ mem_limits_(limits),
flush_id_(0) {
#if (defined(OS_MACOSX) || defined(OS_WIN)) && !defined(USE_AURA)
// Get ViewMsg_SwapBuffers_ACK from browser for single-threaded path.
@@ -264,54 +270,6 @@ WebGraphicsContext3DCommandBufferImpl::
Destroy();
}
-bool WebGraphicsContext3DCommandBufferImpl::InitializeWithDefaultBufferSizes(
- const WebGraphicsContext3D::Attributes& attributes,
- bool bind_generates_resources,
- CauseForGpuLaunch cause) {
- return Initialize(attributes,
- bind_generates_resources,
- cause,
- kDefaultCommandBufferSize,
- kDefaultStartTransferBufferSize,
- kDefaultMinTransferBufferSize,
- kDefaultMaxTransferBufferSize,
- gpu::gles2::GLES2Implementation::kNoLimit);
-}
-
-bool WebGraphicsContext3DCommandBufferImpl::Initialize(
- const WebGraphicsContext3D::Attributes& attributes,
- bool bind_generates_resources,
- CauseForGpuLaunch cause,
- size_t command_buffer_size,
- size_t start_transfer_buffer_size,
- size_t min_transfer_buffer_size,
- size_t max_transfer_buffer_size,
- size_t mapped_memory_limit) {
- TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::initialize");
-
- attributes_ = attributes;
- bind_generates_resources_ = bind_generates_resources;
- DCHECK(!command_buffer_);
-
- if (!factory_)
- return false;
-
- if (attributes.preferDiscreteGPU)
- gpu_preference_ = gfx::PreferDiscreteGpu;
-
- host_ = factory_->EstablishGpuChannelSync(cause);
- if (!host_.get())
- return false;
-
- command_buffer_size_ = command_buffer_size;
- start_transfer_buffer_size_ = start_transfer_buffer_size;
- min_transfer_buffer_size_ = min_transfer_buffer_size;
- max_transfer_buffer_size_ = max_transfer_buffer_size;
- mapped_memory_limit_ = mapped_memory_limit;
-
- return true;
-}
-
bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() {
if (initialized_)
return true;
@@ -439,7 +397,7 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
// Create the GLES2 helper, which writes the command buffer protocol.
gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
- if (!gles2_helper_->Initialize(command_buffer_size_))
+ if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size))
return false;
if (attributes_.noAutomaticFlushes)
@@ -478,10 +436,10 @@ bool WebGraphicsContext3DCommandBufferImpl::CreateContext(
}
if (!real_gl_->Initialize(
- start_transfer_buffer_size_,
- min_transfer_buffer_size_,
- max_transfer_buffer_size_,
- mapped_memory_limit_)) {
+ mem_limits_.start_transfer_buffer_size,
+ mem_limits_.min_transfer_buffer_size,
+ mem_limits_.max_transfer_buffer_size,
+ mem_limits_.mapped_memory_reclaim_limit)) {
return false;
}
@@ -1269,7 +1227,7 @@ void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) {
}
bool WebGraphicsContext3DCommandBufferImpl::ShouldUseSwapClient() {
- return factory_ && factory_->IsMainThread() && swap_client_.get();
+ return !!swap_client_.get();
}
void WebGraphicsContext3DCommandBufferImpl::OnSwapBuffersComplete() {
@@ -1367,20 +1325,19 @@ bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() {
// static
WebGraphicsContext3DCommandBufferImpl*
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- GpuChannelHostFactory* factory,
+ GpuChannelHost* host,
const WebGraphicsContext3D::Attributes& attributes,
const GURL& active_url) {
- if (!factory)
+ if (!host)
return NULL;
base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> null_client;
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
- new WebGraphicsContext3DCommandBufferImpl(
- 0, active_url, factory, null_client));
- CauseForGpuLaunch cause =
- CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
- if (context->InitializeWithDefaultBufferSizes(attributes, false, cause))
- return context.release();
- return NULL;
+ return new WebGraphicsContext3DCommandBufferImpl(0,
+ active_url,
+ host,
+ null_client,
+ attributes,
+ false,
+ SharedMemoryLimits());
}
void WebGraphicsContext3DCommandBufferImpl::
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
index e571eda..21a9598 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h
@@ -13,7 +13,6 @@
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/common/gpu/client/command_buffer_proxy_impl.h"
-#include "content/common/gpu/gpu_process_launch_causes.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "ui/gfx/native_widget_types.h"
@@ -50,7 +49,6 @@ using WebKit::WebGraphicsMemoryAllocation;
namespace content {
class GpuChannelHost;
-class GpuChannelHostFactory;
struct GpuMemoryAllocationForRenderer;
const size_t kDefaultCommandBufferSize = 1024 * 1024;
@@ -79,27 +77,27 @@ class WebGraphicsContext3DCommandBufferImpl
kNoLimit = 0,
};
+ struct SharedMemoryLimits {
+ SharedMemoryLimits();
+
+ size_t command_buffer_size;
+ size_t start_transfer_buffer_size;
+ size_t min_transfer_buffer_size;
+ size_t max_transfer_buffer_size;
+ size_t mapped_memory_reclaim_limit;
+ };
+
WebGraphicsContext3DCommandBufferImpl(
int surface_id,
const GURL& active_url,
- GpuChannelHostFactory* factory,
- const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client);
+ GpuChannelHost* host,
+ const base::WeakPtr<WebGraphicsContext3DSwapBuffersClient>& swap_client,
+ const Attributes& attributes,
+ bool bind_generates_resources,
+ const SharedMemoryLimits& limits);
virtual ~WebGraphicsContext3DCommandBufferImpl();
- bool Initialize(const Attributes& attributes,
- bool bind_generates_resources,
- CauseForGpuLaunch cause,
- size_t command_buffer_size,
- size_t start_transfer_buffer_size,
- size_t min_transfer_buffer_size,
- size_t max_transfer_buffer_size,
- size_t mapped_memory_reclaim_limit);
-
- bool InitializeWithDefaultBufferSizes(const Attributes& attributes,
- bool bind_generates_resources,
- CauseForGpuLaunch cause);
-
// The following 3 IDs let one uniquely identify this context.
// Gets the GPU process ID for this context.
int GetGPUProcessID();
@@ -126,12 +124,12 @@ class WebGraphicsContext3DCommandBufferImpl
// on any failure.
static CONTENT_EXPORT WebGraphicsContext3DCommandBufferImpl*
CreateOffscreenContext(
- GpuChannelHostFactory* factory,
+ GpuChannelHost* host,
const WebGraphicsContext3D::Attributes& attributes,
const GURL& active_url);
size_t GetMappedMemoryLimit() {
- return mapped_memory_limit_;
+ return mem_limits_.mapped_memory_reclaim_limit;
}
//----------------------------------------------------------------------
@@ -712,9 +710,6 @@ class WebGraphicsContext3DCommandBufferImpl
bool initialize_failed_;
- // The channel factory to talk to the GPU process
- GpuChannelHostFactory* factory_;
-
bool visible_;
bool free_command_buffer_when_invisible_;
@@ -754,11 +749,7 @@ class WebGraphicsContext3DCommandBufferImpl
int frame_number_;
bool bind_generates_resources_;
bool use_echo_for_swap_ack_;
- size_t command_buffer_size_;
- size_t start_transfer_buffer_size_;
- size_t min_transfer_buffer_size_;
- size_t max_transfer_buffer_size_;
- size_t mapped_memory_limit_;
+ SharedMemoryLimits mem_limits_;
uint32_t flush_id_;
};
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 1eb2c21..cc83b35 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -45,6 +45,7 @@
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/gpu_messages.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/common/resource_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_constants.h"
@@ -874,24 +875,28 @@ RenderThreadImpl::GetGpuFactories(
const scoped_refptr<base::MessageLoopProxy>& factories_loop) {
DCHECK(IsMainThread());
+ scoped_refptr<GpuChannelHost> gpu_channel_host = GetGpuChannel();
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories;
if (!cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
if (!gpu_va_context_provider_ ||
gpu_va_context_provider_->DestroyedOnMainThread()) {
+ if (!gpu_channel_host) {
+ gpu_channel_host = EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
+ }
gpu_va_context_provider_ = ContextProviderCommandBuffer::Create(
make_scoped_ptr(
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- this,
+ gpu_channel_host.get(),
WebKit::WebGraphicsContext3D::Attributes(),
GURL("chrome://gpu/RenderThreadImpl::GetGpuVDAContext3D"))),
"GPU-VideoAccelerator-Offscreen");
}
}
- GpuChannelHost* gpu_channel_host = GetGpuChannel();
if (gpu_channel_host) {
gpu_factories = new RendererGpuVideoAcceleratorFactories(
- gpu_channel_host, factories_loop, gpu_va_context_provider_);
+ gpu_channel_host.get(), factories_loop, gpu_va_context_provider_);
}
return gpu_factories;
}
@@ -905,9 +910,11 @@ RenderThreadImpl::CreateOffscreenContext3d() {
attributes.antialias = false;
attributes.noAutomaticFlushes = true;
+ scoped_refptr<GpuChannelHost> gpu_channel_host(EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
return make_scoped_ptr(
WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- this,
+ gpu_channel_host.get(),
attributes,
GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext3d")));
}
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index aea1836..678d06f 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -18,7 +18,6 @@
#include "content/child/child_thread.h"
#include "content/common/content_export.h"
#include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
#include "ipc/ipc_channel_proxy.h"
@@ -165,7 +164,7 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
// established or if it has been lost (for example if the GPU plugin crashed).
// If there is a pending asynchronous request, it will be completed by the
// time this routine returns.
- virtual GpuChannelHost* EstablishGpuChannelSync(CauseForGpuLaunch) OVERRIDE;
+ GpuChannelHost* EstablishGpuChannelSync(CauseForGpuLaunch);
// These methods modify how the next message is sent. Normally, when sending
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 1cb162a..241cab4 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -22,6 +22,7 @@
#include "content/child/npapi/webplugin.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/common/input_messages.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
@@ -2796,13 +2797,13 @@ RenderWidget::CreateGraphicsContext3D(
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuCompositing))
return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
- scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
- new WebGraphicsContext3DCommandBufferImpl(
- surface_id(),
- GetURLForGraphicsContext3D(),
- RenderThreadImpl::current(),
- weak_ptr_factory_.GetWeakPtr()));
+ scoped_refptr<GpuChannelHost> gpu_channel_host(
+ RenderThreadImpl::current()->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
+ if (!gpu_channel_host)
+ return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
+ WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
#if defined(OS_ANDROID)
// If we raster too fast we become upload bound, and pending
// uploads consume memory. For maximum upload throughput, we would
@@ -2822,22 +2823,23 @@ RenderWidget::CreateGraphicsContext3D(
static const size_t kBytesPerMegabyte = 1024 * 1024;
// We keep the MappedMemoryReclaimLimit the same as the upload limit
// to avoid unnecessarily stalling the compositor thread.
- const size_t mapped_memory_reclaim_limit =
+ limits.mapped_memory_reclaim_limit =
max_transfer_buffer_usage_mb * kBytesPerMegabyte;
-#else
- const size_t mapped_memory_reclaim_limit =
- WebGraphicsContext3DCommandBufferImpl::kNoLimit;
#endif
- if (!context->Initialize(
+
+ base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client;
+ if (!is_threaded_compositing_enabled_)
+ swap_client = weak_ptr_factory_.GetWeakPtr();
+
+ scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
+ new WebGraphicsContext3DCommandBufferImpl(
+ surface_id(),
+ GetURLForGraphicsContext3D(),
+ gpu_channel_host.get(),
+ swap_client,
attributes,
false /* bind generates resources */,
- CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
- kDefaultCommandBufferSize,
- kDefaultStartTransferBufferSize,
- kDefaultMinTransferBufferSize,
- kDefaultMaxTransferBufferSize,
- mapped_memory_reclaim_limit))
- return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
+ limits));
return context.Pass();
}
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc
index fce9f2b..105ab27 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.cc
+++ b/content/renderer/renderer_webkitplatformsupport_impl.cc
@@ -25,7 +25,9 @@
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/file_utilities_messages.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
+#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
+#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/common/mime_registry_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
@@ -936,8 +938,11 @@ bool RendererWebKitPlatformSupportImpl::processMemorySizesInBytes(
WebKit::WebGraphicsContext3D*
RendererWebKitPlatformSupportImpl::createOffscreenGraphicsContext3D(
const WebKit::WebGraphicsContext3D::Attributes& attributes) {
+ scoped_refptr<GpuChannelHost> gpu_channel_host(
+ RenderThreadImpl::current()->EstablishGpuChannelSync(
+ CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
return WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
- RenderThreadImpl::current(),
+ gpu_channel_host.get(),
attributes,
GURL(attributes.topDocumentURL));
}