Bug 33805 - Must implement OpenGL ES 2.0 semantics for NPOT textures
Summary: Must implement OpenGL ES 2.0 semantics for NPOT textures
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebGL (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac All
: P2 Normal
Assignee: Zhenyao Mo
URL:
Keywords: InRadar
Depends on:
Blocks: 43873
  Show dependency treegraph
 
Reported: 2010-01-18 10:58 PST by Chris Marrin
Modified: 2010-08-12 13:31 PDT (History)
10 users (show)

See Also:


Attachments
patch (63.05 KB, patch)
2010-04-24 22:57 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
revised patch: fix style issues (62.80 KB, patch)
2010-04-24 23:15 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
revised patch: fix a tiny issue (62.98 KB, patch)
2010-04-26 14:37 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
revised patch (28.82 KB, patch)
2010-05-05 15:41 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
revised patch: responding to Gregg Tavares comments (30.25 KB, patch)
2010-05-05 18:47 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
revised patch : responding to Ken Russell's review (27.71 KB, patch)
2010-05-11 18:04 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
revised patch: tiny modification (27.83 KB, patch)
2010-05-11 18:13 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff
patch (3.53 KB, patch)
2010-05-14 11:50 PDT, Zhenyao Mo
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Marrin 2010-01-18 10:58:08 PST
The OpenGL ES 2.0 does not allow mipmapping of NPOT textures. Most desktop OpenGL implementations do. We need to implement the rules specified in the OpenGL ES 2.0 spec, section 3.8.2.
Comment 1 Alice Liu 2010-03-19 17:11:19 PDT
<rdar://problem/7774338>
Comment 2 Kenneth Russell 2010-04-15 11:42:00 PDT
In addition to the mipmapping restrictions, OpenGL ES 2.0 (and therefore WebGL) requires that the repeat mode CLAMP_TO_EDGE be used for NPOT textures. Per the OpenGL ES 2.0 specification section 3.8.2, if for a NPOT texture the minification filter is not GL_NEAREST or GL_LINEAR, or the clamp mode is not CLAMP_TO_EDGE, then sampling the texture in a shader results in (R, G, B, A) = (0, 0, 0, 1). glGenerateMipmaps for a NPOT texture also needs to produce INVALID_OPERATION.
Comment 3 Zhenyao Mo 2010-04-24 22:57:22 PDT
Created attachment 54229 [details]
patch
Comment 4 WebKit Review Bot 2010-04-24 23:02:54 PDT
Attachment 54229 [details] did not pass style-queue:

Failed to run "['WebKitTools/Scripts/check-webkit-style']" exit_code: 1
WebCore/html/canvas/WebGLRenderingContext.cpp:472:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLRenderingContext.cpp:1414:  An else if statement should be written as an if statement when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
WebCore/html/canvas/WebGLRenderingContext.cpp:1909:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLRenderingContext.cpp:1981:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLRenderingContext.cpp:2060:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLRenderingContext.cpp:2140:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLTexture.cpp:83:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLTexture.cpp:161:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLTexture.cpp:203:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
WebCore/html/canvas/WebGLTexture.cpp:205:  Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.  [readability/comparison_to_zero] [5]
Total errors found: 10 in 16 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 5 Oliver Hunt 2010-04-24 23:09:29 PDT
(In reply to comment #3)
> Created an attachment (id=54229) [details]
> patch

Zhenyao you can test for style correctness yourself by running the check-webkit-style script, it may save some time waiting for the style bot to catch up :D
Comment 6 Zhenyao Mo 2010-04-24 23:15:39 PDT
Created attachment 54230 [details]
revised patch: fix style issues
Comment 7 Zhenyao Mo 2010-04-26 14:37:51 PDT
Created attachment 54333 [details]
revised patch: fix a tiny issue

fallback color should be [0, 0, 0, 1] instead of [0, 0, 0, 0] in the original conformance test we copied.
Comment 8 Zhenyao Mo 2010-04-26 14:40:38 PDT
(In reply to comment #5)
> (In reply to comment #3)
> > Created an attachment (id=54229) [details] [details]
> > patch
> 
> Zhenyao you can test for style correctness yourself by running the
> check-webkit-style script, it may save some time waiting for the style bot to
> catch up :D

Thanks for the info.  Sometimes I just get over-confident about my coding style so I unwisely skip the style check. :)
Comment 9 Zhenyao Mo 2010-05-05 15:41:21 PDT
Created attachment 55162 [details]
revised patch
Comment 10 Zhenyao Mo 2010-05-05 18:47:37 PDT
Created attachment 55191 [details]
revised patch: responding to Gregg Tavares comments

The following comments are from Gregg Tavares:

"""
at line 773 you only check m_activeTextureUnit.  You actually have to loop over all the texture units as in

for (GLint ii = 0; ii < max_active_texture_units; ++ii) {
  RefPtr<WebGLTexture> tex2D = m_textureUnits[ii].m_texture2DBinding;

Then, if the texture needs binding you have to call glActiveTexture to make that the active texture unit before you call glBindTexture

Finally, after you call glDraw and you have to loop again, restore all the textures with a similar loop and finally call glActiveTexture to set it back to what it was before you entered this function.
"""
Comment 11 Kenneth Russell 2010-05-10 17:48:03 PDT
Comment on attachment 55191 [details]
revised patch: responding to Gregg Tavares comments

This is good work, but I think it needs some more work before committing.


WebCore/html/canvas/WebGLRenderingContext.cpp:109
 +          addObject(m_blackTextureCubeMap.get());
I think the logic for setting up the 1x1 black texture should be in a private method of the WebGLRenderingContext, not in the WebGLTexture class. That way you can use WebGLRenderingContext::createTexture() to allocate the object and you don't need the manual calls to addObject, which are error prone.


WebCore/html/canvas/WebGLRenderingContext.cpp:458
 +              tex->setSize(target, width, height);
This line should not be executed if the texture is a cube map and the width and height are unequal. That is supposed to yield INVALID_VALUE and the texture's state should remain untouched. Consult Chromium's command buffer service code (TextureManager::ValidForTarget, GLES2DecoderImpl::DoTexImage2D).

WebCore/html/canvas/WebGLRenderingContext.cpp:1833
 +              tex->setSize(target, width, height);
Ditto.

WebCore/html/canvas/WebGLRenderingContext.cpp:3089
 +  }
These two routines contain nearly identical code. Please refactor them into one method taking a boolean argument. Perhaps "handleNPOTTextures(bool preparingForDraw)". Also please add FIXME around use of constant 32.

WebCore/html/canvas/WebGLTexture.cpp:87
 +  void WebGLTexture::setDimensionality(unsigned long dimensionality)
"Dimensionality" is a confusing choice of word. Since everywhere else in the OpenGL spec this concept is "target", please use that term instead.


WebCore/html/canvas/WebGLTexture.cpp:165
 +          if (m_dimensionality == GraphicsContext3D::TEXTURE_CUBE_MAP)
Please factor this "if" clause out of the switch statement.

WebCore/html/canvas/WebGLTexture.cpp:199
 +          return false;
I'm not sure this short circuit is correct. At least it is inconsistent with the command buffer implementation. I think this should read

if (width && (width & (width - 1)))
  return true;

Similarly for height.

WebCore/html/canvas/WebGLTexture.cpp:221
 +              // We only set NPOT for complete cube map textures.
Why is this the case? The command buffer implementation also tracks cube map completeness and manually switches in a black texture if the texture is not cube map complete. I don't think the desktop GL spec has the same guarantees that the OpenGL ES 2.0 spec does in this area (See the OpenGL 2.1 spec, section 3.8.10 "Texture Completeness", subsection "Effects of Completeness on Texture Application") so I think you need all of the logic.


LayoutTests/fast/canvas/webgl/texture-npot.html:85
 +                            canvas2d);         // internalFormat
Incorrect comment.


LayoutTests/fast/canvas/webgl/texture-npot.html:92
 +                            canvas2d);         // internalFormat
Incorrect comment.


LayoutTests/fast/canvas/webgl/texture-npot.html:138
 +                    //      buf[offset + 3]);
Please delete commented out code.
Comment 12 Zhenyao Mo 2010-05-11 18:03:10 PDT
(In reply to comment #11)
> (From update of attachment 55191 [details])
> This is good work, but I think it needs some more work before committing.
> 
> 
> WebCore/html/canvas/WebGLRenderingContext.cpp:109
>  +          addObject(m_blackTextureCubeMap.get());
> I think the logic for setting up the 1x1 black texture should be in a private method of the WebGLRenderingContext, not in the WebGLTexture class. That way you can use WebGLRenderingContext::createTexture() to allocate the object and you don't need the manual calls to addObject, which are error prone.
Done.

> 
> 
> WebCore/html/canvas/WebGLRenderingContext.cpp:458
>  +              tex->setSize(target, width, height);
> This line should not be executed if the texture is a cube map and the width and height are unequal. That is supposed to yield INVALID_VALUE and the texture's state should remain untouched. Consult Chromium's command buffer service code (TextureManager::ValidForTarget, GLES2DecoderImpl::DoTexImage2D).
Done inside setSize().

> 
> WebCore/html/canvas/WebGLRenderingContext.cpp:1833
>  +              tex->setSize(target, width, height);
> Ditto.
> 
Ditto.

> WebCore/html/canvas/WebGLRenderingContext.cpp:3089
>  +  }
> These two routines contain nearly identical code. Please refactor them into one method taking a boolean argument. Perhaps "handleNPOTTextures(bool preparingForDraw)". Also please add FIXME around use of constant 32.
> 
Done.

> WebCore/html/canvas/WebGLTexture.cpp:87
>  +  void WebGLTexture::setDimensionality(unsigned long dimensionality)
> "Dimensionality" is a confusing choice of word. Since everywhere else in the OpenGL spec this concept is "target", please use that term instead.
> 
Done.

> 
> WebCore/html/canvas/WebGLTexture.cpp:165
>  +          if (m_dimensionality == GraphicsContext3D::TEXTURE_CUBE_MAP)
> Please factor this "if" clause out of the switch statement.
Done.

> 
> WebCore/html/canvas/WebGLTexture.cpp:199
>  +          return false;
> I'm not sure this short circuit is correct. At least it is inconsistent with the command buffer implementation. I think this should read
> 
> if (width && (width & (width - 1)))
>   return true;
> 
> Similarly for height.
Per discussion, we won't raise NPOT for incomplete textures.  Desktop GL will handle those case.

> 
> WebCore/html/canvas/WebGLTexture.cpp:221
>  +              // We only set NPOT for complete cube map textures.
> Why is this the case? The command buffer implementation also tracks cube map completeness and manually switches in a black texture if the texture is not cube map complete. I don't think the desktop GL spec has the same guarantees that the OpenGL ES 2.0 spec does in this area (See the OpenGL 2.1 spec, section 3.8.10 "Texture Completeness", subsection "Effects of Completeness on Texture Application") so I think you need all of the logic.
Per discussion, we won't raise NPOT for incomplete textures.  Desktop GL will handle those case.

> 
> 
> LayoutTests/fast/canvas/webgl/texture-npot.html:85
>  +                            canvas2d);         // internalFormat
> Incorrect comment.
Done.

> 
> 
> LayoutTests/fast/canvas/webgl/texture-npot.html:92
>  +                            canvas2d);         // internalFormat
> Incorrect comment.
Done (need to fix this in webgl conformance text also).

> 
> 
> LayoutTests/fast/canvas/webgl/texture-npot.html:138
>  +                    //      buf[offset + 3]);
> Please delete commented out code.
Done.
Comment 13 Zhenyao Mo 2010-05-11 18:04:20 PDT
Created attachment 55789 [details]
revised patch : responding to Ken Russell's review
Comment 14 Zhenyao Mo 2010-05-11 18:13:06 PDT
Created attachment 55790 [details]
revised patch: tiny modification

After setting up black 1x1 textures, need to unbind them.
Comment 15 Kenneth Russell 2010-05-11 18:36:20 PDT
Comment on attachment 55790 [details]
revised patch: tiny modification

Looks good. Thanks for doing a thorough job on this.
Comment 16 Dimitri Glazkov (Google) 2010-05-11 20:30:19 PDT
Comment on attachment 55790 [details]
revised patch: tiny modification

rs=me.
Comment 17 WebKit Commit Bot 2010-05-14 05:52:25 PDT
Comment on attachment 55790 [details]
revised patch: tiny modification

Clearing flags on attachment: 55790

Committed r59470: <http://trac.webkit.org/changeset/59470>
Comment 18 WebKit Commit Bot 2010-05-14 05:52:33 PDT
All reviewed patches have been landed.  Closing bug.
Comment 19 WebKit Review Bot 2010-05-14 08:01:52 PDT
http://trac.webkit.org/changeset/59470 might have broken Leopard Intel Debug (Tests)
Comment 20 Eric Seidel (no email) 2010-05-14 10:06:52 PDT
The sherriff is right. This broke leopard.   Zmo: please advise.
Comment 21 Kenneth Russell 2010-05-14 10:13:56 PDT
Test results linked from here:

http://build.webkit.org/results/Leopard%20Intel%20Debug%20(Tests)/r59472%20(14407)/results.html
Comment 22 Zhenyao Mo 2010-05-14 11:18:09 PDT
The NPOT test is failing on a bot.  Reopen this to investigate the cause.
Comment 23 Zhenyao Mo 2010-05-14 11:50:57 PDT
Created attachment 56090 [details]
patch

Removed the test cases that failed on leopard bot (temporarily).
Created another bug to track this: https://bugs.webkit.org/show_bug.cgi?id=39128
Comment 24 Eric Seidel (no email) 2010-05-14 11:52:47 PDT
Comment on attachment 56090 [details]
patch

OK.  CQ won't work for this since the tree is red.  But I"ll land manually.
Comment 25 Eric Seidel (no email) 2010-05-14 12:00:21 PDT
Comment on attachment 56090 [details]
patch

Clearing flags on attachment: 56090

Committed r59479: <http://trac.webkit.org/changeset/59479>
Comment 26 Eric Seidel (no email) 2010-05-14 12:00:33 PDT
All reviewed patches have been landed.  Closing bug.