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

Side by Side Diff: webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc

Issue 7085002: make command buffer work in DRT (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: put back formatting missing from mac Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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
242 // Allocator for latches.
243 class LatchAllocator {
244 public:
245 static LatchAllocator* GetInstance();
246 static uint32 size() { return kMaxLatchesPerRenderer*sizeof(uint32); }
247 static const uint32_t kFreeLatch = 0xffffffffu;
248
249 LatchAllocator();
250 ~LatchAllocator();
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
45 WebGraphicsContext3DInProcessCommandBufferImpl::WebGraphicsContext3DInProcessCom mandBufferImpl() 710 WebGraphicsContext3DInProcessCommandBufferImpl::WebGraphicsContext3DInProcessCom mandBufferImpl()
46 : initialized_(false), 711 : context_(NULL),
47 render_directly_to_web_view_(false), 712 gl_(NULL),
48 is_gles2_(false), 713 web_view_(NULL),
49 have_ext_framebuffer_object_(false), 714 #if defined(OS_MACOSX)
50 have_ext_framebuffer_multisample_(false), 715 plugin_handle_(NULL),
51 have_angle_framebuffer_multisample_(false), 716 #endif // defined(OS_MACOSX)
52 texture_(0), 717 context_lost_callback_(0),
53 fbo_(0),
54 depth_stencil_buffer_(0),
55 cached_width_(0), 718 cached_width_(0),
56 cached_height_(0), 719 cached_height_(0),
57 multisample_fbo_(0), 720 bound_fbo_(0) {
58 multisample_depth_stencil_buffer_(0), 721 }
59 multisample_color_buffer_(0), 722
60 bound_fbo_(0), 723 WebGraphicsContext3DInProcessCommandBufferImpl::
61 bound_texture_(0), 724 ~WebGraphicsContext3DInProcessCommandBufferImpl() {
62 copy_texture_to_parent_texture_fbo_(0), 725 }
63 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 726
64 scanline_(0), 727 // This string should only be passed for WebGL contexts. Nothing ELSE!!!
65 #endif 728 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of
66 fragment_compiler_(0), 729 // a context should not pass this string.
67 vertex_compiler_(0) { 730 static const char* kWebGLPreferredGLExtensions =
68 } 731 "GL_OES_packed_depth_stencil "
69 732 "GL_OES_depth24 "
70 WebGraphicsContext3DInProcessCommandBufferImpl::~WebGraphicsContext3DInProcessCo mmandBufferImpl() { 733 "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, &copy_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 734
103 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( 735 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize(
104 WebGraphicsContext3D::Attributes attributes, 736 WebGraphicsContext3D::Attributes attributes,
105 WebView* webView, 737 WebKit::WebView* web_view,
106 bool render_directly_to_web_view) { 738 bool render_directly_to_web_view) {
107 if (!gfx::GLSurface::InitializeOneOff()) 739 webkit_glue::BindSkiaToCommandBufferGL();
740
741 // Convert WebGL context creation attributes into GLInProcessContext / EGL
742 // size requests.
743 const int alpha_size = attributes.alpha ? 8 : 0;
744 const int depth_size = attributes.depth ? 24 : 0;
745 const int stencil_size = attributes.stencil ? 8 : 0;
746 const int samples = attributes.antialias ? 4 : 0;
747 const int sample_buffers = attributes.antialias ? 1 : 0;
748 const int32 attribs[] = {
749 GLInProcessContext::ALPHA_SIZE, alpha_size,
750 GLInProcessContext::DEPTH_SIZE, depth_size,
751 GLInProcessContext::STENCIL_SIZE, stencil_size,
752 GLInProcessContext::SAMPLES, samples,
753 GLInProcessContext::SAMPLE_BUFFERS, sample_buffers,
754 GLInProcessContext::NONE,
755 };
756
757 const char* preferred_extensions = attributes.noExtensions ?
758 kWebGLPreferredGLExtensions : "*";
759
760 GURL active_url;
761 if (web_view && web_view->mainFrame())
762 active_url = GURL(web_view->mainFrame()->url());
763
764 GLInProcessContext* parent_context = NULL;
765 if (!render_directly_to_web_view) {
766 WebKit::WebGraphicsContext3D* view_context =
767 web_view->graphicsContext3D();
768 if (view_context) {
769 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl =
770 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>(
771 view_context);
772 parent_context = context_impl->context_;
773 } else {
774 NOTREACHED() << "no parent context.";
775 }
776 }
777
778 context_ = GLInProcessContext::CreateOffscreenContext(
779 parent_context,
780 gfx::Size(1, 1),
781 preferred_extensions,
782 attribs,
783 active_url);
784 web_view_ = NULL;
785
786 if (!context_)
108 return false; 787 return false;
109 gfx::BindSkiaToInProcessGL(); 788
110 789 gl_ = context_->GetImplementation();
111 render_directly_to_web_view_ = render_directly_to_web_view; 790 context_->SetContextLostCallback(
112 gfx::GLContext* share_context = 0; 791 NewCallback(
113 792 this,
114 if (!render_directly_to_web_view) { 793 &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost));
115 // Pick up the compositor's context to share resources with. 794
116 WebGraphicsContext3D* view_context = webView->graphicsContext3D(); 795 // Set attributes_ from created offscreen context.
117 if (view_context) { 796 {
118 WebGraphicsContext3DInProcessCommandBufferImpl* contextImpl = 797 attributes_ = attributes;
119 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>(view_cont ext); 798 GLint alpha_bits = 0;
120 share_context = contextImpl->gl_context_.get(); 799 getIntegerv(GL_ALPHA_BITS, &alpha_bits);
121 } else { 800 attributes_.alpha = alpha_bits > 0;
122 // The compositor's context didn't get created 801 GLint depth_bits = 0;
123 // successfully, so conceptually there is no way we can 802 getIntegerv(GL_DEPTH_BITS, &depth_bits);
124 // render successfully to the WebView. 803 attributes_.depth = depth_bits > 0;
125 render_directly_to_web_view_ = false; 804 GLint stencil_bits = 0;
126 } 805 getIntegerv(GL_STENCIL_BITS, &stencil_bits);
127 } 806 attributes_.stencil = stencil_bits > 0;
128 807 GLint samples = 0;
129 is_gles2_ = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; 808 getIntegerv(GL_SAMPLES, &samples);
130 809 attributes_.antialias = samples > 0;
131 // This implementation always renders offscreen regardless of 810 }
132 // whether render_directly_to_web_view is true. Both DumpRenderTree 811 makeContextCurrent();
133 // and test_shell paint first to an intermediate offscreen buffer 812
134 // and from there to the window, and WebViewImpl::paint already 813 fprintf(stderr, "Running command buffer\n");
135 // correctly handles the case where the compositor is active but 814
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, &copy_texture_to_parent_texture_fbo_);
219
220 initialized_ = true;
221 return true; 815 return true;
222 } 816 }
223 817
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() { 818 bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() {
286 return gl_context_->MakeCurrent(gl_surface_.get()); 819 return GLInProcessContext::MakeCurrent(context_);
820 }
821
822 void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() {
823 // NOTE: Comment in the line below to check for code that is not calling
824 // eglMakeCurrent where appropriate. The issue is code using
825 // WebGraphicsContext3D does not need to call makeContextCurrent. Code using
826 // direct OpenGL bindings needs to call the appropriate form of
827 // eglMakeCurrent. If it doesn't it will be issuing commands on the wrong
828 // context. Uncommenting the line below clears the current context so that
829 // any code not calling eglMakeCurrent in the appropriate place should crash.
830 // This is not a perfect test but generally code that used the direct OpenGL
831 // bindings should not be mixed with code that uses WebGraphicsContext3D.
832 //
833 // GLInProcessContext::MakeCurrent(NULL);
287 } 834 }
288 835
289 int WebGraphicsContext3DInProcessCommandBufferImpl::width() { 836 int WebGraphicsContext3DInProcessCommandBufferImpl::width() {
290 return cached_width_; 837 return cached_width_;
291 } 838 }
292 839
293 int WebGraphicsContext3DInProcessCommandBufferImpl::height() { 840 int WebGraphicsContext3DInProcessCommandBufferImpl::height() {
294 return cached_height_; 841 return cached_height_;
295 } 842 }
296 843
297 bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { 844 bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() {
298 return is_gles2_; 845 return true;
299 } 846 }
300 847
301 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { 848 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() {
302 return texture_; 849 DCHECK(context_);
850 return context_->GetParentTextureId();
303 } 851 }
304 852
305 void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { 853 void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() {
306 if (!render_directly_to_web_view_) { 854 // Copies the contents of the off-screen render target into the texture
307 // We need to prepare our rendering results for the compositor. 855 // used by the compositor.
308 makeContextCurrent(); 856 context_->SwapBuffers();
309 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); 857 }
310 } 858
311 } 859 void WebGraphicsContext3DInProcessCommandBufferImpl::reshape(
312 860 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; 861 cached_width_ = width;
328 cached_height_ = height; 862 cached_height_ = height;
329 makeContextCurrent(); 863
330 864 // TODO(gmam): See if we can comment this in.
331 GLenum target = GL_TEXTURE_2D; 865 // ClearContext();
332 866
333 if (!texture_) { 867 if (web_view_) {
334 // Generate the texture object 868 #if defined(OS_MACOSX)
335 texture_ = CreateTextureObject(target); 869 context_->ResizeOnscreen(gfx::Size(width, height));
336 // Generate the framebuffer object 870 #else
337 glGenFramebuffersEXT(1, &fbo_); 871 gl_->ResizeCHROMIUM(width, height);
338 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); 872 #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 { 873 } else {
363 // GL_RGB8_OES == GL_RGB8 874 context_->ResizeOffscreen(gfx::Size(width, height));
364 internal_multisampled_color_format = GL_RGB8; 875 // Force a SwapBuffers to get the framebuffer to resize.
365 internal_color_format = is_gles2_ ? GL_RGB : GL_RGB8; 876 context_->SwapBuffers();
366 color_format = GL_RGB; 877 }
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 878
552 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 879 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
553 if (scanline_) { 880 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 881 #endif // FLIP_FRAMEBUFFER_VERTICALLY
559 } 882 }
560 883
884 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createCompositorTexture(
885 WGC3Dsizei width, WGC3Dsizei height) {
886 // TODO(gmam): See if we can comment this in.
887 // ClearContext();
888 return context_->CreateParentTexture(gfx::Size(width, height));
889 }
890
891 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteCompositorTexture(
892 WebGLId parent_texture) {
893 // TODO(gmam): See if we can comment this in.
894 // ClearContext();
895 context_->DeleteParentTexture(parent_texture);
896 }
897
561 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 898 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
562 void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( 899 void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically(
563 unsigned char* framebuffer, unsigned int width, unsigned int height) { 900 uint8* framebuffer,
564 unsigned char* scanline = scanline_; 901 unsigned int width,
902 unsigned int height) {
903 uint8* scanline = scanline_.get();
565 if (!scanline) 904 if (!scanline)
566 return; 905 return;
567 unsigned int row_bytes = width * 4; 906 unsigned int row_bytes = width * 4;
568 unsigned int count = height / 2; 907 unsigned int count = height / 2;
569 for (unsigned int i = 0; i < count; i++) { 908 for (unsigned int i = 0; i < count; i++) {
570 unsigned char* row_a = framebuffer + i * row_bytes; 909 uint8* row_a = framebuffer + i * row_bytes;
571 unsigned char* row_b = framebuffer + (height - i - 1) * row_bytes; 910 uint8* row_b = framebuffer + (height - i - 1) * row_bytes;
572 // FIXME: this is where the multiplication of the alpha 911 // TODO(kbr): this is where the multiplication of the alpha
573 // channel into the color buffer will need to occur if the 912 // channel into the color buffer will need to occur if the
574 // user specifies the "premultiplyAlpha" flag in the context 913 // user specifies the "premultiplyAlpha" flag in the context
575 // creation attributes. 914 // creation attributes.
576 memcpy(scanline, row_b, row_bytes); 915 memcpy(scanline, row_b, row_bytes);
577 memcpy(row_b, row_a, row_bytes); 916 memcpy(row_b, row_a, row_bytes);
578 memcpy(row_a, scanline, row_bytes); 917 memcpy(row_a, scanline, row_bytes);
579 } 918 }
580 } 919 }
581 #endif 920 #endif
582 921
583 bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( 922 bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer(
584 unsigned char* pixels, size_t bufferSize) { 923 unsigned char* pixels,
585 if (bufferSize != static_cast<size_t>(4 * width() * height())) 924 size_t buffer_size) {
925 // TODO(gmam): See if we can comment this in.
926 // ClearContext();
927 if (buffer_size != static_cast<size_t>(4 * width() * height())) {
586 return false; 928 return false;
587 929 }
588 makeContextCurrent();
589 930
590 // Earlier versions of this code used the GPU to flip the 931 // Earlier versions of this code used the GPU to flip the
591 // framebuffer vertically before reading it back for compositing 932 // framebuffer vertically before reading it back for compositing
592 // via software. This code was quite complicated, used a lot of 933 // via software. This code was quite complicated, used a lot of
593 // GPU memory, and didn't provide an obvious speedup. Since this 934 // GPU memory, and didn't provide an obvious speedup. Since this
594 // vertical flip is only a temporary solution anyway until Chrome 935 // vertical flip is only a temporary solution anyway until Chrome
595 // is fully GPU composited, it wasn't worth the complexity. 936 // is fully GPU composited, it wasn't worth the complexity.
596 937
597 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); 938 bool mustRestoreFBO = (bound_fbo_ != 0);
598 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); 939 if (mustRestoreFBO) {
599 940 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0);
600 GLint pack_alignment = 4; 941 }
601 bool must_restore_pack_alignment = false; 942 gl_->ReadPixels(0, 0, cached_width_, cached_height_,
602 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); 943 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
603 if (pack_alignment > 4) { 944
604 glPixelStorei(GL_PACK_ALIGNMENT, 4); 945 // Swizzle red and blue channels
605 must_restore_pack_alignment = true; 946 // TODO(kbr): expose GL_BGRA as extension
606 } 947 for (size_t i = 0; i < buffer_size; i += 4) {
607 948 std::swap(pixels[i], pixels[i + 2]);
608 if (is_gles2_) { 949 }
609 // FIXME: consider testing for presence of GL_OES_read_format 950
610 // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here 951 if (mustRestoreFBO) {
611 // directly. 952 gl_->BindFramebuffer(GL_FRAMEBUFFER, bound_fbo_);
612 glReadPixels(0, 0, cached_width_, cached_height_, 953 }
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 954
627 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 955 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
628 if (pixels) 956 if (pixels) {
629 FlipVertically(pixels, cached_width_, cached_height_); 957 FlipVertically(pixels, cached_width_, cached_height_);
958 }
630 #endif 959 #endif
631 960
632 return true; 961 return true;
633 } 962 }
634 963
635 void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(WGC3Denum error) { 964 void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(
636 if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) { 965 WGC3Denum error) {
637 synthetic_errors_set_.insert(error); 966 if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
638 synthetic_errors_list_.push_back(error); 967 synthetic_errors_.end()) {
968 synthetic_errors_.push_back(error);
639 } 969 }
640 } 970 }
641 971
642 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM( 972 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM(
643 WGC3Denum target, WGC3Dintptr offset, 973 WGC3Denum target,
644 WGC3Dsizeiptr size, WGC3Denum access) { 974 WGC3Dintptr offset,
645 return 0; 975 WGC3Dsizeiptr size,
976 WGC3Denum access) {
977 ClearContext();
978 return gl_->MapBufferSubDataCHROMIUM(target, offset, size, access);
646 } 979 }
647 980
648 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM( 981 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM(
649 const void* mem) { 982 const void* mem) {
983 ClearContext();
984 return gl_->UnmapBufferSubDataCHROMIUM(mem);
650 } 985 }
651 986
652 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM( 987 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM(
653 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, 988 WGC3Denum target,
654 WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, 989 WGC3Dint level,
990 WGC3Dint xoffset,
991 WGC3Dint yoffset,
992 WGC3Dsizei width,
993 WGC3Dsizei height,
994 WGC3Denum format,
995 WGC3Denum type,
655 WGC3Denum access) { 996 WGC3Denum access) {
656 return 0; 997 ClearContext();
998 return gl_->MapTexSubImage2DCHROMIUM(
999 target, level, xoffset, yoffset, width, height, format, type, access);
657 } 1000 }
658 1001
659 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM( 1002 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM(
660 const void* mem) { 1003 const void* mem) {
1004 ClearContext();
1005 gl_->UnmapTexSubImage2DCHROMIUM(mem);
661 } 1006 }
662 1007
663 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToParentTextureC HROMIUM( 1008 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToParentTextureC HROMIUM(
664 WebGLId id, WebGLId id2) { 1009 WebGLId texture, WebGLId parentTexture) {
665 if (!glGetTexLevelParameteriv) 1010 // TODO(gmam): See if we can comment this in.
666 return; 1011 // ClearContext();
667 1012 copyTextureToCompositor(texture, parentTexture);
668 makeContextCurrent();
669 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, copy_texture_to_parent_texture_fbo_);
670 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
671 GL_COLOR_ATTACHMENT0,
672 GL_TEXTURE_2D,
673 id,
674 0); // level
675 glBindTexture(GL_TEXTURE_2D, id2);
676 GLsizei width, height;
677 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
678 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
679 glCopyTexImage2D(GL_TEXTURE_2D,
680 0, // level
681 GL_RGBA,
682 0, 0, // x, y
683 width,
684 height,
685 0); // border
686 glBindTexture(GL_TEXTURE_2D, bound_texture_);
687 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
688 } 1013 }
689 1014
690 void WebGraphicsContext3DInProcessCommandBufferImpl::getParentToChildLatchCHROMI UM( 1015 void WebGraphicsContext3DInProcessCommandBufferImpl::getParentToChildLatchCHROMI UM(
691 WGC3Duint* latch_id) 1016 WGC3Duint* latch_id)
692 { 1017 {
1018 ClearContext();
1019 if (!context_->GetParentToChildLatch(latch_id)) {
1020 LOG(ERROR) << "getLatch must only be called on child context";
1021 synthesizeGLError(GL_INVALID_OPERATION);
1022 *latch_id = ::gpu::kInvalidLatchId;
1023 }
693 } 1024 }
694 1025
695 void WebGraphicsContext3DInProcessCommandBufferImpl::getChildToParentLatchCHROMI UM( 1026 void WebGraphicsContext3DInProcessCommandBufferImpl::getChildToParentLatchCHROMI UM(
696 WGC3Duint* latch_id) 1027 WGC3Duint* latch_id)
697 { 1028 {
1029 ClearContext();
1030 if (!context_->GetChildToParentLatch(latch_id)) {
1031 LOG(ERROR) << "getLatch must only be called on child context";
1032 synthesizeGLError(GL_INVALID_OPERATION);
1033 *latch_id = ::gpu::kInvalidLatchId;
1034 }
698 } 1035 }
699 1036
700 void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM( 1037 void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM(
701 WGC3Duint latch_id) 1038 WGC3Duint latch_id)
702 { 1039 {
1040 // TODO(gmam): See if we can comment this in.
1041 // ClearContext();
1042 gl_->WaitLatchCHROMIUM(latch_id);
703 } 1043 }
704 1044
705 void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM( 1045 void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM(
706 WGC3Duint latch_id) 1046 WGC3Duint latch_id)
707 { 1047 {
708 } 1048 // TODO(gmam): See if we can comment this in.
709 1049 // ClearContext();
710 WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1050 gl_->SetLatchCHROMIUM(latch_id);
1051 // required to ensure set command is sent to GPU process
1052 gl_->Flush();
1053 }
1054
1055 void WebGraphicsContext3DInProcessCommandBufferImpl::
1056 rateLimitOffscreenContextCHROMIUM() {
1057 // TODO(gmam): See if we can comment this in.
1058 // ClearContext();
1059 gl_->RateLimitOffscreenContextCHROMIUM();
1060 }
1061
1062 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::
711 getRequestableExtensionsCHROMIUM() { 1063 getRequestableExtensionsCHROMIUM() {
712 return WebString(); 1064 // TODO(gmam): See if we can comment this in.
713 } 1065 // ClearContext();
714 1066 return WebKit::WebString::fromUTF8(
715 void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM(co nst char*) { 1067 gl_->GetRequestableExtensionsCHROMIUM());
1068 }
1069
1070 void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM(
1071 const char* extension) {
1072 // TODO(gmam): See if we can comment this in.
1073 // ClearContext();
1074 gl_->RequestExtensionCHROMIUM(extension);
716 } 1075 }
717 1076
718 void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM( 1077 void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM(
719 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, 1078 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
720 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, 1079 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
721 WGC3Dbitfield mask, WGC3Denum filter) { 1080 WGC3Dbitfield mask, WGC3Denum filter) {
722 } 1081 ClearContext();
723 1082 gl_->BlitFramebufferEXT(
724 void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorageMultisam pleCHROMIUM( 1083 srcX0, srcY0, srcX1, srcY1,
725 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, 1084 dstX0, dstY0, dstX1, dstY1,
726 WGC3Dsizei width, WGC3Dsizei height) { 1085 mask, filter);
1086 }
1087
1088 void WebGraphicsContext3DInProcessCommandBufferImpl::
1089 renderbufferStorageMultisampleCHROMIUM(
1090 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat,
1091 WGC3Dsizei width, WGC3Dsizei height) {
1092 ClearContext();
1093 gl_->RenderbufferStorageMultisampleEXT(
1094 target, samples, internalformat, width, height);
727 } 1095 }
728 1096
729 // Helper macros to reduce the amount of code. 1097 // Helper macros to reduce the amount of code.
730 1098
731 #define DELEGATE_TO_GL(name, glname) \ 1099 #define DELEGATE_TO_GL(name, glname) \
732 void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \ 1100 void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \
733 makeContextCurrent(); \ 1101 ClearContext(); \
734 gl##glname(); \ 1102 gl_->glname(); \
735 } 1103 }
736 1104
737 #define DELEGATE_TO_GL_1(name, glname, t1) \ 1105 #define DELEGATE_TO_GL_1(name, glname, t1) \
738 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1106 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \
739 makeContextCurrent(); \ 1107 ClearContext(); \
740 gl##glname(a1); \ 1108 gl_->glname(a1); \
741 } 1109 }
742 1110
743 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ 1111 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \
744 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1112 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \
745 makeContextCurrent(); \ 1113 ClearContext(); \
746 return gl##glname(a1); \ 1114 return gl_->glname(a1); \
747 } 1115 }
748 1116
749 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ 1117 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \
750 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1118 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \
751 makeContextCurrent(); \ 1119 ClearContext(); \
752 return gl##glname(a1) ? true : false; \ 1120 return gl_->glname(a1) ? true : false; \
753 } 1121 }
754 1122
755 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ 1123 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \
756 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ 1124 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
757 makeContextCurrent(); \ 1125 t1 a1, t2 a2) { \
758 gl##glname(a1, a2); \ 1126 ClearContext(); \
759 } 1127 gl_->glname(a1, a2); \
760 1128 }
761 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ 1129
762 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ 1130 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \
763 makeContextCurrent(); \ 1131 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \
764 return gl##glname(a1, a2); \ 1132 ClearContext(); \
765 } 1133 return gl_->glname(a1, a2); \
766 1134 }
767 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ 1135
768 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \ 1136 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \
769 makeContextCurrent(); \ 1137 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
770 gl##glname(a1, a2, a3); \ 1138 t1 a1, t2 a2, t3 a3) { \
771 } 1139 ClearContext(); \
772 1140 gl_->glname(a1, a2, a3); \
773 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ 1141 }
774 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4) { \ 1142
775 makeContextCurrent(); \ 1143 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \
776 gl##glname(a1, a2, a3, a4); \ 1144 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
777 } 1145 t1 a1, t2 a2, t3 a3, t4 a4) { \
778 1146 ClearContext(); \
779 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ 1147 gl_->glname(a1, a2, a3, a4); \
780 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1148 }
781 t5 a5) { \ 1149
782 makeContextCurrent(); \ 1150 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \
783 gl##glname(a1, a2, a3, a4, a5); \ 1151 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
784 } 1152 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \
785 1153 ClearContext(); \
786 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ 1154 gl_->glname(a1, a2, a3, a4, a5); \
787 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1155 }
788 t5 a5, t6 a6) { \ 1156
789 makeContextCurrent(); \ 1157 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \
790 gl##glname(a1, a2, a3, a4, a5, a6); \ 1158 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
791 } 1159 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \
792 1160 ClearContext(); \
793 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ 1161 gl_->glname(a1, a2, a3, a4, a5, a6); \
794 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1162 }
795 t5 a5, t6 a6, t7 a7) { \ 1163
796 makeContextCurrent(); \ 1164 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \
797 gl##glname(a1, a2, a3, a4, a5, a6, a7); \ 1165 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
798 } 1166 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) { \
799 1167 ClearContext(); \
800 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ 1168 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \
801 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1169 }
802 t5 a5, t6 a6, t7 a7, t8 a8) { \ 1170
803 makeContextCurrent(); \ 1171 #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); \ 1172 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
805 } 1173 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) { \
806 1174 ClearContext(); \
807 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ 1175 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \
808 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1176 }
809 t5 a5, t6 a6, t7 a7, t8 a8, \ 1177
810 t9 a9) { \ 1178 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
811 makeContextCurrent(); \ 1179 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
812 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ 1180 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) { \
813 } 1181 ClearContext(); \
814 1182 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \
815 void WebGraphicsContext3DInProcessCommandBufferImpl::activeTexture(WGC3Denum tex ture) { 1183 }
816 // FIXME: query number of textures available. 1184
817 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) 1185 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum)
818 // FIXME: raise exception.
819 return;
820
821 makeContextCurrent();
822 glActiveTexture(texture);
823 }
824 1186
825 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) 1187 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
826 1188
827 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, 1189 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId,
828 WebGLId, WGC3Duint, const WGC3Dchar*) 1190 WGC3Duint, const WGC3Dchar*)
829 1191
830 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId); 1192 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId)
831 1193
832 void WebGraphicsContext3DInProcessCommandBufferImpl::bindFramebuffer( 1194 void WebGraphicsContext3DInProcessCommandBufferImpl::bindFramebuffer(
833 WGC3Denum target, WebGLId framebuffer) { 1195 WGC3Denum target,
834 makeContextCurrent(); 1196 WebGLId framebuffer) {
835 if (!framebuffer) 1197 ClearContext();
836 framebuffer = (attributes_.antialias ? multisample_fbo_ : fbo_); 1198 gl_->BindFramebuffer(target, framebuffer);
837 if (framebuffer != bound_fbo_) { 1199 bound_fbo_ = framebuffer;
838 glBindFramebufferEXT(target, framebuffer); 1200 }
839 bound_fbo_ = framebuffer; 1201
840 } 1202 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbuffer, WGC3Denum, WebGLId)
841 } 1203
842 1204 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 1205
852 DELEGATE_TO_GL_4(blendColor, BlendColor, 1206 DELEGATE_TO_GL_4(blendColor, BlendColor,
853 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1207 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
854 1208
855 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum) 1209 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
856 1210
857 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, 1211 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
858 WGC3Denum, WGC3Denum) 1212 WGC3Denum, WGC3Denum)
859 1213
860 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum) 1214 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
861 1215
862 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, 1216 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
863 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) 1217 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
864 1218
865 DELEGATE_TO_GL_4(bufferData, BufferData, 1219 DELEGATE_TO_GL_4(bufferData, BufferData,
866 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum) 1220 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
867 1221
868 DELEGATE_TO_GL_4(bufferSubData, BufferSubData, 1222 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
869 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*) 1223 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
870 1224
871 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT, 1225 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatus,
872 WGC3Denum, WGC3Denum) 1226 WGC3Denum, WGC3Denum)
873 1227
874 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield) 1228 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
875 1229
876 DELEGATE_TO_GL_4(clearColor, ClearColor, 1230 DELEGATE_TO_GL_4(clearColor, ClearColor,
877 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf) 1231 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
878 1232
879 DELEGATE_TO_GL_1(clearDepth, ClearDepth, WGC3Dclampf) 1233 DELEGATE_TO_GL_1(clearDepth, ClearDepthf, WGC3Dclampf)
880 1234
881 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint) 1235 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
882 1236
883 DELEGATE_TO_GL_4(colorMask, ColorMask, 1237 DELEGATE_TO_GL_4(colorMask, ColorMask,
884 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean) 1238 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
885 1239
886 void WebGraphicsContext3DInProcessCommandBufferImpl::compileShader(WebGLId shade r) { 1240 DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId)
887 makeContextCurrent();
888 1241
889 ShaderSourceMap::iterator result = shader_source_map_.find(shader); 1242 DELEGATE_TO_GL_8(copyTexImage2D, CopyTexImage2D,
890 if (result == shader_source_map_.end()) { 1243 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
891 // Passing down to gl driver to generate the correct error; or the case 1244 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 1245
899 if (!AngleValidateShaderSource(entry)) { 1246 DELEGATE_TO_GL_8(copyTexSubImage2D, CopyTexSubImage2D,
900 // Shader didn't validate; don't move forward with compiling 1247 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
901 // translated source. 1248 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 1249
953 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum) 1250 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
954 1251
955 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum) 1252 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
956 1253
957 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean) 1254 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
958 1255
959 DELEGATE_TO_GL_2(depthRange, DepthRange, WGC3Dclampf, WGC3Dclampf) 1256 DELEGATE_TO_GL_2(depthRange, DepthRangef, WGC3Dclampf, WGC3Dclampf)
960 1257
961 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) 1258 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
962 1259
963 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum) 1260 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
964 1261
965 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, WGC3Duint) 1262 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray,
1263 WGC3Duint)
966 1264
967 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei) 1265 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
968 1266
969 void WebGraphicsContext3DInProcessCommandBufferImpl::drawElements( 1267 void WebGraphicsContext3DInProcessCommandBufferImpl::drawElements(
970 WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset) { 1268 WGC3Denum mode,
971 makeContextCurrent(); 1269 WGC3Dsizei count,
972 glDrawElements(mode, count, type, 1270 WGC3Denum type,
973 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 1271 WGC3Dintptr offset) {
1272 ClearContext();
1273 gl_->DrawElements(
1274 mode, count, type,
1275 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
974 } 1276 }
975 1277
976 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum) 1278 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
977 1279
978 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, WGC3Duint) 1280 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray,
1281 WGC3Duint)
979 1282
980 DELEGATE_TO_GL(finish, Finish) 1283 DELEGATE_TO_GL(finish, Finish)
981 1284
982 DELEGATE_TO_GL(flush, Flush) 1285 DELEGATE_TO_GL(flush, Flush)
983 1286
984 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbufferEXT, 1287 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbuffer,
985 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId) 1288 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
986 1289
987 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, 1290 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2D,
988 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint) 1291 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
989 1292
990 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum) 1293 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
991 1294
992 void WebGraphicsContext3DInProcessCommandBufferImpl::generateMipmap(WGC3Denum ta rget) { 1295 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 1296
1001 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib( 1297 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveAttrib(
1002 WebGLId program, WGC3Duint index, ActiveInfo& info) { 1298 WebGLId program, WGC3Duint index, ActiveInfo& info) {
1003 makeContextCurrent(); 1299 ClearContext();
1004 if (!program) { 1300 if (!program) {
1005 synthesizeGLError(GL_INVALID_VALUE); 1301 synthesizeGLError(GL_INVALID_VALUE);
1006 return false; 1302 return false;
1007 } 1303 }
1008 GLint max_name_length = -1; 1304 GLint max_name_length = -1;
1009 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length); 1305 gl_->GetProgramiv(
1306 program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
1010 if (max_name_length < 0) 1307 if (max_name_length < 0)
1011 return false; 1308 return false;
1012 scoped_array<GLchar> name(new GLchar[max_name_length]); 1309 scoped_array<GLchar> name(new GLchar[max_name_length]);
1310 if (!name.get()) {
1311 synthesizeGLError(GL_OUT_OF_MEMORY);
1312 return false;
1313 }
1013 GLsizei length = 0; 1314 GLsizei length = 0;
1014 GLint size = -1; 1315 GLint size = -1;
1015 GLenum type = 0; 1316 GLenum type = 0;
1016 glGetActiveAttrib(program, index, max_name_length, 1317 gl_->GetActiveAttrib(
1017 &length, &size, &type, name.get()); 1318 program, index, max_name_length, &length, &size, &type, name.get());
1018 if (size < 0) { 1319 if (size < 0) {
1019 return false; 1320 return false;
1020 } 1321 }
1021 info.name = WebString::fromUTF8(name.get(), length); 1322 info.name = WebKit::WebString::fromUTF8(name.get(), length);
1022 info.type = type; 1323 info.type = type;
1023 info.size = size; 1324 info.size = size;
1024 return true; 1325 return true;
1025 } 1326 }
1026 1327
1027 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveUniform( 1328 bool WebGraphicsContext3DInProcessCommandBufferImpl::getActiveUniform(
1028 WebGLId program, WGC3Duint index, ActiveInfo& info) { 1329 WebGLId program, WGC3Duint index, ActiveInfo& info) {
1029 makeContextCurrent(); 1330 ClearContext();
1030 GLint max_name_length = -1; 1331 GLint max_name_length = -1;
1031 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); 1332 gl_->GetProgramiv(
1333 program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
1032 if (max_name_length < 0) 1334 if (max_name_length < 0)
1033 return false; 1335 return false;
1034 scoped_array<GLchar> name(new GLchar[max_name_length]); 1336 scoped_array<GLchar> name(new GLchar[max_name_length]);
1337 if (!name.get()) {
1338 synthesizeGLError(GL_OUT_OF_MEMORY);
1339 return false;
1340 }
1035 GLsizei length = 0; 1341 GLsizei length = 0;
1036 GLint size = -1; 1342 GLint size = -1;
1037 GLenum type = 0; 1343 GLenum type = 0;
1038 glGetActiveUniform(program, index, max_name_length, 1344 gl_->GetActiveUniform(
1039 &length, &size, &type, name.get()); 1345 program, index, max_name_length, &length, &size, &type, name.get());
1040 if (size < 0) { 1346 if (size < 0) {
1041 return false; 1347 return false;
1042 } 1348 }
1043 info.name = WebString::fromUTF8(name.get(), length); 1349 info.name = WebKit::WebString::fromUTF8(name.get(), length);
1044 info.type = type; 1350 info.type = type;
1045 info.size = size; 1351 info.size = size;
1046 return true; 1352 return true;
1047 } 1353 }
1048 1354
1049 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders, 1355 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
1050 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*) 1356 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
1051 1357
1052 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, 1358 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
1053 WebGLId, const WGC3Dchar*, WGC3Dint) 1359 WebGLId, const WGC3Dchar*, WGC3Dint)
1054 1360
1055 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, 1361 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, WGC3Denum, WGC3Dboolean*)
1056 WGC3Denum, WGC3Dboolean*)
1057 1362
1058 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, 1363 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
1059 WGC3Denum, WGC3Denum, WGC3Dint*) 1364 WGC3Denum, WGC3Denum, WGC3Dint*)
1060 1365
1061 WebGraphicsContext3D::Attributes WebGraphicsContext3DInProcessCommandBufferImpl: : 1366 WebKit::WebGraphicsContext3D::Attributes
1062 getContextAttributes() { 1367 WebGraphicsContext3DInProcessCommandBufferImpl::getContextAttributes() {
1063 return attributes_; 1368 return attributes_;
1064 } 1369 }
1065 1370
1066 WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl::getError() { 1371 WGC3Denum WebGraphicsContext3DInProcessCommandBufferImpl::getError() {
1067 DCHECK(synthetic_errors_list_.size() == synthetic_errors_set_.size()); 1372 ClearContext();
1068 if (!synthetic_errors_set_.empty()) { 1373 if (!synthetic_errors_.empty()) {
1069 WGC3Denum error = synthetic_errors_list_.front(); 1374 std::vector<WGC3Denum>::iterator iter = synthetic_errors_.begin();
1070 synthetic_errors_list_.pop_front(); 1375 WGC3Denum err = *iter;
1071 synthetic_errors_set_.erase(error); 1376 synthetic_errors_.erase(iter);
1072 return error; 1377 return err;
1073 } 1378 }
1074 1379
1075 makeContextCurrent(); 1380 return gl_->GetError();
1076 return glGetError();
1077 } 1381 }
1078 1382
1079 bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() { 1383 bool WebGraphicsContext3DInProcessCommandBufferImpl::isContextLost() {
1080 return false; 1384 return context_->IsCommandBufferContextLost();
1081 } 1385 }
1082 1386
1083 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*) 1387 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
1084 1388
1085 void WebGraphicsContext3DInProcessCommandBufferImpl::getFramebufferAttachmentPar ameteriv( 1389 DELEGATE_TO_GL_4(getFramebufferAttachmentParameteriv,
1086 WGC3Denum target, WGC3Denum attachment, 1390 GetFramebufferAttachmentParameteriv,
1087 WGC3Denum pname, WGC3Dint* value) { 1391 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 1392
1095 void WebGraphicsContext3DInProcessCommandBufferImpl::getIntegerv( 1393 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 1394
1125 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*) 1395 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
1126 1396
1127 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getProgramInfoLog( 1397 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getProgramInfo Log(
1128 WebGLId program) { 1398 WebGLId program) {
1129 makeContextCurrent(); 1399 ClearContext();
1130 GLint log_length; 1400 GLint logLength = 0;
1131 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length); 1401 gl_->GetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
1132 if (!log_length) 1402 if (!logLength)
1133 return WebString(); 1403 return WebKit::WebString();
1134 scoped_array<GLchar> log(new GLchar[log_length]); 1404 scoped_array<GLchar> log(new GLchar[logLength]);
1135 GLsizei returned_log_length; 1405 if (!log.get())
1136 glGetProgramInfoLog(program, log_length, &returned_log_length, log.get()); 1406 return WebKit::WebString();
1137 DCHECK(log_length == returned_log_length + 1); 1407 GLsizei returnedLogLength = 0;
1138 WebString res = WebString::fromUTF8(log.get(), returned_log_length); 1408 gl_->GetProgramInfoLog(
1409 program, logLength, &returnedLogLength, log.get());
1410 DCHECK_EQ(logLength, returnedLogLength + 1);
1411 WebKit::WebString res =
1412 WebKit::WebString::fromUTF8(log.get(), returnedLogLength);
1139 return res; 1413 return res;
1140 } 1414 }
1141 1415
1142 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT, 1416 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameteriv,
1143 WGC3Denum, WGC3Denum, WGC3Dint*) 1417 WGC3Denum, WGC3Denum, WGC3Dint*)
1144 1418
1145 void WebGraphicsContext3DInProcessCommandBufferImpl::getShaderiv( 1419 DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, WGC3Denum, WGC3Dint*)
1146 WebGLId shader, WGC3Denum pname, WGC3Dint* value) {
1147 makeContextCurrent();
1148 1420
1149 ShaderSourceMap::iterator result = shader_source_map_.find(shader); 1421 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderInfoL og(
1150 if (result != shader_source_map_.end()) { 1422 WebGLId shader) {
1151 ShaderSourceEntry* entry = result->second; 1423 ClearContext();
1152 DCHECK(entry); 1424 GLint logLength = 0;
1153 switch (pname) { 1425 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
1154 case GL_COMPILE_STATUS: 1426 if (!logLength)
1155 if (!entry->is_valid) { 1427 return WebKit::WebString();
1156 *value = 0; 1428 scoped_array<GLchar> log(new GLchar[logLength]);
1157 return; 1429 if (!log.get())
1158 } 1430 return WebKit::WebString();
1159 break; 1431 GLsizei returnedLogLength = 0;
1160 case GL_INFO_LOG_LENGTH: 1432 gl_->GetShaderInfoLog(
1161 if (!entry->is_valid) { 1433 shader, logLength, &returnedLogLength, log.get());
1162 *value = entry->log.get() ? strlen(entry->log.get()) : 0; 1434 DCHECK_EQ(logLength, returnedLogLength + 1);
1163 if (*value) 1435 WebKit::WebString res =
1164 (*value)++; 1436 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; 1437 return res;
1205 } 1438 }
1206 1439
1207 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderSource(WebGLI d shader) { 1440 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getShaderSourc e(
1208 makeContextCurrent(); 1441 WebGLId shader) {
1209 1442 ClearContext();
1210 ShaderSourceMap::iterator result = shader_source_map_.find(shader); 1443 GLint logLength = 0;
1211 if (result != shader_source_map_.end()) { 1444 gl_->GetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
1212 ShaderSourceEntry* entry = result->second; 1445 if (!logLength)
1213 DCHECK(entry); 1446 return WebKit::WebString();
1214 if (!entry->source.get()) 1447 scoped_array<GLchar> log(new GLchar[logLength]);
1215 return WebString(); 1448 if (!log.get())
1216 WebString res = WebString::fromUTF8( 1449 return WebKit::WebString();
1217 entry->source.get(), strlen(entry->source.get())); 1450 GLsizei returnedLogLength = 0;
1218 return res; 1451 gl_->GetShaderSource(
1219 } 1452 shader, logLength, &returnedLogLength, log.get());
1220 1453 DCHECK_EQ(logLength, returnedLogLength + 1);
1221 GLint log_length = 0; 1454 WebKit::WebString res =
1222 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &log_length); 1455 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; 1456 return res;
1231 } 1457 }
1232 1458
1233 WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString(WGC3Denum na me) { 1459 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::getString(
1234 makeContextCurrent(); 1460 WGC3Denum name) {
1235 std::string result(reinterpret_cast<const char*>(glGetString(name))); 1461 ClearContext();
1236 if (name == GL_EXTENSIONS) { 1462 return WebKit::WebString::fromUTF8(
1237 // GL_CHROMIUM_copy_texture_to_parent_texture requires the 1463 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 } 1464 }
1245 1465
1246 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, 1466 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
1247 WGC3Denum, WGC3Denum, WGC3Dfloat*) 1467 WGC3Denum, WGC3Denum, WGC3Dfloat*)
1248 1468
1249 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, 1469 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
1250 WGC3Denum, WGC3Denum, WGC3Dint*) 1470 WGC3Denum, WGC3Denum, WGC3Dint*)
1251 1471
1252 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*) 1472 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
1253 1473
1254 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*) 1474 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
1255 1475
1256 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, 1476 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
1257 WebGLId, const WGC3Dchar*, WGC3Dint) 1477 WebGLId, const WGC3Dchar*, WGC3Dint)
1258 1478
1259 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, 1479 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
1260 WGC3Duint, WGC3Denum, WGC3Dfloat*) 1480 WGC3Duint, WGC3Denum, WGC3Dfloat*)
1261 1481
1262 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, 1482 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
1263 WGC3Duint, WGC3Denum, WGC3Dint*) 1483 WGC3Duint, WGC3Denum, WGC3Dint*)
1264 1484
1265 WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl::getVertexAttribOff set( 1485 WGC3Dsizeiptr WebGraphicsContext3DInProcessCommandBufferImpl::getVertexAttribOff set(
1266 WGC3Duint index, WGC3Denum pname) { 1486 WGC3Duint index, WGC3Denum pname) {
1267 makeContextCurrent(); 1487 ClearContext();
1268 void* pointer; 1488 GLvoid* value = NULL;
1269 glGetVertexAttribPointerv(index, pname, &pointer); 1489 // NOTE: If pname is ever a value that returns more then 1 element
1270 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer)); 1490 // this will corrupt memory.
1491 gl_->GetVertexAttribPointerv(index, pname, &value);
1492 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(value));
1271 } 1493 }
1272 1494
1273 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum) 1495 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
1274 1496
1275 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean) 1497 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
1276 1498
1277 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean) 1499 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
1278 1500
1279 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebufferEXT, WebGLId, WGC3Dboolean) 1501 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebuffer, WebGLId, WGC3Dboolean)
1280 1502
1281 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean) 1503 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
1282 1504
1283 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbufferEXT, WebGLId, WGC3Dboolean) 1505 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbuffer, WebGLId, WGC3Dboolean)
1284 1506
1285 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean) 1507 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
1286 1508
1287 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean) 1509 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
1288 1510
1289 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat) 1511 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
1290 1512
1291 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) 1513 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
1292 1514
1293 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint) 1515 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
1294 1516
1295 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat) 1517 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
1296 1518
1297 void WebGraphicsContext3DInProcessCommandBufferImpl::readPixels( 1519 DELEGATE_TO_GL_7(readPixels, ReadPixels,
1298 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, 1520 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Denum,
1299 WGC3Denum format, WGC3Denum type, void* pixels) { 1521 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 1522
1312 glReadPixels(x, y, width, height, format, type, pixels); 1523 void WebGraphicsContext3DInProcessCommandBufferImpl::releaseShaderCompiler() {
1313 1524 ClearContext();
1314 if (needs_resolve)
1315 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
1316 } 1525 }
1317 1526
1318 void WebGraphicsContext3DInProcessCommandBufferImpl::releaseShaderCompiler() { 1527 DELEGATE_TO_GL_4(renderbufferStorage, RenderbufferStorage,
1319 } 1528 WGC3Denum, WGC3Denum, WGC3Dsizei, WGC3Dsizei)
1320 1529
1321 void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorage( 1530 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 1531
1349 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) 1532 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1350 1533
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( 1534 void WebGraphicsContext3DInProcessCommandBufferImpl::shaderSource(
1365 WebGLId shader, const WGC3Dchar* source) { 1535 WebGLId shader, const WGC3Dchar* string) {
1366 makeContextCurrent(); 1536 ClearContext();
1367 GLint length = source ? strlen(source) : 0; 1537 GLint length = strlen(string);
1368 ShaderSourceMap::iterator result = shader_source_map_.find(shader); 1538 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 } 1539 }
1378 1540
1379 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint) 1541 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
1380 1542
1381 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, 1543 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
1382 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint) 1544 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
1383 1545
1384 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint) 1546 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
1385 1547
1386 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, 1548 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
1387 WGC3Denum, WGC3Duint) 1549 WGC3Denum, WGC3Duint)
1388 1550
1389 DELEGATE_TO_GL_3(stencilOp, StencilOp, 1551 DELEGATE_TO_GL_3(stencilOp, StencilOp,
1390 WGC3Denum, WGC3Denum, WGC3Denum) 1552 WGC3Denum, WGC3Denum, WGC3Denum)
1391 1553
1392 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, 1554 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
1393 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum) 1555 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
1394 1556
1395 DELEGATE_TO_GL_3(texParameterf, TexParameterf, WGC3Denum, WGC3Denum, WGC3Dfloat) 1557 DELEGATE_TO_GL_9(texImage2D, TexImage2D,
1558 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dsizei, WGC3Dsizei,
1559 WGC3Dint, WGC3Denum, WGC3Denum, const void*)
1396 1560
1397 DELEGATE_TO_GL_3(texParameteri, TexParameteri, WGC3Denum, WGC3Denum, WGC3Dint) 1561 DELEGATE_TO_GL_3(texParameterf, TexParameterf,
1562 WGC3Denum, WGC3Denum, WGC3Dfloat);
1563
1564 static const unsigned int kTextureWrapR = 0x8072;
1565
1566 void WebGraphicsContext3DInProcessCommandBufferImpl::texParameteri(
1567 WGC3Denum target, WGC3Denum pname, WGC3Dint param) {
1568 ClearContext();
1569 // TODO(kbr): figure out whether the setting of TEXTURE_WRAP_R in
1570 // GraphicsContext3D.cpp is strictly necessary to avoid seams at the
1571 // edge of cube maps, and, if it is, push it into the GLES2 service
1572 // side code.
1573 if (pname == kTextureWrapR) {
1574 return;
1575 }
1576 gl_->TexParameteri(target, pname, param);
1577 }
1398 1578
1399 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, 1579 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
1400 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei, 1580 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
1401 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*) 1581 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
1402 1582
1403 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat) 1583 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
1404 1584
1405 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, 1585 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, WGC3Dint, WGC3Dsizei,
1406 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) 1586 const WGC3Dfloat*)
1407 1587
1408 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint) 1588 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
1409 1589
1410 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1590 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1411 1591
1412 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat) 1592 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
1413 1593
1414 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, 1594 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, WGC3Dint, WGC3Dsizei,
1415 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) 1595 const WGC3Dfloat*)
1416 1596
1417 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint) 1597 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
1418 1598
1419 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1599 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1420 1600
1421 DELEGATE_TO_GL_4(uniform3f, Uniform3f, 1601 DELEGATE_TO_GL_4(uniform3f, Uniform3f, WGC3Dint,
1422 WGC3Dint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1602 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1423 1603
1424 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, 1604 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, WGC3Dint, WGC3Dsizei,
1425 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) 1605 const WGC3Dfloat*)
1426 1606
1427 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) 1607 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1428 1608
1429 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1609 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1430 1610
1431 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint, 1611 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
1432 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1612 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1433 1613
1434 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, 1614 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, WGC3Dint, WGC3Dsizei,
1435 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*) 1615 const WGC3Dfloat*)
1436 1616
1437 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint, 1617 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
1438 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint) 1618 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1439 1619
1440 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*) 1620 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1441 1621
1442 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, 1622 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
1443 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1623 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1444 1624
1445 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, 1625 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
1446 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1626 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1447 1627
1448 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, 1628 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
1449 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*) 1629 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1450 1630
1451 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) 1631 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
1452 1632
1453 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) 1633 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
1454 1634
1455 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat) 1635 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
1456 1636
1457 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, const WGC3Dfloat*) 1637 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint,
1638 const WGC3Dfloat*)
1458 1639
1459 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, 1640 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, WGC3Duint,
1460 WGC3Duint, WGC3Dfloat, WGC3Dfloat) 1641 WGC3Dfloat, WGC3Dfloat)
1461 1642
1462 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, const WGC3Dfloat*) 1643 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint,
1644 const WGC3Dfloat*)
1463 1645
1464 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, 1646 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, WGC3Duint,
1465 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1647 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1466 1648
1467 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, const WGC3Dfloat*) 1649 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint,
1650 const WGC3Dfloat*)
1468 1651
1469 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, 1652 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, WGC3Duint,
1470 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat) 1653 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1471 1654
1472 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, const WGC3Dfloat*) 1655 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint,
1656 const WGC3Dfloat*)
1473 1657
1474 void WebGraphicsContext3DInProcessCommandBufferImpl::vertexAttribPointer( 1658 void WebGraphicsContext3DInProcessCommandBufferImpl::vertexAttribPointer(
1475 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized, 1659 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
1476 WGC3Dsizei stride, WGC3Dintptr offset) { 1660 WGC3Dsizei stride, WGC3Dintptr offset) {
1477 makeContextCurrent(); 1661 ClearContext();
1478 glVertexAttribPointer(index, size, type, normalized, stride, 1662 gl_->VertexAttribPointer(
1479 reinterpret_cast<void*>(static_cast<intptr_t>(offset))); 1663 index, size, type, normalized, stride,
1664 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1480 } 1665 }
1481 1666
1482 DELEGATE_TO_GL_4(viewport, Viewport, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei) 1667 DELEGATE_TO_GL_4(viewport, Viewport,
1668 WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1483 1669
1484 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createBuffer() { 1670 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createBuffer() {
1485 makeContextCurrent(); 1671 ClearContext();
1486 GLuint o; 1672 GLuint o;
1487 glGenBuffersARB(1, &o); 1673 gl_->GenBuffers(1, &o);
1488 return o; 1674 return o;
1489 } 1675 }
1490 1676
1491 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createFramebuffer() { 1677 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createFramebuffer() {
1492 makeContextCurrent(); 1678 ClearContext();
1493 GLuint o = 0; 1679 GLuint o = 0;
1494 glGenFramebuffersEXT(1, &o); 1680 gl_->GenFramebuffers(1, &o);
1495 return o; 1681 return o;
1496 } 1682 }
1497 1683
1498 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createProgram() { 1684 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createProgram() {
1499 makeContextCurrent(); 1685 ClearContext();
1500 return glCreateProgram(); 1686 return gl_->CreateProgram();
1501 } 1687 }
1502 1688
1503 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createRenderbuffer() { 1689 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createRenderbuffer() {
1504 makeContextCurrent(); 1690 ClearContext();
1505 GLuint o; 1691 GLuint o;
1506 glGenRenderbuffersEXT(1, &o); 1692 gl_->GenRenderbuffers(1, &o);
1507 return o; 1693 return o;
1508 } 1694 }
1509 1695
1510 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createShader( 1696 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 1697
1528 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createTexture() { 1698 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createTexture() {
1529 makeContextCurrent(); 1699 ClearContext();
1530 GLuint o; 1700 GLuint o;
1531 glGenTextures(1, &o); 1701 gl_->GenTextures(1, &o);
1532 return o; 1702 return o;
1533 } 1703 }
1534 1704
1535 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer(WebGLId buffer ) { 1705 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteBuffer(
1536 makeContextCurrent(); 1706 WebGLId buffer) {
1537 glDeleteBuffersARB(1, &buffer); 1707 ClearContext();
1708 gl_->DeleteBuffers(1, &buffer);
1538 } 1709 }
1539 1710
1540 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteFramebuffer( 1711 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteFramebuffer(
1541 WebGLId framebuffer) { 1712 WebGLId framebuffer) {
1542 makeContextCurrent(); 1713 ClearContext();
1543 glDeleteFramebuffersEXT(1, &framebuffer); 1714 gl_->DeleteFramebuffers(1, &framebuffer);
1544 } 1715 }
1545 1716
1546 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram(WebGLId progr am) { 1717 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteProgram(
1547 makeContextCurrent(); 1718 WebGLId program) {
1548 glDeleteProgram(program); 1719 ClearContext();
1720 gl_->DeleteProgram(program);
1549 } 1721 }
1550 1722
1551 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteRenderbuffer( 1723 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteRenderbuffer(
1552 WebGLId renderbuffer) { 1724 WebGLId renderbuffer) {
1553 makeContextCurrent(); 1725 ClearContext();
1554 glDeleteRenderbuffersEXT(1, &renderbuffer); 1726 gl_->DeleteRenderbuffers(1, &renderbuffer);
1555 } 1727 }
1556 1728
1557 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader(WebGLId shader ) { 1729 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteShader(
1558 makeContextCurrent(); 1730 WebGLId shader) {
1559 1731 ClearContext();
1560 ShaderSourceMap::iterator result = shader_source_map_.find(shader); 1732 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 } 1733 }
1567 1734
1568 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture(WebGLId textu re) { 1735 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteTexture(
1569 makeContextCurrent(); 1736 WebGLId texture) {
1570 glDeleteTextures(1, &texture); 1737 ClearContext();
1738 gl_->DeleteTextures(1, &texture);
1571 } 1739 }
1572 1740
1573 bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleCreateCompilers() { 1741 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToCompositor(
1574 if (!ShInitialize()) 1742 WebGLId texture, WebGLId parentTexture) {
1575 return false; 1743 // TODO(gmam): See if we can comment this in.
1576 1744 // ClearContext();
1577 ShBuiltInResources resources; 1745 gl_->CopyTextureToParentTextureCHROMIUM(texture, parentTexture);
1578 ShInitBuiltInResources(&resources); 1746 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 } 1747 }
1598 1748
1599 void WebGraphicsContext3DInProcessCommandBufferImpl::AngleDestroyCompilers() { 1749 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 } 1750 }
1609 1751
1610 bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleValidateShaderSource( 1752 void WebGraphicsContext3DInProcessCommandBufferImpl::setContextLostCallback(
1611 ShaderSourceEntry* entry) { 1753 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb)
1612 entry->is_valid = false; 1754 {
1613 entry->translated_source.reset(); 1755 context_lost_callback_ = cb;
1614 entry->log.reset(); 1756 }
1615 1757
1616 ShHandle compiler = 0; 1758 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() {
1617 switch (entry->type) { 1759 if (context_lost_callback_) {
1618 case GL_FRAGMENT_SHADER: 1760 context_lost_callback_->onContextLost();
1619 compiler = fragment_compiler_;
1620 break;
1621 case GL_VERTEX_SHADER:
1622 compiler = vertex_compiler_;
1623 break;
1624 } 1761 }
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 } 1762 }
1659 1763
1660 } // namespace gpu 1764 } // namespace gpu
1661 } // namespace webkit 1765 } // namespace webkit
1662 1766
1767 #endif // defined(ENABLE_GPU)
1768
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698