OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #if defined(ENABLE_GPU) |
| 6 |
5 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" | 7 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" |
6 | 8 |
7 #include <string.h> | 9 #include <GLES2/gl2.h> |
| 10 #ifndef GL_GLEXT_PROTOTYPES |
| 11 #define GL_GLEXT_PROTOTYPES 1 |
| 12 #endif |
| 13 #include <GLES2/gl2ext.h> |
8 | 14 |
9 #include <algorithm> | 15 #include <algorithm> |
10 #include <string> | 16 |
11 | 17 #include "base/string_tokenizer.h" |
| 18 #include "base/command_line.h" |
| 19 #include "base/lazy_instance.h" |
12 #include "base/logging.h" | 20 #include "base/logging.h" |
13 #include "base/memory/scoped_ptr.h" | 21 #include "base/memory/singleton.h" |
| 22 #include "base/metrics/histogram.h" |
| 23 #include "gpu/command_buffer/client/gles2_lib.h" |
| 24 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 25 #include "gpu/command_buffer/common/constants.h" |
| 26 #include "gpu/command_buffer/service/gpu_scheduler.h" |
| 27 #include "gpu/command_buffer/service/command_buffer_service.h" |
| 28 #include "gpu/GLES2/gles2_command_buffer.h" |
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" | |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
17 #include "ui/gfx/gl/gl_bindings.h" | 31 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" |
18 #include "ui/gfx/gl/gl_bindings_skia_in_process.h" | 32 |
19 #include "ui/gfx/gl/gl_context.h" | 33 using gpu::Buffer; |
20 #include "ui/gfx/gl/gl_implementation.h" | 34 using gpu::CommandBuffer; |
21 #include "ui/gfx/gl/gl_surface.h" | 35 using gpu::CommandBufferService; |
| 36 using gpu::gles2::GLES2CmdHelper; |
| 37 using gpu::gles2::GLES2Implementation; |
| 38 using gpu::GpuScheduler; |
22 | 39 |
23 namespace webkit { | 40 namespace webkit { |
24 namespace gpu { | 41 namespace gpu { |
25 | 42 |
26 enum { | 43 class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> { |
27 MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, | 44 public: |
28 MAX_VARYING_VECTORS = 0x8DFC, | 45 // These are the same error codes as used by EGL. |
29 MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD | 46 enum Error { |
| 47 SUCCESS = 0x3000, |
| 48 NOT_INITIALIZED = 0x3001, |
| 49 BAD_ATTRIBUTE = 0x3004, |
| 50 BAD_GLContext = 0x3006, |
| 51 CONTEXT_LOST = 0x300E |
| 52 }; |
| 53 |
| 54 // GLInProcessContext configuration attributes. These are the same as used by |
| 55 // EGL. Attributes are matched using a closest fit algorithm. |
| 56 enum Attribute { |
| 57 ALPHA_SIZE = 0x3021, |
| 58 BLUE_SIZE = 0x3022, |
| 59 GREEN_SIZE = 0x3023, |
| 60 RED_SIZE = 0x3024, |
| 61 DEPTH_SIZE = 0x3025, |
| 62 STENCIL_SIZE = 0x3026, |
| 63 SAMPLES = 0x3031, |
| 64 SAMPLE_BUFFERS = 0x3032, |
| 65 NONE = 0x3038 // Attrib list = terminator |
| 66 }; |
| 67 |
| 68 // Initialize the library. This must have completed before any other |
| 69 // functions are invoked. |
| 70 static bool Initialize(); |
| 71 |
| 72 // Terminate the library. This must be called after any other functions |
| 73 // have completed. |
| 74 static bool Terminate(); |
| 75 |
| 76 ~GLInProcessContext(); |
| 77 |
| 78 // Create a GLInProcessContext that renders directly to a view. The view and |
| 79 // the associated window must not be destroyed until the returned |
| 80 // GLInProcessContext has been destroyed, otherwise the GPU process might |
| 81 // attempt to render to an invalid window handle. |
| 82 // |
| 83 // NOTE: on Mac OS X, this entry point is only used to set up the |
| 84 // accelerated compositor's output. On this platform, we actually pass |
| 85 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, |
| 86 // because the facility to allocate a fake PluginWindowHandle is |
| 87 // already in place. We could add more entry points and messages to |
| 88 // allocate both fake PluginWindowHandles and NativeViewIds and map |
| 89 // from fake NativeViewIds to PluginWindowHandles, but this seems like |
| 90 // unnecessary complexity at the moment. |
| 91 // |
| 92 static GLInProcessContext* CreateViewContext( |
| 93 gfx::PluginWindowHandle render_surface, |
| 94 const char* allowed_extensions, |
| 95 const int32* attrib_list, |
| 96 const GURL& active_arl); |
| 97 |
| 98 #if defined(OS_MACOSX) |
| 99 // On Mac OS X only, view GLInProcessContexts actually behave like offscreen |
| 100 // GLInProcessContexts, and require an explicit resize operation which is |
| 101 // slightly different from that of offscreen GLInProcessContexts. |
| 102 void ResizeOnscreen(const gfx::Size& size); |
| 103 #endif |
| 104 |
| 105 // Create a GLInProcessContext that renders to an offscreen frame buffer. If |
| 106 // parent is not NULL, that GLInProcessContext can access a copy of the |
| 107 // created GLInProcessContext's frame buffer that is updated every time |
| 108 // SwapBuffers is called. It is not as general as shared GLInProcessContexts |
| 109 // in other implementations of OpenGL. If parent is not NULL, it must be used |
| 110 // on the same thread as the parent. A child GLInProcessContext may not |
| 111 // outlive its parent. attrib_list must be NULL or a NONE-terminated list of |
| 112 // attribute/value pairs. |
| 113 static GLInProcessContext* CreateOffscreenContext( |
| 114 GLInProcessContext* parent, |
| 115 const gfx::Size& size, |
| 116 const char* allowed_extensions, |
| 117 const int32* attrib_list, |
| 118 const GURL& active_url); |
| 119 |
| 120 // Resize an offscreen frame buffer. The resize occurs on the next call to |
| 121 // SwapBuffers. This is to avoid waiting until all pending GL calls have been |
| 122 // executed by the GPU process. Everything rendered up to the call to |
| 123 // SwapBuffers will be lost. A lost GLInProcessContext will be reported if the |
| 124 // resize fails. |
| 125 void ResizeOffscreen(const gfx::Size& size); |
| 126 |
| 127 // For an offscreen frame buffer GLInProcessContext, return the texture ID |
| 128 // with respect to the parent GLInProcessContext. Returns zero if |
| 129 // GLInProcessContext does not have a parent. |
| 130 uint32 GetParentTextureId(); |
| 131 |
| 132 // Create a new texture in the parent's GLInProcessContext. Returns zero if |
| 133 // GLInProcessContext does not have a parent. |
| 134 uint32 CreateParentTexture(const gfx::Size& size); |
| 135 |
| 136 // Deletes a texture in the parent's GLInProcessContext. |
| 137 void DeleteParentTexture(uint32 texture); |
| 138 |
| 139 // Provides a callback that will be invoked when SwapBuffers has completed |
| 140 // service side. |
| 141 void SetSwapBuffersCallback(Callback0::Type* callback); |
| 142 |
| 143 void SetContextLostCallback(Callback0::Type* callback); |
| 144 |
| 145 // Set the current GLInProcessContext for the calling thread. |
| 146 static bool MakeCurrent(GLInProcessContext* context); |
| 147 |
| 148 // For a view GLInProcessContext, display everything that has been rendered |
| 149 // since the last call. For an offscreen GLInProcessContext, resolve |
| 150 // everything that has been rendered since the last call to a copy that can be |
| 151 // accessed by the parent GLInProcessContext. |
| 152 bool SwapBuffers(); |
| 153 |
| 154 // TODO(gman): Remove this |
| 155 void DisableShaderTranslation(); |
| 156 |
| 157 // Allows direct access to the GLES2 implementation so a GLInProcessContext |
| 158 // can be used without making it current. |
| 159 GLES2Implementation* GetImplementation(); |
| 160 |
| 161 // Return the current error. |
| 162 Error GetError(); |
| 163 |
| 164 // Return true if GPU process reported GLInProcessContext lost or there was a |
| 165 // problem communicating with the GPU process. |
| 166 bool IsCommandBufferContextLost(); |
| 167 |
| 168 CommandBufferService* GetCommandBufferService(); |
| 169 |
| 170 // Create a latch for synchronization between contexts using glSetLatch and |
| 171 // glWaitLatch. |
| 172 // CreateLatch will only fail if there is a generally unrecoverable |
| 173 // error, in which case 0 is returned. Returns latch_id on success. |
| 174 bool CreateLatch(uint32* ret_latch); |
| 175 |
| 176 // Destroy a latch. |
| 177 bool DestroyLatch(uint32 latch); |
| 178 |
| 179 // All child contexts get a latch pair automatically. These latches are used |
| 180 // for synchronization with parent context. If *this* context does not have a |
| 181 // parent context, these methods will return false. |
| 182 bool GetParentToChildLatch(uint32* parent_to_child_latch); |
| 183 bool GetChildToParentLatch(uint32* child_to_parent_latch); |
| 184 |
| 185 private: |
| 186 GLInProcessContext(GLInProcessContext* parent); |
| 187 |
| 188 bool Initialize(bool onscreen, |
| 189 gfx::PluginWindowHandle render_surface, |
| 190 const gfx::Size& size, |
| 191 const char* allowed_extensions, |
| 192 const int32* attrib_list, |
| 193 const GURL& active_url); |
| 194 void Destroy(); |
| 195 |
| 196 void OnSwapBuffers(); |
| 197 void OnContextLost(); |
| 198 |
| 199 base::WeakPtr<GLInProcessContext> parent_; |
| 200 scoped_ptr<Callback0::Type> swap_buffers_callback_; |
| 201 scoped_ptr<Callback0::Type> context_lost_callback_; |
| 202 uint32 parent_texture_id_; |
| 203 uint32 child_to_parent_latch_; |
| 204 uint32 parent_to_child_latch_; |
| 205 int32 latch_transfer_buffer_id_; |
| 206 scoped_ptr<CommandBufferService> command_buffer_; |
| 207 GpuScheduler* gpu_scheduler_; |
| 208 GLES2CmdHelper* gles2_helper_; |
| 209 int32 transfer_buffer_id_; |
| 210 GLES2Implementation* gles2_implementation_; |
| 211 gfx::Size size_; |
| 212 Error last_error_; |
| 213 |
| 214 DISALLOW_COPY_AND_ASSIGN(GLInProcessContext); |
30 }; | 215 }; |
31 | 216 |
32 struct WebGraphicsContext3DInProcessCommandBufferImpl::ShaderSourceEntry { | 217 namespace { |
33 explicit ShaderSourceEntry(WGC3Denum shader_type) | 218 |
34 : type(shader_type), | 219 const int32 kCommandBufferSize = 1024 * 1024; |
35 is_valid(false) { | 220 // TODO(kbr): make the transfer buffer size configurable via context |
36 } | 221 // creation attributes. |
37 | 222 const int32 kTransferBufferSize = 1024 * 1024; |
38 WGC3Denum type; | 223 |
39 scoped_array<char> source; | 224 const uint32 kMaxLatchesPerRenderer = 2048; |
40 scoped_array<char> log; | 225 const uint32 kInvalidLatchId = 0xffffffffu; |
41 scoped_array<char> translated_source; | 226 |
42 bool is_valid; | 227 // Singleton used to initialize and terminate the gles2 library. |
| 228 class GLES2Initializer { |
| 229 public: |
| 230 GLES2Initializer() { |
| 231 gles2::Initialize(); |
| 232 } |
| 233 |
| 234 ~GLES2Initializer() { |
| 235 gles2::Terminate(); |
| 236 } |
| 237 |
| 238 private: |
| 239 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); |
43 }; | 240 }; |
44 | 241 |
45 WebGraphicsContext3DInProcessCommandBufferImpl::WebGraphicsContext3DInProcessCom
mandBufferImpl() | 242 // Allocator for latches. |
46 : initialized_(false), | 243 class LatchAllocator { |
47 render_directly_to_web_view_(false), | 244 public: |
48 is_gles2_(false), | 245 static LatchAllocator* GetInstance(); |
49 have_ext_framebuffer_object_(false), | 246 static uint32 size() { return kMaxLatchesPerRenderer*sizeof(uint32); } |
50 have_ext_framebuffer_multisample_(false), | 247 static const uint32_t kFreeLatch = 0xffffffffu; |
51 have_angle_framebuffer_multisample_(false), | 248 |
52 texture_(0), | 249 LatchAllocator(); |
53 fbo_(0), | 250 ~LatchAllocator(); |
54 depth_stencil_buffer_(0), | 251 |
| 252 bool AllocateLatch(uint32* latch_id); |
| 253 bool FreeLatch(uint32 latch_id); |
| 254 |
| 255 private: |
| 256 friend struct DefaultSingletonTraits<LatchAllocator>; |
| 257 |
| 258 scoped_array<uint32> latches_; |
| 259 |
| 260 DISALLOW_COPY_AND_ASSIGN(LatchAllocator); |
| 261 }; |
| 262 |
| 263 //////////////////////////////////////////////////////////////////////////////// |
| 264 /// LatchAllocator implementation |
| 265 |
| 266 LatchAllocator* LatchAllocator::GetInstance() { |
| 267 return Singleton<LatchAllocator>::get(); |
| 268 } |
| 269 |
| 270 LatchAllocator::LatchAllocator() { |
| 271 latches_.reset(new uint32[size()]); |
| 272 // Mark all latches as unallocated. |
| 273 for (uint32 i = 0; i < kMaxLatchesPerRenderer; ++i) |
| 274 latches_[i] = kFreeLatch; |
| 275 } |
| 276 |
| 277 LatchAllocator::~LatchAllocator() { |
| 278 } |
| 279 |
| 280 bool LatchAllocator::AllocateLatch(uint32* latch_id) { |
| 281 for (uint32 i = 0; i < kMaxLatchesPerRenderer; ++i) { |
| 282 if (latches_[i] == kFreeLatch) { |
| 283 // mark latch as taken and blocked. |
| 284 // 0 means waiter will block, 1 means waiter will pass. |
| 285 latches_[i] = 0; |
| 286 *latch_id = i; |
| 287 return true; |
| 288 } |
| 289 } |
| 290 return false; |
| 291 } |
| 292 |
| 293 bool LatchAllocator::FreeLatch(uint32 latch_id) { |
| 294 if (latch_id < kMaxLatchesPerRenderer && latches_[latch_id] != kFreeLatch) { |
| 295 latches_[latch_id] = kFreeLatch; |
| 296 return true; |
| 297 } |
| 298 return false; |
| 299 } |
| 300 |
| 301 //////////////////////////////////////////////////////////////////////////////// |
| 302 |
| 303 static base::LazyInstance<GLES2Initializer> g_gles2_initializer( |
| 304 base::LINKER_INITIALIZED); |
| 305 |
| 306 } // namespace anonymous |
| 307 |
| 308 GLInProcessContext::~GLInProcessContext() { |
| 309 Destroy(); |
| 310 } |
| 311 |
| 312 GLInProcessContext* GLInProcessContext::CreateViewContext( |
| 313 gfx::PluginWindowHandle render_surface, |
| 314 const char* allowed_extensions, |
| 315 const int32* attrib_list, |
| 316 const GURL& active_url) { |
| 317 #if defined(ENABLE_GPU) |
| 318 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL)); |
| 319 if (!context->Initialize( |
| 320 true, |
| 321 render_surface, |
| 322 gfx::Size(), |
| 323 allowed_extensions, |
| 324 attrib_list, |
| 325 active_url)) |
| 326 return NULL; |
| 327 |
| 328 return context.release(); |
| 329 #else |
| 330 return NULL; |
| 331 #endif |
| 332 } |
| 333 |
| 334 #if defined(OS_MACOSX) |
| 335 void GLInProcessContext::ResizeOnscreen(const gfx::Size& size) { |
| 336 DCHECK(size.width() > 0 && size.height() > 0); |
| 337 size_ = size; |
| 338 } |
| 339 #endif |
| 340 |
| 341 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( |
| 342 GLInProcessContext* parent, |
| 343 const gfx::Size& size, |
| 344 const char* allowed_extensions, |
| 345 const int32* attrib_list, |
| 346 const GURL& active_url) { |
| 347 #if defined(ENABLE_GPU) |
| 348 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); |
| 349 if (!context->Initialize( |
| 350 false, |
| 351 gfx::kNullPluginWindow, |
| 352 size, |
| 353 allowed_extensions, |
| 354 attrib_list, |
| 355 active_url)) |
| 356 return NULL; |
| 357 |
| 358 return context.release(); |
| 359 #else |
| 360 return NULL; |
| 361 #endif |
| 362 } |
| 363 |
| 364 void GLInProcessContext::ResizeOffscreen(const gfx::Size& size) { |
| 365 DCHECK(size.width() > 0 && size.height() > 0); |
| 366 if (size_ != size) { |
| 367 gpu_scheduler_->ResizeOffscreenFrameBuffer(size); |
| 368 // TODO(gman): See if the next line is needed. |
| 369 gles2_implementation_->ResizeCHROMIUM(size.width(), size.height()); |
| 370 size_ = size; |
| 371 } |
| 372 } |
| 373 |
| 374 uint32 GLInProcessContext::GetParentTextureId() { |
| 375 return parent_texture_id_; |
| 376 } |
| 377 |
| 378 uint32 GLInProcessContext::CreateParentTexture(const gfx::Size& size) { |
| 379 // Allocate a texture ID with respect to the parent. |
| 380 if (parent_.get()) { |
| 381 if (!MakeCurrent(parent_.get())) |
| 382 return 0; |
| 383 uint32 texture_id = parent_->gles2_implementation_->MakeTextureId(); |
| 384 parent_->gles2_implementation_->BindTexture(GL_TEXTURE_2D, texture_id); |
| 385 parent_->gles2_implementation_->TexParameteri( |
| 386 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 387 parent_->gles2_implementation_->TexParameteri( |
| 388 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 389 parent_->gles2_implementation_->TexParameteri( |
| 390 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 391 parent_->gles2_implementation_->TexParameteri( |
| 392 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 393 |
| 394 parent_->gles2_implementation_->TexImage2D(GL_TEXTURE_2D, |
| 395 0, // mip level |
| 396 GL_RGBA, |
| 397 size.width(), |
| 398 size.height(), |
| 399 0, // border |
| 400 GL_RGBA, |
| 401 GL_UNSIGNED_BYTE, |
| 402 NULL); |
| 403 // Make sure that the parent texture's storage is allocated before we let |
| 404 // the caller attempt to use it. |
| 405 int32 token = parent_->gles2_helper_->InsertToken(); |
| 406 parent_->gles2_helper_->WaitForToken(token); |
| 407 return texture_id; |
| 408 } |
| 409 return 0; |
| 410 } |
| 411 |
| 412 void GLInProcessContext::DeleteParentTexture(uint32 texture) { |
| 413 if (parent_.get()) { |
| 414 if (!MakeCurrent(parent_.get())) |
| 415 return; |
| 416 parent_->gles2_implementation_->DeleteTextures(1, &texture); |
| 417 } |
| 418 } |
| 419 |
| 420 void GLInProcessContext::SetSwapBuffersCallback(Callback0::Type* callback) { |
| 421 swap_buffers_callback_.reset(callback); |
| 422 } |
| 423 |
| 424 void GLInProcessContext::SetContextLostCallback(Callback0::Type* callback) { |
| 425 context_lost_callback_.reset(callback); |
| 426 } |
| 427 |
| 428 bool GLInProcessContext::MakeCurrent(GLInProcessContext* context) { |
| 429 if (context) { |
| 430 gles2::SetGLContext(context->gles2_implementation_); |
| 431 |
| 432 // Don't request latest error status from service. Just use the locally |
| 433 // cached information from the last flush. |
| 434 // TODO(apatrick): I'm not sure if this should actually change the |
| 435 // current context if it fails. For now it gets changed even if it fails |
| 436 // because making GL calls with a NULL context crashes. |
| 437 if (context->command_buffer_->GetState().error != ::gpu::error::kNoError) |
| 438 return false; |
| 439 } else { |
| 440 gles2::SetGLContext(NULL); |
| 441 } |
| 442 |
| 443 return true; |
| 444 } |
| 445 |
| 446 bool GLInProcessContext::SwapBuffers() { |
| 447 // Don't request latest error status from service. Just use the locally cached |
| 448 // information from the last flush. |
| 449 if (command_buffer_->GetState().error != ::gpu::error::kNoError) |
| 450 return false; |
| 451 |
| 452 gles2_implementation_->SwapBuffers(); |
| 453 gles2_implementation_->Finish(); |
| 454 return true; |
| 455 } |
| 456 |
| 457 GLInProcessContext::Error GLInProcessContext::GetError() { |
| 458 CommandBuffer::State state = command_buffer_->GetState(); |
| 459 if (state.error == ::gpu::error::kNoError) { |
| 460 Error old_error = last_error_; |
| 461 last_error_ = SUCCESS; |
| 462 return old_error; |
| 463 } else { |
| 464 // All command buffer errors are unrecoverable. The error is treated as a |
| 465 // lost context: destroy the context and create another one. |
| 466 return CONTEXT_LOST; |
| 467 } |
| 468 } |
| 469 |
| 470 bool GLInProcessContext::IsCommandBufferContextLost() { |
| 471 CommandBuffer::State state = command_buffer_->GetState(); |
| 472 return state.error == ::gpu::error::kLostContext; |
| 473 } |
| 474 |
| 475 CommandBufferService* GLInProcessContext::GetCommandBufferService() { |
| 476 return command_buffer_.get(); |
| 477 } |
| 478 |
| 479 // TODO(gman): Remove This |
| 480 void GLInProcessContext::DisableShaderTranslation() { |
| 481 gles2_implementation_->CommandBufferEnableCHROMIUM( |
| 482 PEPPER3D_SKIP_GLSL_TRANSLATION); |
| 483 } |
| 484 |
| 485 GLES2Implementation* GLInProcessContext::GetImplementation() { |
| 486 return gles2_implementation_; |
| 487 } |
| 488 |
| 489 GLInProcessContext::GLInProcessContext(GLInProcessContext* parent) |
| 490 : parent_(parent ? |
| 491 parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), |
| 492 parent_texture_id_(0), |
| 493 child_to_parent_latch_(kInvalidLatchId), |
| 494 parent_to_child_latch_(kInvalidLatchId), |
| 495 latch_transfer_buffer_id_(-1), |
| 496 gpu_scheduler_(NULL), |
| 497 gles2_helper_(NULL), |
| 498 transfer_buffer_id_(-1), |
| 499 gles2_implementation_(NULL), |
| 500 last_error_(SUCCESS) { |
| 501 } |
| 502 |
| 503 bool GLInProcessContext::Initialize(bool onscreen, |
| 504 gfx::PluginWindowHandle render_surface, |
| 505 const gfx::Size& size, |
| 506 const char* allowed_extensions, |
| 507 const int32* attrib_list, |
| 508 const GURL& active_url) { |
| 509 DCHECK(size.width() >= 0 && size.height() >= 0); |
| 510 |
| 511 // Ensure the gles2 library is initialized first in a thread safe way. |
| 512 g_gles2_initializer.Get(); |
| 513 |
| 514 // Allocate a frame buffer ID with respect to the parent. |
| 515 if (parent_.get()) { |
| 516 // Flush any remaining commands in the parent context to make sure the |
| 517 // texture id accounting stays consistent. |
| 518 int32 token = parent_->gles2_helper_->InsertToken(); |
| 519 parent_->gles2_helper_->WaitForToken(token); |
| 520 parent_texture_id_ = parent_->gles2_implementation_->MakeTextureId(); |
| 521 } |
| 522 |
| 523 std::vector<int32> attribs; |
| 524 while (attrib_list) { |
| 525 int32 attrib = *attrib_list++; |
| 526 switch (attrib) { |
| 527 // Known attributes |
| 528 case ALPHA_SIZE: |
| 529 case BLUE_SIZE: |
| 530 case GREEN_SIZE: |
| 531 case RED_SIZE: |
| 532 case DEPTH_SIZE: |
| 533 case STENCIL_SIZE: |
| 534 case SAMPLES: |
| 535 case SAMPLE_BUFFERS: |
| 536 attribs.push_back(attrib); |
| 537 attribs.push_back(*attrib_list++); |
| 538 break; |
| 539 case NONE: |
| 540 attribs.push_back(attrib); |
| 541 attrib_list = NULL; |
| 542 break; |
| 543 default: |
| 544 last_error_ = BAD_ATTRIBUTE; |
| 545 attribs.push_back(NONE); |
| 546 attrib_list = NULL; |
| 547 break; |
| 548 } |
| 549 } |
| 550 |
| 551 command_buffer_.reset(new CommandBufferService); |
| 552 if (!command_buffer_->Initialize(kCommandBufferSize)) |
| 553 return false; |
| 554 |
| 555 gpu_scheduler_ = new GpuScheduler(command_buffer_.get(), NULL, NULL); |
| 556 |
| 557 if (onscreen) { |
| 558 if (render_surface == gfx::kNullPluginWindow) { |
| 559 LOG(ERROR) << "Invalid surface handle for onscreen context."; |
| 560 command_buffer_.reset(); |
| 561 } else { |
| 562 if (!gpu_scheduler_->Initialize(render_surface, |
| 563 gfx::Size(), |
| 564 ::gpu::gles2::DisallowedExtensions(), |
| 565 allowed_extensions, |
| 566 attribs, |
| 567 NULL, |
| 568 0)) { |
| 569 LOG(ERROR) << "Could not initialize GpuScheduler."; |
| 570 command_buffer_.reset(); |
| 571 } |
| 572 } |
| 573 } else { |
| 574 GpuScheduler* parent_scheduler = |
| 575 parent_.get() ? parent_->gpu_scheduler_ : NULL; |
| 576 |
| 577 if (!gpu_scheduler_->Initialize(render_surface, |
| 578 size, |
| 579 ::gpu::gles2::DisallowedExtensions(), |
| 580 allowed_extensions, |
| 581 attribs, |
| 582 parent_scheduler, |
| 583 parent_texture_id_)) { |
| 584 LOG(ERROR) << "Could not initialize offscreen GpuScheduler."; |
| 585 command_buffer_.reset(); |
| 586 } |
| 587 } |
| 588 if (!command_buffer_.get()) { |
| 589 Destroy(); |
| 590 return false; |
| 591 } |
| 592 |
| 593 command_buffer_->SetPutOffsetChangeCallback( |
| 594 NewCallback(gpu_scheduler_, &GpuScheduler::PutChanged)); |
| 595 |
| 596 // Create the GLES2 helper, which writes the command buffer protocol. |
| 597 gles2_helper_ = new GLES2CmdHelper(command_buffer_.get()); |
| 598 if (!gles2_helper_->Initialize(kCommandBufferSize)) { |
| 599 Destroy(); |
| 600 return false; |
| 601 } |
| 602 |
| 603 // Create a transfer buffer. |
| 604 transfer_buffer_id_ = |
| 605 command_buffer_->CreateTransferBuffer( |
| 606 kTransferBufferSize, ::gpu::kCommandBufferSharedMemoryId); |
| 607 if (transfer_buffer_id_ < 0) { |
| 608 Destroy(); |
| 609 return false; |
| 610 } |
| 611 |
| 612 // Map the buffer. |
| 613 Buffer transfer_buffer = |
| 614 command_buffer_->GetTransferBuffer(transfer_buffer_id_); |
| 615 if (!transfer_buffer.ptr) { |
| 616 Destroy(); |
| 617 return false; |
| 618 } |
| 619 |
| 620 // If this is a child context, setup latches for synchronization between child |
| 621 // and parent. |
| 622 if (parent_.get()) { |
| 623 if (!CreateLatch(&child_to_parent_latch_) || |
| 624 !CreateLatch(&parent_to_child_latch_)) { |
| 625 Destroy(); |
| 626 return false; |
| 627 } |
| 628 } |
| 629 |
| 630 // Create the object exposing the OpenGL API. |
| 631 gles2_implementation_ = new GLES2Implementation( |
| 632 gles2_helper_, |
| 633 transfer_buffer.size, |
| 634 transfer_buffer.ptr, |
| 635 transfer_buffer_id_, |
| 636 false); |
| 637 |
| 638 size_ = size; |
| 639 |
| 640 return true; |
| 641 } |
| 642 |
| 643 void GLInProcessContext::Destroy() { |
| 644 if (parent_.get() && parent_texture_id_ != 0) { |
| 645 parent_->gles2_implementation_->FreeTextureId(parent_texture_id_); |
| 646 parent_texture_id_ = 0; |
| 647 } |
| 648 |
| 649 delete gles2_implementation_; |
| 650 gles2_implementation_ = NULL; |
| 651 |
| 652 if (child_to_parent_latch_ != kInvalidLatchId) { |
| 653 DestroyLatch(child_to_parent_latch_); |
| 654 child_to_parent_latch_ = kInvalidLatchId; |
| 655 } |
| 656 if (parent_to_child_latch_ != kInvalidLatchId) { |
| 657 DestroyLatch(parent_to_child_latch_); |
| 658 parent_to_child_latch_ = kInvalidLatchId; |
| 659 } |
| 660 if (command_buffer_.get() && latch_transfer_buffer_id_ != -1) { |
| 661 command_buffer_->DestroyTransferBuffer(latch_transfer_buffer_id_); |
| 662 latch_transfer_buffer_id_ = -1; |
| 663 } |
| 664 |
| 665 if (command_buffer_.get() && transfer_buffer_id_ != -1) { |
| 666 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); |
| 667 transfer_buffer_id_ = -1; |
| 668 } |
| 669 |
| 670 delete gles2_helper_; |
| 671 gles2_helper_ = NULL; |
| 672 |
| 673 command_buffer_.reset(); |
| 674 } |
| 675 |
| 676 void GLInProcessContext::OnSwapBuffers() { |
| 677 if (swap_buffers_callback_.get()) |
| 678 swap_buffers_callback_->Run(); |
| 679 } |
| 680 |
| 681 void GLInProcessContext::OnContextLost() { |
| 682 if (context_lost_callback_.get()) |
| 683 context_lost_callback_->Run(); |
| 684 } |
| 685 |
| 686 bool GLInProcessContext::CreateLatch(uint32* ret_latch) { |
| 687 return LatchAllocator::GetInstance()->AllocateLatch(ret_latch); |
| 688 } |
| 689 |
| 690 bool GLInProcessContext::DestroyLatch(uint32 latch) { |
| 691 return LatchAllocator::GetInstance()->FreeLatch(latch); |
| 692 } |
| 693 |
| 694 bool GLInProcessContext::GetParentToChildLatch(uint32* parent_to_child_latch) { |
| 695 if (parent_.get()) { |
| 696 *parent_to_child_latch = parent_to_child_latch_; |
| 697 return true; |
| 698 } |
| 699 return false; |
| 700 } |
| 701 |
| 702 bool GLInProcessContext::GetChildToParentLatch(uint32* child_to_parent_latch) { |
| 703 if (parent_.get()) { |
| 704 *child_to_parent_latch = child_to_parent_latch_; |
| 705 return true; |
| 706 } |
| 707 return false; |
| 708 } |
| 709 |
| 710 WebGraphicsContext3DInProcessCommandBufferImpl:: |
| 711 WebGraphicsContext3DInProcessCommandBufferImpl() |
| 712 : context_(NULL), |
| 713 gl_(NULL), |
| 714 web_view_(NULL), |
| 715 #if defined(OS_MACOSX) |
| 716 plugin_handle_(NULL), |
| 717 #endif // defined(OS_MACOSX) |
| 718 context_lost_callback_(0), |
55 cached_width_(0), | 719 cached_width_(0), |
56 cached_height_(0), | 720 cached_height_(0), |
57 multisample_fbo_(0), | 721 bound_fbo_(0) { |
58 multisample_depth_stencil_buffer_(0), | 722 } |
59 multisample_color_buffer_(0), | 723 |
60 bound_fbo_(0), | 724 WebGraphicsContext3DInProcessCommandBufferImpl:: |
61 bound_texture_(0), | 725 ~WebGraphicsContext3DInProcessCommandBufferImpl() { |
62 copy_texture_to_parent_texture_fbo_(0), | 726 } |
63 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 727 |
64 scanline_(0), | 728 // This string should only be passed for WebGL contexts. Nothing ELSE!!! |
65 #endif | 729 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of |
66 fragment_compiler_(0), | 730 // a context should not pass this string. |
67 vertex_compiler_(0) { | 731 static const char* kWebGLPreferredGLExtensions = |
68 } | 732 "GL_OES_packed_depth_stencil " |
69 | 733 "GL_OES_depth24 " |
70 WebGraphicsContext3DInProcessCommandBufferImpl::~WebGraphicsContext3DInProcessCo
mmandBufferImpl() { | 734 "GL_CHROMIUM_webglsl"; |
71 if (!initialized_) | |
72 return; | |
73 | |
74 makeContextCurrent(); | |
75 | |
76 if (attributes_.antialias) { | |
77 glDeleteRenderbuffersEXT(1, &multisample_color_buffer_); | |
78 if (attributes_.depth || attributes_.stencil) | |
79 glDeleteRenderbuffersEXT(1, &multisample_depth_stencil_buffer_); | |
80 glDeleteFramebuffersEXT(1, &multisample_fbo_); | |
81 } else { | |
82 if (attributes_.depth || attributes_.stencil) | |
83 glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_); | |
84 } | |
85 glDeleteTextures(1, &texture_); | |
86 glDeleteFramebuffersEXT(1, ©_texture_to_parent_texture_fbo_); | |
87 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | |
88 if (scanline_) | |
89 delete[] scanline_; | |
90 #endif | |
91 glDeleteFramebuffersEXT(1, &fbo_); | |
92 | |
93 gl_context_->Destroy(); | |
94 | |
95 for (ShaderSourceMap::iterator ii = shader_source_map_.begin(); | |
96 ii != shader_source_map_.end(); ++ii) { | |
97 if (ii->second) | |
98 delete ii->second; | |
99 } | |
100 AngleDestroyCompilers(); | |
101 } | |
102 | 735 |
103 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( | 736 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( |
104 WebGraphicsContext3D::Attributes attributes, | 737 WebGraphicsContext3D::Attributes attributes, |
105 WebView* webView, | 738 WebKit::WebView* web_view, |
106 bool render_directly_to_web_view) { | 739 bool render_directly_to_web_view) { |
107 if (!gfx::GLSurface::InitializeOneOff()) | 740 webkit_glue::BindSkiaToCommandBufferGL(); |
| 741 |
| 742 // Convert WebGL context creation attributes into GLInProcessContext / EGL |
| 743 // size requests. |
| 744 const int alpha_size = attributes.alpha ? 8 : 0; |
| 745 const int depth_size = attributes.depth ? 24 : 0; |
| 746 const int stencil_size = attributes.stencil ? 8 : 0; |
| 747 const int samples = attributes.antialias ? 4 : 0; |
| 748 const int sample_buffers = attributes.antialias ? 1 : 0; |
| 749 const int32 attribs[] = { |
| 750 GLInProcessContext::ALPHA_SIZE, alpha_size, |
| 751 GLInProcessContext::DEPTH_SIZE, depth_size, |
| 752 GLInProcessContext::STENCIL_SIZE, stencil_size, |
| 753 GLInProcessContext::SAMPLES, samples, |
| 754 GLInProcessContext::SAMPLE_BUFFERS, sample_buffers, |
| 755 GLInProcessContext::NONE, |
| 756 }; |
| 757 |
| 758 const char* preferred_extensions = attributes.noExtensions ? |
| 759 kWebGLPreferredGLExtensions : "*"; |
| 760 |
| 761 GURL active_url; |
| 762 if (web_view && web_view->mainFrame()) |
| 763 active_url = GURL(web_view->mainFrame()->url()); |
| 764 |
| 765 GLInProcessContext* parent_context = NULL; |
| 766 if (!render_directly_to_web_view) { |
| 767 WebKit::WebGraphicsContext3D* view_context = |
| 768 web_view->graphicsContext3D(); |
| 769 if (view_context) { |
| 770 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl = |
| 771 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>( |
| 772 view_context); |
| 773 parent_context = context_impl->context_; |
| 774 } |
| 775 } |
| 776 |
| 777 context_ = GLInProcessContext::CreateOffscreenContext( |
| 778 parent_context, |
| 779 gfx::Size(1, 1), |
| 780 preferred_extensions, |
| 781 attribs, |
| 782 active_url); |
| 783 web_view_ = NULL; |
| 784 |
| 785 if (!context_) |
108 return false; | 786 return false; |
109 gfx::BindSkiaToInProcessGL(); | 787 |
110 | 788 gl_ = context_->GetImplementation(); |
111 render_directly_to_web_view_ = render_directly_to_web_view; | 789 context_->SetContextLostCallback( |
112 gfx::GLContext* share_context = 0; | 790 NewCallback( |
113 | 791 this, |
114 if (!render_directly_to_web_view) { | 792 &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost)); |
115 // Pick up the compositor's context to share resources with. | 793 |
116 WebGraphicsContext3D* view_context = webView->graphicsContext3D(); | 794 // Set attributes_ from created offscreen context. |
117 if (view_context) { | 795 { |
118 WebGraphicsContext3DInProcessCommandBufferImpl* contextImpl = | 796 attributes_ = attributes; |
119 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>(view_cont
ext); | 797 GLint alpha_bits = 0; |
120 share_context = contextImpl->gl_context_.get(); | 798 getIntegerv(GL_ALPHA_BITS, &alpha_bits); |
121 } else { | 799 attributes_.alpha = alpha_bits > 0; |
122 // The compositor's context didn't get created | 800 GLint depth_bits = 0; |
123 // successfully, so conceptually there is no way we can | 801 getIntegerv(GL_DEPTH_BITS, &depth_bits); |
124 // render successfully to the WebView. | 802 attributes_.depth = depth_bits > 0; |
125 render_directly_to_web_view_ = false; | 803 GLint stencil_bits = 0; |
126 } | 804 getIntegerv(GL_STENCIL_BITS, &stencil_bits); |
127 } | 805 attributes_.stencil = stencil_bits > 0; |
128 | 806 GLint samples = 0; |
129 is_gles2_ = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; | 807 getIntegerv(GL_SAMPLES, &samples); |
130 | 808 attributes_.antialias = samples > 0; |
131 // This implementation always renders offscreen regardless of | 809 } |
132 // whether render_directly_to_web_view is true. Both DumpRenderTree | 810 makeContextCurrent(); |
133 // and test_shell paint first to an intermediate offscreen buffer | 811 |
134 // and from there to the window, and WebViewImpl::paint already | 812 fprintf(stderr, "Running command buffer\n"); |
135 // correctly handles the case where the compositor is active but | 813 |
136 // the output needs to go to a WebCanvas. | |
137 gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); | |
138 | |
139 if (!gl_surface_.get()) { | |
140 if (!is_gles2_) | |
141 return false; | |
142 | |
143 // Embedded systems have smaller limit on number of GL contexts. Sometimes | |
144 // failure of GL context creation is because of existing GL contexts | |
145 // referenced by JavaScript garbages. Collect garbage and try again. | |
146 // TODO: Besides this solution, kbr@chromium.org suggested: upon receiving | |
147 // a page unload event, iterate down any live WebGraphicsContext3D instances | |
148 // and force them to drop their contexts, sending a context lost event if | |
149 // necessary. | |
150 webView->mainFrame()->collectGarbage(); | |
151 | |
152 gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); | |
153 if (!gl_surface_.get()) | |
154 return false; | |
155 } | |
156 | |
157 gl_context_ = gfx::GLContext::CreateGLContext(share_context, | |
158 gl_surface_.get()); | |
159 if (!gl_context_.get()) { | |
160 if (!is_gles2_) | |
161 return false; | |
162 | |
163 // Embedded systems have smaller limit on number of GL contexts. Sometimes | |
164 // failure of GL context creation is because of existing GL contexts | |
165 // referenced by JavaScript garbages. Collect garbage and try again. | |
166 // TODO: Besides this solution, kbr@chromium.org suggested: upon receiving | |
167 // a page unload event, iterate down any live WebGraphicsContext3D instances | |
168 // and force them to drop their contexts, sending a context lost event if | |
169 // necessary. | |
170 webView->mainFrame()->collectGarbage(); | |
171 | |
172 gl_context_ = gfx::GLContext::CreateGLContext(share_context, | |
173 gl_surface_.get()); | |
174 if (!gl_context_.get()) | |
175 return false; | |
176 } | |
177 | |
178 attributes_ = attributes; | |
179 | |
180 // FIXME: for the moment we disable multisampling for the compositor. | |
181 // It actually works in this implementation, but there are a few | |
182 // considerations. First, we likely want to reduce the fuzziness in | |
183 // these tests as much as possible because we want to run pixel tests. | |
184 // Second, Mesa's multisampling doesn't seem to antialias straight | |
185 // edges in some CSS 3D samples. Third, we don't have multisampling | |
186 // support for the compositor in the normal case at the time of this | |
187 // writing. | |
188 if (render_directly_to_web_view) | |
189 attributes_.antialias = false; | |
190 | |
191 if (!gl_context_->MakeCurrent(gl_surface_.get())) { | |
192 gl_context_ = NULL; | |
193 return false; | |
194 } | |
195 | |
196 const char* extensions = | |
197 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); | |
198 DCHECK(extensions); | |
199 have_ext_framebuffer_object_ = | |
200 strstr(extensions, "GL_EXT_framebuffer_object") != NULL; | |
201 have_ext_framebuffer_multisample_ = | |
202 strstr(extensions, "GL_EXT_framebuffer_multisample") != NULL; | |
203 have_angle_framebuffer_multisample_ = | |
204 strstr(extensions, "GL_ANGLE_framebuffer_multisample") != NULL; | |
205 | |
206 ValidateAttributes(); | |
207 | |
208 if (!is_gles2_) { | |
209 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); | |
210 glEnable(GL_POINT_SPRITE); | |
211 } | |
212 | |
213 if (!AngleCreateCompilers()) { | |
214 AngleDestroyCompilers(); | |
215 return false; | |
216 } | |
217 | |
218 glGenFramebuffersEXT(1, ©_texture_to_parent_texture_fbo_); | |
219 | |
220 initialized_ = true; | |
221 return true; | 814 return true; |
222 } | 815 } |
223 | 816 |
224 void WebGraphicsContext3DInProcessCommandBufferImpl::ValidateAttributes() { | |
225 const char* extensions = | |
226 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); | |
227 | |
228 if (attributes_.stencil) { | |
229 if (strstr(extensions, "GL_OES_packed_depth_stencil") || | |
230 strstr(extensions, "GL_EXT_packed_depth_stencil")) { | |
231 if (!attributes_.depth) { | |
232 attributes_.depth = true; | |
233 } | |
234 } else { | |
235 attributes_.stencil = false; | |
236 } | |
237 } | |
238 if (attributes_.antialias) { | |
239 bool isValidVendor = true; | |
240 #if defined(OS_MACOSX) | |
241 // Currently in Mac we only turn on antialias if vendor is NVIDIA. | |
242 const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); | |
243 if (!strstr(vendor, "NVIDIA")) | |
244 isValidVendor = false; | |
245 #endif | |
246 if (!(isValidVendor && | |
247 (have_ext_framebuffer_multisample_ || | |
248 (have_angle_framebuffer_multisample_ && | |
249 strstr(extensions, "GL_OES_rgb8_rgba8"))))) | |
250 attributes_.antialias = false; | |
251 | |
252 // Don't antialias when using Mesa to ensure more reliable testing and | |
253 // because it doesn't appear to multisample straight lines correctly. | |
254 const char* renderer = | |
255 reinterpret_cast<const char*>(glGetString(GL_RENDERER)); | |
256 if (!strncmp(renderer, "Mesa", 4)) { | |
257 attributes_.antialias = false; | |
258 } | |
259 } | |
260 } | |
261 | |
262 void WebGraphicsContext3DInProcessCommandBufferImpl::ResolveMultisampledFramebuf
fer( | |
263 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) { | |
264 if (attributes_.antialias) { | |
265 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fbo_); | |
266 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo_); | |
267 if (have_ext_framebuffer_multisample_) { | |
268 glBlitFramebufferEXT(x, y, | |
269 x + width, y + height, | |
270 x, y, | |
271 x + width, y + height, | |
272 GL_COLOR_BUFFER_BIT, GL_NEAREST); | |
273 } else { | |
274 DCHECK(have_angle_framebuffer_multisample_); | |
275 glBlitFramebufferANGLE(x, y, | |
276 x + width, y + height, | |
277 x, y, | |
278 x + width, y + height, | |
279 GL_COLOR_BUFFER_BIT, GL_NEAREST); | |
280 } | |
281 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | |
282 } | |
283 } | |
284 | |
285 bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { | 817 bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { |
286 return gl_context_->MakeCurrent(gl_surface_.get()); | 818 return GLInProcessContext::MakeCurrent(context_); |
| 819 } |
| 820 |
| 821 void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() { |
| 822 // NOTE: Comment in the line below to check for code that is not calling |
| 823 // eglMakeCurrent where appropriate. The issue is code using |
| 824 // WebGraphicsContext3D does not need to call makeContextCurrent. Code using |
| 825 // direct OpenGL bindings needs to call the appropriate form of |
| 826 // eglMakeCurrent. If it doesn't it will be issuing commands on the wrong |
| 827 // context. Uncommenting the line below clears the current context so that |
| 828 // any code not calling eglMakeCurrent in the appropriate place should crash. |
| 829 // This is not a perfect test but generally code that used the direct OpenGL |
| 830 // bindings should not be mixed with code that uses WebGraphicsContext3D. |
| 831 // |
| 832 // GLInProcessContext::MakeCurrent(NULL); |
287 } | 833 } |
288 | 834 |
289 int WebGraphicsContext3DInProcessCommandBufferImpl::width() { | 835 int WebGraphicsContext3DInProcessCommandBufferImpl::width() { |
290 return cached_width_; | 836 return cached_width_; |
291 } | 837 } |
292 | 838 |
293 int WebGraphicsContext3DInProcessCommandBufferImpl::height() { | 839 int WebGraphicsContext3DInProcessCommandBufferImpl::height() { |
294 return cached_height_; | 840 return cached_height_; |
295 } | 841 } |
296 | 842 |
297 bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { | 843 bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { |
298 return is_gles2_; | 844 return true; |
299 } | 845 } |
300 | 846 |
301 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { | 847 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { |
302 return texture_; | 848 DCHECK(context_); |
| 849 return context_->GetParentTextureId(); |
303 } | 850 } |
304 | 851 |
305 void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { | 852 void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { |
306 if (!render_directly_to_web_view_) { | 853 // Copies the contents of the off-screen render target into the texture |
307 // We need to prepare our rendering results for the compositor. | 854 // used by the compositor. |
308 makeContextCurrent(); | 855 context_->SwapBuffers(); |
309 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); | 856 } |
310 } | 857 |
311 } | 858 void WebGraphicsContext3DInProcessCommandBufferImpl::reshape( |
312 | 859 int width, int height) { |
313 namespace { | |
314 | |
315 int CreateTextureObject(GLenum target) { | |
316 GLuint texture = 0; | |
317 glGenTextures(1, &texture); | |
318 glBindTexture(target, texture); | |
319 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
320 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
321 return texture; | |
322 } | |
323 | |
324 } // anonymous namespace | |
325 | |
326 void WebGraphicsContext3DInProcessCommandBufferImpl::reshape(int width, int heig
ht) { | |
327 cached_width_ = width; | 860 cached_width_ = width; |
328 cached_height_ = height; | 861 cached_height_ = height; |
329 makeContextCurrent(); | 862 |
330 | 863 // TODO(gmam): See if we can comment this in. |
331 GLenum target = GL_TEXTURE_2D; | 864 // ClearContext(); |
332 | 865 |
333 if (!texture_) { | 866 if (web_view_) { |
334 // Generate the texture object | 867 #if defined(OS_MACOSX) |
335 texture_ = CreateTextureObject(target); | 868 context_->ResizeOnscreen(gfx::Size(width, height)); |
336 // Generate the framebuffer object | 869 #else |
337 glGenFramebuffersEXT(1, &fbo_); | 870 gl_->ResizeCHROMIUM(width, height); |
338 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); | 871 #endif |
339 bound_fbo_ = fbo_; | |
340 if (attributes_.depth || attributes_.stencil) | |
341 glGenRenderbuffersEXT(1, &depth_stencil_buffer_); | |
342 // Generate the multisample framebuffer object | |
343 if (attributes_.antialias) { | |
344 glGenFramebuffersEXT(1, &multisample_fbo_); | |
345 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_); | |
346 bound_fbo_ = multisample_fbo_; | |
347 glGenRenderbuffersEXT(1, &multisample_color_buffer_); | |
348 if (attributes_.depth || attributes_.stencil) | |
349 glGenRenderbuffersEXT(1, &multisample_depth_stencil_buffer_); | |
350 } | |
351 } | |
352 | |
353 GLint internal_multisampled_color_format = 0; | |
354 GLint internal_color_format = 0; | |
355 GLint color_format = 0; | |
356 GLint internal_depth_stencil_format = 0; | |
357 if (attributes_.alpha) { | |
358 // GL_RGBA8_OES == GL_RGBA8 | |
359 internal_multisampled_color_format = GL_RGBA8; | |
360 internal_color_format = is_gles2_ ? GL_RGBA : GL_RGBA8; | |
361 color_format = GL_RGBA; | |
362 } else { | 872 } else { |
363 // GL_RGB8_OES == GL_RGB8 | 873 context_->ResizeOffscreen(gfx::Size(width, height)); |
364 internal_multisampled_color_format = GL_RGB8; | 874 // Force a SwapBuffers to get the framebuffer to resize. |
365 internal_color_format = is_gles2_ ? GL_RGB : GL_RGB8; | 875 context_->SwapBuffers(); |
366 color_format = GL_RGB; | 876 } |
367 } | |
368 if (attributes_.stencil || attributes_.depth) { | |
369 // We don't allow the logic where stencil is required and depth is not. | |
370 // See GraphicsContext3DInternal constructor. | |
371 if (attributes_.stencil && attributes_.depth) { | |
372 internal_depth_stencil_format = GL_DEPTH24_STENCIL8_EXT; | |
373 } else { | |
374 if (is_gles2_) | |
375 internal_depth_stencil_format = GL_DEPTH_COMPONENT16; | |
376 else | |
377 internal_depth_stencil_format = GL_DEPTH_COMPONENT; | |
378 } | |
379 } | |
380 | |
381 bool must_restore_fbo = false; | |
382 | |
383 // Resize multisampling FBO | |
384 if (attributes_.antialias) { | |
385 GLint max_sample_count; | |
386 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); | |
387 GLint sample_count = std::min(8, max_sample_count); | |
388 if (bound_fbo_ != multisample_fbo_) { | |
389 must_restore_fbo = true; | |
390 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_); | |
391 } | |
392 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, multisample_color_buffer_); | |
393 if (have_ext_framebuffer_multisample_) { | |
394 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, | |
395 sample_count, | |
396 internal_multisampled_color_format, | |
397 width, | |
398 height); | |
399 } else { | |
400 DCHECK(have_angle_framebuffer_multisample_); | |
401 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, | |
402 sample_count, | |
403 internal_multisampled_color_format, | |
404 width, | |
405 height); | |
406 } | |
407 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
408 GL_COLOR_ATTACHMENT0_EXT, | |
409 GL_RENDERBUFFER_EXT, | |
410 multisample_color_buffer_); | |
411 if (attributes_.stencil || attributes_.depth) { | |
412 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, | |
413 multisample_depth_stencil_buffer_); | |
414 if (have_ext_framebuffer_multisample_) { | |
415 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, | |
416 sample_count, | |
417 internal_depth_stencil_format, | |
418 width, | |
419 height); | |
420 } else { | |
421 DCHECK(have_angle_framebuffer_multisample_); | |
422 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT, | |
423 sample_count, | |
424 internal_depth_stencil_format, | |
425 width, | |
426 height); | |
427 } | |
428 if (attributes_.stencil) | |
429 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
430 GL_STENCIL_ATTACHMENT_EXT, | |
431 GL_RENDERBUFFER_EXT, | |
432 multisample_depth_stencil_buffer_); | |
433 if (attributes_.depth) | |
434 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
435 GL_DEPTH_ATTACHMENT_EXT, | |
436 GL_RENDERBUFFER_EXT, | |
437 multisample_depth_stencil_buffer_); | |
438 } | |
439 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); | |
440 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | |
441 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { | |
442 LOG(ERROR) << "Multisampling framebuffer was incomplete"; | |
443 | |
444 // FIXME: cleanup. | |
445 NOTIMPLEMENTED(); | |
446 } | |
447 } | |
448 | |
449 // Resize regular FBO | |
450 if (bound_fbo_ != fbo_) { | |
451 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); | |
452 must_restore_fbo = true; | |
453 } | |
454 glBindTexture(target, texture_); | |
455 glTexImage2D(target, 0, internal_color_format, | |
456 width, height, | |
457 0, color_format, GL_UNSIGNED_BYTE, 0); | |
458 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
459 GL_COLOR_ATTACHMENT0_EXT, | |
460 target, | |
461 texture_, | |
462 0); | |
463 glBindTexture(target, 0); | |
464 if (!attributes_.antialias && (attributes_.stencil || attributes_.depth)) { | |
465 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer_); | |
466 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | |
467 internal_depth_stencil_format, | |
468 width, height); | |
469 if (attributes_.stencil) | |
470 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
471 GL_STENCIL_ATTACHMENT_EXT, | |
472 GL_RENDERBUFFER_EXT, | |
473 depth_stencil_buffer_); | |
474 if (attributes_.depth) | |
475 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
476 GL_DEPTH_ATTACHMENT_EXT, | |
477 GL_RENDERBUFFER_EXT, | |
478 depth_stencil_buffer_); | |
479 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); | |
480 } | |
481 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | |
482 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { | |
483 LOG(ERROR) << "Framebuffer was incomplete"; | |
484 | |
485 // FIXME: cleanup. | |
486 NOTIMPLEMENTED(); | |
487 } | |
488 | |
489 if (attributes_.antialias) { | |
490 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_); | |
491 if (bound_fbo_ == multisample_fbo_) | |
492 must_restore_fbo = false; | |
493 } | |
494 | |
495 // Initialize renderbuffers to 0. | |
496 GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0; | |
497 GLint clearStencil = 0; | |
498 GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; | |
499 GLboolean depthMask = GL_TRUE; | |
500 GLuint stencilMask = 0xffffffff; | |
501 GLboolean isScissorEnabled = GL_FALSE; | |
502 GLboolean isDitherEnabled = GL_FALSE; | |
503 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | |
504 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor); | |
505 glClearColor(0, 0, 0, 0); | |
506 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); | |
507 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
508 if (attributes_.depth) { | |
509 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth); | |
510 glClearDepth(1); | |
511 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); | |
512 glDepthMask(GL_TRUE); | |
513 clearMask |= GL_DEPTH_BUFFER_BIT; | |
514 } | |
515 if (attributes_.stencil) { | |
516 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil); | |
517 glClearStencil(0); | |
518 glGetIntegerv(GL_STENCIL_WRITEMASK, | |
519 reinterpret_cast<GLint*>(&stencilMask)); | |
520 glStencilMaskSeparate(GL_FRONT, 0xffffffff); | |
521 clearMask |= GL_STENCIL_BUFFER_BIT; | |
522 } | |
523 isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST); | |
524 glDisable(GL_SCISSOR_TEST); | |
525 isDitherEnabled = glIsEnabled(GL_DITHER); | |
526 glDisable(GL_DITHER); | |
527 | |
528 glClear(clearMask); | |
529 | |
530 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); | |
531 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]); | |
532 if (attributes_.depth) { | |
533 glClearDepth(clearDepth); | |
534 glDepthMask(depthMask); | |
535 } | |
536 if (attributes_.stencil) { | |
537 glClearStencil(clearStencil); | |
538 glStencilMaskSeparate(GL_FRONT, stencilMask); | |
539 } | |
540 if (isScissorEnabled) | |
541 glEnable(GL_SCISSOR_TEST); | |
542 else | |
543 glDisable(GL_SCISSOR_TEST); | |
544 if (isDitherEnabled) | |
545 glEnable(GL_DITHER); | |
546 else | |
547 glDisable(GL_DITHER); | |
548 | |
549 if (must_restore_fbo) | |
550 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | |
551 | 877 |
552 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 878 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
553 if (scanline_) { | 879 scanline_.reset(new uint8[width * 4]); |
554 delete[] scanline_; | |
555 scanline_ = 0; | |
556 } | |
557 scanline_ = new unsigned char[width * 4]; | |
558 #endif // FLIP_FRAMEBUFFER_VERTICALLY | 880 #endif // FLIP_FRAMEBUFFER_VERTICALLY |
559 } | 881 } |
560 | 882 |
| 883 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createCompositorTexture( |
| 884 WGC3Dsizei width, WGC3Dsizei height) { |
| 885 // TODO(gmam): See if we can comment this in. |
| 886 // ClearContext(); |
| 887 return context_->CreateParentTexture(gfx::Size(width, height)); |
| 888 } |
| 889 |
| 890 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteCompositorTexture( |
| 891 WebGLId parent_texture) { |
| 892 // TODO(gmam): See if we can comment this in. |
| 893 // ClearContext(); |
| 894 context_->DeleteParentTexture(parent_texture); |
| 895 } |
| 896 |
561 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 897 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
562 void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( | 898 void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( |
563 unsigned char* framebuffer, unsigned int width, unsigned int height) { | 899 uint8* framebuffer, |
564 unsigned char* scanline = scanline_; | 900 unsigned int width, |
| 901 unsigned int height) { |
| 902 uint8* scanline = scanline_.get(); |
565 if (!scanline) | 903 if (!scanline) |
566 return; | 904 return; |
567 unsigned int row_bytes = width * 4; | 905 unsigned int row_bytes = width * 4; |
568 unsigned int count = height / 2; | 906 unsigned int count = height / 2; |
569 for (unsigned int i = 0; i < count; i++) { | 907 for (unsigned int i = 0; i < count; i++) { |
570 unsigned char* row_a = framebuffer + i * row_bytes; | 908 uint8* row_a = framebuffer + i * row_bytes; |
571 unsigned char* row_b = framebuffer + (height - i - 1) * row_bytes; | 909 uint8* row_b = framebuffer + (height - i - 1) * row_bytes; |
572 // FIXME: this is where the multiplication of the alpha | 910 // TODO(kbr): this is where the multiplication of the alpha |
573 // channel into the color buffer will need to occur if the | 911 // channel into the color buffer will need to occur if the |
574 // user specifies the "premultiplyAlpha" flag in the context | 912 // user specifies the "premultiplyAlpha" flag in the context |
575 // creation attributes. | 913 // creation attributes. |
576 memcpy(scanline, row_b, row_bytes); | 914 memcpy(scanline, row_b, row_bytes); |
577 memcpy(row_b, row_a, row_bytes); | 915 memcpy(row_b, row_a, row_bytes); |
578 memcpy(row_a, scanline, row_bytes); | 916 memcpy(row_a, scanline, row_bytes); |
579 } | 917 } |
580 } | 918 } |
581 #endif | 919 #endif |
582 | 920 |
583 bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( | 921 bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( |
584 unsigned char* pixels, size_t bufferSize) { | 922 unsigned char* pixels, |
585 if (bufferSize != static_cast<size_t>(4 * width() * height())) | 923 size_t buffer_size) { |
| 924 // TODO(gmam): See if we can comment this in. |
| 925 // ClearContext(); |
| 926 if (buffer_size != static_cast<size_t>(4 * width() * height())) { |
586 return false; | 927 return false; |
587 | 928 } |
588 makeContextCurrent(); | |
589 | 929 |
590 // Earlier versions of this code used the GPU to flip the | 930 // Earlier versions of this code used the GPU to flip the |
591 // framebuffer vertically before reading it back for compositing | 931 // framebuffer vertically before reading it back for compositing |
592 // via software. This code was quite complicated, used a lot of | 932 // via software. This code was quite complicated, used a lot of |
593 // GPU memory, and didn't provide an obvious speedup. Since this | 933 // GPU memory, and didn't provide an obvious speedup. Since this |
594 // vertical flip is only a temporary solution anyway until Chrome | 934 // vertical flip is only a temporary solution anyway until Chrome |
595 // is fully GPU composited, it wasn't worth the complexity. | 935 // is fully GPU composited, it wasn't worth the complexity. |
596 | 936 |
597 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); | 937 bool mustRestoreFBO = (bound_fbo_ != 0); |
598 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); | 938 if (mustRestoreFBO) { |
599 | 939 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
600 GLint pack_alignment = 4; | 940 } |
601 bool must_restore_pack_alignment = false; | 941 gl_->ReadPixels(0, 0, cached_width_, cached_height_, |
602 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); | 942 GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
603 if (pack_alignment > 4) { | 943 |
604 glPixelStorei(GL_PACK_ALIGNMENT, 4); | 944 // Swizzle red and blue channels |
605 must_restore_pack_alignment = true; | 945 // TODO(kbr): expose GL_BGRA as extension |
606 } | 946 for (size_t i = 0; i < buffer_size; i += 4) { |
607 | 947 std::swap(pixels[i], pixels[i + 2]); |
608 if (is_gles2_) { | 948 } |
609 // FIXME: consider testing for presence of GL_OES_read_format | 949 |
610 // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here | 950 if (mustRestoreFBO) { |
611 // directly. | 951 gl_->BindFramebuffer(GL_FRAMEBUFFER, bound_fbo_); |
612 glReadPixels(0, 0, cached_width_, cached_height_, | 952 } |
613 GL_RGBA, GL_UNSIGNED_BYTE, pixels); | |
614 for (size_t i = 0; i < bufferSize; i += 4) { | |
615 std::swap(pixels[i], pixels[i + 2]); | |
616 } | |
617 } else { | |
618 glReadPixels(0, 0, cached_width_, cached_height_, | |
619 GL_BGRA, GL_UNSIGNED_BYTE, pixels); | |
620 } | |
621 | |
622 if (must_restore_pack_alignment) | |
623 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); | |
624 | |
625 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | |
626 | 953 |
627 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 954 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
628 if (pixels) | 955 if (pixels) { |
629 FlipVertically(pixels, cached_width_, cached_height_); | 956 FlipVertically(pixels, cached_width_, cached_height_); |
| 957 } |
630 #endif | 958 #endif |
631 | 959 |
632 return true; | 960 return true; |
633 } | 961 } |
634 | 962 |
635 void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(WGC3Denum
error) { | 963 void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError( |
636 if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) { | 964 WGC3Denum error) { |
637 synthetic_errors_set_.insert(error); | 965 if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == |
638 synthetic_errors_list_.push_back(error); | 966 synthetic_errors_.end()) { |
| 967 synthetic_errors_.push_back(error); |
639 } | 968 } |
640 } | 969 } |
641 | 970 |
642 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM( | 971 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM( |
643 WGC3Denum target, WGC3Dintptr offset, | 972 WGC3Denum target, |
644 WGC3Dsizeiptr size, WGC3Denum access) { | 973 WGC3Dintptr offset, |
645 return 0; | 974 WGC3Dsizeiptr size, |
| 975 WGC3Denum access) { |
| 976 ClearContext(); |
| 977 return gl_->MapBufferSubDataCHROMIUM(target, offset, size, access); |
646 } | 978 } |
647 | 979 |
648 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM( | 980 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM( |
649 const void* mem) { | 981 const void* mem) { |
| 982 ClearContext(); |
| 983 return gl_->UnmapBufferSubDataCHROMIUM(mem); |
650 } | 984 } |
651 | 985 |
652 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM( | 986 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM( |
653 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, | 987 WGC3Denum target, |
654 WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, | 988 WGC3Dint level, |
| 989 WGC3Dint xoffset, |
| 990 WGC3Dint yoffset, |
| 991 WGC3Dsizei width, |
| 992 WGC3Dsizei height, |
| 993 WGC3Denum format, |
| 994 WGC3Denum type, |
655 WGC3Denum access) { | 995 WGC3Denum access) { |
656 return 0; | 996 ClearContext(); |
| 997 return gl_->MapTexSubImage2DCHROMIUM( |
| 998 target, level, xoffset, yoffset, width, height, format, type, access); |
657 } | 999 } |
658 | 1000 |
659 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM( | 1001 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM( |
660 const void* mem) { | 1002 const void* mem) { |
661 } | 1003 ClearContext(); |
662 | 1004 gl_->UnmapTexSubImage2DCHROMIUM(mem); |
663 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToParentTextureC
HROMIUM( | 1005 } |
664 WebGLId id, WebGLId id2) { | 1006 |
665 if (!glGetTexLevelParameteriv) | 1007 void WebGraphicsContext3DInProcessCommandBufferImpl:: |
666 return; | 1008 copyTextureToParentTextureCHROMIUM(WebGLId texture, WebGLId parentTexture) { |
667 | 1009 // TODO(gmam): See if we can comment this in. |
668 makeContextCurrent(); | 1010 // ClearContext(); |
669 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, copy_texture_to_parent_texture_fbo_); | 1011 copyTextureToCompositor(texture, parentTexture); |
670 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 1012 } |
671 GL_COLOR_ATTACHMENT0, | 1013 |
672 GL_TEXTURE_2D, | 1014 void WebGraphicsContext3DInProcessCommandBufferImpl:: |
673 id, | 1015 getParentToChildLatchCHROMIUM(WGC3Duint* latch_id) |
674 0); // level | 1016 { |
675 glBindTexture(GL_TEXTURE_2D, id2); | 1017 ClearContext(); |
676 GLsizei width, height; | 1018 if (!context_->GetParentToChildLatch(latch_id)) { |
677 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); | 1019 LOG(ERROR) << "getLatch must only be called on child context"; |
678 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); | 1020 synthesizeGLError(GL_INVALID_OPERATION); |
679 glCopyTexImage2D(GL_TEXTURE_2D, | 1021 *latch_id = ::gpu::kInvalidLatchId; |
680 0, // level | 1022 } |
681 GL_RGBA, | 1023 } |
682 0, 0, // x, y | 1024 |
683 width, | 1025 void WebGraphicsContext3DInProcessCommandBufferImpl:: |
684 height, | 1026 getChildToParentLatchCHROMIUM(WGC3Duint* latch_id) |
685 0); // border | 1027 { |
686 glBindTexture(GL_TEXTURE_2D, bound_texture_); | 1028 ClearContext(); |
687 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | 1029 if (!context_->GetChildToParentLatch(latch_id)) { |
688 } | 1030 LOG(ERROR) << "getLatch must only be called on child context"; |
689 | 1031 synthesizeGLError(GL_INVALID_OPERATION); |
690 void WebGraphicsContext3DInProcessCommandBufferImpl::getParentToChildLatchCHROMI
UM( | 1032 *latch_id = ::gpu::kInvalidLatchId; |
691 WGC3Duint* latch_id) | 1033 } |
692 { | |
693 } | |
694 | |
695 void WebGraphicsContext3DInProcessCommandBufferImpl::getChildToParentLatchCHROMI
UM( | |
696 WGC3Duint* latch_id) | |
697 { | |
698 } | 1034 } |
699 | 1035 |
700 void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM( | 1036 void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM( |
701 WGC3Duint latch_id) | 1037 WGC3Duint latch_id) |
702 { | 1038 { |
| 1039 // TODO(gmam): See if we can comment this in. |
| 1040 // ClearContext(); |
| 1041 gl_->WaitLatchCHROMIUM(latch_id); |
703 } | 1042 } |
704 | 1043 |
705 void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM( | 1044 void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM( |
706 WGC3Duint latch_id) | 1045 WGC3Duint latch_id) |
707 { | 1046 { |
708 } | 1047 // TODO(gmam): See if we can comment this in. |
709 | 1048 // ClearContext(); |
710 WebString WebGraphicsContext3DInProcessCommandBufferImpl:: | 1049 gl_->SetLatchCHROMIUM(latch_id); |
| 1050 // required to ensure set command is sent to GPU process |
| 1051 gl_->Flush(); |
| 1052 } |
| 1053 |
| 1054 void WebGraphicsContext3DInProcessCommandBufferImpl:: |
| 1055 rateLimitOffscreenContextCHROMIUM() { |
| 1056 // TODO(gmam): See if we can comment this in. |
| 1057 // ClearContext(); |
| 1058 gl_->RateLimitOffscreenContextCHROMIUM(); |
| 1059 } |
| 1060 |
| 1061 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: |
711 getRequestableExtensionsCHROMIUM() { | 1062 getRequestableExtensionsCHROMIUM() { |
712 return WebString(); | 1063 // TODO(gmam): See if we can comment this in. |
713 } | 1064 // ClearContext(); |
714 | 1065 return WebKit::WebString::fromUTF8( |
715 void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM(co
nst char*) { | 1066 gl_->GetRequestableExtensionsCHROMIUM()); |
| 1067 } |
| 1068 |
| 1069 void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM( |
| 1070 const char* extension) { |
| 1071 // TODO(gmam): See if we can comment this in. |
| 1072 // ClearContext(); |
| 1073 gl_->RequestExtensionCHROMIUM(extension); |
716 } | 1074 } |
717 | 1075 |
718 void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM( | 1076 void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM( |
719 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, | 1077 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, |
720 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, | 1078 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, |
721 WGC3Dbitfield mask, WGC3Denum filter) { | 1079 WGC3Dbitfield mask, WGC3Denum filter) { |
722 } | 1080 ClearContext(); |
723 | 1081 gl_->BlitFramebufferEXT( |
724 void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorageMultisam
pleCHROMIUM( | 1082 srcX0, srcY0, srcX1, srcY1, |
725 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, | 1083 dstX0, dstY0, dstX1, dstY1, |
726 WGC3Dsizei width, WGC3Dsizei height) { | 1084 mask, filter); |
| 1085 } |
| 1086 |
| 1087 void WebGraphicsContext3DInProcessCommandBufferImpl:: |
| 1088 renderbufferStorageMultisampleCHROMIUM( |
| 1089 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, |
| 1090 WGC3Dsizei width, WGC3Dsizei height) { |
| 1091 ClearContext(); |
| 1092 gl_->RenderbufferStorageMultisampleEXT( |
| 1093 target, samples, internalformat, width, height); |
727 } | 1094 } |
728 | 1095 |
729 // Helper macros to reduce the amount of code. | 1096 // Helper macros to reduce the amount of code. |
730 | 1097 |
731 #define DELEGATE_TO_GL(name, glname) \ | 1098 #define DELEGATE_TO_GL(name, glname) \ |
732 void WebGraphicsContext3DInProcessCommandBufferImpl::name() {
\ | 1099 void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \ |
733 makeContextCurrent(); \ | 1100 ClearContext(); \ |
734 gl##glname(); \ | 1101 gl_->glname(); \ |
735 } | 1102 } |
736 | 1103 |
737 #define DELEGATE_TO_GL_1(name, glname, t1) \ | 1104 #define DELEGATE_TO_GL_1(name, glname, t1) \ |
738 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) {
\ | 1105 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ |
739 makeContextCurrent(); \ | 1106 ClearContext(); \ |
740 gl##glname(a1); \ | 1107 gl_->glname(a1); \ |
741 } | 1108 } |
742 | 1109 |
743 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ | 1110 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ |
744 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) {
\ | 1111 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ |
745 makeContextCurrent(); \ | 1112 ClearContext(); \ |
746 return gl##glname(a1); \ | 1113 return gl_->glname(a1); \ |
747 } | 1114 } |
748 | 1115 |
749 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ | 1116 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ |
750 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) {
\ | 1117 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ |
751 makeContextCurrent(); \ | 1118 ClearContext(); \ |
752 return gl##glname(a1) ? true : false; \ | 1119 return gl_->glname(a1) ? true : false; \ |
753 } | 1120 } |
754 | 1121 |
755 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ | 1122 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ |
756 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) {
\ | 1123 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
757 makeContextCurrent(); \ | 1124 t1 a1, t2 a2) { \ |
758 gl##glname(a1, a2); \ | 1125 ClearContext(); \ |
759 } | 1126 gl_->glname(a1, a2); \ |
760 | 1127 } |
761 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ | 1128 |
762 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) {
\ | 1129 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ |
763 makeContextCurrent(); \ | 1130 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ |
764 return gl##glname(a1, a2); \ | 1131 ClearContext(); \ |
765 } | 1132 return gl_->glname(a1, a2); \ |
766 | 1133 } |
767 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ | 1134 |
768 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) {
\ | 1135 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ |
769 makeContextCurrent(); \ | 1136 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
770 gl##glname(a1, a2, a3); \ | 1137 t1 a1, t2 a2, t3 a3) { \ |
771 } | 1138 ClearContext(); \ |
772 | 1139 gl_->glname(a1, a2, a3); \ |
773 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ | 1140 } |
774 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t
4 a4) { \ | 1141 |
775 makeContextCurrent(); \ | 1142 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ |
776 gl##glname(a1, a2, a3, a4); \ | 1143 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
777 } | 1144 t1 a1, t2 a2, t3 a3, t4 a4) { \ |
778 | 1145 ClearContext(); \ |
779 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ | 1146 gl_->glname(a1, a2, a3, a4); \ |
780 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t
4 a4, \ | 1147 } |
781 t5 a5) { \ | 1148 |
782 makeContextCurrent(); \ | 1149 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ |
783 gl##glname(a1, a2, a3, a4, a5); \ | 1150 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
784 } | 1151 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \ |
785 | 1152 ClearContext(); \ |
786 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ | 1153 gl_->glname(a1, a2, a3, a4, a5); \ |
787 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t
4 a4, \ | 1154 } |
788 t5 a5, t6 a6) { \ | 1155 |
789 makeContextCurrent(); \ | 1156 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ |
790 gl##glname(a1, a2, a3, a4, a5, a6); \ | 1157 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
791 } | 1158 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \ |
792 | 1159 ClearContext(); \ |
793 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ | 1160 gl_->glname(a1, a2, a3, a4, a5, a6); \ |
794 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t
4 a4, \ | 1161 } |
795 t5 a5, t6 a6, t7 a7) { \ | 1162 |
796 makeContextCurrent(); \ | 1163 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ |
797 gl##glname(a1, a2, a3, a4, a5, a6, a7); \ | 1164 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
798 } | 1165 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) { \ |
799 | 1166 ClearContext(); \ |
800 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ | 1167 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \ |
801 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t
4 a4, \ | 1168 } |
802 t5 a5, t6 a6, t7 a7, t8 a8) { \ | 1169 |
803 makeContextCurrent(); \ | 1170 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ |
804 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ | 1171 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
805 } | 1172 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) { \ |
806 | 1173 ClearContext(); \ |
807 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ | 1174 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \ |
808 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t
4 a4, \ | 1175 } |
809 t5 a5, t6 a6, t7 a7, t8 a8, \ | 1176 |
810 t9 a9) { \ | 1177 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ |
811 makeContextCurrent(); \ | 1178 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \ |
812 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ | 1179 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) { \ |
813 } | 1180 ClearContext(); \ |
814 | 1181 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ |
815 void WebGraphicsContext3DInProcessCommandBufferImpl::activeTexture(WGC3Denum tex
ture) { | 1182 } |
816 // FIXME: query number of textures available. | 1183 |
817 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) | 1184 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum) |
818 // FIXME: raise exception. | |
819 return; | |
820 | |
821 makeContextCurrent(); | |
822 glActiveTexture(texture); | |
823 } | |
824 | 1185 |
825 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) | 1186 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) |
826 | 1187 |
827 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, | 1188 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, |
828 WebGLId, WGC3Duint, const WGC3Dchar*) | 1189 WGC3Duint, const WGC3Dchar*) |
829 | 1190 |
830 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId); | 1191 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId) |
831 | 1192 |
832 void WebGraphicsContext3DInProcessCommandBufferImpl::bindFramebuffer( | 1193 void WebGraphicsContext3DInProcessCommandBufferImpl::bindFramebuffer( |
833 WGC3Denum target, WebGLId framebuffer) { | 1194 WGC3Denum target, |
834 makeContextCurrent(); | 1195 WebGLId framebuffer) { |
835 if (!framebuffer) | 1196 ClearContext(); |
836 framebuffer = (attributes_.antialias ? multisample_fbo_ : fbo_); | 1197 gl_->BindFramebuffer(target, framebuffer); |
837 if (framebuffer != bound_fbo_) { | 1198 bound_fbo_ = framebuffer; |
838 glBindFramebufferEXT(target, framebuffer); | 1199 } |
839 bound_fbo_ = framebuffer; | 1200 |
840 } | 1201 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId) |
841 } | 1202 |
842 | 1203 DELEGATE_TO_GL_2(bindTexture, BindTexture, WGC3Denum, WebGLId) |
843 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, WGC3Denum, WebGLId) | |
844 | |
845 void WebGraphicsContext3DInProcessCommandBufferImpl::bindTexture( | |
846 WGC3Denum target, WebGLId texture) { | |
847 makeContextCurrent(); | |
848 glBindTexture(target, texture); | |
849 bound_texture_ = texture; | |
850 } | |
851 | 1204 |
852 DELEGATE_TO_GL_4(blendColor, BlendColor, | 1205 DELEGATE_TO_GL_4(blendColor, BlendColor, |
853 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | 1206 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) |
854 | 1207 |
855 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) | 1208 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) |
856 | 1209 |
857 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, | 1210 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, |
858 WGC3Denum, WGC3Denum) | 1211 WGC3Denum, WGC3Denum) |
859 | 1212 |
860 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum) | 1213 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum) |
861 | 1214 |
862 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, | 1215 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, |
863 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) | 1216 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) |
864 | 1217 |
865 DELEGATE_TO_GL_4(bufferData, BufferData, | 1218 DELEGATE_TO_GL_4(bufferData, BufferData, |
866 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum) | 1219 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum) |
867 | 1220 |
868 DELEGATE_TO_GL_4(bufferSubData, BufferSubData, | 1221 DELEGATE_TO_GL_4(bufferSubData, BufferSubData, |
869 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) | 1222 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) |
870 | 1223 |
871 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT, | 1224 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus, |
872 WGC3Denum, WGC3Denum) | 1225 WGC3Denum, WGC3Denum) |
873 | 1226 |
874 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) | 1227 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) |
875 | 1228 |
876 DELEGATE_TO_GL_4(clearColor, ClearColor, | 1229 DELEGATE_TO_GL_4(clearColor, ClearColor, |
877 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) | 1230 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) |
878 | 1231 |
879 DELEGATE_TO_GL_1(clearDepth, ClearDepth, WGC3Dclampf) | 1232 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf) |
880 | 1233 |
881 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) | 1234 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) |
882 | 1235 |
883 DELEGATE_TO_GL_4(colorMask, ColorMask, | 1236 DELEGATE_TO_GL_4(colorMask, ColorMask, |
884 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) | 1237 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) |
885 | 1238 |
886 void WebGraphicsContext3DInProcessCommandBufferImpl::compileShader(WebGLId shade
r) { | 1239 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) |
887 makeContextCurrent(); | |
888 | 1240 |
889 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | 1241 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D, |
890 if (result == shader_source_map_.end()) { | 1242 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, |
891 // Passing down to gl driver to generate the correct error; or the case | 1243 WGC3Dsizei, WGC3Dsizei, WGC3Dint) |
892 // where the shader deletion is delayed when it's attached to a program. | |
893 glCompileShader(shader); | |
894 return; | |
895 } | |
896 ShaderSourceEntry* entry = result->second; | |
897 DCHECK(entry); | |
898 | 1244 |
899 if (!AngleValidateShaderSource(entry)) { | 1245 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D, |
900 // Shader didn't validate; don't move forward with compiling | 1246 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, |
901 // translated source. | 1247 WGC3Dsizei, WGC3Dsizei) |
902 return; | |
903 } | |
904 | |
905 const char* translated_source = entry->translated_source.get(); | |
906 int shader_length = translated_source ? strlen(translated_source) : 0; | |
907 glShaderSource( | |
908 shader, 1, const_cast<const char**>(&translated_source), &shader_length); | |
909 glCompileShader(shader); | |
910 | |
911 #ifndef NDEBUG | |
912 int compileStatus; | |
913 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); | |
914 // DCHECK that ANGLE generated GLSL will be accepted by OpenGL | |
915 DCHECK(compileStatus == GL_TRUE); | |
916 #endif | |
917 } | |
918 | |
919 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTexImage2D( | |
920 WGC3Denum target, WGC3Dint level, WGC3Denum internalformat, WGC3Dint x, | |
921 WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border) { | |
922 makeContextCurrent(); | |
923 | |
924 bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_); | |
925 if (needsResolve) { | |
926 ResolveMultisampledFramebuffer(x, y, width, height); | |
927 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); | |
928 } | |
929 | |
930 glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); | |
931 | |
932 if (needsResolve) | |
933 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | |
934 } | |
935 | |
936 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTexSubImage2D( | |
937 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, | |
938 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) { | |
939 makeContextCurrent(); | |
940 | |
941 bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_); | |
942 if (needsResolve) { | |
943 ResolveMultisampledFramebuffer(x, y, width, height); | |
944 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); | |
945 } | |
946 | |
947 glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); | |
948 | |
949 if (needsResolve) | |
950 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | |
951 } | |
952 | 1248 |
953 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) | 1249 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) |
954 | 1250 |
955 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) | 1251 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) |
956 | 1252 |
957 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) | 1253 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) |
958 | 1254 |
959 DELEGATE_TO_GL_2(depthRange, DepthRange, WGC3Dclampf, WGC3Dclampf) | 1255 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf) |
960 | 1256 |
961 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) | 1257 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) |
962 | 1258 |
963 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) | 1259 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) |
964 | 1260 |
965 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, WGC3Duint) | 1261 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, |
| 1262 WGC3Duint) |
966 | 1263 |
967 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) | 1264 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) |
968 | 1265 |
969 void WebGraphicsContext3DInProcessCommandBufferImpl::drawElements( | 1266 void WebGraphicsContext3DInProcessCommandBufferImpl::drawElements( |
970 WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset) { | 1267 WGC3Denum mode, |
971 makeContextCurrent(); | 1268 WGC3Dsizei count, |
972 glDrawElements(mode, count, type, | 1269 WGC3Denum type, |
973 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); | 1270 WGC3Dintptr offset) { |
| 1271 ClearContext(); |
| 1272 gl_->DrawElements( |
| 1273 mode, count, type, |
| 1274 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); |
974 } | 1275 } |
975 | 1276 |
976 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) | 1277 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) |
977 | 1278 |
978 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, WGC3Duint) | 1279 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, |
| 1280 WGC3Duint) |
979 | 1281 |
980 DELEGATE_TO_GL(finish, Finish) | 1282 DELEGATE_TO_GL(finish, Finish) |
981 | 1283 |
982 DELEGATE_TO_GL(flush, Flush) | 1284 DELEGATE_TO_GL(flush, Flush) |
983 | 1285 |
984 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbufferEXT, | 1286 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer, |
985 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) | 1287 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) |
986 | 1288 |
987 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, | 1289 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D, |
988 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) | 1290 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) |
989 | 1291 |
990 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) | 1292 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) |
991 | 1293 |
992 void WebGraphicsContext3DInProcessCommandBufferImpl::generateMipmap(WGC3Denum ta
rget) { | 1294 DELEGATE_TO_GL_1(generateMipmap, GenerateMipmap, WGC3Denum) |
993 makeContextCurrent(); | |
994 if (is_gles2_ || have_ext_framebuffer_object_) | |
995 glGenerateMipmapEXT(target); | |
996 // FIXME: provide alternative code path? This will be unpleasant | |
997 // to implement if glGenerateMipmapEXT is not available -- it will | |
998 // require a texture readback and re-upload. | |
999 } | |
1000 | 1295 |
1001 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib( | 1296 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib( |
1002 WebGLId program, WGC3Duint index, ActiveInfo& info) { | 1297 WebGLId program, WGC3Duint index, ActiveInfo& info) { |
1003 makeContextCurrent(); | 1298 ClearContext(); |
1004 if (!program) { | 1299 if (!program) { |
1005 synthesizeGLError(GL_INVALID_VALUE); | 1300 synthesizeGLError(GL_INVALID_VALUE); |
1006 return false; | 1301 return false; |
1007 } | 1302 } |
1008 GLint max_name_length = -1; | 1303 GLint max_name_length = -1; |
1009 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); | 1304 gl_->GetProgramiv( |
| 1305 program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); |
1010 if (max_name_length < 0) | 1306 if (max_name_length < 0) |
1011 return false; | 1307 return false; |
1012 scoped_array<GLchar> name(new GLchar[max_name_length]); | 1308 scoped_array<GLchar> name(new GLchar[max_name_length]); |
| 1309 if (!name.get()) { |
| 1310 synthesizeGLError(GL_OUT_OF_MEMORY); |
| 1311 return false; |
| 1312 } |
1013 GLsizei length = 0; | 1313 GLsizei length = 0; |
1014 GLint size = -1; | 1314 GLint size = -1; |
1015 GLenum type = 0; | 1315 GLenum type = 0; |
1016 glGetActiveAttrib(program, index, max_name_length, | 1316 gl_->GetActiveAttrib( |
1017 &length, &size, &type, name.get()); | 1317 program, index, max_name_length, &length, &size, &type, name.get()); |
1018 if (size < 0) { | 1318 if (size < 0) { |
1019 return false; | 1319 return false; |
1020 } | 1320 } |
1021 info.name = WebString::fromUTF8(name.get(), length); | 1321 info.name = WebKit::WebString::fromUTF8(name.get(), length); |
1022 info.type = type; | 1322 info.type = type; |
1023 info.size = size; | 1323 info.size = size; |
1024 return true; | 1324 return true; |
1025 } | 1325 } |
1026 | 1326 |
1027 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveUniform( | 1327 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveUniform( |
1028 WebGLId program, WGC3Duint index, ActiveInfo& info) { | 1328 WebGLId program, WGC3Duint index, ActiveInfo& info) { |
1029 makeContextCurrent(); | 1329 ClearContext(); |
1030 GLint max_name_length = -1; | 1330 GLint max_name_length = -1; |
1031 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); | 1331 gl_->GetProgramiv( |
| 1332 program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); |
1032 if (max_name_length < 0) | 1333 if (max_name_length < 0) |
1033 return false; | 1334 return false; |
1034 scoped_array<GLchar> name(new GLchar[max_name_length]); | 1335 scoped_array<GLchar> name(new GLchar[max_name_length]); |
| 1336 if (!name.get()) { |
| 1337 synthesizeGLError(GL_OUT_OF_MEMORY); |
| 1338 return false; |
| 1339 } |
1035 GLsizei length = 0; | 1340 GLsizei length = 0; |
1036 GLint size = -1; | 1341 GLint size = -1; |
1037 GLenum type = 0; | 1342 GLenum type = 0; |
1038 glGetActiveUniform(program, index, max_name_length, | 1343 gl_->GetActiveUniform( |
1039 &length, &size, &type, name.get()); | 1344 program, index, max_name_length, &length, &size, &type, name.get()); |
1040 if (size < 0) { | 1345 if (size < 0) { |
1041 return false; | 1346 return false; |
1042 } | 1347 } |
1043 info.name = WebString::fromUTF8(name.get(), length); | 1348 info.name = WebKit::WebString::fromUTF8(name.get(), length); |
1044 info.type = type; | 1349 info.type = type; |
1045 info.size = size; | 1350 info.size = size; |
1046 return true; | 1351 return true; |
1047 } | 1352 } |
1048 | 1353 |
1049 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, | 1354 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, |
1050 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*) | 1355 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*) |
1051 | 1356 |
1052 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, | 1357 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, |
1053 WebGLId, const WGC3Dchar*, WGC3Dint) | 1358 WebGLId, const WGC3Dchar*, WGC3Dint) |
1054 | 1359 |
1055 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, | 1360 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*) |
1056 WGC3Denum, WGC3Dboolean*) | |
1057 | 1361 |
1058 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, | 1362 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, |
1059 WGC3Denum, WGC3Denum, WGC3Dint*) | 1363 WGC3Denum, WGC3Denum, WGC3Dint*) |
1060 | 1364 |
1061 WebGraphicsContext3D::Attributes WebGraphicsContext3DInProcessCommandBufferImpl:
: | 1365 WebKit::WebGraphicsContext3D::Attributes |
1062 getContextAttributes() { | 1366 WebGraphicsContext3DInProcessCommandBufferImpl::getContextAttributes() { |
1063 return attributes_; | 1367 return attributes_; |
1064 } | 1368 } |
1065 | 1369 |
1066 WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl::getError() { | 1370 WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl::getError() { |
1067 DCHECK(synthetic_errors_list_.size() == synthetic_errors_set_.size()); | 1371 ClearContext(); |
1068 if (!synthetic_errors_set_.empty()) { | 1372 if (!synthetic_errors_.empty()) { |
1069 WGC3Denum error = synthetic_errors_list_.front(); | 1373 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin(); |
1070 synthetic_errors_list_.pop_front(); | 1374 WGC3Denum err = *iter; |
1071 synthetic_errors_set_.erase(error); | 1375 synthetic_errors_.erase(iter); |
1072 return error; | 1376 return err; |
1073 } | 1377 } |
1074 | 1378 |
1075 makeContextCurrent(); | 1379 return gl_->GetError(); |
1076 return glGetError(); | |
1077 } | 1380 } |
1078 | 1381 |
1079 bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() { | 1382 bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() { |
1080 return false; | 1383 return context_->IsCommandBufferContextLost(); |
1081 } | 1384 } |
1082 | 1385 |
1083 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) | 1386 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) |
1084 | 1387 |
1085 void WebGraphicsContext3DInProcessCommandBufferImpl::getFramebufferAttachmentPar
ameteriv( | 1388 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv, |
1086 WGC3Denum target, WGC3Denum attachment, | 1389 GetFramebufferAttachmentParameteriv, |
1087 WGC3Denum pname, WGC3Dint* value) { | 1390 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Dint*) |
1088 makeContextCurrent(); | |
1089 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) | |
1090 attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT; | |
1091 // either works. | |
1092 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); | |
1093 } | |
1094 | 1391 |
1095 void WebGraphicsContext3DInProcessCommandBufferImpl::getIntegerv( | 1392 DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, WGC3Denum, WGC3Dint*) |
1096 WGC3Denum pname, WGC3Dint* value) { | |
1097 makeContextCurrent(); | |
1098 if (is_gles2_) { | |
1099 glGetIntegerv(pname, value); | |
1100 return; | |
1101 } | |
1102 // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and | |
1103 // MAX_VARYING_VECTORS because desktop GL's corresponding queries | |
1104 // return the number of components whereas GLES2 return the number | |
1105 // of vectors (each vector has 4 components). Therefore, the value | |
1106 // returned by desktop GL needs to be divided by 4. | |
1107 switch (pname) { | |
1108 case MAX_FRAGMENT_UNIFORM_VECTORS: | |
1109 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value); | |
1110 *value /= 4; | |
1111 break; | |
1112 case MAX_VERTEX_UNIFORM_VECTORS: | |
1113 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value); | |
1114 *value /= 4; | |
1115 break; | |
1116 case MAX_VARYING_VECTORS: | |
1117 glGetIntegerv(GL_MAX_VARYING_FLOATS, value); | |
1118 *value /= 4; | |
1119 break; | |
1120 default: | |
1121 glGetIntegerv(pname, value); | |
1122 } | |
1123 } | |
1124 | 1393 |
1125 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) | 1394 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) |
1126 | 1395 |
1127 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getProgramInfoLog( | 1396 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: |
1128 WebGLId program) { | 1397 getProgramInfoLog(WebGLId program) { |
1129 makeContextCurrent(); | 1398 ClearContext(); |
1130 GLint log_length; | 1399 GLint logLength = 0; |
1131 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length); | 1400 gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); |
1132 if (!log_length) | 1401 if (!logLength) |
1133 return WebString(); | 1402 return WebKit::WebString(); |
1134 scoped_array<GLchar> log(new GLchar[log_length]); | 1403 scoped_array<GLchar> log(new GLchar[logLength]); |
1135 GLsizei returned_log_length; | 1404 if (!log.get()) |
1136 glGetProgramInfoLog(program, log_length, &returned_log_length, log.get()); | 1405 return WebKit::WebString(); |
1137 DCHECK(log_length == returned_log_length + 1); | 1406 GLsizei returnedLogLength = 0; |
1138 WebString res = WebString::fromUTF8(log.get(), returned_log_length); | 1407 gl_->GetProgramInfoLog( |
| 1408 program, logLength, &returnedLogLength, log.get()); |
| 1409 DCHECK_EQ(logLength, returnedLogLength + 1); |
| 1410 WebKit::WebString res = |
| 1411 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); |
1139 return res; | 1412 return res; |
1140 } | 1413 } |
1141 | 1414 |
1142 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT, | 1415 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv, |
1143 WGC3Denum, WGC3Denum, WGC3Dint*) | 1416 WGC3Denum, WGC3Denum, WGC3Dint*) |
1144 | 1417 |
1145 void WebGraphicsContext3DInProcessCommandBufferImpl::getShaderiv( | 1418 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*) |
1146 WebGLId shader, WGC3Denum pname, WGC3Dint* value) { | |
1147 makeContextCurrent(); | |
1148 | 1419 |
1149 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | 1420 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: |
1150 if (result != shader_source_map_.end()) { | 1421 getShaderInfoLog(WebGLId shader) { |
1151 ShaderSourceEntry* entry = result->second; | 1422 ClearContext(); |
1152 DCHECK(entry); | 1423 GLint logLength = 0; |
1153 switch (pname) { | 1424 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); |
1154 case GL_COMPILE_STATUS: | 1425 if (!logLength) |
1155 if (!entry->is_valid) { | 1426 return WebKit::WebString(); |
1156 *value = 0; | 1427 scoped_array<GLchar> log(new GLchar[logLength]); |
1157 return; | 1428 if (!log.get()) |
1158 } | 1429 return WebKit::WebString(); |
1159 break; | 1430 GLsizei returnedLogLength = 0; |
1160 case GL_INFO_LOG_LENGTH: | 1431 gl_->GetShaderInfoLog( |
1161 if (!entry->is_valid) { | 1432 shader, logLength, &returnedLogLength, log.get()); |
1162 *value = entry->log.get() ? strlen(entry->log.get()) : 0; | 1433 DCHECK_EQ(logLength, returnedLogLength + 1); |
1163 if (*value) | 1434 WebKit::WebString res = |
1164 (*value)++; | 1435 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); |
1165 return; | |
1166 } | |
1167 break; | |
1168 case GL_SHADER_SOURCE_LENGTH: | |
1169 *value = entry->source.get() ? strlen(entry->source.get()) : 0; | |
1170 if (*value) | |
1171 (*value)++; | |
1172 return; | |
1173 } | |
1174 } | |
1175 | |
1176 glGetShaderiv(shader, pname, value); | |
1177 } | |
1178 | |
1179 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderInfoLog(WebGL
Id shader) { | |
1180 makeContextCurrent(); | |
1181 | |
1182 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | |
1183 if (result != shader_source_map_.end()) { | |
1184 ShaderSourceEntry* entry = result->second; | |
1185 DCHECK(entry); | |
1186 if (!entry->is_valid) { | |
1187 if (!entry->log.get()) | |
1188 return WebString(); | |
1189 WebString res = WebString::fromUTF8( | |
1190 entry->log.get(), strlen(entry->log.get())); | |
1191 return res; | |
1192 } | |
1193 } | |
1194 | |
1195 GLint log_length = 0; | |
1196 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); | |
1197 if (log_length <= 1) | |
1198 return WebString(); | |
1199 scoped_array<GLchar> log(new GLchar[log_length]); | |
1200 GLsizei returned_log_length; | |
1201 glGetShaderInfoLog(shader, log_length, &returned_log_length, log.get()); | |
1202 DCHECK(log_length == returned_log_length + 1); | |
1203 WebString res = WebString::fromUTF8(log.get(), returned_log_length); | |
1204 return res; | 1436 return res; |
1205 } | 1437 } |
1206 | 1438 |
1207 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderSource(WebGLI
d shader) { | 1439 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl:: |
1208 makeContextCurrent(); | 1440 getShaderSource(WebGLId shader) { |
1209 | 1441 ClearContext(); |
1210 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | 1442 GLint logLength = 0; |
1211 if (result != shader_source_map_.end()) { | 1443 gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); |
1212 ShaderSourceEntry* entry = result->second; | 1444 if (!logLength) |
1213 DCHECK(entry); | 1445 return WebKit::WebString(); |
1214 if (!entry->source.get()) | 1446 scoped_array<GLchar> log(new GLchar[logLength]); |
1215 return WebString(); | 1447 if (!log.get()) |
1216 WebString res = WebString::fromUTF8( | 1448 return WebKit::WebString(); |
1217 entry->source.get(), strlen(entry->source.get())); | 1449 GLsizei returnedLogLength = 0; |
1218 return res; | 1450 gl_->GetShaderSource( |
1219 } | 1451 shader, logLength, &returnedLogLength, log.get()); |
1220 | 1452 DCHECK_EQ(logLength, returnedLogLength + 1); |
1221 GLint log_length = 0; | 1453 WebKit::WebString res = |
1222 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &log_length); | 1454 WebKit::WebString::fromUTF8(log.get(), returnedLogLength); |
1223 if (log_length <= 1) | |
1224 return WebString(); | |
1225 scoped_array<GLchar> log(new GLchar[log_length]); | |
1226 GLsizei returned_log_length; | |
1227 glGetShaderSource(shader, log_length, &returned_log_length, log.get()); | |
1228 DCHECK(log_length == returned_log_length + 1); | |
1229 WebString res = WebString::fromUTF8(log.get(), returned_log_length); | |
1230 return res; | 1455 return res; |
1231 } | 1456 } |
1232 | 1457 |
1233 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString(WGC3Denum na
me) { | 1458 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString( |
1234 makeContextCurrent(); | 1459 WGC3Denum name) { |
1235 std::string result(reinterpret_cast<const char*>(glGetString(name))); | 1460 ClearContext(); |
1236 if (name == GL_EXTENSIONS) { | 1461 return WebKit::WebString::fromUTF8( |
1237 // GL_CHROMIUM_copy_texture_to_parent_texture requires the | 1462 reinterpret_cast<const char*>(gl_->GetString(name))); |
1238 // desktopGL-only function glGetTexLevelParameteriv (GLES2 | |
1239 // doesn't support it). | |
1240 if (!is_gles2_) | |
1241 result += " GL_CHROMIUM_copy_texture_to_parent_texture"; | |
1242 } | |
1243 return WebString::fromUTF8(result.c_str()); | |
1244 } | 1463 } |
1245 | 1464 |
1246 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, | 1465 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, |
1247 WGC3Denum, WGC3Denum, WGC3Dfloat*) | 1466 WGC3Denum, WGC3Denum, WGC3Dfloat*) |
1248 | 1467 |
1249 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, | 1468 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, |
1250 WGC3Denum, WGC3Denum, WGC3Dint*) | 1469 WGC3Denum, WGC3Denum, WGC3Dint*) |
1251 | 1470 |
1252 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*) | 1471 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*) |
1253 | 1472 |
1254 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*) | 1473 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*) |
1255 | 1474 |
1256 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, | 1475 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, |
1257 WebGLId, const WGC3Dchar*, WGC3Dint) | 1476 WebGLId, const WGC3Dchar*, WGC3Dint) |
1258 | 1477 |
1259 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, | 1478 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, |
1260 WGC3Duint, WGC3Denum, WGC3Dfloat*) | 1479 WGC3Duint, WGC3Denum, WGC3Dfloat*) |
1261 | 1480 |
1262 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, | 1481 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, |
1263 WGC3Duint, WGC3Denum, WGC3Dint*) | 1482 WGC3Duint, WGC3Denum, WGC3Dint*) |
1264 | 1483 |
1265 WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl::getVertexAttribOff
set( | 1484 WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl:: |
1266 WGC3Duint index, WGC3Denum pname) { | 1485 getVertexAttribOffset(WGC3Duint index, WGC3Denum pname) { |
1267 makeContextCurrent(); | 1486 ClearContext(); |
1268 void* pointer; | 1487 GLvoid* value = NULL; |
1269 glGetVertexAttribPointerv(index, pname, &pointer); | 1488 // NOTE: If pname is ever a value that returns more then 1 element |
1270 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer)); | 1489 // this will corrupt memory. |
| 1490 gl_->GetVertexAttribPointerv(index, pname, &value); |
| 1491 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value)); |
1271 } | 1492 } |
1272 | 1493 |
1273 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) | 1494 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) |
1274 | 1495 |
1275 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) | 1496 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) |
1276 | 1497 |
1277 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) | 1498 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) |
1278 | 1499 |
1279 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebufferEXT, WebGLId, WGC3Dboolean) | 1500 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean) |
1280 | 1501 |
1281 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) | 1502 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) |
1282 | 1503 |
1283 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbufferEXT, WebGLId, WGC3Dboolean) | 1504 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean) |
1284 | 1505 |
1285 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) | 1506 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) |
1286 | 1507 |
1287 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean) | 1508 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean) |
1288 | 1509 |
1289 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat) | 1510 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat) |
1290 | 1511 |
1291 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) | 1512 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) |
1292 | 1513 |
1293 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) | 1514 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) |
1294 | 1515 |
1295 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) | 1516 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) |
1296 | 1517 |
1297 void WebGraphicsContext3DInProcessCommandBufferImpl::readPixels( | 1518 DELEGATE_TO_GL_7(readPixels, ReadPixels, |
1298 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, | 1519 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum, |
1299 WGC3Denum format, WGC3Denum type, void* pixels) { | 1520 WGC3Denum, void*) |
1300 makeContextCurrent(); | |
1301 // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., | |
1302 // all previous rendering calls should be done before reading pixels. | |
1303 glFlush(); | |
1304 bool needs_resolve = | |
1305 (attributes_.antialias && bound_fbo_ == multisample_fbo_); | |
1306 if (needs_resolve) { | |
1307 ResolveMultisampledFramebuffer(x, y, width, height); | |
1308 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); | |
1309 glFlush(); | |
1310 } | |
1311 | 1521 |
1312 glReadPixels(x, y, width, height, format, type, pixels); | 1522 void WebGraphicsContext3DInProcessCommandBufferImpl::releaseShaderCompiler() { |
1313 | 1523 ClearContext(); |
1314 if (needs_resolve) | |
1315 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_); | |
1316 } | 1524 } |
1317 | 1525 |
1318 void WebGraphicsContext3DInProcessCommandBufferImpl::releaseShaderCompiler() { | 1526 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage, |
1319 } | 1527 WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei) |
1320 | 1528 |
1321 void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorage( | 1529 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dfloat, WGC3Dboolean) |
1322 WGC3Denum target, | |
1323 WGC3Denum internalformat, | |
1324 WGC3Dsizei width, | |
1325 WGC3Dsizei height) { | |
1326 makeContextCurrent(); | |
1327 if (!is_gles2_) { | |
1328 switch (internalformat) { | |
1329 case GL_DEPTH_STENCIL: | |
1330 internalformat = GL_DEPTH24_STENCIL8_EXT; | |
1331 break; | |
1332 case GL_DEPTH_COMPONENT16: | |
1333 internalformat = GL_DEPTH_COMPONENT; | |
1334 break; | |
1335 case GL_RGBA4: | |
1336 case GL_RGB5_A1: | |
1337 internalformat = GL_RGBA; | |
1338 break; | |
1339 case 0x8D62: // GL_RGB565 | |
1340 internalformat = GL_RGB; | |
1341 break; | |
1342 } | |
1343 } | |
1344 glRenderbufferStorageEXT(target, internalformat, width, height); | |
1345 } | |
1346 | |
1347 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dclampf, WGC3Dboolean) | |
1348 | 1530 |
1349 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) | 1531 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) |
1350 | 1532 |
1351 void WebGraphicsContext3DInProcessCommandBufferImpl::texImage2D( | |
1352 WGC3Denum target, WGC3Dint level, WGC3Denum internalFormat, | |
1353 WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, | |
1354 WGC3Denum format, WGC3Denum type, const void* pixels) { | |
1355 if (width && height && !pixels) { | |
1356 synthesizeGLError(GL_INVALID_VALUE); | |
1357 return; | |
1358 } | |
1359 makeContextCurrent(); | |
1360 glTexImage2D(target, level, internalFormat, | |
1361 width, height, border, format, type, pixels); | |
1362 } | |
1363 | |
1364 void WebGraphicsContext3DInProcessCommandBufferImpl::shaderSource( | 1533 void WebGraphicsContext3DInProcessCommandBufferImpl::shaderSource( |
1365 WebGLId shader, const WGC3Dchar* source) { | 1534 WebGLId shader, const WGC3Dchar* string) { |
1366 makeContextCurrent(); | 1535 ClearContext(); |
1367 GLint length = source ? strlen(source) : 0; | 1536 GLint length = strlen(string); |
1368 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | 1537 gl_->ShaderSource(shader, 1, &string, &length); |
1369 if (result != shader_source_map_.end()) { | |
1370 ShaderSourceEntry* entry = result->second; | |
1371 DCHECK(entry); | |
1372 entry->source.reset(new char[length + 1]); | |
1373 memcpy(entry->source.get(), source, (length + 1) * sizeof(char)); | |
1374 } else { | |
1375 glShaderSource(shader, 1, &source, &length); | |
1376 } | |
1377 } | 1538 } |
1378 | 1539 |
1379 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) | 1540 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) |
1380 | 1541 |
1381 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, | 1542 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, |
1382 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint) | 1543 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint) |
1383 | 1544 |
1384 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint) | 1545 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint) |
1385 | 1546 |
1386 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, | 1547 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, |
1387 WGC3Denum, WGC3Duint) | 1548 WGC3Denum, WGC3Duint) |
1388 | 1549 |
1389 DELEGATE_TO_GL_3(stencilOp, StencilOp, | 1550 DELEGATE_TO_GL_3(stencilOp, StencilOp, |
1390 WGC3Denum, WGC3Denum, WGC3Denum) | 1551 WGC3Denum, WGC3Denum, WGC3Denum) |
1391 | 1552 |
1392 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, | 1553 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, |
1393 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) | 1554 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) |
1394 | 1555 |
1395 DELEGATE_TO_GL_3(texParameterf, TexParameterf, WGC3Denum, WGC3Denum, WGC3Dfloat) | 1556 DELEGATE_TO_GL_9(texImage2D, TexImage2D, |
| 1557 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei, |
| 1558 WGC3Dint, WGC3Denum, WGC3Denum, const void*) |
1396 | 1559 |
1397 DELEGATE_TO_GL_3(texParameteri, TexParameteri, WGC3Denum, WGC3Denum, WGC3Dint) | 1560 DELEGATE_TO_GL_3(texParameterf, TexParameterf, |
| 1561 WGC3Denum, WGC3Denum, WGC3Dfloat); |
| 1562 |
| 1563 static const unsigned int kTextureWrapR = 0x8072; |
| 1564 |
| 1565 void WebGraphicsContext3DInProcessCommandBufferImpl::texParameteri( |
| 1566 WGC3Denum target, WGC3Denum pname, WGC3Dint param) { |
| 1567 ClearContext(); |
| 1568 // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in |
| 1569 // GraphicsContext3D.cpp is strictly necessary to avoid seams at the |
| 1570 // edge of cube maps, and, if it is, push it into the GLES2 service |
| 1571 // side code. |
| 1572 if (pname == kTextureWrapR) { |
| 1573 return; |
| 1574 } |
| 1575 gl_->TexParameteri(target, pname, param); |
| 1576 } |
1398 | 1577 |
1399 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, | 1578 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, |
1400 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, | 1579 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, |
1401 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) | 1580 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) |
1402 | 1581 |
1403 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) | 1582 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) |
1404 | 1583 |
1405 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, | 1584 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei, |
1406 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) | 1585 const WGC3Dfloat*) |
1407 | 1586 |
1408 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) | 1587 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) |
1409 | 1588 |
1410 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | 1589 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) |
1411 | 1590 |
1412 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) | 1591 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) |
1413 | 1592 |
1414 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, | 1593 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei, |
1415 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) | 1594 const WGC3Dfloat*) |
1416 | 1595 |
1417 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) | 1596 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) |
1418 | 1597 |
1419 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | 1598 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) |
1420 | 1599 |
1421 DELEGATE_TO_GL_4(uniform3f, Uniform3f, | 1600 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint, |
1422 WGC3Dint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | 1601 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) |
1423 | 1602 |
1424 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, | 1603 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei, |
1425 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) | 1604 const WGC3Dfloat*) |
1426 | 1605 |
1427 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) | 1606 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) |
1428 | 1607 |
1429 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | 1608 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) |
1430 | 1609 |
1431 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, | 1610 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, |
1432 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | 1611 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) |
1433 | 1612 |
1434 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, | 1613 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei, |
1435 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) | 1614 const WGC3Dfloat*) |
1436 | 1615 |
1437 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, | 1616 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, |
1438 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) | 1617 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) |
1439 | 1618 |
1440 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) | 1619 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) |
1441 | 1620 |
1442 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, | 1621 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, |
1443 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) | 1622 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) |
1444 | 1623 |
1445 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, | 1624 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, |
1446 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) | 1625 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) |
1447 | 1626 |
1448 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, | 1627 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, |
1449 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) | 1628 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) |
1450 | 1629 |
1451 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) | 1630 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) |
1452 | 1631 |
1453 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) | 1632 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) |
1454 | 1633 |
1455 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) | 1634 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) |
1456 | 1635 |
1457 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, const WGC3Dfloat*) | 1636 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, |
| 1637 const WGC3Dfloat*) |
1458 | 1638 |
1459 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, | 1639 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint, |
1460 WGC3Duint, WGC3Dfloat, WGC3Dfloat) | 1640 WGC3Dfloat, WGC3Dfloat) |
1461 | 1641 |
1462 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, const WGC3Dfloat*) | 1642 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, |
| 1643 const WGC3Dfloat*) |
1463 | 1644 |
1464 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, | 1645 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint, |
1465 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | 1646 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) |
1466 | 1647 |
1467 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, const WGC3Dfloat*) | 1648 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, |
| 1649 const WGC3Dfloat*) |
1468 | 1650 |
1469 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, | 1651 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint, |
1470 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) | 1652 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) |
1471 | 1653 |
1472 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, const WGC3Dfloat*) | 1654 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, |
| 1655 const WGC3Dfloat*) |
1473 | 1656 |
1474 void WebGraphicsContext3DInProcessCommandBufferImpl::vertexAttribPointer( | 1657 void WebGraphicsContext3DInProcessCommandBufferImpl::vertexAttribPointer( |
1475 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, | 1658 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, |
1476 WGC3Dsizei stride, WGC3Dintptr offset) { | 1659 WGC3Dsizei stride, WGC3Dintptr offset) { |
1477 makeContextCurrent(); | 1660 ClearContext(); |
1478 glVertexAttribPointer(index, size, type, normalized, stride, | 1661 gl_->VertexAttribPointer( |
1479 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); | 1662 index, size, type, normalized, stride, |
| 1663 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); |
1480 } | 1664 } |
1481 | 1665 |
1482 DELEGATE_TO_GL_4(viewport, Viewport, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) | 1666 DELEGATE_TO_GL_4(viewport, Viewport, |
| 1667 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) |
1483 | 1668 |
1484 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createBuffer() { | 1669 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createBuffer() { |
1485 makeContextCurrent(); | 1670 ClearContext(); |
1486 GLuint o; | 1671 GLuint o; |
1487 glGenBuffersARB(1, &o); | 1672 gl_->GenBuffers(1, &o); |
1488 return o; | 1673 return o; |
1489 } | 1674 } |
1490 | 1675 |
1491 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createFramebuffer() { | 1676 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createFramebuffer() { |
1492 makeContextCurrent(); | 1677 ClearContext(); |
1493 GLuint o = 0; | 1678 GLuint o = 0; |
1494 glGenFramebuffersEXT(1, &o); | 1679 gl_->GenFramebuffers(1, &o); |
1495 return o; | 1680 return o; |
1496 } | 1681 } |
1497 | 1682 |
1498 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createProgram() { | 1683 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createProgram() { |
1499 makeContextCurrent(); | 1684 ClearContext(); |
1500 return glCreateProgram(); | 1685 return gl_->CreateProgram(); |
1501 } | 1686 } |
1502 | 1687 |
1503 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createRenderbuffer() { | 1688 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createRenderbuffer() { |
1504 makeContextCurrent(); | 1689 ClearContext(); |
1505 GLuint o; | 1690 GLuint o; |
1506 glGenRenderbuffersEXT(1, &o); | 1691 gl_->GenRenderbuffers(1, &o); |
1507 return o; | 1692 return o; |
1508 } | 1693 } |
1509 | 1694 |
1510 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createShader( | 1695 DELEGATE_TO_GL_1R(createShader, CreateShader, WGC3Denum, WebGLId); |
1511 WGC3Denum shaderType) { | |
1512 makeContextCurrent(); | |
1513 DCHECK(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER); | |
1514 GLuint shader = glCreateShader(shaderType); | |
1515 if (shader) { | |
1516 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | |
1517 if (result != shader_source_map_.end()) { | |
1518 delete result->second; | |
1519 shader_source_map_.erase(result); | |
1520 } | |
1521 shader_source_map_.insert( | |
1522 ShaderSourceMap::value_type(shader, new ShaderSourceEntry(shaderType))); | |
1523 } | |
1524 | |
1525 return shader; | |
1526 } | |
1527 | 1696 |
1528 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createTexture() { | 1697 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createTexture() { |
1529 makeContextCurrent(); | 1698 ClearContext(); |
1530 GLuint o; | 1699 GLuint o; |
1531 glGenTextures(1, &o); | 1700 gl_->GenTextures(1, &o); |
1532 return o; | 1701 return o; |
1533 } | 1702 } |
1534 | 1703 |
1535 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer(WebGLId buffer
) { | 1704 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer( |
1536 makeContextCurrent(); | 1705 WebGLId buffer) { |
1537 glDeleteBuffersARB(1, &buffer); | 1706 ClearContext(); |
| 1707 gl_->DeleteBuffers(1, &buffer); |
1538 } | 1708 } |
1539 | 1709 |
1540 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteFramebuffer( | 1710 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteFramebuffer( |
1541 WebGLId framebuffer) { | 1711 WebGLId framebuffer) { |
1542 makeContextCurrent(); | 1712 ClearContext(); |
1543 glDeleteFramebuffersEXT(1, &framebuffer); | 1713 gl_->DeleteFramebuffers(1, &framebuffer); |
1544 } | 1714 } |
1545 | 1715 |
1546 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram(WebGLId progr
am) { | 1716 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram( |
1547 makeContextCurrent(); | 1717 WebGLId program) { |
1548 glDeleteProgram(program); | 1718 ClearContext(); |
| 1719 gl_->DeleteProgram(program); |
1549 } | 1720 } |
1550 | 1721 |
1551 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteRenderbuffer( | 1722 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteRenderbuffer( |
1552 WebGLId renderbuffer) { | 1723 WebGLId renderbuffer) { |
1553 makeContextCurrent(); | 1724 ClearContext(); |
1554 glDeleteRenderbuffersEXT(1, &renderbuffer); | 1725 gl_->DeleteRenderbuffers(1, &renderbuffer); |
1555 } | 1726 } |
1556 | 1727 |
1557 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader(WebGLId shader
) { | 1728 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader( |
1558 makeContextCurrent(); | 1729 WebGLId shader) { |
1559 | 1730 ClearContext(); |
1560 ShaderSourceMap::iterator result = shader_source_map_.find(shader); | 1731 gl_->DeleteShader(shader); |
1561 if (result != shader_source_map_.end()) { | |
1562 delete result->second; | |
1563 shader_source_map_.erase(result); | |
1564 } | |
1565 glDeleteShader(shader); | |
1566 } | 1732 } |
1567 | 1733 |
1568 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture(WebGLId textu
re) { | 1734 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture( |
1569 makeContextCurrent(); | 1735 WebGLId texture) { |
1570 glDeleteTextures(1, &texture); | 1736 ClearContext(); |
| 1737 gl_->DeleteTextures(1, &texture); |
1571 } | 1738 } |
1572 | 1739 |
1573 bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleCreateCompilers() { | 1740 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToCompositor( |
1574 if (!ShInitialize()) | 1741 WebGLId texture, WebGLId parentTexture) { |
1575 return false; | 1742 // TODO(gmam): See if we can comment this in. |
1576 | 1743 // ClearContext(); |
1577 ShBuiltInResources resources; | 1744 gl_->CopyTextureToParentTextureCHROMIUM(texture, parentTexture); |
1578 ShInitBuiltInResources(&resources); | 1745 gl_->Flush(); |
1579 getIntegerv(GL_MAX_VERTEX_ATTRIBS, &resources.MaxVertexAttribs); | |
1580 getIntegerv(MAX_VERTEX_UNIFORM_VECTORS, &resources.MaxVertexUniformVectors); | |
1581 getIntegerv(MAX_VARYING_VECTORS, &resources.MaxVaryingVectors); | |
1582 getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, | |
1583 &resources.MaxVertexTextureImageUnits); | |
1584 getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, | |
1585 &resources.MaxCombinedTextureImageUnits); | |
1586 getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &resources.MaxTextureImageUnits); | |
1587 getIntegerv(MAX_FRAGMENT_UNIFORM_VECTORS, | |
1588 &resources.MaxFragmentUniformVectors); | |
1589 // Always set to 1 for OpenGL ES. | |
1590 resources.MaxDrawBuffers = 1; | |
1591 | |
1592 fragment_compiler_ = ShConstructCompiler( | |
1593 SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, &resources); | |
1594 vertex_compiler_ = ShConstructCompiler( | |
1595 SH_VERTEX_SHADER, SH_WEBGL_SPEC, &resources); | |
1596 return (fragment_compiler_ && vertex_compiler_); | |
1597 } | 1746 } |
1598 | 1747 |
1599 void WebGraphicsContext3DInProcessCommandBufferImpl::AngleDestroyCompilers() { | 1748 void WebGraphicsContext3DInProcessCommandBufferImpl::OnSwapBuffersComplete() { |
1600 if (fragment_compiler_) { | |
1601 ShDestruct(fragment_compiler_); | |
1602 fragment_compiler_ = 0; | |
1603 } | |
1604 if (vertex_compiler_) { | |
1605 ShDestruct(vertex_compiler_); | |
1606 vertex_compiler_ = 0; | |
1607 } | |
1608 } | 1749 } |
1609 | 1750 |
1610 bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleValidateShaderSource( | 1751 void WebGraphicsContext3DInProcessCommandBufferImpl::setContextLostCallback( |
1611 ShaderSourceEntry* entry) { | 1752 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb) |
1612 entry->is_valid = false; | 1753 { |
1613 entry->translated_source.reset(); | 1754 context_lost_callback_ = cb; |
1614 entry->log.reset(); | 1755 } |
1615 | 1756 |
1616 ShHandle compiler = 0; | 1757 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() { |
1617 switch (entry->type) { | 1758 if (context_lost_callback_) { |
1618 case GL_FRAGMENT_SHADER: | 1759 context_lost_callback_->onContextLost(); |
1619 compiler = fragment_compiler_; | |
1620 break; | |
1621 case GL_VERTEX_SHADER: | |
1622 compiler = vertex_compiler_; | |
1623 break; | |
1624 } | 1760 } |
1625 if (!compiler) | |
1626 return false; | |
1627 | |
1628 char* source = entry->source.get(); | |
1629 if (!ShCompile(compiler, &source, 1, SH_OBJECT_CODE)) { | |
1630 int logSize = 0; | |
1631 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize); | |
1632 if (logSize > 1) { | |
1633 entry->log.reset(new char[logSize]); | |
1634 ShGetInfoLog(compiler, entry->log.get()); | |
1635 } | |
1636 return false; | |
1637 } | |
1638 | |
1639 int length = 0; | |
1640 if (is_gles2_) { | |
1641 // ANGLE does not yet have a GLSL ES backend. Therefore if the | |
1642 // compile succeeds we send the original source down. | |
1643 length = strlen(entry->source.get()); | |
1644 if (length > 0) | |
1645 ++length; // Add null terminator | |
1646 } else { | |
1647 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length); | |
1648 } | |
1649 if (length > 1) { | |
1650 entry->translated_source.reset(new char[length]); | |
1651 if (is_gles2_) | |
1652 strncpy(entry->translated_source.get(), entry->source.get(), length); | |
1653 else | |
1654 ShGetObjectCode(compiler, entry->translated_source.get()); | |
1655 } | |
1656 entry->is_valid = true; | |
1657 return true; | |
1658 } | 1761 } |
1659 | 1762 |
1660 } // namespace gpu | 1763 } // namespace gpu |
1661 } // namespace webkit | 1764 } // namespace webkit |
1662 | 1765 |
| 1766 #endif // defined(ENABLE_GPU) |
| 1767 |
OLD | NEW |