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. 4 5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 6 7 #include "third_party/khronos/GLES2/gl2.h" 8 #ifndef GL_GLEXT_PROTOTYPES 9 #define GL_GLEXT_PROTOTYPES 1 10 #endif 11 #include "third_party/khronos/GLES2/gl2ext.h" 12 13 #include <algorithm> 14 #include <map> 15 16 #include "base/atomicops.h" 17 #include "base/bind.h" 18 #include "base/command_line.h" 19 #include "base/debug/trace_event.h" 20 #include "base/lazy_instance.h" 21 #include "base/logging.h" 22 #include "base/message_loop/message_loop.h" 23 #include "base/metrics/field_trial.h" 24 #include "base/metrics/histogram.h" 25 #include "base/synchronization/lock.h" 26 #include "content/common/gpu/client/gpu_channel_host.h" 27 #include "content/public/common/content_constants.h" 28 #include "content/public/common/content_switches.h" 29 #include "gpu/GLES2/gl2extchromium.h" 30 #include "gpu/command_buffer/client/gles2_cmd_helper.h" 31 #include "gpu/command_buffer/client/gles2_implementation.h" 32 #include "gpu/command_buffer/client/gles2_lib.h" 33 #include "gpu/command_buffer/client/gles2_trace_implementation.h" 34 #include "gpu/command_buffer/client/transfer_buffer.h" 35 #include "gpu/command_buffer/common/constants.h" 36 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 37 #include "gpu/command_buffer/common/mailbox.h" 38 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" 39 #include "third_party/skia/include/core/SkTypes.h" 40 41 namespace content { 42 43 namespace { 44 45 static base::LazyInstance<base::Lock>::Leaky 46 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER; 47 48 typedef std::multimap<GpuChannelHost*, WebGraphicsContext3DCommandBufferImpl*> 49 ContextMap; 50 static base::LazyInstance<ContextMap> g_all_shared_contexts = 51 LAZY_INSTANCE_INITIALIZER; 52 53 uint32_t GenFlushID() { 54 static base::subtle::Atomic32 flush_id = 0; 55 56 base::subtle::Atomic32 my_id = base::subtle::Barrier_AtomicIncrement( 57 &flush_id, 1); 58 return static_cast<uint32_t>(my_id); 59 } 60 61 // Singleton used to initialize and terminate the gles2 library. 62 class GLES2Initializer { 63 public: 64 GLES2Initializer() { 65 gles2::Initialize(); 66 } 67 68 ~GLES2Initializer() { 69 gles2::Terminate(); 70 } 71 72 private: 73 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); 74 }; 75 76 //////////////////////////////////////////////////////////////////////////////// 77 78 base::LazyInstance<GLES2Initializer> g_gles2_initializer = 79 LAZY_INSTANCE_INITIALIZER; 80 81 //////////////////////////////////////////////////////////////////////////////// 82 83 } // namespace anonymous 84 85 // Helper macros to reduce the amount of code. 86 87 #define DELEGATE_TO_GL(name, glname) \ 88 void WebGraphicsContext3DCommandBufferImpl::name() { \ 89 gl_->glname(); \ 90 } 91 92 #define DELEGATE_TO_GL_R(name, glname, rt) \ 93 rt WebGraphicsContext3DCommandBufferImpl::name() { \ 94 return gl_->glname(); \ 95 } 96 97 #define DELEGATE_TO_GL_1(name, glname, t1) \ 98 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \ 99 gl_->glname(a1); \ 100 } 101 102 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ 103 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \ 104 return gl_->glname(a1); \ 105 } 106 107 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ 108 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1) { \ 109 return gl_->glname(a1) ? true : false; \ 110 } 111 112 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ 113 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) { \ 114 gl_->glname(a1, a2); \ 115 } 116 117 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ 118 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2) { \ 119 return gl_->glname(a1, a2); \ 120 } 121 122 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ 123 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \ 124 gl_->glname(a1, a2, a3); \ 125 } 126 127 #define DELEGATE_TO_GL_3R(name, glname, t1, t2, t3, rt) \ 128 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \ 129 return gl_->glname(a1, a2, a3); \ 130 } 131 132 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ 133 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 134 t4 a4) { \ 135 gl_->glname(a1, a2, a3, a4); \ 136 } 137 138 #define DELEGATE_TO_GL_4R(name, glname, t1, t2, t3, t4, rt) \ 139 rt WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 140 t4 a4) { \ 141 return gl_->glname(a1, a2, a3, a4); \ 142 } 143 144 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ 145 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 146 t4 a4, t5 a5) { \ 147 gl_->glname(a1, a2, a3, a4, a5); \ 148 } 149 150 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ 151 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 152 t4 a4, t5 a5, t6 a6) { \ 153 gl_->glname(a1, a2, a3, a4, a5, a6); \ 154 } 155 156 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ 157 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 158 t4 a4, t5 a5, t6 a6, \ 159 t7 a7) { \ 160 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \ 161 } 162 163 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ 164 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 165 t4 a4, t5 a5, t6 a6, \ 166 t7 a7, t8 a8) { \ 167 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \ 168 } 169 170 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ 171 void WebGraphicsContext3DCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, \ 172 t4 a4, t5 a5, t6 a6, \ 173 t7 a7, t8 a8, t9 a9) { \ 174 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ 175 } 176 177 class WebGraphicsContext3DErrorMessageCallback 178 : public gpu::gles2::GLES2Implementation::ErrorMessageCallback { 179 public: 180 WebGraphicsContext3DErrorMessageCallback( 181 WebGraphicsContext3DCommandBufferImpl* context) 182 : graphics_context_(context) { 183 } 184 185 virtual void OnErrorMessage(const char* msg, int id) OVERRIDE; 186 187 private: 188 WebGraphicsContext3DCommandBufferImpl* graphics_context_; 189 190 DISALLOW_COPY_AND_ASSIGN(WebGraphicsContext3DErrorMessageCallback); 191 }; 192 193 void WebGraphicsContext3DErrorMessageCallback::OnErrorMessage( 194 const char* msg, int id) { 195 graphics_context_->OnErrorMessage(msg, id); 196 } 197 198 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits() 199 : command_buffer_size(kDefaultCommandBufferSize), 200 start_transfer_buffer_size(kDefaultStartTransferBufferSize), 201 min_transfer_buffer_size(kDefaultMinTransferBufferSize), 202 max_transfer_buffer_size(kDefaultMaxTransferBufferSize), 203 mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {} 204 205 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( 206 int surface_id, 207 const GURL& active_url, 208 GpuChannelHost* host, 209 const Attributes& attributes, 210 bool bind_generates_resources, 211 const SharedMemoryLimits& limits) 212 : initialize_failed_(false), 213 visible_(false), 214 host_(host), 215 surface_id_(surface_id), 216 active_url_(active_url), 217 context_lost_callback_(0), 218 context_lost_reason_(GL_NO_ERROR), 219 error_message_callback_(0), 220 attributes_(attributes), 221 gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu 222 : gfx::PreferIntegratedGpu), 223 weak_ptr_factory_(this), 224 initialized_(false), 225 gl_(NULL), 226 bind_generates_resources_(bind_generates_resources), 227 mem_limits_(limits), 228 flush_id_(0) { 229 } 230 231 WebGraphicsContext3DCommandBufferImpl:: 232 ~WebGraphicsContext3DCommandBufferImpl() { 233 if (real_gl_) { 234 real_gl_->SetErrorMessageCallback(NULL); 235 } 236 237 Destroy(); 238 } 239 240 bool WebGraphicsContext3DCommandBufferImpl::MaybeInitializeGL() { 241 if (initialized_) 242 return true; 243 244 if (initialize_failed_) 245 return false; 246 247 TRACE_EVENT0("gpu", "WebGfxCtx3DCmdBfrImpl::MaybeInitializeGL"); 248 249 if (!CreateContext(surface_id_ != 0)) { 250 Destroy(); 251 initialize_failed_ = true; 252 return false; 253 } 254 255 // TODO(twiz): This code is too fragile in that it assumes that only WebGL 256 // contexts will request noExtensions. 257 if (gl_ && attributes_.noExtensions) 258 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); 259 260 command_buffer_->SetChannelErrorCallback( 261 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost, 262 weak_ptr_factory_.GetWeakPtr())); 263 264 command_buffer_->SetOnConsoleMessageCallback( 265 base::Bind(&WebGraphicsContext3DCommandBufferImpl::OnErrorMessage, 266 weak_ptr_factory_.GetWeakPtr())); 267 268 client_error_message_callback_.reset( 269 new WebGraphicsContext3DErrorMessageCallback(this)); 270 real_gl_->SetErrorMessageCallback(client_error_message_callback_.get()); 271 272 // Set attributes_ from created offscreen context. 273 { 274 static const int pcount = 4; 275 static const GLenum pnames[pcount] = { 276 GL_ALPHA_BITS, 277 GL_DEPTH_BITS, 278 GL_STENCIL_BITS, 279 GL_SAMPLE_BUFFERS, 280 }; 281 GLint pvalues[pcount] = { 0, 0, 0, 0 }; 282 283 gl_->GetMultipleIntegervCHROMIUM(pnames, pcount, 284 pvalues, sizeof(pvalues)); 285 286 attributes_.alpha = pvalues[0] > 0; 287 attributes_.depth = pvalues[1] > 0; 288 attributes_.stencil = pvalues[2] > 0; 289 attributes_.antialias = pvalues[3] > 0; 290 } 291 292 visible_ = true; 293 initialized_ = true; 294 return true; 295 } 296 297 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( 298 bool onscreen) { 299 if (!host_.get()) 300 return false; 301 // We need to lock g_all_shared_contexts to ensure that the context we picked 302 // for our share group isn't deleted. 303 // (There's also a lock in our destructor.) 304 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 305 CommandBufferProxyImpl* share_group = NULL; 306 if (attributes_.shareResources) { 307 ContextMap& all_contexts = g_all_shared_contexts.Get(); 308 ContextMap::const_iterator it = all_contexts.find(host_.get()); 309 if (it != all_contexts.end()) 310 share_group = it->second->command_buffer_.get(); 311 } 312 313 std::vector<int32> attribs; 314 attribs.push_back(ALPHA_SIZE); 315 attribs.push_back(attributes_.alpha ? 8 : 0); 316 attribs.push_back(DEPTH_SIZE); 317 attribs.push_back(attributes_.depth ? 24 : 0); 318 attribs.push_back(STENCIL_SIZE); 319 attribs.push_back(attributes_.stencil ? 8 : 0); 320 attribs.push_back(SAMPLES); 321 attribs.push_back(attributes_.antialias ? 4 : 0); 322 attribs.push_back(SAMPLE_BUFFERS); 323 attribs.push_back(attributes_.antialias ? 1 : 0); 324 attribs.push_back(FAIL_IF_MAJOR_PERF_CAVEAT); 325 attribs.push_back(attributes_.failIfMajorPerformanceCaveat ? 1 : 0); 326 attribs.push_back(NONE); 327 328 // Create a proxy to a command buffer in the GPU process. 329 if (onscreen) { 330 command_buffer_.reset(host_->CreateViewCommandBuffer( 331 surface_id_, 332 share_group, 333 attribs, 334 active_url_, 335 gpu_preference_)); 336 } else { 337 command_buffer_.reset(host_->CreateOffscreenCommandBuffer( 338 gfx::Size(1, 1), 339 share_group, 340 attribs, 341 active_url_, 342 gpu_preference_)); 343 } 344 345 if (!command_buffer_) 346 return false; 347 348 // Initialize the command buffer. 349 return command_buffer_->Initialize(); 350 } 351 352 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( 353 bool onscreen) { 354 // Ensure the gles2 library is initialized first in a thread safe way. 355 g_gles2_initializer.Get(); 356 357 if (!command_buffer_ && 358 !InitializeCommandBuffer(onscreen)) { 359 return false; 360 } 361 362 // Create the GLES2 helper, which writes the command buffer protocol. 363 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); 364 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) 365 return false; 366 367 if (attributes_.noAutomaticFlushes) 368 gles2_helper_->SetAutomaticFlushes(false); 369 370 // Create a transfer buffer used to copy resources between the renderer 371 // process and the GPU process. 372 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); 373 374 DCHECK(host_.get()); 375 scoped_ptr<base::AutoLock> lock; 376 scoped_refptr<gpu::gles2::ShareGroup> share_group; 377 if (attributes_.shareResources) { 378 // Make sure two clients don't try to create a new ShareGroup 379 // simultaneously. 380 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); 381 ContextMap& all_contexts = g_all_shared_contexts.Get(); 382 ContextMap::const_iterator it = all_contexts.find(host_.get()); 383 if (it != all_contexts.end()) { 384 share_group = it->second->GetImplementation()->share_group(); 385 DCHECK(share_group); 386 } 387 } 388 389 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 390 bool free_command_buffer_when_invisible = 391 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers); 392 393 // Create the object exposing the OpenGL API. 394 real_gl_.reset(new gpu::gles2::GLES2Implementation( 395 gles2_helper_.get(), 396 share_group, 397 transfer_buffer_.get(), 398 bind_generates_resources_, 399 free_command_buffer_when_invisible, 400 command_buffer_.get())); 401 gl_ = real_gl_.get(); 402 403 if (attributes_.shareResources) { 404 // 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)); 406 lock.reset(); 407 } 408 409 if (!real_gl_->Initialize( 410 mem_limits_.start_transfer_buffer_size, 411 mem_limits_.min_transfer_buffer_size, 412 mem_limits_.max_transfer_buffer_size, 413 mem_limits_.mapped_memory_reclaim_limit)) { 414 return false; 415 } 416 417 if (CommandLine::ForCurrentProcess()->HasSwitch( 418 switches::kEnableGpuClientTracing)) { 419 trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_)); 420 gl_ = trace_gl_.get(); 421 } 422 423 return true; 424 } 425 426 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { 427 if (!MaybeInitializeGL()) 428 return false; 429 gles2::SetGLContext(gl_); 430 if (command_buffer_->GetLastError() != gpu::error::kNoError) 431 return false; 432 433 return true; 434 } 435 436 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { 437 return flush_id_; 438 } 439 440 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int) 441 442 void WebGraphicsContext3DCommandBufferImpl::Destroy() { 443 if (host_.get()) { 444 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 445 ContextMap& all_contexts = g_all_shared_contexts.Get(); 446 ContextMap::iterator it = std::find( 447 all_contexts.begin(), 448 all_contexts.end(), 449 std::pair<GpuChannelHost* const, 450 WebGraphicsContext3DCommandBufferImpl*>(host_.get(), this)); 451 if (it != all_contexts.end()) 452 all_contexts.erase(it); 453 } 454 455 if (gl_) { 456 // First flush the context to ensure that any pending frees of resources 457 // are completed. Otherwise, if this context is part of a share group, 458 // those resources might leak. Also, any remaining side effects of commands 459 // issued on this context might not be visible to other contexts in the 460 // share group. 461 gl_->Flush(); 462 gl_ = NULL; 463 } 464 465 trace_gl_.reset(); 466 real_gl_.reset(); 467 transfer_buffer_.reset(); 468 gles2_helper_.reset(); 469 real_gl_.reset(); 470 471 if (command_buffer_) { 472 if (host_.get()) 473 host_->DestroyCommandBuffer(command_buffer_.release()); 474 command_buffer_.reset(); 475 } 476 477 host_ = NULL; 478 } 479 480 // TODO(apatrick,piman): This should be renamed to something clearer. 481 int WebGraphicsContext3DCommandBufferImpl::GetGPUProcessID() { 482 return host_.get() ? host_->gpu_host_id() : 0; 483 } 484 485 gpu::ContextSupport* 486 WebGraphicsContext3DCommandBufferImpl::GetContextSupport() { 487 return real_gl_.get(); 488 } 489 490 void WebGraphicsContext3DCommandBufferImpl::prepareTexture() { 491 NOTREACHED(); 492 } 493 494 void WebGraphicsContext3DCommandBufferImpl::postSubBufferCHROMIUM( 495 int x, int y, int width, int height) { 496 NOTREACHED(); 497 } 498 499 DELEGATE_TO_GL_3(reshapeWithScaleFactor, ResizeCHROMIUM, int, int, float) 500 501 void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError( 502 WGC3Denum error) { 503 if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == 504 synthetic_errors_.end()) { 505 synthetic_errors_.push_back(error); 506 } 507 } 508 509 DELEGATE_TO_GL_4R(mapBufferSubDataCHROMIUM, MapBufferSubDataCHROMIUM, WGC3Denum, 510 WGC3Dintptr, WGC3Dsizeiptr, WGC3Denum, void*) 511 512 DELEGATE_TO_GL_1(unmapBufferSubDataCHROMIUM, UnmapBufferSubDataCHROMIUM, 513 const void*) 514 515 void* WebGraphicsContext3DCommandBufferImpl::mapTexSubImage2DCHROMIUM( 516 WGC3Denum target, 517 WGC3Dint level, 518 WGC3Dint xoffset, 519 WGC3Dint yoffset, 520 WGC3Dsizei width, 521 WGC3Dsizei height, 522 WGC3Denum format, 523 WGC3Denum type, 524 WGC3Denum access) { 525 return gl_->MapTexSubImage2DCHROMIUM( 526 target, level, xoffset, yoffset, width, height, format, type, access); 527 } 528 529 DELEGATE_TO_GL_1(unmapTexSubImage2DCHROMIUM, UnmapTexSubImage2DCHROMIUM, 530 const void*) 531 532 void WebGraphicsContext3DCommandBufferImpl::setVisibilityCHROMIUM( 533 bool visible) { 534 NOTREACHED(); 535 } 536 537 DELEGATE_TO_GL_3(discardFramebufferEXT, DiscardFramebufferEXT, WGC3Denum, 538 WGC3Dsizei, const WGC3Denum*) 539 540 void WebGraphicsContext3DCommandBufferImpl::copyTextureToParentTextureCHROMIUM( 541 WebGLId texture, WebGLId parentTexture) { 542 NOTIMPLEMENTED(); 543 } 544 545 DELEGATE_TO_GL(rateLimitOffscreenContextCHROMIUM, 546 RateLimitOffscreenContextCHROMIUM) 547 548 blink::WebString WebGraphicsContext3DCommandBufferImpl:: 549 getRequestableExtensionsCHROMIUM() { 550 return blink::WebString::fromUTF8( 551 gl_->GetRequestableExtensionsCHROMIUM()); 552 } 553 554 DELEGATE_TO_GL_1(requestExtensionCHROMIUM, RequestExtensionCHROMIUM, 555 const char*) 556 557 void WebGraphicsContext3DCommandBufferImpl::blitFramebufferCHROMIUM( 558 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, 559 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, 560 WGC3Dbitfield mask, WGC3Denum filter) { 561 gl_->BlitFramebufferCHROMIUM( 562 srcX0, srcY0, srcX1, srcY1, 563 dstX0, dstY0, dstX1, dstY1, 564 mask, filter); 565 } 566 567 DELEGATE_TO_GL_5(renderbufferStorageMultisampleCHROMIUM, 568 RenderbufferStorageMultisampleCHROMIUM, WGC3Denum, WGC3Dsizei, 569 WGC3Denum, WGC3Dsizei, WGC3Dsizei) 570 571 DELEGATE_TO_GL_1R(createStreamTextureCHROMIUM, CreateStreamTextureCHROMIUM, 572 WebGLId, WebGLId) 573 574 DELEGATE_TO_GL_1(destroyStreamTextureCHROMIUM, DestroyStreamTextureCHROMIUM, 575 WebGLId) 576 577 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum) 578 579 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) 580 581 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, 582 WGC3Duint, const WGC3Dchar*) 583 584 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId) 585 586 DELEGATE_TO_GL_2(bindFramebuffer, BindFramebuffer, WGC3Denum, WebGLId) 587 588 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId) 589 590 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId) 591 592 DELEGATE_TO_GL_4(blendColor, BlendColor, 593 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) 594 595 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) 596 597 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, 598 WGC3Denum, WGC3Denum) 599 600 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum) 601 602 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, 603 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) 604 605 DELEGATE_TO_GL_4(bufferData, BufferData, 606 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum) 607 608 DELEGATE_TO_GL_4(bufferSubData, BufferSubData, 609 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) 610 611 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus, 612 WGC3Denum, WGC3Denum) 613 614 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) 615 616 DELEGATE_TO_GL_4(clearColor, ClearColor, 617 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) 618 619 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf) 620 621 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) 622 623 DELEGATE_TO_GL_4(colorMask, ColorMask, 624 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) 625 626 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) 627 628 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D, 629 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, 630 WGC3Dsizei, WGC3Dsizei, const void*) 631 632 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D, 633 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, 634 WGC3Denum, WGC3Dsizei, const void*) 635 636 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D, 637 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, 638 WGC3Dsizei, WGC3Dsizei, WGC3Dint) 639 640 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D, 641 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, 642 WGC3Dsizei, WGC3Dsizei) 643 644 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) 645 646 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) 647 648 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) 649 650 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf) 651 652 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) 653 654 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) 655 656 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, 657 WGC3Duint) 658 659 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) 660 661 void WebGraphicsContext3DCommandBufferImpl::drawElements(WGC3Denum mode, 662 WGC3Dsizei count, 663 WGC3Denum type, 664 WGC3Dintptr offset) { 665 gl_->DrawElements( 666 mode, count, type, 667 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 668 } 669 670 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) 671 672 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, 673 WGC3Duint) 674 675 void WebGraphicsContext3DCommandBufferImpl::finish() { 676 flush_id_ = GenFlushID(); 677 gl_->Finish(); 678 } 679 680 void WebGraphicsContext3DCommandBufferImpl::flush() { 681 flush_id_ = GenFlushID(); 682 gl_->Flush(); 683 } 684 685 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer, 686 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) 687 688 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D, 689 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) 690 691 DELEGATE_TO_GL_6(framebufferTexture2DMultisampleEXT, 692 FramebufferTexture2DMultisampleEXT, 693 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint, WGC3Dsizei) 694 695 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) 696 697 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum) 698 699 bool WebGraphicsContext3DCommandBufferImpl::getActiveAttrib( 700 WebGLId program, WGC3Duint index, ActiveInfo& info) { 701 if (!program) { 702 synthesizeGLError(GL_INVALID_VALUE); 703 return false; 704 } 705 GLint max_name_length = -1; 706 gl_->GetProgramiv( 707 program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); 708 if (max_name_length < 0) 709 return false; 710 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]); 711 if (!name) { 712 synthesizeGLError(GL_OUT_OF_MEMORY); 713 return false; 714 } 715 GLsizei length = 0; 716 GLint size = -1; 717 GLenum type = 0; 718 gl_->GetActiveAttrib( 719 program, index, max_name_length, &length, &size, &type, name.get()); 720 if (size < 0) { 721 return false; 722 } 723 info.name = blink::WebString::fromUTF8(name.get(), length); 724 info.type = type; 725 info.size = size; 726 return true; 727 } 728 729 bool WebGraphicsContext3DCommandBufferImpl::getActiveUniform( 730 WebGLId program, WGC3Duint index, ActiveInfo& info) { 731 GLint max_name_length = -1; 732 gl_->GetProgramiv( 733 program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); 734 if (max_name_length < 0) 735 return false; 736 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]); 737 if (!name) { 738 synthesizeGLError(GL_OUT_OF_MEMORY); 739 return false; 740 } 741 GLsizei length = 0; 742 GLint size = -1; 743 GLenum type = 0; 744 gl_->GetActiveUniform( 745 program, index, max_name_length, &length, &size, &type, name.get()); 746 if (size < 0) { 747 return false; 748 } 749 info.name = blink::WebString::fromUTF8(name.get(), length); 750 info.type = type; 751 info.size = size; 752 return true; 753 } 754 755 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, 756 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*) 757 758 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, 759 WebGLId, const WGC3Dchar*, WGC3Dint) 760 761 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*) 762 763 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, 764 WGC3Denum, WGC3Denum, WGC3Dint*) 765 766 blink::WebGraphicsContext3D::Attributes 767 WebGraphicsContext3DCommandBufferImpl::getContextAttributes() { 768 return attributes_; 769 } 770 771 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getError() { 772 if (!synthetic_errors_.empty()) { 773 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); 774 WGC3Denum err = *iter; 775 synthetic_errors_.erase(iter); 776 return err; 777 } 778 779 return gl_->GetError(); 780 } 781 782 bool WebGraphicsContext3DCommandBufferImpl::isContextLost() { 783 return initialize_failed_ || 784 (command_buffer_ && IsCommandBufferContextLost()) || 785 context_lost_reason_ != GL_NO_ERROR; 786 } 787 788 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) 789 790 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, 791 GetFramebufferAttachmentParameteriv, 792 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) 793 794 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) 795 796 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) 797 798 blink::WebString WebGraphicsContext3DCommandBufferImpl::getProgramInfoLog( 799 WebGLId program) { 800 GLint logLength = 0; 801 gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 802 if (!logLength) 803 return blink::WebString(); 804 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 805 if (!log) 806 return blink::WebString(); 807 GLsizei returnedLogLength = 0; 808 gl_->GetProgramInfoLog( 809 program, logLength, &returnedLogLength, log.get()); 810 DCHECK_EQ(logLength, returnedLogLength + 1); 811 blink::WebString res = 812 blink::WebString::fromUTF8(log.get(), returnedLogLength); 813 return res; 814 } 815 816 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv, 817 WGC3Denum, WGC3Denum, WGC3Dint*) 818 819 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*) 820 821 blink::WebString WebGraphicsContext3DCommandBufferImpl::getShaderInfoLog( 822 WebGLId shader) { 823 GLint logLength = 0; 824 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 825 if (!logLength) 826 return blink::WebString(); 827 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 828 if (!log) 829 return blink::WebString(); 830 GLsizei returnedLogLength = 0; 831 gl_->GetShaderInfoLog( 832 shader, logLength, &returnedLogLength, log.get()); 833 DCHECK_EQ(logLength, returnedLogLength + 1); 834 blink::WebString res = 835 blink::WebString::fromUTF8(log.get(), returnedLogLength); 836 return res; 837 } 838 839 DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat, 840 WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*) 841 842 blink::WebString WebGraphicsContext3DCommandBufferImpl::getShaderSource( 843 WebGLId shader) { 844 GLint logLength = 0; 845 gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); 846 if (!logLength) 847 return blink::WebString(); 848 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 849 if (!log) 850 return blink::WebString(); 851 GLsizei returnedLogLength = 0; 852 gl_->GetShaderSource( 853 shader, logLength, &returnedLogLength, log.get()); 854 if (!returnedLogLength) 855 return blink::WebString(); 856 DCHECK_EQ(logLength, returnedLogLength + 1); 857 blink::WebString res = 858 blink::WebString::fromUTF8(log.get(), returnedLogLength); 859 return res; 860 } 861 862 blink::WebString WebGraphicsContext3DCommandBufferImpl:: 863 getTranslatedShaderSourceANGLE(WebGLId shader) { 864 GLint logLength = 0; 865 gl_->GetShaderiv( 866 shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength); 867 if (!logLength) 868 return blink::WebString(); 869 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 870 if (!log) 871 return blink::WebString(); 872 GLsizei returnedLogLength = 0; 873 gl_->GetTranslatedShaderSourceANGLE( 874 shader, logLength, &returnedLogLength, log.get()); 875 if (!returnedLogLength) 876 return blink::WebString(); 877 DCHECK_EQ(logLength, returnedLogLength + 1); 878 blink::WebString res = 879 blink::WebString::fromUTF8(log.get(), returnedLogLength); 880 return res; 881 } 882 883 blink::WebString WebGraphicsContext3DCommandBufferImpl::getString( 884 WGC3Denum name) { 885 return blink::WebString::fromUTF8( 886 reinterpret_cast<const char*>(gl_->GetString(name))); 887 } 888 889 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, 890 WGC3Denum, WGC3Denum, WGC3Dfloat*) 891 892 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, 893 WGC3Denum, WGC3Denum, WGC3Dint*) 894 895 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*) 896 897 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*) 898 899 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, 900 WebGLId, const WGC3Dchar*, WGC3Dint) 901 902 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, 903 WGC3Duint, WGC3Denum, WGC3Dfloat*) 904 905 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, 906 WGC3Duint, WGC3Denum, WGC3Dint*) 907 908 WGC3Dsizeiptr WebGraphicsContext3DCommandBufferImpl::getVertexAttribOffset( 909 WGC3Duint index, WGC3Denum pname) { 910 GLvoid* value = NULL; 911 // NOTE: If pname is ever a value that returns more then 1 element 912 // this will corrupt memory. 913 gl_->GetVertexAttribPointerv(index, pname, &value); 914 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value)); 915 } 916 917 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) 918 919 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) 920 921 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) 922 923 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean) 924 925 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) 926 927 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean) 928 929 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) 930 931 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean) 932 933 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat) 934 935 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) 936 937 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) 938 939 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) 940 941 DELEGATE_TO_GL_7(readPixels, ReadPixels, 942 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum, 943 WGC3Denum, void*) 944 945 void WebGraphicsContext3DCommandBufferImpl::releaseShaderCompiler() { 946 } 947 948 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage, 949 WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei) 950 951 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean) 952 953 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) 954 955 void WebGraphicsContext3DCommandBufferImpl::shaderSource( 956 WebGLId shader, const WGC3Dchar* string) { 957 GLint length = strlen(string); 958 gl_->ShaderSource(shader, 1, &string, &length); 959 } 960 961 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) 962 963 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, 964 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint) 965 966 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint) 967 968 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, 969 WGC3Denum, WGC3Duint) 970 971 DELEGATE_TO_GL_3(stencilOp, StencilOp, 972 WGC3Denum, WGC3Denum, WGC3Denum) 973 974 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, 975 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) 976 977 DELEGATE_TO_GL_9(texImage2D, TexImage2D, 978 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, 979 WGC3Dint, WGC3Denum, WGC3Denum, const void*) 980 981 DELEGATE_TO_GL_3(texParameterf, TexParameterf, 982 WGC3Denum, WGC3Denum, WGC3Dfloat); 983 984 static const unsigned int kTextureWrapR = 0x8072; 985 986 void WebGraphicsContext3DCommandBufferImpl::texParameteri( 987 WGC3Denum target, WGC3Denum pname, WGC3Dint param) { 988 // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in 989 // GraphicsContext3D.cpp is strictly necessary to avoid seams at the 990 // edge of cube maps, and, if it is, push it into the GLES2 service 991 // side code. 992 if (pname == kTextureWrapR) { 993 return; 994 } 995 gl_->TexParameteri(target, pname, param); 996 } 997 998 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, 999 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, 1000 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) 1001 1002 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) 1003 1004 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei, 1005 const WGC3Dfloat*) 1006 1007 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) 1008 1009 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1010 1011 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) 1012 1013 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei, 1014 const WGC3Dfloat*) 1015 1016 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) 1017 1018 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1019 1020 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint, 1021 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1022 1023 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei, 1024 const WGC3Dfloat*) 1025 1026 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) 1027 1028 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1029 1030 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, 1031 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1032 1033 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei, 1034 const WGC3Dfloat*) 1035 1036 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, 1037 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) 1038 1039 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1040 1041 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, 1042 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1043 1044 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, 1045 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1046 1047 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, 1048 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1049 1050 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) 1051 1052 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) 1053 1054 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) 1055 1056 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, 1057 const WGC3Dfloat*) 1058 1059 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint, 1060 WGC3Dfloat, WGC3Dfloat) 1061 1062 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, 1063 const WGC3Dfloat*) 1064 1065 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint, 1066 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1067 1068 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, 1069 const WGC3Dfloat*) 1070 1071 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint, 1072 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1073 1074 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, 1075 const WGC3Dfloat*) 1076 1077 void WebGraphicsContext3DCommandBufferImpl::vertexAttribPointer( 1078 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, 1079 WGC3Dsizei stride, WGC3Dintptr offset) { 1080 gl_->VertexAttribPointer( 1081 index, size, type, normalized, stride, 1082 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 1083 } 1084 1085 DELEGATE_TO_GL_4(viewport, Viewport, 1086 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) 1087 1088 DELEGATE_TO_GL_2(genBuffers, GenBuffers, WGC3Dsizei, WebGLId*); 1089 1090 DELEGATE_TO_GL_2(genFramebuffers, GenFramebuffers, WGC3Dsizei, WebGLId*); 1091 1092 DELEGATE_TO_GL_2(genRenderbuffers, GenRenderbuffers, WGC3Dsizei, WebGLId*); 1093 1094 DELEGATE_TO_GL_2(genTextures, GenTextures, WGC3Dsizei, WebGLId*); 1095 1096 DELEGATE_TO_GL_2(deleteBuffers, DeleteBuffers, WGC3Dsizei, WebGLId*); 1097 1098 DELEGATE_TO_GL_2(deleteFramebuffers, DeleteFramebuffers, WGC3Dsizei, WebGLId*); 1099 1100 DELEGATE_TO_GL_2(deleteRenderbuffers, DeleteRenderbuffers, WGC3Dsizei, 1101 WebGLId*); 1102 1103 DELEGATE_TO_GL_2(deleteTextures, DeleteTextures, WGC3Dsizei, WebGLId*); 1104 1105 WebGLId WebGraphicsContext3DCommandBufferImpl::createBuffer() { 1106 GLuint o; 1107 gl_->GenBuffers(1, &o); 1108 return o; 1109 } 1110 1111 WebGLId WebGraphicsContext3DCommandBufferImpl::createFramebuffer() { 1112 GLuint o = 0; 1113 gl_->GenFramebuffers(1, &o); 1114 return o; 1115 } 1116 1117 WebGLId WebGraphicsContext3DCommandBufferImpl::createRenderbuffer() { 1118 GLuint o; 1119 gl_->GenRenderbuffers(1, &o); 1120 return o; 1121 } 1122 1123 WebGLId WebGraphicsContext3DCommandBufferImpl::createTexture() { 1124 GLuint o; 1125 gl_->GenTextures(1, &o); 1126 return o; 1127 } 1128 1129 void WebGraphicsContext3DCommandBufferImpl::deleteBuffer(WebGLId buffer) { 1130 gl_->DeleteBuffers(1, &buffer); 1131 } 1132 1133 void WebGraphicsContext3DCommandBufferImpl::deleteFramebuffer( 1134 WebGLId framebuffer) { 1135 gl_->DeleteFramebuffers(1, &framebuffer); 1136 } 1137 1138 void WebGraphicsContext3DCommandBufferImpl::deleteRenderbuffer( 1139 WebGLId renderbuffer) { 1140 gl_->DeleteRenderbuffers(1, &renderbuffer); 1141 } 1142 1143 void WebGraphicsContext3DCommandBufferImpl::deleteTexture(WebGLId texture) { 1144 gl_->DeleteTextures(1, &texture); 1145 } 1146 1147 DELEGATE_TO_GL_R(createProgram, CreateProgram, WebGLId) 1148 1149 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId) 1150 1151 DELEGATE_TO_GL_1(deleteProgram, DeleteProgram, WebGLId) 1152 1153 DELEGATE_TO_GL_1(deleteShader, DeleteShader, WebGLId) 1154 1155 void WebGraphicsContext3DCommandBufferImpl::setErrorMessageCallback( 1156 WebGraphicsContext3D::WebGraphicsErrorMessageCallback* cb) { 1157 error_message_callback_ = cb; 1158 } 1159 1160 void WebGraphicsContext3DCommandBufferImpl::setContextLostCallback( 1161 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) { 1162 context_lost_callback_ = cb; 1163 } 1164 1165 WGC3Denum WebGraphicsContext3DCommandBufferImpl::getGraphicsResetStatusARB() { 1166 if (IsCommandBufferContextLost() && 1167 context_lost_reason_ == GL_NO_ERROR) { 1168 return GL_UNKNOWN_CONTEXT_RESET_ARB; 1169 } 1170 1171 return context_lost_reason_; 1172 } 1173 1174 bool WebGraphicsContext3DCommandBufferImpl::IsCommandBufferContextLost() { 1175 // If the channel shut down unexpectedly, let that supersede the 1176 // command buffer's state. 1177 if (host_.get() && host_->IsLost()) 1178 return true; 1179 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 1180 return state.error == gpu::error::kLostContext; 1181 } 1182 1183 // static 1184 WebGraphicsContext3DCommandBufferImpl* 1185 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 1186 GpuChannelHost* host, 1187 const WebGraphicsContext3D::Attributes& attributes, 1188 const GURL& active_url, 1189 const SharedMemoryLimits& limits) { 1190 if (!host) 1191 return NULL; 1192 return new WebGraphicsContext3DCommandBufferImpl(0, 1193 active_url, 1194 host, 1195 attributes, 1196 false, 1197 limits); 1198 } 1199 1200 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, 1201 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) 1202 1203 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, 1204 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) 1205 1206 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() { 1207 GLuint o; 1208 gl_->GenQueriesEXT(1, &o); 1209 return o; 1210 } 1211 1212 void WebGraphicsContext3DCommandBufferImpl::deleteQueryEXT( 1213 WebGLId query) { 1214 gl_->DeleteQueriesEXT(1, &query); 1215 } 1216 1217 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryEXT, WebGLId, WGC3Dboolean) 1218 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryEXT, WGC3Denum, WebGLId) 1219 DELEGATE_TO_GL_1(endQueryEXT, EndQueryEXT, WGC3Denum) 1220 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*) 1221 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT, 1222 WebGLId, WGC3Denum, WGC3Duint*) 1223 1224 DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum, 1225 WebGLId, WebGLId, WGC3Dint, WGC3Denum, WGC3Denum); 1226 1227 DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM, 1228 WebGLId, WGC3Dint, const WGC3Dchar*) 1229 1230 void WebGraphicsContext3DCommandBufferImpl::shallowFlushCHROMIUM() { 1231 flush_id_ = GenFlushID(); 1232 gl_->ShallowFlushCHROMIUM(); 1233 } 1234 1235 void WebGraphicsContext3DCommandBufferImpl::shallowFinishCHROMIUM() { 1236 flush_id_ = GenFlushID(); 1237 gl_->ShallowFinishCHROMIUM(); 1238 } 1239 1240 DELEGATE_TO_GL_1(waitSyncPoint, WaitSyncPointCHROMIUM, GLuint) 1241 1242 void WebGraphicsContext3DCommandBufferImpl::loseContextCHROMIUM( 1243 WGC3Denum current, WGC3Denum other) { 1244 gl_->LoseContextCHROMIUM(current, other); 1245 gl_->Flush(); 1246 } 1247 1248 DELEGATE_TO_GL_1(genMailboxCHROMIUM, GenMailboxCHROMIUM, WGC3Dbyte*) 1249 DELEGATE_TO_GL_2(produceTextureCHROMIUM, ProduceTextureCHROMIUM, 1250 WGC3Denum, const WGC3Dbyte*) 1251 DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM, 1252 WGC3Denum, const WGC3Dbyte*) 1253 1254 void WebGraphicsContext3DCommandBufferImpl::insertEventMarkerEXT( 1255 const WGC3Dchar* marker) { 1256 gl_->InsertEventMarkerEXT(0, marker); 1257 } 1258 1259 void WebGraphicsContext3DCommandBufferImpl::pushGroupMarkerEXT( 1260 const WGC3Dchar* marker) { 1261 gl_->PushGroupMarkerEXT(0, marker); 1262 } 1263 1264 DELEGATE_TO_GL(popGroupMarkerEXT, PopGroupMarkerEXT); 1265 1266 WebGLId WebGraphicsContext3DCommandBufferImpl::createVertexArrayOES() { 1267 GLuint array; 1268 gl_->GenVertexArraysOES(1, &array); 1269 return array; 1270 } 1271 1272 void WebGraphicsContext3DCommandBufferImpl::deleteVertexArrayOES( 1273 WebGLId array) { 1274 gl_->DeleteVertexArraysOES(1, &array); 1275 } 1276 1277 DELEGATE_TO_GL_1R(isVertexArrayOES, IsVertexArrayOES, WebGLId, WGC3Dboolean) 1278 DELEGATE_TO_GL_1(bindVertexArrayOES, BindVertexArrayOES, WebGLId) 1279 1280 DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM, 1281 WGC3Denum, WGC3Dint) 1282 DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM, 1283 WGC3Denum, WGC3Dint) 1284 1285 DELEGATE_TO_GL_2R(mapBufferCHROMIUM, MapBufferCHROMIUM, WGC3Denum, WGC3Denum, 1286 void*) 1287 DELEGATE_TO_GL_1R(unmapBufferCHROMIUM, UnmapBufferCHROMIUM, WGC3Denum, 1288 WGC3Dboolean) 1289 1290 DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, WGC3Denum, 1291 WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint, 1292 WGC3Denum, WGC3Denum, const void*) 1293 DELEGATE_TO_GL_9(asyncTexSubImage2DCHROMIUM, AsyncTexSubImage2DCHROMIUM, 1294 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, 1295 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) 1296 1297 DELEGATE_TO_GL_1(waitAsyncTexImage2DCHROMIUM, WaitAsyncTexImage2DCHROMIUM, 1298 WGC3Denum) 1299 1300 DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, WGC3Dsizei, const WGC3Denum*) 1301 1302 DELEGATE_TO_GL_4(drawArraysInstancedANGLE, DrawArraysInstancedANGLE, WGC3Denum, 1303 WGC3Dint, WGC3Dsizei, WGC3Dsizei) 1304 1305 void WebGraphicsContext3DCommandBufferImpl::drawElementsInstancedANGLE( 1306 WGC3Denum mode, 1307 WGC3Dsizei count, 1308 WGC3Denum type, 1309 WGC3Dintptr offset, 1310 WGC3Dsizei primcount) { 1311 gl_->DrawElementsInstancedANGLE( 1312 mode, count, type, 1313 reinterpret_cast<void*>(static_cast<intptr_t>(offset)), primcount); 1314 } 1315 1316 DELEGATE_TO_GL_2(vertexAttribDivisorANGLE, VertexAttribDivisorANGLE, WGC3Duint, 1317 WGC3Duint) 1318 1319 DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM, 1320 WGC3Dsizei, WGC3Dsizei, WGC3Denum, 1321 WGC3Duint); 1322 1323 DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint); 1324 1325 DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM, 1326 WGC3Duint, WGC3Denum, GLint*); 1327 1328 DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM, 1329 WGC3Duint, WGC3Denum, void*); 1330 1331 DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint); 1332 1333 GrGLInterface* WebGraphicsContext3DCommandBufferImpl::createGrGLInterface() { 1334 return skia_bindings::CreateCommandBufferSkiaGLBinding(); 1335 } 1336 1337 namespace { 1338 1339 WGC3Denum convertReason(gpu::error::ContextLostReason reason) { 1340 switch (reason) { 1341 case gpu::error::kGuilty: 1342 return GL_GUILTY_CONTEXT_RESET_ARB; 1343 case gpu::error::kInnocent: 1344 return GL_INNOCENT_CONTEXT_RESET_ARB; 1345 case gpu::error::kUnknown: 1346 return GL_UNKNOWN_CONTEXT_RESET_ARB; 1347 } 1348 1349 NOTREACHED(); 1350 return GL_UNKNOWN_CONTEXT_RESET_ARB; 1351 } 1352 1353 } // anonymous namespace 1354 1355 void WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost() { 1356 context_lost_reason_ = convertReason( 1357 command_buffer_->GetLastState().context_lost_reason); 1358 if (context_lost_callback_) { 1359 context_lost_callback_->onContextLost(); 1360 } 1361 1362 DCHECK(host_.get()); 1363 { 1364 base::AutoLock lock(g_all_shared_contexts_lock.Get()); 1365 g_all_shared_contexts.Get().erase(host_.get()); 1366 } 1367 } 1368 1369 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( 1370 const std::string& message, int id) { 1371 if (error_message_callback_) { 1372 blink::WebString str = blink::WebString::fromUTF8(message.c_str()); 1373 error_message_callback_->onErrorMessage(str, id); 1374 } 1375 } 1376 1377 } // namespace content 1378