Diff
Modified: trunk/Source/WTF/ChangeLog (223314 => 223315)
--- trunk/Source/WTF/ChangeLog 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WTF/ChangeLog 2017-10-14 02:38:09 UTC (rev 223315)
@@ -1,3 +1,22 @@
+2017-10-13 Jer Noble <jer.no...@apple.com>
+
+ Performance: Skip texture upload if source image and destination texture haven't changed
+ https://bugs.webkit.org/show_bug.cgi?id=178254
+ <rdar://problem/34968181>
+
+ Reviewed by Dean Jackson.
+
+ Add a new class, UnsafePointer, for safely holding pointers to objects with uncontrolled lifetimes.
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/UnsafePointer.h: Added.
+ (WTF::UnsafePointer::UnsafePointer):
+ (WTF::UnsafePointer::operator== const):
+ (WTF::UnsafePointer::operator!= const):
+ (WTF::UnsafePointer::operator bool const):
+ (WTF::operator==):
+ (WTF::operator!=):
+
2017-10-13 Per Arne Vollan <pvol...@apple.com>
[Win] When built with VS2017, MiniBrowser crashes on startup.
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (223314 => 223315)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-10-14 02:38:09 UTC (rev 223315)
@@ -562,6 +562,7 @@
CD5497AA15857D0300B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = "<group>"; };
CD5497AB15857D0300B5BC30 /* MediaTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaTime.h; sourceTree = "<group>"; };
CD6D9FCD1EEF3AD4008B0671 /* Algorithms.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Algorithms.h; sourceTree = "<group>"; };
+ CD7600FF1F90A3CA00026E26 /* UnsafePointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UnsafePointer.h; sourceTree = "<group>"; };
CE46516D19DB1FB4003ECA05 /* NSMapTableSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSMapTableSPI.h; sourceTree = "<group>"; };
CE73E02419DCB7AB00580D5C /* XPCSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPCSPI.h; sourceTree = "<group>"; };
DCEE21FA1CEA7538000C2396 /* CFBundleSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CFBundleSPI.h; path = cf/CFBundleSPI.h; sourceTree = "<group>"; };
@@ -1015,6 +1016,7 @@
83FBA93119DF459700F30ADB /* TypeCasts.h */,
A8A4735C151A825B004123FF /* UnionFind.h */,
5C7C88D31D0A3A0A009D2F6D /* UniqueRef.h */,
+ CD7600FF1F90A3CA00026E26 /* UnsafePointer.h */,
7AFEC6B01EB22B5900DADE36 /* UUID.cpp */,
7AFEC6AE1EB22AC600DADE36 /* UUID.h */,
A8A4736F151A825B004123FF /* ValueCheck.h */,
Added: trunk/Source/WTF/wtf/UnsafePointer.h (0 => 223315)
--- trunk/Source/WTF/wtf/UnsafePointer.h (rev 0)
+++ trunk/Source/WTF/wtf/UnsafePointer.h 2017-10-14 02:38:09 UTC (rev 223315)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WTF {
+
+// A UnsafePointer<> can be used to hold a pointer whose lifetime is not guaranteed
+// and where the dereferencing of that pointer is therefore unsafe. Once assigned
+// to an UnsafePoniter<>, the pointer itself cannot be extracted from the class, but
+// the class can still be used to test for pointer equality.
+template<typename T>
+class UnsafePointer {
+public:
+ typedef typename std::remove_pointer<T>::type ValueType;
+ typedef ValueType* PtrType;
+
+ UnsafePointer() : m_pointer(nullptr) { }
+ UnsafePointer(PtrType pointer) : m_pointer(pointer) { }
+
+ bool operator==(PtrType pointer) const { return pointer == m_pointer; }
+ bool operator!=(PtrType pointer) const { return pointer != m_pointer; }
+ operator bool() const { return m_pointer; }
+
+private:
+ PtrType m_pointer;
+};
+
+template<typename T>
+bool operator==(typename UnsafePointer<T>::PtrType barePointer, const UnsafePointer<T>& unsafePointer)
+{
+ return unsafePointer == barePointer;
+}
+
+template<typename T>
+bool operator!=(typename UnsafePointer<T>::PtrType barePointer, const UnsafePointer<T>& unsafePointer)
+{
+ return unsafePointer != barePointer;
+}
+
+} // namespace WTF
+
+using WTF::UnsafePointer;
Modified: trunk/Source/WebCore/ChangeLog (223314 => 223315)
--- trunk/Source/WebCore/ChangeLog 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WebCore/ChangeLog 2017-10-14 02:38:09 UTC (rev 223315)
@@ -1,3 +1,42 @@
+2017-10-13 Jer Noble <jer.no...@apple.com>
+
+ Performance: Skip texture upload if source image and destination texture haven't changed
+ https://bugs.webkit.org/show_bug.cgi?id=178254
+ <rdar://problem/34968181>
+
+ Reviewed by Dean Jackson.
+
+ Update GraphicsContext3D to track which texture is bound to which texture unit, and also to
+ track when those bound textures have their backing stores modified. This new "seed" value
+ will be used to determine whether a given texture which has previously had image data
+ uploaded to it needs to be re-updated.
+
+ In VideoTextureCopierCV, track whether the texture's seed changed, whether the IOSurface is
+ the same, whether the IOSurface's seed has changed, and whether the "flipY" parameter
+ changed since the last time the copier was asked to upload to the texture.
+
+ * platform/graphics/GraphicsContext3D.h:
+ (WebCore::GraphicsContext3D::textureSeed):
+ (WebCore::GraphicsContext3D::GraphicsContext3DState::currentBoundTexture):
+ (WebCore::GraphicsContext3D::GraphicsContext3DState::boundTexture):
+ (WebCore::GraphicsContext3D::GraphicsContext3DState::setBoundTexture):
+ * platform/graphics/cv/VideoTextureCopierCV.cpp:
+ (WebCore::VideoTextureCopierCV::copyImageToPlatformTexture):
+ * platform/graphics/cv/VideoTextureCopierCV.h:
+ (WebCore::VideoTextureCopierCV::lastTextureSeed):
+ * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+ (WebCore::GraphicsContext3D::prepareTexture):
+ (WebCore::GraphicsContext3D::bindTexture):
+ (WebCore::GraphicsContext3D::texStorage2D):
+ (WebCore::GraphicsContext3D::texStorage3D):
+ (WebCore::GraphicsContext3D::framebufferTexture2D):
+ (WebCore::GraphicsContext3D::texSubImage2D):
+ (WebCore::GraphicsContext3D::compressedTexImage2D):
+ (WebCore::GraphicsContext3D::compressedTexSubImage2D):
+ (WebCore::GraphicsContext3D::createTexture):
+ (WebCore::GraphicsContext3D::deleteTexture):
+ (WebCore::GraphicsContext3D::texImage2DDirect):
+
2017-10-13 Per Arne Vollan <pvol...@apple.com>
[Win] When built with VS2017, MiniBrowser crashes on startup.
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (223314 => 223315)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-10-14 02:38:09 UTC (rev 223315)
@@ -32,6 +32,7 @@
#include "IntRect.h"
#include "PlatformLayer.h"
#include <memory>
+#include <wtf/HashCountedSet.h>
#include <wtf/HashMap.h>
#include <wtf/ListHashSet.h>
#include <wtf/RefCounted.h>
@@ -1281,6 +1282,8 @@
void setFailNextGPUStatusCheck() { m_failNextStatusCheck = true; }
+ unsigned textureSeed(GC3Duint texture) { return m_state.textureSeedCount.count(texture); }
+
private:
GraphicsContext3D(GraphicsContext3DAttributes, HostWindow*, RenderStyle = RenderOffscreen);
@@ -1426,7 +1429,38 @@
struct GraphicsContext3DState {
GC3Duint boundFBO { 0 };
GC3Denum activeTexture { GraphicsContext3D::TEXTURE0 };
- GC3Duint boundTexture0 { 0 };
+
+ using BoundTextureMap = HashMap<GC3Denum,
+ std::pair<GC3Duint, GC3Denum>,
+ WTF::IntHash<GC3Denum>,
+ WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>,
+ WTF::PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>, WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>>
+ >;
+ BoundTextureMap boundTextureMap;
+ GC3Duint currentBoundTexture() { return boundTexture(activeTexture); }
+ GC3Duint boundTexture(GC3Denum textureUnit)
+ {
+ auto iterator = boundTextureMap.find(textureUnit);
+ if (iterator != boundTextureMap.end())
+ return iterator->value.first;
+ return 0;
+ }
+
+ GC3Denum boundTarget(GC3Denum textureUnit)
+ {
+ auto iterator = boundTextureMap.find(textureUnit);
+ if (iterator != boundTextureMap.end())
+ return iterator->value.second;
+ return 0;
+ }
+
+ void setBoundTexture(GC3Denum textureUnit, GC3Duint texture, GC3Denum target)
+ {
+ boundTextureMap.set(textureUnit, std::make_pair(texture, target));
+ }
+
+ using TextureSeedCount = HashCountedSet<GC3Duint, WTF::IntHash<GC3Duint>, WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>>;
+ TextureSeedCount textureSeedCount;
};
GraphicsContext3DState m_state;
Modified: trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp (223314 => 223315)
--- trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp 2017-10-14 02:38:09 UTC (rev 223315)
@@ -516,6 +516,17 @@
if (!surface)
return false;
+ auto newSurfaceSeed = IOSurfaceGetSeed(surface);
+ auto newTextureSeed = m_context->textureSeed(outputTexture);
+ if (flipY == m_lastFlipY
+ && surface == m_lastSurface
+ && newSurfaceSeed == m_lastSurfaceSeed
+ && lastTextureSeed(outputTexture) == newTextureSeed) {
+ // If the texture hasn't been modified since the last time we copied to it, and the
+ // image hasn't been modified since the last time it was copied, this is a no-op.
+ return true;
+ }
+
GC3DStateSaver stateSaver(m_context.get());
if (!m_yuvProgram) {
@@ -606,6 +617,11 @@
m_context->deleteTexture(uvTexture);
m_context->bindTexture(videoTextureTarget, 0);
+ m_lastSurface = surface;
+ m_lastSurfaceSeed = newSurfaceSeed;
+ m_lastTextureSeed.set(outputTexture, newTextureSeed);
+ m_lastFlipY = flipY;
+
return true;
#else
return false;
Modified: trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h (223314 => 223315)
--- trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h 2017-10-14 02:38:09 UTC (rev 223315)
@@ -27,6 +27,7 @@
#define VideoTextureCopierCV_h
#import "GraphicsContext3D.h"
+#import <wtf/UnsafePointer.h>
typedef struct __CVBuffer* CVImageBufferRef;
typedef struct __CVBuffer* CVPixelBufferRef;
@@ -83,6 +84,14 @@
bool initializeContextObjects();
bool initializeUVContextObjects();
+#if USE(IOSURFACE)
+ unsigned lastTextureSeed(GC3Duint texture)
+ {
+ auto iterator = m_lastTextureSeed.find(texture);
+ return iterator == m_lastTextureSeed.end() ? 0 : iterator->value;
+ }
+#endif
+
Ref<GraphicsContext3D> m_context;
std::unique_ptr<TextureCacheCV> m_textureCache;
Platform3DObject m_framebuffer { 0 };
@@ -102,6 +111,15 @@
GC3Dint m_yuvPositionAttributeLocation { -1 };
GC3Dint m_yTextureSizeUniformLocation { -1 };
GC3Dint m_uvTextureSizeUniformLocation { -1 };
+
+#if USE(IOSURFACE)
+ bool m_lastFlipY { false };
+ UnsafePointer<IOSurfaceRef> m_lastSurface;
+ uint32_t m_lastSurfaceSeed { 0 };
+
+ using TextureSeedMap = HashMap<GC3Duint, unsigned, WTF::IntHash<GC3Duint>, WTF::UnsignedWithZeroKeyHashTraits<GC3Duint>>;
+ TextureSeedMap m_lastTextureSeed;
+#endif
};
}
Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (223314 => 223315)
--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2017-10-14 00:50:39 UTC (rev 223314)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2017-10-14 02:38:09 UTC (rev 223315)
@@ -261,7 +261,7 @@
#endif
::glActiveTexture(GL_TEXTURE0);
- ::glBindTexture(GL_TEXTURE_2D, m_state.boundTexture0);
+ ::glBindTexture(GL_TEXTURE_2D, m_state.boundTarget(GL_TEXTURE0) == GL_TEXTURE_2D ? m_state.boundTexture(GL_TEXTURE0) : 0);
::glActiveTexture(m_state.activeTexture);
if (m_state.boundFBO != m_fbo)
::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_state.boundFBO);
@@ -505,8 +505,7 @@
void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
{
makeContextCurrent();
- if (m_state.activeTexture == GL_TEXTURE0 && target == GL_TEXTURE_2D)
- m_state.boundTexture0 = texture;
+ m_state.setBoundTexture(m_state.activeTexture, texture, target);
::glBindTexture(target, texture);
}
@@ -582,6 +581,7 @@
{
makeContextCurrent();
::glTexStorage2D(target, levels, internalformat, width, height);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
void GraphicsContext3D::texStorage3D(GC3Denum target, GC3Dsizei levels, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dsizei depth)
@@ -588,6 +588,7 @@
{
makeContextCurrent();
::glTexStorage3D(target, levels, internalformat, width, height, depth);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
void GraphicsContext3D::getActiveUniforms(Platform3DObject program, const Vector<GC3Duint>& uniformIndices, GC3Denum pname, Vector<GC3Dint>& params)
@@ -838,6 +839,7 @@
{
makeContextCurrent();
::glFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
void GraphicsContext3D::frontFace(GC3Denum mode)
@@ -1874,6 +1876,7 @@
// FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size.
::glTexSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
void GraphicsContext3D::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data)
@@ -1880,6 +1883,7 @@
{
makeContextCurrent();
::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
void GraphicsContext3D::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data)
@@ -1886,6 +1890,7 @@
{
makeContextCurrent();
::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
Platform3DObject GraphicsContext3D::createBuffer()
@@ -1929,6 +1934,7 @@
makeContextCurrent();
GLuint o = 0;
glGenTextures(1, &o);
+ m_state.textureSeedCount.add(o);
return o;
}
@@ -1971,9 +1977,11 @@
void GraphicsContext3D::deleteTexture(Platform3DObject texture)
{
makeContextCurrent();
- if (m_state.boundTexture0 == texture)
- m_state.boundTexture0 = 0;
+ m_state.boundTextureMap.removeIf([texture] (auto& keyValue) {
+ return keyValue.value.first == texture;
+ });
glDeleteTextures(1, &texture);
+ m_state.textureSeedCount.removeAll(texture);
}
void GraphicsContext3D::synthesizeGLError(GC3Denum error)
@@ -2028,6 +2036,7 @@
{
makeContextCurrent();
::glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+ m_state.textureSeedCount.add(m_state.currentBoundTexture());
}
void GraphicsContext3D::drawArraysInstanced(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)