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

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

Powered by Google App Engine
This is Rietveld 408576698