Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc

Issue 101223005: Plumbing explicit share groups through context creation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Better share group management Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
6 6
7 #include "third_party/khronos/GLES2/gl2.h" 7 #include "third_party/khronos/GLES2/gl2.h"
8 #ifndef GL_GLEXT_PROTOTYPES 8 #ifndef GL_GLEXT_PROTOTYPES
9 #define GL_GLEXT_PROTOTYPES 1 9 #define GL_GLEXT_PROTOTYPES 1
10 #endif 10 #endif
11 #include "third_party/khronos/GLES2/gl2ext.h" 11 #include "third_party/khronos/GLES2/gl2ext.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <map> 14 #include <map>
15 15
16 #include "base/atomicops.h" 16 #include "base/atomicops.h"
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/command_line.h" 18 #include "base/command_line.h"
19 #include "base/debug/trace_event.h" 19 #include "base/debug/trace_event.h"
20 #include "base/lazy_instance.h" 20 #include "base/lazy_instance.h"
21 #include "base/logging.h" 21 #include "base/logging.h"
22 #include "base/message_loop/message_loop.h" 22 #include "base/message_loop/message_loop.h"
23 #include "base/metrics/field_trial.h" 23 #include "base/metrics/field_trial.h"
24 #include "base/metrics/histogram.h" 24 #include "base/metrics/histogram.h"
25 #include "base/synchronization/lock.h"
26 #include "content/common/gpu/client/gpu_channel_host.h" 25 #include "content/common/gpu/client/gpu_channel_host.h"
27 #include "content/public/common/content_constants.h" 26 #include "content/public/common/content_constants.h"
28 #include "content/public/common/content_switches.h" 27 #include "content/public/common/content_switches.h"
29 #include "gpu/GLES2/gl2extchromium.h" 28 #include "gpu/GLES2/gl2extchromium.h"
30 #include "gpu/command_buffer/client/gles2_cmd_helper.h" 29 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
31 #include "gpu/command_buffer/client/gles2_implementation.h" 30 #include "gpu/command_buffer/client/gles2_implementation.h"
32 #include "gpu/command_buffer/client/gles2_lib.h" 31 #include "gpu/command_buffer/client/gles2_lib.h"
33 #include "gpu/command_buffer/client/gles2_trace_implementation.h" 32 #include "gpu/command_buffer/client/gles2_trace_implementation.h"
34 #include "gpu/command_buffer/client/transfer_buffer.h" 33 #include "gpu/command_buffer/client/transfer_buffer.h"
35 #include "gpu/command_buffer/common/constants.h" 34 #include "gpu/command_buffer/common/constants.h"
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 graphics_context_->OnErrorMessage(msg, id); 194 graphics_context_->OnErrorMessage(msg, id);
196 } 195 }
197 196
198 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits() 197 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits()
199 : command_buffer_size(kDefaultCommandBufferSize), 198 : command_buffer_size(kDefaultCommandBufferSize),
200 start_transfer_buffer_size(kDefaultStartTransferBufferSize), 199 start_transfer_buffer_size(kDefaultStartTransferBufferSize),
201 min_transfer_buffer_size(kDefaultMinTransferBufferSize), 200 min_transfer_buffer_size(kDefaultMinTransferBufferSize),
202 max_transfer_buffer_size(kDefaultMaxTransferBufferSize), 201 max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
203 mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {} 202 mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {}
204 203
204 WebGraphicsContext3DCommandBufferImpl::ShareGroup::ShareGroup() {
205 }
206
207 WebGraphicsContext3DCommandBufferImpl::ShareGroup::~ShareGroup() {
208 DCHECK(contexts_.empty());
209 }
210
205 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( 211 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl(
206 int surface_id, 212 int surface_id,
207 const GURL& active_url, 213 const GURL& active_url,
208 GpuChannelHost* host, 214 GpuChannelHost* host,
209 const Attributes& attributes, 215 const Attributes& attributes,
210 bool bind_generates_resources, 216 bool bind_generates_resources,
211 const SharedMemoryLimits& limits) 217 const SharedMemoryLimits& limits,
218 WebGraphicsContext3DCommandBufferImpl* share_context)
212 : initialize_failed_(false), 219 : initialize_failed_(false),
213 visible_(false), 220 visible_(false),
214 host_(host), 221 host_(host),
215 surface_id_(surface_id), 222 surface_id_(surface_id),
216 active_url_(active_url), 223 active_url_(active_url),
217 context_lost_callback_(0), 224 context_lost_callback_(0),
218 context_lost_reason_(GL_NO_ERROR), 225 context_lost_reason_(GL_NO_ERROR),
219 error_message_callback_(0), 226 error_message_callback_(0),
220 attributes_(attributes), 227 attributes_(attributes),
221 gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu 228 gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu
222 : gfx::PreferIntegratedGpu), 229 : gfx::PreferIntegratedGpu),
223 weak_ptr_factory_(this), 230 weak_ptr_factory_(this),
224 initialized_(false), 231 initialized_(false),
225 gl_(NULL), 232 gl_(NULL),
226 bind_generates_resources_(bind_generates_resources), 233 bind_generates_resources_(bind_generates_resources),
227 mem_limits_(limits), 234 mem_limits_(limits),
228 flush_id_(0) { 235 flush_id_(0) {
236 if (share_context) {
237 share_group_ = share_context->share_group_;
238 } else {
239 share_group_ = attributes_.shareResources ? NULL
240 : new ShareGroup();
241 }
229 } 242 }
230 243
231 WebGraphicsContext3DCommandBufferImpl:: 244 WebGraphicsContext3DCommandBufferImpl::
232 ~WebGraphicsContext3DCommandBufferImpl() { 245 ~WebGraphicsContext3DCommandBufferImpl() {
233 if (real_gl_) { 246 if (real_gl_) {
234 real_gl_->SetErrorMessageCallback(NULL); 247 real_gl_->SetErrorMessageCallback(NULL);
235 } 248 }
236 249
237 Destroy(); 250 Destroy();
238 } 251 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 attributes_.stencil = pvalues[2] > 0; 301 attributes_.stencil = pvalues[2] > 0;
289 attributes_.antialias = pvalues[3] > 0; 302 attributes_.antialias = pvalues[3] > 0;
290 } 303 }
291 304
292 visible_ = true; 305 visible_ = true;
293 initialized_ = true; 306 initialized_ = true;
294 return true; 307 return true;
295 } 308 }
296 309
297 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( 310 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer(
298 bool onscreen) { 311 bool onscreen, WebGraphicsContext3DCommandBufferImpl* share_context) {
299 if (!host_.get()) 312 if (!host_.get())
300 return false; 313 return false;
314
315 CommandBufferProxyImpl* share_group_command_buffer = NULL;
316
317 if (share_context) {
318 share_group_command_buffer = share_context->command_buffer_.get();
319 }
320
301 // We need to lock g_all_shared_contexts to ensure that the context we picked 321 // We need to lock g_all_shared_contexts to ensure that the context we picked
302 // for our share group isn't deleted. 322 // for our share group isn't deleted.
303 // (There's also a lock in our destructor.) 323 // (There's also a lock in our destructor.)
304 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 324 base::AutoLock lock(g_all_shared_contexts_lock.Get());
305 CommandBufferProxyImpl* share_group = NULL; 325
306 if (attributes_.shareResources) { 326 if (attributes_.shareResources && !share_group_command_buffer) {
307 ContextMap& all_contexts = g_all_shared_contexts.Get(); 327 ContextMap& all_contexts = g_all_shared_contexts.Get();
308 ContextMap::const_iterator it = all_contexts.find(host_.get()); 328 ContextMap::const_iterator it = all_contexts.find(host_.get());
309 if (it != all_contexts.end()) 329 if (it != all_contexts.end())
310 share_group = it->second->command_buffer_.get(); 330 share_group_command_buffer = it->second->command_buffer_.get();
311 } 331 }
312 332
313 std::vector<int32> attribs; 333 std::vector<int32> attribs;
314 attribs.push_back(ALPHA_SIZE); 334 attribs.push_back(ALPHA_SIZE);
315 attribs.push_back(attributes_.alpha ? 8 : 0); 335 attribs.push_back(attributes_.alpha ? 8 : 0);
316 attribs.push_back(DEPTH_SIZE); 336 attribs.push_back(DEPTH_SIZE);
317 attribs.push_back(attributes_.depth ? 24 : 0); 337 attribs.push_back(attributes_.depth ? 24 : 0);
318 attribs.push_back(STENCIL_SIZE); 338 attribs.push_back(STENCIL_SIZE);
319 attribs.push_back(attributes_.stencil ? 8 : 0); 339 attribs.push_back(attributes_.stencil ? 8 : 0);
320 attribs.push_back(SAMPLES); 340 attribs.push_back(SAMPLES);
321 attribs.push_back(attributes_.antialias ? 4 : 0); 341 attribs.push_back(attributes_.antialias ? 4 : 0);
322 attribs.push_back(SAMPLE_BUFFERS); 342 attribs.push_back(SAMPLE_BUFFERS);
323 attribs.push_back(attributes_.antialias ? 1 : 0); 343 attribs.push_back(attributes_.antialias ? 1 : 0);
324 attribs.push_back(FAIL_IF_MAJOR_PERF_CAVEAT); 344 attribs.push_back(FAIL_IF_MAJOR_PERF_CAVEAT);
325 attribs.push_back(attributes_.failIfMajorPerformanceCaveat ? 1 : 0); 345 attribs.push_back(attributes_.failIfMajorPerformanceCaveat ? 1 : 0);
326 attribs.push_back(NONE); 346 attribs.push_back(NONE);
327 347
328 // Create a proxy to a command buffer in the GPU process. 348 // Create a proxy to a command buffer in the GPU process.
329 if (onscreen) { 349 if (onscreen) {
330 command_buffer_.reset(host_->CreateViewCommandBuffer( 350 command_buffer_.reset(host_->CreateViewCommandBuffer(
331 surface_id_, 351 surface_id_,
332 share_group, 352 share_group_command_buffer,
333 attribs, 353 attribs,
334 active_url_, 354 active_url_,
335 gpu_preference_)); 355 gpu_preference_));
336 } else { 356 } else {
337 command_buffer_.reset(host_->CreateOffscreenCommandBuffer( 357 command_buffer_.reset(host_->CreateOffscreenCommandBuffer(
338 gfx::Size(1, 1), 358 gfx::Size(1, 1),
339 share_group, 359 share_group_command_buffer,
340 attribs, 360 attribs,
341 active_url_, 361 active_url_,
342 gpu_preference_)); 362 gpu_preference_));
343 } 363 }
344 364
345 if (!command_buffer_) 365 if (!command_buffer_)
346 return false; 366 return false;
347 367
348 // Initialize the command buffer. 368 // Initialize the command buffer.
349 return command_buffer_->Initialize(); 369 return command_buffer_->Initialize();
350 } 370 }
351 371
352 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( 372 bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) {
353 bool onscreen) {
354 // Ensure the gles2 library is initialized first in a thread safe way. 373 // Ensure the gles2 library is initialized first in a thread safe way.
355 g_gles2_initializer.Get(); 374 g_gles2_initializer.Get();
356 375
357 if (!command_buffer_ && 376 scoped_refptr<gpu::gles2::ShareGroup> gles2_share_group;
358 !InitializeCommandBuffer(onscreen)) { 377
359 return false; 378 if (!command_buffer_) {
379 scoped_ptr<base::AutoLock> share_group_lock;
380 WebGraphicsContext3DCommandBufferImpl* share_context = NULL;
381
382 if (share_group_) {
383 share_group_lock.reset(new base::AutoLock(share_group_->lock()));
384 share_context = share_group_->GetAnyContext();
385 }
386
387 if (!InitializeCommandBuffer(onscreen, share_context))
388 return false;
389
390 if (share_context)
391 gles2_share_group = share_context->GetImplementation()->share_group();
392
393 if (share_group_)
394 share_group_->AddContext(this);
360 } 395 }
piman 2013/12/12 23:56:39 So, there is a race risk here. After you release t
bajones 2013/12/13 00:17:20 I like it! I was thinking about replacing g_all_sh
361 396
362 // Create the GLES2 helper, which writes the command buffer protocol. 397 // Create the GLES2 helper, which writes the command buffer protocol.
363 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); 398 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get()));
364 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) 399 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size))
365 return false; 400 return false;
366 401
367 if (attributes_.noAutomaticFlushes) 402 if (attributes_.noAutomaticFlushes)
368 gles2_helper_->SetAutomaticFlushes(false); 403 gles2_helper_->SetAutomaticFlushes(false);
369 404
370 // Create a transfer buffer used to copy resources between the renderer 405 // Create a transfer buffer used to copy resources between the renderer
371 // process and the GPU process. 406 // process and the GPU process.
372 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); 407 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get()));
373 408
374 DCHECK(host_.get()); 409 DCHECK(host_.get());
375 scoped_ptr<base::AutoLock> lock; 410 scoped_ptr<base::AutoLock> lock;
376 scoped_refptr<gpu::gles2::ShareGroup> share_group; 411
377 if (attributes_.shareResources) { 412 if (attributes_.shareResources && !gles2_share_group) {
378 // Make sure two clients don't try to create a new ShareGroup 413 // Make sure two clients don't try to create a new ShareGroup
379 // simultaneously. 414 // simultaneously.
380 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); 415 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get()));
381 ContextMap& all_contexts = g_all_shared_contexts.Get(); 416 ContextMap& all_contexts = g_all_shared_contexts.Get();
382 ContextMap::const_iterator it = all_contexts.find(host_.get()); 417 ContextMap::const_iterator it = all_contexts.find(host_.get());
383 if (it != all_contexts.end()) { 418 if (it != all_contexts.end()) {
384 share_group = it->second->GetImplementation()->share_group(); 419 gles2_share_group = it->second->GetImplementation()->share_group();
385 DCHECK(share_group); 420 DCHECK(gles2_share_group);
386 } 421 }
387 } 422 }
388 423
389 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 424 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
390 bool free_command_buffer_when_invisible = 425 bool free_command_buffer_when_invisible =
391 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers); 426 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers);
392 427
393 // Create the object exposing the OpenGL API. 428 // Create the object exposing the OpenGL API.
394 real_gl_.reset(new gpu::gles2::GLES2Implementation( 429 real_gl_.reset(new gpu::gles2::GLES2Implementation(
395 gles2_helper_.get(), 430 gles2_helper_.get(),
396 share_group, 431 gles2_share_group,
397 transfer_buffer_.get(), 432 transfer_buffer_.get(),
398 bind_generates_resources_, 433 bind_generates_resources_,
399 free_command_buffer_when_invisible, 434 free_command_buffer_when_invisible,
400 command_buffer_.get())); 435 command_buffer_.get()));
401 gl_ = real_gl_.get(); 436 gl_ = real_gl_.get();
402 437
403 if (attributes_.shareResources) { 438 if (attributes_.shareResources) {
404 // Don't add ourselves to the list before others can get to our ShareGroup. 439 // Don't add ourselves to the list before others can get to our ShareGroup.
405 g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this)); 440 g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this));
406 lock.reset(); 441 lock.reset();
(...skipping 26 matching lines...) Expand all
433 return true; 468 return true;
434 } 469 }
435 470
436 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { 471 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() {
437 return flush_id_; 472 return flush_id_;
438 } 473 }
439 474
440 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int) 475 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int)
441 476
442 void WebGraphicsContext3DCommandBufferImpl::Destroy() { 477 void WebGraphicsContext3DCommandBufferImpl::Destroy() {
478 if (share_group_) {
479 share_group_->RemoveContext(this);
480 }
481
443 if (host_.get()) { 482 if (host_.get()) {
444 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 483 base::AutoLock lock(g_all_shared_contexts_lock.Get());
445 ContextMap& all_contexts = g_all_shared_contexts.Get(); 484 ContextMap& all_contexts = g_all_shared_contexts.Get();
446 ContextMap::iterator it = std::find( 485 ContextMap::iterator it = std::find(
447 all_contexts.begin(), 486 all_contexts.begin(),
448 all_contexts.end(), 487 all_contexts.end(),
449 std::pair<GpuChannelHost* const, 488 std::pair<GpuChannelHost* const,
450 WebGraphicsContext3DCommandBufferImpl*>(host_.get(), this)); 489 WebGraphicsContext3DCommandBufferImpl*>(host_.get(), this));
451 if (it != all_contexts.end()) 490 if (it != all_contexts.end())
452 all_contexts.erase(it); 491 all_contexts.erase(it);
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 1224 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
1186 return state.error == gpu::error::kLostContext; 1225 return state.error == gpu::error::kLostContext;
1187 } 1226 }
1188 1227
1189 // static 1228 // static
1190 WebGraphicsContext3DCommandBufferImpl* 1229 WebGraphicsContext3DCommandBufferImpl*
1191 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 1230 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
1192 GpuChannelHost* host, 1231 GpuChannelHost* host,
1193 const WebGraphicsContext3D::Attributes& attributes, 1232 const WebGraphicsContext3D::Attributes& attributes,
1194 const GURL& active_url, 1233 const GURL& active_url,
1195 const SharedMemoryLimits& limits) { 1234 const SharedMemoryLimits& limits,
1235 WebGraphicsContext3D* share_context) {
piman 2013/12/12 23:56:39 nit: pass a WebGraphicsContext3DCommandBufferImpl
1196 if (!host) 1236 if (!host)
1197 return NULL; 1237 return NULL;
1238
1239 WebGraphicsContext3DCommandBufferImpl* share_context_impl = NULL;
1240 if (share_context) {
1241 share_context_impl =
1242 static_cast<WebGraphicsContext3DCommandBufferImpl*>(share_context);
1243 }
1244
1198 return new WebGraphicsContext3DCommandBufferImpl(0, 1245 return new WebGraphicsContext3DCommandBufferImpl(0,
1199 active_url, 1246 active_url,
1200 host, 1247 host,
1201 attributes, 1248 attributes,
1202 false, 1249 false,
1203 limits); 1250 limits,
1251 share_context_impl);
1204 } 1252 }
1205 1253
1206 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, 1254 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM,
1207 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) 1255 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint)
1208 1256
1209 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, 1257 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
1210 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) 1258 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
1211 1259
1212 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() { 1260 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() {
1213 GLuint o; 1261 GLuint o;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 command_buffer_->GetLastState().context_lost_reason); 1411 command_buffer_->GetLastState().context_lost_reason);
1364 if (context_lost_callback_) { 1412 if (context_lost_callback_) {
1365 context_lost_callback_->onContextLost(); 1413 context_lost_callback_->onContextLost();
1366 } 1414 }
1367 1415
1368 DCHECK(host_.get()); 1416 DCHECK(host_.get());
1369 { 1417 {
1370 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 1418 base::AutoLock lock(g_all_shared_contexts_lock.Get());
1371 g_all_shared_contexts.Get().erase(host_.get()); 1419 g_all_shared_contexts.Get().erase(host_.get());
1372 } 1420 }
1421
1422 if (share_group_)
1423 share_group_->RemoveAllContexts();
1373 } 1424 }
1374 1425
1375 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( 1426 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage(
1376 const std::string& message, int id) { 1427 const std::string& message, int id) {
1377 if (error_message_callback_) { 1428 if (error_message_callback_) {
1378 blink::WebString str = blink::WebString::fromUTF8(message.c_str()); 1429 blink::WebString str = blink::WebString::fromUTF8(message.c_str());
1379 error_message_callback_->onErrorMessage(str, id); 1430 error_message_callback_->onErrorMessage(str, id);
1380 } 1431 }
1381 } 1432 }
1382 1433
1383 } // namespace content 1434 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698