<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[180285] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/180285">180285</a></dd>
<dt>Author</dt> <dd>roger_fong@apple.com</dd>
<dt>Date</dt> <dd>2015-02-18 12:42:53 -0800 (Wed, 18 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebGL2: Promote various WebGL1 extensions to core for WebGL2.
https://bugs.webkit.org/show_bug.cgi?id=141446
&lt;rdar://problem/19633715&gt;

Reviewed by Brent Fulham.

Tests covered by WebGL2 conformance tests.

This patch promotes the following WebGL1 extensions to core in WebGL2:
OES_element_index_uint 
EXT_sRGB 
EXT_blend_minmax 
EXT_frag_depth 
EXT_shader_texture_lod
OES_standard_derivatives 

The latter 3 are enabled by default now for GLSL1, though we will get these extensions 
for free when GLSL3 becomes available.

WebGL2 binding code should actually fall back to base implementation for getFramebufferAttachmentParameter.
* bindings/js/JSWebGL2RenderingContextCustom.cpp: 
(WebCore::JSWebGL2RenderingContext::getFramebufferAttachmentParameter): Deleted.
* html/canvas/WebGL2RenderingContext.idl: Ditto.

* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::getExtension): Enable WEBGL_lose_context as an extension again.
It was not promoted to core as I originally thought it had been.
(WebCore::WebGL2RenderingContext::getSupportedExtensions): Ditto.
(WebCore::WebGL2RenderingContext::WebGL2RenderingContext): Promote the 3 shader extensions for GLSL1 to core.
(WebCore::WebGL2RenderingContext::initializeShaderExtensions): Ditto.
(WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Promote SRGB extension to core.
(WebCore::WebGL2RenderingContext::renderbufferStorage): Ditto.
(WebCore::WebGL2RenderingContext::hint): Ditto.
(WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Ditto.
(WebCore::WebGL2RenderingContext::validateIndexArrayConservative): Promote OES_element_index_uint extension to core.
(WebCore::WebGL2RenderingContext::validateDrawElements): Ditto.
(WebCore::WebGL2RenderingContext::validateBlendEquation): Promote EXT_blend_minmax extension to core.
* html/canvas/WebGL2RenderingContext.h:

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::getFramebufferAttachmentParameter): Copied form WebGLRenderingContextBase.
(WebCore::WebGLRenderingContext::renderbufferStorage): Ditto.
(WebCore::WebGLRenderingContext::hint): Ditto.
(WebCore::WebGLRenderingContext::validateIndexArrayConservative): Ditto.
(WebCore::WebGLRenderingContext::validateDrawElements): Ditto.
(WebCore::WebGLRenderingContext::validateBlendEquation): Ditto.
* html/canvas/WebGLRenderingContext.h:

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::validateIndexArrayConservative): Deleted.
(WebCore::WebGLRenderingContextBase::validateDrawElements): Deleted.
(WebCore::WebGLRenderingContextBase::getExtension): Deleted.
(WebCore::WebGLRenderingContextBase::getFramebufferAttachmentParameter): Deleted.
(WebCore::WebGLRenderingContextBase::hint): Deleted.
(WebCore::WebGLRenderingContextBase::renderbufferStorage): Deleted.
(WebCore::WebGLRenderingContextBase::validateBlendEquation): Deleted.
* html/canvas/WebGLRenderingContextBase.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSWebGL2RenderingContextCustomcpp">trunk/Source/WebCore/bindings/js/JSWebGL2RenderingContextCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGL2RenderingContextidl">trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContexth">trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/ChangeLog        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -1,3 +1,63 @@
</span><ins>+2015-02-18  Roger Fong  &lt;roger_fong@apple.com&gt;
+
+        WebGL2: Promote various WebGL1 extensions to core for WebGL2.
+        https://bugs.webkit.org/show_bug.cgi?id=141446
+        &lt;rdar://problem/19633715&gt;
+
+        Reviewed by Brent Fulham.
+
+        Tests covered by WebGL2 conformance tests.
+
+        This patch promotes the following WebGL1 extensions to core in WebGL2:
+        OES_element_index_uint 
+        EXT_sRGB 
+        EXT_blend_minmax 
+        EXT_frag_depth 
+        EXT_shader_texture_lod
+        OES_standard_derivatives 
+        
+        The latter 3 are enabled by default now for GLSL1, though we will get these extensions 
+        for free when GLSL3 becomes available.
+
+        WebGL2 binding code should actually fall back to base implementation for getFramebufferAttachmentParameter.
+        * bindings/js/JSWebGL2RenderingContextCustom.cpp: 
+        (WebCore::JSWebGL2RenderingContext::getFramebufferAttachmentParameter): Deleted.
+        * html/canvas/WebGL2RenderingContext.idl: Ditto.
+
+        * html/canvas/WebGL2RenderingContext.cpp:
+        (WebCore::WebGL2RenderingContext::getExtension): Enable WEBGL_lose_context as an extension again.
+        It was not promoted to core as I originally thought it had been.
+        (WebCore::WebGL2RenderingContext::getSupportedExtensions): Ditto.
+        (WebCore::WebGL2RenderingContext::WebGL2RenderingContext): Promote the 3 shader extensions for GLSL1 to core.
+        (WebCore::WebGL2RenderingContext::initializeShaderExtensions): Ditto.
+        (WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Promote SRGB extension to core.
+        (WebCore::WebGL2RenderingContext::renderbufferStorage): Ditto.
+        (WebCore::WebGL2RenderingContext::hint): Ditto.
+        (WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Ditto.
+        (WebCore::WebGL2RenderingContext::validateIndexArrayConservative): Promote OES_element_index_uint extension to core.
+        (WebCore::WebGL2RenderingContext::validateDrawElements): Ditto.
+        (WebCore::WebGL2RenderingContext::validateBlendEquation): Promote EXT_blend_minmax extension to core.
+        * html/canvas/WebGL2RenderingContext.h:
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::getFramebufferAttachmentParameter): Copied form WebGLRenderingContextBase.
+        (WebCore::WebGLRenderingContext::renderbufferStorage): Ditto.
+        (WebCore::WebGLRenderingContext::hint): Ditto.
+        (WebCore::WebGLRenderingContext::validateIndexArrayConservative): Ditto.
+        (WebCore::WebGLRenderingContext::validateDrawElements): Ditto.
+        (WebCore::WebGLRenderingContext::validateBlendEquation): Ditto.
+        * html/canvas/WebGLRenderingContext.h:
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::validateIndexArrayConservative): Deleted.
+        (WebCore::WebGLRenderingContextBase::validateDrawElements): Deleted.
+        (WebCore::WebGLRenderingContextBase::getExtension): Deleted.
+        (WebCore::WebGLRenderingContextBase::getFramebufferAttachmentParameter): Deleted.
+        (WebCore::WebGLRenderingContextBase::hint): Deleted.
+        (WebCore::WebGLRenderingContextBase::renderbufferStorage): Deleted.
+        (WebCore::WebGLRenderingContextBase::validateBlendEquation): Deleted.
+        * html/canvas/WebGLRenderingContextBase.h:
+
</ins><span class="cx"> 2015-02-18  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Streamline unexported function build fixes
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSWebGL2RenderingContextCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSWebGL2RenderingContextCustom.cpp (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSWebGL2RenderingContextCustom.cpp        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/bindings/js/JSWebGL2RenderingContextCustom.cpp        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -69,12 +69,6 @@
</span><span class="cx"> {
</span><span class="cx">     visitor.addOpaqueRoot(&amp;impl());
</span><span class="cx"> }
</span><del>-    
-JSValue JSWebGL2RenderingContext::getFramebufferAttachmentParameter(ExecState* exec)
-{
-    UNUSED_PARAM(exec);
-    return jsUndefined();
-}
</del><span class="cx"> 
</span><span class="cx"> JSValue JSWebGL2RenderingContext::getInternalformatParameter(ExecState* exec)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx"> #include &quot;WebGLDebugRendererInfo.h&quot;
</span><span class="cx"> #include &quot;WebGLDebugShaders.h&quot;
</span><span class="cx"> #include &quot;WebGLDepthTexture.h&quot;
</span><ins>+#include &quot;WebGLLoseContext.h&quot;
</ins><span class="cx"> #include &quot;WebGLQuery.h&quot;
</span><span class="cx"> #include &quot;WebGLSampler.h&quot;
</span><span class="cx"> #include &quot;WebGLSync.h&quot;
</span><span class="lines">@@ -59,13 +60,23 @@
</span><span class="cx"> WebGL2RenderingContext::WebGL2RenderingContext(HTMLCanvasElement* passedCanvas, GraphicsContext3D::Attributes attributes)
</span><span class="cx">     : WebGLRenderingContextBase(passedCanvas, attributes)
</span><span class="cx"> {
</span><ins>+    initializeShaderExtensions();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebGL2RenderingContext::WebGL2RenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr&lt;GraphicsContext3D&gt; context,
</span><span class="cx">     GraphicsContext3D::Attributes attributes) : WebGLRenderingContextBase(passedCanvas, context, attributes)
</span><span class="cx"> {
</span><ins>+    initializeShaderExtensions();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebGL2RenderingContext::initializeShaderExtensions()
+{
+    m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_standard_derivatives&quot;);
+    m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_draw_buffers&quot;);
+    m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_shader_texture_lod&quot;);
+    m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_frag_depth&quot;);
+}
+
</ins><span class="cx"> void WebGL2RenderingContext::copyBufferSubData(GC3Denum readTarget, GC3Denum writeTarget, GC3Dint64 readOffset, GC3Dint64 writeOffset, GC3Dint64 size)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(readTarget);
</span><span class="lines">@@ -89,15 +100,6 @@
</span><span class="cx">     UNUSED_PARAM(returnedData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp; ec)
-{
-    UNUSED_PARAM(target);
-    UNUSED_PARAM(attachment);
-    UNUSED_PARAM(pname);
-    UNUSED_PARAM(ec);
-    return WebGLGetInfo();
-}
-
</del><span class="cx"> void WebGL2RenderingContext::blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(srcX0);
</span><span class="lines">@@ -830,6 +832,11 @@
</span><span class="cx">         }
</span><span class="cx">         return m_oesTextureHalfFloatLinear.get();
</span><span class="cx">     }
</span><ins>+    if (equalIgnoringCase(name, &quot;WEBGL_lose_context&quot;)) {
+        if (!m_webglLoseContext)
+            m_webglLoseContext = std::make_unique&lt;WebGLLoseContext&gt;(this);
+        return m_webglLoseContext.get();
+    }
</ins><span class="cx">     if ((equalIgnoringCase(name, &quot;WEBKIT_WEBGL_compressed_texture_atc&quot;))
</span><span class="cx">         &amp;&amp; WebGLCompressedTextureATC::supported(this)) {
</span><span class="cx">         if (!m_webglCompressedTextureATC)
</span><span class="lines">@@ -898,7 +905,7 @@
</span><span class="cx">         result.append(&quot;WEBGL_compressed_texture_s3tc&quot;);
</span><span class="cx">     if (WebGLDepthTexture::supported(graphicsContext3D()))
</span><span class="cx">         result.append(&quot;WEBGL_depth_texture&quot;);
</span><del>-    
</del><ins>+    result.append(&quot;WEBGL_lose_context&quot;);
</ins><span class="cx">     if (allowPrivilegedExtensions()) {
</span><span class="cx">         if (m_context-&gt;getExtensions()-&gt;supports(&quot;GL_ANGLE_translated_shader_source&quot;))
</span><span class="cx">             result.append(&quot;WEBGL_debug_shaders&quot;);
</span><span class="lines">@@ -908,6 +915,156 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp; ec)
+{
+    UNUSED_PARAM(ec);
+    if (isContextLostOrPending() || !validateFramebufferFuncParameters(&quot;getFramebufferAttachmentParameter&quot;, target, attachment))
+        return WebGLGetInfo();
+    
+    if (!m_framebufferBinding || !m_framebufferBinding-&gt;object()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;getFramebufferAttachmentParameter&quot;, &quot;no framebuffer bound&quot;);
+        return WebGLGetInfo();
+    }
+    
+    WebGLSharedObject* object = m_framebufferBinding-&gt;getAttachmentObject(attachment);
+    if (!object) {
+        if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+            return WebGLGetInfo(GraphicsContext3D::NONE);
+        // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+        // specifies INVALID_OPERATION.
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name&quot;);
+        return WebGLGetInfo();
+    }
+    
+    ASSERT(object-&gt;isTexture() || object-&gt;isRenderbuffer());
+    if (object-&gt;isTexture()) {
+        switch (pname) {
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+            return WebGLGetInfo(GraphicsContext3D::TEXTURE);
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+            return WebGLGetInfo(PassRefPtr&lt;WebGLTexture&gt;(reinterpret_cast&lt;WebGLTexture*&gt;(object)));
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: {
+            GC3Dint value = 0;
+            m_context-&gt;getFramebufferAttachmentParameteriv(target, attachment, pname, &amp;value);
+            return WebGLGetInfo(value);
+        }
+        default:
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for texture attachment&quot;);
+            return WebGLGetInfo();
+        }
+    } else {
+        switch (pname) {
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+            return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+            return WebGLGetInfo(PassRefPtr&lt;WebGLRenderbuffer&gt;(reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object)));
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING : {
+            WebGLRenderbuffer* renderBuffer = reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object);
+            GC3Denum renderBufferFormat = renderBuffer-&gt;getInternalFormat();
+            if (renderBufferFormat == GraphicsContext3D::SRGB8_ALPHA8
+                || renderBufferFormat == GraphicsContext3D::COMPRESSED_SRGB8_ETC2
+                || renderBufferFormat == GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+                || renderBufferFormat == GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) {
+                return WebGLGetInfo(GraphicsContext3D::SRGB);
+            }
+            return WebGLGetInfo(GraphicsContext3D::LINEAR);
+        }
+        default:
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for renderbuffer attachment&quot;);
+            return WebGLGetInfo();
+        }
+    }
+}
+
+void WebGL2RenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
+{
+    if (isContextLostOrPending())
+        return;
+    if (target != GraphicsContext3D::RENDERBUFFER) {
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid target&quot;);
+        return;
+    }
+    if (!m_renderbufferBinding || !m_renderbufferBinding-&gt;object()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;renderbufferStorage&quot;, &quot;no bound renderbuffer&quot;);
+        return;
+    }
+    if (!validateSize(&quot;renderbufferStorage&quot;, width, height))
+        return;
+    switch (internalformat) {
+    case GraphicsContext3D::DEPTH_COMPONENT16:
+    case GraphicsContext3D::DEPTH_COMPONENT32F:
+    case GraphicsContext3D::DEPTH_COMPONENT24:
+    case GraphicsContext3D::RGBA32I:
+    case GraphicsContext3D::RGBA32UI:
+    case GraphicsContext3D::RGBA16I:
+    case GraphicsContext3D::RGBA16UI:
+    case GraphicsContext3D::RGBA8:
+    case GraphicsContext3D::RGBA8I:
+    case GraphicsContext3D::RGBA8UI:
+    case GraphicsContext3D::RGB10_A2:
+    case GraphicsContext3D::RGB10_A2UI:
+    case GraphicsContext3D::RGBA4:
+    case GraphicsContext3D::RG32I:
+    case GraphicsContext3D::RG32UI:
+    case GraphicsContext3D::RG16I:
+    case GraphicsContext3D::RG16UI:
+    case GraphicsContext3D::RG8:
+    case GraphicsContext3D::RG8I:
+    case GraphicsContext3D::RG8UI:
+    case GraphicsContext3D::R32I:
+    case GraphicsContext3D::R32UI:
+    case GraphicsContext3D::R16I:
+    case GraphicsContext3D::R16UI:
+    case GraphicsContext3D::R8:
+    case GraphicsContext3D::R8I:
+    case GraphicsContext3D::R8UI:
+    case GraphicsContext3D::RGB5_A1:
+    case GraphicsContext3D::RGB565:
+    case GraphicsContext3D::STENCIL_INDEX8:
+    case GraphicsContext3D::SRGB8_ALPHA8:
+        m_context-&gt;renderbufferStorage(target, internalformat, width, height);
+        m_renderbufferBinding-&gt;setInternalFormat(internalformat);
+        m_renderbufferBinding-&gt;setIsValid(true);
+        m_renderbufferBinding-&gt;setSize(width, height);
+        break;
+    case GraphicsContext3D::DEPTH32F_STENCIL8:
+    case GraphicsContext3D::DEPTH24_STENCIL8:
+        if (!isDepthStencilSupported()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid internalformat&quot;);
+            return;
+        }
+        m_context-&gt;renderbufferStorage(target, internalformat, width, height);
+        m_renderbufferBinding-&gt;setSize(width, height);
+        m_renderbufferBinding-&gt;setIsValid(isDepthStencilSupported());
+        m_renderbufferBinding-&gt;setInternalFormat(internalformat);
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid internalformat&quot;);
+        return;
+    }
+    applyStencilTest();
+}
+
+void WebGL2RenderingContext::hint(GC3Denum target, GC3Denum mode)
+{
+    if (isContextLostOrPending())
+        return;
+    bool isValid = false;
+    switch (target) {
+    case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+    case GraphicsContext3D::FRAGMENT_SHADER_DERIVATIVE_HINT:
+        isValid = true;
+        break;
+    }
+    if (!isValid) {
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;hint&quot;, &quot;invalid target&quot;);
+        return;
+    }
+    m_context-&gt;hint(target, mode);
+}
+
</ins><span class="cx"> void WebGL2RenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
</span><span class="cx"> {
</span><span class="cx">     if (isContextLostOrPending())
</span><span class="lines">@@ -1323,6 +1480,7 @@
</span><span class="cx">     case GraphicsContext3D::RGB8I:
</span><span class="cx">     case GraphicsContext3D::RGB8UI:
</span><span class="cx">     case GraphicsContext3D::SRGB8:
</span><ins>+    case GraphicsContext3D::SRGB8_ALPHA8:
</ins><span class="cx">     case GraphicsContext3D::R11F_G11F_B10F:
</span><span class="cx">     case GraphicsContext3D::RGB9_E5:
</span><span class="cx">     case GraphicsContext3D::RG32F:
</span><span class="lines">@@ -2034,6 +2192,159 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WebGL2RenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired)
+{
+    // Performs conservative validation by caching a maximum index of
+    // the given type per element array buffer. If all of the bound
+    // array buffers have enough elements to satisfy that maximum
+    // index, skips the expensive per-draw-call iteration in
+    // validateIndexArrayPrecise.
+    
+    RefPtr&lt;WebGLBuffer&gt; elementArrayBuffer = m_boundVertexArrayObject-&gt;getElementArrayBuffer();
+    
+    if (!elementArrayBuffer)
+        return false;
+    
+    GC3Dsizeiptr numElements = elementArrayBuffer-&gt;byteLength();
+    // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+    if (!numElements)
+        return false;
+    const ArrayBuffer* buffer = elementArrayBuffer-&gt;elementArrayBuffer();
+    ASSERT(buffer);
+    
+    int maxIndex = elementArrayBuffer-&gt;getCachedMaxIndex(type);
+    if (maxIndex &lt; 0) {
+        // Compute the maximum index in the entire buffer for the given type of index.
+        switch (type) {
+        case GraphicsContext3D::UNSIGNED_BYTE: {
+            const GC3Dubyte* p = static_cast&lt;const GC3Dubyte*&gt;(buffer-&gt;data());
+            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
+                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
+            break;
+        }
+        case GraphicsContext3D::UNSIGNED_SHORT: {
+            numElements /= sizeof(GC3Dushort);
+            const GC3Dushort* p = static_cast&lt;const GC3Dushort*&gt;(buffer-&gt;data());
+            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
+                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
+            break;
+        }
+        case GraphicsContext3D::UNSIGNED_INT: {
+            numElements /= sizeof(GC3Duint);
+            const GC3Duint* p = static_cast&lt;const GC3Duint*&gt;(buffer-&gt;data());
+            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
+                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
+            break;
+        }
+        default:
+            return false;
+        }
+        elementArrayBuffer-&gt;setCachedMaxIndex(type, maxIndex);
+    }
+    
+    if (maxIndex &gt;= 0) {
+        // The number of required elements is one more than the maximum
+        // index that will be accessed.
+        numElementsRequired = maxIndex + 1;
+        return true;
+    }
+    
+    return false;
+}
+
+bool WebGL2RenderingContext::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primitiveCount)
+{
+    if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
+        return false;
+    
+    if (!validateStencilSettings(functionName))
+        return false;
+    
+    switch (type) {
+    case GraphicsContext3D::UNSIGNED_BYTE:
+    case GraphicsContext3D::UNSIGNED_SHORT:
+        break;
+    case GraphicsContext3D::UNSIGNED_INT:
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid type&quot;);
+        return false;
+    }
+    
+    if (count &lt; 0 || offset &lt; 0) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;count or offset &lt; 0&quot;);
+        return false;
+    }
+    
+    if (!count) {
+        markContextChanged();
+        return false;
+    }
+    
+    if (primitiveCount &lt; 0) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;primcount &lt; 0&quot;);
+        return false;
+    }
+    
+    if (!m_boundVertexArrayObject-&gt;getElementArrayBuffer()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;no ELEMENT_ARRAY_BUFFER bound&quot;);
+        return false;
+    }
+    
+    if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+        // Ensure we have a valid rendering state
+        if (!validateElementArraySize(count, type, static_cast&lt;GC3Dintptr&gt;(offset))) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;request out of bounds for current ELEMENT_ARRAY_BUFFER&quot;);
+            return false;
+        }
+        if (!count)
+            return false;
+        
+        Checked&lt;GC3Dint, RecordOverflow&gt; checkedCount(count);
+        Checked&lt;GC3Dint, RecordOverflow&gt; checkedPrimitiveCount(primitiveCount);
+        if (checkedCount.hasOverflowed() || checkedPrimitiveCount.hasOverflowed()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attempt to access out of bounds arrays&quot;);
+            return false;
+        }
+        
+        if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
+            if (!validateIndexArrayPrecise(checkedCount.unsafeGet(), type, static_cast&lt;GC3Dintptr&gt;(offset), numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
+                synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attempt to access out of bounds arrays&quot;);
+                return false;
+            }
+        }
+    } else {
+        if (!validateVertexAttributes(0)) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attribs not setup correctly&quot;);
+            return false;
+        }
+    }
+    
+    const char* reason = &quot;framebuffer incomplete&quot;;
+    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+        return false;
+    }
+    
+    return true;
+}
+
+bool WebGL2RenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
+{
+    switch (mode) {
+    case GraphicsContext3D::FUNC_ADD:
+    case GraphicsContext3D::FUNC_SUBTRACT:
+    case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
+    case GraphicsContext3D::MIN:
+    case GraphicsContext3D::MAX:
+        return true;
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid mode&quot;);
+        return false;
+    }
+}
+
</ins><span class="cx"> bool WebGL2RenderingContext::validateCapability(const char* functionName, GC3Denum cap)
</span><span class="cx"> {
</span><span class="cx">     switch (cap) {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">     void getBufferSubData(GC3Denum target, GC3Dint64 offset, ArrayBuffer* returnedData);
</span><span class="cx">     
</span><span class="cx">     /* Framebuffer objects */
</span><del>-    WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp;);
</del><ins>+    virtual WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp;) override;
</ins><span class="cx">     void blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter);
</span><span class="cx">     void framebufferTextureLayer(GC3Denum target, GC3Denum attachment, GC3Duint texture, GC3Dint level, GC3Dint layer);
</span><span class="cx">     WebGLGetInfo getInternalformatParameter(GC3Denum target, GC3Denum internalformat, GC3Denum pname);
</span><span class="lines">@@ -167,9 +167,10 @@
</span><span class="cx">     /* Extensions */
</span><span class="cx">     virtual WebGLExtension* getExtension(const String&amp;) override;
</span><span class="cx">     virtual Vector&lt;String&gt; getSupportedExtensions() override;
</span><ins>+    virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&amp;) override;
</ins><span class="cx"> 
</span><del>-    virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&amp;) override;
-    
</del><ins>+    virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
+    virtual void hint(GC3Denum target, GC3Denum mode) override;
</ins><span class="cx">     virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
</span><span class="cx">     virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp;) override;
</span><span class="cx">     virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;) override;
</span><span class="lines">@@ -188,6 +189,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><ins>+    virtual bool validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired) override;
+    virtual bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primitiveCount) override;
+    virtual bool validateBlendEquation(const char* functionName, GC3Denum mode) override;
</ins><span class="cx">     virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
</span><span class="cx">     virtual bool validateTexFuncParameters(const char* functionName,
</span><span class="cx">         TexFuncValidationFunctionType,
</span><span class="lines">@@ -204,6 +208,7 @@
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
</span><ins>+    void initializeShaderExtensions();
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContextidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.idl        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -338,7 +338,6 @@
</span><span class="cx">     [StrictTypeChecking] void getBufferSubData(GLenum target, GLintptr offset, ArrayBuffer returnedData);
</span><span class="cx"> 
</span><span class="cx">     /* Framebuffer objects */
</span><del>-    [StrictTypeChecking, Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
</del><span class="cx">     [StrictTypeChecking] void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
</span><span class="cx">     [StrictTypeChecking] void framebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
</span><span class="cx">     [StrictTypeChecking, Custom] any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -287,6 +287,135 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp; ec)
+{
+    UNUSED_PARAM(ec);
+    if (isContextLostOrPending() || !validateFramebufferFuncParameters(&quot;getFramebufferAttachmentParameter&quot;, target, attachment))
+        return WebGLGetInfo();
+    
+    if (!m_framebufferBinding || !m_framebufferBinding-&gt;object()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;getFramebufferAttachmentParameter&quot;, &quot;no framebuffer bound&quot;);
+        return WebGLGetInfo();
+    }
+    
+    WebGLSharedObject* object = m_framebufferBinding-&gt;getAttachmentObject(attachment);
+    if (!object) {
+        if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+            return WebGLGetInfo(GraphicsContext3D::NONE);
+        // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+        // specifies INVALID_OPERATION.
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name&quot;);
+        return WebGLGetInfo();
+    }
+    
+    ASSERT(object-&gt;isTexture() || object-&gt;isRenderbuffer());
+    if (object-&gt;isTexture()) {
+        switch (pname) {
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+            return WebGLGetInfo(GraphicsContext3D::TEXTURE);
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+            return WebGLGetInfo(PassRefPtr&lt;WebGLTexture&gt;(reinterpret_cast&lt;WebGLTexture*&gt;(object)));
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+        case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
+            GC3Dint value = 0;
+            m_context-&gt;getFramebufferAttachmentParameteriv(target, attachment, pname, &amp;value);
+            return WebGLGetInfo(value);
+        }
+        default:
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for texture attachment&quot;);
+            return WebGLGetInfo();
+        }
+    } else {
+        switch (pname) {
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+            return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
+        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+            return WebGLGetInfo(PassRefPtr&lt;WebGLRenderbuffer&gt;(reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object)));
+        case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
+            if (!m_extsRGB) {
+                synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for renderbuffer attachment&quot;);
+                return WebGLGetInfo();
+            }
+            WebGLRenderbuffer* renderBuffer = reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object);
+            GC3Denum renderBufferFormat = renderBuffer-&gt;getInternalFormat();
+            ASSERT(renderBufferFormat != Extensions3D::SRGB_EXT &amp;&amp; renderBufferFormat != Extensions3D::SRGB_ALPHA_EXT);
+            if (renderBufferFormat == Extensions3D::SRGB8_ALPHA8_EXT)
+                return WebGLGetInfo(Extensions3D::SRGB_EXT);
+            return WebGLGetInfo(GraphicsContext3D::LINEAR);
+        }
+        default:
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for renderbuffer attachment&quot;);
+            return WebGLGetInfo();
+        }
+    }
+}
+
+void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
+{
+    if (isContextLostOrPending())
+        return;
+    if (target != GraphicsContext3D::RENDERBUFFER) {
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid target&quot;);
+        return;
+    }
+    if (!m_renderbufferBinding || !m_renderbufferBinding-&gt;object()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;renderbufferStorage&quot;, &quot;no bound renderbuffer&quot;);
+        return;
+    }
+    if (!validateSize(&quot;renderbufferStorage&quot;, width, height))
+        return;
+    switch (internalformat) {
+    case GraphicsContext3D::DEPTH_COMPONENT16:
+    case GraphicsContext3D::RGBA4:
+    case GraphicsContext3D::RGB5_A1:
+    case GraphicsContext3D::RGB565:
+    case GraphicsContext3D::STENCIL_INDEX8:
+    case Extensions3D::SRGB8_ALPHA8_EXT:
+        if (internalformat == Extensions3D::SRGB8_ALPHA8_EXT &amp;&amp; !m_extsRGB) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid internalformat&quot;);
+            return;
+        }
+        m_context-&gt;renderbufferStorage(target, internalformat, width, height);
+        m_renderbufferBinding-&gt;setInternalFormat(internalformat);
+        m_renderbufferBinding-&gt;setIsValid(true);
+        m_renderbufferBinding-&gt;setSize(width, height);
+        break;
+    case GraphicsContext3D::DEPTH_STENCIL:
+        if (isDepthStencilSupported())
+            m_context-&gt;renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
+        m_renderbufferBinding-&gt;setSize(width, height);
+        m_renderbufferBinding-&gt;setIsValid(isDepthStencilSupported());
+        m_renderbufferBinding-&gt;setInternalFormat(internalformat);
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid internalformat&quot;);
+        return;
+    }
+    applyStencilTest();
+}
+
+void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
+{
+    if (isContextLostOrPending())
+        return;
+    bool isValid = false;
+    switch (target) {
+    case GraphicsContext3D::GENERATE_MIPMAP_HINT:
+        isValid = true;
+        break;
+    case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+        if (m_oesStandardDerivatives)
+            isValid = true;
+        break;
+    }
+    if (!isValid) {
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;hint&quot;, &quot;invalid target&quot;);
+        return;
+    }
+    m_context-&gt;hint(target, mode);
+}
+
</ins><span class="cx"> void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
</span><span class="cx"> {
</span><span class="cx">     if (isContextLostOrPending())
</span><span class="lines">@@ -976,6 +1105,168 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WebGLRenderingContext::validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired)
+{
+    // Performs conservative validation by caching a maximum index of
+    // the given type per element array buffer. If all of the bound
+    // array buffers have enough elements to satisfy that maximum
+    // index, skips the expensive per-draw-call iteration in
+    // validateIndexArrayPrecise.
+    
+    RefPtr&lt;WebGLBuffer&gt; elementArrayBuffer = m_boundVertexArrayObject-&gt;getElementArrayBuffer();
+    
+    if (!elementArrayBuffer)
+        return false;
+    
+    GC3Dsizeiptr numElements = elementArrayBuffer-&gt;byteLength();
+    // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
+    if (!numElements)
+        return false;
+    const ArrayBuffer* buffer = elementArrayBuffer-&gt;elementArrayBuffer();
+    ASSERT(buffer);
+    
+    int maxIndex = elementArrayBuffer-&gt;getCachedMaxIndex(type);
+    if (maxIndex &lt; 0) {
+        // Compute the maximum index in the entire buffer for the given type of index.
+        switch (type) {
+        case GraphicsContext3D::UNSIGNED_BYTE: {
+            const GC3Dubyte* p = static_cast&lt;const GC3Dubyte*&gt;(buffer-&gt;data());
+            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
+                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
+            break;
+        }
+        case GraphicsContext3D::UNSIGNED_SHORT: {
+            numElements /= sizeof(GC3Dushort);
+            const GC3Dushort* p = static_cast&lt;const GC3Dushort*&gt;(buffer-&gt;data());
+            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
+                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
+            break;
+        }
+        case GraphicsContext3D::UNSIGNED_INT: {
+            if (!m_oesElementIndexUint)
+                return false;
+            numElements /= sizeof(GC3Duint);
+            const GC3Duint* p = static_cast&lt;const GC3Duint*&gt;(buffer-&gt;data());
+            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
+                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
+            break;
+        }
+        default:
+            return false;
+    }
+    elementArrayBuffer-&gt;setCachedMaxIndex(type, maxIndex);
+    }
+    
+    if (maxIndex &gt;= 0) {
+        // The number of required elements is one more than the maximum
+        // index that will be accessed.
+        numElementsRequired = maxIndex + 1;
+        return true;
+    }
+    
+    return false;
+}
+
+bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primitiveCount)
+{
+    if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
+        return false;
+    
+    if (!validateStencilSettings(functionName))
+        return false;
+    
+    switch (type) {
+    case GraphicsContext3D::UNSIGNED_BYTE:
+    case GraphicsContext3D::UNSIGNED_SHORT:
+        break;
+    case GraphicsContext3D::UNSIGNED_INT:
+        if (m_oesElementIndexUint)
+            break;
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid type&quot;);
+        return false;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid type&quot;);
+        return false;
+    }
+    
+    if (count &lt; 0 || offset &lt; 0) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;count or offset &lt; 0&quot;);
+        return false;
+    }
+    
+    if (!count) {
+        markContextChanged();
+        return false;
+    }
+    
+    if (primitiveCount &lt; 0) {
+        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;primcount &lt; 0&quot;);
+        return false;
+    }
+    
+    if (!m_boundVertexArrayObject-&gt;getElementArrayBuffer()) {
+        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;no ELEMENT_ARRAY_BUFFER bound&quot;);
+        return false;
+    }
+    
+    if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
+        // Ensure we have a valid rendering state
+        if (!validateElementArraySize(count, type, static_cast&lt;GC3Dintptr&gt;(offset))) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;request out of bounds for current ELEMENT_ARRAY_BUFFER&quot;);
+            return false;
+        }
+        if (!count)
+            return false;
+        
+        Checked&lt;GC3Dint, RecordOverflow&gt; checkedCount(count);
+        Checked&lt;GC3Dint, RecordOverflow&gt; checkedPrimitiveCount(primitiveCount);
+        if (checkedCount.hasOverflowed() || checkedPrimitiveCount.hasOverflowed()) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attempt to access out of bounds arrays&quot;);
+            return false;
+        }
+        
+        if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
+            if (!validateIndexArrayPrecise(checkedCount.unsafeGet(), type, static_cast&lt;GC3Dintptr&gt;(offset), numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
+                synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attempt to access out of bounds arrays&quot;);
+                return false;
+            }
+        }
+    } else {
+        if (!validateVertexAttributes(0)) {
+            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attribs not setup correctly&quot;);
+            return false;
+        }
+    }
+    
+    const char* reason = &quot;framebuffer incomplete&quot;;
+    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+        return false;
+    }
+    
+    return true;
+}
+
+bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
+{
+    switch (mode) {
+    case GraphicsContext3D::FUNC_ADD:
+    case GraphicsContext3D::FUNC_SUBTRACT:
+    case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
+    case Extensions3D::MIN_EXT:
+    case Extensions3D::MAX_EXT:
+        if ((mode == Extensions3D::MIN_EXT || mode == Extensions3D::MAX_EXT) &amp;&amp; !m_extBlendMinMax) {
+            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid mode&quot;);
+            return false;
+        }
+        return true;
+        break;
+    default:
+        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid mode&quot;);
+        return false;
+    }
+}
+
</ins><span class="cx"> bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap)
</span><span class="cx"> {
</span><span class="cx">     switch (cap) {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -40,6 +40,9 @@
</span><span class="cx">     virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&amp;) override;
</span><span class="cx">     virtual Vector&lt;String&gt; getSupportedExtensions() override;
</span><span class="cx"> 
</span><ins>+    virtual WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp;) override;
+    virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) override;
+    virtual void hint(GC3Denum target, GC3Denum mode) override;
</ins><span class="cx">     virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
</span><span class="cx">     virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&amp;) override;
</span><span class="cx">     virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&amp;) override;
</span><span class="lines">@@ -58,6 +61,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><ins>+    virtual bool validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired) override;
+    virtual bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primitiveCount) override;
+    virtual bool validateBlendEquation(const char* functionName, GC3Denum mode) override;
</ins><span class="cx">     virtual bool validateTexFuncParameters(const char* functionName,
</span><span class="cx">         TexFuncValidationFunctionType,
</span><span class="cx">         GC3Denum target, GC3Dint level,
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -1720,68 +1720,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebGLRenderingContextBase::validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired)
-{
-    // Performs conservative validation by caching a maximum index of
-    // the given type per element array buffer. If all of the bound
-    // array buffers have enough elements to satisfy that maximum
-    // index, skips the expensive per-draw-call iteration in
-    // validateIndexArrayPrecise.
-    
-    RefPtr&lt;WebGLBuffer&gt; elementArrayBuffer = m_boundVertexArrayObject-&gt;getElementArrayBuffer();
-
-    if (!elementArrayBuffer)
-        return false;
-
-    GC3Dsizeiptr numElements = elementArrayBuffer-&gt;byteLength();
-    // The case count==0 is already dealt with in drawElements before validateIndexArrayConservative.
-    if (!numElements)
-        return false;
-    const ArrayBuffer* buffer = elementArrayBuffer-&gt;elementArrayBuffer();
-    ASSERT(buffer);
-
-    int maxIndex = elementArrayBuffer-&gt;getCachedMaxIndex(type);
-    if (maxIndex &lt; 0) {
-        // Compute the maximum index in the entire buffer for the given type of index.
-        switch (type) {
-        case GraphicsContext3D::UNSIGNED_BYTE: {
-            const GC3Dubyte* p = static_cast&lt;const GC3Dubyte*&gt;(buffer-&gt;data());
-            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
-                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
-            break;
-        }
-        case GraphicsContext3D::UNSIGNED_SHORT: {
-            numElements /= sizeof(GC3Dushort);
-            const GC3Dushort* p = static_cast&lt;const GC3Dushort*&gt;(buffer-&gt;data());
-            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
-                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
-            break;
-        }
-        case GraphicsContext3D::UNSIGNED_INT: {
-            if (!m_oesElementIndexUint)
-                return false;
-            numElements /= sizeof(GC3Duint);
-            const GC3Duint* p = static_cast&lt;const GC3Duint*&gt;(buffer-&gt;data());
-            for (GC3Dsizeiptr i = 0; i &lt; numElements; i++)
-                maxIndex = std::max(maxIndex, static_cast&lt;int&gt;(p[i]));
-            break;
-        }
-        default:
-            return false;
-        }
-        elementArrayBuffer-&gt;setCachedMaxIndex(type, maxIndex);
-    }
-
-    if (maxIndex &gt;= 0) {
-        // The number of required elements is one more than the maximum
-        // index that will be accessed.
-        numElementsRequired = maxIndex + 1;
-        return true;
-    }
-
-    return false;
-}
-
</del><span class="cx"> bool WebGLRenderingContextBase::validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned&amp; numElementsRequired)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(count &gt;= 0 &amp;&amp; offset &gt;= 0);
</span><span class="lines">@@ -1974,86 +1912,6 @@
</span><span class="cx">     markContextChanged();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primitiveCount)
-{
-    if (isContextLostOrPending() || !validateDrawMode(functionName, mode))
-        return false;
-
-    if (!validateStencilSettings(functionName))
-        return false;
-
-    switch (type) {
-    case GraphicsContext3D::UNSIGNED_BYTE:
-    case GraphicsContext3D::UNSIGNED_SHORT:
-        break;
-    case GraphicsContext3D::UNSIGNED_INT:
-        if (m_oesElementIndexUint)
-            break;
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid type&quot;);
-        return false;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid type&quot;);
-        return false;
-    }
-
-    if (count &lt; 0 || offset &lt; 0) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;count or offset &lt; 0&quot;);
-        return false;
-    }
-
-    if (!count) {
-        markContextChanged();
-        return false;
-    }
-
-    if (primitiveCount &lt; 0) {
-        synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, &quot;primcount &lt; 0&quot;);
-        return false;
-    }
-
-    if (!m_boundVertexArrayObject-&gt;getElementArrayBuffer()) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;no ELEMENT_ARRAY_BUFFER bound&quot;);
-        return false;
-    }
-
-    if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
-        // Ensure we have a valid rendering state
-        if (!validateElementArraySize(count, type, static_cast&lt;GC3Dintptr&gt;(offset))) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;request out of bounds for current ELEMENT_ARRAY_BUFFER&quot;);
-            return false;
-        }
-        if (!count)
-            return false;
-
-        Checked&lt;GC3Dint, RecordOverflow&gt; checkedCount(count);
-        Checked&lt;GC3Dint, RecordOverflow&gt; checkedPrimitiveCount(primitiveCount);
-        if (checkedCount.hasOverflowed() || checkedPrimitiveCount.hasOverflowed()) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attempt to access out of bounds arrays&quot;);
-            return false;
-        }
-
-        if (!validateIndexArrayConservative(type, numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
-            if (!validateIndexArrayPrecise(checkedCount.unsafeGet(), type, static_cast&lt;GC3Dintptr&gt;(offset), numElements) || !validateVertexAttributes(numElements, checkedPrimitiveCount.unsafeGet())) {
-                synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attempt to access out of bounds arrays&quot;);
-                return false;
-            }
-        }
-    } else {
-        if (!validateVertexAttributes(0)) {
-            synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, &quot;attribs not setup correctly&quot;);
-            return false;
-        }
-    }
-
-    const char* reason = &quot;framebuffer incomplete&quot;;
-    if (m_framebufferBinding &amp;&amp; !m_framebufferBinding-&gt;onAccess(graphicsContext3D(), !isResourceSafe(), &amp;reason)) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
-        return false;
-    }
-
-    return true;
-}
-
</del><span class="cx"> void WebGLRenderingContextBase::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(ec);
</span><span class="lines">@@ -2363,229 +2221,6 @@
</span><span class="cx">     return m_context-&gt;getError();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebGLExtension* WebGLRenderingContextBase::getExtension(const String&amp; name)
-{
-    if (isContextLostOrPending())
-        return nullptr;
-
-    if (equalIgnoringCase(name, &quot;EXT_blend_minmax&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_EXT_blend_minmax&quot;)) {
-        if (!m_extBlendMinMax) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_blend_minmax&quot;);
-            m_extBlendMinMax = std::make_unique&lt;EXTBlendMinMax&gt;(this);
-        }
-        return m_extBlendMinMax.get();
-    }
-    if (equalIgnoringCase(name, &quot;EXT_sRGB&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_EXT_sRGB&quot;)) {
-        if (!m_extsRGB) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_sRGB&quot;);
-            m_extsRGB = std::make_unique&lt;EXTsRGB&gt;(this);
-        }
-        return m_extsRGB.get();
-    }
-    if (equalIgnoringCase(name, &quot;EXT_frag_depth&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_EXT_frag_depth&quot;)) {
-        if (!m_extFragDepth) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_frag_depth&quot;);
-            m_extFragDepth = std::make_unique&lt;EXTFragDepth&gt;(this);
-        }
-        return m_extFragDepth.get();
-    }
-    if (equalIgnoringCase(name, &quot;EXT_shader_texture_lod&quot;)
-        &amp;&amp; (m_context-&gt;getExtensions()-&gt;supports(&quot;GL_EXT_shader_texture_lod&quot;) || m_context-&gt;getExtensions()-&gt;supports(&quot;GL_ARB_shader_texture_lod&quot;))) {
-        if (!m_extShaderTextureLOD) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_shader_texture_lod&quot;);
-            m_extShaderTextureLOD = std::make_unique&lt;EXTShaderTextureLOD&gt;(this);
-        }
-        return m_extShaderTextureLOD.get();
-    }
-    if (equalIgnoringCase(name, &quot;WEBKIT_EXT_texture_filter_anisotropic&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_EXT_texture_filter_anisotropic&quot;)) {
-        if (!m_extTextureFilterAnisotropic) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_texture_filter_anisotropic&quot;);
-            m_extTextureFilterAnisotropic = std::make_unique&lt;EXTTextureFilterAnisotropic&gt;(this);
-        }
-        return m_extTextureFilterAnisotropic.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_standard_derivatives&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_standard_derivatives&quot;)) {
-        if (!m_oesStandardDerivatives) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_standard_derivatives&quot;);
-            m_oesStandardDerivatives = std::make_unique&lt;OESStandardDerivatives&gt;(this);
-        }
-        return m_oesStandardDerivatives.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_texture_float&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_texture_float&quot;)) {
-        if (!m_oesTextureFloat) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_texture_float&quot;);
-            m_oesTextureFloat = std::make_unique&lt;OESTextureFloat&gt;(this);
-        }
-        return m_oesTextureFloat.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_texture_float_linear&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_texture_float_linear&quot;)) {
-        if (!m_oesTextureFloatLinear) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_texture_float_linear&quot;);
-            m_oesTextureFloatLinear = std::make_unique&lt;OESTextureFloatLinear&gt;(this);
-        }
-        return m_oesTextureFloatLinear.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_texture_half_float&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_texture_half_float&quot;)) {
-        if (!m_oesTextureHalfFloat) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_texture_half_float&quot;);
-            m_oesTextureHalfFloat = std::make_unique&lt;OESTextureHalfFloat&gt;(this);
-        }
-        return m_oesTextureHalfFloat.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_texture_half_float_linear&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_texture_half_float_linear&quot;)) {
-        if (!m_oesTextureHalfFloatLinear) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_texture_half_float_linear&quot;);
-            m_oesTextureHalfFloatLinear = std::make_unique&lt;OESTextureHalfFloatLinear&gt;(this);
-        }
-        return m_oesTextureHalfFloatLinear.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_vertex_array_object&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_vertex_array_object&quot;)) {
-        if (!m_oesVertexArrayObject) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_vertex_array_object&quot;);
-            m_oesVertexArrayObject = std::make_unique&lt;OESVertexArrayObject&gt;(this);
-        }
-        return m_oesVertexArrayObject.get();
-    }
-    if (equalIgnoringCase(name, &quot;OES_element_index_uint&quot;)
-        &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_OES_element_index_uint&quot;)) {
-        if (!m_oesElementIndexUint) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_OES_element_index_uint&quot;);
-            m_oesElementIndexUint = std::make_unique&lt;OESElementIndexUint&gt;(this);
-        }
-        return m_oesElementIndexUint.get();
-    }
-    if (equalIgnoringCase(name, &quot;WEBGL_lose_context&quot;)) {
-        if (!m_webglLoseContext)
-            m_webglLoseContext = std::make_unique&lt;WebGLLoseContext&gt;(this);
-        return m_webglLoseContext.get();
-    }
-    if ((equalIgnoringCase(name, &quot;WEBKIT_WEBGL_compressed_texture_atc&quot;))
-        &amp;&amp; WebGLCompressedTextureATC::supported(this)) {
-        if (!m_webglCompressedTextureATC)
-            m_webglCompressedTextureATC = std::make_unique&lt;WebGLCompressedTextureATC&gt;(this);
-        return m_webglCompressedTextureATC.get();
-    }
-    if ((equalIgnoringCase(name, &quot;WEBKIT_WEBGL_compressed_texture_pvrtc&quot;))
-        &amp;&amp; WebGLCompressedTexturePVRTC::supported(this)) {
-        if (!m_webglCompressedTexturePVRTC)
-            m_webglCompressedTexturePVRTC = std::make_unique&lt;WebGLCompressedTexturePVRTC&gt;(this);
-        return m_webglCompressedTexturePVRTC.get();
-    }
-    if (equalIgnoringCase(name, &quot;WEBGL_compressed_texture_s3tc&quot;)
-        &amp;&amp; WebGLCompressedTextureS3TC::supported(this)) {
-        if (!m_webglCompressedTextureS3TC)
-            m_webglCompressedTextureS3TC = std::make_unique&lt;WebGLCompressedTextureS3TC&gt;(this);
-        return m_webglCompressedTextureS3TC.get();
-    }
-    if (equalIgnoringCase(name, &quot;WEBGL_depth_texture&quot;)
-        &amp;&amp; WebGLDepthTexture::supported(graphicsContext3D())) {
-        if (!m_webglDepthTexture) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_CHROMIUM_depth_texture&quot;);
-            m_webglDepthTexture = std::make_unique&lt;WebGLDepthTexture&gt;(this);
-        }
-        return m_webglDepthTexture.get();
-    }
-    if (equalIgnoringCase(name, &quot;WEBGL_draw_buffers&quot;) &amp;&amp; supportsDrawBuffers()) {
-        if (!m_webglDrawBuffers) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_EXT_draw_buffers&quot;);
-            m_webglDrawBuffers = std::make_unique&lt;WebGLDrawBuffers&gt;(this);
-        }
-        return m_webglDrawBuffers.get();
-    }
-    if (equalIgnoringCase(name, &quot;ANGLE_instanced_arrays&quot;) &amp;&amp; ANGLEInstancedArrays::supported(this)) {
-        if (!m_angleInstancedArrays) {
-            m_context-&gt;getExtensions()-&gt;ensureEnabled(&quot;GL_ANGLE_instanced_arrays&quot;);
-            m_angleInstancedArrays = std::make_unique&lt;ANGLEInstancedArrays&gt;(this);
-        }
-        return m_angleInstancedArrays.get();
-    }
-    if (allowPrivilegedExtensions()) {
-        if (equalIgnoringCase(name, &quot;WEBGL_debug_renderer_info&quot;)) {
-            if (!m_webglDebugRendererInfo)
-                m_webglDebugRendererInfo = std::make_unique&lt;WebGLDebugRendererInfo&gt;(this);
-            return m_webglDebugRendererInfo.get();
-        }
-        if (equalIgnoringCase(name, &quot;WEBGL_debug_shaders&quot;)
-            &amp;&amp; m_context-&gt;getExtensions()-&gt;supports(&quot;GL_ANGLE_translated_shader_source&quot;)) {
-            if (!m_webglDebugShaders)
-                m_webglDebugShaders = std::make_unique&lt;WebGLDebugShaders&gt;(this);
-            return m_webglDebugShaders.get();
-        }
-    }
-
-    return nullptr;
-}
-
-WebGLGetInfo WebGLRenderingContextBase::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp; ec)
-{
-    UNUSED_PARAM(ec);
-    if (isContextLostOrPending() || !validateFramebufferFuncParameters(&quot;getFramebufferAttachmentParameter&quot;, target, attachment))
-        return WebGLGetInfo();
-
-    if (!m_framebufferBinding || !m_framebufferBinding-&gt;object()) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;getFramebufferAttachmentParameter&quot;, &quot;no framebuffer bound&quot;);
-        return WebGLGetInfo();
-    }
-
-    WebGLSharedObject* object = m_framebufferBinding-&gt;getAttachmentObject(attachment);
-    if (!object) {
-        if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
-            return WebGLGetInfo(GraphicsContext3D::NONE);
-        // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
-        // specifies INVALID_OPERATION.
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name&quot;);
-        return WebGLGetInfo();
-    }
-
-    ASSERT(object-&gt;isTexture() || object-&gt;isRenderbuffer());
-    if (object-&gt;isTexture()) {
-        switch (pname) {
-        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-            return WebGLGetInfo(GraphicsContext3D::TEXTURE);
-        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-            return WebGLGetInfo(PassRefPtr&lt;WebGLTexture&gt;(reinterpret_cast&lt;WebGLTexture*&gt;(object)));
-        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
-        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-        case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
-            GC3Dint value = 0;
-            m_context-&gt;getFramebufferAttachmentParameteriv(target, attachment, pname, &amp;value);
-            return WebGLGetInfo(value);
-        }
-        default:
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for texture attachment&quot;);
-            return WebGLGetInfo();
-        }
-    } else {
-        switch (pname) {
-        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-            return WebGLGetInfo(GraphicsContext3D::RENDERBUFFER);
-        case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-            return WebGLGetInfo(PassRefPtr&lt;WebGLRenderbuffer&gt;(reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object)));
-        case Extensions3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: {
-            WebGLRenderbuffer* renderBuffer = reinterpret_cast&lt;WebGLRenderbuffer*&gt;(object);
-            GC3Denum renderBufferFormat = renderBuffer-&gt;getInternalFormat();
-            ASSERT(renderBufferFormat != Extensions3D::SRGB_EXT &amp;&amp; renderBufferFormat != Extensions3D::SRGB_ALPHA_EXT);
-            if (renderBufferFormat == Extensions3D::SRGB8_ALPHA8_EXT)
-                return WebGLGetInfo(Extensions3D::SRGB_EXT);
-            return WebGLGetInfo(GraphicsContext3D::LINEAR);
-        }
-        default:
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;getFramebufferAttachmentParameter&quot;, &quot;invalid parameter name for renderbuffer attachment&quot;);
-            return WebGLGetInfo();
-        }
-    }
-}
-
</del><span class="cx"> WebGLGetInfo WebGLRenderingContextBase::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(ec);
</span><span class="lines">@@ -3003,27 +2638,6 @@
</span><span class="cx">     return static_cast&lt;long long&gt;(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContextBase::hint(GC3Denum target, GC3Denum mode)
-{
-    if (isContextLostOrPending())
-        return;
-    bool isValid = false;
-    switch (target) {
-    case GraphicsContext3D::GENERATE_MIPMAP_HINT:
-        isValid = true;
-        break;
-    case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
-        if (m_oesStandardDerivatives)
-            isValid = true;
-        break;
-    }
-    if (!isValid) {
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;hint&quot;, &quot;invalid target&quot;);
-        return;
-    }
-    m_context-&gt;hint(target, mode);
-}
-
</del><span class="cx"> GC3Dboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
</span><span class="cx"> {
</span><span class="cx">     if (!buffer || isContextLostOrPending())
</span><span class="lines">@@ -3283,51 +2897,6 @@
</span><span class="cx">     m_context-&gt;releaseShaderCompiler();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebGLRenderingContextBase::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
-    if (isContextLostOrPending())
-        return;
-    if (target != GraphicsContext3D::RENDERBUFFER) {
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid target&quot;);
-        return;
-    }
-    if (!m_renderbufferBinding || !m_renderbufferBinding-&gt;object()) {
-        synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, &quot;renderbufferStorage&quot;, &quot;no bound renderbuffer&quot;);
-        return;
-    }
-    if (!validateSize(&quot;renderbufferStorage&quot;, width, height))
-        return;
-    switch (internalformat) {
-    case GraphicsContext3D::DEPTH_COMPONENT16:
-    case GraphicsContext3D::RGBA4:
-    case GraphicsContext3D::RGB5_A1:
-    case GraphicsContext3D::RGB565:
-    case GraphicsContext3D::STENCIL_INDEX8:
-    case Extensions3D::SRGB8_ALPHA8_EXT:
-        if (internalformat == Extensions3D::SRGB8_ALPHA8_EXT &amp;&amp; !m_extsRGB) {
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid internalformat&quot;);
-            return;
-        }
-        m_context-&gt;renderbufferStorage(target, internalformat, width, height);
-        m_renderbufferBinding-&gt;setInternalFormat(internalformat);
-        m_renderbufferBinding-&gt;setIsValid(true);
-        m_renderbufferBinding-&gt;setSize(width, height);
-        break;
-    case GraphicsContext3D::DEPTH_STENCIL:
-        if (isDepthStencilSupported()) {
-            m_context-&gt;renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
-        }
-        m_renderbufferBinding-&gt;setSize(width, height);
-        m_renderbufferBinding-&gt;setIsValid(isDepthStencilSupported());
-        m_renderbufferBinding-&gt;setInternalFormat(internalformat);
-        break;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, &quot;renderbufferStorage&quot;, &quot;invalid internalformat&quot;);
-        return;
-    }
-    applyStencilTest();
-}
-
</del><span class="cx"> void WebGLRenderingContextBase::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
</span><span class="cx"> {
</span><span class="cx">     if (isContextLostOrPending())
</span><span class="lines">@@ -4883,26 +4452,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebGLRenderingContextBase::validateBlendEquation(const char* functionName, GC3Denum mode)
-{
-    switch (mode) {
-    case GraphicsContext3D::FUNC_ADD:
-    case GraphicsContext3D::FUNC_SUBTRACT:
-    case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
-    case Extensions3D::MIN_EXT:
-    case Extensions3D::MAX_EXT:
-        if ((mode == Extensions3D::MIN_EXT || mode == Extensions3D::MAX_EXT) &amp;&amp; !m_extBlendMinMax) {
-            synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid mode&quot;);
-            return false;
-        }
-        return true;
-        break;
-    default:
-        synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, &quot;invalid mode&quot;);
-        return false;
-    }
-}
-
</del><span class="cx"> bool WebGLRenderingContextBase::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
</span><span class="cx"> {
</span><span class="cx">     if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (180284 => 180285)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2015-02-18 20:15:53 UTC (rev 180284)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2015-02-18 20:42:53 UTC (rev 180285)
</span><span class="lines">@@ -226,7 +226,7 @@
</span><span class="cx">     PassRefPtr&lt;WebGLContextAttributes&gt; getContextAttributes();
</span><span class="cx">     GC3Denum getError();
</span><span class="cx">     virtual WebGLExtension* getExtension(const String&amp; name) = 0;
</span><del>-    WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp;);
</del><ins>+    virtual WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&amp;) = 0;
</ins><span class="cx">     virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&amp;) = 0;
</span><span class="cx">     WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname, ExceptionCode&amp;);
</span><span class="cx">     String getProgramInfoLog(WebGLProgram*, ExceptionCode&amp;);
</span><span class="lines">@@ -242,7 +242,7 @@
</span><span class="cx">     WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname, ExceptionCode&amp;);
</span><span class="cx">     long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
</span><span class="cx"> 
</span><del>-    void hint(GC3Denum target, GC3Denum mode);
</del><ins>+    virtual void hint(GC3Denum target, GC3Denum mode) = 0;
</ins><span class="cx">     GC3Dboolean isBuffer(WebGLBuffer*);
</span><span class="cx">     bool isContextLost() const;
</span><span class="cx">     GC3Dboolean isEnabled(GC3Denum cap);
</span><span class="lines">@@ -258,7 +258,7 @@
</span><span class="cx">     void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
</span><span class="cx">     void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&amp;);
</span><span class="cx">     void releaseShaderCompiler();
</span><del>-    void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
</del><ins>+    virtual void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height) = 0;
</ins><span class="cx">     void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
</span><span class="cx">     void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
</span><span class="cx">     void shaderSource(WebGLShader*, const String&amp;, ExceptionCode&amp;);
</span><span class="lines">@@ -398,7 +398,7 @@
</span><span class="cx">     friend class WebGLRenderingContextErrorMessageCallback;
</span><span class="cx">     friend class WebGLVertexArrayObjectOES;
</span><span class="cx"> 
</span><del>-    void initializeNewContext();
</del><ins>+    virtual void initializeNewContext();
</ins><span class="cx">     void setupFlags();
</span><span class="cx"> 
</span><span class="cx">     // ActiveDOMObject
</span><span class="lines">@@ -432,7 +432,7 @@
</span><span class="cx">     bool validateElementArraySize(GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
</span><span class="cx"> 
</span><span class="cx">     // Conservative but quick index validation
</span><del>-    bool validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired);
</del><ins>+    virtual bool validateIndexArrayConservative(GC3Denum type, unsigned&amp; numElementsRequired) = 0;
</ins><span class="cx"> 
</span><span class="cx">     // Precise but slow index validation -- only done if conservative checks fail
</span><span class="cx">     bool validateIndexArrayPrecise(GC3Dsizei count, GC3Denum type, GC3Dintptr offset, unsigned&amp; numElementsRequired);
</span><span class="lines">@@ -441,7 +441,7 @@
</span><span class="cx">     bool validateWebGLObject(const char*, WebGLObject*);
</span><span class="cx"> 
</span><span class="cx">     bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
</span><del>-    bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primcount);
</del><ins>+    virtual bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset, unsigned&amp; numElements, GC3Dsizei primcount) = 0;
</ins><span class="cx"> 
</span><span class="cx">     // Adds a compressed texture format.
</span><span class="cx">     void addCompressedTextureFormat(GC3Denum);
</span><span class="lines">@@ -770,7 +770,7 @@
</span><span class="cx">     bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
</span><span class="cx"> 
</span><span class="cx">     // Helper function to validate blend equation mode.
</span><del>-    bool validateBlendEquation(const char* functionName, GC3Denum);
</del><ins>+    virtual bool validateBlendEquation(const char* functionName, GC3Denum) = 0;
</ins><span class="cx"> 
</span><span class="cx">     // Helper function to validate blend func factors.
</span><span class="cx">     bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
</span></span></pre>
</div>
</div>

</body>
</html>