1 // Copyright (c) 2012 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.
5 #include "content/renderer/pepper/pepper_platform_context_3d.h"
8 #include "content/common/gpu/client/context_provider_command_buffer.h"
9 #include "content/common/gpu/client/gpu_channel_host.h"
10 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
11 #include "content/renderer/render_thread_impl.h"
12 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
13 #include "gpu/command_buffer/client/gles2_implementation.h"
14 #include "ppapi/c/pp_graphics_3d.h"
15 #include "ui/gl/gpu_preference.h"
20 PlatformContext3D::PlatformContext3D()
22 command_buffer_(NULL),
23 weak_ptr_factory_(this) {
26 PlatformContext3D::~PlatformContext3D() {
27 if (command_buffer_) {
28 DCHECK(channel_.get());
29 channel_->DestroyCommandBuffer(command_buffer_);
30 command_buffer_ = NULL;
36 bool PlatformContext3D::Init(const int32* attrib_list,
37 PlatformContext3D* share_context) {
38 // Ignore initializing more than once.
42 RenderThreadImpl* render_thread = RenderThreadImpl::current();
46 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
48 channel_ = render_thread->EstablishGpuChannelSync(
49 CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
53 gfx::Size surface_size;
54 std::vector<int32> attribs;
55 // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer()
56 // interface to accept width and height in the attrib_list so that
57 // we do not need to filter for width and height here.
59 for (const int32_t* attr = attrib_list;
60 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
63 case PP_GRAPHICS3DATTRIB_WIDTH:
64 surface_size.set_width(attr[1]);
66 case PP_GRAPHICS3DATTRIB_HEIGHT:
67 surface_size.set_height(attr[1]);
69 case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
71 (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER) ?
72 gfx::PreferIntegratedGpu : gfx::PreferDiscreteGpu;
74 case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
75 has_alpha_ = attr[1] > 0;
78 attribs.push_back(attr[0]);
79 attribs.push_back(attr[1]);
83 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
86 CommandBufferProxyImpl* share_buffer = NULL;
88 PlatformContext3D* share_impl =
89 static_cast<PlatformContext3D*>(share_context);
90 share_buffer = share_impl->command_buffer_;
93 command_buffer_ = channel_->CreateOffscreenCommandBuffer(
101 if (!command_buffer_->Initialize())
103 gpu::Mailbox mailbox = gpu::Mailbox::Generate();
104 if (!command_buffer_->ProduceFrontBuffer(mailbox))
108 command_buffer_->SetChannelErrorCallback(
109 base::Bind(&PlatformContext3D::OnContextLost,
110 weak_ptr_factory_.GetWeakPtr()));
111 command_buffer_->SetOnConsoleMessageCallback(
112 base::Bind(&PlatformContext3D::OnConsoleMessage,
113 weak_ptr_factory_.GetWeakPtr()));
118 void PlatformContext3D::GetBackingMailbox(gpu::Mailbox* mailbox) {
122 bool PlatformContext3D::IsOpaque() {
123 DCHECK(command_buffer_);
127 gpu::CommandBuffer* PlatformContext3D::GetCommandBuffer() {
128 return command_buffer_;
131 gpu::GpuControl* PlatformContext3D::GetGpuControl() {
132 return command_buffer_;
135 int PlatformContext3D::GetCommandBufferRouteId() {
136 DCHECK(command_buffer_);
137 return command_buffer_->GetRouteID();
140 void PlatformContext3D::SetContextLostCallback(const base::Closure& task) {
141 context_lost_callback_ = task;
144 void PlatformContext3D::SetOnConsoleMessageCallback(
145 const ConsoleMessageCallback& task) {
146 console_message_callback_ = task;
149 void PlatformContext3D::Echo(const base::Closure& task) {
150 command_buffer_->Echo(task);
153 void PlatformContext3D::OnContextLost() {
154 DCHECK(command_buffer_);
156 if (!context_lost_callback_.is_null())
157 context_lost_callback_.Run();
160 void PlatformContext3D::OnConsoleMessage(const std::string& msg, int id) {
161 DCHECK(command_buffer_);
163 if (!console_message_callback_.is_null())
164 console_message_callback_.Run(msg, id);
167 } // namespace content