Display new Autofill UI Contents in Views
[chromium-blink-merge.git] / webkit / gpu / webgraphicscontext3d_in_process_impl.cc
blob6decabf44ec26b556224754ab20e10ea6dbabd4d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
7 #include <string.h>
9 #include <algorithm>
10 #include <string>
11 #include <vector>
13 #include "base/lazy_instance.h"
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/string_split.h"
17 #include "base/synchronization/lock.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
21 #include "ui/gl/gl_bindings.h"
22 #include "ui/gl/gl_bindings_skia_in_process.h"
23 #include "ui/gl/gl_context.h"
24 #include "ui/gl/gl_implementation.h"
25 #include "ui/gl/gl_surface.h"
27 namespace webkit {
28 namespace gpu {
30 enum {
31 MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB,
32 MAX_VARYING_VECTORS = 0x8DFC,
33 MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD
36 struct WebGraphicsContext3DInProcessImpl::ShaderSourceEntry {
37 explicit ShaderSourceEntry(WGC3Denum shader_type)
38 : type(shader_type),
39 is_valid(false) {
42 WGC3Denum type;
43 scoped_array<char> source;
44 scoped_array<char> log;
45 scoped_array<char> translated_source;
46 bool is_valid;
49 WebGraphicsContext3DInProcessImpl::WebGraphicsContext3DInProcessImpl(
50 gfx::GLSurface* surface,
51 gfx::GLContext* context,
52 bool render_directly_to_web_view)
53 : initialized_(false),
54 render_directly_to_web_view_(render_directly_to_web_view),
55 is_gles2_(false),
56 have_ext_framebuffer_object_(false),
57 have_ext_framebuffer_multisample_(false),
58 have_angle_framebuffer_multisample_(false),
59 texture_(0),
60 fbo_(0),
61 depth_stencil_buffer_(0),
62 cached_width_(0),
63 cached_height_(0),
64 multisample_fbo_(0),
65 multisample_depth_stencil_buffer_(0),
66 multisample_color_buffer_(0),
67 bound_fbo_(0),
68 bound_texture_(0),
69 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
70 scanline_(0),
71 #endif
72 gl_context_(context),
73 gl_surface_(surface),
74 fragment_compiler_(0),
75 vertex_compiler_(0) {
78 // All instances in a process that share resources are in the same share group.
79 static base::LazyInstance<
80 std::set<WebGraphicsContext3DInProcessImpl*> >
81 g_all_shared_contexts = LAZY_INSTANCE_INITIALIZER;
82 static base::LazyInstance<base::Lock>::Leaky
83 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER;
85 WebGraphicsContext3DInProcessImpl::~WebGraphicsContext3DInProcessImpl() {
86 base::AutoLock a(g_all_shared_contexts_lock.Get());
87 g_all_shared_contexts.Pointer()->erase(this);
89 if (!initialized_)
90 return;
92 makeContextCurrent();
94 if (attributes_.antialias) {
95 glDeleteRenderbuffersEXT(1, &multisample_color_buffer_);
96 if (attributes_.depth || attributes_.stencil)
97 glDeleteRenderbuffersEXT(1, &multisample_depth_stencil_buffer_);
98 glDeleteFramebuffersEXT(1, &multisample_fbo_);
99 } else {
100 if (attributes_.depth || attributes_.stencil)
101 glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_);
103 glDeleteTextures(1, &texture_);
104 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
105 if (scanline_)
106 delete[] scanline_;
107 #endif
108 glDeleteFramebuffersEXT(1, &fbo_);
110 gl_context_->ReleaseCurrent(gl_surface_.get());
111 gl_context_->Destroy();
112 gl_surface_->Destroy();
114 for (ShaderSourceMap::iterator ii = shader_source_map_.begin();
115 ii != shader_source_map_.end(); ++ii) {
116 if (ii->second)
117 delete ii->second;
119 AngleDestroyCompilers();
122 WebGraphicsContext3DInProcessImpl*
123 WebGraphicsContext3DInProcessImpl::CreateForWebView(
124 WebGraphicsContext3D::Attributes attributes,
125 bool render_directly_to_web_view) {
126 if (!gfx::GLSurface::InitializeOneOff())
127 return NULL;
129 gfx::GLShareGroup* share_group = NULL;
131 if (attributes.shareResources) {
132 WebGraphicsContext3DInProcessImpl* context_impl =
133 g_all_shared_contexts.Pointer()->empty() ?
134 NULL : *g_all_shared_contexts.Pointer()->begin();
135 if (context_impl)
136 share_group = context_impl->gl_context_->share_group();
139 // This implementation always renders offscreen regardless of whether
140 // render_directly_to_web_view is true. Both DumpRenderTree and test_shell
141 // paint first to an intermediate offscreen buffer and from there to the
142 // window, and WebViewImpl::paint already correctly handles the case where the
143 // compositor is active but the output needs to go to a WebCanvas.
144 scoped_refptr<gfx::GLSurface> gl_surface =
145 gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
147 if (!gl_surface.get())
148 return NULL;
150 // TODO(kbr): This implementation doesn't yet support lost contexts
151 // and therefore can't yet properly support GPU switching.
152 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
154 scoped_refptr<gfx::GLContext> gl_context = gfx::GLContext::CreateGLContext(
155 share_group,
156 gl_surface.get(),
157 gpu_preference);
159 if (!gl_context.get())
160 return NULL;
162 scoped_ptr<WebGraphicsContext3DInProcessImpl> context(
163 new WebGraphicsContext3DInProcessImpl(
164 gl_surface.get(), gl_context.get(), render_directly_to_web_view));
165 if (!context->Initialize(attributes))
166 return NULL;
167 return context.release();
170 WebGraphicsContext3DInProcessImpl*
171 WebGraphicsContext3DInProcessImpl::CreateForWindow(
172 WebGraphicsContext3D::Attributes attributes,
173 gfx::AcceleratedWidget window,
174 gfx::GLShareGroup* share_group) {
175 if (!gfx::GLSurface::InitializeOneOff())
176 return NULL;
178 scoped_refptr<gfx::GLSurface> gl_surface =
179 gfx::GLSurface::CreateViewGLSurface(false, window);
180 if (!gl_surface.get())
181 return NULL;
183 gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
185 scoped_refptr<gfx::GLContext> gl_context = gfx::GLContext::CreateGLContext(
186 share_group,
187 gl_surface.get(),
188 gpu_preference);
189 if (!gl_context.get())
190 return NULL;
191 scoped_ptr<WebGraphicsContext3DInProcessImpl> context(
192 new WebGraphicsContext3DInProcessImpl(
193 gl_surface.get(), gl_context.get(), true));
194 if (!context->Initialize(attributes))
195 return NULL;
196 return context.release();
199 bool WebGraphicsContext3DInProcessImpl::Initialize(
200 WebGraphicsContext3D::Attributes attributes) {
201 is_gles2_ = gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
204 attributes_ = attributes;
206 // FIXME: for the moment we disable multisampling for the compositor.
207 // It actually works in this implementation, but there are a few
208 // considerations. First, we likely want to reduce the fuzziness in
209 // these tests as much as possible because we want to run pixel tests.
210 // Second, Mesa's multisampling doesn't seem to antialias straight
211 // edges in some CSS 3D samples. Third, we don't have multisampling
212 // support for the compositor in the normal case at the time of this
213 // writing.
214 if (render_directly_to_web_view_)
215 attributes_.antialias = false;
217 if (!gl_context_->MakeCurrent(gl_surface_.get())) {
218 gl_context_ = NULL;
219 return false;
222 const char* extensions =
223 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
224 DCHECK(extensions);
225 have_ext_framebuffer_object_ =
226 strstr(extensions, "GL_EXT_framebuffer_object") != NULL;
227 have_ext_framebuffer_multisample_ =
228 strstr(extensions, "GL_EXT_framebuffer_multisample") != NULL;
229 have_angle_framebuffer_multisample_ =
230 strstr(extensions, "GL_ANGLE_framebuffer_multisample") != NULL;
232 ValidateAttributes();
234 if (!is_gles2_) {
235 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
236 glEnable(GL_POINT_SPRITE);
239 if (!AngleCreateCompilers()) {
240 AngleDestroyCompilers();
241 return false;
244 initialized_ = true;
245 gl_context_->ReleaseCurrent(gl_surface_.get());
247 if (attributes_.shareResources)
248 g_all_shared_contexts.Pointer()->insert(this);
250 return true;
253 void WebGraphicsContext3DInProcessImpl::ValidateAttributes() {
254 const char* extensions =
255 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
257 if (attributes_.stencil) {
258 if (strstr(extensions, "GL_OES_packed_depth_stencil") ||
259 strstr(extensions, "GL_EXT_packed_depth_stencil")) {
260 if (!attributes_.depth) {
261 attributes_.depth = true;
263 } else {
264 attributes_.stencil = false;
267 if (attributes_.antialias) {
268 bool isValidVendor = true;
269 #if defined(OS_MACOSX)
270 // Currently in Mac we only turn on antialias if vendor is NVIDIA.
271 const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
272 if (!strstr(vendor, "NVIDIA"))
273 isValidVendor = false;
274 #endif
275 if (!(isValidVendor &&
276 (have_ext_framebuffer_multisample_ ||
277 (have_angle_framebuffer_multisample_ &&
278 strstr(extensions, "GL_OES_rgb8_rgba8")))))
279 attributes_.antialias = false;
281 // Don't antialias when using Mesa to ensure more reliable testing and
282 // because it doesn't appear to multisample straight lines correctly.
283 const char* renderer =
284 reinterpret_cast<const char*>(glGetString(GL_RENDERER));
285 if (!strncmp(renderer, "Mesa", 4)) {
286 attributes_.antialias = false;
291 void WebGraphicsContext3DInProcessImpl::ResolveMultisampledFramebuffer(
292 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) {
293 if (attributes_.antialias) {
294 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, multisample_fbo_);
295 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo_);
296 if (have_ext_framebuffer_multisample_) {
297 glBlitFramebufferEXT(x, y,
298 x + width, y + height,
299 x, y,
300 x + width, y + height,
301 GL_COLOR_BUFFER_BIT, GL_NEAREST);
302 } else {
303 DCHECK(have_angle_framebuffer_multisample_);
304 glBlitFramebufferANGLE(x, y,
305 x + width, y + height,
306 x, y,
307 x + width, y + height,
308 GL_COLOR_BUFFER_BIT, GL_NEAREST);
310 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
314 bool WebGraphicsContext3DInProcessImpl::makeContextCurrent() {
315 return gl_context_->MakeCurrent(gl_surface_.get());
318 int WebGraphicsContext3DInProcessImpl::width() {
319 return cached_width_;
322 int WebGraphicsContext3DInProcessImpl::height() {
323 return cached_height_;
326 bool WebGraphicsContext3DInProcessImpl::isGLES2Compliant() {
327 return is_gles2_;
330 bool WebGraphicsContext3DInProcessImpl::setParentContext(
331 WebGraphicsContext3D* parent_context) {
332 return false;
335 WebGLId WebGraphicsContext3DInProcessImpl::getPlatformTextureId() {
336 return texture_;
339 void WebGraphicsContext3DInProcessImpl::prepareTexture() {
340 if (!gl_surface_->IsOffscreen()) {
341 gl_surface_->SwapBuffers();
342 } else if (!render_directly_to_web_view_) {
343 // We need to prepare our rendering results for the compositor.
344 makeContextCurrent();
345 ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_);
349 void WebGraphicsContext3DInProcessImpl::postSubBufferCHROMIUM(
350 int x, int y, int width, int height) {
351 DCHECK(gl_surface_->HasExtension("GL_CHROMIUM_post_sub_buffer"));
352 gl_surface_->PostSubBuffer(x, y, width, height);
355 namespace {
357 int CreateTextureObject(GLenum target) {
358 GLuint texture = 0;
359 glGenTextures(1, &texture);
360 glBindTexture(target, texture);
361 glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
362 glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
363 return texture;
366 } // anonymous namespace
368 void WebGraphicsContext3DInProcessImpl::reshape(int width, int height) {
369 cached_width_ = width;
370 cached_height_ = height;
371 makeContextCurrent();
373 bool must_restore_fbo = false;
374 if (gl_surface_->IsOffscreen())
375 must_restore_fbo = AllocateOffscreenFrameBuffer(width, height);
377 gl_surface_->Resize(gfx::Size(width, height));
378 ClearRenderTarget();
380 if (must_restore_fbo)
381 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
383 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
384 if (scanline_) {
385 delete[] scanline_;
386 scanline_ = 0;
388 scanline_ = new unsigned char[width * 4];
389 #endif // FLIP_FRAMEBUFFER_VERTICALLY
392 bool WebGraphicsContext3DInProcessImpl::AllocateOffscreenFrameBuffer(
393 int width, int height) {
394 GLenum target = GL_TEXTURE_2D;
396 if (!texture_) {
397 // Generate the texture object
398 texture_ = CreateTextureObject(target);
399 // Generate the framebuffer object
400 glGenFramebuffersEXT(1, &fbo_);
401 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
402 bound_fbo_ = fbo_;
403 if (attributes_.depth || attributes_.stencil)
404 glGenRenderbuffersEXT(1, &depth_stencil_buffer_);
405 // Generate the multisample framebuffer object
406 if (attributes_.antialias) {
407 glGenFramebuffersEXT(1, &multisample_fbo_);
408 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_);
409 bound_fbo_ = multisample_fbo_;
410 glGenRenderbuffersEXT(1, &multisample_color_buffer_);
411 if (attributes_.depth || attributes_.stencil)
412 glGenRenderbuffersEXT(1, &multisample_depth_stencil_buffer_);
416 GLint internal_multisampled_color_format = 0;
417 GLint internal_color_format = 0;
418 GLint color_format = 0;
419 GLint internal_depth_stencil_format = 0;
420 if (attributes_.alpha) {
421 // GL_RGBA8_OES == GL_RGBA8
422 internal_multisampled_color_format = GL_RGBA8;
423 internal_color_format = is_gles2_ ? GL_RGBA : GL_RGBA8;
424 color_format = GL_RGBA;
425 } else {
426 // GL_RGB8_OES == GL_RGB8
427 internal_multisampled_color_format = GL_RGB8;
428 internal_color_format = is_gles2_ ? GL_RGB : GL_RGB8;
429 color_format = GL_RGB;
431 if (attributes_.stencil || attributes_.depth) {
432 // We don't allow the logic where stencil is required and depth is not.
433 // See GraphicsContext3DInternal constructor.
434 if (attributes_.stencil && attributes_.depth) {
435 internal_depth_stencil_format = GL_DEPTH24_STENCIL8_EXT;
436 } else {
437 if (is_gles2_)
438 internal_depth_stencil_format = GL_DEPTH_COMPONENT16;
439 else
440 internal_depth_stencil_format = GL_DEPTH_COMPONENT;
444 bool must_restore_fbo = false;
446 // Resize multisampling FBO
447 if (attributes_.antialias) {
448 GLint max_sample_count;
449 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
450 GLint sample_count = std::min(8, max_sample_count);
451 if (bound_fbo_ != multisample_fbo_) {
452 must_restore_fbo = true;
453 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_);
455 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, multisample_color_buffer_);
456 if (have_ext_framebuffer_multisample_) {
457 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
458 sample_count,
459 internal_multisampled_color_format,
460 width,
461 height);
462 } else {
463 DCHECK(have_angle_framebuffer_multisample_);
464 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT,
465 sample_count,
466 internal_multisampled_color_format,
467 width,
468 height);
470 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
471 GL_COLOR_ATTACHMENT0_EXT,
472 GL_RENDERBUFFER_EXT,
473 multisample_color_buffer_);
474 if (attributes_.stencil || attributes_.depth) {
475 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
476 multisample_depth_stencil_buffer_);
477 if (have_ext_framebuffer_multisample_) {
478 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
479 sample_count,
480 internal_depth_stencil_format,
481 width,
482 height);
483 } else {
484 DCHECK(have_angle_framebuffer_multisample_);
485 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT,
486 sample_count,
487 internal_depth_stencil_format,
488 width,
489 height);
491 if (attributes_.stencil)
492 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
493 GL_STENCIL_ATTACHMENT_EXT,
494 GL_RENDERBUFFER_EXT,
495 multisample_depth_stencil_buffer_);
496 if (attributes_.depth)
497 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
498 GL_DEPTH_ATTACHMENT_EXT,
499 GL_RENDERBUFFER_EXT,
500 multisample_depth_stencil_buffer_);
502 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
503 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
504 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
505 LOG(ERROR) << "Multisampling framebuffer was incomplete";
507 // FIXME: cleanup.
508 NOTIMPLEMENTED();
512 // Resize regular FBO
513 if (bound_fbo_ != fbo_) {
514 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
515 must_restore_fbo = true;
517 glBindTexture(target, texture_);
518 glTexImage2D(target, 0, internal_color_format,
519 width, height,
520 0, color_format, GL_UNSIGNED_BYTE, 0);
521 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
522 GL_COLOR_ATTACHMENT0_EXT,
523 target,
524 texture_,
526 glBindTexture(target, 0);
527 if (!attributes_.antialias && (attributes_.stencil || attributes_.depth)) {
528 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer_);
529 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
530 internal_depth_stencil_format,
531 width, height);
532 if (attributes_.stencil)
533 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
534 GL_STENCIL_ATTACHMENT_EXT,
535 GL_RENDERBUFFER_EXT,
536 depth_stencil_buffer_);
537 if (attributes_.depth)
538 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
539 GL_DEPTH_ATTACHMENT_EXT,
540 GL_RENDERBUFFER_EXT,
541 depth_stencil_buffer_);
542 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
544 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
545 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
546 LOG(ERROR) << "Framebuffer was incomplete";
548 // FIXME: cleanup.
549 NOTIMPLEMENTED();
552 if (attributes_.antialias) {
553 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, multisample_fbo_);
554 if (bound_fbo_ == multisample_fbo_)
555 must_restore_fbo = false;
557 return must_restore_fbo;
560 void WebGraphicsContext3DInProcessImpl::ClearRenderTarget() {
561 // Initialize renderbuffers to 0.
562 GLfloat clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
563 GLint clearStencil = 0;
564 GLboolean colorMask[] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
565 GLboolean depthMask = GL_TRUE;
566 GLuint stencilMask = 0xffffffff;
567 GLboolean isScissorEnabled = GL_FALSE;
568 GLboolean isDitherEnabled = GL_FALSE;
569 GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
570 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
571 glClearColor(0, 0, 0, 0);
572 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
573 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
574 if (attributes_.depth) {
575 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
576 glClearDepth(1);
577 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
578 glDepthMask(GL_TRUE);
579 clearMask |= GL_DEPTH_BUFFER_BIT;
581 if (attributes_.stencil) {
582 glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil);
583 glClearStencil(0);
584 glGetIntegerv(GL_STENCIL_WRITEMASK,
585 reinterpret_cast<GLint*>(&stencilMask));
586 glStencilMaskSeparate(GL_FRONT, 0xffffffff);
587 clearMask |= GL_STENCIL_BUFFER_BIT;
589 isScissorEnabled = glIsEnabled(GL_SCISSOR_TEST);
590 glDisable(GL_SCISSOR_TEST);
591 isDitherEnabled = glIsEnabled(GL_DITHER);
592 glDisable(GL_DITHER);
594 glClear(clearMask);
596 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
597 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
598 if (attributes_.depth) {
599 glClearDepth(clearDepth);
600 glDepthMask(depthMask);
602 if (attributes_.stencil) {
603 glClearStencil(clearStencil);
604 glStencilMaskSeparate(GL_FRONT, stencilMask);
606 if (isScissorEnabled)
607 glEnable(GL_SCISSOR_TEST);
608 else
609 glDisable(GL_SCISSOR_TEST);
610 if (isDitherEnabled)
611 glEnable(GL_DITHER);
612 else
613 glDisable(GL_DITHER);
616 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
617 void WebGraphicsContext3DInProcessImpl::FlipVertically(
618 unsigned char* framebuffer, unsigned int width, unsigned int height) {
619 unsigned char* scanline = scanline_;
620 if (!scanline)
621 return;
622 unsigned int row_bytes = width * 4;
623 unsigned int count = height / 2;
624 for (unsigned int i = 0; i < count; i++) {
625 unsigned char* row_a = framebuffer + i * row_bytes;
626 unsigned char* row_b = framebuffer + (height - i - 1) * row_bytes;
627 // FIXME: this is where the multiplication of the alpha
628 // channel into the color buffer will need to occur if the
629 // user specifies the "premultiplyAlpha" flag in the context
630 // creation attributes.
631 memcpy(scanline, row_b, row_bytes);
632 memcpy(row_b, row_a, row_bytes);
633 memcpy(row_a, scanline, row_bytes);
636 #endif
638 bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
639 unsigned char* pixels, size_t bufferSize, WebGLId framebuffer,
640 int width, int height) {
641 if (bufferSize != static_cast<size_t>(4 * width * height))
642 return false;
644 makeContextCurrent();
646 // Earlier versions of this code used the GPU to flip the
647 // framebuffer vertically before reading it back for compositing
648 // via software. This code was quite complicated, used a lot of
649 // GPU memory, and didn't provide an obvious speedup. Since this
650 // vertical flip is only a temporary solution anyway until Chrome
651 // is fully GPU composited, it wasn't worth the complexity.
653 // In this implementation fbo_, not 0, is the drawing buffer, so
654 // special-case that.
655 if (framebuffer == 0)
656 framebuffer = fbo_;
658 if (framebuffer == fbo_)
659 ResolveMultisampledFramebuffer(0, 0, width, height);
660 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
662 GLint pack_alignment = 4;
663 bool must_restore_pack_alignment = false;
664 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
665 if (pack_alignment > 4) {
666 glPixelStorei(GL_PACK_ALIGNMENT, 4);
667 must_restore_pack_alignment = true;
670 if (is_gles2_) {
671 // FIXME: consider testing for presence of GL_OES_read_format
672 // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here
673 // directly.
674 glReadPixels(0, 0, width, height,
675 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
676 for (size_t i = 0; i < bufferSize; i += 4) {
677 std::swap(pixels[i], pixels[i + 2]);
679 } else {
680 glReadPixels(0, 0, width, height,
681 GL_BGRA, GL_UNSIGNED_BYTE, pixels);
684 if (must_restore_pack_alignment)
685 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
687 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
689 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
690 if (pixels)
691 FlipVertically(pixels, width, height);
692 #endif
694 return true;
697 bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
698 unsigned char* pixels, size_t bufferSize) {
699 return readBackFramebuffer(pixels, bufferSize, fbo_, width(), height());
702 void WebGraphicsContext3DInProcessImpl::synthesizeGLError(WGC3Denum error) {
703 if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) {
704 synthetic_errors_set_.insert(error);
705 synthetic_errors_list_.push_back(error);
709 void* WebGraphicsContext3DInProcessImpl::mapBufferSubDataCHROMIUM(
710 WGC3Denum target, WGC3Dintptr offset,
711 WGC3Dsizeiptr size, WGC3Denum access) {
712 return 0;
715 void WebGraphicsContext3DInProcessImpl::unmapBufferSubDataCHROMIUM(
716 const void* mem) {
719 void* WebGraphicsContext3DInProcessImpl::mapTexSubImage2DCHROMIUM(
720 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
721 WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type,
722 WGC3Denum access) {
723 return 0;
726 void WebGraphicsContext3DInProcessImpl::unmapTexSubImage2DCHROMIUM(
727 const void* mem) {
730 void WebGraphicsContext3DInProcessImpl::setVisibilityCHROMIUM(bool visible) {
733 void WebGraphicsContext3DInProcessImpl::
734 setMemoryAllocationChangedCallbackCHROMIUM(
735 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {
738 void WebGraphicsContext3DInProcessImpl::discardFramebufferEXT(
739 WGC3Denum target, WGC3Dsizei numAttachments, const WGC3Denum* attachments) {
742 void WebGraphicsContext3DInProcessImpl::ensureFramebufferCHROMIUM() {
745 void WebGraphicsContext3DInProcessImpl::copyTextureToParentTextureCHROMIUM(
746 WebGLId id, WebGLId id2) {
747 NOTIMPLEMENTED();
750 void WebGraphicsContext3DInProcessImpl::bindUniformLocationCHROMIUM(
751 WebGLId program, WGC3Dint location, const WGC3Dchar* uniform) {
752 NOTIMPLEMENTED();
755 void WebGraphicsContext3DInProcessImpl::genMailboxCHROMIUM(
756 WGC3Dbyte* mailbox) {
757 NOTIMPLEMENTED();
760 void WebGraphicsContext3DInProcessImpl::produceTextureCHROMIUM(
761 WGC3Denum target, const WGC3Dbyte* mailbox) {
762 NOTIMPLEMENTED();
765 void WebGraphicsContext3DInProcessImpl::consumeTextureCHROMIUM(
766 WGC3Denum target, const WGC3Dbyte* mailbox) {
767 NOTIMPLEMENTED();
770 WebString WebGraphicsContext3DInProcessImpl::
771 getRequestableExtensionsCHROMIUM() {
772 return WebString();
775 void WebGraphicsContext3DInProcessImpl::requestExtensionCHROMIUM(const char*) {
778 void WebGraphicsContext3DInProcessImpl::blitFramebufferCHROMIUM(
779 WGC3Dint srcX0, WGC3Dint srcY0, WGC3Dint srcX1, WGC3Dint srcY1,
780 WGC3Dint dstX0, WGC3Dint dstY0, WGC3Dint dstX1, WGC3Dint dstY1,
781 WGC3Dbitfield mask, WGC3Denum filter) {
784 void WebGraphicsContext3DInProcessImpl::renderbufferStorageMultisampleCHROMIUM(
785 WGC3Denum target, WGC3Dsizei samples, WGC3Denum internalformat,
786 WGC3Dsizei width, WGC3Dsizei height) {
789 // Helper macros to reduce the amount of code.
791 #define DELEGATE_TO_GL(name, glname) \
792 void WebGraphicsContext3DInProcessImpl::name() { \
793 makeContextCurrent(); \
794 gl##glname(); \
797 #define DELEGATE_TO_GL_1(name, glname, t1) \
798 void WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
799 makeContextCurrent(); \
800 gl##glname(a1); \
803 #define DELEGATE_TO_GL_1R(name, glname, t1, rt) \
804 rt WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
805 makeContextCurrent(); \
806 return gl##glname(a1); \
809 #define DELEGATE_TO_GL_1RB(name, glname, t1, rt) \
810 rt WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
811 makeContextCurrent(); \
812 return gl##glname(a1) ? true : false; \
815 #define DELEGATE_TO_GL_2(name, glname, t1, t2) \
816 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2) { \
817 makeContextCurrent(); \
818 gl##glname(a1, a2); \
821 #define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \
822 rt WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2) { \
823 makeContextCurrent(); \
824 return gl##glname(a1, a2); \
827 #define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \
828 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3) { \
829 makeContextCurrent(); \
830 gl##glname(a1, a2, a3); \
833 #define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \
834 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) { \
835 makeContextCurrent(); \
836 gl##glname(a1, a2, a3, a4); \
839 #define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \
840 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
841 t5 a5) { \
842 makeContextCurrent(); \
843 gl##glname(a1, a2, a3, a4, a5); \
846 #define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \
847 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
848 t5 a5, t6 a6) { \
849 makeContextCurrent(); \
850 gl##glname(a1, a2, a3, a4, a5, a6); \
853 #define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \
854 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
855 t5 a5, t6 a6, t7 a7) { \
856 makeContextCurrent(); \
857 gl##glname(a1, a2, a3, a4, a5, a6, a7); \
860 #define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \
861 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
862 t5 a5, t6 a6, t7 a7, t8 a8) { \
863 makeContextCurrent(); \
864 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \
867 #define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
868 void WebGraphicsContext3DInProcessImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, \
869 t5 a5, t6 a6, t7 a7, t8 a8, \
870 t9 a9) { \
871 makeContextCurrent(); \
872 gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \
875 void WebGraphicsContext3DInProcessImpl::activeTexture(WGC3Denum texture) {
876 // FIXME: query number of textures available.
877 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32)
878 // FIXME: raise exception.
879 return;
881 makeContextCurrent();
882 glActiveTexture(texture);
885 DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId)
887 DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation,
888 WebGLId, WGC3Duint, const WGC3Dchar*)
890 DELEGATE_TO_GL_2(bindBuffer, BindBuffer, WGC3Denum, WebGLId);
892 void WebGraphicsContext3DInProcessImpl::bindFramebuffer(
893 WGC3Denum target, WebGLId framebuffer) {
894 makeContextCurrent();
895 if (!framebuffer)
896 framebuffer = (attributes_.antialias ? multisample_fbo_ : fbo_);
897 if (framebuffer != bound_fbo_) {
898 glBindFramebufferEXT(target, framebuffer);
899 bound_fbo_ = framebuffer;
903 DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, WGC3Denum, WebGLId)
905 void WebGraphicsContext3DInProcessImpl::bindTexture(
906 WGC3Denum target, WebGLId texture) {
907 makeContextCurrent();
908 glBindTexture(target, texture);
909 bound_texture_ = texture;
912 DELEGATE_TO_GL_4(blendColor, BlendColor,
913 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
915 DELEGATE_TO_GL_1(blendEquation, BlendEquation, WGC3Denum)
917 DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate,
918 WGC3Denum, WGC3Denum)
920 DELEGATE_TO_GL_2(blendFunc, BlendFunc, WGC3Denum, WGC3Denum)
922 DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate,
923 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
925 DELEGATE_TO_GL_4(bufferData, BufferData,
926 WGC3Denum, WGC3Dsizeiptr, const void*, WGC3Denum)
928 DELEGATE_TO_GL_4(bufferSubData, BufferSubData,
929 WGC3Denum, WGC3Dintptr, WGC3Dsizeiptr, const void*)
931 DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT,
932 WGC3Denum, WGC3Denum)
934 DELEGATE_TO_GL_1(clear, Clear, WGC3Dbitfield)
936 DELEGATE_TO_GL_4(clearColor, ClearColor,
937 WGC3Dclampf, WGC3Dclampf, WGC3Dclampf, WGC3Dclampf)
939 DELEGATE_TO_GL_1(clearDepth, ClearDepth, WGC3Dclampf)
941 DELEGATE_TO_GL_1(clearStencil, ClearStencil, WGC3Dint)
943 DELEGATE_TO_GL_4(colorMask, ColorMask,
944 WGC3Dboolean, WGC3Dboolean, WGC3Dboolean, WGC3Dboolean)
946 void WebGraphicsContext3DInProcessImpl::compileShader(WebGLId shader) {
947 makeContextCurrent();
949 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
950 if (result == shader_source_map_.end()) {
951 // Passing down to gl driver to generate the correct error; or the case
952 // where the shader deletion is delayed when it's attached to a program.
953 glCompileShader(shader);
954 return;
956 ShaderSourceEntry* entry = result->second;
957 DCHECK(entry);
959 if (!AngleValidateShaderSource(entry)) {
960 // Shader didn't validate; don't move forward with compiling
961 // translated source.
962 return;
965 const char* translated_source = entry->translated_source.get();
966 int shader_length = translated_source ? strlen(translated_source) : 0;
967 glShaderSource(
968 shader, 1, const_cast<const char**>(&translated_source), &shader_length);
969 glCompileShader(shader);
971 #ifndef NDEBUG
972 int compileStatus;
973 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
974 // DCHECK that ANGLE generated GLSL will be accepted by OpenGL
975 DCHECK(compileStatus == GL_TRUE);
976 #endif
979 DELEGATE_TO_GL_8(compressedTexImage2D, CompressedTexImage2D,
980 WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint,
981 WGC3Dsizei, WGC3Dsizei, const void*)
983 DELEGATE_TO_GL_9(compressedTexSubImage2D, CompressedTexSubImage2D,
984 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint,
985 WGC3Denum, WGC3Dsizei, const void*)
987 void WebGraphicsContext3DInProcessImpl::copyTexImage2D(
988 WGC3Denum target, WGC3Dint level, WGC3Denum internalformat, WGC3Dint x,
989 WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border) {
990 makeContextCurrent();
992 bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_);
993 if (needsResolve) {
994 ResolveMultisampledFramebuffer(x, y, width, height);
995 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
998 glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
1000 if (needsResolve)
1001 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
1004 void WebGraphicsContext3DInProcessImpl::copyTexSubImage2D(
1005 WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
1006 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height) {
1007 makeContextCurrent();
1009 bool needsResolve = (attributes_.antialias && bound_fbo_ == multisample_fbo_);
1010 if (needsResolve) {
1011 ResolveMultisampledFramebuffer(x, y, width, height);
1012 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
1015 glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
1017 if (needsResolve)
1018 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
1021 DELEGATE_TO_GL_1(cullFace, CullFace, WGC3Denum)
1023 DELEGATE_TO_GL_1(depthFunc, DepthFunc, WGC3Denum)
1025 DELEGATE_TO_GL_1(depthMask, DepthMask, WGC3Dboolean)
1027 DELEGATE_TO_GL_2(depthRange, DepthRange, WGC3Dclampf, WGC3Dclampf)
1029 DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId)
1031 DELEGATE_TO_GL_1(disable, Disable, WGC3Denum)
1033 DELEGATE_TO_GL_1(disableVertexAttribArray, DisableVertexAttribArray, WGC3Duint)
1035 DELEGATE_TO_GL_3(drawArrays, DrawArrays, WGC3Denum, WGC3Dint, WGC3Dsizei)
1037 void WebGraphicsContext3DInProcessImpl::drawElements(
1038 WGC3Denum mode, WGC3Dsizei count, WGC3Denum type, WGC3Dintptr offset) {
1039 makeContextCurrent();
1040 glDrawElements(mode, count, type,
1041 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1044 DELEGATE_TO_GL_1(enable, Enable, WGC3Denum)
1046 DELEGATE_TO_GL_1(enableVertexAttribArray, EnableVertexAttribArray, WGC3Duint)
1048 DELEGATE_TO_GL(finish, Finish)
1050 DELEGATE_TO_GL(flush, Flush)
1052 DELEGATE_TO_GL_4(framebufferRenderbuffer, FramebufferRenderbufferEXT,
1053 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId)
1055 DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT,
1056 WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint)
1058 DELEGATE_TO_GL_1(frontFace, FrontFace, WGC3Denum)
1060 void WebGraphicsContext3DInProcessImpl::generateMipmap(WGC3Denum target) {
1061 makeContextCurrent();
1062 if (is_gles2_ || have_ext_framebuffer_object_)
1063 glGenerateMipmapEXT(target);
1064 // FIXME: provide alternative code path? This will be unpleasant
1065 // to implement if glGenerateMipmapEXT is not available -- it will
1066 // require a texture readback and re-upload.
1069 bool WebGraphicsContext3DInProcessImpl::getActiveAttrib(
1070 WebGLId program, WGC3Duint index, ActiveInfo& info) {
1071 makeContextCurrent();
1072 if (!program) {
1073 synthesizeGLError(GL_INVALID_VALUE);
1074 return false;
1076 GLint max_name_length = -1;
1077 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_name_length);
1078 if (max_name_length < 0)
1079 return false;
1080 scoped_array<GLchar> name(new GLchar[max_name_length]);
1081 GLsizei length = 0;
1082 GLint size = -1;
1083 GLenum type = 0;
1084 glGetActiveAttrib(program, index, max_name_length,
1085 &length, &size, &type, name.get());
1086 if (size < 0) {
1087 return false;
1089 info.name = WebString::fromUTF8(name.get(), length);
1090 info.type = type;
1091 info.size = size;
1092 return true;
1095 bool WebGraphicsContext3DInProcessImpl::getActiveUniform(
1096 WebGLId program, WGC3Duint index, ActiveInfo& info) {
1097 makeContextCurrent();
1098 GLint max_name_length = -1;
1099 glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length);
1100 if (max_name_length < 0)
1101 return false;
1102 scoped_array<GLchar> name(new GLchar[max_name_length]);
1103 GLsizei length = 0;
1104 GLint size = -1;
1105 GLenum type = 0;
1106 glGetActiveUniform(program, index, max_name_length,
1107 &length, &size, &type, name.get());
1108 if (size < 0) {
1109 return false;
1111 info.name = WebString::fromUTF8(name.get(), length);
1112 info.type = type;
1113 info.size = size;
1114 return true;
1117 DELEGATE_TO_GL_4(getAttachedShaders, GetAttachedShaders,
1118 WebGLId, WGC3Dsizei, WGC3Dsizei*, WebGLId*)
1120 DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation,
1121 WebGLId, const WGC3Dchar*, WGC3Dint)
1123 DELEGATE_TO_GL_2(getBooleanv, GetBooleanv,
1124 WGC3Denum, WGC3Dboolean*)
1126 DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv,
1127 WGC3Denum, WGC3Denum, WGC3Dint*)
1129 WebGraphicsContext3D::Attributes WebGraphicsContext3DInProcessImpl::
1130 getContextAttributes() {
1131 return attributes_;
1134 WGC3Denum WebGraphicsContext3DInProcessImpl::getError() {
1135 DCHECK(synthetic_errors_list_.size() == synthetic_errors_set_.size());
1136 if (!synthetic_errors_set_.empty()) {
1137 WGC3Denum error = synthetic_errors_list_.front();
1138 synthetic_errors_list_.pop_front();
1139 synthetic_errors_set_.erase(error);
1140 return error;
1143 makeContextCurrent();
1144 return glGetError();
1147 bool WebGraphicsContext3DInProcessImpl::isContextLost() {
1148 return false;
1151 DELEGATE_TO_GL_2(getFloatv, GetFloatv, WGC3Denum, WGC3Dfloat*)
1153 void WebGraphicsContext3DInProcessImpl::getFramebufferAttachmentParameteriv(
1154 WGC3Denum target, WGC3Denum attachment,
1155 WGC3Denum pname, WGC3Dint* value) {
1156 makeContextCurrent();
1157 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
1158 attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT;
1159 // either works.
1160 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value);
1163 void WebGraphicsContext3DInProcessImpl::getIntegerv(
1164 WGC3Denum pname, WGC3Dint* value) {
1165 makeContextCurrent();
1166 if (is_gles2_) {
1167 glGetIntegerv(pname, value);
1168 return;
1170 // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and
1171 // MAX_VARYING_VECTORS because desktop GL's corresponding queries
1172 // return the number of components whereas GLES2 return the number
1173 // of vectors (each vector has 4 components). Therefore, the value
1174 // returned by desktop GL needs to be divided by 4.
1175 switch (pname) {
1176 case MAX_FRAGMENT_UNIFORM_VECTORS:
1177 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
1178 *value /= 4;
1179 break;
1180 case MAX_VERTEX_UNIFORM_VECTORS:
1181 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value);
1182 *value /= 4;
1183 break;
1184 case MAX_VARYING_VECTORS:
1185 glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
1186 *value /= 4;
1187 break;
1188 default:
1189 glGetIntegerv(pname, value);
1193 DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, WGC3Denum, WGC3Dint*)
1195 WebString WebGraphicsContext3DInProcessImpl::getProgramInfoLog(
1196 WebGLId program) {
1197 makeContextCurrent();
1198 GLint log_length;
1199 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
1200 if (!log_length)
1201 return WebString();
1202 scoped_array<GLchar> log(new GLchar[log_length]);
1203 GLsizei returned_log_length;
1204 glGetProgramInfoLog(program, log_length, &returned_log_length, log.get());
1205 DCHECK(log_length == returned_log_length + 1);
1206 WebString res = WebString::fromUTF8(log.get(), returned_log_length);
1207 return res;
1210 DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT,
1211 WGC3Denum, WGC3Denum, WGC3Dint*)
1213 void WebGraphicsContext3DInProcessImpl::getShaderiv(
1214 WebGLId shader, WGC3Denum pname, WGC3Dint* value) {
1215 makeContextCurrent();
1217 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1218 if (result != shader_source_map_.end()) {
1219 ShaderSourceEntry* entry = result->second;
1220 DCHECK(entry);
1221 switch (pname) {
1222 case GL_COMPILE_STATUS:
1223 if (!entry->is_valid) {
1224 *value = 0;
1225 return;
1227 break;
1228 case GL_INFO_LOG_LENGTH:
1229 if (!entry->is_valid) {
1230 *value = entry->log.get() ? strlen(entry->log.get()) : 0;
1231 if (*value)
1232 (*value)++;
1233 return;
1235 break;
1236 case GL_SHADER_SOURCE_LENGTH:
1237 *value = entry->source.get() ? strlen(entry->source.get()) : 0;
1238 if (*value)
1239 (*value)++;
1240 return;
1244 glGetShaderiv(shader, pname, value);
1247 DELEGATE_TO_GL_4(getShaderPrecisionFormat, GetShaderPrecisionFormat,
1248 WGC3Denum, WGC3Denum, WGC3Dint*, WGC3Dint*)
1250 WebString WebGraphicsContext3DInProcessImpl::getShaderInfoLog(WebGLId shader) {
1251 makeContextCurrent();
1253 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1254 if (result != shader_source_map_.end()) {
1255 ShaderSourceEntry* entry = result->second;
1256 DCHECK(entry);
1257 if (!entry->is_valid) {
1258 if (!entry->log.get())
1259 return WebString();
1260 WebString res = WebString::fromUTF8(
1261 entry->log.get(), strlen(entry->log.get()));
1262 return res;
1266 GLint log_length = 0;
1267 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
1268 if (log_length <= 1)
1269 return WebString();
1270 scoped_array<GLchar> log(new GLchar[log_length]);
1271 GLsizei returned_log_length;
1272 glGetShaderInfoLog(shader, log_length, &returned_log_length, log.get());
1273 DCHECK(log_length == returned_log_length + 1);
1274 WebString res = WebString::fromUTF8(log.get(), returned_log_length);
1275 return res;
1278 WebString WebGraphicsContext3DInProcessImpl::getShaderSource(WebGLId shader) {
1279 makeContextCurrent();
1281 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1282 if (result != shader_source_map_.end()) {
1283 ShaderSourceEntry* entry = result->second;
1284 DCHECK(entry);
1285 if (!entry->source.get())
1286 return WebString();
1287 WebString res = WebString::fromUTF8(
1288 entry->source.get(), strlen(entry->source.get()));
1289 return res;
1292 GLint log_length = 0;
1293 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &log_length);
1294 if (log_length <= 1)
1295 return WebString();
1296 scoped_array<GLchar> log(new GLchar[log_length]);
1297 GLsizei returned_log_length;
1298 glGetShaderSource(shader, log_length, &returned_log_length, log.get());
1299 DCHECK(log_length == returned_log_length + 1);
1300 WebString res = WebString::fromUTF8(log.get(), returned_log_length);
1301 return res;
1304 WebString WebGraphicsContext3DInProcessImpl::getString(WGC3Denum name) {
1305 makeContextCurrent();
1306 std::string result;
1307 if (name == GL_EXTENSIONS) {
1308 result = gl_context_->GetExtensions();
1309 if (!is_gles2_) {
1310 std::vector<std::string> split;
1311 base::SplitString(result, ' ', &split);
1312 if (std::find(split.begin(), split.end(), "GL_EXT_bgra") != split.end()) {
1313 // If we support GL_EXT_bgra, pretend we support a couple of GLES2
1314 // extension that are a subset of it.
1315 result += " GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra";
1318 std::string surface_extensions = gl_surface_->GetExtensions();
1319 if (!surface_extensions.empty())
1320 result += " " + surface_extensions;
1321 } else {
1322 result = reinterpret_cast<const char*>(glGetString(name));
1324 return WebString::fromUTF8(result.c_str());
1327 DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv,
1328 WGC3Denum, WGC3Denum, WGC3Dfloat*)
1330 DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv,
1331 WGC3Denum, WGC3Denum, WGC3Dint*)
1333 DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, WGC3Dint, WGC3Dfloat*)
1335 DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, WGC3Dint, WGC3Dint*)
1337 DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation,
1338 WebGLId, const WGC3Dchar*, WGC3Dint)
1340 DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv,
1341 WGC3Duint, WGC3Denum, WGC3Dfloat*)
1343 DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv,
1344 WGC3Duint, WGC3Denum, WGC3Dint*)
1346 WGC3Dsizeiptr WebGraphicsContext3DInProcessImpl::getVertexAttribOffset(
1347 WGC3Duint index, WGC3Denum pname) {
1348 makeContextCurrent();
1349 void* pointer;
1350 glGetVertexAttribPointerv(index, pname, &pointer);
1351 return static_cast<WGC3Dsizeiptr>(reinterpret_cast<intptr_t>(pointer));
1354 DELEGATE_TO_GL_2(hint, Hint, WGC3Denum, WGC3Denum)
1356 DELEGATE_TO_GL_1RB(isBuffer, IsBuffer, WebGLId, WGC3Dboolean)
1358 DELEGATE_TO_GL_1RB(isEnabled, IsEnabled, WGC3Denum, WGC3Dboolean)
1360 DELEGATE_TO_GL_1RB(isFramebuffer, IsFramebufferEXT, WebGLId, WGC3Dboolean)
1362 DELEGATE_TO_GL_1RB(isProgram, IsProgram, WebGLId, WGC3Dboolean)
1364 DELEGATE_TO_GL_1RB(isRenderbuffer, IsRenderbufferEXT, WebGLId, WGC3Dboolean)
1366 DELEGATE_TO_GL_1RB(isShader, IsShader, WebGLId, WGC3Dboolean)
1368 DELEGATE_TO_GL_1RB(isTexture, IsTexture, WebGLId, WGC3Dboolean)
1370 DELEGATE_TO_GL_1(lineWidth, LineWidth, WGC3Dfloat)
1372 DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId)
1374 DELEGATE_TO_GL_2(pixelStorei, PixelStorei, WGC3Denum, WGC3Dint)
1376 DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, WGC3Dfloat, WGC3Dfloat)
1378 void WebGraphicsContext3DInProcessImpl::readPixels(
1379 WGC3Dint x, WGC3Dint y, WGC3Dsizei width, WGC3Dsizei height,
1380 WGC3Denum format, WGC3Denum type, void* pixels) {
1381 makeContextCurrent();
1382 // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e.,
1383 // all previous rendering calls should be done before reading pixels.
1384 glFlush();
1385 bool needs_resolve =
1386 (attributes_.antialias && bound_fbo_ == multisample_fbo_);
1387 if (needs_resolve) {
1388 ResolveMultisampledFramebuffer(x, y, width, height);
1389 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
1390 glFlush();
1393 glReadPixels(x, y, width, height, format, type, pixels);
1395 if (needs_resolve)
1396 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bound_fbo_);
1399 void WebGraphicsContext3DInProcessImpl::releaseShaderCompiler() {
1402 void WebGraphicsContext3DInProcessImpl::renderbufferStorage(
1403 WGC3Denum target,
1404 WGC3Denum internalformat,
1405 WGC3Dsizei width,
1406 WGC3Dsizei height) {
1407 makeContextCurrent();
1408 if (!is_gles2_) {
1409 switch (internalformat) {
1410 case GL_DEPTH_STENCIL:
1411 internalformat = GL_DEPTH24_STENCIL8_EXT;
1412 break;
1413 case GL_DEPTH_COMPONENT16:
1414 internalformat = GL_DEPTH_COMPONENT;
1415 break;
1416 case GL_RGBA4:
1417 case GL_RGB5_A1:
1418 internalformat = GL_RGBA;
1419 break;
1420 case 0x8D62: // GL_RGB565
1421 internalformat = GL_RGB;
1422 break;
1425 glRenderbufferStorageEXT(target, internalformat, width, height);
1428 DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, WGC3Dclampf, WGC3Dboolean)
1430 DELEGATE_TO_GL_4(scissor, Scissor, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1432 void WebGraphicsContext3DInProcessImpl::texImage2D(
1433 WGC3Denum target, WGC3Dint level, WGC3Denum internalFormat,
1434 WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border,
1435 WGC3Denum format, WGC3Denum type, const void* pixels) {
1436 makeContextCurrent();
1437 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
1438 if (format == GL_BGRA_EXT && internalFormat == GL_BGRA_EXT) {
1439 internalFormat = GL_RGBA;
1440 } else if (type == GL_FLOAT) {
1441 if (format == GL_RGBA) {
1442 internalFormat = GL_RGBA32F_ARB;
1443 } else if (format == GL_RGB) {
1444 internalFormat = GL_RGB32F_ARB;
1448 glTexImage2D(target, level, internalFormat,
1449 width, height, border, format, type, pixels);
1452 void WebGraphicsContext3DInProcessImpl::shaderSource(
1453 WebGLId shader, const WGC3Dchar* source) {
1454 makeContextCurrent();
1455 GLint length = source ? strlen(source) : 0;
1456 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1457 if (result != shader_source_map_.end()) {
1458 ShaderSourceEntry* entry = result->second;
1459 DCHECK(entry);
1460 entry->source.reset(new char[length + 1]);
1461 if (source)
1462 memcpy(entry->source.get(), source, (length + 1) * sizeof(char));
1463 else
1464 entry->source[0] = '\0';
1465 } else {
1466 glShaderSource(shader, 1, &source, &length);
1470 DELEGATE_TO_GL_3(stencilFunc, StencilFunc, WGC3Denum, WGC3Dint, WGC3Duint)
1472 DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate,
1473 WGC3Denum, WGC3Denum, WGC3Dint, WGC3Duint)
1475 DELEGATE_TO_GL_1(stencilMask, StencilMask, WGC3Duint)
1477 DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate,
1478 WGC3Denum, WGC3Duint)
1480 DELEGATE_TO_GL_3(stencilOp, StencilOp,
1481 WGC3Denum, WGC3Denum, WGC3Denum)
1483 DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate,
1484 WGC3Denum, WGC3Denum, WGC3Denum, WGC3Denum)
1486 DELEGATE_TO_GL_3(texParameterf, TexParameterf, WGC3Denum, WGC3Denum, WGC3Dfloat)
1488 DELEGATE_TO_GL_3(texParameteri, TexParameteri, WGC3Denum, WGC3Denum, WGC3Dint)
1490 DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D,
1491 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dsizei,
1492 WGC3Dsizei, WGC3Denum, WGC3Denum, const void*)
1494 DELEGATE_TO_GL_2(uniform1f, Uniform1f, WGC3Dint, WGC3Dfloat)
1496 DELEGATE_TO_GL_3(uniform1fv, Uniform1fv,
1497 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1499 DELEGATE_TO_GL_2(uniform1i, Uniform1i, WGC3Dint, WGC3Dint)
1501 DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1503 DELEGATE_TO_GL_3(uniform2f, Uniform2f, WGC3Dint, WGC3Dfloat, WGC3Dfloat)
1505 DELEGATE_TO_GL_3(uniform2fv, Uniform2fv,
1506 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1508 DELEGATE_TO_GL_3(uniform2i, Uniform2i, WGC3Dint, WGC3Dint, WGC3Dint)
1510 DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1512 DELEGATE_TO_GL_4(uniform3f, Uniform3f,
1513 WGC3Dint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1515 DELEGATE_TO_GL_3(uniform3fv, Uniform3fv,
1516 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1518 DELEGATE_TO_GL_4(uniform3i, Uniform3i, WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1520 DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1522 DELEGATE_TO_GL_5(uniform4f, Uniform4f, WGC3Dint,
1523 WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1525 DELEGATE_TO_GL_3(uniform4fv, Uniform4fv,
1526 WGC3Dint, WGC3Dsizei, const WGC3Dfloat*)
1528 DELEGATE_TO_GL_5(uniform4i, Uniform4i, WGC3Dint,
1529 WGC3Dint, WGC3Dint, WGC3Dint, WGC3Dint)
1531 DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, WGC3Dint, WGC3Dsizei, const WGC3Dint*)
1533 DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv,
1534 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1536 DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv,
1537 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1539 DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv,
1540 WGC3Dint, WGC3Dsizei, WGC3Dboolean, const WGC3Dfloat*)
1542 DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId)
1544 DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId)
1546 DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, WGC3Duint, WGC3Dfloat)
1548 DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, WGC3Duint, const WGC3Dfloat*)
1550 DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f,
1551 WGC3Duint, WGC3Dfloat, WGC3Dfloat)
1553 DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, WGC3Duint, const WGC3Dfloat*)
1555 DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f,
1556 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1558 DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, WGC3Duint, const WGC3Dfloat*)
1560 DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f,
1561 WGC3Duint, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat, WGC3Dfloat)
1563 DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, WGC3Duint, const WGC3Dfloat*)
1565 void WebGraphicsContext3DInProcessImpl::vertexAttribPointer(
1566 WGC3Duint index, WGC3Dint size, WGC3Denum type, WGC3Dboolean normalized,
1567 WGC3Dsizei stride, WGC3Dintptr offset) {
1568 makeContextCurrent();
1569 glVertexAttribPointer(index, size, type, normalized, stride,
1570 reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
1573 DELEGATE_TO_GL_4(viewport, Viewport, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei)
1575 WebGLId WebGraphicsContext3DInProcessImpl::createBuffer() {
1576 makeContextCurrent();
1577 GLuint o = 0;
1578 glGenBuffersARB(1, &o);
1579 return o;
1582 WebGLId WebGraphicsContext3DInProcessImpl::createFramebuffer() {
1583 makeContextCurrent();
1584 GLuint o = 0;
1585 glGenFramebuffersEXT(1, &o);
1586 return o;
1589 WebGLId WebGraphicsContext3DInProcessImpl::createProgram() {
1590 makeContextCurrent();
1591 return glCreateProgram();
1594 WebGLId WebGraphicsContext3DInProcessImpl::createRenderbuffer() {
1595 makeContextCurrent();
1596 GLuint o = 0;
1597 glGenRenderbuffersEXT(1, &o);
1598 return o;
1601 WebGLId WebGraphicsContext3DInProcessImpl::createShader(
1602 WGC3Denum shaderType) {
1603 makeContextCurrent();
1604 DCHECK(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER);
1605 GLuint shader = glCreateShader(shaderType);
1606 if (shader) {
1607 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1608 if (result != shader_source_map_.end()) {
1609 delete result->second;
1610 shader_source_map_.erase(result);
1612 shader_source_map_.insert(
1613 ShaderSourceMap::value_type(shader, new ShaderSourceEntry(shaderType)));
1616 return shader;
1619 WebGLId WebGraphicsContext3DInProcessImpl::createTexture() {
1620 makeContextCurrent();
1621 GLuint o = 0;
1622 glGenTextures(1, &o);
1623 return o;
1626 void WebGraphicsContext3DInProcessImpl::deleteBuffer(WebGLId buffer) {
1627 makeContextCurrent();
1628 glDeleteBuffersARB(1, &buffer);
1631 void WebGraphicsContext3DInProcessImpl::deleteFramebuffer(
1632 WebGLId framebuffer) {
1633 makeContextCurrent();
1634 glDeleteFramebuffersEXT(1, &framebuffer);
1637 void WebGraphicsContext3DInProcessImpl::deleteProgram(WebGLId program) {
1638 makeContextCurrent();
1639 glDeleteProgram(program);
1642 void WebGraphicsContext3DInProcessImpl::deleteRenderbuffer(
1643 WebGLId renderbuffer) {
1644 makeContextCurrent();
1645 glDeleteRenderbuffersEXT(1, &renderbuffer);
1648 void WebGraphicsContext3DInProcessImpl::deleteShader(WebGLId shader) {
1649 makeContextCurrent();
1651 ShaderSourceMap::iterator result = shader_source_map_.find(shader);
1652 if (result != shader_source_map_.end()) {
1653 delete result->second;
1654 shader_source_map_.erase(result);
1656 glDeleteShader(shader);
1659 void WebGraphicsContext3DInProcessImpl::deleteTexture(WebGLId texture) {
1660 makeContextCurrent();
1661 glDeleteTextures(1, &texture);
1664 WGC3Denum WebGraphicsContext3DInProcessImpl::getGraphicsResetStatusARB() {
1665 // TODO(kbr): this implementation doesn't support lost contexts yet.
1666 return GL_NO_ERROR;
1669 void WebGraphicsContext3DInProcessImpl::texImageIOSurface2DCHROMIUM(
1670 WGC3Denum target, WGC3Dint width, WGC3Dint height,
1671 WGC3Duint ioSurfaceId, WGC3Duint plane) {
1674 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT,
1675 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint)
1677 WebGLId WebGraphicsContext3DInProcessImpl::createQueryEXT() {
1678 makeContextCurrent();
1679 GLuint o = 0;
1680 glGenQueriesARB(1, &o);
1681 return o;
1684 void WebGraphicsContext3DInProcessImpl::deleteQueryEXT(WebGLId query) {
1685 makeContextCurrent();
1686 glDeleteQueriesARB(1, &query);
1689 DELEGATE_TO_GL_1R(isQueryEXT, IsQueryARB, WebGLId, WGC3Dboolean)
1690 DELEGATE_TO_GL_2(beginQueryEXT, BeginQueryARB, WGC3Denum, WebGLId)
1691 DELEGATE_TO_GL_1(endQueryEXT, EndQueryARB, WGC3Denum)
1692 DELEGATE_TO_GL_3(getQueryivEXT, GetQueryivARB, WGC3Denum, WGC3Denum, WGC3Dint*)
1693 DELEGATE_TO_GL_3(getQueryObjectuivEXT, GetQueryObjectuivARB,
1694 WebGLId, WGC3Denum, WGC3Duint*)
1696 void WebGraphicsContext3DInProcessImpl::copyTextureCHROMIUM(
1697 WGC3Denum, WGC3Duint, WGC3Duint, WGC3Dint, WGC3Denum) {
1698 NOTIMPLEMENTED();
1701 GrGLInterface* WebGraphicsContext3DInProcessImpl::onCreateGrGLInterface() {
1702 return gfx::CreateInProcessSkiaGLBinding();
1705 bool WebGraphicsContext3DInProcessImpl::AngleCreateCompilers() {
1706 if (!ShInitialize())
1707 return false;
1709 ShBuiltInResources resources;
1710 ShInitBuiltInResources(&resources);
1711 getIntegerv(GL_MAX_VERTEX_ATTRIBS, &resources.MaxVertexAttribs);
1712 getIntegerv(MAX_VERTEX_UNIFORM_VECTORS, &resources.MaxVertexUniformVectors);
1713 getIntegerv(MAX_VARYING_VECTORS, &resources.MaxVaryingVectors);
1714 getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
1715 &resources.MaxVertexTextureImageUnits);
1716 getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
1717 &resources.MaxCombinedTextureImageUnits);
1718 getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &resources.MaxTextureImageUnits);
1719 getIntegerv(MAX_FRAGMENT_UNIFORM_VECTORS,
1720 &resources.MaxFragmentUniformVectors);
1721 // Always set to 1 for OpenGL ES.
1722 resources.MaxDrawBuffers = 1;
1724 fragment_compiler_ = ShConstructCompiler(
1725 SH_FRAGMENT_SHADER, SH_WEBGL_SPEC,
1726 is_gles2_ ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT, &resources);
1727 vertex_compiler_ = ShConstructCompiler(
1728 SH_VERTEX_SHADER, SH_WEBGL_SPEC,
1729 is_gles2_ ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT, &resources);
1730 return (fragment_compiler_ && vertex_compiler_);
1733 void WebGraphicsContext3DInProcessImpl::AngleDestroyCompilers() {
1734 if (fragment_compiler_) {
1735 ShDestruct(fragment_compiler_);
1736 fragment_compiler_ = 0;
1738 if (vertex_compiler_) {
1739 ShDestruct(vertex_compiler_);
1740 vertex_compiler_ = 0;
1744 bool WebGraphicsContext3DInProcessImpl::AngleValidateShaderSource(
1745 ShaderSourceEntry* entry) {
1746 entry->is_valid = false;
1747 entry->translated_source.reset();
1748 entry->log.reset();
1750 ShHandle compiler = 0;
1751 switch (entry->type) {
1752 case GL_FRAGMENT_SHADER:
1753 compiler = fragment_compiler_;
1754 break;
1755 case GL_VERTEX_SHADER:
1756 compiler = vertex_compiler_;
1757 break;
1759 if (!compiler)
1760 return false;
1762 char* source = entry->source.get();
1763 if (!ShCompile(compiler, &source, 1, SH_OBJECT_CODE)) {
1764 int logSize = 0;
1765 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &logSize);
1766 if (logSize > 1) {
1767 entry->log.reset(new char[logSize]);
1768 ShGetInfoLog(compiler, entry->log.get());
1770 return false;
1773 int length = 0;
1774 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &length);
1775 if (length > 1) {
1776 entry->translated_source.reset(new char[length]);
1777 ShGetObjectCode(compiler, entry->translated_source.get());
1779 entry->is_valid = true;
1780 return true;
1783 } // namespace gpu
1784 } // namespace webkit