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

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: update deps 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"
21 #include "base/memory/singleton.h"
22 #include "base/metrics/histogram.h"
23 #include "content/common/content_switches.h"
24 #include "gpu/command_buffer/client/gles2_lib.h"
25 #include "gpu/command_buffer/client/gles2_implementation.h"
26 #include "gpu/command_buffer/common/constants.h"
27 #include "gpu/command_buffer/service/gpu_scheduler.h"
28 #include "gpu/command_buffer/service/command_buffer_service.h"
29 #include "gpu/GLES2/gles2_command_buffer.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
16 #include "ui/gfx/gl/gl_bindings.h" 32 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h"
17 #include "ui/gfx/gl/gl_bindings_skia_in_process.h" 33
18 #include "ui/gfx/gl/gl_context.h" 34 using gpu::Buffer;
19 #include "ui/gfx/gl/gl_implementation.h" 35 using gpu::CommandBuffer;
20 #include "ui/gfx/gl/gl_surface.h" 36 using gpu::CommandBufferService;
37 using gpu::gles2::GLES2CmdHelper;
38 using gpu::gles2::GLES2Implementation;
39 using gpu::GpuScheduler;
21 40
22 namespace webkit { 41 namespace webkit {
23 namespace gpu { 42 namespace gpu {
24 43
25 enum { 44 class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> {
26 MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, 45 public:
27 MAX_VARYING_VECTORS = 0x8DFC, 46 // These are the same error codes as used by EGL.
28 MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD 47 enum Error {
48 SUCCESS = 0x3000,
49 NOT_INITIALIZED = 0x3001,
50 BAD_ATTRIBUTE = 0x3004,
51 BAD_GLContext = 0x3006,
52 CONTEXT_LOST = 0x300E
53 };
54
55 // GLInProcessContext configuration attributes. These are the same as used by
56 // EGL. Attributes are matched using a closest fit algorithm.
57 enum Attribute {
58 ALPHA_SIZE = 0x3021,
59 BLUE_SIZE = 0x3022,
60 GREEN_SIZE = 0x3023,
61 RED_SIZE = 0x3024,
62 DEPTH_SIZE = 0x3025,
63 STENCIL_SIZE = 0x3026,
64 SAMPLES = 0x3031,
65 SAMPLE_BUFFERS = 0x3032,
66 NONE = 0x3038 // Attrib list = terminator
67 };
68
69 // Initialize the library. This must have completed before any other
70 // functions are invoked.
71 static bool Initialize();
72
73 // Terminate the library. This must be called after any other functions
74 // have completed.
75 static bool Terminate();
76
77 ~GLInProcessContext();
78
79 // Create a GLInProcessContext that renders directly to a view. The view and
80 // the associated window must not be destroyed until the returned
81 // GLInProcessContext has been destroyed, otherwise the GPU process might
82 // attempt to render to an invalid window handle.
83 //
84 // NOTE: on Mac OS X, this entry point is only used to set up the
85 // accelerated compositor's output. On this platform, we actually pass
86 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId,
87 // because the facility to allocate a fake PluginWindowHandle is
88 // already in place. We could add more entry points and messages to
89 // allocate both fake PluginWindowHandles and NativeViewIds and map
90 // from fake NativeViewIds to PluginWindowHandles, but this seems like
91 // unnecessary complexity at the moment.
92 //
93 static GLInProcessContext* CreateViewContext(
94 gfx::PluginWindowHandle render_surface,
95 const char* allowed_extensions,
96 const int32* attrib_list,
97 const GURL& active_arl);
98
99 #if defined(OS_MACOSX)
100 // On Mac OS X only, view GLInProcessContexts actually behave like offscreen
101 // GLInProcessContexts, and require an explicit resize operation which is
102 // slightly different from that of offscreen GLInProcessContexts.
103 void ResizeOnscreen(const gfx::Size& size);
104 #endif
105
106 // Create a GLInProcessContext that renders to an offscreen frame buffer. If
107 // parent is not NULL, that GLInProcessContext can access a copy of the
108 // created GLInProcessContext's frame buffer that is updated every time
109 // SwapBuffers is called. It is not as general as shared GLInProcessContexts
110 // in other implementations of OpenGL. If parent is not NULL, it must be used
111 // on the same thread as the parent. A child GLInProcessContext may not
112 // outlive its parent. attrib_list must be NULL or a NONE-terminated list of
113 // attribute/value pairs.
114 static GLInProcessContext* CreateOffscreenContext(
115 GLInProcessContext* parent,
116 const gfx::Size& size,
117 const char* allowed_extensions,
118 const int32* attrib_list,
119 const GURL& active_url);
120
121 // Resize an offscreen frame buffer. The resize occurs on the next call to
122 // SwapBuffers. This is to avoid waiting until all pending GL calls have been
123 // executed by the GPU process. Everything rendered up to the call to
124 // SwapBuffers will be lost. A lost GLInProcessContext will be reported if the
125 // resize fails.
126 void ResizeOffscreen(const gfx::Size& size);
127
128 // For an offscreen frame buffer GLInProcessContext, return the texture ID
129 // with respect to the parent GLInProcessContext. Returns zero if
130 // GLInProcessContext does not have a parent.
131 uint32 GetParentTextureId();
132
133 // Create a new texture in the parent's GLInProcessContext. Returns zero if
134 // GLInProcessContext does not have a parent.
135 uint32 CreateParentTexture(const gfx::Size& size);
136
137 // Deletes a texture in the parent's GLInProcessContext.
138 void DeleteParentTexture(uint32 texture);
139
140 // Provides a callback that will be invoked when SwapBuffers has completed
141 // service side.
142 void SetSwapBuffersCallback(Callback0::Type* callback);
143
144 void SetContextLostCallback(Callback0::Type* callback);
145
146 // Set the current GLInProcessContext for the calling thread.
147 static bool MakeCurrent(GLInProcessContext* context);
148
149 // For a view GLInProcessContext, display everything that has been rendered
150 // since the last call. For an offscreen GLInProcessContext, resolve
151 // everything that has been rendered since the last call to a copy that can be
152 // accessed by the parent GLInProcessContext.
153 bool SwapBuffers();
154
155 // TODO(gman): Remove this
156 void DisableShaderTranslation();
157
158 // Allows direct access to the GLES2 implementation so a GLInProcessContext
159 // can be used without making it current.
160 GLES2Implementation* GetImplementation();
161
162 // Return the current error.
163 Error GetError();
164
165 // Return true if GPU process reported GLInProcessContext lost or there was a
166 // problem communicating with the GPU process.
167 bool IsCommandBufferContextLost();
168
169 CommandBufferService* GetCommandBufferService();
170
171 // Create a latch for synchronization between contexts using glSetLatch and
172 // glWaitLatch.
173 // CreateLatch will only fail if there is a generally unrecoverable
174 // error, in which case 0 is returned. Returns latch_id on success.
175 bool CreateLatch(uint32* ret_latch);
176
177 // Destroy a latch.
178 bool DestroyLatch(uint32 latch);
179
180 // All child contexts get a latch pair automatically. These latches are used
181 // for synchronization with parent context. If *this* context does not have a
182 // parent context, these methods will return false.
183 bool GetParentToChildLatch(uint32* parent_to_child_latch);
184 bool GetChildToParentLatch(uint32* child_to_parent_latch);
185
186 private:
187 GLInProcessContext(GLInProcessContext* parent);
188
189 bool Initialize(bool onscreen,
190 gfx::PluginWindowHandle render_surface,
191 const gfx::Size& size,
192 const char* allowed_extensions,
193 const int32* attrib_list,
194 const GURL& active_url);
195 void Destroy();
196
197 void OnSwapBuffers();
198 void OnContextLost();
199
200 base::WeakPtr<GLInProcessContext> parent_;
201 scoped_ptr<Callback0::Type> swap_buffers_callback_;
202 scoped_ptr<Callback0::Type> context_lost_callback_;
203 uint32 parent_texture_id_;
204 uint32 child_to_parent_latch_;
205 uint32 parent_to_child_latch_;
206 int32 latch_transfer_buffer_id_;
207 scoped_ptr<CommandBufferService> command_buffer_;
208 GpuScheduler* gpu_scheduler_;
209 GLES2CmdHelper* gles2_helper_;
210 int32 transfer_buffer_id_;
211 GLES2Implementation* gles2_implementation_;
212 gfx::Size size_;
213 Error last_error_;
214
215 DISALLOW_COPY_AND_ASSIGN(GLInProcessContext);
29 }; 216 };
30 217
31 struct WebGraphicsContext3DInProcessCommandBufferImpl::ShaderSourceEntry { 218 namespace {
32 explicit ShaderSourceEntry(WGC3Denum shader_type) 219
33 : type(shader_type), 220 const int32 kCommandBufferSize = 1024 * 1024;
34 is_valid(false) { 221 // TODO(kbr): make the transfer buffer size configurable via context
35 } 222 // creation attributes.
36 223 const int32 kTransferBufferSize = 1024 * 1024;
37 WGC3Denum type; 224
38 scoped_array<char> source; 225 const uint32 kMaxLatchesPerRenderer = 2048;
39 scoped_array<char> log; 226 const uint32 kInvalidLatchId = 0xffffffffu;
40 scoped_array<char> translated_source; 227
41 bool is_valid; 228 // Singleton used to initialize and terminate the gles2 library.
229 class GLES2Initializer {
230 public:
231 GLES2Initializer() {
232 gles2::Initialize();
233 }
234
235 ~GLES2Initializer() {
236 gles2::Terminate();
237 }
238
239 private:
240 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
42 }; 241 };
43 242
243 // Shared memory allocator for latches. Creates a block of shared memory for
jamesr 2011/06/01 02:07:02 this isn't really shared memory in this implementa
greggman 2011/06/01 21:55:39 Done.
244 // each renderer process.
245 class LatchAllocator {
246 public:
247 static LatchAllocator* GetInstance();
248 static uint32 size() { return kMaxLatchesPerRenderer*sizeof(uint32); }
249 static const uint32_t kFreeLatch = 0xffffffffu;
250
251 LatchAllocator();
252 ~LatchAllocator();
253
254 bool AllocateLatch(uint32* latch_id);
255 bool FreeLatch(uint32 latch_id);
256
257 private:
258 friend struct DefaultSingletonTraits<LatchAllocator>;
259
260 // Because this is in process this can just be normal memory.
261 scoped_array<uint32> memory_;
262
263 // Pointer to mapped shared memory.
jamesr 2011/06/01 02:07:02 this is confusing - can't we just use memory_ (and
greggman 2011/06/01 21:55:39 Done.
264 volatile uint32* latches_;
265
266 DISALLOW_COPY_AND_ASSIGN(LatchAllocator);
267 };
268
269 ////////////////////////////////////////////////////////////////////////////////
270 /// LatchAllocator implementation
271
272 LatchAllocator* LatchAllocator::GetInstance() {
273 return Singleton<LatchAllocator>::get();
274 }
275
276 LatchAllocator::LatchAllocator() {
277 memory_.reset(new uint32[size()]);
278 latches_ = memory_.get();
279 // Mark all latches as unallocated.
280 for (uint32 i = 0; i < kMaxLatchesPerRenderer; ++i)
281 latches_[i] = kFreeLatch;
282 }
283
284 LatchAllocator::~LatchAllocator() {
285 }
286
287 bool LatchAllocator::AllocateLatch(uint32* latch_id) {
288 for (uint32 i = 0; i < kMaxLatchesPerRenderer; ++i) {
289 if (latches_[i] == kFreeLatch) {
290 // mark latch as taken and blocked.
291 // 0 means waiter will block, 1 means waiter will pass.
292 latches_[i] = 0;
293 *latch_id = i;
294 return true;
295 }
296 }
297 return false;
298 }
299
300 bool LatchAllocator::FreeLatch(uint32 latch_id) {
301 if (latch_id < kMaxLatchesPerRenderer && latches_[latch_id] != kFreeLatch) {
302 latches_[latch_id] = kFreeLatch;
303 return true;
304 }
305 return false;
306 }
307
308 ////////////////////////////////////////////////////////////////////////////////
309
310 static base::LazyInstance<GLES2Initializer> g_gles2_initializer(
311 base::LINKER_INITIALIZED);
312
313 } // namespace anonymous
314
315 GLInProcessContext::~GLInProcessContext() {
316 Destroy();
317 }
318
319 GLInProcessContext* GLInProcessContext::CreateViewContext(
320 gfx::PluginWindowHandle render_surface,
321 const char* allowed_extensions,
322 const int32* attrib_list,
323 const GURL& active_url) {
324 #if defined(ENABLE_GPU)
325 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL));
326 if (!context->Initialize(
327 true,
328 render_surface,
329 gfx::Size(),
330 allowed_extensions,
331 attrib_list,
332 active_url))
333 return NULL;
334
335 return context.release();
336 #else
337 return NULL;
338 #endif
339 }
340
341 #if defined(OS_MACOSX)
342 void GLInProcessContext::ResizeOnscreen(const gfx::Size& size) {
343 DCHECK(size.width() > 0 && size.height() > 0);
344 size_ = size;
345 }
346 #endif
347
348 GLInProcessContext* GLInProcessContext::CreateOffscreenContext(
349 GLInProcessContext* parent,
350 const gfx::Size& size,
351 const char* allowed_extensions,
352 const int32* attrib_list,
353 const GURL& active_url) {
354 #if defined(ENABLE_GPU)
355 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent));
356 if (!context->Initialize(
357 false,
358 gfx::kNullPluginWindow,
359 size,
360 allowed_extensions,
361 attrib_list,
362 active_url))
363 return NULL;
364
365 return context.release();
366 #else
367 return NULL;
368 #endif
369 }
370
371 void GLInProcessContext::ResizeOffscreen(const gfx::Size& size) {
372 DCHECK(size.width() > 0 && size.height() > 0);
373 if (size_ != size) {
374 gpu_scheduler_->ResizeOffscreenFrameBuffer(size);
375 // TODO(gman): See if the next line is needed.
376 gles2_implementation_->ResizeCHROMIUM(size.width(), size.height());
377 size_ = size;
378 }
379 }
380
381 uint32 GLInProcessContext::GetParentTextureId() {
382 return parent_texture_id_;
383 }
384
385 uint32 GLInProcessContext::CreateParentTexture(const gfx::Size& size) {
386 // Allocate a texture ID with respect to the parent.
387 if (parent_.get()) {
388 if (!MakeCurrent(parent_.get()))
389 return 0;
390 uint32 texture_id = parent_->gles2_implementation_->MakeTextureId();
391 parent_->gles2_implementation_->BindTexture(GL_TEXTURE_2D, texture_id);
392 parent_->gles2_implementation_->TexParameteri(
393 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
394 parent_->gles2_implementation_->TexParameteri(
395 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
396 parent_->gles2_implementation_->TexParameteri(
397 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
398 parent_->gles2_implementation_->TexParameteri(
399 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
400
401 parent_->gles2_implementation_->TexImage2D(GL_TEXTURE_2D,
402 0, // mip level
403 GL_RGBA,
404 size.width(),
405 size.height(),
406 0, // border
407 GL_RGBA,
408 GL_UNSIGNED_BYTE,
409 NULL);
410 // Make sure that the parent texture's storage is allocated before we let
411 // the caller attempt to use it.
412 int32 token = parent_->gles2_helper_->InsertToken();
413 parent_->gles2_helper_->WaitForToken(token);
414 return texture_id;
415 }
416 return 0;
417 }
418
419 void GLInProcessContext::DeleteParentTexture(uint32 texture) {
420 if (parent_.get()) {
421 if (!MakeCurrent(parent_.get()))
422 return;
423 parent_->gles2_implementation_->DeleteTextures(1, &texture);
424 }
425 }
426
427 void GLInProcessContext::SetSwapBuffersCallback(Callback0::Type* callback) {
428 swap_buffers_callback_.reset(callback);
429 }
430
431 void GLInProcessContext::SetContextLostCallback(Callback0::Type* callback) {
432 context_lost_callback_.reset(callback);
433 }
434
435 bool GLInProcessContext::MakeCurrent(GLInProcessContext* context) {
436 if (context) {
437 gles2::SetGLContext(context->gles2_implementation_);
438
439 // Don't request latest error status from service. Just use the locally
440 // cached information from the last flush.
441 // TODO(apatrick): I'm not sure if this should actually change the
442 // current context if it fails. For now it gets changed even if it fails
443 // because making GL calls with a NULL context crashes.
444 if (context->command_buffer_->GetState().error != ::gpu::error::kNoError)
445 return false;
446 } else {
447 gles2::SetGLContext(NULL);
448 }
449
450 return true;
451 }
452
453 bool GLInProcessContext::SwapBuffers() {
454 // Don't request latest error status from service. Just use the locally cached
455 // information from the last flush.
456 if (command_buffer_->GetState().error != ::gpu::error::kNoError)
457 return false;
458
459 gles2_implementation_->SwapBuffers();
460 gles2_implementation_->Finish();
461 return true;
462 }
463
464 GLInProcessContext::Error GLInProcessContext::GetError() {
465 CommandBuffer::State state = command_buffer_->GetState();
466 if (state.error == ::gpu::error::kNoError) {
467 Error old_error = last_error_;
468 last_error_ = SUCCESS;
469 return old_error;
470 } else {
471 // All command buffer errors are unrecoverable. The error is treated as a
472 // lost context: destroy the context and create another one.
473 return CONTEXT_LOST;
474 }
475 }
476
477 bool GLInProcessContext::IsCommandBufferContextLost() {
478 CommandBuffer::State state = command_buffer_->GetState();
479 return state.error == ::gpu::error::kLostContext;
480 }
481
482 CommandBufferService* GLInProcessContext::GetCommandBufferService() {
483 return command_buffer_.get();
484 }
485
486 // TODO(gman): Remove This
487 void GLInProcessContext::DisableShaderTranslation() {
488 gles2_implementation_->CommandBufferEnableCHROMIUM(
489 PEPPER3D_SKIP_GLSL_TRANSLATION);
490 }
491
492 GLES2Implementation* GLInProcessContext::GetImplementation() {
493 return gles2_implementation_;
494 }
495
496 GLInProcessContext::GLInProcessContext(GLInProcessContext* parent)
497 : parent_(parent ?
498 parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()),
499 parent_texture_id_(0),
500 child_to_parent_latch_(kInvalidLatchId),
501 parent_to_child_latch_(kInvalidLatchId),
502 latch_transfer_buffer_id_(-1),
503 gpu_scheduler_(NULL),
504 gles2_helper_(NULL),
505 transfer_buffer_id_(-1),
506 gles2_implementation_(NULL),
507 last_error_(SUCCESS) {
508 }
509
510 bool GLInProcessContext::Initialize(bool onscreen,
511 gfx::PluginWindowHandle render_surface,
512 const gfx::Size& size,
513 const char* allowed_extensions,
514 const int32* attrib_list,
515 const GURL& active_url) {
516 DCHECK(size.width() >= 0 && size.height() >= 0);
517
518 // Ensure the gles2 library is initialized first in a thread safe way.
519 g_gles2_initializer.Get();
520
521 // Allocate a frame buffer ID with respect to the parent.
522 if (parent_.get()) {
523 // Flush any remaining commands in the parent context to make sure the
524 // texture id accounting stays consistent.
525 int32 token = parent_->gles2_helper_->InsertToken();
526 parent_->gles2_helper_->WaitForToken(token);
527 parent_texture_id_ = parent_->gles2_implementation_->MakeTextureId();
528 }
529
530 std::vector<int32> attribs;
531 while (attrib_list) {
532 int32 attrib = *attrib_list++;
533 switch (attrib) {
534 // Known attributes
535 case ALPHA_SIZE:
536 case BLUE_SIZE:
537 case GREEN_SIZE:
538 case RED_SIZE:
539 case DEPTH_SIZE:
540 case STENCIL_SIZE:
541 case SAMPLES:
542 case SAMPLE_BUFFERS:
543 attribs.push_back(attrib);
544 attribs.push_back(*attrib_list++);
545 break;
546 case NONE:
547 attribs.push_back(attrib);
548 attrib_list = NULL;
549 break;
550 default:
551 last_error_ = BAD_ATTRIBUTE;
552 attribs.push_back(NONE);
553 attrib_list = NULL;
554 break;
555 }
556 }
557
558 command_buffer_.reset(new CommandBufferService);
559 if (!command_buffer_->Initialize(kCommandBufferSize))
560 return false;
561
562 gpu_scheduler_ = new GpuScheduler(command_buffer_.get(), NULL);
563
564 if (onscreen) {
565 if (render_surface == gfx::kNullPluginWindow) {
566 LOG(ERROR) << "Invalid surface handle for onscreen context.";
567 command_buffer_.reset();
568 } else {
569 if (!gpu_scheduler_->Initialize(render_surface,
570 gfx::Size(),
571 ::gpu::gles2::DisallowedExtensions(),
572 allowed_extensions,
573 attribs,
574 NULL,
575 0)) {
576 LOG(ERROR) << "Could not initialize GpuScheduler.";
577 command_buffer_.reset();
578 }
579 }
580 } else {
581 GpuScheduler* parent_scheduler =
582 parent_.get() ? parent_->gpu_scheduler_ : NULL;
583
584 if (!gpu_scheduler_->Initialize(render_surface,
585 size,
586 ::gpu::gles2::DisallowedExtensions(),
587 allowed_extensions,
588 attribs,
589 parent_scheduler,
590 parent_texture_id_)) {
591 LOG(ERROR) << "Could not initialize offscreen GpuScheduler.";
592 command_buffer_.reset();
593 }
594 }
595 if (!command_buffer_.get()) {
596 Destroy();
597 return false;
598 }
599
600 command_buffer_->SetPutOffsetChangeCallback(
601 NewCallback(gpu_scheduler_, &GpuScheduler::PutChanged));
602
603 // Create the GLES2 helper, which writes the command buffer protocol.
604 gles2_helper_ = new GLES2CmdHelper(command_buffer_.get());
605 if (!gles2_helper_->Initialize(kCommandBufferSize)) {
606 Destroy();
607 return false;
608 }
609
610 // Create a transfer buffer used to copy resources between the renderer
611 // process and the GPU process.
jamesr 2011/06/01 02:07:02 comment isn't quite correct for this case. what i
greggman 2011/06/01 21:55:39 Done.
612 transfer_buffer_id_ =
613 command_buffer_->CreateTransferBuffer(
614 kTransferBufferSize, ::gpu::kCommandBufferSharedMemoryId);
615 if (transfer_buffer_id_ < 0) {
616 Destroy();
617 return false;
618 }
619
620 // Map the buffer into the renderer process's address space.
621 Buffer transfer_buffer =
622 command_buffer_->GetTransferBuffer(transfer_buffer_id_);
jamesr 2011/06/01 02:07:02 this is a no-op for this case right?
greggman 2011/06/01 21:55:39 I don't actually know and I shouldn't have to. I w
623 if (!transfer_buffer.ptr) {
624 Destroy();
625 return false;
626 }
627
628 // Register transfer buffer so that the context can access latches.
jamesr 2011/06/01 02:07:02 comment is misleading
greggman 2011/06/01 21:55:39 Done.
629 // LatchAllocator* latch_shm = LatchAllocator::GetInstance();
630 // latch_transfer_buffer_id_ = command_buffer_->RegisterTransferBuffer(
jamesr 2011/06/01 02:07:02 what does this really do?
greggman 2011/06/01 21:55:39 This code has been deleted.
631 // latch_shm->shared_memory(), LatchAllocator::size(),
632 // ::gpu::kLatchSharedMemoryId);
633 // if (latch_transfer_buffer_id_ != ::gpu::kLatchSharedMemoryId) {
634 // Destroy();
635 // return false;
636 // }
637
638 // If this is a child context, setup latches for synchronization between child
639 // and parent.
640 if (parent_.get()) {
641 if (!CreateLatch(&child_to_parent_latch_) ||
642 !CreateLatch(&parent_to_child_latch_)) {
643 Destroy();
644 return false;
645 }
646 }
647
648 // Create the object exposing the OpenGL API.
649 gles2_implementation_ = new GLES2Implementation(
650 gles2_helper_,
651 transfer_buffer.size,
652 transfer_buffer.ptr,
653 transfer_buffer_id_,
654 false);
655
656 size_ = size;
657
658 return true;
659 }
660
661 void GLInProcessContext::Destroy() {
662 if (parent_.get() && parent_texture_id_ != 0) {
663 parent_->gles2_implementation_->FreeTextureId(parent_texture_id_);
664 parent_texture_id_ = 0;
665 }
666
667 delete gles2_implementation_;
668 gles2_implementation_ = NULL;
669
670 if (child_to_parent_latch_ != kInvalidLatchId) {
671 DestroyLatch(child_to_parent_latch_);
672 child_to_parent_latch_ = kInvalidLatchId;
673 }
674 if (parent_to_child_latch_ != kInvalidLatchId) {
675 DestroyLatch(parent_to_child_latch_);
676 parent_to_child_latch_ = kInvalidLatchId;
677 }
678 if (command_buffer_.get() && latch_transfer_buffer_id_ != -1) {
679 command_buffer_->DestroyTransferBuffer(latch_transfer_buffer_id_);
680 latch_transfer_buffer_id_ = -1;
681 }
682
683 if (command_buffer_.get() && transfer_buffer_id_ != -1) {
684 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_);
685 transfer_buffer_id_ = -1;
686 }
687
688 delete gles2_helper_;
689 gles2_helper_ = NULL;
690
691 command_buffer_.reset();
692 }
693
694 void GLInProcessContext::OnSwapBuffers() {
695 if (swap_buffers_callback_.get())
696 swap_buffers_callback_->Run();
697 }
698
699 void GLInProcessContext::OnContextLost() {
700 if (context_lost_callback_.get())
701 context_lost_callback_->Run();
702 }
703
704 bool GLInProcessContext::CreateLatch(uint32* ret_latch) {
705 return LatchAllocator::GetInstance()->AllocateLatch(ret_latch);
706 }
707
708 bool GLInProcessContext::DestroyLatch(uint32 latch) {
709 return LatchAllocator::GetInstance()->FreeLatch(latch);
710 }
711
712 bool GLInProcessContext::GetParentToChildLatch(uint32* parent_to_child_latch) {
713 if (parent_.get()) {
714 *parent_to_child_latch = parent_to_child_latch_;
715 return true;
716 }
717 return false;
718 }
719
720 bool GLInProcessContext::GetChildToParentLatch(uint32* child_to_parent_latch) {
721 if (parent_.get()) {
722 *child_to_parent_latch = child_to_parent_latch_;
723 return true;
724 }
725 return false;
726 }
727
44 WebGraphicsContext3DInProcessCommandBufferImpl::WebGraphicsContext3DInProcessCom mandBufferImpl() 728 WebGraphicsContext3DInProcessCommandBufferImpl::WebGraphicsContext3DInProcessCom mandBufferImpl()
45 : initialized_(false), 729 : context_(NULL),
46 render_directly_to_web_view_(false), 730 gl_(NULL),
47 is_gles2_(false), 731 web_view_(NULL),
48 have_ext_framebuffer_object_(false), 732 #if defined(OS_MACOSX)
49 have_ext_framebuffer_multisample_(false), 733 plugin_handle_(NULL),
50 have_angle_framebuffer_multisample_(false), 734 #endif // defined(OS_MACOSX)
51 texture_(0), 735 context_lost_callback_(0),
52 fbo_(0),
53 depth_stencil_buffer_(0),
54 cached_width_(0), 736 cached_width_(0),
55 cached_height_(0), 737 cached_height_(0),
56 multisample_fbo_(0), 738 bound_fbo_(0) {
57 multisample_depth_stencil_buffer_(0), 739 }
58 multisample_color_buffer_(0), 740
59 bound_fbo_(0), 741 WebGraphicsContext3DInProcessCommandBufferImpl::
60 bound_texture_(0), 742 ~WebGraphicsContext3DInProcessCommandBufferImpl() {
61 copy_texture_to_parent_texture_fbo_(0), 743 }
62 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 744
63 scanline_(0), 745 // This string should only be passed for WebGL contexts. Nothing ELSE!!!
64 #endif 746 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of
65 fragment_compiler_(0), 747 // a context should not pass this string.
66 vertex_compiler_(0) { 748 static const char* kWebGLPreferredGLExtensions =
67 } 749 "GL_OES_packed_depth_stencil "
68 750 "GL_OES_depth24 "
69 WebGraphicsContext3DInProcessCommandBufferImpl::~WebGraphicsContext3DInProcessCo mmandBufferImpl() { 751 "GL_CHROMIUM_webglsl";
70 if (!initialized_)
71 return;
72
73 makeContextCurrent();
74
75 if (attributes_.antialias) {
76 glDeleteRenderbuffersEXT(1, &multisample_color_buffer_);
77 if (attributes_.depth || attributes_.stencil)
78 glDeleteRenderbuffersEXT(1, &multisample_depth_stencil_buffer_);
79 glDeleteFramebuffersEXT(1, &multisample_fbo_);
80 } else {
81 if (attributes_.depth || attributes_.stencil)
82 glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_);
83 }
84 glDeleteTextures(1, &texture_);
85 glDeleteFramebuffersEXT(1, &copy_texture_to_parent_texture_fbo_);
86 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
87 if (scanline_)
88 delete[] scanline_;
89 #endif
90 glDeleteFramebuffersEXT(1, &fbo_);
91
92 gl_context_->Destroy();
93
94 for (ShaderSourceMap::iterator ii = shader_source_map_.begin();
95 ii != shader_source_map_.end(); ++ii) {
96 if (ii->second)
97 delete ii->second;
98 }
99 AngleDestroyCompilers();
100 }
101 752
102 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize( 753 bool WebGraphicsContext3DInProcessCommandBufferImpl::initialize(
103 WebGraphicsContext3D::Attributes attributes, 754 WebGraphicsContext3D::Attributes attributes,
104 WebView* webView, 755 WebKit::WebView* web_view,
105 bool render_directly_to_web_view) { 756 bool render_directly_to_web_view) {
106 if (!gfx::GLSurface::InitializeOneOff()) 757 webkit_glue::BindSkiaToCommandBufferGL();
758
759 // Convert WebGL context creation attributes into GLInProcessContext / EGL
760 // size requests.
761 const int alpha_size = attributes.alpha ? 8 : 0;
762 const int depth_size = attributes.depth ? 24 : 0;
763 const int stencil_size = attributes.stencil ? 8 : 0;
764 const int samples = attributes.antialias ? 4 : 0;
765 const int sample_buffers = attributes.antialias ? 1 : 0;
766 const int32 attribs[] = {
767 GLInProcessContext::ALPHA_SIZE, alpha_size,
768 GLInProcessContext::DEPTH_SIZE, depth_size,
769 GLInProcessContext::STENCIL_SIZE, stencil_size,
770 GLInProcessContext::SAMPLES, samples,
771 GLInProcessContext::SAMPLE_BUFFERS, sample_buffers,
772 GLInProcessContext::NONE,
773 };
774
775 const char* preferred_extensions = attributes.noExtensions ?
776 kWebGLPreferredGLExtensions : "*";
777
778 GURL active_url;
779 if (web_view && web_view->mainFrame())
780 active_url = GURL(web_view->mainFrame()->url());
781
782 GLInProcessContext* parent_context = NULL;
783 if (!render_directly_to_web_view) {
784 WebKit::WebGraphicsContext3D* view_context =
785 web_view->graphicsContext3D();
786 if (view_context) {
787 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl =
788 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>(
789 view_context);
790 parent_context = context_impl->context_;
791 } else {
792 NOTREACHED() << "no parent context.";
793 }
794 }
795
796 context_ = GLInProcessContext::CreateOffscreenContext(
797 parent_context,
798 gfx::Size(1, 1),
799 preferred_extensions,
800 attribs,
801 active_url);
802 web_view_ = NULL;
803
804 if (!context_)
107 return false; 805 return false;
108 gfx::BindSkiaToInProcessGL(); 806
109 807 gl_ = context_->GetImplementation();
110 render_directly_to_web_view_ = render_directly_to_web_view; 808 context_->SetContextLostCallback(
111 gfx::GLContext* share_context = 0; 809 NewCallback(
112 810 this,
113 if (!render_directly_to_web_view) { 811 &WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost));
114 // Pick up the compositor's context to share resources with. 812
115 WebGraphicsContext3D* view_context = webView->graphicsContext3D(); 813 // Set attributes_ from created offscreen context.
116 if (view_context) { 814 {
117 WebGraphicsContext3DInProcessCommandBufferImpl* contextImpl = 815 attributes_ = attributes;
118 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>(view_cont ext); 816 GLint alpha_bits = 0;
119 share_context = contextImpl->gl_context_.get(); 817 getIntegerv(GL_ALPHA_BITS, &alpha_bits);
120 } else { 818 attributes_.alpha = alpha_bits > 0;
121 // The compositor's context didn't get created 819 GLint depth_bits = 0;
122 // successfully, so conceptually there is no way we can 820 getIntegerv(GL_DEPTH_BITS, &depth_bits);
123 // render successfully to the WebView. 821 attributes_.depth = depth_bits > 0;
124 render_directly_to_web_view_ = false; 822 GLint stencil_bits = 0;
125 } 823 getIntegerv(GL_STENCIL_BITS, &stencil_bits);
126 } 824 attributes_.stencil = stencil_bits > 0;
127 825 GLint samples = 0;
128 is_gles2_ = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; 826 getIntegerv(GL_SAMPLES, &samples);
129 827 attributes_.antialias = samples > 0;
130 // This implementation always renders offscreen regardless of 828 }
131 // whether render_directly_to_web_view is true. Both DumpRenderTree 829 makeContextCurrent();
132 // and test_shell paint first to an intermediate offscreen buffer 830
133 // and from there to the window, and WebViewImpl::paint already
134 // correctly handles the case where the compositor is active but
135 // the output needs to go to a WebCanvas.
136 gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)));
137
138 if (!gl_surface_.get()) {
139 if (!is_gles2_)
140 return false;
141
142 // Embedded systems have smaller limit on number of GL contexts. Sometimes
143 // failure of GL context creation is because of existing GL contexts
144 // referenced by JavaScript garbages. Collect garbage and try again.
145 // TODO: Besides this solution, kbr@chromium.org suggested: upon receiving
146 // a page unload event, iterate down any live WebGraphicsContext3D instances
147 // and force them to drop their contexts, sending a context lost event if
148 // necessary.
149 webView->mainFrame()->collectGarbage();
150
151 gl_surface_.reset(gfx::GLSurface::CreateOffscreenGLSurface(
152 gfx::Size(1, 1)));
153 if (!gl_surface_.get())
154 return false;
155 }
156
157 gl_context_.reset(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_.reset(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_.reset();
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; 831 return true;
222 } 832 }
223 833
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() { 834 bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() {
286 return gl_context_->MakeCurrent(gl_surface_.get()); 835 return GLInProcessContext::MakeCurrent(context_);
836 }
837
838 void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() {
839 // Comment the next line in to help find missing MakeCurrent calls
840 // in code not going through WebGraphicsContext3D.
841 // GLInProcessContext::MakeCurrent(NULL);
jamesr 2011/06/01 02:07:02 comment and code are out of sync
greggman 2011/06/01 21:55:39 I updated the comment though it still says basical
287 } 842 }
288 843
289 int WebGraphicsContext3DInProcessCommandBufferImpl::width() { 844 int WebGraphicsContext3DInProcessCommandBufferImpl::width() {
290 return cached_width_; 845 return cached_width_;
291 } 846 }
292 847
293 int WebGraphicsContext3DInProcessCommandBufferImpl::height() { 848 int WebGraphicsContext3DInProcessCommandBufferImpl::height() {
294 return cached_height_; 849 return cached_height_;
295 } 850 }
296 851
297 bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() { 852 bool WebGraphicsContext3DInProcessCommandBufferImpl::isGLES2Compliant() {
298 return is_gles2_; 853 return true;
299 } 854 }
300 855
301 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() { 856 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::getPlatformTextureId() {
302 return texture_; 857 DCHECK(context_);
858 return context_->GetParentTextureId();
303 } 859 }
304 860
305 void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() { 861 void WebGraphicsContext3DInProcessCommandBufferImpl::prepareTexture() {
306 if (!render_directly_to_web_view_) { 862 // Copies the contents of the off-screen render target into the texture
307 // We need to prepare our rendering results for the compositor. 863 // used by the compositor.
308 makeContextCurrent(); 864 context_->SwapBuffers();
309 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); 865 }
310 } 866
311 } 867 void WebGraphicsContext3DInProcessCommandBufferImpl::reshape(
312 868 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; 869 cached_width_ = width;
328 cached_height_ = height; 870 cached_height_ = height;
329 makeContextCurrent(); 871
330 872 ClearContext();
331 GLenum target = GL_TEXTURE_2D; 873
332 874 if (web_view_) {
333 if (!texture_) { 875 #if defined(OS_MACOSX)
334 // Generate the texture object 876 context_->ResizeOnscreen(gfx::Size(width, height));
335 texture_ = CreateTextureObject(target); 877 #else
336 // Generate the framebuffer object 878 gl_->ResizeCHROMIUM(width, height);
337 glGenFramebuffersEXT(1, &fbo_); 879 #endif
338 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
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 { 880 } else {
363 // GL_RGB8_OES == GL_RGB8 881 context_->ResizeOffscreen(gfx::Size(width, height));
364 internal_multisampled_color_format = GL_RGB8; 882 // Force a SwapBuffers to get the framebuffer to resize.
365 internal_color_format = is_gles2_ ? GL_RGB : GL_RGB8; 883 context_->SwapBuffers();
366 color_format = GL_RGB; 884 }
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 885
552 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 886 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
553 if (scanline_) { 887 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 888 #endif // FLIP_FRAMEBUFFER_VERTICALLY
559 } 889 }
560 890
891 WebGLId WebGraphicsContext3DInProcessCommandBufferImpl::createCompositorTexture(
892 WGC3Dsizei width, WGC3Dsizei height) {
893 ClearContext();
894 return context_->CreateParentTexture(gfx::Size(width, height));
895 }
896
897 void WebGraphicsContext3DInProcessCommandBufferImpl::deleteCompositorTexture(
898 WebGLId parent_texture) {
899 ClearContext();
900 context_->DeleteParentTexture(parent_texture);
901 }
902
561 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 903 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
562 void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( 904 void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically(
563 unsigned char* framebuffer, unsigned int width, unsigned int height) { 905 uint8* framebuffer,
564 unsigned char* scanline = scanline_; 906 unsigned int width,
907 unsigned int height) {
908 uint8* scanline = scanline_.get();
565 if (!scanline) 909 if (!scanline)
566 return; 910 return;
567 unsigned int row_bytes = width * 4; 911 unsigned int row_bytes = width * 4;
568 unsigned int count = height / 2; 912 unsigned int count = height / 2;
569 for (unsigned int i = 0; i < count; i++) { 913 for (unsigned int i = 0; i < count; i++) {
570 unsigned char* row_a = framebuffer + i * row_bytes; 914 uint8* row_a = framebuffer + i * row_bytes;
571 unsigned char* row_b = framebuffer + (height - i - 1) * row_bytes; 915 uint8* row_b = framebuffer + (height - i - 1) * row_bytes;
572 // FIXME: this is where the multiplication of the alpha 916 // TODO(kbr): this is where the multiplication of the alpha
573 // channel into the color buffer will need to occur if the 917 // channel into the color buffer will need to occur if the
574 // user specifies the "premultiplyAlpha" flag in the context 918 // user specifies the "premultiplyAlpha" flag in the context
575 // creation attributes. 919 // creation attributes.
576 memcpy(scanline, row_b, row_bytes); 920 memcpy(scanline, row_b, row_bytes);
577 memcpy(row_b, row_a, row_bytes); 921 memcpy(row_b, row_a, row_bytes);
578 memcpy(row_a, scanline, row_bytes); 922 memcpy(row_a, scanline, row_bytes);
579 } 923 }
580 } 924 }
581 #endif 925 #endif
582 926
583 bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( 927 bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer(
584 unsigned char* pixels, size_t bufferSize) { 928 unsigned char* pixels,
585 if (bufferSize != static_cast<size_t>(4 * width() * height())) 929 size_t buffer_size) {
930 ClearContext();
931 if (buffer_size != static_cast<size_t>(4 * width() * height())) {
586 return false; 932 return false;
587 933 }
588 makeContextCurrent();
589 934
590 // Earlier versions of this code used the GPU to flip the 935 // Earlier versions of this code used the GPU to flip the
591 // framebuffer vertically before reading it back for compositing 936 // framebuffer vertically before reading it back for compositing
592 // via software. This code was quite complicated, used a lot of 937 // via software. This code was quite complicated, used a lot of
593 // GPU memory, and didn't provide an obvious speedup. Since this 938 // GPU memory, and didn't provide an obvious speedup. Since this
594 // vertical flip is only a temporary solution anyway until Chrome 939 // vertical flip is only a temporary solution anyway until Chrome
595 // is fully GPU composited, it wasn't worth the complexity. 940 // is fully GPU composited, it wasn't worth the complexity.
596 941
597 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); 942 bool mustRestoreFBO = (bound_fbo_ != 0);
598 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); 943 if (mustRestoreFBO) {
599 944 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0);
600 GLint pack_alignment = 4; 945 }
601 bool must_restore_pack_alignment = false; 946 gl_->ReadPixels(0, 0, cached_width_, cached_height_,
602 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); 947 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
603 if (pack_alignment > 4) { 948
604 glPixelStorei(GL_PACK_ALIGNMENT, 4); 949 // Swizzle red and blue channels
605 must_restore_pack_alignment = true; 950 // TODO(kbr): expose GL_BGRA as extension
606 } 951 for (size_t i = 0; i < buffer_size; i += 4) {
607 952 std::swap(pixels[i], pixels[i + 2]);
608 if (is_gles2_) { 953 }
609 // FIXME: consider testing for presence of GL_OES_read_format 954
610 // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here 955 if (mustRestoreFBO) {
611 // directly. 956 gl_->BindFramebuffer(GL_FRAMEBUFFER, bound_fbo_);
612 glReadPixels(0, 0, cached_width_, cached_height_, 957 }
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 958
627 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 959 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
628 if (pixels) 960 if (pixels) {
629 FlipVertically(pixels, cached_width_, cached_height_); 961 FlipVertically(pixels, cached_width_, cached_height_);
962 }
630 #endif 963 #endif
631 964
632 return true; 965 return true;
633 } 966 }
634 967
635 void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(WGC3Denum error) { 968 void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(
636 if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) { 969 WGC3Denum error) {
637 synthetic_errors_set_.insert(error); 970 if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
638 synthetic_errors_list_.push_back(error); 971 synthetic_errors_.end()) {
972 synthetic_errors_.push_back(error);
639 } 973 }
640 } 974 }
641 975
642 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM( 976 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapBufferSubDataCHROMIUM(
643 WGC3Denum target, WGC3Dintptr offset, 977 WGC3Denum target,
644 WGC3Dsizeiptr size, WGC3Denum access) { 978 WGC3Dintptr offset,
645 return 0; 979 WGC3Dsizeiptr size,
980 WGC3Denum access) {
981 ClearContext();
982 return gl_->MapBufferSubDataCHROMIUM(target, offset, size, access);
646 } 983 }
647 984
648 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM( 985 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapBufferSubDataCHROMIUM(
649 const void* mem) { 986 const void* mem) {
987 ClearContext();
988 return gl_->UnmapBufferSubDataCHROMIUM(mem);
650 } 989 }
651 990
652 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM( 991 void* WebGraphicsContext3DInProcessCommandBufferImpl::mapTexSubImage2DCHROMIUM(
653 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, 992 WGC3Denum target,
654 WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, 993 WGC3Dint level,
994 WGC3Dint xoffset,
995 WGC3Dint yoffset,
996 WGC3Dsizei width,
997 WGC3Dsizei height,
998 WGC3Denum format,
999 WGC3Denum type,
655 WGC3Denum access) { 1000 WGC3Denum access) {
656 return 0; 1001 ClearContext();
1002 return gl_->MapTexSubImage2DCHROMIUM(
1003 target, level, xoffset, yoffset, width, height, format, type, access);
657 } 1004 }
658 1005
659 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM( 1006 void WebGraphicsContext3DInProcessCommandBufferImpl::unmapTexSubImage2DCHROMIUM(
660 const void* mem) { 1007 const void* mem) {
1008 ClearContext();
1009 gl_->UnmapTexSubImage2DCHROMIUM(mem);
661 } 1010 }
662 1011
663 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToParentTextureC HROMIUM( 1012 void WebGraphicsContext3DInProcessCommandBufferImpl::copyTextureToParentTextureC HROMIUM(
664 WebGLId id, WebGLId id2) { 1013 WebGLId texture, WebGLId parentTexture) {
665 if (!glGetTexLevelParameteriv) 1014 ClearContext();
666 return; 1015 copyTextureToCompositor(texture, parentTexture);
667
668 makeContextCurrent();
669 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, copy_texture_to_parent_texture_fbo_);
670 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
671 GL_COLOR_ATTACHMENT0,
672 GL_TEXTURE_2D,
673 id,
674 0); // level
675 glBindTexture(GL_TEXTURE_2D, id2);
676 GLsizei width, height;
677 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
678 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
679 glCopyTexImage2D(GL_TEXTURE_2D,
680 0, // level
681 GL_RGBA,
682 0, 0, // x, y
683 width,
684 height,
685 0); // border
686 glBindTexture(GL_TEXTURE_2D, bound_texture_);
687 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
688 } 1016 }
689 1017
690 void WebGraphicsContext3DInProcessCommandBufferImpl::getParentToChildLatchCHROMI UM( 1018 void WebGraphicsContext3DInProcessCommandBufferImpl::getParentToChildLatchCHROMI UM(
691 WGC3Duint* latch_id) 1019 WGC3Duint* latch_id)
692 { 1020 {
1021 ClearContext();
1022 if (!context_->GetParentToChildLatch(latch_id)) {
1023 LOG(ERROR) << "getLatch must only be called on child context";
1024 synthesizeGLError(GL_INVALID_OPERATION);
1025 *latch_id = ::gpu::kInvalidLatchId;
1026 }
693 } 1027 }
694 1028
695 void WebGraphicsContext3DInProcessCommandBufferImpl::getChildToParentLatchCHROMI UM( 1029 void WebGraphicsContext3DInProcessCommandBufferImpl::getChildToParentLatchCHROMI UM(
696 WGC3Duint* latch_id) 1030 WGC3Duint* latch_id)
697 { 1031 {
1032 ClearContext();
1033 if (!context_->GetChildToParentLatch(latch_id)) {
1034 LOG(ERROR) << "getLatch must only be called on child context";
1035 synthesizeGLError(GL_INVALID_OPERATION);
1036 *latch_id = ::gpu::kInvalidLatchId;
1037 }
698 } 1038 }
699 1039
700 void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM( 1040 void WebGraphicsContext3DInProcessCommandBufferImpl::waitLatchCHROMIUM(
701 WGC3Duint latch_id) 1041 WGC3Duint latch_id)
702 { 1042 {
1043 ClearContext();
1044 gl_->WaitLatchCHROMIUM(latch_id);
703 } 1045 }
704 1046
705 void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM( 1047 void WebGraphicsContext3DInProcessCommandBufferImpl::setLatchCHROMIUM(
706 WGC3Duint latch_id) 1048 WGC3Duint latch_id)
707 { 1049 {
708 } 1050 ClearContext();
709 1051 gl_->SetLatchCHROMIUM(latch_id);
710 WebString WebGraphicsContext3DInProcessCommandBufferImpl:: 1052 // required to ensure set command is sent to GPU process
1053 gl_->Flush();
1054 }
1055
1056 void WebGraphicsContext3DInProcessCommandBufferImpl::
1057 rateLimitOffscreenContextCHROMIUM() {
1058 ClearContext();
1059 gl_->RateLimitOffscreenContextCHROMIUM();
1060 }
1061
1062 WebKit::WebString WebGraphicsContext3DInProcessCommandBufferImpl::
711 getRequestableExtensionsCHROMIUM() { 1063 getRequestableExtensionsCHROMIUM() {
712 return WebString(); 1064 ClearContext();
713 } 1065 return WebKit::WebString::fromUTF8(
714 1066 gl_->GetRequestableExtensionsCHROMIUM());
715 void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM(co nst char*) { 1067 }
1068
1069 void WebGraphicsContext3DInProcessCommandBufferImpl::requestExtensionCHROMIUM(
1070 const char* extension) {
1071 ClearContext();
1072 gl_->RequestExtensionCHROMIUM(extension);
716 } 1073 }
717 1074
718 void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM( 1075 void WebGraphicsContext3DInProcessCommandBufferImpl::blitFramebufferCHROMIUM(
719 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1, 1076 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
720 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1, 1077 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
721 WGC3Dbitfield mask, WGC3Denum filter) { 1078 WGC3Dbitfield mask, WGC3Denum filter) {
722 } 1079 ClearContext();
723 1080 gl_->BlitFramebufferEXT(
724 void WebGraphicsContext3DInProcessCommandBufferImpl::renderbufferStorageMultisam pleCHROMIUM( 1081 srcX0, srcY0, srcX1, srcY1,
725 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat, 1082 dstX0, dstY0, dstX1, dstY1,
726 WGC3Dsizei width, WGC3Dsizei height) { 1083 mask, filter);
1084 }
1085
1086 void WebGraphicsContext3DInProcessCommandBufferImpl::
1087 renderbufferStorageMultisampleCHROMIUM(
1088 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat,
1089 WGC3Dsizei width, WGC3Dsizei height) {
1090 ClearContext();
1091 gl_->RenderbufferStorageMultisampleEXT(
1092 target, samples, internalformat, width, height);
727 } 1093 }
728 1094
729 // Helper macros to reduce the amount of code. 1095 // Helper macros to reduce the amount of code.
730 1096
731 #define DELEGATE_TO_GL(name, glname) \ 1097 #define DELEGATE_TO_GL(name, glname) \
732 void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \ 1098 void WebGraphicsContext3DInProcessCommandBufferImpl::name() { \
733 makeContextCurrent(); \ 1099 ClearContext(); \
734 gl##glname(); \ 1100 gl_->glname(); \
735 } 1101 }
736 1102
737 #define DELEGATE_TO_GL_1(name, glname, t1) \ 1103 #define DELEGATE_TO_GL_1(name, glname, t1) \
738 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1104 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \
739 makeContextCurrent(); \ 1105 ClearContext(); \
740 gl##glname(a1); \ 1106 gl_->glname(a1); \
741 } 1107 }
742 1108
743 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ 1109 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \
744 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1110 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \
745 makeContextCurrent(); \ 1111 ClearContext(); \
746 return gl##glname(a1); \ 1112 return gl_->glname(a1); \
747 } 1113 }
748 1114
749 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \ 1115 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \
750 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \ 1116 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1) { \
751 makeContextCurrent(); \ 1117 ClearContext(); \
752 return gl##glname(a1) ? true : false; \ 1118 return gl_->glname(a1) ? true : false; \
753 } 1119 }
754 1120
755 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \ 1121 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \
756 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ 1122 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
757 makeContextCurrent(); \ 1123 t1 a1, t2 a2) { \
758 gl##glname(a1, a2); \ 1124 ClearContext(); \
759 } 1125 gl_->glname(a1, a2); \
760 1126 }
761 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ 1127
762 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \ 1128 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \
763 makeContextCurrent(); \ 1129 rt WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2) { \
764 return gl##glname(a1, a2); \ 1130 ClearContext(); \
765 } 1131 return gl_->glname(a1, a2); \
766 1132 }
767 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ 1133
768 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3) { \ 1134 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \
769 makeContextCurrent(); \ 1135 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
770 gl##glname(a1, a2, a3); \ 1136 t1 a1, t2 a2, t3 a3) { \
771 } 1137 ClearContext(); \
772 1138 gl_->glname(a1, a2, a3); \
773 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ 1139 }
774 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4) { \ 1140
775 makeContextCurrent(); \ 1141 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \
776 gl##glname(a1, a2, a3, a4); \ 1142 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
777 } 1143 t1 a1, t2 a2, t3 a3, t4 a4) { \
778 1144 ClearContext(); \
779 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ 1145 gl_->glname(a1, a2, a3, a4); \
780 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1146 }
781 t5 a5) { \ 1147
782 makeContextCurrent(); \ 1148 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \
783 gl##glname(a1, a2, a3, a4, a5); \ 1149 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
784 } 1150 t1 a1, t2 a2, t3 a3, \
785 1151 t4 a4, t5 a5) { \
786 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ 1152 ClearContext(); \
787 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1153 gl_->glname(a1, a2, a3, a4, a5); \
788 t5 a5, t6 a6) { \ 1154 }
789 makeContextCurrent(); \ 1155
790 gl##glname(a1, a2, a3, a4, a5, a6); \ 1156 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \
791 } 1157 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
792 1158 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \
793 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ 1159 ClearContext(); \
794 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1160 gl_->glname(a1, a2, a3, a4, a5, a6); \
795 t5 a5, t6 a6, t7 a7) { \ 1161 }
796 makeContextCurrent(); \ 1162
797 gl##glname(a1, a2, a3, a4, a5, a6, a7); \ 1163 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \
798 } 1164 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
799 1165 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) { \
800 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ 1166 ClearContext(); \
801 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1167 gl_->glname(a1, a2, a3, a4, a5, a6, a7); \
802 t5 a5, t6 a6, t7 a7, t8 a8) { \ 1168 }
803 makeContextCurrent(); \ 1169
804 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ 1170 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \
805 } 1171 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
806 1172 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) { \
807 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ 1173 ClearContext(); \
808 void WebGraphicsContext3DInProcessCommandBufferImpl::name(t1 a1, t2 a2, t3 a3, t 4 a4, \ 1174 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8); \
809 t5 a5, t6 a6, t7 a7, t8 a8, \ 1175 }
810 t9 a9) { \ 1176
811 makeContextCurrent(); \ 1177 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
812 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ 1178 void WebGraphicsContext3DInProcessCommandBufferImpl::name( \
813 } 1179 t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) { \
814 1180 ClearContext(); \
815 void WebGraphicsContext3DInProcessCommandBufferImpl::activeTexture(WGC3Denum tex ture) { 1181 gl_->glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \
816 // FIXME: query number of textures available. 1182 }
817 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) 1183
818 // FIXME: raise exception. 1184 DELEGATE_TO_GL_1(activeTexture, ActiveTexture, WGC3Denum)
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::getProgramInfo Log(
1128 WebGLId program) { 1397 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::getShaderInfoL og(
1150 if (result != shader_source_map_.end()) { 1421 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::getShaderSourc e(
1208 makeContextCurrent(); 1440 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::getVertexAttribOff set(
1266 WGC3Duint index, WGC3Denum pname) { 1485 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 ClearContext();
1576 1743 gl_->CopyTextureToParentTextureCHROMIUM(texture, parentTexture);
1577 ShBuiltInResources resources; 1744 gl_->Flush();
1578 ShInitBuiltInResources(&resources);
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 } 1745 }
1598 1746
1599 void WebGraphicsContext3DInProcessCommandBufferImpl::AngleDestroyCompilers() { 1747 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 } 1748 }
1609 1749
1610 bool WebGraphicsContext3DInProcessCommandBufferImpl::AngleValidateShaderSource( 1750 void WebGraphicsContext3DInProcessCommandBufferImpl::setContextLostCallback(
1611 ShaderSourceEntry* entry) { 1751 WebGraphicsContext3D::WebGraphicsContextLostCallback* cb)
1612 entry->is_valid = false; 1752 {
1613 entry->translated_source.reset(); 1753 context_lost_callback_ = cb;
1614 entry->log.reset(); 1754 }
1615 1755
1616 ShHandle compiler = 0; 1756 void WebGraphicsContext3DInProcessCommandBufferImpl::OnContextLost() {
1617 switch (entry->type) { 1757 if (context_lost_callback_) {
1618 case GL_FRAGMENT_SHADER: 1758 context_lost_callback_->onContextLost();
1619 compiler = fragment_compiler_;
1620 break;
1621 case GL_VERTEX_SHADER:
1622 compiler = vertex_compiler_;
1623 break;
1624 } 1759 }
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 } 1760 }
1659 1761
1660 } // namespace gpu 1762 } // namespace gpu
1661 } // namespace webkit 1763 } // namespace webkit
1662 1764
1765 #endif // defined(ENABLE_GPU)
1766
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