<!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>[179842] 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/179842">179842</a></dd>
<dt>Author</dt> <dd>roger_fong@apple.com</dd>
<dt>Date</dt> <dd>2015-02-09 12:50:15 -0800 (Mon, 09 Feb 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>WebGL 2: Texture call format, internal format, and type validation.
https://bugs.webkit.org/show_bug.cgi?id=141318.
<rdar://problem/19733828>
Reviewed by Brent Fulgham.
Tests will be covered by WebGL2 conformance tests.
* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Add missing ExceptionCode argument.
(WebCore::WebGL2RenderingContext::copyTexImage2D): Validate texture formats based on GLES3 spec.
(WebCore::WebGL2RenderingContext::texSubImage2DBase): Validate using internal format from texture target.
(WebCore::WebGL2RenderingContext::texSubImage2DImpl): Validate using internal format from texture target.
(WebCore::WebGL2RenderingContext::texSubImage2D): Validate using internal format from texture target.
(WebCore::WebGL2RenderingContext::validateTexFuncParameters): Do extra validation for copyTexImage2D.
(WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Validate internal format, format and type combination.
(WebCore::WebGL2RenderingContext::validateTexFuncData): Validate new data types.
This method now accepts an internal format argument.
(WebCore::WebGL2RenderingContext::baseInternalFormatFromInternalFormat):
Helper method to convert internal format to base internal format.
* html/canvas/WebGL2RenderingContext.h:
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::copyTexImage2D): Moved from WebGLRenderingContextBase.
(WebCore::WebGLRenderingContext::texSubImage2DBase): Ditto.
(WebCore::WebGLRenderingContext::texSubImage2DImpl): Ditto.
(WebCore::WebGLRenderingContext::texSubImage2D): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncParameters): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncData): Ditto.
* html/canvas/WebGLRenderingContext.h:
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::texImage2DBase):
(WebCore::WebGLRenderingContextBase::validateTexFunc):
(WebCore::WebGLRenderingContextBase::texImage2D):
(WebCore::WebGLRenderingContextBase::copyTexImage2D): Deleted.
(WebCore::WebGLRenderingContextBase::texSubImage2DBase): Deleted.
(WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Deleted.
(WebCore::WebGLRenderingContextBase::texSubImage2D): Deleted.
(WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Deleted.
(WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Deleted.
(WebCore::WebGLRenderingContextBase::validateTexFuncData): Deleted.
* html/canvas/WebGLRenderingContextBase.h: Modify validation type enums to differentiate between CopyImage, TexImage and TexSubImage calls.
(WebCore::ScopedDrawingBufferBinder::ScopedDrawingBufferBinder): Moved from WebGLRenderingContextBase.
(WebCore::ScopedDrawingBufferBinder::~ScopedDrawingBufferBinder): Ditto.
(WebCore::clip1D): Ditto.
(WebCore::clip2D): Ditto.
* platform/graphics/GraphicsContext3D.h: Rename a typo'ed enum.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</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="#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>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh">trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/ChangeLog        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2015-02-07 Roger Fong <roger_fong@apple.com>
+
+ WebGL 2: Texture call format, internal format, and type validation.
+ https://bugs.webkit.org/show_bug.cgi?id=141318.
+ <rdar://problem/19733828>
+
+ Reviewed by Brent Fulgham.
+
+ Tests will be covered by WebGL2 conformance tests.
+
+ * html/canvas/WebGL2RenderingContext.cpp:
+ (WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Add missing ExceptionCode argument.
+ (WebCore::WebGL2RenderingContext::copyTexImage2D): Validate texture formats based on GLES3 spec.
+ (WebCore::WebGL2RenderingContext::texSubImage2DBase): Validate using internal format from texture target.
+ (WebCore::WebGL2RenderingContext::texSubImage2DImpl): Validate using internal format from texture target.
+ (WebCore::WebGL2RenderingContext::texSubImage2D): Validate using internal format from texture target.
+ (WebCore::WebGL2RenderingContext::validateTexFuncParameters): Do extra validation for copyTexImage2D.
+ (WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Validate internal format, format and type combination.
+ (WebCore::WebGL2RenderingContext::validateTexFuncData): Validate new data types.
+ This method now accepts an internal format argument.
+ (WebCore::WebGL2RenderingContext::baseInternalFormatFromInternalFormat):
+ Helper method to convert internal format to base internal format.
+ * html/canvas/WebGL2RenderingContext.h:
+
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::copyTexImage2D): Moved from WebGLRenderingContextBase.
+ (WebCore::WebGLRenderingContext::texSubImage2DBase): Ditto.
+ (WebCore::WebGLRenderingContext::texSubImage2DImpl): Ditto.
+ (WebCore::WebGLRenderingContext::texSubImage2D): Ditto.
+ (WebCore::WebGLRenderingContext::validateTexFuncParameters): Ditto.
+ (WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Ditto.
+ (WebCore::WebGLRenderingContext::validateTexFuncData): Ditto.
+ * html/canvas/WebGLRenderingContext.h:
+
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::texImage2DBase):
+ (WebCore::WebGLRenderingContextBase::validateTexFunc):
+ (WebCore::WebGLRenderingContextBase::texImage2D):
+ (WebCore::WebGLRenderingContextBase::copyTexImage2D): Deleted.
+ (WebCore::WebGLRenderingContextBase::texSubImage2DBase): Deleted.
+ (WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Deleted.
+ (WebCore::WebGLRenderingContextBase::texSubImage2D): Deleted.
+ (WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Deleted.
+ (WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Deleted.
+ (WebCore::WebGLRenderingContextBase::validateTexFuncData): Deleted.
+ * html/canvas/WebGLRenderingContextBase.h: Modify validation type enums to differentiate between CopyImage, TexImage and TexSubImage calls.
+ (WebCore::ScopedDrawingBufferBinder::ScopedDrawingBufferBinder): Moved from WebGLRenderingContextBase.
+ (WebCore::ScopedDrawingBufferBinder::~ScopedDrawingBufferBinder): Ditto.
+ (WebCore::clip1D): Ditto.
+ (WebCore::clip2D): Ditto.
+ * platform/graphics/GraphicsContext3D.h: Rename a typo'ed enum.
+
</ins><span class="cx"> 2015-02-09 Commit Queue <commit-queue@webkit.org>
</span><span class="cx">
</span><span class="cx"> Unreviewed, rolling out r179494.
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -28,16 +28,23 @@
</span><span class="cx"> #if ENABLE(WEBGL)
</span><span class="cx"> #include "WebGL2RenderingContext.h"
</span><span class="cx">
</span><ins>+#include "CachedImage.h"
</ins><span class="cx"> #include "EXTTextureFilterAnisotropic.h"
</span><span class="cx"> #include "Extensions3D.h"
</span><ins>+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "ImageData.h"
</ins><span class="cx"> #include "OESTextureFloat.h"
</span><span class="cx"> #include "OESTextureFloatLinear.h"
</span><span class="cx"> #include "OESTextureHalfFloat.h"
</span><span class="cx"> #include "OESTextureHalfFloatLinear.h"
</span><ins>+#include "RenderBox.h"
</ins><span class="cx"> #include "WebGLActiveInfo.h"
</span><span class="cx"> #include "WebGLCompressedTextureATC.h"
</span><span class="cx"> #include "WebGLCompressedTexturePVRTC.h"
</span><span class="cx"> #include "WebGLCompressedTextureS3TC.h"
</span><ins>+#include "WebGLContextAttributes.h"
</ins><span class="cx"> #include "WebGLDebugRendererInfo.h"
</span><span class="cx"> #include "WebGLDebugShaders.h"
</span><span class="cx"> #include "WebGLDepthTexture.h"
</span><span class="lines">@@ -82,11 +89,12 @@
</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)
</del><ins>+WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
</ins><span class="cx"> {
</span><span class="cx"> UNUSED_PARAM(target);
</span><span class="cx"> UNUSED_PARAM(attachment);
</span><span class="cx"> UNUSED_PARAM(pname);
</span><ins>+ UNUSED_PARAM(ec);
</ins><span class="cx"> return WebGLGetInfo();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -900,6 +908,812 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebGL2RenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+{
+ if (isContextLostOrPending())
+ return;
+ RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
+ GC3Denum bufferFormat = attributes->alpha() ? GraphicsContext3D::RGBA : GraphicsContext3D::RGB;
+ if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalformat, width, height, border, bufferFormat, GraphicsContext3D::UNSIGNED_BYTE))
+ return;
+ if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ if (isResourceSafe()) {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ } else {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
+ internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
+ if (clippedWidth > 0 && clippedHeight > 0) {
+ m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
+ clippedX, clippedY, clippedWidth, clippedHeight);
+ }
+ } else
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ }
+ // FIXME: if the framebuffer is not complete, none of the below should be executed.
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+}
+
+void WebGL2RenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
+{
+ ec = 0;
+ ASSERT(!isContextLost());
+ if (!validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, internalformat, width, height, 0, format, type))
+ return;
+ ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
+ ASSERT(validateSettableTexFormat("texSubImage2D", format));
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ if (!tex) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT((xoffset + width) >= 0);
+ ASSERT((yoffset + height) >= 0);
+ ASSERT(tex->getWidth(target, level) >= (xoffset + width));
+ ASSERT(tex->getHeight(target, level) >= (yoffset + height));
+ ASSERT(tex->getInternalFormat(target, level) == format);
+ ASSERT(tex->getType(target, level) == type);
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGL2RenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ Vector<uint8_t> data;
+ GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
+ return;
+ }
+ GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ GC3Denum internalformat = tex->getInternalFormat(target, level);
+ texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), internalformat, format, type, needConversion ? data.data() : imagePixelData, ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
+{
+ if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, GraphicsContext3D::NONE, format, type, pixels, NullNotAllowed) || !validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, GraphicsContext3D::NONE, width, height, 0, format, type, xoffset, yoffset))
+ return;
+
+ void* data = pixels->baseAddress();
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!m_context->extractTextureData(width, height, format, type,
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ GC3Denum internalformat = tex->getInternalFormat(target, level);
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, internalformat, format, type, data, ec);
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, GraphicsContext3D::NONE, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
+ needConversion = false;
+ else {
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ GC3Denum internalformat = tex->getInternalFormat(target, level);
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), internalformat, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec))
+ return;
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
+
+ if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, GraphicsContext3D::NONE, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
+ || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, GraphicsContext3D::NONE, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
+ else
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+#if ENABLE(VIDEO)
+void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec)
+ || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, GraphicsContext3D::NONE, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
+ if (!image)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+#endif
+
+bool WebGL2RenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
+{
+ if (functionType == CopyTexImage) {
+ GC3Denum framebufferInternalFormat = 0;
+ WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(GraphicsContext3D::COLOR_ATTACHMENT0);
+ if (object->isTexture()) {
+ WebGLTexture* texture = reinterpret_cast<WebGLTexture*>(object);
+ framebufferInternalFormat = baseInternalFormatFromInternalFormat(texture->getInternalFormat(GraphicsContext3D::TEXTURE_2D, 0));
+ } else if (object->isRenderbuffer()) {
+ WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object);
+ framebufferInternalFormat = baseInternalFormatFromInternalFormat(renderBuffer->getInternalFormat());
+ }
+
+ GC3Denum baseTextureInternalFormat = baseInternalFormatFromInternalFormat(internalformat);
+ bool validFormatCombination = true;
+ switch (framebufferInternalFormat) {
+ case GraphicsContext3D::RED:
+ if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED)
+ validFormatCombination = false;
+ break;
+ case GraphicsContext3D::RG:
+ if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG)
+ validFormatCombination = false;
+ break;
+ case GraphicsContext3D::RGB:
+ if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB)
+ validFormatCombination = false;
+ break;
+ case GraphicsContext3D::RGBA:
+ if (baseTextureInternalFormat != GraphicsContext3D::ALPHA && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE_ALPHA && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB && baseTextureInternalFormat != GraphicsContext3D::RGBA)
+ validFormatCombination = false;
+ break;
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ validFormatCombination = false;
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ validFormatCombination = false;
+ break;
+ }
+
+ if (!validFormatCombination) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "copyTexImage: invalid combination of framebuffer and texture formats");
+ return false;
+ }
+
+ ExceptionCode ec;
+ bool isSRGB = (getFramebufferAttachmentParameter(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, ec).getInt() == GraphicsContext3D::SRGB);
+ if (isSRGB != (framebufferInternalFormat == GraphicsContext3D::SRGB8 || framebufferInternalFormat == GraphicsContext3D::SRGB8_ALPHA8)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "framebuffer attachment color encoding and internal format do not match");
+ return false;
+ }
+ }
+
+ // We absolutely have to validate the format and type combination.
+ // The texImage2D entry points taking HTMLImage, etc. will produce
+ // temporary data based on this combination, so it must be legal.
+ if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+ return false;
+
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (functionType != TexSubImage && width != height) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ // No need to check height here. For texImage width == height.
+ // For texSubImage that will be checked when checking yoffset + height is in range.
+ if (width > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+
+ if (border) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGL2RenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
+{
+ // Verify that a valid format has been provided.
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::RGBA_INTEGER:
+ case GraphicsContext3D::RG:
+ case GraphicsContext3D::RG_INTEGER:
+ case GraphicsContext3D::RED_INTEGER:
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ if (m_webglDepthTexture)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
+ return false;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
+ return false;
+ }
+
+ // Verify that a valid type has been provided.
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ case GraphicsContext3D::SHORT:
+ case GraphicsContext3D::UNSIGNED_INT:
+ case GraphicsContext3D::INT:
+ case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+ case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+ case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ break;
+ case GraphicsContext3D::FLOAT:
+ if (m_oesTextureFloat)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GraphicsContext3D::HALF_FLOAT:
+ case GraphicsContext3D::HALF_FLOAT_OES:
+ if (m_oesTextureHalfFloat)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GraphicsContext3D::UNSIGNED_INT_24_8:
+ case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV:
+ if (isDepthStencilSupported())
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+
+ // Veryify that a valid internal format has been provided.
+ switch (internalformat) {
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::ALPHA:
+ 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::RGB8:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA8_SNORM:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGB32I:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::R11F_G11F_B10F:
+ case GraphicsContext3D::RGB9_E5:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::STENCIL_INDEX8:
+ break;
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ if (m_webglDepthTexture)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
+ return false;
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ if (isDepthStencilSupported())
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format");
+ return false;
+ case GraphicsContext3D::NONE:
+ // When calling validateTexFuncFormatAndType with internalformat == GraphicsContext3D::NONE, the intent is
+ // only to check for whether or not the format and type are valid types, which we have already done at this point.
+ return true;
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format");
+ return false;
+ }
+
+ // Verify that the combination of format, internalformat and type is supported.
+ switch (format) {
+ case GraphicsContext3D::RGBA:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE
+ && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA8 || internalformat == GraphicsContext3D::RGB5_A1 || internalformat == GraphicsContext3D::RGBA4 || internalformat == GraphicsContext3D::SRGB8_ALPHA8))
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8_SNORM)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
+ && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA4))
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
+ && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGB5_A1))
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV
+ && (internalformat == GraphicsContext3D::RGB10_A2 || internalformat == GraphicsContext3D::RGB5_A1))
+ break;
+ if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RGBA16F)
+ break;
+ if (type == GraphicsContext3D::FLOAT
+ && (internalformat == GraphicsContext3D::RGBA32F || internalformat == GraphicsContext3D::RGBA16F))
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RGBA_INTEGER:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGBA8UI)
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGBA16UI)
+ break;
+ if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGBA16I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGBA32UI)
+ break;
+ if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGBA32I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV && internalformat == GraphicsContext3D::RGB10_A2UI)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RGB:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE
+ && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB8 || internalformat == GraphicsContext3D::RGB565
+ || internalformat == GraphicsContext3D::SRGB8))
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8_SNORM)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT_5_6_5
+ && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB565))
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV && internalformat == GraphicsContext3D::R11F_G11F_B10F)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV && internalformat == GraphicsContext3D::RGB9_E5)
+ break;
+ if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES)
+ && (internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
+ break;
+ if (type == GraphicsContext3D::FLOAT
+ && (internalformat == GraphicsContext3D::RGB32F || internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5))
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RGB_INTEGER:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGB8UI)
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGB16UI)
+ break;
+ if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGB16I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGB32UI)
+ break;
+ if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGB32I)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RG:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8)
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8_SNORM)
+ break;
+ if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RG16F)
+ break;
+ if (type == GraphicsContext3D::FLOAT
+ && (internalformat == GraphicsContext3D::RG32F || internalformat == GraphicsContext3D::RG16F))
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RG_INTEGER:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8UI)
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RG16UI)
+ break;
+ if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RG16I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RG32UI)
+ break;
+ if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RG32I)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RED:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8)
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8_SNORM)
+ break;
+ if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::R16F)
+ break;
+ if (type == GraphicsContext3D::FLOAT
+ && (internalformat == GraphicsContext3D::R32F || internalformat == GraphicsContext3D::R16F))
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::RED_INTEGER:
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8UI)
+ break;
+ if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::R16UI)
+ break;
+ if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::R16I)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::R32UI)
+ break;
+ if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::R32I)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ if (!m_webglDepthTexture) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
+ return false;
+ }
+ if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::DEPTH_COMPONENT16)
+ break;
+ if (type == GraphicsContext3D::UNSIGNED_INT
+ && (internalformat == GraphicsContext3D::DEPTH_COMPONENT24 || internalformat == GraphicsContext3D::DEPTH_COMPONENT16))
+ break;
+ if (type == GraphicsContext3D::FLOAT && internalformat == GraphicsContext3D::DEPTH_COMPONENT32F)
+ break;
+ if (level > 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
+ return false;
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ if (!m_webglDepthTexture || !isDepthStencilSupported()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
+ return false;
+ }
+ if (type == GraphicsContext3D::UNSIGNED_INT_24_8 && internalformat == GraphicsContext3D::DEPTH24_STENCIL8)
+ break;
+ if (type == GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV && internalformat == GraphicsContext3D::DEPTH32F_STENCIL8)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ if ((type == GraphicsContext3D::UNSIGNED_BYTE || type == GraphicsContext3D::HALF_FLOAT_OES || type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::FLOAT) && internalformat == format)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination");
+ return false;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return true;
+}
+
+bool WebGL2RenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum internalformat, GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition disposition)
+{
+ if (!pixels) {
+ if (disposition == NullAllowed)
+ return true;
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+
+ if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
+ return false;
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+
+ switch (type) {
+ case GraphicsContext3D::BYTE:
+ if (pixels->getType() != JSC::TypeInt8) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type BYTE but ArrayBufferView not Int8Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ if (pixels->getType() != JSC::TypeUint8) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::SHORT:
+ if (pixels->getType() != JSC::TypeInt16) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type SHORT but ArrayBufferView not Int16Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ if (pixels->getType() != JSC::TypeUint16) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::INT:
+ if (pixels->getType() != JSC::TypeInt32) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type INT but ArrayBufferView not Int32Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::UNSIGNED_INT:
+ case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV:
+ case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV:
+ if (pixels->getType() != JSC::TypeUint32) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_INT but ArrayBufferView not Uint32Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::HALF_FLOAT:
+ case GraphicsContext3D::FLOAT:
+ if (pixels->getType() != JSC::TypeFloat32) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
+ // As per the specification, ArrayBufferView should be null when
+ // OES_texture_half_float is enabled.
+ if (pixels) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ unsigned totalBytesRequired;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, functionName, "invalid texture dimensions");
+ return false;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ if (m_unpackAlignment != 1) {
+ error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
+ if (pixels->byteLength() == totalBytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
+ return false;
+ }
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
+ return false;
+ }
+ return true;
+}
+
+GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat)
+{
+ // Handles sized, unsized, and compressed internal formats.
+ switch (internalformat) {
+ case GraphicsContext3D::R8:
+ case GraphicsContext3D::R8_SNORM:
+ case GraphicsContext3D::R16F:
+ case GraphicsContext3D::R32F:
+ case GraphicsContext3D::R8I:
+ case GraphicsContext3D::R8UI:
+ case GraphicsContext3D::R16I:
+ case GraphicsContext3D::R16UI:
+ case GraphicsContext3D::R32I:
+ case GraphicsContext3D::R32UI:
+ case GraphicsContext3D::COMPRESSED_R11_EAC:
+ case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC:
+ return GraphicsContext3D::RED;
+ case GraphicsContext3D::RG8:
+ case GraphicsContext3D::RG8_SNORM:
+ case GraphicsContext3D::RG16F:
+ case GraphicsContext3D::RG32F:
+ case GraphicsContext3D::RG8I:
+ case GraphicsContext3D::RG8UI:
+ case GraphicsContext3D::RG16I:
+ case GraphicsContext3D::RG16UI:
+ case GraphicsContext3D::RG32I:
+ case GraphicsContext3D::RG32UI:
+ case GraphicsContext3D::COMPRESSED_RG11_EAC:
+ case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC:
+ return GraphicsContext3D::RG;
+ case GraphicsContext3D::RGB8:
+ case GraphicsContext3D::RGB8_SNORM:
+ case GraphicsContext3D::RGB565:
+ case GraphicsContext3D::SRGB8:
+ case GraphicsContext3D::RGB16F:
+ case GraphicsContext3D::RGB32F:
+ case GraphicsContext3D::RGB8I:
+ case GraphicsContext3D::RGB8UI:
+ case GraphicsContext3D::RGB16I:
+ case GraphicsContext3D::RGB16UI:
+ case GraphicsContext3D::RGB32I:
+ case GraphicsContext3D::RGB32UI:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::COMPRESSED_RGB8_ETC2:
+ case GraphicsContext3D::COMPRESSED_SRGB8_ETC2:
+ return GraphicsContext3D::RGB;
+ case GraphicsContext3D::RGBA4:
+ case GraphicsContext3D::RGB5_A1:
+ case GraphicsContext3D::RGBA8:
+ case GraphicsContext3D::RGBA8_SNORM:
+ case GraphicsContext3D::RGB10_A2:
+ case GraphicsContext3D::RGB10_A2UI:
+ case GraphicsContext3D::SRGB8_ALPHA8:
+ case GraphicsContext3D::RGBA16F:
+ case GraphicsContext3D::RGBA32F:
+ case GraphicsContext3D::RGBA8I:
+ case GraphicsContext3D::RGBA8UI:
+ case GraphicsContext3D::RGBA16I:
+ case GraphicsContext3D::RGBA16UI:
+ case GraphicsContext3D::RGBA32I:
+ case GraphicsContext3D::RGBA32UI:
+ case GraphicsContext3D::RGBA:
+ case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC:
+ case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ return GraphicsContext3D::RGBA;
+ case GraphicsContext3D::DEPTH_COMPONENT16:
+ case GraphicsContext3D::DEPTH_COMPONENT24:
+ case GraphicsContext3D::DEPTH_COMPONENT32F:
+ return GraphicsContext3D::DEPTH_COMPONENT;
+ case GraphicsContext3D::DEPTH24_STENCIL8:
+ case GraphicsContext3D::DEPTH32F_STENCIL8:
+ return GraphicsContext3D::DEPTH_STENCIL;
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::ALPHA:
+ return internalformat;
+ default:
+ ASSERT_NOT_REACHED();
+ return GraphicsContext3D::NONE;
+ }
+}
+
</ins><span class="cx"> WebGLGetInfo WebGL2RenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> UNUSED_PARAM(ec);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGL2RenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h        2015-02-09 20:50:15 UTC (rev 179842)
</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);
</del><ins>+ WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&);
</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">@@ -169,7 +169,41 @@
</span><span class="cx"> virtual Vector<String> getSupportedExtensions() override;
</span><span class="cx">
</span><span class="cx"> virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) override;
</span><del>- bool validateCapability(const char* functionName, GC3Denum cap) override;
</del><ins>+
+ virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
+ 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&) override;
+ virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) override;
+#if ENABLE(VIDEO)
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) override;
+#endif
+
+protected:
+ virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
+ virtual bool validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type) override;
+ virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum internalformat, GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition) override;
+ virtual bool validateCapability(const char* functionName, GC3Denum cap) override;
+
+private:
+ GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat);
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -29,12 +29,17 @@
</span><span class="cx"> #include "WebGLRenderingContext.h"
</span><span class="cx">
</span><span class="cx"> #include "ANGLEInstancedArrays.h"
</span><ins>+#include "CachedImage.h"
</ins><span class="cx"> #include "EXTBlendMinMax.h"
</span><span class="cx"> #include "EXTFragDepth.h"
</span><span class="cx"> #include "EXTShaderTextureLOD.h"
</span><span class="cx"> #include "EXTTextureFilterAnisotropic.h"
</span><span class="cx"> #include "EXTsRGB.h"
</span><span class="cx"> #include "Extensions3D.h"
</span><ins>+#include "HTMLCanvasElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
+#include "ImageData.h"
</ins><span class="cx"> #include "OESElementIndexUint.h"
</span><span class="cx"> #include "OESStandardDerivatives.h"
</span><span class="cx"> #include "OESTextureFloat.h"
</span><span class="lines">@@ -42,6 +47,7 @@
</span><span class="cx"> #include "OESTextureHalfFloat.h"
</span><span class="cx"> #include "OESTextureHalfFloatLinear.h"
</span><span class="cx"> #include "OESVertexArrayObject.h"
</span><ins>+#include "RenderBox.h"
</ins><span class="cx"> #include "WebGLCompressedTextureATC.h"
</span><span class="cx"> #include "WebGLCompressedTexturePVRTC.h"
</span><span class="cx"> #include "WebGLCompressedTextureS3TC.h"
</span><span class="lines">@@ -281,6 +287,454 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
+{
+ if (isContextLostOrPending())
+ return;
+ if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
+ return;
+ if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ if (isResourceSafe()) {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ } else {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ GC3Dint clippedX, clippedY;
+ GC3Dsizei clippedWidth, clippedHeight;
+ if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
+ m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
+ internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
+ if (clippedWidth > 0 && clippedHeight > 0) {
+ m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
+ clippedX, clippedY, clippedWidth, clippedHeight);
+ }
+ } else
+ m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ }
+ // FIXME: if the framebuffer is not complete, none of the below should be executed.
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
+{
+ UNUSED_PARAM(internalformat);
+ // FIXME: For now we ignore any errors returned
+ ec = 0;
+ ASSERT(!isContextLost());
+ ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, format, width, height, 0, format, type));
+ ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
+ ASSERT(validateSettableTexFormat("texSubImage2D", format));
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ if (!tex) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT((xoffset + width) >= 0);
+ ASSERT((yoffset + height) >= 0);
+ ASSERT(tex->getWidth(target, level) >= (xoffset + width));
+ ASSERT(tex->getHeight(target, level) >= (yoffset + height));
+ ASSERT(tex->getInternalFormat(target, level) == format);
+ ASSERT(tex->getType(target, level) == type);
+ m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
+{
+ ec = 0;
+ Vector<uint8_t> data;
+ GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
+ return;
+ }
+ GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, format, type, needConversion ? data.data() : imagePixelData, ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
+{
+ if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, format, format, type, pixels, NullNotAllowed) || !validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
+ return;
+
+ void* data = pixels->baseAddress();
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!m_context->extractTextureData(width, height, format, type,
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, format, type, data, ec);
+ if (changeUnpackAlignment)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
+ needConversion = false;
+ else {
+ if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
+
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, format, type, needConversion ? data.data() : pixels->data()->data(), ec);
+ if (m_unpackAlignment != 1)
+ m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec))
+ return;
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
+
+ if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
+ || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
+ else
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+
+#if ENABLE(VIDEO)
+void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
+{
+ ec = 0;
+ if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec)
+ || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
+ if (!image)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
+}
+#endif
+
+bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType functionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type)
+{
+ // We absolutely have to validate the format and type combination.
+ // The texImage2D entry points taking HTMLImage, etc. will produce
+ // temporary data based on this combination, so it must be legal.
+ if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+ return false;
+
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
+ switch (target) {
+ case GraphicsContext3D::TEXTURE_2D:
+ if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (functionType != TexSubImage && width != height) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ // No need to check height here. For texImage width == height.
+ // For texSubImage that will be checked when checking yoffset + height is in range.
+ if (width > maxTextureSizeForLevel) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+
+ if (format != internalformat) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");
+ return false;
+ }
+
+ if (border) {
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level)
+{
+ UNUSED_PARAM(internalformat);
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ case GraphicsContext3D::RGB:
+ case GraphicsContext3D::RGBA:
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ if (m_webglDepthTexture)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
+ return false;
+ case Extensions3D::SRGB_EXT:
+ case Extensions3D::SRGB_ALPHA_EXT:
+ default:
+ if ((format == Extensions3D::SRGB_EXT || format == Extensions3D::SRGB_ALPHA_EXT)
+ && m_extsRGB)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
+ return false;
+ }
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ break;
+ case GraphicsContext3D::FLOAT:
+ if (m_oesTextureFloat)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GraphicsContext3D::HALF_FLOAT_OES:
+ if (m_oesTextureHalfFloat)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GraphicsContext3D::UNSIGNED_INT:
+ case GraphicsContext3D::UNSIGNED_INT_24_8:
+ case GraphicsContext3D::UNSIGNED_SHORT:
+ if (m_webglDepthTexture)
+ break;
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ default:
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+
+ // Verify that the combination of format and type is supported.
+ switch (format) {
+ case GraphicsContext3D::ALPHA:
+ case GraphicsContext3D::LUMINANCE:
+ case GraphicsContext3D::LUMINANCE_ALPHA:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::FLOAT
+ && type != GraphicsContext3D::HALF_FLOAT_OES) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::RGB:
+ case Extensions3D::SRGB_EXT:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
+ && type != GraphicsContext3D::FLOAT
+ && type != GraphicsContext3D::HALF_FLOAT_OES) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::RGBA:
+ case Extensions3D::SRGB_ALPHA_EXT:
+ if (type != GraphicsContext3D::UNSIGNED_BYTE
+ && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
+ && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
+ && type != GraphicsContext3D::FLOAT
+ && type != GraphicsContext3D::HALF_FLOAT_OES) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_COMPONENT:
+ if (!m_webglDepthTexture) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
+ return false;
+ }
+ if (type != GraphicsContext3D::UNSIGNED_SHORT
+ && type != GraphicsContext3D::UNSIGNED_INT) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::DEPTH_STENCIL:
+ if (!m_webglDepthTexture) {
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
+ return false;
+ }
+ if (type != GraphicsContext3D::UNSIGNED_INT_24_8) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition disposition)
+{
+ if (!pixels) {
+ if (disposition == NullAllowed)
+ return true;
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+
+ if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level))
+ return false;
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+
+ switch (type) {
+ case GraphicsContext3D::UNSIGNED_BYTE:
+ if (pixels->getType() != JSC::TypeUint8) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+ case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+ case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+ if (pixels->getType() != JSC::TypeUint16) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::FLOAT: // OES_texture_float
+ if (pixels->getType() != JSC::TypeFloat32) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
+ return false;
+ }
+ break;
+ case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
+ // As per the specification, ArrayBufferView should be null when
+ // OES_texture_half_float is enabled.
+ if (pixels) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ unsigned totalBytesRequired;
+ GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+ if (error != GraphicsContext3D::NO_ERROR) {
+ synthesizeGLError(error, functionName, "invalid texture dimensions");
+ return false;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ if (m_unpackAlignment != 1) {
+ error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
+ if (pixels->byteLength() == totalBytesRequired) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
+ return false;
+ }
+ }
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
+ return false;
+ }
+ return true;
+}
+
</ins><span class="cx"> WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> UNUSED_PARAM(ec);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -39,7 +39,38 @@
</span><span class="cx"> virtual WebGLExtension* getExtension(const String&) override;
</span><span class="cx"> virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) override;
</span><span class="cx"> virtual Vector<String> getSupportedExtensions() override;
</span><del>- bool validateCapability(const char* functionName, GC3Denum cap) override;
</del><ins>+
+ virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override;
+ 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&) override;
+ virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) override;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) override;
+#if ENABLE(VIDEO)
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) override;
+#endif
+
+protected:
+ virtual bool validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type) override;
+ virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override;
+ virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum internalformat, GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition) override;
+ virtual bool validateCapability(const char* functionName, GC3Denum cap) override;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -99,60 +99,12 @@
</span><span class="cx"> const int maxGLErrorsAllowedToConsole = 256;
</span><span class="cx">
</span><span class="cx"> namespace {
</span><del>-
- class ScopedDrawingBufferBinder {
- public:
- ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
- : m_drawingBuffer(drawingBuffer)
- , m_framebufferBinding(framebufferBinding)
- {
- // Commit DrawingBuffer if needed (e.g., for multisampling)
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->commit();
- }
-
- ~ScopedDrawingBufferBinder()
- {
- // Restore DrawingBuffer if needed
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->bind();
- }
-
- private:
- DrawingBuffer* m_drawingBuffer;
- WebGLFramebuffer* m_framebufferBinding;
- };
-
</del><ins>+
</ins><span class="cx"> Platform3DObject objectOrZero(WebGLObject* object)
</span><span class="cx"> {
</span><span class="cx"> return object ? object->object() : 0;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
- {
- ASSERT(clippedStart && clippedRange);
- if (start < 0) {
- range += start;
- start = 0;
- }
- GC3Dint end = start + range;
- if (end > sourceRange)
- range -= end - sourceRange;
- *clippedStart = start;
- *clippedRange = range;
- }
-
- // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
- bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
- GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
- GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
- {
- ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
- clip1D(x, width, sourceWidth, clippedX, clippedWidth);
- clip1D(y, height, sourceHeight, clippedY, clippedHeight);
- return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
- }
-
</del><span class="cx"> GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
</span><span class="cx"> {
</span><span class="cx"> if (value < min)
</span><span class="lines">@@ -1442,52 +1394,6 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void WebGLRenderingContextBase::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- if (isContextLostOrPending())
- return;
- if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
- return;
- if (!validateSettableTexFormat("copyTexImage2D", internalformat))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
- if (!tex)
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
- return;
- }
- if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
- synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
- return;
- }
- clearIfComposited();
- if (isResourceSafe()) {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- } else {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- GC3Dint clippedX, clippedY;
- GC3Dsizei clippedWidth, clippedHeight;
- if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
- m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
- internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
- if (clippedWidth > 0 && clippedHeight > 0) {
- m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
- clippedX, clippedY, clippedWidth, clippedHeight);
- }
- } else
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- }
- // FIXME: if the framebuffer is not complete, none of the below should be executed.
- tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
-}
-
</del><span class="cx"> void WebGLRenderingContextBase::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
</span><span class="cx"> {
</span><span class="cx"> if (isContextLostOrPending())
</span><span class="lines">@@ -3547,7 +3453,7 @@
</span><span class="cx"> // FIXME: For now we ignore any errors returned.
</span><span class="cx"> ec = 0;
</span><span class="cx"> WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
</span><del>- ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
</del><ins>+ ASSERT(validateTexFuncParameters("texImage2D", TexImage, target, level, internalformat, width, height, border, format, type));
</ins><span class="cx"> ASSERT(tex);
</span><span class="cx"> ASSERT(!level || !WebGLTexture::isNPOT(width, height));
</span><span class="cx"> if (!pixels) {
</span><span class="lines">@@ -3616,7 +3522,7 @@
</span><span class="cx"> if (!texture)
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (functionType == NotTexSubImage2D) {
</del><ins>+ if (functionType != TexSubImage) {
</ins><span class="cx"> if (level && WebGLTexture::isNPOT(width, height)) {
</span><span class="cx"> synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level > 0 not power of 2");
</span><span class="cx"> return false;
</span><span class="lines">@@ -3654,8 +3560,8 @@
</span><span class="cx"> GC3Dsizei width, GC3Dsizei height, GC3Dint border,
</span><span class="cx"> GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
</span><span class="cx"> {
</span><del>- if (isContextLostOrPending() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
</del><ins>+ if (isContextLostOrPending() || !validateTexFuncData("texImage2D", level, width, height, internalformat, format, type, pixels, NullAllowed)
+ || !validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
</ins><span class="cx"> return;
</span><span class="cx"> void* data = pixels ? pixels->baseAddress() : 0;
</span><span class="cx"> Vector<uint8_t> tempData;
</span><span class="lines">@@ -3682,7 +3588,7 @@
</span><span class="cx"> GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> ec = 0;
</span><del>- if (isContextLostOrPending() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
</del><ins>+ if (isContextLostOrPending() || !pixels || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
</ins><span class="cx"> return;
</span><span class="cx"> Vector<uint8_t> data;
</span><span class="cx"> bool needConversion = true;
</span><span class="lines">@@ -3730,7 +3636,7 @@
</span><span class="cx"> if (imageForRender->isSVGImage())
</span><span class="cx"> imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
</span><span class="cx">
</span><del>- if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
</del><ins>+ if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
</span><span class="lines">@@ -3740,7 +3646,7 @@
</span><span class="cx"> GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> ec = 0;
</span><del>- if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
</del><ins>+ if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
</span><span class="lines">@@ -3785,7 +3691,7 @@
</span><span class="cx"> {
</span><span class="cx"> ec = 0;
</span><span class="cx"> if (isContextLostOrPending() || !validateHTMLVideoElement("texImage2D", video, ec)
</span><del>- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
</del><ins>+ || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
</ins><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
</span><span class="lines">@@ -3860,159 +3766,6 @@
</span><span class="cx"> texParameter(target, pname, 0, param, false);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void WebGLRenderingContextBase::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)
-{
- // FIXME: For now we ignore any errors returned
- ec = 0;
- ASSERT(!isContextLost());
- ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
- ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
- ASSERT(validateSettableTexFormat("texSubImage2D", format));
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- if (!tex) {
- ASSERT_NOT_REACHED();
- return;
- }
- ASSERT((xoffset + width) >= 0);
- ASSERT((yoffset + height) >= 0);
- ASSERT(tex->getWidth(target, level) >= (xoffset + width));
- ASSERT(tex->getHeight(target, level) >= (yoffset + height));
- ASSERT(tex->getInternalFormat(target, level) == format);
- ASSERT(tex->getType(target, level) == type);
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGLRenderingContextBase::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)
-{
- ec = 0;
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type, needConversion ? data.data() : imagePixelData, ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
-{
- if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
- return;
- void* data = pixels->baseAddress();
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
- return;
-
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), ec);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
- return;
-
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
- else
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-
-#if ENABLE(VIDEO)
-void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)
-{
- ec = 0;
- if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);
- if (!image)
- return;
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
-}
-#endif
-
</del><span class="cx"> void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> UNUSED_PARAM(ec);
</span><span class="lines">@@ -4863,128 +4616,6 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level)
-{
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- case GraphicsContext3D::RGB:
- case GraphicsContext3D::RGBA:
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- case GraphicsContext3D::DEPTH_COMPONENT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");
- return false;
- case Extensions3D::SRGB_EXT:
- case Extensions3D::SRGB_ALPHA_EXT:
- default:
- if ((format == Extensions3D::SRGB_EXT || format == Extensions3D::SRGB_ALPHA_EXT)
- && m_extsRGB)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
- return false;
- }
-
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- break;
- case GraphicsContext3D::FLOAT:
- if (m_oesTextureFloat)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GraphicsContext3D::HALF_FLOAT_OES:
- if (m_oesTextureHalfFloat)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GraphicsContext3D::UNSIGNED_INT:
- case GraphicsContext3D::UNSIGNED_INT_24_8:
- case GraphicsContext3D::UNSIGNED_SHORT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
- return false;
- }
-
- // Verify that the combination of format and type is supported.
- switch (format) {
- case GraphicsContext3D::ALPHA:
- case GraphicsContext3D::LUMINANCE:
- case GraphicsContext3D::LUMINANCE_ALPHA:
- if (type != GraphicsContext3D::UNSIGNED_BYTE
- && type != GraphicsContext3D::FLOAT
- && type != GraphicsContext3D::HALF_FLOAT_OES) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format");
- return false;
- }
- break;
- case GraphicsContext3D::RGB:
- case Extensions3D::SRGB_EXT:
- if (type != GraphicsContext3D::UNSIGNED_BYTE
- && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
- && type != GraphicsContext3D::FLOAT
- && type != GraphicsContext3D::HALF_FLOAT_OES) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format");
- return false;
- }
- break;
- case GraphicsContext3D::RGBA:
- case Extensions3D::SRGB_ALPHA_EXT:
- if (type != GraphicsContext3D::UNSIGNED_BYTE
- && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
- && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
- && type != GraphicsContext3D::FLOAT
- && type != GraphicsContext3D::HALF_FLOAT_OES) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format");
- return false;
- }
- break;
- case GraphicsContext3D::DEPTH_COMPONENT:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
- return false;
- }
- if (type != GraphicsContext3D::UNSIGNED_SHORT
- && type != GraphicsContext3D::UNSIGNED_INT) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
- return false;
- }
- break;
- case GraphicsContext3D::DEPTH_STENCIL:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
- return false;
- }
- if (type != GraphicsContext3D::UNSIGNED_INT_24_8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- return true;
-}
-
</del><span class="cx"> bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
</span><span class="cx"> {
</span><span class="cx"> if (level < 0) {
</span><span class="lines">@@ -5015,138 +4646,6 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType functionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type)
-{
- // We absolutely have to validate the format and type combination.
- // The texImage2D entry points taking HTMLImage, etc. will produce
- // temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
- return false;
-
- if (width < 0 || height < 0) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);
- switch (target) {
- case GraphicsContext3D::TEXTURE_2D:
- if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
- return false;
- }
- break;
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (functionType != TexSubImage2D && width != height) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");
- return false;
- }
- // No need to check height here. For texImage width == height.
- // For texSubImage that will be checked when checking yoffset + height is in range.
- if (width > maxTextureSizeForLevel) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");
- return false;
- }
- break;
- default:
- synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
- return false;
- }
-
- if (format != internalformat) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");
- return false;
- }
-
- if (border) {
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition disposition)
-{
- if (!pixels) {
- if (disposition == NullAllowed)
- return true;
- synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
- return false;
- }
-
- if (!validateTexFuncFormatAndType(functionName, format, type, level))
- return false;
- if (!validateSettableTexFormat(functionName, format))
- return false;
-
- switch (type) {
- case GraphicsContext3D::UNSIGNED_BYTE:
- if (pixels->getType() != JSC::TypeUint8) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
- return false;
- }
- break;
- case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
- case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
- case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
- if (pixels->getType() != JSC::TypeUint16) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
- return false;
- }
- break;
- case GraphicsContext3D::FLOAT: // OES_texture_float
- if (pixels->getType() != JSC::TypeFloat32) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
- return false;
- }
- break;
- case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
- // As per the specification, ArrayBufferView should be null when
- // OES_texture_half_float is enabled.
- if (pixels) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- unsigned int totalBytesRequired;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
- if (error != GraphicsContext3D::NO_ERROR) {
- synthesizeGLError(error, functionName, "invalid texture dimensions");
- return false;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- if (m_unpackAlignment != 1) {
- error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
- if (pixels->byteLength() == totalBytesRequired) {
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
- return false;
- }
- }
- synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
- return false;
- }
- return true;
-}
-
</del><span class="cx"> bool WebGLRenderingContextBase::validateCompressedTexFormat(GC3Denum format)
</span><span class="cx"> {
</span><span class="cx"> return m_compressedTextureFormats.contains(format);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include "ImageBuffer.h"
</span><span class="cx"> #include "Timer.h"
</span><span class="cx"> #include "WebGLGetInfo.h"
</span><ins>+#include "WebGLObject.h"
</ins><span class="cx"> #include <memory>
</span><span class="cx"> #include <runtime/Float32Array.h>
</span><span class="cx"> #include <runtime/Int32Array.h>
</span><span class="lines">@@ -85,6 +86,54 @@
</span><span class="cx">
</span><span class="cx"> typedef int ExceptionCode;
</span><span class="cx">
</span><ins>+class ScopedDrawingBufferBinder {
+public:
+ ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
+ : m_drawingBuffer(drawingBuffer)
+ , m_framebufferBinding(framebufferBinding)
+ {
+ // Commit DrawingBuffer if needed (e.g., for multisampling)
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->commit();
+ }
+
+ ~ScopedDrawingBufferBinder()
+ {
+ // Restore DrawingBuffer if needed
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->bind();
+ }
+
+private:
+ DrawingBuffer* m_drawingBuffer;
+ WebGLFramebuffer* m_framebufferBinding;
+};
+
+inline void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)
+{
+ ASSERT(clippedStart && clippedRange);
+ if (start < 0) {
+ range += start;
+ start = 0;
+ }
+ GC3Dint end = start + range;
+ if (end > sourceRange)
+ range -= end - sourceRange;
+ *clippedStart = start;
+ *clippedRange = range;
+}
+
+// Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.
+inline bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,
+ GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,
+ GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)
+{
+ ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);
+ clip1D(x, width, sourceWidth, clippedX, clippedWidth);
+ clip1D(y, height, sourceHeight, clippedY, clippedHeight);
+ return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
+}
+
</ins><span class="cx"> class WebGLRenderingContextBase : public CanvasRenderingContext, public ActiveDOMObject {
</span><span class="cx"> public:
</span><span class="cx"> static std::unique_ptr<WebGLRenderingContextBase> create(HTMLCanvasElement*, WebGLContextAttributes*, const String&);
</span><span class="lines">@@ -132,7 +181,7 @@
</span><span class="cx"> void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
</span><span class="cx"> GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
</span><span class="cx">
</span><del>- void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
</del><ins>+ virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) = 0;
</ins><span class="cx"> void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
</span><span class="cx">
</span><span class="cx"> PassRefPtr<WebGLBuffer> createBuffer();
</span><span class="lines">@@ -237,18 +286,18 @@
</span><span class="cx"> void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
</span><span class="cx"> void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
</span><span class="cx">
</span><del>- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);
</del><ins>+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) = 0;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) = 0;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) = 0;
+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) = 0;
</ins><span class="cx"> #if ENABLE(VIDEO)
</span><del>- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);
</del><ins>+ virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) = 0;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> void uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode&);
</span><span class="lines">@@ -584,8 +633,8 @@
</span><span class="cx">
</span><span class="cx"> void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
</span><span class="cx"> void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
</span><del>- void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);
- void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);
</del><ins>+ 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&) = 0;
+ virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) = 0;
</ins><span class="cx">
</span><span class="cx"> void checkTextureCompleteness(const char*, bool);
</span><span class="cx">
</span><span class="lines">@@ -624,15 +673,16 @@
</span><span class="cx">
</span><span class="cx"> // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
</span><span class="cx"> // Generates GL error and returns false if parameters are invalid.
</span><del>- bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
</del><ins>+ virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) = 0;
</ins><span class="cx">
</span><span class="cx"> // Helper function to check input level for functions {copy}Tex{Sub}Image.
</span><span class="cx"> // Generates GL error and returns false if level is invalid.
</span><span class="cx"> bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
</span><span class="cx">
</span><span class="cx"> enum TexFuncValidationFunctionType {
</span><del>- NotTexSubImage2D,
- TexSubImage2D,
</del><ins>+ TexImage,
+ TexSubImage,
+ CopyTexImage
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> enum TexFuncValidationSourceType {
</span><span class="lines">@@ -650,12 +700,12 @@
</span><span class="cx">
</span><span class="cx"> // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
</span><span class="cx"> // Generates GL error and returns false if parameters are invalid.
</span><del>- bool validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type);
</del><ins>+ virtual bool validateTexFuncParameters(const char* functionName,
+ TexFuncValidationFunctionType,
+ GC3Denum target, GC3Dint level,
+ GC3Denum internalformat,
+ GC3Dsizei width, GC3Dsizei height, GC3Dint border,
+ GC3Denum format, GC3Denum type) = 0;
</ins><span class="cx">
</span><span class="cx"> enum NullDisposition {
</span><span class="cx"> NullAllowed,
</span><span class="lines">@@ -665,11 +715,11 @@
</span><span class="cx"> // Helper function to validate that the given ArrayBufferView
</span><span class="cx"> // is of the correct type and contains enough data for the texImage call.
</span><span class="cx"> // Generates GL error and returns false if parameters are invalid.
</span><del>- bool validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition);
</del><ins>+ virtual bool validateTexFuncData(const char* functionName, GC3Dint level,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum internalformat, GC3Denum format, GC3Denum type,
+ ArrayBufferView* pixels,
+ NullDisposition) = 0;
</ins><span class="cx">
</span><span class="cx"> // Helper function to validate a given texture format is settable as in
</span><span class="cx"> // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContext3Dh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (179841 => 179842)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2015-02-09 20:27:51 UTC (rev 179841)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h        2015-02-09 20:50:15 UTC (rev 179842)
</span><span class="lines">@@ -508,7 +508,7 @@
</span><span class="cx"> COMPARE_REF_TO_TEXTURE = 0x884E,
</span><span class="cx"> RGBA32F = 0x8814,
</span><span class="cx"> RGB32F = 0x8815,
</span><del>- RGBA16 = 0x881A,
</del><ins>+ RGBA16F = 0x881A,
</ins><span class="cx"> RGB16F = 0x881B,
</span><span class="cx"> VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD,
</span><span class="cx"> MAX_ARRAY_TEXTURE_LAYERS = 0x88FF,
</span></span></pre>
</div>
</div>
</body>
</html>