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"
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"
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
)
43 scoped_array
<char> source
;
44 scoped_array
<char> log
;
45 scoped_array
<char> translated_source
;
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
),
56 have_ext_framebuffer_object_(false),
57 have_ext_framebuffer_multisample_(false),
58 have_angle_framebuffer_multisample_(false),
61 depth_stencil_buffer_(0),
65 multisample_depth_stencil_buffer_(0),
66 multisample_color_buffer_(0),
69 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
74 fragment_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);
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_
);
100 if (attributes_
.depth
|| attributes_
.stencil
)
101 glDeleteRenderbuffersEXT(1, &depth_stencil_buffer_
);
103 glDeleteTextures(1, &texture_
);
104 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
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
) {
119 AngleDestroyCompilers();
122 WebGraphicsContext3DInProcessImpl
*
123 WebGraphicsContext3DInProcessImpl::CreateForWebView(
124 WebGraphicsContext3D::Attributes attributes
,
125 bool render_directly_to_web_view
) {
126 if (!gfx::GLSurface::InitializeOneOff())
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();
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())
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(
159 if (!gl_context
.get())
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
))
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())
178 scoped_refptr
<gfx::GLSurface
> gl_surface
=
179 gfx::GLSurface::CreateViewGLSurface(false, window
);
180 if (!gl_surface
.get())
183 gfx::GpuPreference gpu_preference
= gfx::PreferDiscreteGpu
;
185 scoped_refptr
<gfx::GLContext
> gl_context
= gfx::GLContext::CreateGLContext(
189 if (!gl_context
.get())
191 scoped_ptr
<WebGraphicsContext3DInProcessImpl
> context(
192 new WebGraphicsContext3DInProcessImpl(
193 gl_surface
.get(), gl_context
.get(), true));
194 if (!context
->Initialize(attributes
))
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
214 if (render_directly_to_web_view_
)
215 attributes_
.antialias
= false;
217 if (!gl_context_
->MakeCurrent(gl_surface_
.get())) {
222 const char* extensions
=
223 reinterpret_cast<const char*>(glGetString(GL_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();
235 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE
);
236 glEnable(GL_POINT_SPRITE
);
239 if (!AngleCreateCompilers()) {
240 AngleDestroyCompilers();
245 gl_context_
->ReleaseCurrent(gl_surface_
.get());
247 if (attributes_
.shareResources
)
248 g_all_shared_contexts
.Pointer()->insert(this);
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;
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;
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
,
300 x
+ width
, y
+ height
,
301 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
303 DCHECK(have_angle_framebuffer_multisample_
);
304 glBlitFramebufferANGLE(x
, y
,
305 x
+ width
, y
+ height
,
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() {
330 bool WebGraphicsContext3DInProcessImpl::setParentContext(
331 WebGraphicsContext3D
* parent_context
) {
335 WebGLId
WebGraphicsContext3DInProcessImpl::getPlatformTextureId() {
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
);
357 int CreateTextureObject(GLenum target
) {
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
);
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
));
380 if (must_restore_fbo
)
381 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, bound_fbo_
);
383 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
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
;
397 // Generate the texture object
398 texture_
= CreateTextureObject(target
);
399 // Generate the framebuffer object
400 glGenFramebuffersEXT(1, &fbo_
);
401 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 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
;
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
;
438 internal_depth_stencil_format
= GL_DEPTH_COMPONENT16
;
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
,
459 internal_multisampled_color_format
,
463 DCHECK(have_angle_framebuffer_multisample_
);
464 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT
,
466 internal_multisampled_color_format
,
470 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
471 GL_COLOR_ATTACHMENT0_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
,
480 internal_depth_stencil_format
,
484 DCHECK(have_angle_framebuffer_multisample_
);
485 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER_EXT
,
487 internal_depth_stencil_format
,
491 if (attributes_
.stencil
)
492 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
493 GL_STENCIL_ATTACHMENT_EXT
,
495 multisample_depth_stencil_buffer_
);
496 if (attributes_
.depth
)
497 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
498 GL_DEPTH_ATTACHMENT_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";
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
,
520 0, color_format
, GL_UNSIGNED_BYTE
, 0);
521 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
,
522 GL_COLOR_ATTACHMENT0_EXT
,
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
,
532 if (attributes_
.stencil
)
533 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
534 GL_STENCIL_ATTACHMENT_EXT
,
536 depth_stencil_buffer_
);
537 if (attributes_
.depth
)
538 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
539 GL_DEPTH_ATTACHMENT_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";
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
);
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
);
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
);
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
);
609 glDisable(GL_SCISSOR_TEST
);
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_
;
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
);
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
))
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)
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;
671 // FIXME: consider testing for presence of GL_OES_read_format
672 // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here
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]);
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
691 FlipVertically(pixels
, width
, height
);
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
) {
715 void WebGraphicsContext3DInProcessImpl::unmapBufferSubDataCHROMIUM(
719 void* WebGraphicsContext3DInProcessImpl::mapTexSubImage2DCHROMIUM(
720 WGC3Denum target
, WGC3Dint level
, WGC3Dint xoffset
, WGC3Dint yoffset
,
721 WGC3Dsizei width
, WGC3Dsizei height
, WGC3Denum format
, WGC3Denum type
,
726 void WebGraphicsContext3DInProcessImpl::unmapTexSubImage2DCHROMIUM(
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
) {
750 void WebGraphicsContext3DInProcessImpl::bindUniformLocationCHROMIUM(
751 WebGLId program
, WGC3Dint location
, const WGC3Dchar
* uniform
) {
755 void WebGraphicsContext3DInProcessImpl::genMailboxCHROMIUM(
756 WGC3Dbyte
* mailbox
) {
760 void WebGraphicsContext3DInProcessImpl::produceTextureCHROMIUM(
761 WGC3Denum target
, const WGC3Dbyte
* mailbox
) {
765 void WebGraphicsContext3DInProcessImpl::consumeTextureCHROMIUM(
766 WGC3Denum target
, const WGC3Dbyte
* mailbox
) {
770 WebString
WebGraphicsContext3DInProcessImpl::
771 getRequestableExtensionsCHROMIUM() {
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(); \
797 #define DELEGATE_TO_GL_1(name, glname, t1) \
798 void WebGraphicsContext3DInProcessImpl::name(t1 a1) { \
799 makeContextCurrent(); \
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, \
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, \
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, \
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.
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();
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
);
956 ShaderSourceEntry
* entry
= result
->second
;
959 if (!AngleValidateShaderSource(entry
)) {
960 // Shader didn't validate; don't move forward with compiling
961 // translated source.
965 const char* translated_source
= entry
->translated_source
.get();
966 int shader_length
= translated_source
? strlen(translated_source
) : 0;
968 shader
, 1, const_cast<const char**>(&translated_source
), &shader_length
);
969 glCompileShader(shader
);
973 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &compileStatus
);
974 // DCHECK that ANGLE generated GLSL will be accepted by OpenGL
975 DCHECK(compileStatus
== GL_TRUE
);
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_
);
994 ResolveMultisampledFramebuffer(x
, y
, width
, height
);
995 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fbo_
);
998 glCopyTexImage2D(target
, level
, internalformat
, x
, y
, width
, height
, border
);
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_
);
1011 ResolveMultisampledFramebuffer(x
, y
, width
, height
);
1012 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fbo_
);
1015 glCopyTexSubImage2D(target
, level
, xoffset
, yoffset
, x
, y
, width
, height
);
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();
1073 synthesizeGLError(GL_INVALID_VALUE
);
1076 GLint max_name_length
= -1;
1077 glGetProgramiv(program
, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
, &max_name_length
);
1078 if (max_name_length
< 0)
1080 scoped_array
<GLchar
> name(new GLchar
[max_name_length
]);
1084 glGetActiveAttrib(program
, index
, max_name_length
,
1085 &length
, &size
, &type
, name
.get());
1089 info
.name
= WebString::fromUTF8(name
.get(), length
);
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)
1102 scoped_array
<GLchar
> name(new GLchar
[max_name_length
]);
1106 glGetActiveUniform(program
, index
, max_name_length
,
1107 &length
, &size
, &type
, name
.get());
1111 info
.name
= WebString::fromUTF8(name
.get(), length
);
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() {
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
);
1143 makeContextCurrent();
1144 return glGetError();
1147 bool WebGraphicsContext3DInProcessImpl::isContextLost() {
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;
1160 glGetFramebufferAttachmentParameterivEXT(target
, attachment
, pname
, value
);
1163 void WebGraphicsContext3DInProcessImpl::getIntegerv(
1164 WGC3Denum pname
, WGC3Dint
* value
) {
1165 makeContextCurrent();
1167 glGetIntegerv(pname
, value
);
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.
1176 case MAX_FRAGMENT_UNIFORM_VECTORS
:
1177 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS
, value
);
1180 case MAX_VERTEX_UNIFORM_VECTORS
:
1181 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS
, value
);
1184 case MAX_VARYING_VECTORS
:
1185 glGetIntegerv(GL_MAX_VARYING_FLOATS
, value
);
1189 glGetIntegerv(pname
, value
);
1193 DELEGATE_TO_GL_3(getProgramiv
, GetProgramiv
, WebGLId
, WGC3Denum
, WGC3Dint
*)
1195 WebString
WebGraphicsContext3DInProcessImpl::getProgramInfoLog(
1197 makeContextCurrent();
1199 glGetProgramiv(program
, GL_INFO_LOG_LENGTH
, &log_length
);
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
);
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
;
1222 case GL_COMPILE_STATUS
:
1223 if (!entry
->is_valid
) {
1228 case GL_INFO_LOG_LENGTH
:
1229 if (!entry
->is_valid
) {
1230 *value
= entry
->log
.get() ? strlen(entry
->log
.get()) : 0;
1236 case GL_SHADER_SOURCE_LENGTH
:
1237 *value
= entry
->source
.get() ? strlen(entry
->source
.get()) : 0;
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
;
1257 if (!entry
->is_valid
) {
1258 if (!entry
->log
.get())
1260 WebString res
= WebString::fromUTF8(
1261 entry
->log
.get(), strlen(entry
->log
.get()));
1266 GLint log_length
= 0;
1267 glGetShaderiv(shader
, GL_INFO_LOG_LENGTH
, &log_length
);
1268 if (log_length
<= 1)
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
);
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
;
1285 if (!entry
->source
.get())
1287 WebString res
= WebString::fromUTF8(
1288 entry
->source
.get(), strlen(entry
->source
.get()));
1292 GLint log_length
= 0;
1293 glGetShaderiv(shader
, GL_SHADER_SOURCE_LENGTH
, &log_length
);
1294 if (log_length
<= 1)
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
);
1304 WebString
WebGraphicsContext3DInProcessImpl::getString(WGC3Denum name
) {
1305 makeContextCurrent();
1307 if (name
== GL_EXTENSIONS
) {
1308 result
= gl_context_
->GetExtensions();
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
;
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();
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.
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_
);
1393 glReadPixels(x
, y
, width
, height
, format
, type
, pixels
);
1396 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, bound_fbo_
);
1399 void WebGraphicsContext3DInProcessImpl::releaseShaderCompiler() {
1402 void WebGraphicsContext3DInProcessImpl::renderbufferStorage(
1404 WGC3Denum internalformat
,
1406 WGC3Dsizei height
) {
1407 makeContextCurrent();
1409 switch (internalformat
) {
1410 case GL_DEPTH_STENCIL
:
1411 internalformat
= GL_DEPTH24_STENCIL8_EXT
;
1413 case GL_DEPTH_COMPONENT16
:
1414 internalformat
= GL_DEPTH_COMPONENT
;
1418 internalformat
= GL_RGBA
;
1420 case 0x8D62: // GL_RGB565
1421 internalformat
= GL_RGB
;
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
;
1460 entry
->source
.reset(new char[length
+ 1]);
1462 memcpy(entry
->source
.get(), source
, (length
+ 1) * sizeof(char));
1464 entry
->source
[0] = '\0';
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();
1578 glGenBuffersARB(1, &o
);
1582 WebGLId
WebGraphicsContext3DInProcessImpl::createFramebuffer() {
1583 makeContextCurrent();
1585 glGenFramebuffersEXT(1, &o
);
1589 WebGLId
WebGraphicsContext3DInProcessImpl::createProgram() {
1590 makeContextCurrent();
1591 return glCreateProgram();
1594 WebGLId
WebGraphicsContext3DInProcessImpl::createRenderbuffer() {
1595 makeContextCurrent();
1597 glGenRenderbuffersEXT(1, &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
);
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
)));
1619 WebGLId
WebGraphicsContext3DInProcessImpl::createTexture() {
1620 makeContextCurrent();
1622 glGenTextures(1, &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.
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();
1680 glGenQueriesARB(1, &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
) {
1701 GrGLInterface
* WebGraphicsContext3DInProcessImpl::onCreateGrGLInterface() {
1702 return gfx::CreateInProcessSkiaGLBinding();
1705 bool WebGraphicsContext3DInProcessImpl::AngleCreateCompilers() {
1706 if (!ShInitialize())
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();
1750 ShHandle compiler
= 0;
1751 switch (entry
->type
) {
1752 case GL_FRAGMENT_SHADER
:
1753 compiler
= fragment_compiler_
;
1755 case GL_VERTEX_SHADER
:
1756 compiler
= vertex_compiler_
;
1762 char* source
= entry
->source
.get();
1763 if (!ShCompile(compiler
, &source
, 1, SH_OBJECT_CODE
)) {
1765 ShGetInfo(compiler
, SH_INFO_LOG_LENGTH
, &logSize
);
1767 entry
->log
.reset(new char[logSize
]);
1768 ShGetInfoLog(compiler
, entry
->log
.get());
1774 ShGetInfo(compiler
, SH_OBJECT_CODE_LENGTH
, &length
);
1776 entry
->translated_source
.reset(new char[length
]);
1777 ShGetObjectCode(compiler
, entry
->translated_source
.get());
1779 entry
->is_valid
= true;
1784 } // namespace webkit