Title: [196460] trunk/Source/WebCore
Revision
196460
Author
[email protected]
Date
2016-02-11 17:05:48 -0800 (Thu, 11 Feb 2016)

Log Message

Optimize texture-complete checks
https://bugs.webkit.org/show_bug.cgi?id=98308

Reviewed by Dean Jackson.

No new tests: No change in behavior.

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::initializeNewContext): Initially consider all
textures as suspect.
(WebCore::WebGLRenderingContextBase::extensions): New helper function.
(WebCore::WebGLRenderingContextBase::reshape): Mark textures as invalid when appropriate.
(WebCore::WebGLRenderingContextBase::bindTexture): Identify invalid textures and mark
them for later fix-up. Likewise, remove 'known good' textures from the fix-up pass.
(WebCore::WebGLRenderingContextBase::deleteTexture): Remove instances of the deleted texture
from our set of invalid textures.
(WebCore::WebGLRenderingContextBase::checkTextureCompleteness): Only iterate through
the 'bad' textures, rather than checking every single texture.
* html/canvas/WebGLRenderingContextBase.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (196459 => 196460)


--- trunk/Source/WebCore/ChangeLog	2016-02-12 01:05:14 UTC (rev 196459)
+++ trunk/Source/WebCore/ChangeLog	2016-02-12 01:05:48 UTC (rev 196460)
@@ -1,3 +1,25 @@
+2016-02-11  Brent Fulgham  <[email protected]>
+
+        Optimize texture-complete checks
+        https://bugs.webkit.org/show_bug.cgi?id=98308
+
+        Reviewed by Dean Jackson.
+
+        No new tests: No change in behavior.
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::initializeNewContext): Initially consider all
+        textures as suspect.
+        (WebCore::WebGLRenderingContextBase::extensions): New helper function.
+        (WebCore::WebGLRenderingContextBase::reshape): Mark textures as invalid when appropriate.
+        (WebCore::WebGLRenderingContextBase::bindTexture): Identify invalid textures and mark
+        them for later fix-up. Likewise, remove 'known good' textures from the fix-up pass.
+        (WebCore::WebGLRenderingContextBase::deleteTexture): Remove instances of the deleted texture
+        from our set of invalid textures.
+        (WebCore::WebGLRenderingContextBase::checkTextureCompleteness): Only iterate through
+        the 'bad' textures, rather than checking every single texture.
+        * html/canvas/WebGLRenderingContextBase.h:
+
 2016-02-11  Alex Christensen  <[email protected]>
 
         Assert that IDBTransaction::transitionedToFinishing transitions to finishing.

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (196459 => 196460)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2016-02-12 01:05:14 UTC (rev 196459)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2016-02-12 01:05:48 UTC (rev 196460)
@@ -520,6 +520,8 @@
     m_context->getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
     m_textureUnits.clear();
     m_textureUnits.resize(numCombinedTextureImageUnits);
+    for (GC3Dint i = 0; i < numCombinedTextureImageUnits; ++i)
+        m_unrenderableTextureUnits.add(i);
 
     GC3Dint numVertexAttribs = 0;
     m_context->getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &numVertexAttribs);
@@ -749,6 +751,11 @@
     return m_context->paintRenderingResultsToImageData();
 }
 
+WebGLTexture::TextureExtensionFlag WebGLRenderingContextBase::textureExtensionFlags() const
+{
+    return static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureExtensionFloatLinearEnabled : 0) | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureExtensionHalfFloatLinearEnabled : 0));
+}
+
 void WebGLRenderingContextBase::reshape(int width, int height)
 {
     if (isContextLostOrPending())
@@ -776,7 +783,10 @@
     // clear (and this matches what reshape will do).
     m_context->reshape(width, height);
 
-    m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].texture2DBinding.get()));
+    auto& textureUnit = m_textureUnits[m_activeTextureUnit];
+    m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(textureUnit.texture2DBinding.get()));
+    if (textureUnit.texture2DBinding && textureUnit.texture2DBinding->needToUseBlackTexture(textureExtensionFlags()))
+        m_unrenderableTextureUnits.add(m_activeTextureUnit);
     m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
     if (m_framebufferBinding)
       m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
@@ -944,18 +954,27 @@
     if (!checkObjectToBeBound("bindTexture", texture, deleted))
         return;
     if (deleted)
-        texture = 0;
+        texture = nullptr;
     if (texture && texture->getTarget() && texture->getTarget() != target) {
         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
         return;
     }
     GC3Dint maxLevel = 0;
+    auto& textureUnit = m_textureUnits[m_activeTextureUnit];
     if (target == GraphicsContext3D::TEXTURE_2D) {
-        m_textureUnits[m_activeTextureUnit].texture2DBinding = texture;
+        textureUnit.texture2DBinding = texture;
         maxLevel = m_maxTextureLevel;
+        if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+            m_unrenderableTextureUnits.add(m_activeTextureUnit);
+        else
+            m_unrenderableTextureUnits.remove(m_activeTextureUnit);
     } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
-        m_textureUnits[m_activeTextureUnit].textureCubeMapBinding = texture;
+        textureUnit.textureCubeMapBinding = texture;
         maxLevel = m_maxCubeMapTextureLevel;
+        if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+            m_unrenderableTextureUnits.add(m_activeTextureUnit);
+        else
+            m_unrenderableTextureUnits.remove(m_activeTextureUnit);
     } else {
         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target");
         return;
@@ -1500,11 +1519,18 @@
 {
     if (!deleteObject(texture))
         return;
+
+    unsigned current = 0;
     for (auto& textureUnit : m_textureUnits) {
-        if (texture == textureUnit.texture2DBinding)
+        if (texture == textureUnit.texture2DBinding) {
             textureUnit.texture2DBinding = nullptr;
-        if (texture == textureUnit.textureCubeMapBinding)
+            m_unrenderableTextureUnits.remove(current);
+        }
+        if (texture == textureUnit.textureCubeMapBinding) {
             textureUnit.textureCubeMapBinding = nullptr;
+            m_unrenderableTextureUnits.remove(current);
+        }
+        ++current;
     }
     if (m_framebufferBinding)
         m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
@@ -3955,39 +3981,50 @@
 void WebGLRenderingContextBase::checkTextureCompleteness(const char* functionName, bool prepareToDraw)
 {
     bool resetActiveUnit = false;
-    WebGLTexture::TextureExtensionFlag extensions = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureExtensionFloatLinearEnabled : 0) | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureExtensionHalfFloatLinearEnabled : 0));
+    WebGLTexture::TextureExtensionFlag extensions = textureExtensionFlags();
 
-    for (unsigned ii = 0; ii < m_textureUnits.size(); ++ii) {
-        if ((m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
-            || (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))) {
-            if (ii != m_activeTextureUnit) {
-                m_context->activeTexture(ii + GraphicsContext3D::TEXTURE0);
-                resetActiveUnit = true;
-            } else if (resetActiveUnit) {
-                m_context->activeTexture(ii + GraphicsContext3D::TEXTURE0);
-                resetActiveUnit = false;
-            }
-            WebGLTexture* tex2D;
-            WebGLTexture* texCubeMap;
-            if (prepareToDraw) {
-                String msg(String("texture bound to texture unit ") + String::number(ii)
-                    + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
-                    + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
-                printGLWarningToConsole(functionName, msg.utf8().data());
-                tex2D = m_blackTexture2D.get();
-                texCubeMap = m_blackTextureCubeMap.get();
-            } else {
-                tex2D = m_textureUnits[ii].texture2DBinding.get();
-                texCubeMap = m_textureUnits[ii].textureCubeMapBinding.get();
-            }
-            if (m_textureUnits[ii].texture2DBinding && m_textureUnits[ii].texture2DBinding->needToUseBlackTexture(extensions))
-                m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
-            if (m_textureUnits[ii].textureCubeMapBinding && m_textureUnits[ii].textureCubeMapBinding->needToUseBlackTexture(extensions))
-                m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+    Vector<unsigned> noLongerUnrenderable;
+    for (unsigned badTexture : m_unrenderableTextureUnits) {
+        ASSERT(badTexture < m_textureUnits.size());
+        auto& textureUnit = m_textureUnits[badTexture];
+        bool needsToUseBlack2DTexture = textureUnit.texture2DBinding && textureUnit.texture2DBinding->needToUseBlackTexture(extensions);
+        bool needsToUseBlack3DTexture = textureUnit.textureCubeMapBinding && textureUnit.textureCubeMapBinding->needToUseBlackTexture(extensions);
+
+        if (!needsToUseBlack2DTexture && !needsToUseBlack3DTexture) {
+            noLongerUnrenderable.append(badTexture);
+            continue;
         }
+
+        if (badTexture != m_activeTextureUnit) {
+            m_context->activeTexture(badTexture + GraphicsContext3D::TEXTURE0);
+            resetActiveUnit = true;
+        } else if (resetActiveUnit) {
+            m_context->activeTexture(badTexture + GraphicsContext3D::TEXTURE0);
+            resetActiveUnit = false;
+        }
+        WebGLTexture* tex2D;
+        WebGLTexture* texCubeMap;
+        if (prepareToDraw) {
+            String msg(String("texture bound to texture unit ") + String::number(badTexture)
+                + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete',"
+                + " or it is a float/half-float type with linear filtering and without the relevant float/half-float linear extension enabled.");
+            printGLWarningToConsole(functionName, msg.utf8().data());
+            tex2D = m_blackTexture2D.get();
+            texCubeMap = m_blackTextureCubeMap.get();
+        } else {
+            tex2D = textureUnit.texture2DBinding.get();
+            texCubeMap = textureUnit.textureCubeMapBinding.get();
+        }
+        if (needsToUseBlack2DTexture)
+            m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, objectOrZero(tex2D));
+        if (needsToUseBlack3DTexture)
+            m_context->bindTexture(GraphicsContext3D::TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
     }
     if (resetActiveUnit)
         m_context->activeTexture(m_activeTextureUnit + GraphicsContext3D::TEXTURE0);
+
+    for (unsigned renderable : noLongerUnrenderable)
+        m_unrenderableTextureUnits.remove(renderable);
 }
 
 void WebGLRenderingContextBase::createFallbackBlackTextures1x1()
@@ -4076,6 +4113,10 @@
         synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
         return nullptr;
     }
+
+    if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+        m_unrenderableTextureUnits.add(m_activeTextureUnit);
+
     if (!texture)
         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
     return texture;
@@ -4929,7 +4970,10 @@
 void WebGLRenderingContextBase::restoreCurrentTexture2D()
 {
     ExceptionCode ec;
-    bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureUnits[m_activeTextureUnit].texture2DBinding.get(), ec);
+    auto texture = m_textureUnits[m_activeTextureUnit].texture2DBinding.get();
+    bindTexture(GraphicsContext3D::TEXTURE_2D, texture, ec);
+    if (texture && texture->needToUseBlackTexture(textureExtensionFlags()))
+        m_unrenderableTextureUnits.add(m_activeTextureUnit);
 }
 
 bool WebGLRenderingContextBase::supportsDrawBuffers()

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (196459 => 196460)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2016-02-12 01:05:14 UTC (rev 196459)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2016-02-12 01:05:48 UTC (rev 196460)
@@ -33,6 +33,7 @@
 #include "Timer.h"
 #include "WebGLGetInfo.h"
 #include "WebGLObject.h"
+#include "WebGLTexture.h"
 #include <memory>
 #include <runtime/Float32Array.h>
 #include <runtime/Int32Array.h>
@@ -79,7 +80,6 @@
 class WebGLShader;
 class WebGLSharedObject;
 class WebGLShaderPrecisionFormat;
-class WebGLTexture;
 class WebGLUniformLocation;
 class WebGLVertexArrayObjectOES;
 
@@ -432,6 +432,8 @@
     PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, ExceptionCode&);
 #endif
 
+    WebGLTexture::TextureExtensionFlag textureExtensionFlags() const;
+
     RefPtr<GraphicsContext3D> m_context;
     RefPtr<WebGLContextGroup> m_contextGroup;
 
@@ -494,6 +496,8 @@
         RefPtr<WebGLTexture> textureCubeMapBinding;
     };
     Vector<TextureUnitState> m_textureUnits;
+    HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_unrenderableTextureUnits;
+
     unsigned long m_activeTextureUnit;
 
     RefPtr<WebGLTexture> m_blackTexture2D;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to