[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
zmo at google.com
zmo at google.com
Wed Dec 22 11:09:12 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 2d85c6d7e97f80062766150b58dd5dff87923b3a
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jul 13 22:53:42 2010 +0000
2010-07-04 Zhenyao Mo <zmo at google.com>
Reviewed by Darin Fisher.
Need to track texture completeness
https://bugs.webkit.org/show_bug.cgi?id=41381
Test: fast/canvas/webgl/texture-complete.html
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::WebGLRenderingContext): Init max texture level.
(WebCore::WebGLRenderingContext::bindTexture): Pass max texture level to setTarget().
(WebCore::WebGLRenderingContext::copyTexImage2D): Cache full texture info rather than partial.
(WebCore::WebGLRenderingContext::generateMipmap): Ditto.
(WebCore::WebGLRenderingContext::texImage2DBase): Ditto.
(WebCore::WebGLRenderingContext::validateTexFuncParameters): Also validate level.
* html/canvas/WebGLRenderingContext.h: Add max texture level.
* html/canvas/WebGLTexture.cpp: Update the class to fully cache texture information and track NPOT and COMPLETE states.
(WebCore::WebGLTexture::WebGLTexture):
(WebCore::WebGLTexture::setTarget): Check whether the texture is initialized or has been deleted.
(WebCore::WebGLTexture::setParameteri): Ditto.
(WebCore::WebGLTexture::setParameterf): Ditto.
(WebCore::WebGLTexture::setLevelInfo): Set texture info.
(WebCore::WebGLTexture::generateMipmapLevelInfo): Generate texture info for all levels after generateMipmaps() is called.
(WebCore::WebGLTexture::getInternalFormat): Return internal format on texture face 0 level 0.
(WebCore::WebGLTexture::isNPOT): Check whether the texture is initialized or has been deleted.
(WebCore::WebGLTexture::needToUseBlackTexture): Ditto.
(WebCore::WebGLTexture::_deleteObject):
(WebCore::WebGLTexture::mapTargetToIndex): Map target to index.
(WebCore::WebGLTexture::canGenerateMipmaps): Check whether Mipmaps can be generated.
(WebCore::WebGLTexture::computeLevelCount): Compute texture level count from width/height.
(WebCore::WebGLTexture::update): Update NPOT/COMPLETE states.
* html/canvas/WebGLTexture.h: Ditto.
(WebCore::WebGLTexture::LevelInfo::LevelInfo): Add data structure to fully cache texture info.
(WebCore::WebGLTexture::LevelInfo::setInfo): Set information.
2010-07-04 Zhenyao Mo <zmo at google.com>
Reviewed by Darin Fisher.
Need to track texture completeness
https://bugs.webkit.org/show_bug.cgi?id=41381
* fast/canvas/webgl/texture-complete-expected.txt: Added.
* fast/canvas/webgl/texture-complete.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 57b4323..112e847 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-07-04 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Darin Fisher.
+
+ Need to track texture completeness
+ https://bugs.webkit.org/show_bug.cgi?id=41381
+
+ * fast/canvas/webgl/texture-complete-expected.txt: Added.
+ * fast/canvas/webgl/texture-complete.html: Added.
+
2010-07-13 Andreas Kling <andreas.kling at nokia.com>
Reviewed by Darin Adler.
diff --git a/LayoutTests/fast/canvas/webgl/texture-complete-expected.txt b/LayoutTests/fast/canvas/webgl/texture-complete-expected.txt
new file mode 100644
index 0000000..8b5ff70
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/texture-complete-expected.txt
@@ -0,0 +1,8 @@
+
+Checks that a texture that is not -texture-complete- does not draw if filtering needs mips
+
+PASS texture that is not -texture-complete- when TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/texture-complete.html b/LayoutTests/fast/canvas/webgl/texture-complete.html
new file mode 100644
index 0000000..47b1924
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/texture-complete.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>WebGL "Texture Complete" texture conformance test.</title>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/utils3d.js"> </script>
+</head>
+<body>
+<canvas id="example" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
+<canvas id="canvas2d" width="16" height="16" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+uniform sampler2D tex;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = texture2D(tex, texCoord);
+}
+</script>
+
+<script>
+function init()
+{
+ if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ }
+
+ debug("Checks that a texture that is not -texture-complete- does not draw if"+
+ " filtering needs mips");
+ debug("");
+
+ var canvas2d = document.getElementById("canvas2d");
+ var ctx2d = canvas2d.getContext("2d");
+ ctx2d.fillStyle = "rgba(0,192,128,255)";
+ ctx2d.fillRect(0, 0, 16, 16);
+
+ gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "texCoord0"],
+ [ 0, 0, 0, 1 ], 1);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER,
+ new Float32Array([ -1,1,0, 1,1,0, -1,-1,0,
+ -1,-1,0, 1,1,0, 1,-1,0 ]),
+ gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER,
+ new Float32Array([ 0,0, 1,0, 0,1,
+ 0,1, 1,0, 1,1 ]),
+ gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // 16x16 texture no mips
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+
+ var loc = gl.getUniformLocation(gl.program, "tex");
+ gl.uniform1i(loc, 0);
+
+ checkBuffer(0,0,0,255,
+ "texture that is not -texture-complete- when " +
+ "TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255");
+
+ function checkBuffer(r, g, b, a, msg) {
+ gl.clearColor(1,1,1,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ gl.flush();
+ var buf = new Uint8Array(4 * 4 * 4);
+ gl.readPixels(0, 0, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ for (var i = 0; i < 4 * 4; ++i) {
+ var offset = i * 4;
+ if (buf[offset + 0] != r ||
+ buf[offset + 1] != g ||
+ buf[offset + 2] != b ||
+ buf[offset + 3] != a) {
+ debug('expected: ' + r + ', ' + g + ', ' + b + ', ' + a +
+ ' was: ' +
+ buf[offset + 0] + ', ' +
+ buf[offset + 1] + ', ' +
+ buf[offset + 2] + ', ' +
+ buf[offset + 3]);
+ testFailed(msg);
+ return;
+ }
+ }
+ testPassed(msg);
+ }
+}
+
+init();
+successfullyParsed = true;
+</script>
+
+<script src="../../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1a98128..c92638e 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,39 @@
+2010-07-04 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Darin Fisher.
+
+ Need to track texture completeness
+ https://bugs.webkit.org/show_bug.cgi?id=41381
+
+ Test: fast/canvas/webgl/texture-complete.html
+
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::WebGLRenderingContext): Init max texture level.
+ (WebCore::WebGLRenderingContext::bindTexture): Pass max texture level to setTarget().
+ (WebCore::WebGLRenderingContext::copyTexImage2D): Cache full texture info rather than partial.
+ (WebCore::WebGLRenderingContext::generateMipmap): Ditto.
+ (WebCore::WebGLRenderingContext::texImage2DBase): Ditto.
+ (WebCore::WebGLRenderingContext::validateTexFuncParameters): Also validate level.
+ * html/canvas/WebGLRenderingContext.h: Add max texture level.
+ * html/canvas/WebGLTexture.cpp: Update the class to fully cache texture information and track NPOT and COMPLETE states.
+ (WebCore::WebGLTexture::WebGLTexture):
+ (WebCore::WebGLTexture::setTarget): Check whether the texture is initialized or has been deleted.
+ (WebCore::WebGLTexture::setParameteri): Ditto.
+ (WebCore::WebGLTexture::setParameterf): Ditto.
+ (WebCore::WebGLTexture::setLevelInfo): Set texture info.
+ (WebCore::WebGLTexture::generateMipmapLevelInfo): Generate texture info for all levels after generateMipmaps() is called.
+ (WebCore::WebGLTexture::getInternalFormat): Return internal format on texture face 0 level 0.
+ (WebCore::WebGLTexture::isNPOT): Check whether the texture is initialized or has been deleted.
+ (WebCore::WebGLTexture::needToUseBlackTexture): Ditto.
+ (WebCore::WebGLTexture::_deleteObject):
+ (WebCore::WebGLTexture::mapTargetToIndex): Map target to index.
+ (WebCore::WebGLTexture::canGenerateMipmaps): Check whether Mipmaps can be generated.
+ (WebCore::WebGLTexture::computeLevelCount): Compute texture level count from width/height.
+ (WebCore::WebGLTexture::update): Update NPOT/COMPLETE states.
+ * html/canvas/WebGLTexture.h: Ditto.
+ (WebCore::WebGLTexture::LevelInfo::LevelInfo): Add data structure to fully cache texture info.
+ (WebCore::WebGLTexture::LevelInfo::setInfo): Set information.
+
2010-07-13 Andreas Kling <andreas.kling at nokia.com>
Reviewed by Darin Adler.
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index b166c3b..a09e3ae 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -115,12 +115,12 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
m_context->getIntegerv(GraphicsContext3D::IMPLEMENTATION_COLOR_READ_TYPE, &implementationColorReadType);
m_implementationColorReadType = implementationColorReadType;
- int maxTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
- m_maxTextureSize = maxTextureSize;
- int maxCubeMapTextureSize = 0;
- m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapTextureSize);
- m_maxCubeMapTextureSize = maxCubeMapTextureSize;
+ m_maxTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+ m_maxCubeMapTextureSize = 0;
+ m_context->getIntegerv(GraphicsContext3D::MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+ m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
if (!isGLES2Compliant()) {
createFallbackBlackTextures1x1();
@@ -293,17 +293,20 @@ void WebGLRenderingContext::bindTexture(unsigned long target, WebGLTexture* text
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
- if (target == GraphicsContext3D::TEXTURE_2D)
+ int maxLevel = 0;
+ if (target == GraphicsContext3D::TEXTURE_2D) {
m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
- else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
+ maxLevel = m_maxTextureLevel;
+ } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
- else {
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
return;
}
m_context->bindTexture(target, texture);
if (!isGLES2Compliant() && texture)
- texture->setTarget(target);
+ texture->setTarget(target, maxLevel);
cleanupAfterGraphicsCall(false);
}
@@ -555,10 +558,8 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
// FIXME: if the framebuffer is not complete, none of the below should be executed.
WebGLTexture* tex = getTextureBinding(target);
if (!isGLES2Compliant()) {
- if (tex && !level) // only for level 0
- tex->setSize(target, width, height);
if (tex)
- tex->setInternalFormat(internalformat);
+ tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
}
if (m_framebufferBinding && tex)
m_framebufferBinding->onAttachedObjectChange(tex);
@@ -1130,18 +1131,22 @@ void WebGLRenderingContext::frontFace(unsigned long mode)
void WebGLRenderingContext::generateMipmap(unsigned long target)
{
+ RefPtr<WebGLTexture> tex;
if (!isGLES2Compliant()) {
- RefPtr<WebGLTexture> tex = 0;
if (target == GraphicsContext3D::TEXTURE_2D)
tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding;
else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP)
tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding;
- if (tex && tex->isNPOT()) {
+ if (tex && !tex->canGenerateMipmaps()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
}
m_context->generateMipmap(target);
+ if (!isGLES2Compliant()) {
+ if (tex)
+ tex->generateMipmapLevelInfo();
+ }
cleanupAfterGraphicsCall(false);
}
@@ -2130,10 +2135,8 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
border, format, type, pixels);
WebGLTexture* tex = getTextureBinding(target);
if (!isGLES2Compliant()) {
- if (tex && !level) // only for level 0
- tex->setSize(target, width, height);
if (tex)
- tex->setInternalFormat(internalformat);
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
}
if (m_framebufferBinding && tex)
m_framebufferBinding->onAttachedObjectChange(tex);
@@ -3417,9 +3420,6 @@ bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long
if (!validateTexFuncFormatAndType(format, type))
return false;
- if (isGLES2Compliant())
- return true;
-
if (width < 0 || height < 0 || level < 0) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return false;
@@ -3427,7 +3427,7 @@ bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long
switch (target) {
case GraphicsContext3D::TEXTURE_2D:
- if (width > m_maxTextureSize || height > m_maxTextureSize) {
+ if (width > m_maxTextureSize || height > m_maxTextureSize || level > m_maxTextureLevel) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return false;
}
@@ -3438,7 +3438,7 @@ bool WebGLRenderingContext::validateTexFuncParameters(unsigned long target, long
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (width != height || width > m_maxCubeMapTextureSize) {
+ if (width != height || width > m_maxCubeMapTextureSize || level > m_maxCubeMapTextureLevel) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return false;
}
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index dc000b6..fa0d9d0 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -412,8 +412,10 @@ class WebKitCSSMatrix;
RefPtr<WebGLTexture> m_blackTexture2D;
RefPtr<WebGLTexture> m_blackTextureCubeMap;
- long m_maxTextureSize;
- long m_maxCubeMapTextureSize;
+ int m_maxTextureSize;
+ int m_maxCubeMapTextureSize;
+ int m_maxTextureLevel;
+ int m_maxCubeMapTextureLevel;
int m_packAlignment;
int m_unpackAlignment;
diff --git a/WebCore/html/canvas/WebGLTexture.cpp b/WebCore/html/canvas/WebGLTexture.cpp
index 1cc7d5d..d832038 100644
--- a/WebCore/html/canvas/WebGLTexture.cpp
+++ b/WebCore/html/canvas/WebGLTexture.cpp
@@ -45,32 +45,39 @@ WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
, m_magFilter(GraphicsContext3D::LINEAR)
, m_wrapS(GraphicsContext3D::REPEAT)
, m_wrapT(GraphicsContext3D::REPEAT)
- , m_internalFormat(0)
, m_isNPOT(false)
+ , m_isComplete(false)
, m_needToUseBlackTexture(false)
{
setObject(context()->graphicsContext3D()->createTexture());
- for (int ii = 0; ii < 6; ++ii) {
- m_width[ii] = 0;
- m_height[ii] = 0;
- }
}
-void WebGLTexture::setTarget(unsigned long target)
+void WebGLTexture::setTarget(unsigned long target, int maxLevel)
{
+ if (!object())
+ return;
// Target is finalized the first time bindTexture() is called.
if (m_target)
return;
switch (target) {
case GraphicsContext3D::TEXTURE_2D:
+ m_target = target;
+ m_info.resize(1);
+ m_info[0].resize(maxLevel);
+ break;
case GraphicsContext3D::TEXTURE_CUBE_MAP:
m_target = target;
+ m_info.resize(6);
+ for (int ii = 0; ii < 6; ++ii)
+ m_info[ii].resize(maxLevel);
break;
}
}
void WebGLTexture::setParameteri(unsigned long pname, int param)
{
+ if (!object() || !m_target)
+ return;
switch (pname) {
case GraphicsContext3D::TEXTURE_MIN_FILTER:
switch (param) {
@@ -113,88 +120,195 @@ void WebGLTexture::setParameteri(unsigned long pname, int param)
default:
return;
}
- updateNPOTStates();
+ update();
}
void WebGLTexture::setParameterf(unsigned long pname, float param)
{
+ if (!object() || !m_target)
+ return;
int iparam = static_cast<int>(param);
setParameteri(pname, iparam);
}
-void WebGLTexture::setSize(unsigned long target, unsigned width, unsigned height)
+void WebGLTexture::setLevelInfo(unsigned long target, int level, unsigned long internalFormat, int width, int height, unsigned long type)
{
- if (!width || !height)
+ if (!object() || !m_target)
return;
- int iTarget = -1;
+ // We assume level, internalFormat, width, height, and type have all been
+ // validated already.
+ int index = mapTargetToIndex(target);
+ if (index < 0)
+ return;
+ m_info[index][level].setInfo(internalFormat, width, height, type);
+ update();
+}
+
+void WebGLTexture::generateMipmapLevelInfo()
+{
+ if (!object() || !m_target)
+ return;
+ if (!canGenerateMipmaps())
+ return;
+ if (m_isComplete)
+ return;
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ const LevelInfo& info0 = m_info[ii][0];
+ int width = info0.width;
+ int height = info0.height;
+ int levelCount = computeLevelCount(width, height);
+ for (int level = 1; level < levelCount; ++level) {
+ width = std::max(1, width >> 1);
+ height = std::max(1, height >> 1);
+ LevelInfo& info = m_info[ii][level];
+ info.setInfo(info0.internalFormat, width, height, info0.type);
+ }
+ }
+ m_isComplete = true;
+}
+
+unsigned long WebGLTexture::getInternalFormat() const
+{
+ if (!object() || !m_target)
+ return 0;
+ return m_info[0][0].internalFormat;
+}
+
+bool WebGLTexture::isNPOT(unsigned width, unsigned height)
+{
+ if (!width || !height)
+ return false;
+ if ((width & (width - 1)) || (height & (height - 1)))
+ return true;
+ return false;
+}
+
+bool WebGLTexture::isNPOT() const
+{
+ if (!object())
+ return false;
+ return m_isNPOT;
+}
+
+bool WebGLTexture::needToUseBlackTexture() const
+{
+ if (!object())
+ return false;
+ return m_needToUseBlackTexture;
+}
+
+void WebGLTexture::_deleteObject(Platform3DObject object)
+{
+ context()->graphicsContext3D()->deleteTexture(object);
+}
+
+int WebGLTexture::mapTargetToIndex(unsigned long target)
+{
if (m_target == GraphicsContext3D::TEXTURE_2D) {
if (target == GraphicsContext3D::TEXTURE_2D)
- iTarget = 0;
- } else if (m_target == GraphicsContext3D::TEXTURE_CUBE_MAP && width == height) {
+ return 0;
+ } else if (m_target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
switch (target) {
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:
- iTarget = 0;
- break;
+ return 0;
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:
- iTarget = 1;
- break;
+ return 1;
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:
- iTarget = 2;
- break;
+ return 2;
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:
- iTarget = 3;
- break;
+ return 3;
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
- iTarget = 4;
- break;
+ return 4;
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
- iTarget = 5;
- break;
+ return 5;
}
}
- if (iTarget < 0)
- return;
- m_width[iTarget] = width;
- m_height[iTarget] = height;
- updateNPOTStates();
+ return -1;
}
-bool WebGLTexture::isNPOT(unsigned width, unsigned height)
+bool WebGLTexture::canGenerateMipmaps()
{
- if (!width || !height)
+ if (isNPOT())
return false;
- if ((width & (width - 1)) || (height & (height - 1)))
- return true;
- return false;
+ const LevelInfo& first = m_info[0][0];
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ const LevelInfo& info = m_info[ii][0];
+ if (!info.valid
+ || info.width != first.width || info.height != first.height
+ || info.internalFormat != first.internalFormat || info.type != first.type)
+ return false;
+ }
+ return true;
}
-void WebGLTexture::_deleteObject(Platform3DObject object)
+int WebGLTexture::computeLevelCount(int width, int height)
{
- context()->graphicsContext3D()->deleteTexture(object);
+ // return 1 + log2Floor(std::max(width, height));
+ int n = std::max(width, height);
+ if (n <= 0)
+ return 0;
+ int log = 0;
+ int value = n;
+ for (int ii = 4; ii >= 0; --ii) {
+ int shift = (1 << ii);
+ int x = (value >> shift);
+ if (x) {
+ value = x;
+ log += shift;
+ }
+ }
+ ASSERT(value == 1);
+ return log + 1;
}
-void WebGLTexture::updateNPOTStates()
+void WebGLTexture::update()
{
- int numTargets = 0;
- if (m_target == GraphicsContext3D::TEXTURE_2D)
- numTargets = 1;
- else if (m_target == GraphicsContext3D::TEXTURE_CUBE_MAP)
- numTargets = 6;
m_isNPOT = false;
- unsigned w0 = m_width[0], h0 = m_height[0];
- for (int ii = 0; ii < numTargets; ++ii) {
- if (ii && (!m_width[ii] || !m_height[ii] || m_width[ii] != w0 || m_height[ii] != h0)) {
- // We only set NPOT for complete cube map textures.
- m_isNPOT = false;
+ for (size_t ii = 0; ii < m_info.size(); ++ii) {
+ if (isNPOT(m_info[ii][0].width, m_info[ii][0].height)) {
+ m_isNPOT = true;
break;
}
- if (isNPOT(m_width[ii], m_height[ii]))
- m_isNPOT = true;
}
+ m_isComplete = true;
+ const LevelInfo& first = m_info[0][0];
+ int levelCount = computeLevelCount(first.width, first.height);
+ if (levelCount < 1)
+ m_isComplete = false;
+ else {
+ for (size_t ii = 0; ii < m_info.size() && m_isComplete; ++ii) {
+ const LevelInfo& info0 = m_info[ii][0];
+ if (!info0.valid
+ || info0.width != first.width || info0.height != first.height
+ || info0.internalFormat != first.internalFormat || info0.type != first.type) {
+ m_isComplete = false;
+ break;
+ }
+ int width = info0.width;
+ int height = info0.height;
+ for (int level = 1; level < levelCount; ++level) {
+ width = std::max(1, width >> 1);
+ height = std::max(1, height >> 1);
+ const LevelInfo& info = m_info[ii][level];
+ if (!info.valid
+ || info.width != width || info.height != height
+ || info.internalFormat != info0.internalFormat || info.type != info0.type) {
+ m_isComplete = false;
+ break;
+ }
+
+ }
+ }
+ }
+
m_needToUseBlackTexture = false;
+ // NPOT
if (m_isNPOT && ((m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::LINEAR)
|| m_wrapS != GraphicsContext3D::CLAMP_TO_EDGE || m_wrapT != GraphicsContext3D::CLAMP_TO_EDGE))
m_needToUseBlackTexture = true;
+ // Completeness
+ if (!m_isComplete && m_minFilter != GraphicsContext3D::NEAREST && m_minFilter != GraphicsContext3D::LINEAR)
+ m_needToUseBlackTexture = true;
}
}
diff --git a/WebCore/html/canvas/WebGLTexture.h b/WebCore/html/canvas/WebGLTexture.h
index 4d16b59..d4a32f0 100644
--- a/WebCore/html/canvas/WebGLTexture.h
+++ b/WebCore/html/canvas/WebGLTexture.h
@@ -30,6 +30,7 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
namespace WebCore {
@@ -47,19 +48,26 @@ namespace WebCore {
cubeMapRWrapModeInitialized = initialized;
}
- void setTarget(unsigned long);
+ void setTarget(unsigned long target, int maxLevel);
void setParameteri(unsigned long pname, int param);
void setParameterf(unsigned long pname, float param);
- void setSize(unsigned long target, unsigned width, unsigned height);
- void setInternalFormat(unsigned long internalformat) { m_internalFormat = internalformat; }
- unsigned long getInternalFormat() const { return m_internalFormat; }
+ void setLevelInfo(unsigned long target, int level, unsigned long internalFormat, int width, int height, unsigned long type);
+ bool canGenerateMipmaps();
+ // Generate all level information.
+ void generateMipmapLevelInfo();
+
+ unsigned long getInternalFormat() const;
+
+ // Whether width/height is NotPowerOfTwo.
static bool isNPOT(unsigned, unsigned);
- bool isNPOT() const { return m_isNPOT; }
+ bool isNPOT() const;
// Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2).
- bool needToUseBlackTexture() const { return m_needToUseBlackTexture; }
+ bool needToUseBlackTexture() const;
+
+ static int computeLevelCount(int width, int height);
protected:
WebGLTexture(WebGLRenderingContext*);
@@ -69,7 +77,9 @@ namespace WebCore {
private:
virtual bool isTexture() const { return true; }
- void updateNPOTStates();
+ void update();
+
+ int mapTargetToIndex(unsigned long);
bool cubeMapRWrapModeInitialized;
@@ -80,12 +90,37 @@ namespace WebCore {
int m_wrapS;
int m_wrapT;
- unsigned long m_internalFormat;
-
- unsigned m_width[6];
- unsigned m_height[6];
+ class LevelInfo {
+ public:
+ LevelInfo()
+ : valid(false)
+ , internalFormat(0)
+ , width(0)
+ , height(0)
+ , type(0)
+ {
+ }
+
+ void setInfo(unsigned long internalFmt, int w, int h, unsigned long tp)
+ {
+ valid = true;
+ internalFormat = internalFmt;
+ width = w;
+ height = h;
+ type = tp;
+ }
+
+ bool valid;
+ unsigned long internalFormat;
+ int width;
+ int height;
+ unsigned long type;
+ };
+
+ Vector<Vector<LevelInfo> > m_info;
bool m_isNPOT;
+ bool m_isComplete;
bool m_needToUseBlackTexture;
};
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list