Disable ContentSettingBubbleModelTest.RPHAllow which is flaky.
[chromium-blink-merge.git] / content / renderer / pepper / pepper_platform_context_3d_impl.cc
blob09e59359f9b6d3d5a00fcc93121d6f964291ed79
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_impl.h"
7 #include "base/bind.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 "googleurl/src/gurl.h"
13 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
14 #include "gpu/command_buffer/client/gles2_implementation.h"
15 #include "gpu/ipc/command_buffer_proxy.h"
16 #include "ppapi/c/pp_graphics_3d.h"
17 #include "ui/gl/gpu_preference.h"
19 #ifdef ENABLE_GPU
21 namespace content {
23 PlatformContext3DImpl::PlatformContext3DImpl()
24 : parent_texture_id_(0),
25 has_alpha_(false),
26 command_buffer_(NULL),
27 weak_ptr_factory_(this) {
30 PlatformContext3DImpl::~PlatformContext3DImpl() {
31 DestroyParentContextProviderAndBackingTexture();
33 if (command_buffer_) {
34 DCHECK(channel_.get());
35 channel_->DestroyCommandBuffer(command_buffer_);
36 command_buffer_ = NULL;
39 channel_ = NULL;
42 bool PlatformContext3DImpl::Init(const int32* attrib_list,
43 PlatformContext3D* share_context) {
44 // Ignore initializing more than once.
45 if (command_buffer_)
46 return true;
48 RenderThreadImpl* render_thread = RenderThreadImpl::current();
49 if (!render_thread)
50 return false;
52 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
54 channel_ = render_thread->EstablishGpuChannelSync(
55 CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE);
56 if (!channel_)
57 return false;
58 DCHECK(channel_->state() == GpuChannelHost::kConnected);
60 gfx::Size surface_size;
61 std::vector<int32> attribs;
62 // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer()
63 // interface to accept width and height in the attrib_list so that
64 // we do not need to filter for width and height here.
65 if (attrib_list) {
66 for (const int32_t* attr = attrib_list;
67 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
68 attr += 2) {
69 switch (attr[0]) {
70 case PP_GRAPHICS3DATTRIB_WIDTH:
71 surface_size.set_width(attr[1]);
72 break;
73 case PP_GRAPHICS3DATTRIB_HEIGHT:
74 surface_size.set_height(attr[1]);
75 break;
76 case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE:
77 gpu_preference =
78 (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER) ?
79 gfx::PreferIntegratedGpu : gfx::PreferDiscreteGpu;
80 break;
81 case PP_GRAPHICS3DATTRIB_ALPHA_SIZE:
82 has_alpha_ = attr[1] > 0;
83 // fall-through
84 default:
85 attribs.push_back(attr[0]);
86 attribs.push_back(attr[1]);
87 break;
90 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
93 CommandBufferProxyImpl* share_buffer = NULL;
94 if (share_context) {
95 PlatformContext3DImpl* share_impl =
96 static_cast<PlatformContext3DImpl*>(share_context);
97 share_buffer = share_impl->command_buffer_;
100 command_buffer_ = channel_->CreateOffscreenCommandBuffer(
101 surface_size,
102 share_buffer,
103 "*",
104 attribs,
105 GURL::EmptyGURL(),
106 gpu_preference);
107 if (!command_buffer_)
108 return false;
110 command_buffer_->SetChannelErrorCallback(
111 base::Bind(&PlatformContext3DImpl::OnContextLost,
112 weak_ptr_factory_.GetWeakPtr()));
113 command_buffer_->SetOnConsoleMessageCallback(
114 base::Bind(&PlatformContext3DImpl::OnConsoleMessage,
115 weak_ptr_factory_.GetWeakPtr()));
117 return SetParentAndCreateBackingTextureIfNeeded();
120 bool PlatformContext3DImpl::SetParentAndCreateBackingTextureIfNeeded() {
121 if (parent_context_provider_ &&
122 !parent_context_provider_->DestroyedOnMainThread() &&
123 parent_texture_id_)
124 return true;
126 parent_context_provider_ =
127 RenderThreadImpl::current()->OffscreenContextProviderForMainThread();
128 parent_texture_id_ = 0;
129 if (!parent_context_provider_)
130 return false;
132 // Flush any remaining commands in the parent context to make sure the
133 // texture id accounting stays consistent.
134 gpu::gles2::GLES2Implementation* parent_gles2 =
135 parent_context_provider_->Context3d()->GetImplementation();
136 parent_gles2->helper()->CommandBufferHelper::Finish();
137 parent_texture_id_ = parent_gles2->MakeTextureId();
139 CommandBufferProxyImpl* parent_command_buffer =
140 parent_context_provider_->Context3d()->GetCommandBufferProxy();
141 if (!command_buffer_->SetParent(parent_command_buffer, parent_texture_id_))
142 return false;
144 return true;
147 void PlatformContext3DImpl::DestroyParentContextProviderAndBackingTexture() {
148 if (!parent_context_provider_)
149 return;
151 if (parent_texture_id_) {
152 // Flush any remaining commands in the parent context to make sure the
153 // texture id accounting stays consistent.
154 gpu::gles2::GLES2Implementation* parent_gles2 =
155 parent_context_provider_->Context3d()->GetImplementation();
156 parent_gles2->helper()->CommandBufferHelper::Finish();
157 parent_gles2->FreeTextureId(parent_texture_id_);
158 parent_texture_id_ = 0;
161 parent_context_provider_ = NULL;
164 unsigned PlatformContext3DImpl::GetBackingTextureId() {
165 DCHECK(command_buffer_);
166 return parent_texture_id_;
169 WebKit::WebGraphicsContext3D* PlatformContext3DImpl::GetParentContext() {
170 if (!parent_context_provider_)
171 return NULL;
172 return parent_context_provider_->Context3d();
175 bool PlatformContext3DImpl::IsOpaque() {
176 DCHECK(command_buffer_);
177 return !has_alpha_;
180 gpu::CommandBuffer* PlatformContext3DImpl::GetCommandBuffer() {
181 return command_buffer_;
184 int PlatformContext3DImpl::GetCommandBufferRouteId() {
185 DCHECK(command_buffer_);
186 return command_buffer_->GetRouteID();
189 void PlatformContext3DImpl::SetContextLostCallback(const base::Closure& task) {
190 context_lost_callback_ = task;
193 void PlatformContext3DImpl::SetOnConsoleMessageCallback(
194 const ConsoleMessageCallback& task) {
195 console_message_callback_ = task;
198 bool PlatformContext3DImpl::Echo(const base::Closure& task) {
199 return command_buffer_->Echo(task);
202 void PlatformContext3DImpl::OnContextLost() {
203 DCHECK(command_buffer_);
205 if (!context_lost_callback_.is_null())
206 context_lost_callback_.Run();
209 void PlatformContext3DImpl::OnConsoleMessage(const std::string& msg, int id) {
210 DCHECK(command_buffer_);
212 if (!console_message_callback_.is_null())
213 console_message_callback_.Run(msg, id);
216 } // namespace content
218 #endif // ENABLE_GPU