webgraphicscontext3d_in_process_command_buffer_impl.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" 6 7#include <GLES2/gl2.h> 8#ifndef GL_GLEXT_PROTOTYPES 9#define GL_GLEXT_PROTOTYPES 1 10#endif 11#include <GLES2/gl2ext.h> 12#include <GLES2/gl2extchromium.h> 13 14#include <algorithm> 15#include <set> 16#include <string> 17 18#include "base/bind.h" 19#include "base/bind_helpers.h" 20#include "base/callback.h" 21#include "base/command_line.h" 22#include "base/lazy_instance.h" 23#include "base/logging.h" 24#include "base/memory/singleton.h" 25#include "base/message_loop.h" 26#include "base/metrics/histogram.h" 27#include "base/synchronization/lock.h" 28#include "gpu/command_buffer/client/gles2_implementation.h" 29#include "gpu/command_buffer/client/gles2_lib.h" 30#include "gpu/command_buffer/client/image_factory.h" 31#include "gpu/command_buffer/client/transfer_buffer.h" 32#include "gpu/command_buffer/common/constants.h" 33#include "gpu/command_buffer/service/command_buffer_service.h" 34#include "gpu/command_buffer/service/context_group.h" 35#include "gpu/command_buffer/service/gl_context_virtual.h" 36#include "gpu/command_buffer/service/gpu_scheduler.h" 37#include "gpu/command_buffer/service/image_manager.h" 38#include "gpu/command_buffer/service/transfer_buffer_manager.h" 39#include "ui/gl/gl_context.h" 40#include "ui/gl/gl_image.h" 41#include "ui/gl/gl_share_group.h" 42#include "ui/gl/gl_surface.h" 43#include "webkit/common/gpu/gl_bindings_skia_cmd_buffer.h" 44 45using gpu::Buffer; 46using gpu::CommandBuffer; 47using gpu::CommandBufferService; 48using gpu::gles2::GLES2CmdHelper; 49using gpu::gles2::GLES2Implementation; 50using gpu::gles2::ImageFactory; 51using gpu::gles2::ImageManager; 52using gpu::GpuMemoryBuffer; 53using gpu::GpuScheduler; 54using gpu::TransferBuffer; 55using gpu::TransferBufferManager; 56using gpu::TransferBufferManagerInterface; 57 58namespace webkit { 59namespace gpu { 60namespace { 61class ImageFactoryInProcess; 62} 63 64class GLInProcessContext { 65 public: 66 // These are the same error codes as used by EGL. 67 enum Error { 68 SUCCESS = 0x3000, 69 NOT_INITIALIZED = 0x3001, 70 BAD_ATTRIBUTE = 0x3004, 71 BAD_GLContext = 0x3006, 72 CONTEXT_LOST = 0x300E 73 }; 74 75 // GLInProcessContext configuration attributes. These are the same as used by 76 // EGL. Attributes are matched using a closest fit algorithm. 77 enum Attribute { 78 ALPHA_SIZE = 0x3021, 79 BLUE_SIZE = 0x3022, 80 GREEN_SIZE = 0x3023, 81 RED_SIZE = 0x3024, 82 DEPTH_SIZE = 0x3025, 83 STENCIL_SIZE = 0x3026, 84 SAMPLES = 0x3031, 85 SAMPLE_BUFFERS = 0x3032, 86 NONE = 0x3038 // Attrib list = terminator 87 }; 88 89 // Initialize the library. This must have completed before any other 90 // functions are invoked. 91 static bool Initialize(); 92 93 // Terminate the library. This must be called after any other functions 94 // have completed. 95 static bool Terminate(); 96 97 ~GLInProcessContext(); 98 99 void PumpCommands(); 100 bool GetBufferChanged(int32 transfer_buffer_id); 101 102 // Create a GLInProcessContext, if |is_offscreen| is true, renders to an 103 // offscreen context. |attrib_list| must be NULL or a NONE-terminated list 104 // of attribute/value pairs. 105 static GLInProcessContext* CreateContext( 106 bool is_offscreen, 107 gfx::AcceleratedWidget window, 108 const gfx::Size& size, 109 bool share_resources, 110 const char* allowed_extensions, 111 const int32* attrib_list, 112 gfx::GpuPreference gpu_preference); 113 114 // For an offscreen frame buffer GLInProcessContext, return the texture ID 115 // with respect to the parent GLInProcessContext. Returns zero if 116 // GLInProcessContext does not have a parent. 117 uint32 GetParentTextureId(); 118 119 // Create a new texture in the parent's GLInProcessContext. Returns zero if 120 // GLInProcessContext does not have a parent. 121 uint32 CreateParentTexture(const gfx::Size& size); 122 123 // Deletes a texture in the parent's GLInProcessContext. 124 void DeleteParentTexture(uint32 texture); 125 126 void SetContextLostCallback(const base::Closure& callback); 127 128 // Set the current GLInProcessContext for the calling thread. 129 static bool MakeCurrent(GLInProcessContext* context); 130 131 // For a view GLInProcessContext, display everything that has been rendered 132 // since the last call. For an offscreen GLInProcessContext, resolve 133 // everything that has been rendered since the last call to a copy that can be 134 // accessed by the parent GLInProcessContext. 135 bool SwapBuffers(); 136 137 // TODO(gman): Remove this 138 void DisableShaderTranslation(); 139 140 // Allows direct access to the GLES2 implementation so a GLInProcessContext 141 // can be used without making it current. 142 GLES2Implementation* GetImplementation(); 143 144 // Return the current error. 145 Error GetError(); 146 147 // Return true if GPU process reported GLInProcessContext lost or there was a 148 // problem communicating with the GPU process. 149 bool IsCommandBufferContextLost(); 150 151 void LoseContext(uint32 current, uint32 other); 152 153 void SetSignalSyncPointCallback( 154 scoped_ptr< 155 WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback); 156 157 CommandBufferService* GetCommandBufferService(); 158 159 ::gpu::gles2::GLES2Decoder* GetDecoder(); 160 161 void OnResizeView(gfx::Size size, float scale_factor); 162 163 private: 164 explicit GLInProcessContext(bool share_resources); 165 166 bool Initialize(bool is_offscreen, 167 gfx::AcceleratedWidget window, 168 const gfx::Size& size, 169 const char* allowed_extensions, 170 const int32* attrib_list, 171 gfx::GpuPreference gpu_preference); 172 void Destroy(); 173 174 void OnContextLost(); 175 176 ::gpu::gles2::ImageManager* GetImageManager(); 177 178 scoped_refptr<ImageFactoryInProcess> GetImageFactory(); 179 180 base::Closure context_lost_callback_; 181 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; 182 scoped_ptr<CommandBufferService> command_buffer_; 183 scoped_ptr< ::gpu::GpuScheduler> gpu_scheduler_; 184 scoped_ptr< ::gpu::gles2::GLES2Decoder> decoder_; 185 scoped_refptr<gfx::GLContext> context_; 186 scoped_refptr<gfx::GLSurface> surface_; 187 scoped_ptr<GLES2CmdHelper> gles2_helper_; 188 scoped_ptr<TransferBuffer> transfer_buffer_; 189 scoped_ptr<GLES2Implementation> gles2_implementation_; 190 scoped_refptr<ImageFactoryInProcess> image_factory_; 191 scoped_ptr<WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> 192 signal_sync_point_callback_; 193 Error last_error_; 194 bool share_resources_; 195 bool context_lost_; 196 197 DISALLOW_COPY_AND_ASSIGN(GLInProcessContext); 198}; 199 200namespace { 201 202const int32 kCommandBufferSize = 1024 * 1024; 203// TODO(kbr): make the transfer buffer size configurable via context 204// creation attributes. 205const size_t kStartTransferBufferSize = 4 * 1024 * 1024; 206const size_t kMinTransferBufferSize = 1 * 256 * 1024; 207const size_t kMaxTransferBufferSize = 16 * 1024 * 1024; 208 209// Singleton used to initialize and terminate the gles2 library. 210class GLES2Initializer { 211 public: 212 GLES2Initializer() { 213 gles2::Initialize(); 214 } 215 216 ~GLES2Initializer() { 217 gles2::Terminate(); 218 } 219 220 private: 221 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); 222}; 223 224//////////////////////////////////////////////////////////////////////////////// 225 226static base::LazyInstance<GLES2Initializer> g_gles2_initializer = 227 LAZY_INSTANCE_INITIALIZER; 228 229} // namespace anonymous 230 231GLInProcessContext::~GLInProcessContext() { 232 Destroy(); 233} 234 235GLInProcessContext* GLInProcessContext::CreateContext( 236 bool is_offscreen, 237 gfx::AcceleratedWidget window, 238 const gfx::Size& size, 239 bool share_resources, 240 const char* allowed_extensions, 241 const int32* attrib_list, 242 gfx::GpuPreference gpu_preference) { 243 scoped_ptr<GLInProcessContext> context( 244 new GLInProcessContext(share_resources)); 245 if (!context->Initialize( 246 is_offscreen, 247 window, 248 size, 249 allowed_extensions, 250 attrib_list, 251 gpu_preference)) 252 return NULL; 253 254 return context.release(); 255} 256 257// In the normal command buffer implementation, all commands are passed over IPC 258// to the gpu process where they are fed to the GLES2Decoder from a single 259// thread. In layout tests, any thread could call this function. GLES2Decoder, 260// and in particular the GL implementations behind it, are not generally 261// threadsafe, so we guard entry points with a mutex. 262static base::LazyInstance<base::Lock> g_decoder_lock = 263 LAZY_INSTANCE_INITIALIZER; 264 265static base::LazyInstance< 266 std::set<GLInProcessContext*> > 267 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER; 268 269static bool g_use_virtualized_gl_context = false; 270 271namespace { 272 273// Also calls DetachFromThreadHack on all GLES2Decoders before the lock is 274// released to maintain the invariant that all decoders are unbound while the 275// lock is not held. This is to workaround DumpRenderTree using WGC3DIPCBI with 276// shared resources on different threads. 277// Remove this as part of crbug.com/234964. 278class AutoLockAndDecoderDetachThread { 279 public: 280 AutoLockAndDecoderDetachThread(base::Lock& lock, 281 const std::set<GLInProcessContext*>& contexts); 282 ~AutoLockAndDecoderDetachThread(); 283 284 private: 285 base::AutoLock auto_lock_; 286 const std::set<GLInProcessContext*>& contexts_; 287}; 288 289AutoLockAndDecoderDetachThread::AutoLockAndDecoderDetachThread( 290 base::Lock& lock, 291 const std::set<GLInProcessContext*>& contexts) 292 : auto_lock_(lock), 293 contexts_(contexts) { 294} 295 296void DetachThread(GLInProcessContext* context) { 297 if (context->GetDecoder()) 298 context->GetDecoder()->DetachFromThreadHack(); 299} 300 301AutoLockAndDecoderDetachThread::~AutoLockAndDecoderDetachThread() { 302 std::for_each(contexts_.begin(), 303 contexts_.end(), 304 &DetachThread); 305} 306 307static WebGraphicsContext3DInProcessCommandBufferImpl::GpuMemoryBufferCreator* 308 g_gpu_memory_buffer_creator = NULL; 309 310class ImageFactoryInProcess 311 : public ImageFactory, 312 public base::RefCountedThreadSafe<ImageFactoryInProcess> { 313 public: 314 explicit ImageFactoryInProcess(ImageManager* image_manager); 315 316 // methods from ImageFactory 317 virtual scoped_ptr<GpuMemoryBuffer> CreateGpuMemoryBuffer( 318 int width, int height, GLenum internalformat, 319 unsigned* image_id) OVERRIDE; 320 virtual void DeleteGpuMemoryBuffer(unsigned image_id) OVERRIDE; 321 private: 322 friend class base::RefCountedThreadSafe<ImageFactoryInProcess>; 323 virtual ~ImageFactoryInProcess(); 324 325 // ImageManager is referred by the ContextGroup and the 326 // ContextGroup outlives the client. 327 ImageManager* image_manager_; 328 unsigned next_id_; 329 330 DISALLOW_COPY_AND_ASSIGN(ImageFactoryInProcess); 331}; 332 333ImageFactoryInProcess::ImageFactoryInProcess( 334 ImageManager* image_manager) : image_manager_(image_manager), 335 next_id_(0) { 336} 337 338ImageFactoryInProcess::~ImageFactoryInProcess() { 339} 340 341scoped_ptr<GpuMemoryBuffer> ImageFactoryInProcess::CreateGpuMemoryBuffer( 342 int width, int height, GLenum internalformat, unsigned int* image_id) { 343 // We're taking the lock here because we're accessing the ContextGroup's 344 // shared ImageManager and next_id_. 345 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 346 g_all_shared_contexts.Get()); 347 // For Android WebView we assume the |internalformat| will always be 348 // GL_RGBA8_OES. 349 DCHECK_EQ(GL_RGBA8_OES, internalformat); 350 scoped_ptr<GpuMemoryBuffer> buffer = 351 g_gpu_memory_buffer_creator(width, height); 352 353 if (buffer.get() == NULL) 354 return buffer.Pass(); 355 356 scoped_refptr<gfx::GLImage> gl_image = 357 gfx::GLImage::CreateGLImageForGpuMemoryBuffer(buffer->GetNativeBuffer(), 358 gfx::Size(width, height)); 359 *image_id = ++next_id_; // Valid image_ids start from 1. 360 image_manager_->AddImage(gl_image, *image_id); 361 return buffer.Pass(); 362} 363 364void ImageFactoryInProcess::DeleteGpuMemoryBuffer(unsigned int image_id) { 365 // We're taking the lock here because we're accessing the ContextGroup's 366 // shared ImageManager. 367 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 368 g_all_shared_contexts.Get()); 369 image_manager_->RemoveImage(image_id); 370} 371 372} // namespace 373 374static void CallAndDestroy( 375 scoped_ptr< 376 WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) { 377 callback->onSyncPointReached(); 378} 379 380void GLInProcessContext::PumpCommands() { 381 if (!context_lost_) { 382 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 383 g_all_shared_contexts.Get()); 384 decoder_->MakeCurrent(); 385 gpu_scheduler_->PutChanged(); 386 ::gpu::CommandBuffer::State state = command_buffer_->GetState(); 387 if (::gpu::error::IsError(state.error)) 388 context_lost_ = true; 389 } 390 391 if (!context_lost_ && signal_sync_point_callback_) { 392 base::MessageLoop::current()->PostTask( 393 FROM_HERE, 394 base::Bind(&CallAndDestroy, 395 base::Passed(&signal_sync_point_callback_))); 396 } 397} 398 399bool GLInProcessContext::GetBufferChanged(int32 transfer_buffer_id) { 400 return gpu_scheduler_->SetGetBuffer(transfer_buffer_id); 401} 402 403uint32 GLInProcessContext::GetParentTextureId() { 404 return 0; 405} 406 407uint32 GLInProcessContext::CreateParentTexture(const gfx::Size& size) { 408 uint32 texture = 0; 409 gles2_implementation_->GenTextures(1, &texture); 410 gles2_implementation_->Flush(); 411 return texture; 412} 413 414void GLInProcessContext::DeleteParentTexture(uint32 texture) { 415 gles2_implementation_->DeleteTextures(1, &texture); 416} 417 418void GLInProcessContext::SetContextLostCallback(const base::Closure& callback) { 419 context_lost_callback_ = callback; 420} 421 422bool GLInProcessContext::MakeCurrent(GLInProcessContext* context) { 423 if (context) { 424 gles2::SetGLContext(context->gles2_implementation_.get()); 425 426 // Don't request latest error status from service. Just use the locally 427 // cached information from the last flush. 428 // TODO(apatrick): I'm not sure if this should actually change the 429 // current context if it fails. For now it gets changed even if it fails 430 // because making GL calls with a NULL context crashes. 431 if (context->command_buffer_->GetState().error != ::gpu::error::kNoError) 432 return false; 433 } else { 434 gles2::SetGLContext(NULL); 435 } 436 437 return true; 438} 439 440bool GLInProcessContext::SwapBuffers() { 441 // Don't request latest error status from service. Just use the locally cached 442 // information from the last flush. 443 if (command_buffer_->GetState().error != ::gpu::error::kNoError) 444 return false; 445 446 gles2_implementation_->SwapBuffers(); 447 gles2_implementation_->Finish(); 448 return true; 449} 450 451GLInProcessContext::Error GLInProcessContext::GetError() { 452 CommandBuffer::State state = command_buffer_->GetState(); 453 if (state.error == ::gpu::error::kNoError) { 454 // TODO(gman): Figure out and document what this logic is for. 455 Error old_error = last_error_; 456 last_error_ = SUCCESS; 457 return old_error; 458 } else { 459 // All command buffer errors are unrecoverable. The error is treated as a 460 // lost context: destroy the context and create another one. 461 return CONTEXT_LOST; 462 } 463} 464 465bool GLInProcessContext::IsCommandBufferContextLost() { 466 if (context_lost_ || !command_buffer_) { 467 return true; 468 } 469 CommandBuffer::State state = command_buffer_->GetState(); 470 return ::gpu::error::IsError(state.error); 471} 472 473void GLInProcessContext::LoseContext(uint32 current, uint32 other) { 474 gles2_implementation_->LoseContextCHROMIUM(current, other); 475 gles2_implementation_->Finish(); 476 DCHECK(IsCommandBufferContextLost()); 477} 478 479void GLInProcessContext::SetSignalSyncPointCallback( 480 scoped_ptr< 481 WebKit::WebGraphicsContext3D::WebGraphicsSyncPointCallback> callback) { 482 signal_sync_point_callback_ = callback.Pass(); 483} 484 485CommandBufferService* GLInProcessContext::GetCommandBufferService() { 486 return command_buffer_.get(); 487} 488 489::gpu::gles2::GLES2Decoder* GLInProcessContext::GetDecoder() { 490 return decoder_.get(); 491} 492 493void GLInProcessContext::OnResizeView(gfx::Size size, float scale_factor) { 494 DCHECK(!surface_->IsOffscreen()); 495 surface_->Resize(size); 496} 497 498// TODO(gman): Remove This 499void GLInProcessContext::DisableShaderTranslation() { 500 NOTREACHED(); 501} 502 503GLES2Implementation* GLInProcessContext::GetImplementation() { 504 return gles2_implementation_.get(); 505} 506 507::gpu::gles2::ImageManager* GLInProcessContext::GetImageManager() { 508 return decoder_->GetContextGroup()->image_manager(); 509} 510 511scoped_refptr<ImageFactoryInProcess> GLInProcessContext::GetImageFactory() { 512 return image_factory_; 513} 514 515GLInProcessContext::GLInProcessContext(bool share_resources) 516 : last_error_(SUCCESS), 517 share_resources_(share_resources), 518 context_lost_(false) { 519} 520 521bool GLInProcessContext::Initialize( 522 bool is_offscreen, 523 gfx::AcceleratedWidget window, 524 const gfx::Size& size, 525 const char* allowed_extensions, 526 const int32* attrib_list, 527 gfx::GpuPreference gpu_preference) { 528 // Use one share group for all contexts. 529 CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, 530 (new gfx::GLShareGroup)); 531 532 DCHECK(size.width() >= 0 && size.height() >= 0); 533 534 // Ensure the gles2 library is initialized first in a thread safe way. 535 g_gles2_initializer.Get(); 536 537 std::vector<int32> attribs; 538 while (attrib_list) { 539 int32 attrib = *attrib_list++; 540 switch (attrib) { 541 // Known attributes 542 case ALPHA_SIZE: 543 case BLUE_SIZE: 544 case GREEN_SIZE: 545 case RED_SIZE: 546 case DEPTH_SIZE: 547 case STENCIL_SIZE: 548 case SAMPLES: 549 case SAMPLE_BUFFERS: 550 attribs.push_back(attrib); 551 attribs.push_back(*attrib_list++); 552 break; 553 case NONE: 554 attribs.push_back(attrib); 555 attrib_list = NULL; 556 break; 557 default: 558 last_error_ = BAD_ATTRIBUTE; 559 attribs.push_back(NONE); 560 attrib_list = NULL; 561 break; 562 } 563 } 564 565 { 566 TransferBufferManager* manager = new TransferBufferManager(); 567 transfer_buffer_manager_.reset(manager); 568 manager->Initialize(); 569 } 570 571 command_buffer_.reset( 572 new CommandBufferService(transfer_buffer_manager_.get())); 573 if (!command_buffer_->Initialize()) { 574 LOG(ERROR) << "Could not initialize command buffer."; 575 Destroy(); 576 return false; 577 } 578 579 GLInProcessContext* context_group = NULL; 580 581 { 582 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 583 g_all_shared_contexts.Get()); 584 if (share_resources_ && !g_all_shared_contexts.Get().empty()) { 585 for (std::set<GLInProcessContext*>::iterator it = 586 g_all_shared_contexts.Get().begin(); 587 it != g_all_shared_contexts.Get().end(); 588 ++it) { 589 if (!(*it)->IsCommandBufferContextLost()) { 590 context_group = *it; 591 break; 592 } 593 } 594 if (!context_group) 595 share_group = new gfx::GLShareGroup; 596 } 597 598 // TODO(gman): This needs to be true if this is Pepper. 599 bool bind_generates_resource = false; 600 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group ? 601 context_group->decoder_->GetContextGroup() : 602 new ::gpu::gles2::ContextGroup( 603 NULL, NULL, NULL, bind_generates_resource))); 604 605 gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(), 606 decoder_.get(), 607 decoder_.get())); 608 609 decoder_->set_engine(gpu_scheduler_.get()); 610 611 if (is_offscreen) 612 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, size); 613 else 614 surface_ = gfx::GLSurface::CreateViewGLSurface(false, window); 615 616 if (!surface_) { 617 LOG(ERROR) << "Could not create GLSurface."; 618 Destroy(); 619 return false; 620 } 621 622 if (g_use_virtualized_gl_context) { 623 context_ = share_group->GetSharedContext(); 624 if (!context_) { 625 context_ = gfx::GLContext::CreateGLContext(share_group.get(), 626 surface_.get(), 627 gpu_preference); 628 share_group->SetSharedContext(context_); 629 } 630 631 context_ = new ::gpu::GLContextVirtual(share_group.get(), 632 context_, 633 decoder_->AsWeakPtr()); 634 if (context_->Initialize(surface_, gpu_preference)) { 635 VLOG(1) << "Created virtual GL context."; 636 } else { 637 context_ = NULL; 638 } 639 } else { 640 context_ = gfx::GLContext::CreateGLContext(share_group.get(), 641 surface_.get(), 642 gpu_preference); 643 } 644 645 if (!context_) { 646 LOG(ERROR) << "Could not create GLContext."; 647 Destroy(); 648 return false; 649 } 650 651 if (!context_->MakeCurrent(surface_)) { 652 LOG(ERROR) << "Could not make context current."; 653 Destroy(); 654 return false; 655 } 656 657 ::gpu::gles2::DisallowedFeatures disallowed_features; 658 disallowed_features.swap_buffer_complete_callback = true; 659 disallowed_features.gpu_memory_manager = true; 660 if (!decoder_->Initialize(surface_, 661 context_, 662 is_offscreen, 663 size, 664 disallowed_features, 665 allowed_extensions, 666 attribs)) { 667 LOG(ERROR) << "Could not initialize decoder."; 668 Destroy(); 669 return false; 670 } 671 672 if (!is_offscreen) { 673 decoder_->SetResizeCallback(base::Bind(&GLInProcessContext::OnResizeView, 674 base::Unretained(this))); 675 } 676 } 677 678 command_buffer_->SetPutOffsetChangeCallback( 679 base::Bind(&GLInProcessContext::PumpCommands, base::Unretained(this))); 680 command_buffer_->SetGetBufferChangeCallback( 681 base::Bind( 682 &GLInProcessContext::GetBufferChanged, base::Unretained(this))); 683 command_buffer_->SetParseErrorCallback( 684 base::Bind(&GLInProcessContext::OnContextLost, base::Unretained(this))); 685 686 // Create the GLES2 helper, which writes the command buffer protocol. 687 gles2_helper_.reset(new GLES2CmdHelper(command_buffer_.get())); 688 if (!gles2_helper_->Initialize(kCommandBufferSize)) { 689 Destroy(); 690 return false; 691 } 692 693 // Create a transfer buffer. 694 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get())); 695 696 if (share_resources_) { 697 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 698 g_all_shared_contexts.Get()); 699 if (g_all_shared_contexts.Get().empty()) { 700 // Create the image factory for the first context. 701 image_factory_ = new ImageFactoryInProcess(GetImageManager()); 702 } else { 703 // Share the image factory created by the first context. 704 GLInProcessContext* first_context = *g_all_shared_contexts.Get().begin(); 705 image_factory_ = first_context->GetImageFactory(); 706 } 707 } else { 708 // Create the image factory, this object retains its ownership. 709 image_factory_ = new ImageFactoryInProcess(GetImageManager()); 710 } 711 712 // Create the object exposing the OpenGL API. 713 gles2_implementation_.reset(new GLES2Implementation( 714 gles2_helper_.get(), 715 context_group ? context_group->GetImplementation()->share_group() : NULL, 716 transfer_buffer_.get(), 717 true, 718 false, 719 image_factory_)); 720 721 if (!gles2_implementation_->Initialize( 722 kStartTransferBufferSize, 723 kMinTransferBufferSize, 724 kMaxTransferBufferSize)) { 725 return false; 726 } 727 728 if (share_resources_) { 729 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 730 g_all_shared_contexts.Get()); 731 g_all_shared_contexts.Pointer()->insert(this); 732 } 733 734 return true; 735} 736 737void GLInProcessContext::Destroy() { 738 bool context_lost = IsCommandBufferContextLost(); 739 740 if (gles2_implementation_) { 741 // First flush the context to ensure that any pending frees of resources 742 // are completed. Otherwise, if this context is part of a share group, 743 // those resources might leak. Also, any remaining side effects of commands 744 // issued on this context might not be visible to other contexts in the 745 // share group. 746 gles2_implementation_->Flush(); 747 748 gles2_implementation_.reset(); 749 } 750 751 transfer_buffer_.reset(); 752 gles2_helper_.reset(); 753 command_buffer_.reset(); 754 755 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 756 g_all_shared_contexts.Get()); 757 if (decoder_) { 758 decoder_->Destroy(!context_lost); 759 } 760 761 g_all_shared_contexts.Pointer()->erase(this); 762} 763 764void GLInProcessContext::OnContextLost() { 765 if (!context_lost_callback_.is_null()) 766 context_lost_callback_.Run(); 767 768 context_lost_ = true; 769 if (share_resources_) { 770 for (std::set<GLInProcessContext*>::iterator it = 771 g_all_shared_contexts.Get().begin(); 772 it != g_all_shared_contexts.Get().end(); 773 ++it) 774 (*it)->context_lost_ = true; 775 } 776} 777 778// static 779void 780WebGraphicsContext3DInProcessCommandBufferImpl::EnableVirtualizedContext() { 781#if !defined(NDEBUG) 782 { 783 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), 784 g_all_shared_contexts.Get()); 785 DCHECK(g_all_shared_contexts.Get().empty()); 786 } 787#endif // !defined(NDEBUG) 788 g_use_virtualized_gl_context = true; 789} 790 791// static 792WebGraphicsContext3DInProcessCommandBufferImpl* 793WebGraphicsContext3DInProcessCommandBufferImpl::CreateViewContext( 794 const WebKit::WebGraphicsContext3D::Attributes& attributes, 795 gfx::AcceleratedWidget window) { 796 if (!gfx::GLSurface::InitializeOneOff()) 797 return NULL; 798 return new WebGraphicsContext3DInProcessCommandBufferImpl( 799 attributes, false, window); 800} 801 802// static 803WebGraphicsContext3DInProcessCommandBufferImpl* 804WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext( 805 const WebKit::WebGraphicsContext3D::Attributes& attributes) { 806 return new WebGraphicsContext3DInProcessCommandBufferImpl( 807 attributes, true, gfx::kNullAcceleratedWidget); 808} 809 810WebGraphicsContext3DInProcessCommandBufferImpl:: 811 WebGraphicsContext3DInProcessCommandBufferImpl( 812 const WebKit::WebGraphicsContext3D::Attributes& attributes, 813 bool is_offscreen, 814 gfx::AcceleratedWidget window) 815 : is_offscreen_(is_offscreen), 816 window_(window), 817 initialized_(false), 818 initialize_failed_(false), 819 context_(NULL), 820 gl_(NULL), 821 context_lost_callback_(NULL), 822 context_lost_reason_(GL_NO_ERROR), 823 attributes_(attributes), 824 cached_width_(0), 825 cached_height_(0), 826 bound_fbo_(0) { 827} 828 829WebGraphicsContext3DInProcessCommandBufferImpl:: 830 ~WebGraphicsContext3DInProcessCommandBufferImpl() { 831} 832 833bool WebGraphicsContext3DInProcessCommandBufferImpl::MaybeInitializeGL() { 834 if (initialized_) 835 return true; 836 837 if (initialize_failed_) 838 return false; 839 840 // Convert WebGL context creation attributes into GLInProcessContext / EGL 841 // size requests. 842 const int alpha_size = attributes_.alpha ? 8 : 0; 843 const int depth_size = attributes_.depth ? 24 : 0; 844 const int stencil_size = attributes_.stencil ? 8 : 0; 845 const int samples = attributes_.antialias ? 4 : 0; 846 const int sample_buffers = attributes_.antialias ? 1 : 0; 847 const int32 attribs[] = { 848 GLInProcessContext::ALPHA_SIZE, alpha_size, 849 GLInProcessContext::DEPTH_SIZE, depth_size, 850 GLInProcessContext::STENCIL_SIZE, stencil_size, 851 GLInProcessContext::SAMPLES, samples, 852 GLInProcessContext::SAMPLE_BUFFERS, sample_buffers, 853 GLInProcessContext::NONE, 854 }; 855 856 const char* preferred_extensions = "*"; 857 858 // TODO(kbr): More work will be needed in this implementation to 859 // properly support GPU switching. Like in the out-of-process 860 // command buffer implementation, all previously created contexts 861 // will need to be lost either when the first context requesting the 862 // discrete GPU is created, or the last one is destroyed. 863 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; 864 865 context_ = GLInProcessContext::CreateContext( 866 is_offscreen_, 867 window_, 868 gfx::Size(1, 1), 869 attributes_.shareResources, 870 preferred_extensions, 871 attribs, 872 gpu_preference); 873 874 if (!context_) { 875 initialize_failed_ = true; 876 return false; 877 } 878 879 gl_ = context_->GetImplementation(); 880 881 if (gl_ && attributes_.noExtensions) 882 gl_->EnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"); 883 884 context_->SetContextLostCallback( 885 base::Bind( 886 &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost, 887 base::Unretained(this))); 888 889 // Set attributes_ from created offscreen context. 890 { 891 GLint alpha_bits = 0; 892 getIntegerv(GL_ALPHA_BITS, &alpha_bits); 893 attributes_.alpha = alpha_bits > 0; 894 GLint depth_bits = 0; 895 getIntegerv(GL_DEPTH_BITS, &depth_bits); 896 attributes_.depth = depth_bits > 0; 897 GLint stencil_bits = 0; 898 getIntegerv(GL_STENCIL_BITS, &stencil_bits); 899 attributes_.stencil = stencil_bits > 0; 900 GLint sample_buffers = 0; 901 getIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers); 902 attributes_.antialias = sample_buffers > 0; 903 } 904 905 initialized_ = true; 906 return true; 907} 908 909bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { 910 if (!MaybeInitializeGL()) 911 return false; 912 913 return GLInProcessContext::MakeCurrent(context_); 914} 915 916void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() { 917 // NOTE: Comment in the line below to check for code that is not calling 918 // eglMakeCurrent where appropriate. The issue is code using 919 // WebGraphicsContext3D does not need to call makeContextCurrent. Code using 920 // direct OpenGL bindings needs to call the appropriate form of 921 // eglMakeCurrent. If it doesn't it will be issuing commands on the wrong 922 // context. Uncommenting the line below clears the current context so that 923 // any code not calling eglMakeCurrent in the appropriate place should crash. 924 // This is not a perfect test but generally code that used the direct OpenGL 925 // bindings should not be mixed with code that uses WebGraphicsContext3D. 926 // 927 // GLInProcessContext::MakeCurrent(NULL); 928} 929 930int WebGraphicsContext3DInProcessCommandBufferImpl::width() { 931 return cached_width_; 932} 933 934int WebGraphicsContext3DInProcessCommandBufferImpl::height() { 935 return cached_height_; 936} 937 938bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { 939 return true; 940} 941 942bool WebGraphicsContext3DInProcessCommandBufferImpl::setParentContext( 943 WebGraphicsContext3D* parent_context) { 944 return false; 945} 946 947WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { 948 DCHECK(context_); 949 return context_->GetParentTextureId(); 950} 951 952void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { 953 // Copies the contents of the off-screen render target into the texture 954 // used by the compositor. 955 context_->SwapBuffers(); 956} 957 958void WebGraphicsContext3DInProcessCommandBufferImpl::postSubBufferCHROMIUM( 959 int x, int y, int width, int height) { 960 gl_->PostSubBufferCHROMIUM(x, y, width, height); 961} 962 963void WebGraphicsContext3DInProcessCommandBufferImpl::reshape( 964 int width, int height) { 965 reshapeWithScaleFactor(width, height, 1.0f); 966} 967 968void WebGraphicsContext3DInProcessCommandBufferImpl::reshapeWithScaleFactor( 969 int width, int height, float scale_factor) { 970 cached_width_ = width; 971 cached_height_ = height; 972 973 // TODO(gmam): See if we can comment this in. 974 // ClearContext(); 975 976 gl_->ResizeCHROMIUM(width, height, scale_factor); 977} 978 979WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createCompositorTexture( 980 WGC3Dsizei width, WGC3Dsizei height) { 981 // TODO(gmam): See if we can comment this in. 982 // ClearContext(); 983 return context_->CreateParentTexture(gfx::Size(width, height)); 984} 985 986void WebGraphicsContext3DInProcessCommandBufferImpl::deleteCompositorTexture( 987 WebGLId parent_texture) { 988 // TODO(gmam): See if we can comment this in. 989 // ClearContext(); 990 context_->DeleteParentTexture(parent_texture); 991} 992 993void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( 994 uint8* framebuffer, 995 unsigned int width, 996 unsigned int height) { 997 if (width == 0) 998 return; 999 scanline_.resize(width * 4); 1000 uint8* scanline = &scanline_[0]; 1001 unsigned int row_bytes = width * 4; 1002 unsigned int count = height / 2; 1003 for (unsigned int i = 0; i < count; i++) { 1004 uint8* row_a = framebuffer + i * row_bytes; 1005 uint8* row_b = framebuffer + (height - i - 1) * row_bytes; 1006 // TODO(kbr): this is where the multiplication of the alpha 1007 // channel into the color buffer will need to occur if the 1008 // user specifies the "premultiplyAlpha" flag in the context 1009 // creation attributes. 1010 memcpy(scanline, row_b, row_bytes); 1011 memcpy(row_b, row_a, row_bytes); 1012 memcpy(row_a, scanline, row_bytes); 1013 } 1014} 1015 1016bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( 1017 unsigned char* pixels, 1018 size_t buffer_size, 1019 WebGLId framebuffer, 1020 int width, 1021 int height) { 1022 // TODO(gmam): See if we can comment this in. 1023 // ClearContext(); 1024 if (buffer_size != static_cast<size_t>(4 * width * height)) { 1025 return false; 1026 } 1027 1028 // Earlier versions of this code used the GPU to flip the 1029 // framebuffer vertically before reading it back for compositing 1030 // via software. This code was quite complicated, used a lot of 1031 // GPU memory, and didn't provide an obvious speedup. Since this 1032 // vertical flip is only a temporary solution anyway until Chrome 1033 // is fully GPU composited, it wasn't worth the complexity. 1034 1035 bool mustRestoreFBO = (bound_fbo_ != framebuffer); 1036 if (mustRestoreFBO) { 1037 gl_->BindFramebuffer(GL_FRAMEBUFFER, framebuffer); 1038 } 1039 gl_->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 1040 1041 // Swizzle red and blue channels 1042 // TODO(kbr): expose GL_BGRA as extension 1043 for (size_t i = 0; i < buffer_size; i += 4) { 1044 std::swap(pixels[i], pixels[i + 2]); 1045 } 1046 1047 if (mustRestoreFBO) { 1048 gl_->BindFramebuffer(GL_FRAMEBUFFER, bound_fbo_); 1049 } 1050 1051 if (pixels) { 1052 FlipVertically(pixels, width, height); 1053 } 1054 1055 return true; 1056} 1057 1058bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( 1059 unsigned char* pixels, 1060 size_t buffer_size) { 1061 return readBackFramebuffer(pixels, buffer_size, 0, width(), height()); 1062} 1063 1064void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError( 1065 WGC3Denum error) { 1066 if (std::find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == 1067 synthetic_errors_.end()) { 1068 synthetic_errors_.push_back(error); 1069 } 1070} 1071 1072void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM( 1073 WGC3Denum target, 1074 WGC3Dintptr offset, 1075 WGC3Dsizeiptr size, 1076 WGC3Denum access) { 1077 ClearContext(); 1078 return gl_->MapBufferSubDataCHROMIUM(target, offset, size, access); 1079} 1080 1081void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM( 1082 const void* mem) { 1083 ClearContext(); 1084 return gl_->UnmapBufferSubDataCHROMIUM(mem); 1085} 1086 1087void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM( 1088 WGC3Denum target, 1089 WGC3Dint level, 1090 WGC3Dint xoffset, 1091 WGC3Dint yoffset, 1092 WGC3Dsizei width, 1093 WGC3Dsizei height, 1094 WGC3Denum format, 1095 WGC3Denum type, 1096 WGC3Denum access) { 1097 ClearContext(); 1098 return gl_->MapTexSubImage2DCHROMIUM( 1099 target, level, xoffset, yoffset, width, height, format, type, access); 1100} 1101 1102void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM( 1103 const void* mem) { 1104 ClearContext(); 1105 gl_->UnmapTexSubImage2DCHROMIUM(mem); 1106} 1107 1108void WebGraphicsContext3DInProcessCommandBufferImpl::setVisibilityCHROMIUM( 1109 bool visible) { 1110} 1111 1112void WebGraphicsContext3DInProcessCommandBufferImpl:: 1113 setMemoryAllocationChangedCallbackCHROMIUM( 1114 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) { 1115} 1116 1117void WebGraphicsContext3DInProcessCommandBufferImpl::discardFramebufferEXT( 1118 WGC3Denum target, WGC3Dsizei numAttachments, const WGC3Denum* attachments) { 1119 gl_->DiscardFramebufferEXT(target, numAttachments, attachments); 1120} 1121 1122void WebGraphicsContext3DInProcessCommandBufferImpl:: 1123 discardBackbufferCHROMIUM() { 1124} 1125 1126void WebGraphicsContext3DInProcessCommandBufferImpl:: 1127 ensureBackbufferCHROMIUM() { 1128} 1129 1130void WebGraphicsContext3DInProcessCommandBufferImpl:: 1131 copyTextureToParentTextureCHROMIUM(WebGLId texture, WebGLId parentTexture) { 1132 NOTIMPLEMENTED(); 1133} 1134 1135void WebGraphicsContext3DInProcessCommandBufferImpl:: 1136 rateLimitOffscreenContextCHROMIUM() { 1137 // TODO(gmam): See if we can comment this in. 1138 // ClearContext(); 1139 gl_->RateLimitOffscreenContextCHROMIUM(); 1140} 1141 1142WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1143 getRequestableExtensionsCHROMIUM() { 1144 // TODO(gmam): See if we can comment this in. 1145 // ClearContext(); 1146 return WebKit::WebString::fromUTF8( 1147 gl_->GetRequestableExtensionsCHROMIUM()); 1148} 1149 1150void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM( 1151 const char* extension) { 1152 // TODO(gmam): See if we can comment this in. 1153 // ClearContext(); 1154 gl_->RequestExtensionCHROMIUM(extension); 1155} 1156 1157void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM( 1158 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, 1159 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, 1160 WGC3Dbitfield mask, WGC3Denum filter) { 1161 ClearContext(); 1162 gl_->BlitFramebufferEXT( 1163 srcX0, srcY0, srcX1, srcY1, 1164 dstX0, dstY0, dstX1, dstY1, 1165 mask, filter); 1166} 1167 1168void WebGraphicsContext3DInProcessCommandBufferImpl:: 1169 renderbufferStorageMultisampleCHROMIUM( 1170 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, 1171 WGC3Dsizei width, WGC3Dsizei height) { 1172 ClearContext(); 1173 gl_->RenderbufferStorageMultisampleEXT( 1174 target, samples, internalformat, width, height); 1175} 1176 1177// Helper macros to reduce the amount of code. 1178 1179#define DELEGATE_TO_GL(name, glname) \ 1180void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \ 1181 ClearContext(); \ 1182 gl_->glname(); \ 1183} 1184 1185#define DELEGATE_TO_GL_1(name, glname, t1) \ 1186void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1187 ClearContext(); \ 1188 gl_->glname(a1); \ 1189} 1190 1191#define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ 1192rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1193 ClearContext(); \ 1194 return gl_->glname(a1); \ 1195} 1196 1197#define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ 1198rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1199 ClearContext(); \ 1200 return gl_->glname(a1) ? true : false; \ 1201} 1202 1203#define DELEGATE_TO_GL_2(name, glname, t1, t2) \ 1204void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1205 t1 a1, t2 a2) { \ 1206 ClearContext(); \ 1207 gl_->glname(a1, a2); \ 1208} 1209 1210#define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ 1211rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ 1212 ClearContext(); \ 1213 return gl_->glname(a1, a2); \ 1214} 1215 1216#define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ 1217void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1218 t1 a1, t2 a2, t3 a3) { \ 1219 ClearContext(); \ 1220 gl_->glname(a1, a2, a3); \ 1221} 1222 1223#define DELEGATE_TO_GL_3R(name, glname, t1, t2, t3, rt) \ 1224rt WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1225 t1 a1, t2 a2, t3 a3) { \ 1226 ClearContext(); \ 1227 return gl_->glname(a1, a2, a3); \ 1228} 1229 1230#define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ 1231void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1232 t1 a1, t2 a2, t3 a3, t4 a4) { \ 1233 ClearContext(); \ 1234 gl_->glname(a1, a2, a3, a4); \ 1235} 1236 1237#define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ 1238void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1239 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \ 1240 ClearContext(); \ 1241 gl_->glname(a1, a2, a3, a4, a5); \ 1242} 1243 1244#define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ 1245void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1246 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \ 1247 ClearContext(); \ 1248 gl_->glname(a1, a2, a3, a4, a5, a6); \ 1249} 1250 1251#define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ 1252void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1253 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) { \ 1254 ClearContext(); \ 1255 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \ 1256} 1257 1258#define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ 1259void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1260 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) { \ 1261 ClearContext(); \ 1262 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \ 1263} 1264 1265#define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ 1266void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ 1267 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) { \ 1268 ClearContext(); \ 1269 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ 1270} 1271 1272DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum) 1273 1274DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) 1275 1276DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, 1277 WGC3Duint, const WGC3Dchar*) 1278 1279DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId) 1280 1281void WebGraphicsContext3DInProcessCommandBufferImpl::bindFramebuffer( 1282 WGC3Denum target, 1283 WebGLId framebuffer) { 1284 ClearContext(); 1285 gl_->BindFramebuffer(target, framebuffer); 1286 bound_fbo_ = framebuffer; 1287} 1288 1289DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId) 1290 1291DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId) 1292 1293DELEGATE_TO_GL_4(blendColor, BlendColor, 1294 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) 1295 1296DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) 1297 1298DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, 1299 WGC3Denum, WGC3Denum) 1300 1301DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum) 1302 1303DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, 1304 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) 1305 1306DELEGATE_TO_GL_4(bufferData, BufferData, 1307 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum) 1308 1309DELEGATE_TO_GL_4(bufferSubData, BufferSubData, 1310 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) 1311 1312DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus, 1313 WGC3Denum, WGC3Denum) 1314 1315DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) 1316 1317DELEGATE_TO_GL_4(clearColor, ClearColor, 1318 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) 1319 1320DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf) 1321 1322DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) 1323 1324DELEGATE_TO_GL_4(colorMask, ColorMask, 1325 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) 1326 1327DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) 1328 1329DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D, 1330 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, 1331 WGC3Dsizei, WGC3Dsizei, const void*) 1332 1333DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D, 1334 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, 1335 WGC3Denum, WGC3Dsizei, const void*) 1336 1337DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D, 1338 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, 1339 WGC3Dsizei, WGC3Dsizei, WGC3Dint) 1340 1341DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D, 1342 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, 1343 WGC3Dsizei, WGC3Dsizei) 1344 1345DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) 1346 1347DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) 1348 1349DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) 1350 1351DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf) 1352 1353DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) 1354 1355DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) 1356 1357DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, 1358 WGC3Duint) 1359 1360DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) 1361 1362void WebGraphicsContext3DInProcessCommandBufferImpl::drawElements( 1363 WGC3Denum mode, 1364 WGC3Dsizei count, 1365 WGC3Denum type, 1366 WGC3Dintptr offset) { 1367 ClearContext(); 1368 gl_->DrawElements( 1369 mode, count, type, 1370 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 1371} 1372 1373DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) 1374 1375DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, 1376 WGC3Duint) 1377 1378DELEGATE_TO_GL(finish, Finish) 1379 1380DELEGATE_TO_GL(flush, Flush) 1381 1382DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer, 1383 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) 1384 1385DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D, 1386 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) 1387 1388DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) 1389 1390DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum) 1391 1392bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib( 1393 WebGLId program, WGC3Duint index, ActiveInfo& info) { 1394 ClearContext(); 1395 if (!program) { 1396 synthesizeGLError(GL_INVALID_VALUE); 1397 return false; 1398 } 1399 GLint max_name_length = -1; 1400 gl_->GetProgramiv( 1401 program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); 1402 if (max_name_length < 0) 1403 return false; 1404 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]); 1405 if (!name) { 1406 synthesizeGLError(GL_OUT_OF_MEMORY); 1407 return false; 1408 } 1409 GLsizei length = 0; 1410 GLint size = -1; 1411 GLenum type = 0; 1412 gl_->GetActiveAttrib( 1413 program, index, max_name_length, &length, &size, &type, name.get()); 1414 if (size < 0) { 1415 return false; 1416 } 1417 info.name = WebKit::WebString::fromUTF8(name.get(), length); 1418 info.type = type; 1419 info.size = size; 1420 return true; 1421} 1422 1423bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveUniform( 1424 WebGLId program, WGC3Duint index, ActiveInfo& info) { 1425 ClearContext(); 1426 GLint max_name_length = -1; 1427 gl_->GetProgramiv( 1428 program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); 1429 if (max_name_length < 0) 1430 return false; 1431 scoped_ptr<GLchar[]> name(new GLchar[max_name_length]); 1432 if (!name) { 1433 synthesizeGLError(GL_OUT_OF_MEMORY); 1434 return false; 1435 } 1436 GLsizei length = 0; 1437 GLint size = -1; 1438 GLenum type = 0; 1439 gl_->GetActiveUniform( 1440 program, index, max_name_length, &length, &size, &type, name.get()); 1441 if (size < 0) { 1442 return false; 1443 } 1444 info.name = WebKit::WebString::fromUTF8(name.get(), length); 1445 info.type = type; 1446 info.size = size; 1447 return true; 1448} 1449 1450DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, 1451 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*) 1452 1453DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, 1454 WebGLId, const WGC3Dchar*, WGC3Dint) 1455 1456DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*) 1457 1458DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, 1459 WGC3Denum, WGC3Denum, WGC3Dint*) 1460 1461WebKit::WebGraphicsContext3D::Attributes 1462WebGraphicsContext3DInProcessCommandBufferImpl::getContextAttributes() { 1463 return attributes_; 1464} 1465 1466WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl::getError() { 1467 ClearContext(); 1468 if (!synthetic_errors_.empty()) { 1469 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); 1470 WGC3Denum err = *iter; 1471 synthetic_errors_.erase(iter); 1472 return err; 1473 } 1474 1475 return gl_->GetError(); 1476} 1477 1478bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() { 1479 return context_->IsCommandBufferContextLost(); 1480} 1481 1482DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) 1483 1484DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, 1485 GetFramebufferAttachmentParameteriv, 1486 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) 1487 1488DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) 1489 1490DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) 1491 1492WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1493 getProgramInfoLog(WebGLId program) { 1494 ClearContext(); 1495 GLint logLength = 0; 1496 gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 1497 if (!logLength) 1498 return WebKit::WebString(); 1499 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 1500 if (!log) 1501 return WebKit::WebString(); 1502 GLsizei returnedLogLength = 0; 1503 gl_->GetProgramInfoLog( 1504 program, logLength, &returnedLogLength, log.get()); 1505 DCHECK_EQ(logLength, returnedLogLength + 1); 1506 WebKit::WebString res = 1507 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); 1508 return res; 1509} 1510 1511DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv, 1512 WGC3Denum, WGC3Denum, WGC3Dint*) 1513 1514DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*) 1515 1516WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1517 getShaderInfoLog(WebGLId shader) { 1518 ClearContext(); 1519 GLint logLength = 0; 1520 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 1521 if (!logLength) 1522 return WebKit::WebString(); 1523 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 1524 if (!log) 1525 return WebKit::WebString(); 1526 GLsizei returnedLogLength = 0; 1527 gl_->GetShaderInfoLog( 1528 shader, logLength, &returnedLogLength, log.get()); 1529 DCHECK_EQ(logLength, returnedLogLength + 1); 1530 WebKit::WebString res = 1531 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); 1532 return res; 1533} 1534 1535DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat, 1536 WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*) 1537 1538WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1539 getShaderSource(WebGLId shader) { 1540 ClearContext(); 1541 GLint logLength = 0; 1542 gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); 1543 if (!logLength) 1544 return WebKit::WebString(); 1545 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 1546 if (!log) 1547 return WebKit::WebString(); 1548 GLsizei returnedLogLength = 0; 1549 gl_->GetShaderSource( 1550 shader, logLength, &returnedLogLength, log.get()); 1551 if (!returnedLogLength) 1552 return WebKit::WebString(); 1553 DCHECK_EQ(logLength, returnedLogLength + 1); 1554 WebKit::WebString res = 1555 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); 1556 return res; 1557} 1558 1559WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1560 getTranslatedShaderSourceANGLE(WebGLId shader) { 1561 ClearContext(); 1562 GLint logLength = 0; 1563 gl_->GetShaderiv( 1564 shader, GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, &logLength); 1565 if (!logLength) 1566 return WebKit::WebString(); 1567 scoped_ptr<GLchar[]> log(new GLchar[logLength]); 1568 if (!log) 1569 return WebKit::WebString(); 1570 GLsizei returnedLogLength = 0; 1571 gl_->GetTranslatedShaderSourceANGLE( 1572 shader, logLength, &returnedLogLength, log.get()); 1573 if (!returnedLogLength) 1574 return WebKit::WebString(); 1575 DCHECK_EQ(logLength, returnedLogLength + 1); 1576 WebKit::WebString res = 1577 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); 1578 return res; 1579} 1580 1581WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString( 1582 WGC3Denum name) { 1583 ClearContext(); 1584 return WebKit::WebString::fromUTF8( 1585 reinterpret_cast<const char*>(gl_->GetString(name))); 1586} 1587 1588DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, 1589 WGC3Denum, WGC3Denum, WGC3Dfloat*) 1590 1591DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, 1592 WGC3Denum, WGC3Denum, WGC3Dint*) 1593 1594DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*) 1595 1596DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*) 1597 1598DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, 1599 WebGLId, const WGC3Dchar*, WGC3Dint) 1600 1601DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, 1602 WGC3Duint, WGC3Denum, WGC3Dfloat*) 1603 1604DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, 1605 WGC3Duint, WGC3Denum, WGC3Dint*) 1606 1607WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl:: 1608 getVertexAttribOffset(WGC3Duint index, WGC3Denum pname) { 1609 ClearContext(); 1610 GLvoid* value = NULL; 1611 // NOTE: If pname is ever a value that returns more then 1 element 1612 // this will corrupt memory. 1613 gl_->GetVertexAttribPointerv(index, pname, &value); 1614 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value)); 1615} 1616 1617DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) 1618 1619DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) 1620 1621DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) 1622 1623DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean) 1624 1625DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) 1626 1627DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean) 1628 1629DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) 1630 1631DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean) 1632 1633DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat) 1634 1635DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) 1636 1637DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) 1638 1639DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) 1640 1641DELEGATE_TO_GL_7(readPixels, ReadPixels, 1642 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum, 1643 WGC3Denum, void*) 1644 1645void WebGraphicsContext3DInProcessCommandBufferImpl::releaseShaderCompiler() { 1646 ClearContext(); 1647} 1648 1649DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage, 1650 WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei) 1651 1652DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean) 1653 1654DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) 1655 1656void WebGraphicsContext3DInProcessCommandBufferImpl::shaderSource( 1657 WebGLId shader, const WGC3Dchar* string) { 1658 ClearContext(); 1659 GLint length = strlen(string); 1660 gl_->ShaderSource(shader, 1, &string, &length); 1661} 1662 1663DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) 1664 1665DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, 1666 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint) 1667 1668DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint) 1669 1670DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, 1671 WGC3Denum, WGC3Duint) 1672 1673DELEGATE_TO_GL_3(stencilOp, StencilOp, 1674 WGC3Denum, WGC3Denum, WGC3Denum) 1675 1676DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, 1677 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) 1678 1679DELEGATE_TO_GL_9(texImage2D, TexImage2D, 1680 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, 1681 WGC3Dint, WGC3Denum, WGC3Denum, const void*) 1682 1683DELEGATE_TO_GL_3(texParameterf, TexParameterf, 1684 WGC3Denum, WGC3Denum, WGC3Dfloat); 1685 1686static const unsigned int kTextureWrapR = 0x8072; 1687 1688void WebGraphicsContext3DInProcessCommandBufferImpl::texParameteri( 1689 WGC3Denum target, WGC3Denum pname, WGC3Dint param) { 1690 ClearContext(); 1691 // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in 1692 // GraphicsContext3D.cpp is strictly necessary to avoid seams at the 1693 // edge of cube maps, and, if it is, push it into the GLES2 service 1694 // side code. 1695 if (pname == kTextureWrapR) { 1696 return; 1697 } 1698 gl_->TexParameteri(target, pname, param); 1699} 1700 1701DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, 1702 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, 1703 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) 1704 1705DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) 1706 1707DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei, 1708 const WGC3Dfloat*) 1709 1710DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) 1711 1712DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1713 1714DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) 1715 1716DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei, 1717 const WGC3Dfloat*) 1718 1719DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) 1720 1721DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1722 1723DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint, 1724 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1725 1726DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei, 1727 const WGC3Dfloat*) 1728 1729DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) 1730 1731DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1732 1733DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, 1734 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1735 1736DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei, 1737 const WGC3Dfloat*) 1738 1739DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, 1740 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) 1741 1742DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1743 1744DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, 1745 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1746 1747DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, 1748 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1749 1750DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, 1751 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1752 1753DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) 1754 1755DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) 1756 1757DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) 1758 1759DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, 1760 const WGC3Dfloat*) 1761 1762DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint, 1763 WGC3Dfloat, WGC3Dfloat) 1764 1765DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, 1766 const WGC3Dfloat*) 1767 1768DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint, 1769 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1770 1771DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, 1772 const WGC3Dfloat*) 1773 1774DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint, 1775 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1776 1777DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, 1778 const WGC3Dfloat*) 1779 1780void WebGraphicsContext3DInProcessCommandBufferImpl::vertexAttribPointer( 1781 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, 1782 WGC3Dsizei stride, WGC3Dintptr offset) { 1783 ClearContext(); 1784 gl_->VertexAttribPointer( 1785 index, size, type, normalized, stride, 1786 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 1787} 1788 1789DELEGATE_TO_GL_4(viewport, Viewport, 1790 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) 1791 1792WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createBuffer() { 1793 ClearContext(); 1794 GLuint o; 1795 gl_->GenBuffers(1, &o); 1796 return o; 1797} 1798 1799WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createFramebuffer() { 1800 ClearContext(); 1801 GLuint o = 0; 1802 gl_->GenFramebuffers(1, &o); 1803 return o; 1804} 1805 1806WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createProgram() { 1807 ClearContext(); 1808 return gl_->CreateProgram(); 1809} 1810 1811WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createRenderbuffer() { 1812 ClearContext(); 1813 GLuint o; 1814 gl_->GenRenderbuffers(1, &o); 1815 return o; 1816} 1817 1818DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId); 1819 1820WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createTexture() { 1821 ClearContext(); 1822 GLuint o; 1823 gl_->GenTextures(1, &o); 1824 return o; 1825} 1826 1827void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer( 1828 WebGLId buffer) { 1829 ClearContext(); 1830 gl_->DeleteBuffers(1, &buffer); 1831} 1832 1833void WebGraphicsContext3DInProcessCommandBufferImpl::deleteFramebuffer( 1834 WebGLId framebuffer) { 1835 ClearContext(); 1836 gl_->DeleteFramebuffers(1, &framebuffer); 1837} 1838 1839void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram( 1840 WebGLId program) { 1841 ClearContext(); 1842 gl_->DeleteProgram(program); 1843} 1844 1845void WebGraphicsContext3DInProcessCommandBufferImpl::deleteRenderbuffer( 1846 WebGLId renderbuffer) { 1847 ClearContext(); 1848 gl_->DeleteRenderbuffers(1, &renderbuffer); 1849} 1850 1851void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader( 1852 WebGLId shader) { 1853 ClearContext(); 1854 gl_->DeleteShader(shader); 1855} 1856 1857void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture( 1858 WebGLId texture) { 1859 ClearContext(); 1860 gl_->DeleteTextures(1, &texture); 1861} 1862 1863void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToCompositor( 1864 WebGLId texture, WebGLId parentTexture) { 1865 NOTIMPLEMENTED(); 1866} 1867 1868void WebGraphicsContext3DInProcessCommandBufferImpl::OnSwapBuffersComplete() { 1869} 1870 1871void WebGraphicsContext3DInProcessCommandBufferImpl::setContextLostCallback( 1872 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) { 1873 context_lost_callback_ = cb; 1874} 1875 1876WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl:: 1877 getGraphicsResetStatusARB() { 1878 return context_lost_reason_; 1879} 1880 1881DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, 1882 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) 1883 1884DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, 1885 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) 1886 1887WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createQueryEXT() { 1888 GLuint o; 1889 gl_->GenQueriesEXT(1, &o); 1890 return o; 1891} 1892 1893void WebGraphicsContext3DInProcessCommandBufferImpl:: 1894 deleteQueryEXT(WebGLId query) { 1895 gl_->DeleteQueriesEXT(1, &query); 1896} 1897 1898DELEGATE_TO_GL_1R(isQueryEXT, IsQueryEXT, WebGLId, WGC3Dboolean) 1899DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryEXT, WGC3Denum, WebGLId) 1900DELEGATE_TO_GL_1(endQueryEXT, EndQueryEXT, WGC3Denum) 1901DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivEXT, WGC3Denum, WGC3Denum, WGC3Dint*) 1902DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivEXT, 1903 WebGLId, WGC3Denum, WGC3Duint*) 1904 1905DELEGATE_TO_GL_6(copyTextureCHROMIUM, CopyTextureCHROMIUM, WGC3Denum, WGC3Duint, 1906 WGC3Duint, WGC3Dint, WGC3Denum, WGC3Denum) 1907 1908void WebGraphicsContext3DInProcessCommandBufferImpl::insertEventMarkerEXT( 1909 const WGC3Dchar* marker) { 1910 gl_->InsertEventMarkerEXT(0, marker); 1911} 1912 1913void WebGraphicsContext3DInProcessCommandBufferImpl::pushGroupMarkerEXT( 1914 const WGC3Dchar* marker) { 1915 gl_->PushGroupMarkerEXT(0, marker); 1916} 1917 1918DELEGATE_TO_GL(popGroupMarkerEXT, PopGroupMarkerEXT); 1919 1920DELEGATE_TO_GL_2(bindTexImage2DCHROMIUM, BindTexImage2DCHROMIUM, 1921 WGC3Denum, WGC3Dint) 1922DELEGATE_TO_GL_2(releaseTexImage2DCHROMIUM, ReleaseTexImage2DCHROMIUM, 1923 WGC3Denum, WGC3Dint) 1924 1925void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferCHROMIUM( 1926 WGC3Denum target, WGC3Denum access) { 1927 ClearContext(); 1928 return gl_->MapBufferCHROMIUM(target, access); 1929} 1930 1931WGC3Dboolean WebGraphicsContext3DInProcessCommandBufferImpl:: 1932 unmapBufferCHROMIUM(WGC3Denum target) { 1933 ClearContext(); 1934 return gl_->UnmapBufferCHROMIUM(target); 1935} 1936 1937GrGLInterface* WebGraphicsContext3DInProcessCommandBufferImpl:: 1938 onCreateGrGLInterface() { 1939 return CreateCommandBufferSkiaGLBinding(); 1940} 1941 1942void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { 1943 // TODO(kbr): improve the precision here. 1944 context_lost_reason_ = GL_UNKNOWN_CONTEXT_RESET_ARB; 1945 if (context_lost_callback_) { 1946 context_lost_callback_->onContextLost(); 1947 } 1948} 1949 1950DELEGATE_TO_GL_3R(createImageCHROMIUM, CreateImageCHROMIUM, 1951 WGC3Dsizei, WGC3Dsizei, WGC3Denum, WGC3Duint); 1952 1953DELEGATE_TO_GL_1(destroyImageCHROMIUM, DestroyImageCHROMIUM, WGC3Duint); 1954 1955DELEGATE_TO_GL_3(getImageParameterivCHROMIUM, GetImageParameterivCHROMIUM, 1956 WGC3Duint, WGC3Denum, GLint*); 1957 1958DELEGATE_TO_GL_2R(mapImageCHROMIUM, MapImageCHROMIUM, 1959 WGC3Duint, WGC3Denum, void*); 1960 1961DELEGATE_TO_GL_1(unmapImageCHROMIUM, UnmapImageCHROMIUM, WGC3Duint); 1962 1963DELEGATE_TO_GL_3(bindUniformLocationCHROMIUM, BindUniformLocationCHROMIUM, 1964 WebGLId, WGC3Dint, const WGC3Dchar*) 1965 1966DELEGATE_TO_GL(shallowFlushCHROMIUM, ShallowFlushCHROMIUM) 1967 1968DELEGATE_TO_GL_1(genMailboxCHROMIUM, GenMailboxCHROMIUM, WGC3Dbyte*) 1969DELEGATE_TO_GL_2(produceTextureCHROMIUM, ProduceTextureCHROMIUM, 1970 WGC3Denum, const WGC3Dbyte*) 1971DELEGATE_TO_GL_2(consumeTextureCHROMIUM, ConsumeTextureCHROMIUM, 1972 WGC3Denum, const WGC3Dbyte*) 1973 1974DELEGATE_TO_GL_2(drawBuffersEXT, DrawBuffersEXT, 1975 WGC3Dsizei, const WGC3Denum*) 1976 1977unsigned WebGraphicsContext3DInProcessCommandBufferImpl::insertSyncPoint() { 1978 shallowFlushCHROMIUM(); 1979 return 0; 1980} 1981 1982void WebGraphicsContext3DInProcessCommandBufferImpl::signalSyncPoint( 1983 unsigned sync_point, 1984 WebGraphicsSyncPointCallback* callback) { 1985 // Take ownership of the callback. 1986 context_->SetSignalSyncPointCallback(make_scoped_ptr(callback)); 1987 // Stick something in the command buffer. 1988 shallowFlushCHROMIUM(); 1989} 1990 1991void WebGraphicsContext3DInProcessCommandBufferImpl::loseContextCHROMIUM( 1992 WGC3Denum current, WGC3Denum other) { 1993 context_->LoseContext(current, other); 1994} 1995 1996DELEGATE_TO_GL_9(asyncTexImage2DCHROMIUM, AsyncTexImage2DCHROMIUM, 1997 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, WGC3Dint, 1998 WGC3Denum, WGC3Denum, const void*) 1999 2000DELEGATE_TO_GL_9(asyncTexSubImage2DCHROMIUM, AsyncTexSubImage2DCHROMIUM, 2001 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, 2002 WGC3Denum, WGC3Denum, const void*) 2003 2004DELEGATE_TO_GL_1(waitAsyncTexImage2DCHROMIUM, WaitAsyncTexImage2DCHROMIUM, 2005 WGC3Denum) 2006 2007void WebGraphicsContext3DInProcessCommandBufferImpl::SetGpuMemoryBufferCreator( 2008 GpuMemoryBufferCreator* creator) { 2009 g_gpu_memory_buffer_creator = creator; 2010} 2011 2012} // namespace gpu 2013} // namespace webkit 2014