summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure8
-rw-r--r--dist/changes-5.4.047
-rw-r--r--doc/global/externalsites/qtcreator.qdoc12
-rw-r--r--doc/global/template/images/Qt-logo.pngbin4344 -> 2425 bytes
-rw-r--r--doc/global/template/images/logo.pngbin2205 -> 2370 bytes
-rw-r--r--doc/global/template/images/sprites-combined.pngbin62534 -> 53964 bytes
-rw-r--r--doc/global/template/style/offline.css20
-rw-r--r--doc/src/images/analogclock-example.pngbin2383 -> 14556 bytes
-rw-r--r--doc/src/images/application.pngbin26272 -> 19503 bytes
-rw-r--r--doc/src/images/digitalclock-example.pngbin6142 -> 6603 bytes
-rw-r--r--doc/src/images/scribble-example.pngbin9053 -> 19910 bytes
-rw-r--r--examples/gui/doc/images/analogclock-window-example.pngbin2383 -> 14556 bytes
-rw-r--r--examples/network/bearermonitor/bearermonitor.cpp3
-rw-r--r--examples/network/securesocketclient/sslclient.cpp2
-rw-r--r--examples/network/securesocketclient/sslclient.ui4
-rw-r--r--examples/opengl/legacy/framebufferobject2/cubelogo.pngbin5920 -> 2884 bytes
-rw-r--r--examples/opengl/legacy/pbuffers/cubelogo.pngbin5920 -> 2884 bytes
-rw-r--r--examples/sql/doc/images/drilldown-example.pngbin52950 -> 9092 bytes
-rw-r--r--examples/sql/drilldown/images/qt-creator.pngbin46906 -> 6655 bytes
-rw-r--r--examples/sql/drilldown/images/qt-logo.pngbin45652 -> 5527 bytes
-rw-r--r--examples/sql/drilldown/images/qt-project.pngbin37795 -> 16832 bytes
-rw-r--r--examples/sql/drilldown/images/qt-quick.pngbin43238 -> 26635 bytes
-rw-r--r--examples/widgets/animation/animatedtiles/images/kinetic.pngbin6776 -> 5055 bytes
-rw-r--r--examples/widgets/animation/easing/images/qt-logo.pngbin5149 -> 1495 bytes
-rw-r--r--examples/widgets/doc/images/dropsite-example.pngbin36033 -> 29056 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_16x16.pngbin1184 -> 563 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_17x17.pngbin1219 -> 605 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_32x32.pngbin2185 -> 916 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_33x33.pngbin2435 -> 975 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_48x48.pngbin3805 -> 1270 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_64x64.pngbin3805 -> 1614 bytes
-rw-r--r--examples/widgets/doc/images/icons_qt_extended_8x8.pngbin685 -> 340 bytes
-rw-r--r--examples/widgets/doc/src/application.qdoc6
-rw-r--r--examples/widgets/doc/src/dockwidgets.qdoc4
-rw-r--r--examples/widgets/draganddrop/puzzle/example.jpgbin42654 -> 42654 bytes
-rw-r--r--examples/widgets/graphicsview/boxes/qt-logo.jpgbin40886 -> 20316 bytes
-rw-r--r--examples/widgets/graphicsview/boxes/qt-logo.pngbin13923 -> 12167 bytes
-rw-r--r--examples/widgets/itemviews/puzzle/example.jpgbin42654 -> 42654 bytes
-rw-r--r--examples/widgets/painting/basicdrawing/images/qt-logo.pngbin3696 -> 1831 bytes
-rw-r--r--examples/widgets/widgets/icons/images/qt_extended_16x16.pngbin834 -> 524 bytes
-rw-r--r--examples/widgets/widgets/icons/images/qt_extended_32x32.pngbin1892 -> 892 bytes
-rw-r--r--examples/widgets/widgets/icons/images/qt_extended_48x48.pngbin3672 -> 1294 bytes
-rw-r--r--examples/widgets/widgets/mousebuttons/buttontester.cpp2
-rw-r--r--examples/widgets/widgets/mousebuttons/buttontester.h2
-rw-r--r--examples/widgets/widgets/mousebuttons/main.cpp5
-rw-r--r--mkspecs/common/clang.conf3
-rw-r--r--mkspecs/common/qcc-base.conf7
-rw-r--r--mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in2
-rw-r--r--mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in2
-rw-r--r--mkspecs/devices/linux-rasp-pi-g++/qmake.conf3
-rw-r--r--mkspecs/features/configure.prf5
-rw-r--r--mkspecs/features/mac/default_post.prf24
-rw-r--r--mkspecs/features/mac/sdk.prf4
-rw-r--r--mkspecs/features/qt_common.prf12
-rw-r--r--mkspecs/features/qt_module.prf2
-rw-r--r--mkspecs/features/qt_module_headers.prf4
-rw-r--r--mkspecs/features/qt_module_pris.prf5
-rw-r--r--mkspecs/features/resources.prf2
-rw-r--r--mkspecs/features/winrt/package_manifest.prf15
-rw-r--r--mkspecs/macx-clang-32/Info.plist.lib2
-rw-r--r--mkspecs/macx-clang/Info.plist.lib2
-rw-r--r--mkspecs/macx-g++-32/Info.plist.lib2
-rw-r--r--mkspecs/macx-g++/Info.plist.lib2
-rw-r--r--mkspecs/macx-g++40/Info.plist.lib2
-rw-r--r--mkspecs/macx-g++42/Info.plist.lib2
-rw-r--r--mkspecs/macx-icc/Info.plist.lib2
-rw-r--r--mkspecs/macx-icc/qmake.conf5
-rwxr-xr-xmkspecs/macx-ios-clang/Info.plist.app2
-rw-r--r--mkspecs/macx-ios-clang/LaunchScreen.xib45
-rw-r--r--mkspecs/macx-ios-clang/features/default_post.prf34
-rw-r--r--mkspecs/macx-ios-clang/features/qt.prf6
-rw-r--r--mkspecs/macx-ios-clang/features/qt_config.prf4
-rw-r--r--mkspecs/macx-ios-clang/features/sdk.prf4
-rw-r--r--mkspecs/macx-ios-clang/qmake.conf4
-rwxr-xr-xmkspecs/macx-ios-clang/rename_main.sh10
-rw-r--r--mkspecs/macx-llvm/Info.plist.lib2
-rw-r--r--mkspecs/unsupported/freebsd-clang/qmake.conf2
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp59
-rw-r--r--qmake/generators/unix/unixmake2.cpp22
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp16
-rw-r--r--qmake/library/proitems.cpp4
-rw-r--r--qtbase.pro5
-rw-r--r--src/3rdparty/angle/AUTHORS2
-rw-r--r--src/3rdparty/angle/CONTRIBUTORS5
-rw-r--r--src/3rdparty/angle/include/EGL/egl.h2
-rw-r--r--src/3rdparty/angle/include/EGL/eglext.h16
-rw-r--r--src/3rdparty/angle/include/EGL/eglplatform.h19
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderLang.h210
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderVars.h64
-rw-r--r--src/3rdparty/angle/include/angle_windowsstore.h37
-rw-r--r--src/3rdparty/angle/src/commit.h4
-rw-r--r--src/3rdparty/angle/src/common/NativeWindow.h82
-rw-r--r--src/3rdparty/angle/src/common/angleutils.cpp25
-rw-r--r--src/3rdparty/angle/src/common/angleutils.h11
-rw-r--r--src/3rdparty/angle/src/common/debug.cpp242
-rw-r--r--src/3rdparty/angle/src/common/debug.h19
-rw-r--r--src/3rdparty/angle/src/common/features.h35
-rw-r--r--src/3rdparty/angle/src/common/mathutil.h4
-rw-r--r--src/3rdparty/angle/src/common/platform.h90
-rw-r--r--src/3rdparty/angle/src/common/tls.cpp107
-rw-r--r--src/3rdparty/angle/src/common/tls.h17
-rw-r--r--src/3rdparty/angle/src/common/utilities.cpp89
-rw-r--r--src/3rdparty/angle/src/common/utilities.h6
-rw-r--r--src/3rdparty/angle/src/common/win32/NativeWindow.cpp66
-rw-r--r--src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp200
-rw-r--r--src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h39
-rw-r--r--src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp274
-rw-r--r--src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h91
-rw-r--r--src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp226
-rw-r--r--src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h79
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h3
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp35
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp4
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Compiler.cpp63
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Compiler.h10
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp52
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h19
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp79
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h3
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermNode.cpp76
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermNode.h5
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Intermediate.cpp1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp18
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp57
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputHLSL.h1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ParseContext.cpp13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ParseContext.h2
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Pragma.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp371
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp165
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SymbolTable.h41
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp11
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp30
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp81
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariableInfo.h17
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp16
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VersionGLSL.h4
-rw-r--r--src/3rdparty/angle/src/compiler/translator/glslang.y34
-rw-r--r--src/3rdparty/angle/src/compiler/translator/intermOut.cpp6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.cpp47
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.h12
-rw-r--r--src/3rdparty/angle/src/libEGL/AttributeMap.cpp40
-rw-r--r--src/3rdparty/angle/src/libEGL/AttributeMap.h33
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.cpp169
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.h22
-rw-r--r--src/3rdparty/angle/src/libEGL/Error.cpp48
-rw-r--r--src/3rdparty/angle/src/libEGL/Error.h39
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.cpp339
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.h60
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.cpp465
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp40
-rw-r--r--src/3rdparty/angle/src/libEGL/main.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/BinaryStream.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.h1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.cpp865
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.h62
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Data.cpp51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Data.h38
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.cpp176
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.h35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp277
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.h50
-rw-r--r--src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp91
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ImageIndex.h29
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.cpp24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp2080
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.h133
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp235
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.h113
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.cpp11
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/State.cpp125
-rw-r--r--src/3rdparty/angle/src/libGLESv2/State.h26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.cpp199
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.h74
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexArray.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.cpp21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.h16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp1045
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp99
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.h25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp146
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h127
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp45
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h237
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp68
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp245
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp1814
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h184
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp108
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp796
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h195
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp118
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp1711
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h227
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp108
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h38
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp88
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp214
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp549
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp116
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp327
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h84
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp1298
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h152
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp169
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp1817
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h177
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp94
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp227
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp63
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp654
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h43
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp165
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h60
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp756
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h134
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp377
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h46
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES.cpp66
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES3.cpp23
-rw-r--r--src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp5
-rw-r--r--src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch149
-rw-r--r--src/3rdparty/freebsd/strtoll.c134
-rw-r--r--src/3rdparty/freebsd/strtoull.c112
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeX86_common.c4
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java389
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java435
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java12
-rw-r--r--src/android/templates/templates.pro2
-rw-r--r--src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch1194
-rw-r--r--src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch31
-rw-r--r--src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch33
-rw-r--r--src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch31
-rw-r--r--src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch84
-rw-r--r--src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch49
-rw-r--r--src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch28
-rw-r--r--src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch37
-rw-r--r--src/angle/patches/0009-ANGLE-Support-WinRT.patch1769
-rw-r--r--src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch266
-rw-r--r--src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch16
-rw-r--r--src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch31
-rw-r--r--src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch37
-rw-r--r--src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch309
-rw-r--r--src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch322
-rw-r--r--src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch62
-rw-r--r--src/angle/src/libEGL/libEGL.pro20
-rw-r--r--src/angle/src/libGLESv2/libGLESv2.pro26
-rw-r--r--src/corelib/animation/qanimationgroup.cpp2
-rw-r--r--src/corelib/animation/qvariantanimation.cpp8
-rw-r--r--src/corelib/codecs/qtextcodec.cpp26
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp8
-rw-r--r--src/corelib/doc/snippets/qstring/main.cpp8
-rw-r--r--src/corelib/doc/src/animation.qdoc9
-rw-r--r--src/corelib/doc/src/containers.qdoc22
-rw-r--r--src/corelib/doc/src/datastreamformat.qdoc2
-rw-r--r--src/corelib/doc/src/filestorage.qdoc4
-rw-r--r--src/corelib/doc/src/implicit-sharing.qdoc1
-rw-r--r--src/corelib/doc/src/objectmodel/signalsandslots.qdoc10
-rw-r--r--src/corelib/doc/src/statemachine.qdoc1
-rw-r--r--src/corelib/global/qcompilerdetection.h66
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp10
-rw-r--r--src/corelib/global/qlogging.cpp23
-rw-r--r--src/corelib/global/qnamespace.qdoc25
-rw-r--r--src/corelib/global/qprocessordetection.h4
-rw-r--r--src/corelib/io/io.pri5
-rw-r--r--src/corelib/io/qdatastream.cpp6
-rw-r--r--src/corelib/io/qfsfileengine.cpp41
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qiodevice_p.h18
-rw-r--r--src/corelib/io/qlockfile.cpp2
-rw-r--r--src/corelib/io/qlockfile_unix.cpp2
-rw-r--r--src/corelib/io/qsettings.cpp9
-rw-r--r--src/corelib/io/qsettings_mac.cpp4
-rw-r--r--src/corelib/io/qsettings_p.h2
-rw-r--r--src/corelib/io/qstandardpaths.cpp4
-rw-r--r--src/corelib/io/qstandardpaths_ios.mm2
-rw-r--r--src/corelib/io/qstandardpaths_mac.mm (renamed from src/corelib/io/qstandardpaths_mac.cpp)12
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp7
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp7
-rw-r--r--src/corelib/io/qstorageinfo_win.cpp2
-rw-r--r--src/corelib/io/qurl.cpp42
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp41
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp34
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel_p.h2
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp2
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp26
-rw-r--r--src/corelib/json/qjsonarray.cpp2
-rw-r--r--src/corelib/json/qjsonarray.h2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp69
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h3
-rw-r--r--src/corelib/kernel/qjni.cpp248
-rw-r--r--src/corelib/kernel/qjni_p.h48
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp38
-rw-r--r--src/corelib/kernel/qjnihelpers_p.h3
-rw-r--r--src/corelib/kernel/qmetaobject.h6
-rw-r--r--src/corelib/kernel/qsystemerror.cpp4
-rw-r--r--src/corelib/kernel/qtranslator.cpp5
-rw-r--r--src/corelib/kernel/qvariant.h26
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp4
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp4
-rw-r--r--src/corelib/plugin/qplugin.h2
-rw-r--r--src/corelib/thread/qbasicatomic.h10
-rw-r--r--src/corelib/tools/qbytearray.cpp9
-rw-r--r--src/corelib/tools/qbytearraylist.h1
-rw-r--r--src/corelib/tools/qdatetime.h3
-rw-r--r--src/corelib/tools/qelapsedtimer.h4
-rw-r--r--src/corelib/tools/qelapsedtimer_unix.cpp19
-rw-r--r--src/corelib/tools/qlist.cpp20
-rw-r--r--src/corelib/tools/qlist.h23
-rw-r--r--src/corelib/tools/qlocale.cpp4
-rw-r--r--src/corelib/tools/qlocale_p.h4
-rw-r--r--src/corelib/tools/qsimd.cpp2
-rw-r--r--src/corelib/tools/qsimd_p.h8
-rw-r--r--src/corelib/tools/qstring.cpp87
-rw-r--r--src/corelib/tools/qversionnumber.cpp3
-rw-r--r--src/corelib/tools/qversionnumber_p.h (renamed from src/corelib/tools/qversionnumber.h)0
-rw-r--r--src/corelib/tools/tools.pri2
-rw-r--r--src/dbus/qdbusconnection_p.h16
-rw-r--r--src/dbus/qdbusintegrator.cpp75
-rw-r--r--src/dbus/qdbusmessage.cpp4
-rw-r--r--src/dbus/qdbusthreaddebug_p.h10
-rw-r--r--src/gui/doc/src/richtext.qdoc1
-rw-r--r--src/gui/image/qicon.cpp2
-rw-r--r--src/gui/image/qimage_conversions.cpp2
-rw-r--r--src/gui/image/qimage_neon.cpp4
-rw-r--r--src/gui/image/qjpeghandler.cpp155
-rw-r--r--src/gui/kernel/qguiapplication.cpp25
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qopenglcontext_p.h3
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp6
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h1
-rw-r--r--src/gui/kernel/qwindow.cpp12
-rw-r--r--src/gui/kernel/qwindow.h13
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp36
-rw-r--r--src/gui/opengl/qopenglpaintdevice.cpp4
-rw-r--r--src/gui/opengl/qopenglpaintdevice.h2
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp2
-rw-r--r--src/gui/painting/qbrush.cpp3
-rw-r--r--src/gui/painting/qdrawhelper.cpp2
-rw-r--r--src/gui/painting/qpdf.cpp7
-rw-r--r--src/gui/text/qfontdatabase.cpp10
-rw-r--r--src/gui/text/qfontdatabase.h2
-rw-r--r--src/gui/text/qfontengine.cpp8
-rw-r--r--src/gui/text/qfontengine_ft.cpp75
-rw-r--r--src/gui/text/qfontengine_ft_p.h3
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qharfbuzzng.cpp6
-rw-r--r--src/gui/text/qtextengine.cpp2
-rw-r--r--src/gui/text/qtextimagehandler.cpp67
-rw-r--r--src/gui/text/qtextlayout.cpp10
-rw-r--r--src/gui/util/qvalidator.cpp26
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp2
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp1
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp12
-rw-r--r--src/network/socket/qlocalserver_unix.cpp54
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp92
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h9
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp23
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp21
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h1
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp2
-rw-r--r--src/opengl/qgl.cpp29
-rw-r--r--src/opengl/qgl_p.h2
-rw-r--r--src/opengl/qglframebufferobject.cpp31
-rw-r--r--src/opengl/qglpaintdevice.cpp13
-rw-r--r--src/opengl/qglpixelbuffer.cpp2
-rw-r--r--src/platformsupport/clipboard/qmacmime.mm9
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp31
-rw-r--r--src/platformsupport/fontdatabases/basic/basic.pri1
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp2
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm5
-rw-r--r--src/plugins/bearer/connman/connman.pro4
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.h2
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm23
-rw-r--r--src/plugins/bearer/linux_common/qofonoservice_linux.cpp (renamed from src/plugins/bearer/connman/qofonoservice_linux.cpp)107
-rw-r--r--src/plugins/bearer/linux_common/qofonoservice_linux_p.h (renamed from src/plugins/bearer/connman/qofonoservice_linux_p.h)28
-rw-r--r--src/plugins/bearer/networkmanager/main.cpp5
-rw-r--r--src/plugins/bearer/networkmanager/networkmanager.pro6
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp659
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.h37
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp740
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.h112
-rw-r--r--src/plugins/bearer/networkmanager/qnmdbushelper.cpp140
-rw-r--r--src/plugins/bearer/qnetworksession_impl.cpp3
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.cpp26
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.h3
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp59
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp29
-rw-r--r--src/plugins/platforms/android/androidjnimain.h23
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp27
-rw-r--r--src/plugins/platforms/android/androidjnimenu.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformclipboard.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp22
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h6
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.cpp3
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp297
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.h16
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm13
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm13
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintrospection.mm52
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm19
-rw-r--r--src/plugins/platforms/cocoa/qcocoamimetypes.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm142
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm209
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm280
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm16
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac_p.h3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp16
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h1
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp9
-rw-r--r--src/plugins/platforms/directfb/directfb.pro2
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h1
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp2
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm15
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h22
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm45
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.h10
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm223
-rw-r--r--src/plugins/platforms/ios/qiosmenu.mm23
-rw-r--r--src/plugins/platforms/ios/qiosplatformaccessibility.mm20
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.h6
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm80
-rw-r--r--src/plugins/platforms/ios/quiview.mm66
-rw-r--r--src/plugins/platforms/ios/quiview_accessibility.mm11
-rw-r--r--src/plugins/platforms/kms/kms.pro1
-rw-r--r--src/plugins/platforms/linuxfb/linuxfb.pro1
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h14
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp4
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp87
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h1
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp27
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h1
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp20
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h7
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp49
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp190
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp7
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp15
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.h1
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro2
-rw-r--r--src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp1
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp5
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp18
-rw-r--r--src/printsupport/kernel/qprintengine_win_p.h4
-rw-r--r--src/printsupport/kernel/qprinter.cpp4
-rw-r--r--src/testlib/qtest.h6
-rw-r--r--src/testlib/qtestcase.cpp12
-rw-r--r--src/testlib/qtesteventloop.h7
-rw-r--r--src/testlib/qtestlog.cpp1
-rw-r--r--src/tools/bootstrap/bootstrap.pro5
-rw-r--r--src/tools/moc/generator.cpp20
-rw-r--r--src/tools/moc/preprocessor.cpp6
-rw-r--r--src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp6
-rw-r--r--src/tools/qdoc/cppcodemarker.cpp12
-rw-r--r--src/tools/qdoc/doc/images/qt-logo.pngbin5149 -> 1495 bytes
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp129
-rw-r--r--src/tools/qdoc/htmlgenerator.h3
-rw-r--r--src/tools/qdoc/qdocindexfiles.cpp1
-rw-r--r--src/tools/qdoc/qmlparser/qqmljs.g115
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsgrammar.cpp1668
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsgrammar_p.h12
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsparser.cpp384
-rw-r--r--src/tools/qdoc/qmlparser/qqmljsparser_p.h4
-rw-r--r--src/tools/qlalr/doc/src/images/qt-logo.pngbin1422 -> 892 bytes
-rw-r--r--src/tools/rcc/rcc.cpp52
-rw-r--r--src/widgets/accessible/simplewidgets.cpp2
-rw-r--r--src/widgets/dialogs/images/qtlogo-64.pngbin2991 -> 1676 bytes
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/dialogs/qfiledialog.ui3
-rw-r--r--src/widgets/dialogs/qfiledialog_embedded.ui207
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp2
-rw-r--r--src/widgets/dialogs/qwizard.cpp8
-rw-r--r--src/widgets/doc/snippets/code/doc_src_layout.cpp2
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/main.cpp2
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp2
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/model.cpp21
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/model.h2
-rw-r--r--src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro1
-rw-r--r--src/widgets/doc/src/model-view-programming.qdoc3
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp38
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp6
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h16
-rw-r--r--src/widgets/itemviews/qlistview.cpp6
-rw-r--r--src/widgets/kernel/qapplication.cpp38
-rw-r--r--src/widgets/kernel/qapplication_p.h3
-rw-r--r--src/widgets/kernel/qgesture_p.h13
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp20
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp12
-rw-r--r--src/widgets/kernel/qstandardgestures.cpp76
-rw-r--r--src/widgets/kernel/qstandardgestures_p.h5
-rw-r--r--src/widgets/kernel/qwidget.cpp12
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp74
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h4
-rw-r--r--src/widgets/styles/qandroidstyle.cpp379
-rw-r--r--src/widgets/styles/qandroidstyle_p.h11
-rw-r--r--src/widgets/styles/qcommonstyle.cpp2
-rw-r--r--src/widgets/styles/qfusionstyle.cpp4
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp4
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm265
-rw-r--r--src/widgets/styles/qmacstyle_mac_p_p.h6
-rw-r--r--src/widgets/styles/qstyle.cpp3
-rw-r--r--src/widgets/styles/qstyle.h2
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp14
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp6
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp5
-rw-r--r--src/widgets/widgets/qlineedit.cpp7
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp2
-rw-r--r--src/widgets/widgets/qmainwindow.cpp7
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp22
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h2
-rw-r--r--src/widgets/widgets/qmdiarea.cpp16
-rw-r--r--src/widgets/widgets/qmdiarea_p.h9
-rw-r--r--src/widgets/widgets/qmenu.cpp6
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp14
-rw-r--r--src/widgets/widgets/qtextedit.cpp14
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp24
-rw-r--r--src/widgets/widgets/qtoolbararealayout_p.h2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h2
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp9
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp4
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qlogging.cpp12
-rw-r--r--tests/auto/corelib/io/qsettings/bom.ini4
-rw-r--r--tests/auto/corelib/io/qsettings/qsettings.qrc17
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp10
-rw-r--r--tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp10
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp9
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp130
-rw-r--r--tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp52
-rw-r--r--tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp19
-rw-r--r--tests/auto/corelib/kernel/qvariant/qvariant.pro1
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp12
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp22
-rw-r--r--tests/auto/corelib/tools/qversionnumber/qversionnumber.pro2
-rw-r--r--tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp2
-rw-r--r--tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp11
-rw-r--r--tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp28
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpgbin0 -> 910 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpgbin0 -> 910 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpgbin0 -> 988 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpgbin0 -> 995 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpgbin0 -> 912 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpgbin0 -> 911 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpgbin0 -> 987 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpgbin0 -> 991 bytes
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp18
-rw-r--r--tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp27
-rw-r--r--tests/auto/gui/util/qregularexpressionvalidator/tst_qregularexpressionvalidator.cpp3
-rw-r--r--tests/auto/network/access/qnetworkreply/BLACKLIST3
-rw-r--r--tests/auto/network/socket/qsocks5socketengine/BLACKLIST4
-rw-r--r--tests/auto/network/ssl/ssl.pro8
-rw-r--r--tests/auto/opengl/qgl/tst_qgl.cpp90
-rw-r--r--tests/auto/other/qaccessibility/BLACKLIST2
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp38
-rw-r--r--tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp20
-rw-r--r--tests/auto/tools/moc/parse-defines.h2
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro1
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp2
-rw-r--r--tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp9
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp4
-rw-r--r--tests/auto/widgets/kernel/qaction/tst_qaction.cpp10
-rw-r--r--[-rwxr-xr-x]tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro0
-rw-r--r--[-rwxr-xr-x]tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp101
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp8
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp2
-rw-r--r--tests/manual/diaglib/README.txt34
-rw-r--r--tests/manual/diaglib/diaglib.pri43
-rw-r--r--tests/manual/diaglib/eventfilter.cpp113
-rw-r--r--tests/manual/diaglib/eventfilter.h77
-rw-r--r--tests/manual/diaglib/glinfo.cpp112
-rw-r--r--tests/manual/diaglib/glinfo.h48
-rw-r--r--tests/manual/diaglib/nativewindowdump.cpp46
-rw-r--r--tests/manual/diaglib/nativewindowdump.h46
-rw-r--r--tests/manual/diaglib/nativewindowdump_win.cpp207
-rw-r--r--tests/manual/diaglib/qwidgetdump.cpp94
-rw-r--r--tests/manual/diaglib/qwidgetdump.h45
-rw-r--r--tests/manual/diaglib/qwindowdump.cpp176
-rw-r--r--tests/manual/diaglib/qwindowdump.h (renamed from src/plugins/bearer/networkmanager/qnmdbushelper.h)54
-rw-r--r--tests/manual/manual.pro1
-rw-r--r--tests/manual/touch/main.cpp209
-rw-r--r--tests/manual/touch/touch.pro5
690 files changed, 25838 insertions, 18024 deletions
diff --git a/configure b/configure
index 6edcd38e68..95c8ef64d8 100755
--- a/configure
+++ b/configure
@@ -1434,7 +1434,8 @@ while [ "$#" -gt 0 ]; do
fi
;;
feature-*)
- FEATURE=`echo $VAR | sed 's,^[^-]*-\([^-]*\),\1,' | tr 'abcdefghijklmnopqrstuvwxyz-' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ FEATURE=`echo $VAR | sed 's,^[^-]*-\([^-]*\),\1,' | tr 'abcdefghijklmnopqrstuvwxyz-' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ if grep "^Feature: *${FEATURE} *\$" "$relpath"/src/corelib/global/qfeatures.txt >/dev/null 2>&1; then
if [ "$VAL" = "no" ]; then
QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_$FEATURE"
elif [ "$VAL" = "yes" ] || [ "$VAL" = "unknown" ]; then
@@ -1442,6 +1443,10 @@ while [ "$#" -gt 0 ]; do
else
UNKNOWN_OPT=yes
fi
+ else
+ echo "ERROR: Unknown feature $FEATURE"
+ UNKNOWN_OPT=yes
+ fi
;;
shared)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
@@ -3183,6 +3188,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples"
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples"
+ CFG_PRECOMPILE="no" # Precompiled headers not supported with multiple -arch arguments
# If the user passes -sdk on the command line we build a SDK-specific Qt build.
# Otherwise we build a joined simulator and device build, which is the default.
diff --git a/dist/changes-5.4.0 b/dist/changes-5.4.0
index 927ca0f9f1..c3c7f532a3 100644
--- a/dist/changes-5.4.0
+++ b/dist/changes-5.4.0
@@ -25,6 +25,10 @@ QtCore
- Added QEnableSharedFromThis, a class that allows obtaining a
QSharedPointer for an object already managed by a shared pointer.
+QtGui
+-----
+
+ - QImageReader now automatically rotates JPEG images according to Exif orientation
QtSql
-----
@@ -43,3 +47,46 @@ OS X
- OS X 10.10 is now supported.
- QMacStyle has been updated with better OS 10.10 support.
- The Qt binary packages are now configured with C++11 enabled.
+
+Windows
+-------
+
+ - [QTBUG-38259] Changed configure defaults so that Qt5Core does not
+ link against ICU libraries anymore. Pass '-icu' to enable it.
+
+****************************************************************************
+* Tools *
+****************************************************************************
+
+configure & build system
+------------------------
+
+ - The -process/-fully-process/-dont-process configure options have been
+ removed due to being unnecessary and counterproductive.
+ - [QTBUG-36955] The -vcproj configure option was removed. Use "qmake -r -tp vc"
+ _after_ building Qt in case you want to use Visual Studio to work on Qt.
+ - [QTBUG-37961] Qt plugins contain version info again.
+ - [QTBUG-39216] Fixed more cases where the Qt build would pick up headers
+ from a pre-existing Qt installation.
+ - [QTBUG-41267] Fixed parallelized (jom) -debug-and-release builds.
+
+qmake
+-----
+
+ - [QTBUG-21910][Unix] Added 'make dist' target for SUBDIRS projects.
+ - [QTBUG-32895][iOS] Fixed structure of bundles. They can be signed now.
+ - [QTBUG-26782][VS] Fixed handling of TARGET_EXT.
+ - [QTBUG-30712][VS] Fixed handling of QMAKE_LIBFLAGS.
+ - [QTBUG-30373][VS] Using different RESOURCES in different build variants
+ no longer produces invalid vcxproj files.
+ - [QTBUG-37520][VS] Made it possible to suppress qmake warnings about
+ unknown compiler options. CONFIG+=suppress_vcproj_warnings.
+ - [QTBUG-37363][MSVC2012+] embed_manifest_exe is now properly supported.
+ - [QTBUG-41504][MSVC2012+] Building DLLs targeting Windows XP is now
+ supported. As a side effect, Windows CE makespecs must not add /ENTRY: to
+ QMAKE_LFLAGS_CONSOLE any more. The flag is hard-coded in console.prf now.
+ - [QTBUG-35318][Xcode] Fixed QMAKE_BUNDLE_DATA's path resolution.
+ - [QTBUG-39527] Fixed qtCompile() when used with jom -jN.
+ - QMAKE_EXTRA_COMPILERS' commands and depend_command are no longer mangled.
+ Use $$shell_path() and $$shell_quote() to prepare the commands correctly.
+ - Added link-time optimization support for Clang, GCC and ICC. CONFIG+=ltgc.
diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc
index 46609de160..a98fbd0a56 100644
--- a/doc/global/externalsites/qtcreator.qdoc
+++ b/doc/global/externalsites/qtcreator.qdoc
@@ -483,3 +483,15 @@
\externalpage http://qt-project.org/doc/qtcreator/creator-developing-winrt.html
\title Qt Creator: Connecting Windows Runtime Devices
*/
+/*!
+ \externalpage http://qt-project.org/doc/qtcreator/creator-clang-codemodel.html
+ \title Qt Creator: Parsing C++ Files
+*/
+/*!
+ \externalpage http://qt-project.org/doc/qtcreator/creator-quick-ui-forms.html
+ \title Qt Creator: Qt Quick UI Forms
+*/
+/*!
+ \externalpage http://qt-project.org/doc/qtcreator/creator-clang-static-analyzer.html
+ \title Qt Creator: Using Clang Static Analyzer
+*/
diff --git a/doc/global/template/images/Qt-logo.png b/doc/global/template/images/Qt-logo.png
index 64c1c4aaa3..01256ab08d 100644
--- a/doc/global/template/images/Qt-logo.png
+++ b/doc/global/template/images/Qt-logo.png
Binary files differ
diff --git a/doc/global/template/images/logo.png b/doc/global/template/images/logo.png
index 1e7ed4cf21..698dde9215 100644
--- a/doc/global/template/images/logo.png
+++ b/doc/global/template/images/logo.png
Binary files differ
diff --git a/doc/global/template/images/sprites-combined.png b/doc/global/template/images/sprites-combined.png
index 3a48b21f6b..c4f01c4bb9 100644
--- a/doc/global/template/images/sprites-combined.png
+++ b/doc/global/template/images/sprites-combined.png
Binary files differ
diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css
index 5adb699972..16f26f43bb 100644
--- a/doc/global/template/style/offline.css
+++ b/doc/global/template/style/offline.css
@@ -2,7 +2,6 @@ body {
font: normal 400 14px/1.2 Arial;
margin-top: 85px;
font-family: Arial, Helvetica;
- color: #313131;
text-align: left;
margin-left: 5px;
margin-right: 5px;
@@ -365,7 +364,9 @@ h3.fn, span.fn {
margin: 0px;
margin-top: 45px;
}
-
+h3.fn code {
+ float: right;
+}
h3.fn:target {
background-color: #F6F6D6;
}
@@ -711,8 +712,21 @@ Landing page
float: left;
}
-.icons1of3 h2 {
+.icons1of3 h2, .doc-column h2 {
font-size: 15px;
margin: 0px;
padding: 0px;
}
+
+div.multi-column {
+ position: relative;
+}
+
+div.multi-column div {
+ display: -moz-inline-box;
+ display: inline-block;
+ vertical-align: top;
+ margin-top: 1em;
+ margin-right: 4em;
+ width: 24em;
+}
diff --git a/doc/src/images/analogclock-example.png b/doc/src/images/analogclock-example.png
index ffd7baa716..b195f8bf24 100644
--- a/doc/src/images/analogclock-example.png
+++ b/doc/src/images/analogclock-example.png
Binary files differ
diff --git a/doc/src/images/application.png b/doc/src/images/application.png
index 2fb7f2f18e..bff37369a4 100644
--- a/doc/src/images/application.png
+++ b/doc/src/images/application.png
Binary files differ
diff --git a/doc/src/images/digitalclock-example.png b/doc/src/images/digitalclock-example.png
index 473986608c..917035a0f0 100644
--- a/doc/src/images/digitalclock-example.png
+++ b/doc/src/images/digitalclock-example.png
Binary files differ
diff --git a/doc/src/images/scribble-example.png b/doc/src/images/scribble-example.png
index a2cb1de3e8..54091baa6b 100644
--- a/doc/src/images/scribble-example.png
+++ b/doc/src/images/scribble-example.png
Binary files differ
diff --git a/examples/gui/doc/images/analogclock-window-example.png b/examples/gui/doc/images/analogclock-window-example.png
index ffd7baa716..f5e92e400a 100644
--- a/examples/gui/doc/images/analogclock-window-example.png
+++ b/examples/gui/doc/images/analogclock-window-example.png
Binary files differ
diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp
index 4590a91f4f..2f5d6cda1c 100644
--- a/examples/network/bearermonitor/bearermonitor.cpp
+++ b/examples/network/bearermonitor/bearermonitor.cpp
@@ -127,6 +127,9 @@ static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &confi
void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent)
{
+ if (!config.isValid())
+ return;
+
QTreeWidgetItem *item = new QTreeWidgetItem;
updateItem(item, config);
diff --git a/examples/network/securesocketclient/sslclient.cpp b/examples/network/securesocketclient/sslclient.cpp
index 23ca7e41e7..0cec70c742 100644
--- a/examples/network/securesocketclient/sslclient.cpp
+++ b/examples/network/securesocketclient/sslclient.cpp
@@ -181,7 +181,7 @@ void SslClient::sendData()
form->sessionInput->clear();
}
-void SslClient::socketError(QAbstractSocket::SocketError error)
+void SslClient::socketError(QAbstractSocket::SocketError)
{
QMessageBox::critical(this, tr("Connection error"), socket->errorString());
}
diff --git a/examples/network/securesocketclient/sslclient.ui b/examples/network/securesocketclient/sslclient.ui
index 4b81fe46eb..19bae83a09 100644
--- a/examples/network/securesocketclient/sslclient.ui
+++ b/examples/network/securesocketclient/sslclient.ui
@@ -26,7 +26,7 @@
<item row="0" column="1">
<widget class="QLineEdit" name="hostNameEdit">
<property name="text">
- <string>imap.example.com</string>
+ <string>www.qt.io</string>
</property>
</widget>
</item>
@@ -46,7 +46,7 @@
<number>65535</number>
</property>
<property name="value">
- <number>993</number>
+ <number>443</number>
</property>
</widget>
</item>
diff --git a/examples/opengl/legacy/framebufferobject2/cubelogo.png b/examples/opengl/legacy/framebufferobject2/cubelogo.png
index 3ae0f9ba3f..2ccbede774 100644
--- a/examples/opengl/legacy/framebufferobject2/cubelogo.png
+++ b/examples/opengl/legacy/framebufferobject2/cubelogo.png
Binary files differ
diff --git a/examples/opengl/legacy/pbuffers/cubelogo.png b/examples/opengl/legacy/pbuffers/cubelogo.png
index 3ae0f9ba3f..2ccbede774 100644
--- a/examples/opengl/legacy/pbuffers/cubelogo.png
+++ b/examples/opengl/legacy/pbuffers/cubelogo.png
Binary files differ
diff --git a/examples/sql/doc/images/drilldown-example.png b/examples/sql/doc/images/drilldown-example.png
index fd315a437e..fed51d3629 100644
--- a/examples/sql/doc/images/drilldown-example.png
+++ b/examples/sql/doc/images/drilldown-example.png
Binary files differ
diff --git a/examples/sql/drilldown/images/qt-creator.png b/examples/sql/drilldown/images/qt-creator.png
index fa0f6ed7ce..0602bdcad1 100644
--- a/examples/sql/drilldown/images/qt-creator.png
+++ b/examples/sql/drilldown/images/qt-creator.png
Binary files differ
diff --git a/examples/sql/drilldown/images/qt-logo.png b/examples/sql/drilldown/images/qt-logo.png
index 53bc39c38c..7603fa0c90 100644
--- a/examples/sql/drilldown/images/qt-logo.png
+++ b/examples/sql/drilldown/images/qt-logo.png
Binary files differ
diff --git a/examples/sql/drilldown/images/qt-project.png b/examples/sql/drilldown/images/qt-project.png
index c34d3f099d..e066fbe3f9 100644
--- a/examples/sql/drilldown/images/qt-project.png
+++ b/examples/sql/drilldown/images/qt-project.png
Binary files differ
diff --git a/examples/sql/drilldown/images/qt-quick.png b/examples/sql/drilldown/images/qt-quick.png
index f66127e8e7..90d9fd075d 100644
--- a/examples/sql/drilldown/images/qt-quick.png
+++ b/examples/sql/drilldown/images/qt-quick.png
Binary files differ
diff --git a/examples/widgets/animation/animatedtiles/images/kinetic.png b/examples/widgets/animation/animatedtiles/images/kinetic.png
index 55cfa5515f..d5fc0af0f2 100644
--- a/examples/widgets/animation/animatedtiles/images/kinetic.png
+++ b/examples/widgets/animation/animatedtiles/images/kinetic.png
Binary files differ
diff --git a/examples/widgets/animation/easing/images/qt-logo.png b/examples/widgets/animation/easing/images/qt-logo.png
index 14ddf2a028..6b72d5fb72 100644
--- a/examples/widgets/animation/easing/images/qt-logo.png
+++ b/examples/widgets/animation/easing/images/qt-logo.png
Binary files differ
diff --git a/examples/widgets/doc/images/dropsite-example.png b/examples/widgets/doc/images/dropsite-example.png
index 2c42c7be69..c555dd3609 100644
--- a/examples/widgets/doc/images/dropsite-example.png
+++ b/examples/widgets/doc/images/dropsite-example.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_16x16.png b/examples/widgets/doc/images/icons_qt_extended_16x16.png
index 92743690e3..8bae9499e4 100644
--- a/examples/widgets/doc/images/icons_qt_extended_16x16.png
+++ b/examples/widgets/doc/images/icons_qt_extended_16x16.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_17x17.png b/examples/widgets/doc/images/icons_qt_extended_17x17.png
index e9bb24a282..7ef4222f93 100644
--- a/examples/widgets/doc/images/icons_qt_extended_17x17.png
+++ b/examples/widgets/doc/images/icons_qt_extended_17x17.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_32x32.png b/examples/widgets/doc/images/icons_qt_extended_32x32.png
index cd3d0f3255..7b0c54bac3 100644
--- a/examples/widgets/doc/images/icons_qt_extended_32x32.png
+++ b/examples/widgets/doc/images/icons_qt_extended_32x32.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_33x33.png b/examples/widgets/doc/images/icons_qt_extended_33x33.png
index a67565cc2b..1a38f6e44b 100644
--- a/examples/widgets/doc/images/icons_qt_extended_33x33.png
+++ b/examples/widgets/doc/images/icons_qt_extended_33x33.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_48x48.png b/examples/widgets/doc/images/icons_qt_extended_48x48.png
index 5aa2d73f71..85dcb5f26c 100644
--- a/examples/widgets/doc/images/icons_qt_extended_48x48.png
+++ b/examples/widgets/doc/images/icons_qt_extended_48x48.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_64x64.png b/examples/widgets/doc/images/icons_qt_extended_64x64.png
index 5aa2d73f71..d0bfd97f10 100644
--- a/examples/widgets/doc/images/icons_qt_extended_64x64.png
+++ b/examples/widgets/doc/images/icons_qt_extended_64x64.png
Binary files differ
diff --git a/examples/widgets/doc/images/icons_qt_extended_8x8.png b/examples/widgets/doc/images/icons_qt_extended_8x8.png
index 8de7fce038..dcbb5811c6 100644
--- a/examples/widgets/doc/images/icons_qt_extended_8x8.png
+++ b/examples/widgets/doc/images/icons_qt_extended_8x8.png
Binary files differ
diff --git a/examples/widgets/doc/src/application.qdoc b/examples/widgets/doc/src/application.qdoc
index 0d244bce00..e0379e9d75 100644
--- a/examples/widgets/doc/src/application.qdoc
+++ b/examples/widgets/doc/src/application.qdoc
@@ -75,12 +75,12 @@
\snippet mainwindows/application/mainwindow.cpp 0
- We start by including \c <QtGui>, a header file that contains the
- definition of all classes in the Qt Core and Qt GUI
+ We start by including \c <QtWidgets>, a header file that contains the
+ definition of all classes in the Qt Core, Qt GUI and Qt Widgets
modules. This saves us from the trouble of having to include
every class individually. We also include \c mainwindow.h.
- You might wonder why we don't include \c <QtGui> in \c
+ You might wonder why we don't include \c <QtWidgets> in \c
mainwindow.h and be done with it. The reason is that including
such a large header from another header file can rapidly degrade
performances. Here, it wouldn't do any harm, but it's still
diff --git a/examples/widgets/doc/src/dockwidgets.qdoc b/examples/widgets/doc/src/dockwidgets.qdoc
index 2987ec1211..a11524f4f4 100644
--- a/examples/widgets/doc/src/dockwidgets.qdoc
+++ b/examples/widgets/doc/src/dockwidgets.qdoc
@@ -55,8 +55,8 @@
\snippet mainwindows/dockwidgets/mainwindow.cpp 0
- We start by including \c <QtGui>, a header file that contains the
- definition of all classes in the Qt Core and Qt GUI
+ We start by including \c <QtWidgets>, a header file that contains the
+ definition of all classes in the Qt Core, Qt GUI and Qt Widgets
modules. This saves us from having to include
every class individually and is especially convenient if we add new
widgets. We also include \c mainwindow.h.
diff --git a/examples/widgets/draganddrop/puzzle/example.jpg b/examples/widgets/draganddrop/puzzle/example.jpg
index e09fb70757..023203c57a 100644
--- a/examples/widgets/draganddrop/puzzle/example.jpg
+++ b/examples/widgets/draganddrop/puzzle/example.jpg
Binary files differ
diff --git a/examples/widgets/graphicsview/boxes/qt-logo.jpg b/examples/widgets/graphicsview/boxes/qt-logo.jpg
index 4014b4659c..8d7fab052a 100644
--- a/examples/widgets/graphicsview/boxes/qt-logo.jpg
+++ b/examples/widgets/graphicsview/boxes/qt-logo.jpg
Binary files differ
diff --git a/examples/widgets/graphicsview/boxes/qt-logo.png b/examples/widgets/graphicsview/boxes/qt-logo.png
index 7d3e97eb36..0b0b15480c 100644
--- a/examples/widgets/graphicsview/boxes/qt-logo.png
+++ b/examples/widgets/graphicsview/boxes/qt-logo.png
Binary files differ
diff --git a/examples/widgets/itemviews/puzzle/example.jpg b/examples/widgets/itemviews/puzzle/example.jpg
index e09fb70757..023203c57a 100644
--- a/examples/widgets/itemviews/puzzle/example.jpg
+++ b/examples/widgets/itemviews/puzzle/example.jpg
Binary files differ
diff --git a/examples/widgets/painting/basicdrawing/images/qt-logo.png b/examples/widgets/painting/basicdrawing/images/qt-logo.png
index a8b452e07a..abfc8caadb 100644
--- a/examples/widgets/painting/basicdrawing/images/qt-logo.png
+++ b/examples/widgets/painting/basicdrawing/images/qt-logo.png
Binary files differ
diff --git a/examples/widgets/widgets/icons/images/qt_extended_16x16.png b/examples/widgets/widgets/icons/images/qt_extended_16x16.png
index 95d3bae838..bee4e7d6cd 100644
--- a/examples/widgets/widgets/icons/images/qt_extended_16x16.png
+++ b/examples/widgets/widgets/icons/images/qt_extended_16x16.png
Binary files differ
diff --git a/examples/widgets/widgets/icons/images/qt_extended_32x32.png b/examples/widgets/widgets/icons/images/qt_extended_32x32.png
index 7b7a790c12..6e7d000c04 100644
--- a/examples/widgets/widgets/icons/images/qt_extended_32x32.png
+++ b/examples/widgets/widgets/icons/images/qt_extended_32x32.png
Binary files differ
diff --git a/examples/widgets/widgets/icons/images/qt_extended_48x48.png b/examples/widgets/widgets/icons/images/qt_extended_48x48.png
index 8434dc26db..7a93d88900 100644
--- a/examples/widgets/widgets/icons/images/qt_extended_48x48.png
+++ b/examples/widgets/widgets/icons/images/qt_extended_48x48.png
Binary files differ
diff --git a/examples/widgets/widgets/mousebuttons/buttontester.cpp b/examples/widgets/widgets/mousebuttons/buttontester.cpp
index 41c6c95adf..51287f541b 100644
--- a/examples/widgets/widgets/mousebuttons/buttontester.cpp
+++ b/examples/widgets/widgets/mousebuttons/buttontester.cpp
@@ -41,6 +41,8 @@
#include "buttontester.h"
+#include <QDebug>
+
void ButtonTester::mousePressEvent(QMouseEvent *e)
{
int j = ButtonTester::buttonByNumber (e->button());
diff --git a/examples/widgets/widgets/mousebuttons/buttontester.h b/examples/widgets/widgets/mousebuttons/buttontester.h
index 9e7011ac9a..41ae8d0582 100644
--- a/examples/widgets/widgets/mousebuttons/buttontester.h
+++ b/examples/widgets/widgets/mousebuttons/buttontester.h
@@ -41,10 +41,8 @@
#ifndef BUTTONTESTER_H
#define BUTTONTESTER_H
-#include <QtWidgets>
#include <QTextEdit>
#include <QString>
-#include <QDebug>
#include <QMouseEvent>
#include <QWheelEvent>
diff --git a/examples/widgets/widgets/mousebuttons/main.cpp b/examples/widgets/widgets/mousebuttons/main.cpp
index 184547113e..b5446df9e9 100644
--- a/examples/widgets/widgets/mousebuttons/main.cpp
+++ b/examples/widgets/widgets/mousebuttons/main.cpp
@@ -40,7 +40,10 @@
****************************************************************************/
#include "buttontester.h"
-#include <QtGui>
+
+#include <QApplication>
+#include <QPushButton>
+#include <QVBoxLayout>
int main(int argv, char **args)
{
diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
index 6235296ef3..2c29bb88fb 100644
--- a/mkspecs/common/clang.conf
+++ b/mkspecs/common/clang.conf
@@ -7,6 +7,9 @@ QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc
QMAKE_CC = clang
QMAKE_CXX = clang++
+QMAKE_LINK_C = $$QMAKE_CC
+QMAKE_LINK_C_SHLIB = $$QMAKE_CC
+
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
diff --git a/mkspecs/common/qcc-base.conf b/mkspecs/common/qcc-base.conf
index 122f940ec3..f529d7fc7b 100644
--- a/mkspecs/common/qcc-base.conf
+++ b/mkspecs/common/qcc-base.conf
@@ -11,11 +11,15 @@
QMAKE_COMPILER = rim_qcc gcc # qcc is mostly gcc in disguise
+QMAKE_CFLAGS_OPTIMIZE = -O2
+QMAKE_CFLAGS_OPTIMIZE_FULL = -O3
+
QMAKE_CFLAGS += -Wno-psabi
QMAKE_CFLAGS_DEPS += -M
QMAKE_CFLAGS_WARN_ON += -Wall -W
QMAKE_CFLAGS_WARN_OFF += -w
-QMAKE_CFLAGS_RELEASE += -O2
+QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g
QMAKE_CFLAGS_DEBUG += -g
QMAKE_CFLAGS_SHLIB += -fPIC -shared
QMAKE_CFLAGS_STATIC_LIB += -fPIC
@@ -36,6 +40,7 @@ QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB
diff --git a/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
index 97d3407403..a6fc9697f4 100644
--- a/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
+++ b/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
@@ -34,7 +34,7 @@
<m2:ShowOn Tile=\"square150x150Logo\" />
</m2:ShowNameOnTiles>
</m2:DefaultTile>
- <m2:SplashScreen Image=\"$${WINRT_MANIFEST.logo_splash}\" />
+ <m2:SplashScreen Image=\"$${WINRT_MANIFEST.logo_splash}\" />$${WINRT_MANIFEST.rotation_preference}
</m2:VisualElements>
</Application>
</Applications>$${WINRT_MANIFEST.capabilities}$${WINRT_MANIFEST.dependencies}
diff --git a/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in
index cf18a4dc79..b75570ad4e 100644
--- a/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in
+++ b/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in
@@ -37,7 +37,7 @@
<m3:ShowOn Tile=\"square150x150Logo\" />
</m3:ShowNameOnTiles>
</m3:DefaultTile>
- <m3:SplashScreen Image=\"$${WINRT_MANIFEST.logo_480x800}\" />
+ <m3:SplashScreen Image=\"$${WINRT_MANIFEST.logo_480x800}\" />$${WINRT_MANIFEST.rotation_preference}
</m3:VisualElements>
</Application>
</Applications>$${WINRT_MANIFEST.capabilities}$${WINRT_MANIFEST.dependencies}
diff --git a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
index 5f923ad5c6..6537d457ab 100644
--- a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
+++ b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
@@ -4,8 +4,6 @@
include(../common/linux_device_pre.conf)
-QT_QPA_DEFAULT_PLATFORM = wayland
-
QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/opt/vc/lib
QMAKE_LIBDIR_OPENGL_ES2 = $$[QT_SYSROOT]/opt/vc/lib
@@ -21,7 +19,6 @@ QMAKE_LIBS_EGL = -lEGL -lGLESv2
contains(DISTRO, squeeze) {
#Debian Squeeze: Legacy everything
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 -lEGL
- QT_QPA_DEFAULT_PLATFORM = eglfs
} else:contains(DISTRO, arch) {
#On principle: no wizardry required
} else {
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index 05e10c9641..6b37a04450 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -1,4 +1,7 @@
-equals(MAKEFILE_GENERATOR, UNIX) {
+QMAKE_MAKE = $$(MAKE)
+!isEmpty(QMAKE_MAKE) {
+ # We were called recursively. Use the right make, as MAKEFLAGS may be set as well.
+} else:equals(MAKEFILE_GENERATOR, UNIX) {
QMAKE_MAKE = make
} else:equals(MAKEFILE_GENERATOR, MINGW) {
!equals(QMAKE_HOST.os, Windows): \
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index 530683552b..246c9c60e6 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -35,6 +35,30 @@ qt:!isEmpty(QT_CONFIG) {
QMAKE_LFLAGS += -stdlib=libstdc++
}
}
+ # If Qt was built with shared libraries with rpath support and project does
+ # not specify own rpaths (including empty list) add one pointing to Qt
+ # libraries. This applies only to apps, since all loaded libraries inherit
+ # rpaths from current process executable.
+ else:!if(host_build:force_bootstrap):equals(TEMPLATE, app):!defined(QMAKE_RPATHDIR, var):contains(QT_CONFIG, rpath) {
+ # If app is outside of Qt SDK prefix use absolute path to Qt libraries,
+ # otherwise make it relative, so all SDK tools and examples work when
+ # relocated.
+ # Tests are an exception, since they are launched in their build not
+ # install location by CI, so we cannot use relative rpaths there.
+ if(!contains(target.path, "$$re_escape($$[QT_INSTALL_PREFIX])/.*")|\
+ contains(target.path, "$$re_escape($$[QT_INSTALL_TESTS])/.*")) {
+ QMAKE_RPATHDIR = $$[QT_INSTALL_LIBS]
+ } else {
+ app_bundle {
+ ios: binpath = $$target.path/$${TARGET}.app
+ else: binpath = $$target.path/$${TARGET}.app/Contents/MacOS
+ } else {
+ binpath = $$target.path
+ }
+ QMAKE_RPATHDIR = @loader_path/$$relative_path($$[QT_INSTALL_LIBS], $$binpath)
+ unset(binpath)
+ }
+ }
}
macx-xcode:!isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) {
diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf
index 36bff00496..97be211595 100644
--- a/mkspecs/features/mac/sdk.prf
+++ b/mkspecs/features/mac/sdk.prf
@@ -9,8 +9,12 @@ isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path) {
QMAKE_MAC_SDK_PATH = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -version Path 2>/dev/null")
isEmpty(QMAKE_MAC_SDK_PATH): error("Could not resolve SDK path for \'$$QMAKE_MAC_SDK\'")
cache(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path, set stash, QMAKE_MAC_SDK_PATH)
+ QMAKE_MAC_SDK_VERSION = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -version SDKVersion 2>/dev/null")
+ isEmpty(QMAKE_MAC_SDK_VERSION): error("Could not resolve SDK version for \'$$QMAKE_MAC_SDK\'")
+ cache(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.version, set stash, QMAKE_MAC_SDK_VERSION)
} else {
QMAKE_MAC_SDK_PATH = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)
+ QMAKE_MAC_SDK_VERSION = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.version)
}
!equals(MAKEFILE_GENERATOR, XCODE) {
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index ebc5f00b8f..af9d6cae67 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -44,20 +44,20 @@ warnings_are_errors:warning_clean {
# This setting is compiler-dependent anyway because it depends on the version of the
# compiler.
clang {
- # Apple clang 4.0-4.2,5.0
+ # Apple clang 4.0-4.2,5.0-5.1
# Regular clang 3.3 & 3.4
apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION}
- contains(apple_ver, "4\\.[012]|5\\.0")|contains(reg_ver, "3\\.[34]") {
+ contains(apple_ver, "4\\.[012]|5\\.[01]")|contains(reg_ver, "3\\.[34]") {
QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR
# glibc's bswap_XX macros use the "register" keyword
linux:equals(reg_ver, "3.4"): QMAKE_CXXFLAGS_WARN_ON += -Wno-error=deprecated-register
}
} else:intel_icc:linux {
- # Intel CC 13.0 - 14.0, on Linux only
+ # Intel CC 13.0 - 15.0, on Linux only
ver = $${QT_ICC_MAJOR_VERSION}.$${QT_ICC_MINOR_VERSION}
- linux:contains(ver, "(13\\.|14\\.0)") {
+ linux:contains(ver, "(1[34]\\.|15\\.0)") {
# 177: function "entity" was declared but never referenced
# (too aggressive; ICC reports even for functions created due to template instantiation)
# 1224: #warning directive
@@ -67,9 +67,9 @@ warnings_are_errors:warning_clean {
QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1881 $$WERROR
}
} else:gcc:!clang:!intel_icc {
- # GCC 4.6-4.8
+ # GCC 4.6-4.9
ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION}
- contains(ver, "4\\.[678]") {
+ contains(ver, "4\\.[6789]") {
QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=cpp -Wno-error=deprecated-declarations $$WERROR
# GCC prints this bogus warning, after it has inlined a lot of code
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 8599a47ecd..d213f9e260 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -94,6 +94,8 @@ else: \
# OS X and iOS frameworks
mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
+ # Set the CFBundleIdentifier prefix for Qt frameworks
+ QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project
#QMAKE_FRAMEWORK_VERSION = 4.0
CONFIG += lib_bundle sliced_bundle qt_framework
CONFIG -= qt_install_headers #no need to install these as well
diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf
index baeb22d9b4..5015d58861 100644
--- a/mkspecs/features/qt_module_headers.prf
+++ b/mkspecs/features/qt_module_headers.prf
@@ -58,7 +58,9 @@ MODULE_MASTER_DEPS_HEADER = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME/$${MOD
MODULE_MASTER_DEPS_HEADER_CONT = $$autogen_warning
MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}ifdef __cplusplus /* create empty PCH in C mode */"
for(dep, MODULE_DEPENDS) {
- depname = $$eval(QT.$${dep}.name)
+ depname = $$eval(QT.$${dep}.master_header)
+ isEmpty(depname): \
+ depname = $$eval(QT.$${dep}.name)
MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}include <$$depname/$$depname>"
}
MODULE_MASTER_DEPS_HEADER_CONT += "$${LITERAL_HASH}endif"
diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf
index 3d438e52f4..9a876caf5e 100644
--- a/mkspecs/features/qt_module_pris.prf
+++ b/mkspecs/features/qt_module_pris.prf
@@ -74,6 +74,10 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
module_plugtypes = "QT.$${MODULE_ID}.plugin_types = $$replace(MODULE_PLUGIN_TYPES, /.*$, )"
else: \
module_plugtypes =
+ !isEmpty(MODULE_MASTER_HEADER): \
+ module_master = "QT.$${MODULE_ID}.master_header = $$MODULE_MASTER_HEADER"
+ else: \
+ module_master =
!no_module_headers:!minimal_syncqt {
MODULE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME
MODULE_PRIVATE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME/$$VERSION \
@@ -97,6 +101,7 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
"QT.$${MODULE_ID}.name = $$TARGET" \
"QT.$${MODULE_ID}.libs = $$module_libs" \
$$module_rpath \
+ $$module_master \
"QT.$${MODULE_ID}.includes = $$MODULE_INCLUDES"
!host_build: MODULE_PRI_CONT += \
"QT.$${MODULE_ID}.bins = \$\$QT_MODULE_BIN_BASE" \
diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf
index 27db7d7d7a..8564731a22 100644
--- a/mkspecs/features/resources.prf
+++ b/mkspecs/features/resources.prf
@@ -11,7 +11,7 @@ rcc.name = RCC ${QMAKE_FILE_IN}
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
rcc.CONFIG += add_inputs_as_makefile_deps
-resources_small|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") {
+!resources_big|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") {
rcc.output = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
rcc.commands = $$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf
index b4242bfdaa..2ccb5db963 100644
--- a/mkspecs/features/winrt/package_manifest.prf
+++ b/mkspecs/features/winrt/package_manifest.prf
@@ -24,6 +24,7 @@
# WINRT_MANIFEST.logo_medium: Medium logo image file. Default provided by the mkspec.
# WINRT_MANIFEST.logo_large: Large logo image file. Default provided by the mkspec.
# WINRT_MANIFEST.splash_screen: Splash screen image file. Default provided by the mkspec.
+# WINRT_MANIFEST.rotation_preference: Orientation specification. Default is empty. (portrait, landscape, landscapeFlipped)
# WINRT_MANIFEST.iconic_tile_icon: Image file for the "iconic" tile template icon. Default provided by the mkspec.
# WINRT_MANIFEST.iconic_tile_small: Image file for the small "iconic" tile template logo. Default provided by the mkspec.
# WINRT_MANIFEST.default_language: Specifies the default language of the application
@@ -87,6 +88,20 @@
isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light
isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en
+ INDENT = "$$escape_expand(\\r\\n) "
+
+ VS_XML_NAMESPACE = "m2"
+ winphone: VS_XML_NAMESPACE = "m3"
+ WINRT_MANIFEST.rotation_preference = $$unique(WINRT_MANIFEST.rotation_preference)
+ !isEmpty(WINRT_MANIFEST.rotation_preference) {
+ MANIFEST_ROTATION += "<$${VS_XML_NAMESPACE}:InitialRotationPreference>"
+ for(ROTATION, WINRT_MANIFEST.rotation_preference): \
+ MANIFEST_ROTATION += " <$${VS_XML_NAMESPACE}:Rotation Preference=\"$$ROTATION\" />"
+ MANIFEST_ROTATION += "</$${VS_XML_NAMESPACE}:InitialRotationPreference>"
+
+ WINRT_MANIFEST.rotation_preference = $$join(MANIFEST_ROTATION, $$INDENT, $$INDENT)
+ }
+
INDENT = "$$escape_expand(\\r\\n) "
# Capabilities are given as a string list and may change with the configuration (network, sensors, etc.)
diff --git a/mkspecs/macx-clang-32/Info.plist.lib b/mkspecs/macx-clang-32/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-clang-32/Info.plist.lib
+++ b/mkspecs/macx-clang-32/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-clang/Info.plist.lib b/mkspecs/macx-clang/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-clang/Info.plist.lib
+++ b/mkspecs/macx-clang/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-g++-32/Info.plist.lib b/mkspecs/macx-g++-32/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-g++-32/Info.plist.lib
+++ b/mkspecs/macx-g++-32/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-g++/Info.plist.lib b/mkspecs/macx-g++/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-g++/Info.plist.lib
+++ b/mkspecs/macx-g++/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-g++40/Info.plist.lib b/mkspecs/macx-g++40/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-g++40/Info.plist.lib
+++ b/mkspecs/macx-g++40/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-g++42/Info.plist.lib b/mkspecs/macx-g++42/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-g++42/Info.plist.lib
+++ b/mkspecs/macx-g++42/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-icc/Info.plist.lib b/mkspecs/macx-icc/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-icc/Info.plist.lib
+++ b/mkspecs/macx-icc/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf
index a1783c97ad..5e45e67d0c 100644
--- a/mkspecs/macx-icc/qmake.conf
+++ b/mkspecs/macx-icc/qmake.conf
@@ -52,8 +52,7 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
-# Disabled, due to invalid C++11 code on Apple headers
-#QMAKE_CXXFLAGS_CXX11 = -std=c++11
+QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS
QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
@@ -85,7 +84,7 @@ QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_
QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
+QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9
include(../common/macx.conf)
diff --git a/mkspecs/macx-ios-clang/Info.plist.app b/mkspecs/macx-ios-clang/Info.plist.app
index 2987804e33..623ed496c5 100755
--- a/mkspecs/macx-ios-clang/Info.plist.app
+++ b/mkspecs/macx-ios-clang/Info.plist.app
@@ -24,6 +24,8 @@
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
diff --git a/mkspecs/macx-ios-clang/LaunchScreen.xib b/mkspecs/macx-ios-clang/LaunchScreen.xib
new file mode 100644
index 0000000000..d28c06b375
--- /dev/null
+++ b/mkspecs/macx-ios-clang/LaunchScreen.xib
@@ -0,0 +1,45 @@
+<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
+<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"6250\" systemVersion=\"14A343f\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\">
+ <dependencies>
+ <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"6244\"/>
+ <capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>
+ </dependencies>
+ <objects>
+ <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File\'s Owner\"/>
+ <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>
+ <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">
+ <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"480\"/>
+ <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>
+ <subviews>
+ <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8ie-xW-0ye\">
+ <rect key=\"frame\" x=\"20\" y=\"439\" width=\"441\" height=\"21\"/>
+ <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>
+ <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>
+ <nil key=\"highlightedColor\"/>
+ <variation key=\"widthClass=compact\">
+ <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"11\"/>
+ </variation>
+ </label>
+ <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"$$TARGET\"
+ textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"kId-c2-rCX\">
+ <rect key=\"frame\" x=\"20\" y=\"140\" width=\"441\" height=\"43\"/>
+ <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>
+ <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>
+ <nil key=\"highlightedColor\"/>
+ </label>
+ </subviews>
+ <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>
+ <constraints>
+ <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"centerY\" secondItem=\"iN0-l3-epB\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"Kid-kn-2rF\"/>
+ <constraint firstAttribute=\"centerX\" secondItem=\"kId-c2-rCX\" secondAttribute=\"centerX\" id=\"Koa-jz-hwk\"/>
+ <constraint firstAttribute=\"bottom\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"bottom\" constant=\"20\" id=\"Kzo-t9-V3l\"/>
+ <constraint firstItem=\"8ie-xW-0ye\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"MfP-vx-nX0\"/>
+ <constraint firstAttribute=\"centerX\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"centerX\" id=\"ZEH-qu-HZ9\"/>
+ <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"fvb-Df-36g\"/>
+ </constraints>
+ <nil key=\"simulatedStatusBarMetrics\"/>
+ <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>
+ <point key=\"canvasLocation\" x=\"404\" y=\"445\"/>
+ </view>
+ </objects>
+</document>
diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf
index 79024c588c..643a17e23e 100644
--- a/mkspecs/macx-ios-clang/features/default_post.prf
+++ b/mkspecs/macx-ios-clang/features/default_post.prf
@@ -184,6 +184,14 @@ macx-xcode {
QMAKE_SUBSTITUTES += copy_image
launch_images.files = $$copy_image.output
QMAKE_BUNDLE_DATA += launch_images
+
+ # Set up default LaunchScreen to support iPhone6/6+
+ launch_screen = LaunchScreen.xib
+ copy_launch_screen.input = $$QMAKESPEC/$$launch_screen
+ copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$launch_screen
+ QMAKE_SUBSTITUTES += copy_launch_screen
+ launch_screens.files = $$copy_launch_screen.output
+ QMAKE_BUNDLE_DATA += launch_screens
}
macx-xcode {
@@ -193,22 +201,32 @@ macx-xcode {
arch_iphonesimulator.value = $$QMAKE_IOS_SIMULATOR_ARCHS
QMAKE_MAC_XCODE_SETTINGS += arch_iphoneos arch_iphonesimulator
- unset(QMAKE_XCODE_ARCHS)
+ QMAKE_XCODE_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS
+
+ only_active_arch.name = ONLY_ACTIVE_ARCH
+ only_active_arch.value = YES
+ only_active_arch.build = debug
+ QMAKE_MAC_XCODE_SETTINGS += only_active_arch
} else {
-# Be more specific about which architecture we're targeting
- equals(QT_ARCH, arm): \
- actual_archs = $$QMAKE_IOS_DEVICE_ARCHS
+ # Be more specific about which architecture we're targeting
+ contains(QT_ARCH, arm.*): \
+ VALID_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS
else: \
- actual_archs = $$QMAKE_IOS_SIMULATOR_ARCHS
+ VALID_ARCHS = $$QMAKE_IOS_SIMULATOR_ARCHS
+
+ single_arch: VALID_ARCHS = $$first(VALID_ARCHS)
+
+ ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS))
+ ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ACTIVE_ARCHS), $(EXPORT_ACTIVE_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch))
+
+ QMAKE_EXTRA_VARIABLES += VALID_ARCHS ACTIVE_ARCHS ARCH_ARGS
- for(arch, actual_archs): \
- arch_flags += -arch $$arch
+ arch_flags = $(EXPORT_ARCH_ARGS)
QMAKE_CFLAGS += $$arch_flags
QMAKE_CXXFLAGS += $$arch_flags
QMAKE_OBJECTIVE_CFLAGS += $$arch_flags
QMAKE_LFLAGS += $$arch_flags
}
-unset(actual_archs)
load(default_post)
diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf
index a5b00377ee..7ca3198dbe 100644
--- a/mkspecs/macx-ios-clang/features/qt.prf
+++ b/mkspecs/macx-ios-clang/features/qt.prf
@@ -32,17 +32,19 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) {
# called 'qt_main' now.
macx-xcode {
- objects_dir = "${OBJECT_FILE_DIR}-${CURRENT_VARIANT}/${CURRENT_ARCH}"
+ objects_dir = "${OBJECT_FILE_DIR}-${CURRENT_VARIANT}"
+ archs = "${ARCHS}"
} else {
objects_dir = $$OBJECTS_DIR
isEmpty(objects_dir): \
objects_dir = .
+ archs = "$$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS"
}
!isEmpty(QMAKE_PRE_LINK): \
QMAKE_PRE_LINK += ";"
- QMAKE_PRE_LINK += $$QMAKESPEC/rename_main.sh $${objects_dir}
+ QMAKE_PRE_LINK += $$QMAKESPEC/rename_main.sh $${objects_dir} \"$${archs}\"
}
}
diff --git a/mkspecs/macx-ios-clang/features/qt_config.prf b/mkspecs/macx-ios-clang/features/qt_config.prf
index d9a13f65eb..d1a1a36933 100644
--- a/mkspecs/macx-ios-clang/features/qt_config.prf
+++ b/mkspecs/macx-ios-clang/features/qt_config.prf
@@ -9,4 +9,8 @@ isEmpty(QT_ARCH) {
QT_ARCH = arm
else: \ # Simulator
QT_ARCH = i386
+
+ # Prevent the arch/config tests from building as multi-arch binaries,
+ # as we only want the lowest common denominator features.
+ CONFIG += single_arch
}
diff --git a/mkspecs/macx-ios-clang/features/sdk.prf b/mkspecs/macx-ios-clang/features/sdk.prf
new file mode 100644
index 0000000000..607a71bb26
--- /dev/null
+++ b/mkspecs/macx-ios-clang/features/sdk.prf
@@ -0,0 +1,4 @@
+load(sdk)
+
+lessThan(QMAKE_MAC_SDK_VERSION, "8.0"): \
+ error("Current $$QMAKE_MAC_SDK SDK version ($$QMAKE_MAC_SDK_VERSION) is too old. Please upgrade Xcode.")
diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf
index 7b2e7a17e7..0c083edf80 100644
--- a/mkspecs/macx-ios-clang/qmake.conf
+++ b/mkspecs/macx-ios-clang/qmake.conf
@@ -15,8 +15,8 @@ DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG
# Universal target (iPhone and iPad)
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2
-QMAKE_IOS_DEVICE_ARCHS = armv7
-QMAKE_IOS_SIMULATOR_ARCHS = i386
+QMAKE_IOS_DEVICE_ARCHS = armv7 arm64
+QMAKE_IOS_SIMULATOR_ARCHS = i386 x86_64
include(../common/ios.conf)
include(../common/gcc-base-mac.conf)
diff --git a/mkspecs/macx-ios-clang/rename_main.sh b/mkspecs/macx-ios-clang/rename_main.sh
index b1321e855e..040140b7ee 100755
--- a/mkspecs/macx-ios-clang/rename_main.sh
+++ b/mkspecs/macx-ios-clang/rename_main.sh
@@ -41,10 +41,14 @@
##
#############################################################################
-if [ $# -eq 0 ]; then
- echo "usage: $0 <path to object files>"
+if [ $# -ne 2 ]; then
+ echo "$0: wrong number of arguments for internal tool used by iOS mkspec"
else
- for f in $(find $1 -name '*.o'); do
+ arch_paths=""
+ for a in $2; do
+ arch_paths="$arch_paths $1/$a"
+ done
+ for f in $(find $arch_paths -name '*.o'); do
# Skip object files without the _main symbol
nm $f 2>/dev/null | grep -q 'T _main$' || continue
diff --git a/mkspecs/macx-llvm/Info.plist.lib b/mkspecs/macx-llvm/Info.plist.lib
index 2a44d1721e..7cbdb9af12 100644
--- a/mkspecs/macx-llvm/Info.plist.lib
+++ b/mkspecs/macx-llvm/Info.plist.lib
@@ -14,6 +14,8 @@
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@LIBRARY@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@BUNDLEIDENTIFIER@</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/unsupported/freebsd-clang/qmake.conf
index ad4fa3487e..2cfd763688 100644
--- a/mkspecs/unsupported/freebsd-clang/qmake.conf
+++ b/mkspecs/unsupported/freebsd-clang/qmake.conf
@@ -13,6 +13,7 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_INCDIR = /usr/local/include
QMAKE_LIBDIR = /usr/local/lib
+QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_THREAD = -pthread
QMAKE_LIBS =
@@ -28,6 +29,5 @@ QMAKE_RANLIB =
include(../../common/unix.conf)
include(../../common/gcc-base-unix.conf)
-include(../../common/g++-unix.conf)
include(../../common/clang.conf)
load(qt_config)
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 3659621391..0ff42500de 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1029,6 +1029,21 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if (!project->isEmpty("QMAKE_PRE_LINK")) {
QString phase_key = keyFor("QMAKE_PBX_PRELINK_BUILDPHASE");
project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
+
+ ProStringList inputPaths;
+ ProStringList outputPaths;
+ const ProStringList &archs = project->values("QMAKE_XCODE_ARCHS");
+ if (!archs.isEmpty()) {
+ for (int i = 0; i < archs.size(); ++i) {
+ const ProString &arch = archs.at(i);
+ inputPaths << "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/" + arch + "/";
+ outputPaths << "$(LINK_FILE_LIST_$(CURRENT_VARIANT)_" + arch + ")";
+ }
+ } else {
+ inputPaths << "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/";
+ outputPaths << "$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))";
+ }
+
t << "\t\t" << phase_key << " = {\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n"
@@ -1036,8 +1051,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
// resolved dependenices, so we have to ensure that this phase is run after the
// compilation phase, and before the link phase. Making the phase depend on the
// object file directory, and "write" to the list of files to link achieves that.
- << "\t\t\t" << writeSettings("inputPaths", ProStringList("$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/"), SettingsAsList, 4) << ";\n"
- << "\t\t\t" << writeSettings("outputPaths", ProStringList("$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"), SettingsAsList, 4) << ";\n"
+ << "\t\t\t" << writeSettings("inputPaths", inputPaths, SettingsAsList, 4) << ";\n"
+ << "\t\t\t" << writeSettings("outputPaths", outputPaths, SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n"
@@ -1107,9 +1122,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";\n"
<< "\t\t};\n";
}
+ bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app";
+ ProStringList bundle_resources_files;
// Copy Bundle Data
if (!project->isEmpty("QMAKE_BUNDLE_DATA")) {
ProStringList bundle_file_refs;
+ bool ios = project->isActiveConfig("ios");
//all bundle data
const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
@@ -1137,21 +1155,27 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t};\n";
}
- QString phase_key = keyFor("QMAKE_PBX_BUNDLE_COPY." + bundle_data[i]);
- if (!project->isEmpty(ProKey(bundle_data[i] + ".version"))) {
- //###
- }
+ if (copyBundleResources && ((ios && path.isEmpty())
+ || (!ios && path == QLatin1String("Contents/Resources")))) {
+ foreach (const ProString &s, bundle_files)
+ bundle_resources_files << s;
+ } else {
+ QString phase_key = keyFor("QMAKE_PBX_BUNDLE_COPY." + bundle_data[i]);
+ if (!project->isEmpty(ProKey(bundle_data[i] + ".version"))) {
+ //###
+ }
- project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
- t << "\t\t" << phase_key << " = {\n"
- << "\t\t\t" << writeSettings("name", "Copy '" + bundle_data[i] + "' Files to Bundle") << ";\n"
- << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
- << "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";\n"
- << "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";\n"
- << "\t\t\t" << writeSettings("files", bundle_files, SettingsAsList, 4) << ";\n"
- << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n"
- << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
- << "\t\t};\n";
+ project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
+ t << "\t\t" << phase_key << " = {\n"
+ << "\t\t\t" << writeSettings("name", "Copy '" + bundle_data[i] + "' Files to Bundle") << ";\n"
+ << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";\n"
+ << "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("files", bundle_files, SettingsAsList, 4) << ";\n"
+ << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
+ << "\t\t};\n";
+ }
}
QString bundle_data_key = keyFor("QMAKE_PBX_BUNDLE_DATA");
@@ -1166,8 +1190,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
// Copy bundle resources. Optimizes resources, and puts them into the Resources
// subdirectory on OSX, but doesn't support paths.
- if (project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app") {
- ProStringList bundle_resources_files;
+ if (copyBundleResources) {
if (!project->isEmpty("ICON")) {
ProString icon = project->first("ICON");
if (icon.length() >= 2 && (icon.at(0) == '"' || icon.at(0) == '\'') && icon.endsWith(icon.at(0)))
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index d9b0e10057..8270f02feb 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -814,22 +814,26 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
}
commonSedArgs << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" ";
+
+ QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
+ if (bundlePrefix.isEmpty())
+ bundlePrefix = "com.yourcompany";
+ if (bundlePrefix.endsWith("."))
+ bundlePrefix.chop(1);
+ QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
+ if (bundleIdentifier.endsWith(".app"))
+ bundleIdentifier.chop(4);
+ if (bundleIdentifier.endsWith(".framework"))
+ bundleIdentifier.chop(10);
+ commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" ";
+
if (isApp) {
QString icon = fileFixify(var("ICON"));
- QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
- if (bundlePrefix.isEmpty())
- bundlePrefix = "com.yourcompany";
- if (bundlePrefix.endsWith("."))
- bundlePrefix.chop(1);
- QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
- if (bundleIdentifier.endsWith(".app"))
- bundleIdentifier.chop(4);
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
<< "@sed ";
foreach (const ProString &arg, commonSedArgs)
t << arg;
t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" "
- << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "
<< "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" "
<< "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index f2d55d481d..4ddb76032e 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE
const char _CLCompile[] = "ClCompile";
const char _ItemGroup[] = "ItemGroup";
const char _Link[] = "Link";
+const char _Lib[] = "Lib";
const char _ManifestTool[] = "ManifestTool";
const char _Midl[] = "Midl";
const char _ResourceCompile[] = "ResourceCompile";
@@ -757,8 +758,11 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
// ClCompile
write(xml, config.compiler);
- // Link
- write(xml, config.linker);
+ // Librarian / Linker
+ if (config.ConfigurationType == typeStaticLibrary)
+ write(xml, config.librarian);
+ else
+ write(xml, config.linker);
// Midl
write(xml, config.idl);
@@ -1686,7 +1690,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCustomBuildTool &tool)
void VCXProjectWriter::write(XmlOutput &xml, const VCLibrarianTool &tool)
{
xml
- << tag(_Link)
+ << tag(_Lib)
<< attrTagX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
<< attrTagX(_AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories, ";")
<< attrTagX(_AdditionalOptions, tool.AdditionalOptions, " ")
@@ -1706,7 +1710,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCLibrarianTool &tool)
//unused << attrTagS(_TargetMachine, tool.TargetMachine)
//unused << attrTagT(_TreatLibWarningAsErrors, tool.TreatLibWarningAsErrors)
//unused << attrTagT(_Verbose, tool.Verbose)
- << closetag(_Link);
+ << closetag(_Lib);
}
void VCXProjectWriter::write(XmlOutput &xml, const VCResourceCompilerTool &tool)
@@ -1911,10 +1915,10 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml
}
// Actual XML output ----------------------------------
- if (hasCustomBuildStep || filter.useCompilerTool
+ if (hasCustomBuildStep || filter.useCustomBuildTool || filter.useCompilerTool
|| !d->inBuild || filter.Name.startsWith("Deployment Files")) {
- if (hasCustomBuildStep)
+ if (hasCustomBuildStep || filter.useCustomBuildTool)
{
if (!fileAdded) {
fileAdded = true;
diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp
index e4dc840b22..97cc590d84 100644
--- a/qmake/library/proitems.cpp
+++ b/qmake/library/proitems.cpp
@@ -416,8 +416,8 @@ QStringList ProStringList::toQStringList() const
{
QStringList ret;
ret.reserve(size());
- foreach (const ProString &str, *this)
- ret << str.toQString();
+ for (int i = 0; i < size(); i++) // foreach causes MSVC2010 ICE
+ ret << at(i).toQString();
return ret;
}
diff --git a/qtbase.pro b/qtbase.pro
index d6861cf09f..6d0de44f6d 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -140,7 +140,7 @@ for (ft, features) {
"$${LITERAL_HASH} define QT_NO_$$ft" \
"$${LITERAL_HASH}endif"
FEATURES_PRI += \
- "contains(QT_DISABLED_FEATURES, "^($$lower($$join($$list($$replace(features.$${ft}.depends, _, -)), "|")))$"): \\" \
+ "contains(QT_DISABLED_FEATURES, "$$lower($$join($$list($$replace(features.$${ft}.depends, _, -)), "|"))"): \\" \
" QT_DISABLED_FEATURES += $$lower($$replace(ft, _, -))"
}
}
@@ -168,7 +168,8 @@ for (def, QT_NO_DEFINES) {
}
no_features = $$unique(no_features)
-# Can't simply add these to QT_CONFIG, as e.g., contains(QT_CONFIG, accessibility) matches no-accessibililty.
+# Don't simply add these to QT_CONFIG, as then one might expect them to be there without load(qfeatures).
+# And we don't want to do that automatically, as the dynamic dependency resolution is somewhat expensive.
FEATURES_PRI = \
"$${LITERAL_HASH} Features disabled by configure:" \
"QT_DISABLED_FEATURES =$$lower($$join($$list($$replace(no_features, _, -)), " ", " "))" \
diff --git a/src/3rdparty/angle/AUTHORS b/src/3rdparty/angle/AUTHORS
index b79bb5d161..be114bcf68 100644
--- a/src/3rdparty/angle/AUTHORS
+++ b/src/3rdparty/angle/AUTHORS
@@ -21,10 +21,12 @@ Mozilla Corporation
Turbulenz
Klarälvdalens Datakonsult AB
Microsoft Open Technologies, Inc.
+NVIDIA Corporation
Jacek Caban
Mark Callow
Ginn Chen
+Tibor den Ouden
James Hauxwell
Sam Hocevar
Pierre Leveille
diff --git a/src/3rdparty/angle/CONTRIBUTORS b/src/3rdparty/angle/CONTRIBUTORS
index 0cae10a0f6..94d009f2b3 100644
--- a/src/3rdparty/angle/CONTRIBUTORS
+++ b/src/3rdparty/angle/CONTRIBUTORS
@@ -78,7 +78,12 @@ Turbulenz
Ulrik Persson (ddefrostt)
Mark Banner (standard8mbp)
David Kilzer
+Jacek Caban
+Tibor den Ouden
Microsoft Open Technologies, Inc.
Cooper Partin
Austin Kinross
+
+NVIDIA Corporation
+ Olli Etuaho
diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h
index ab2f0cdfbe..12590a0e20 100644
--- a/src/3rdparty/angle/include/EGL/egl.h
+++ b/src/3rdparty/angle/include/EGL/egl.h
@@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
#ifndef EGL_VERSION_1_5
#define EGL_VERSION_1_5 1
typedef void *EGLSync;
-typedef khronos_intptr_t EGLAttrib;
+typedef intptr_t EGLAttrib;
typedef khronos_utime_nanoseconds_t EGLTime;
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h
index 989359b026..0cc5eec293 100644
--- a/src/3rdparty/angle/include/EGL/eglext.h
+++ b/src/3rdparty/angle/include/EGL/eglext.h
@@ -59,7 +59,7 @@ extern "C" {
#ifndef EGL_KHR_cl_event2
#define EGL_KHR_cl_event2 1
typedef void *EGLSyncKHR;
-typedef khronos_intptr_t EGLAttribKHR;
+typedef intptr_t EGLAttribKHR;
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
@@ -442,20 +442,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_ANGLE_platform_angle 1
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
-#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3203
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3204
+#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3205
#endif /* EGL_ANGLE_platform_angle */
#ifndef EGL_ANGLE_platform_angle_d3d
#define EGL_ANGLE_platform_angle_d3d 1
-#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3204
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
+#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
#endif /* EGL_ANGLE_platform_angle_d3d */
#ifndef EGL_ANGLE_platform_angle_opengl
#define EGL_ANGLE_platform_angle_opengl 1
-#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3207
-#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
#endif /* EGL_ANGLE_platform_angle_opengl */
#ifndef EGL_ARM_pixmap_multisample_discard
diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
index ea9f5778ee..2eb3674a0b 100644
--- a/src/3rdparty/angle/include/EGL/eglplatform.h
+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
@@ -67,23 +67,22 @@
* implementations.
*/
-#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
-
-struct IUnknown;
-
-typedef IUnknown *EGLNativeDisplayType;
-typedef void *EGLNativePixmapType;
-typedef IUnknown *EGLNativeWindowType;
-
-#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
-typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
+
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
+#include <inspectable.h>
+typedef IInspectable* EGLNativeDisplayType;
+typedef IInspectable* EGLNativeWindowType;
+#else
+typedef HDC EGLNativeDisplayType;
typedef HWND EGLNativeWindowType;
+#endif
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
index b7989f5f7e..647fed6a02 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
@@ -27,6 +27,10 @@
#include "KHR/khrplatform.h"
+#include <map>
+#include <string>
+#include <vector>
+
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@@ -42,18 +46,17 @@ typedef unsigned int GLenum;
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
#include "ShaderVars.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Version number for shader translation API.
// It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 130
+#define ANGLE_SH_VERSION 132
typedef enum {
SH_GLES2_SPEC = 0x8B40,
SH_WEBGL_SPEC = 0x8B41,
+ SH_GLES3_SPEC = 0x8B86,
+ SH_WEBGL2_SPEC = 0x8B87,
+
// The CSS Shaders spec is a subset of the WebGL spec.
//
// In both CSS vertex and fragment shaders, ANGLE:
@@ -85,31 +88,6 @@ typedef enum {
SH_HLSL11_OUTPUT = 0x8B48
} ShShaderOutput;
-typedef enum {
- SH_PRECISION_HIGHP = 0x5001,
- SH_PRECISION_MEDIUMP = 0x5002,
- SH_PRECISION_LOWP = 0x5003,
- SH_PRECISION_UNDEFINED = 0
-} ShPrecisionType;
-
-typedef enum {
- SH_INFO_LOG_LENGTH = 0x8B84,
- SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
- SH_ACTIVE_UNIFORMS = 0x8B86,
- SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
- SH_ACTIVE_ATTRIBUTES = 0x8B89,
- SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
- SH_VARYINGS = 0x8BBB,
- SH_VARYING_MAX_LENGTH = 0x8BBC,
- SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
- SH_NAME_MAX_LENGTH = 0x6001,
- SH_HASHED_NAME_MAX_LENGTH = 0x6002,
- SH_HASHED_NAMES_COUNT = 0x6003,
- SH_SHADER_VERSION = 0x6004,
- SH_RESOURCES_STRING_LENGTH = 0x6005,
- SH_OUTPUT_TYPE = 0x6006
-} ShShaderInfo;
-
// Compile options.
typedef enum {
SH_VALIDATE = 0,
@@ -208,14 +186,14 @@ typedef enum {
//
// Driver must call this first, once, before doing any other
// compiler operations.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
//
-COMPILER_EXPORT int ShInitialize();
+COMPILER_EXPORT bool ShInitialize();
//
// Driver should call this at shutdown.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
//
-COMPILER_EXPORT int ShFinalize();
+COMPILER_EXPORT bool ShFinalize();
// The 64 bits hash function. The first parameter is the input string; the
// second parameter is the string length.
@@ -246,6 +224,12 @@ typedef struct
int EXT_frag_depth;
int EXT_shader_texture_lod;
+ // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
+ // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
+ // EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
+ // function. This applies to Tegra K1 devices.
+ int NV_draw_buffers;
+
// Set to 1 if highp precision is supported in the fragment language.
// Default is 0.
int FragmentPrecisionHigh;
@@ -274,8 +258,10 @@ typedef struct
//
// Initialize built-in resources with minimum expected values.
+// Parameters:
+// resources: The object to initialize. Will be comparable with memcmp.
//
-COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
+COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
//
// ShHandle held by but opaque to the driver. It is allocated,
@@ -284,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
//
// If handle creation fails, 0 will be returned.
//
-typedef void* ShHandle;
+typedef void *ShHandle;
//
-// Returns the a concatenated list of the items in ShBuiltInResources as a string.
+// Returns the a concatenated list of the items in ShBuiltInResources as a
+// null-terminated string.
// This function must be updated whenever ShBuiltInResources is changed.
// Parameters:
// handle: Specifies the handle of the compiler to be used.
-// outStringLen: Specifies the size of the buffer, in number of characters. The size
-// of the buffer required to store the resources string can be obtained
-// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
-// outStr: Returns a null-terminated string representing all the built-in resources.
-COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
+COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
//
// Driver calls these to create and destroy compiler objects.
@@ -313,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler(
sh::GLenum type,
ShShaderSpec spec,
ShShaderOutput output,
- const ShBuiltInResources* resources);
+ const ShBuiltInResources *resources);
COMPILER_EXPORT void ShDestruct(ShHandle handle);
//
// Compiles the given shader source.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
// Parameters:
// handle: Specifies the handle of compiler to be used.
// shaderStrings: Specifies an array of pointers to null-terminated strings
@@ -340,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
// Can be queried by calling ShGetVariableInfo().
//
-COMPILER_EXPORT int ShCompile(
+COMPILER_EXPORT bool ShCompile(
const ShHandle handle,
- const char* const shaderStrings[],
+ const char * const shaderStrings[],
size_t numStrings,
- int compileOptions
- );
+ int compileOptions);
-// Returns a parameter from a compiled shader.
-// Parameters:
-// handle: Specifies the compiler
-// pname: Specifies the parameter to query.
-// The following parameters are defined:
-// SH_INFO_LOG_LENGTH: the number of characters in the information log
-// including the null termination character.
-// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
-// including the null termination character.
-// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
-// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
-// variable name including the null
-// termination character.
-// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
-// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
-// variable name including the null
-// termination character.
-// SH_VARYINGS: the number of varying variables.
-// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
-// including the null termination character.
-// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
-// the null termination character.
-// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
-// null termination character.
-// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
-// null termination character.
-// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
-// SH_SHADER_VERSION: the version of the shader language
-// SH_OUTPUT_TYPE: the currently set language output type
-//
-// params: Requested parameter
-COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
- ShShaderInfo pname,
- size_t* params);
+// Return the version of the shader language.
+COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
-// Returns nul-terminated information log for a compiled shader.
+// Return the currently set language output type.
+COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
+ const ShHandle handle);
+
+// Returns null-terminated information log for a compiled shader.
// Parameters:
// handle: Specifies the compiler
-// infoLog: Specifies an array of characters that is used to return
-// the information log. It is assumed that infoLog has enough memory
-// to accomodate the information log. The size of the buffer required
-// to store the returned information log can be obtained by calling
-// ShGetInfo with SH_INFO_LOG_LENGTH.
-COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
+COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
// Returns null-terminated object code for a compiled shader.
// Parameters:
// handle: Specifies the compiler
-// infoLog: Specifies an array of characters that is used to return
-// the object code. It is assumed that infoLog has enough memory to
-// accomodate the object code. The size of the buffer required to
-// store the returned object code can be obtained by calling
-// ShGetInfo with SH_OBJECT_CODE_LENGTH.
-COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
-
-// Returns information about a shader variable.
-// Parameters:
-// handle: Specifies the compiler
-// variableType: Specifies the variable type; options include
-// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
-// index: Specifies the index of the variable to be queried.
-// length: Returns the number of characters actually written in the string
-// indicated by name (excluding the null terminator) if a value other
-// than NULL is passed.
-// size: Returns the size of the variable.
-// type: Returns the data type of the variable.
-// precision: Returns the precision of the variable.
-// staticUse: Returns 1 if the variable is accessed in a statement after
-// pre-processing, whether or not run-time flow of control will
-// cause that statement to be executed.
-// Returns 0 otherwise.
-// name: Returns a null terminated string containing the name of the
-// variable. It is assumed that name has enough memory to accormodate
-// the variable name. The size of the buffer required to store the
-// variable name can be obtained by calling ShGetInfo with
-// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
-// SH_VARYING_MAX_LENGTH.
-// mappedName: Returns a null terminated string containing the mapped name of
-// the variable, It is assumed that mappedName has enough memory
-// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
-// mapped name. If the name is not mapped, then name and mappedName
-// are the same.
-COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
- ShShaderInfo variableType,
- int index,
- size_t* length,
- int* size,
- sh::GLenum* type,
- ShPrecisionType* precision,
- int* staticUse,
- char* name,
- char* mappedName);
-
-// Returns information about a name hashing entry from the latest compile.
+COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
+
+// Returns a (original_name, hash) map containing all the user defined
+// names in the shader, including variable names, function names, struct
+// names, and struct field names.
// Parameters:
// handle: Specifies the compiler
-// index: Specifies the index of the name hashing entry to be queried.
-// name: Returns a null terminated string containing the user defined name.
-// It is assumed that name has enough memory to accomodate the name.
-// The size of the buffer required to store the user defined name can
-// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
-// hashedName: Returns a null terminated string containing the hashed name of
-// the uniform variable, It is assumed that hashedName has enough
-// memory to accomodate the name. The size of the buffer required
-// to store the name can be obtained by calling ShGetInfo with
-// SH_HASHED_NAME_MAX_LENGTH.
-COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
- int index,
- char* name,
- char* hashedName);
+COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
+ const ShHandle handle);
// Shader variable inspection.
// Returns a pointer to a list of variables of the designated type.
@@ -476,17 +372,17 @@ typedef struct
int size;
} ShVariableInfo;
-// Returns 1 if the passed in variables pack in maxVectors following
+// Returns true if the passed in variables pack in maxVectors following
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
-// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
+// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
// flag above.
// Parameters:
// maxVectors: the available rows of registers.
// varInfoArray: an array of variable info (types and sizes).
// varInfoArraySize: the size of the variable array.
-COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
+COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
int maxVectors,
- ShVariableInfo* varInfoArray,
+ ShVariableInfo *varInfoArray,
size_t varInfoArraySize);
// Gives the compiler-assigned register for an interface block.
@@ -497,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
// interfaceBlockName: Specifies the interface block
// indexOut: output variable that stores the assigned register
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
- const char *interfaceBlockName,
+ const std::string &interfaceBlockName,
unsigned int *indexOut);
// Gives the compiler-assigned register for uniforms in the default
@@ -509,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
// interfaceBlockName: Specifies the uniform
// indexOut: output variable that stores the assigned register
COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
- const char *uniformName,
+ const std::string &uniformName,
unsigned int *indexOut);
-#ifdef __cplusplus
-}
-#endif
-
#endif // _COMPILER_INTERFACE_INCLUDED_
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
index 9c38647dda..da21c3e76e 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
@@ -52,6 +52,21 @@ struct COMPILER_EXPORT ShaderVariable
unsigned int elementCount() const { return std::max(1u, arraySize); }
bool isStruct() const { return !fields.empty(); }
+ // All of the shader's variables are described using nested data
+ // structures. This is needed in order to disambiguate similar looking
+ // types, such as two structs containing the same fields, but in
+ // different orders. "findInfoByMappedName" provides an easy query for
+ // users to dive into the data structure and fetch the unique variable
+ // instance corresponding to a dereferencing chain of the top-level
+ // variable.
+ // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
+ // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
+ // in |originalName|, based on the assumption that |this| defines 'a'.
+ // If no match is found, return false.
+ bool findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string* originalFullName) const;
+
GLenum type;
GLenum precision;
std::string name;
@@ -60,6 +75,16 @@ struct COMPILER_EXPORT ShaderVariable
bool staticUse;
std::vector<ShaderVariable> fields;
std::string structName;
+
+ protected:
+ bool isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision) const;
+
+ bool operator==(const ShaderVariable &other) const;
+ bool operator!=(const ShaderVariable &other) const
+ {
+ return !operator==(other);
+ }
};
struct COMPILER_EXPORT Uniform : public ShaderVariable
@@ -68,6 +93,16 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable
~Uniform();
Uniform(const Uniform &other);
Uniform &operator=(const Uniform &other);
+ bool operator==(const Uniform &other) const;
+ bool operator!=(const Uniform &other) const
+ {
+ return !operator==(other);
+ }
+
+ // Decide whether two uniforms are the same at shader link time,
+ // assuming one from vertex shader and the other from fragment shader.
+ // See GLSL ES Spec 3.00.3, sec 4.3.5.
+ bool isSameUniformAtLinkTime(const Uniform &other) const;
};
struct COMPILER_EXPORT Attribute : public ShaderVariable
@@ -76,6 +111,11 @@ struct COMPILER_EXPORT Attribute : public ShaderVariable
~Attribute();
Attribute(const Attribute &other);
Attribute &operator=(const Attribute &other);
+ bool operator==(const Attribute &other) const;
+ bool operator!=(const Attribute &other) const
+ {
+ return !operator==(other);
+ }
int location;
};
@@ -86,6 +126,18 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
~InterfaceBlockField();
InterfaceBlockField(const InterfaceBlockField &other);
InterfaceBlockField &operator=(const InterfaceBlockField &other);
+ bool operator==(const InterfaceBlockField &other) const;
+ bool operator!=(const InterfaceBlockField &other) const
+ {
+ return !operator==(other);
+ }
+
+ // Decide whether two InterfaceBlock fields are the same at shader
+ // link time, assuming one from vertex shader and the other from
+ // fragment shader.
+ // See GLSL ES Spec 3.00.3, sec 4.3.7.
+ bool isSameInterfaceBlockFieldAtLinkTime(
+ const InterfaceBlockField &other) const;
bool isRowMajorLayout;
};
@@ -94,8 +146,18 @@ struct COMPILER_EXPORT Varying : public ShaderVariable
{
Varying();
~Varying();
- Varying(const Varying &other);
+ Varying(const Varying &otherg);
Varying &operator=(const Varying &other);
+ bool operator==(const Varying &other) const;
+ bool operator!=(const Varying &other) const
+ {
+ return !operator==(other);
+ }
+
+ // Decide whether two varyings are the same at shader link time,
+ // assuming one from vertex shader and the other from fragment shader.
+ // See GLSL ES Spec 3.00.3, sec 4.3.9.
+ bool isSameVaryingAtLinkTime(const Varying &other) const;
InterpolationType interpolation;
bool isInvariant;
diff --git a/src/3rdparty/angle/include/angle_windowsstore.h b/src/3rdparty/angle/include/angle_windowsstore.h
new file mode 100644
index 0000000000..53ec93e037
--- /dev/null
+++ b/src/3rdparty/angle/include/angle_windowsstore.h
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// angle_windowsstore.h:
+
+#ifndef ANGLE_WINDOWSSTORE_H_
+#define ANGLE_WINDOWSSTORE_H_
+
+// The following properties can be set on the CoreApplication to support additional
+// ANGLE configuration options.
+//
+// The Visual Studio sample templates provided with this version of ANGLE have examples
+// of how to set these property values.
+
+//
+// Property: EGLNativeWindowTypeProperty
+// Type: IInspectable
+// Description: Set this property to specify the window type to use for creating a surface.
+// If this property is missing, surface creation will fail.
+//
+const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
+
+//
+// Property: EGLRenderSurfaceSizeProperty
+// Type: Size
+// Description: Set this property to specify a preferred size in pixels of the render surface.
+// The render surface size width and height must be greater than 0.
+// If this property is set, then the render surface size is fixed.
+// If this property is missing, a default behavior will be provided.
+// The default behavior uses the window size if a CoreWindow is specified or
+// the size of the SwapChainPanel control if one is specified.
+//
+const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
+
+#endif // ANGLE_WINDOWSSTORE_H_
diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h
index a2e761b131..08fc893c25 100644
--- a/src/3rdparty/angle/src/commit.h
+++ b/src/3rdparty/angle/src/commit.h
@@ -7,6 +7,6 @@
// This is a default commit hash header, when git is not available.
//
-#define ANGLE_COMMIT_HASH "abce76206141"
+#define ANGLE_COMMIT_HASH "30d6c255d238"
#define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2014-09-23 19:37:05 +0000"
+#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h
new file mode 100644
index 0000000000..c4a0e42bcc
--- /dev/null
+++ b/src/3rdparty/angle/src/common/NativeWindow.h
@@ -0,0 +1,82 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// NativeWindow.h: Defines NativeWindow, a class for managing and
+// performing operations on an EGLNativeWindowType.
+// It is used for HWND (Desktop Windows) and IInspectable objects
+//(Windows Store Applications).
+
+#ifndef COMMON_NATIVEWINDOW_H_
+#define COMMON_NATIVEWINDOW_H_
+
+#include <EGL/eglplatform.h>
+#include "common/debug.h"
+#include "common/platform.h"
+
+// DXGISwapChain and DXGIFactory are typedef'd to specific required
+// types. The HWND NativeWindow implementation requires IDXGISwapChain
+// and IDXGIFactory and the Windows Store NativeWindow
+// implementation requires IDXGISwapChain1 and IDXGIFactory2.
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+typedef IDXGISwapChain1 DXGISwapChain;
+typedef IDXGIFactory2 DXGIFactory;
+
+#include <wrl.h>
+#include <wrl/wrappers/corewrappers.h>
+#include <windows.applicationmodel.core.h>
+#include <memory>
+
+namespace rx
+{
+class InspectableNativeWindow;
+}
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+#else
+typedef IDXGISwapChain DXGISwapChain;
+typedef IDXGIFactory DXGIFactory;
+#endif
+
+namespace rx
+{
+
+class NativeWindow
+{
+public:
+ explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
+
+ bool initialize();
+ bool getClientRect(LPRECT rect);
+ bool isIconic();
+
+# if defined(ANGLE_ENABLE_D3D11)
+ typedef ID3D11Device Device;
+#else
+ typedef IDirect3DDevice9 Device;
+#endif
+ HRESULT createSwapChain(Device* device, DXGIFactory* factory,
+ DXGI_FORMAT format, UINT width, UINT height,
+ DXGISwapChain** swapChain);
+
+ inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
+ inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; }
+
+ private:
+ EGLNativeWindowType mWindow;
+ EGLNativeDisplayType mDisplay;
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ std::shared_ptr<InspectableNativeWindow> mImpl;
+#endif
+
+};
+
+bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
+}
+
+#endif // COMMON_NATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/common/angleutils.cpp b/src/3rdparty/angle/src/common/angleutils.cpp
index 2673abf30a..c1367c460a 100644
--- a/src/3rdparty/angle/src/common/angleutils.cpp
+++ b/src/3rdparty/angle/src/common/angleutils.cpp
@@ -5,26 +5,33 @@
//
#include "common/angleutils.h"
-
+#include "debug.h"
+#include <stdio.h>
#include <vector>
-std::string FormatString(const char *fmt, va_list vararg)
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
{
- static std::vector<char> buffer(512);
-
// Attempt to just print to the current buffer
- int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
- if (len < 0 || static_cast<size_t>(len) >= buffer.size())
+ int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
+ if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
{
// Buffer was not large enough, calculate the required size and resize the buffer
len = vsnprintf(NULL, 0, fmt, vararg);
- buffer.resize(len + 1);
+ outBuffer.resize(len + 1);
// Print again
- vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
+ len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
}
+ ASSERT(len >= 0);
+ return static_cast<size_t>(len);
+}
+
+std::string FormatString(const char *fmt, va_list vararg)
+{
+ static std::vector<char> buffer(512);
- return std::string(buffer.data(), len);
+ size_t len = FormatStringIntoVector(fmt, vararg, buffer);
+ return std::string(&buffer[0], len);
}
std::string FormatString(const char *fmt, ...)
diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h
index ddbbd5f501..b343ece5bc 100644
--- a/src/3rdparty/angle/src/common/angleutils.h
+++ b/src/3rdparty/angle/src/common/angleutils.h
@@ -17,6 +17,7 @@
#include <set>
#include <sstream>
#include <cstdarg>
+#include <vector>
// A macro to disallow the copy constructor and operator= functions
// This must be used in the private: declarations for a class
@@ -95,6 +96,13 @@ inline void StructZero(T *obj)
memset(obj, 0, sizeof(T));
}
+template <typename T>
+inline bool IsMaskFlagSet(T mask, T flag)
+{
+ // Handles multibit flags as well
+ return (mask & flag) == flag;
+}
+
inline const char* MakeStaticString(const std::string &str)
{
static std::set<std::string> strings;
@@ -132,9 +140,12 @@ inline std::string Str(int i)
return strstr.str();
}
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
+
std::string FormatString(const char *fmt, va_list vararg);
std::string FormatString(const char *fmt, ...);
+// snprintf is not defined with MSVC prior to to msvc14
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp
index dcad327564..5f55ff1e39 100644
--- a/src/3rdparty/angle/src/common/debug.cpp
+++ b/src/3rdparty/angle/src/common/debug.cpp
@@ -17,41 +17,211 @@
namespace gl
{
-#if defined(ANGLE_ENABLE_PERF)
-typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
-#else
-typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
-#endif
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+// Wraps the D3D9/D3D11 debug annotation functions.
+class DebugAnnotationWrapper
+{
+ public:
+ DebugAnnotationWrapper() { };
+ virtual ~DebugAnnotationWrapper() { };
+ virtual void beginEvent(const std::wstring &eventName) = 0;
+ virtual void endEvent() = 0;
+ virtual void setMarker(const std::wstring &markerName) = 0;
+ virtual bool getStatus() = 0;
+};
-static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
+#if defined(ANGLE_ENABLE_D3D9)
+class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
{
-#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
- std::string formattedMessage = FormatString(format, vararg);
+ public:
+ void beginEvent(const std::wstring &eventName)
+ {
+ D3DPERF_BeginEvent(0, eventName.c_str());
+ }
+
+ void endEvent()
+ {
+ D3DPERF_EndEvent();
+ }
+
+ void setMarker(const std::wstring &markerName)
+ {
+ D3DPERF_SetMarker(0, markerName.c_str());
+ }
+
+ bool getStatus()
+ {
+ return !!D3DPERF_GetStatus();
+ }
+};
+#endif // ANGLE_ENABLE_D3D9
+
+#if defined(ANGLE_ENABLE_D3D11)
+class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper
+{
+ public:
+
+ D3D11DebugAnnotationWrapper()
+ : mInitialized(false),
+ mD3d11Module(NULL),
+ mUserDefinedAnnotation(NULL)
+ {
+ // D3D11 devices can't be created during DllMain.
+ // We defer device creation until the object is actually used.
+ }
+
+ ~D3D11DebugAnnotationWrapper()
+ {
+ if (mInitialized)
+ {
+ SafeRelease(mUserDefinedAnnotation);
+ FreeLibrary(mD3d11Module);
+ }
+ }
+
+ virtual void beginEvent(const std::wstring &eventName)
+ {
+ initializeDevice();
+
+ mUserDefinedAnnotation->BeginEvent(eventName.c_str());
+ }
+
+ virtual void endEvent()
+ {
+ initializeDevice();
+
+ mUserDefinedAnnotation->EndEvent();
+ }
+
+ virtual void setMarker(const std::wstring &markerName)
+ {
+ initializeDevice();
+
+ mUserDefinedAnnotation->SetMarker(markerName.c_str());
+ }
+
+ virtual bool getStatus()
+ {
+ // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
+
+#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
+ // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
+ // This should only be called in DEBUG mode.
+ // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
+ IDXGraphicsAnalysis* graphicsAnalysis;
+ DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
+ bool underCapture = (graphicsAnalysis != NULL);
+ SafeRelease(graphicsAnalysis);
+ return underCapture;
#endif
-#if defined(ANGLE_ENABLE_PERF)
- if (perfActive())
+ // Otherwise, we have to return true here.
+ return true;
+ }
+
+ protected:
+
+ void initializeDevice()
{
- // The perf function only accepts wide strings, widen the ascii message
- static std::wstring wideMessage;
- if (wideMessage.capacity() < formattedMessage.length())
+ if (!mInitialized)
{
- wideMessage.reserve(formattedMessage.size());
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+ ASSERT(mD3d11Module);
+
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+ ASSERT(D3D11CreateDevice != NULL);
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+
+ ID3D11Device* device = NULL;
+ ID3D11DeviceContext* context = NULL;
+
+ HRESULT hr = E_FAIL;
+
+ // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
+ hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
+ ASSERT(SUCCEEDED(hr));
+
+ hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast<void**>(&mUserDefinedAnnotation));
+ ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL);
+
+ SafeRelease(device);
+ SafeRelease(context);
+
+ mInitialized = true;
}
+ }
+
+ bool mInitialized;
+ HMODULE mD3d11Module;
+ ID3DUserDefinedAnnotation* mUserDefinedAnnotation;
+};
+#endif // ANGLE_ENABLE_D3D11
+
+static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL;
+
+void InitializeDebugAnnotations()
+{
+#if defined(ANGLE_ENABLE_D3D9)
+ g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper();
+#elif defined(ANGLE_ENABLE_D3D11)
+ // If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer.
+ // However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations.
+ // The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext.
+ // This doesn't have to be the same DeviceContext that the renderer uses, though.
+ g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper();
+#endif
+}
+
+void UninitializeDebugAnnotations()
+{
+ if (g_DebugAnnotationWrapper != NULL)
+ {
+ SafeDelete(g_DebugAnnotationWrapper);
+ }
+}
+
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
- wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
+enum DebugTraceOutputType
+{
+ DebugTraceOutputTypeNone,
+ DebugTraceOutputTypeSetMarker,
+ DebugTraceOutputTypeBeginEvent
+};
+
+static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg)
+{
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ static std::vector<char> buffer(512);
- perfFunc(0, wideMessage.c_str());
+ if (perfActive())
+ {
+ size_t len = FormatStringIntoVector(format, vararg, buffer);
+ std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
+
+ switch (outputType)
+ {
+ case DebugTraceOutputTypeNone:
+ break;
+ case DebugTraceOutputTypeBeginEvent:
+ g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
+ break;
+ case DebugTraceOutputTypeSetMarker:
+ g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
+ break;
+ }
}
-#endif // ANGLE_ENABLE_PERF
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
-#if defined(ANGLE_ENABLE_TRACE)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
#if defined(NDEBUG)
- if (traceFileDebugOnly)
+ if (traceInDebugOnly)
{
return;
}
#endif // NDEBUG
+ std::string formattedMessage = FormatString(format, vararg);
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
if (file)
@@ -60,25 +230,29 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
file.flush();
}
-#endif // ANGLE_ENABLE_TRACE
+#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
+ OutputDebugStringA(formattedMessage.c_str());
+#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
+
+#endif // ANGLE_ENABLE_DEBUG_TRACE
}
-void trace(bool traceFileDebugOnly, const char *format, ...)
+void trace(bool traceInDebugOnly, const char *format, ...)
{
va_list vararg;
va_start(vararg, format);
-#if defined(ANGLE_ENABLE_PERF)
- output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
#else
- output(traceFileDebugOnly, NULL, format, vararg);
+ output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
#endif
va_end(vararg);
}
bool perfActive()
{
-#if defined(ANGLE_ENABLE_PERF)
- static bool active = D3DPERF_GetStatus() != 0;
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ static bool active = g_DebugAnnotationWrapper->getStatus();
return active;
#else
return false;
@@ -87,26 +261,28 @@ bool perfActive()
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
-#if defined(ANGLE_ENABLE_PERF)
-#if !defined(ANGLE_ENABLE_TRACE)
+#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
if (!perfActive())
{
return;
}
-#endif // !ANGLE_ENABLE_TRACE
+#endif // !ANGLE_ENABLE_DEBUG_TRACE
va_list vararg;
va_start(vararg, format);
- output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
+#else
+ output(true, DebugTraceOutputTypeNone, format, vararg);
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
va_end(vararg);
-#endif // ANGLE_ENABLE_PERF
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
-#if defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
if (perfActive())
{
- D3DPERF_EndEvent();
+ g_DebugAnnotationWrapper->endEvent();
}
#endif
}
diff --git a/src/3rdparty/angle/src/common/debug.h b/src/3rdparty/angle/src/common/debug.h
index bf2bca8f24..c177f51314 100644
--- a/src/3rdparty/angle/src/common/debug.h
+++ b/src/3rdparty/angle/src/common/debug.h
@@ -20,8 +20,8 @@
namespace gl
{
- // Outputs text to the debugging log
- void trace(bool traceFileDebugOnly, const char *format, ...);
+ // Outputs text to the debugging log, or the debugging window
+ void trace(bool traceInDebugOnly, const char *format, ...);
// Returns whether D3DPERF is active.
bool perfActive();
@@ -36,31 +36,34 @@ namespace gl
private:
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
};
+
+ void InitializeDebugAnnotations();
+ void UninitializeDebugAnnotations();
}
// A macro to output a trace of a function call and its arguments to the debugging log
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define TRACE(message, ...) (void(0))
#endif
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define FIXME(message, ...) (void(0))
#endif
// A macro to output a function call and its arguments to the debugging log, in case of error.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define ERR(message, ...) (void(0))
#endif
// A macro to log a performance event around a scope.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#if defined(_MSC_VER)
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
#else
@@ -83,7 +86,7 @@ namespace gl
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
#endif
-#ifndef ANGLE_ENABLE_TRACE
+#ifndef ANGLE_ENABLE_DEBUG_TRACE
#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
#else
#define UNUSED_TRACE_VARIABLE(variable)
@@ -128,7 +131,7 @@ namespace gl
#endif
// A macro functioning as a compile-time assert to validate constant conditions
-#if defined(_MSC_VER) && _MSC_VER >= 1600
+#if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GNUC__) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3))
#define META_ASSERT_MSG(condition, msg) static_assert(condition, msg)
#else
#define META_ASSERT_CONCAT(a, b) a ## b
diff --git a/src/3rdparty/angle/src/common/features.h b/src/3rdparty/angle/src/common/features.h
new file mode 100644
index 0000000000..b49a0ee852
--- /dev/null
+++ b/src/3rdparty/angle/src/common/features.h
@@ -0,0 +1,35 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#define ANGLE_DISABLED 0
+#define ANGLE_ENABLED 1
+
+// Feature defaults
+
+// Direct3D9EX
+// The "Debug This Pixel..." feature in PIX often fails when using the
+// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
+// machine, define "ANGLE_D3D9EX=0" in your project file.
+#if !defined(ANGLE_D3D9EX)
+#define ANGLE_D3D9EX ANGLE_ENABLED
+#endif
+
+// Vsync
+// ENABLED allows Vsync to be configured at runtime
+// DISABLED disallows Vsync
+#if !defined(ANGLE_VSYNC)
+#define ANGLE_VSYNC ANGLE_ENABLED
+#endif
+
+// Program binary loading
+#if !defined(ANGLE_PROGRAM_BINARY_LOAD)
+#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED
+#endif
+
+// Shader debug info
+#if !defined(ANGLE_SHADER_DEBUG_INFO)
+#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
+#endif
diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h
index 52f2bc1c0e..a1717892fd 100644
--- a/src/3rdparty/angle/src/common/mathutil.h
+++ b/src/3rdparty/angle/src/common/mathutil.h
@@ -109,7 +109,7 @@ inline unsigned int unorm(float x)
inline bool supportsSSE2()
{
-#ifdef ANGLE_PLATFORM_WINDOWS
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
static bool checked = false;
static bool supports = false;
@@ -118,7 +118,6 @@ inline bool supportsSSE2()
return supports;
}
-#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid()
int info[4];
__cpuid(info, 0);
@@ -128,7 +127,6 @@ inline bool supportsSSE2()
supports = (info[3] >> 26) & 1;
}
-#endif
checked = true;
diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
index b53394f337..5bf97f9184 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
@@ -11,9 +11,6 @@
#if defined(_WIN32) || defined(_WIN64)
# define ANGLE_PLATFORM_WINDOWS 1
-# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
-# define ANGLE_PLATFORM_WINRT 1
-# endif
#elif defined(__APPLE__)
# define ANGLE_PLATFORM_APPLE 1
# define ANGLE_PLATFORM_POSIX 1
@@ -37,6 +34,9 @@
#endif
#ifdef ANGLE_PLATFORM_WINDOWS
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+# define ANGLE_ENABLE_WINDOWS_STORE 1
+# endif
# ifndef STRICT
# define STRICT 1
# endif
@@ -50,8 +50,9 @@
# include <windows.h>
# include <intrin.h>
-# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
+# if defined(ANGLE_ENABLE_D3D9)
# include <d3d9.h>
+# include <dxgi.h>
# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
@@ -62,13 +63,26 @@
# include <d3d10.h>
# include <d3d11.h>
# include <dxgi.h>
-# if _MSC_VER >= 1700
+# if defined(_MSC_VER) && (_MSC_VER >= 1700)
+# include <d3d11_1.h>
# include <dxgi1_2.h>
# endif
# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
-# if defined(__MINGW32__)
+# endif
+
+# if defined(ANGLE_ENABLE_WINDOWS_STORE)
+# include <dxgi1_3.h>
+# if defined(_DEBUG)
+# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+# include <DXProgrammableCapture.h>
+# endif
+# include <dxgidebug.h>
+# endif
+# endif
+
+# if defined(__MINGW32__) // Missing defines on MinGW
typedef enum D3D11_MAP_FLAG
{
D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
@@ -78,8 +92,68 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS
UINT64 NumPrimitivesWritten;
UINT64 PrimitivesStorageNeeded;
} D3D11_QUERY_DATA_SO_STATISTICS;
-# endif
-# endif
+typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)(
+ IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *,
+ UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
+#define D3D11_MESSAGE_CATEGORY UINT
+#define D3D11_MESSAGE_SEVERITY UINT
+#define D3D11_MESSAGE_ID UINT
+struct D3D11_MESSAGE;
+typedef struct D3D11_INFO_QUEUE_FILTER_DESC
+{
+ UINT NumCategories;
+ D3D11_MESSAGE_CATEGORY *pCategoryList;
+ UINT NumSeverities;
+ D3D11_MESSAGE_SEVERITY *pSeverityList;
+ UINT NumIDs;
+ D3D11_MESSAGE_ID *pIDList;
+} D3D11_INFO_QUEUE_FILTER_DESC;
+typedef struct D3D11_INFO_QUEUE_FILTER
+{
+ D3D11_INFO_QUEUE_FILTER_DESC AllowList;
+ D3D11_INFO_QUEUE_FILTER_DESC DenyList;
+} D3D11_INFO_QUEUE_FILTER;
+static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
+MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
+{
+public:
+ virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
+ virtual void __stdcall ClearStoredMessages() = 0;
+ virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
+ virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
+ virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
+ virtual UINT64 __stdcall GetNumStoredMessages() = 0;
+ virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
+ virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
+ virtual UINT64 __stdcall GetMessageCountLimit() = 0;
+ virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
+ virtual void __stdcall ClearStorageFilter() = 0;
+ virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
+ virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
+ virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual void __stdcall PopStorageFilter() = 0;
+ virtual UINT __stdcall GetStorageFilterStackSize() = 0;
+ virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
+ virtual void __stdcall ClearRetrievalFilter() = 0;
+ virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
+ virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
+ virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual void __stdcall PopRetrievalFilter() = 0;
+ virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
+ virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
+ virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
+ virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
+ virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
+ virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
+ virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
+ virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
+ virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
+ virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
+ virtual BOOL __stdcall GetMuteDebugOutput() = 0;
+};
+#endif // __MINGW32__
# undef near
# undef far
diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp
index c46fab5303..cb1b32d325 100644
--- a/src/3rdparty/angle/src/common/tls.cpp
+++ b/src/3rdparty/angle/src/common/tls.cpp
@@ -10,29 +10,50 @@
#include <assert.h>
-#if defined(ANGLE_PLATFORM_WINRT)
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
#include <vector>
-std::vector<void *> *tls = nullptr;
-std::vector<TLSIndex> *freeIndices = nullptr;
+#include <set>
+#include <map>
+#include <mutex>
+
+#include <wrl/client.h>
+#include <wrl/async.h>
+#include <Windows.System.Threading.h>
+
+using namespace std;
+using namespace Windows::Foundation;
+using namespace ABI::Windows::System::Threading;
+
+// Thread local storage for Windows Store support
+typedef vector<void*> ThreadLocalData;
+
+static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
+static set<ThreadLocalData*> allThreadData;
+static DWORD nextTlsIndex = 0;
+static vector<DWORD> freeTlsIndices;
+
#endif
TLSIndex CreateTLSIndex()
{
TLSIndex index;
-#if defined(ANGLE_PLATFORM_WINRT)
- if (!tls)
- tls = new std::vector<void *>;
- if (freeIndices && !freeIndices->empty()) {
- index = freeIndices->back();
- freeIndices->pop_back();
- return index;
- } else {
- tls->push_back(nullptr);
- return tls->size() - 1;
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ if (!freeTlsIndices.empty())
+ {
+ DWORD result = freeTlsIndices.back();
+ freeTlsIndices.pop_back();
+ index = result;
}
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+ else
+ {
+ index = nextTlsIndex++;
+ }
+#else
index = TlsAlloc();
+#endif
+
#elif defined(ANGLE_PLATFORM_POSIX)
// Create global pool key
if ((pthread_key_create(&index, NULL)) != 0)
@@ -53,13 +74,23 @@ bool DestroyTLSIndex(TLSIndex index)
return false;
}
-#if defined(ANGLE_PLATFORM_WINRT)
- if (!freeIndices)
- freeIndices = new std::vector<TLSIndex>;
- freeIndices->push_back(index);
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ assert(index < nextTlsIndex);
+ assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
+
+ freeTlsIndices.push_back(index);
+ for (auto threadData : allThreadData)
+ {
+ if (threadData->size() > index)
+ {
+ threadData->at(index) = nullptr;
+ }
+ }
return true;
-#elif ANGLE_PLATFORM_WINDOWS
+#else
return (TlsFree(index) == TRUE);
+#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return (pthread_key_delete(index) == 0);
#endif
@@ -73,11 +104,25 @@ bool SetTLSValue(TLSIndex index, void *value)
return false;
}
-#if defined(ANGLE_PLATFORM_WINRT)
- tls->at(index) = value;
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ ThreadLocalData* threadData = currentThreadData;
+ if (!threadData)
+ {
+ threadData = new ThreadLocalData(index + 1, nullptr);
+ allThreadData.insert(threadData);
+ currentThreadData = threadData;
+ }
+ else if (threadData->size() <= index)
+ {
+ threadData->resize(index + 1, nullptr);
+ }
+
+ threadData->at(index) = value;
return true;
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#else
return (TlsSetValue(index, value) == TRUE);
+#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return (pthread_setspecific(index, value) == 0);
#endif
@@ -85,18 +130,26 @@ bool SetTLSValue(TLSIndex index, void *value)
void *GetTLSValue(TLSIndex index)
{
-#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation
assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
-#endif
if (index == TLS_INVALID_INDEX)
{
return NULL;
}
-#if defined(ANGLE_PLATFORM_WINRT)
- return tls->at(index);
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ ThreadLocalData* threadData = currentThreadData;
+ if (threadData && threadData->size() > index)
+ {
+ return threadData->at(index);
+ }
+ else
+ {
+ return nullptr;
+ }
+#else
return TlsGetValue(index);
+#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return pthread_getspecific(index);
#endif
diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h
index c40ae1a061..8a06e92d1a 100644
--- a/src/3rdparty/angle/src/common/tls.h
+++ b/src/3rdparty/angle/src/common/tls.h
@@ -11,11 +11,15 @@
#include "common/platform.h"
-#if defined(ANGLE_PLATFORM_WINRT)
- typedef size_t TLSIndex;
-# define TLS_OUT_OF_INDEXES (static_cast<TLSIndex>(-1))
-# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#ifdef ANGLE_PLATFORM_WINDOWS
+
+// TLS does not exist for Windows Store and needs to be emulated
+# ifdef ANGLE_ENABLE_WINDOWS_STORE
+# define TLS_OUT_OF_INDEXES -1
+# ifndef CREATE_SUSPENDED
+# define CREATE_SUSPENDED 0x00000004
+# endif
+# endif
typedef DWORD TLSIndex;
# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
#elif defined(ANGLE_PLATFORM_POSIX)
@@ -28,6 +32,9 @@
# error Unsupported platform.
#endif
+// TODO(kbr): for POSIX platforms this will have to be changed to take
+// in a destructor function pointer, to allow the thread-local storage
+// to be properly deallocated upon thread exit.
TLSIndex CreateTLSIndex();
bool DestroyTLSIndex(TLSIndex index);
diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp
index 4b8e325d22..9d797a6612 100644
--- a/src/3rdparty/angle/src/common/utilities.cpp
+++ b/src/3rdparty/angle/src/common/utilities.cpp
@@ -9,17 +9,16 @@
#include "common/utilities.h"
#include "common/mathutil.h"
#include "common/platform.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-# include <locale>
-# include <codecvt>
-# include <wrl.h>
-# include <windows.storage.h>
- using namespace Microsoft::WRL;
- using namespace ABI::Windows::Storage;
-#endif
#include <set>
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+# include <wrl.h>
+# include <wrl/wrappers/corewrappers.h>
+# include <windows.applicationmodel.core.h>
+# include <windows.graphics.display.h>
+#endif
+
namespace gl
{
@@ -447,50 +446,10 @@ int VariableSortOrder(GLenum type)
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- static std::string path;
-
- while (path.empty())
- {
- ComPtr<IApplicationDataStatics> factory;
- Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData);
- HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory));
- if (FAILED(result))
- break;
-
- ComPtr<IApplicationData> applicationData;
- result = factory->get_Current(&applicationData);
- if (FAILED(result))
- break;
-
- ComPtr<IStorageFolder> storageFolder;
- result = applicationData->get_LocalFolder(&storageFolder);
- if (FAILED(result))
- break;
-
- ComPtr<IStorageItem> localFolder;
- result = storageFolder.As(&localFolder);
- if (FAILED(result))
- break;
-
- HSTRING localFolderPath;
- result = localFolder->get_Path(&localFolderPath);
- if (FAILED(result))
- break;
-
- std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
- path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
- if (path.empty())
- {
- UNREACHABLE();
- break;
- }
- }
-
- return path;
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#ifdef ANGLE_PLATFORM_WINDOWS
char path[MAX_PATH];
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
if (pathLen == 0)
@@ -525,3 +484,33 @@ void writeFile(const char* path, const void* content, size_t size)
fwrite(content, sizeof(char), size, file);
fclose(file);
}
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+
+void Sleep(unsigned long dwMilliseconds)
+{
+ static HANDLE singletonEvent = nullptr;
+ HANDLE sleepEvent = singletonEvent;
+ if (!sleepEvent)
+ {
+ sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+
+ if (!sleepEvent)
+ return;
+
+ HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
+
+ if (previousEvent)
+ {
+ // Back out if multiple threads try to demand create at the same time.
+ CloseHandle(sleepEvent);
+ sleepEvent = previousEvent;
+ }
+ }
+
+ // Emulate sleep by waiting with timeout on an event that is never signalled.
+ WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
+}
+
+#endif // ANGLE_ENABLE_WINDOWS_STORE
diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h
index a823184ecd..2cf6bed176 100644
--- a/src/3rdparty/angle/src/common/utilities.h
+++ b/src/3rdparty/angle/src/common/utilities.h
@@ -46,7 +46,13 @@ template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
+#endif
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+void Sleep(_In_ unsigned long dwMilliseconds);
+#endif
#endif // LIBGLESV2_UTILITIES_H
diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
new file mode 100644
index 0000000000..46082a2e28
--- /dev/null
+++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// NativeWindow.cpp: Handler for managing HWND native window types.
+
+#include "common/NativeWindow.h"
+#include "common/debug.h"
+
+namespace rx
+{
+bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
+{
+ return (IsWindow(window) == TRUE);
+}
+
+NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display)
+{
+}
+
+bool NativeWindow::initialize()
+{
+ return true;
+}
+
+bool NativeWindow::getClientRect(LPRECT rect)
+{
+ return GetClientRect(mWindow, rect) == TRUE;
+}
+
+bool NativeWindow::isIconic()
+{
+ return IsIconic(mWindow) == TRUE;
+}
+
+HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory,
+ DXGI_FORMAT format, unsigned int width, unsigned int height,
+ DXGISwapChain** swapChain)
+{
+ if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.BufferDesc.Format = format;
+ swapChainDesc.BufferDesc.Width = width;
+ swapChainDesc.BufferDesc.Height = height;
+ swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.Flags = 0;
+ swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+ return factory->CreateSwapChain(device, &swapChainDesc, swapChain);
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
new file mode 100644
index 0000000000..9b65c15625
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
@@ -0,0 +1,200 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
+
+#include <algorithm>
+#include "common/winrt/CoreWindowNativeWindow.h"
+using namespace ABI::Windows::Foundation::Collections;
+
+namespace rx
+{
+
+typedef ITypedEventHandler<ABI::Windows::UI::Core::CoreWindow *, ABI::Windows::UI::Core::WindowSizeChangedEventArgs *> SizeChangedHandler;
+
+CoreWindowNativeWindow::~CoreWindowNativeWindow()
+{
+ unregisterForSizeChangeEvents();
+}
+
+bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+{
+ ComPtr<IPropertySet> props = propertySet;
+ ComPtr<IInspectable> win = window;
+ ComPtr<IInspectable> displayInformation = display;
+ SIZE swapChainSize = {};
+ bool swapChainSizeSpecified = false;
+ HRESULT result = S_OK;
+
+ // IPropertySet is an optional parameter and can be null.
+ // If one is specified, cache as an IMap and read the properties
+ // used for initial host initialization.
+ if (propertySet)
+ {
+ result = props.As(&mPropertyMap);
+ if (SUCCEEDED(result))
+ {
+ // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = win.As(&mCoreWindow);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = displayInformation.As(&mDisplayInformation);
+ }
+
+ if (SUCCEEDED(result))
+ {
+#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation2> displayInformation2;
+ result = mDisplayInformation.As(&displayInformation2);
+ ASSERT(SUCCEEDED(result));
+
+ result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
+ ASSERT(SUCCEEDED(result));
+#else
+ ABI::Windows::Graphics::Display::ResolutionScale resolutionScale;
+ result = mDisplayInformation->get_ResolutionScale(&resolutionScale);
+ ASSERT(SUCCEEDED(result));
+
+ mScaleFactor = DOUBLE(resolutionScale) / 100.0;
+#endif
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // If a swapchain size is specfied, then the automatic resize
+ // behaviors implemented by the host should be disabled. The swapchain
+ // will be still be scaled when being rendered to fit the bounds
+ // of the host.
+ // Scaling of the swapchain output occurs automatically because if
+ // the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
+ if (swapChainSizeSpecified)
+ {
+ mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
+ mSupportsSwapChainResize = false;
+ }
+ else
+ {
+ ABI::Windows::Foundation::Rect rect;
+ HRESULT result = mCoreWindow->get_Bounds(&rect);
+ if (SUCCEEDED(result))
+ {
+ LONG width = std::floor(rect.Width * mScaleFactor + 0.5);
+ LONG height = std::floor(rect.Height * mScaleFactor + 0.5);
+ mClientRect = { 0, 0, width, height };
+ }
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ mNewClientRect = mClientRect;
+ mClientRectChanged = false;
+ return registerForSizeChangeEvents();
+ }
+
+ return false;
+}
+
+bool CoreWindowNativeWindow::registerForSizeChangeEvents()
+{
+ HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
+ &mSizeChangedEventToken);
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
+{
+ if (mCoreWindow)
+ {
+ (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
+ }
+ mSizeChangedEventToken.value = 0;
+}
+
+HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+ if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+
+ *swapChain = nullptr;
+
+ ComPtr<IDXGISwapChain1> newSwapChain;
+ HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
+ if (SUCCEEDED(result))
+ {
+
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected
+ // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
+ // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
+ // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
+ if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED)
+ {
+ mSupportsSwapChainResize = false;
+ }
+#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+
+ result = newSwapChain.CopyTo(swapChain);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // If automatic swapchain resize behaviors have been disabled, then
+ // unregister for the resize change events.
+ if (mSupportsSwapChainResize == false)
+ {
+ unregisterForSizeChangeEvents();
+ }
+ }
+
+ return result;
+}
+
+// Basically, this shouldn't be used on Phone
+HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
+{
+ ABI::Windows::Foundation::Size size;
+ if (SUCCEEDED(e->get_Size(&size)))
+ {
+ SIZE windowSizeInPixels = {
+ std::floor(size.Width * mScaleFactor + 0.5),
+ std::floor(size.Height * mScaleFactor + 0.5)
+ };
+ setNewClientSize(windowSizeInPixels);
+ }
+
+ return S_OK;
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
new file mode 100644
index 0000000000..1c5512417d
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
+
+#ifndef COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
+#define COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
+
+#include "common/winrt/InspectableNativeWindow.h"
+#include <memory>
+#include <windows.graphics.display.h>
+
+namespace rx
+{
+
+class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
+{
+ public:
+ ~CoreWindowNativeWindow();
+
+ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
+ bool registerForSizeChangeEvents();
+ void unregisterForSizeChangeEvents();
+ HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+
+ private:
+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
+
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
+ ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
+};
+
+}
+
+#endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
new file mode 100644
index 0000000000..0589f6dce5
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
@@ -0,0 +1,274 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InspectableNativeWindow.cpp: NativeWindow base class for managing IInspectable native window types.
+
+#include "common/winrt/CoreWindowNativeWindow.h"
+#include "common/winrt/SwapChainPanelNativeWindow.h"
+
+namespace rx
+{
+NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
+ : mWindow(window), mDisplay(display)
+{
+}
+
+bool NativeWindow::initialize()
+{
+ // If the native window type is a IPropertySet, extract the
+ // EGLNativeWindowType (IInspectable) and initialize the
+ // proper host with this IPropertySet.
+ ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
+ ComPtr<IInspectable> eglNativeWindow;
+ if (IsEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow))
+ {
+ // A property set was found and the EGLNativeWindowType was
+ // retrieved. The mWindow member of the host to must be updated
+ // to use the EGLNativeWindowType specified in the property set.
+ // mWindow is treated as a raw pointer not an AddRef'd interface, so
+ // the old mWindow does not need a Release() before this assignment.
+ mWindow = eglNativeWindow.Get();
+ }
+
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
+ if (IsCoreWindow(mWindow, &coreWindow))
+ {
+ mImpl = std::make_shared<CoreWindowNativeWindow>();
+ if (mImpl)
+ {
+ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ }
+ }
+ else if (IsSwapChainPanel(mWindow, &swapChainPanel))
+ {
+ mImpl = std::make_shared<SwapChainPanelNativeWindow>();
+ if (mImpl)
+ {
+ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ }
+ }
+ else
+ {
+ ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow, ISwapChainPanel and IPropertySet");
+ }
+
+ return false;
+}
+
+bool NativeWindow::getClientRect(RECT *rect)
+{
+ if (mImpl)
+ {
+ return mImpl->getClientRect(rect);
+ }
+
+ return false;
+}
+
+bool NativeWindow::isIconic()
+{
+ return false;
+}
+
+HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+ if (mImpl)
+ {
+ return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
+ }
+
+ return E_UNEXPECTED;
+}
+
+bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
+{
+ if (!window)
+ {
+ return false;
+ }
+
+ ComPtr<IInspectable> win = window;
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
+ if (SUCCEEDED(win.As(&coreWin)))
+ {
+ if (coreWindow != nullptr)
+ {
+ *coreWindow = coreWin.Detach();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel)
+{
+ if (!window)
+ {
+ return false;
+ }
+
+ ComPtr<IInspectable> win = window;
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> panel;
+ if (SUCCEEDED(win.As(&panel)))
+ {
+ if (swapChainPanel != nullptr)
+ {
+ *swapChainPanel = panel.Detach();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow)
+{
+ if (!window)
+ {
+ return false;
+ }
+
+ ComPtr<IInspectable> props = window;
+ ComPtr<IPropertySet> propSet;
+ ComPtr<IInspectable> nativeWindow;
+ ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> propMap;
+ boolean hasEglNativeWindowPropertyKey = false;
+
+ HRESULT result = props.As(&propSet);
+ if (SUCCEEDED(result))
+ {
+ result = propSet.As(&propMap);
+ }
+
+ // Look for the presence of the EGLNativeWindowType in the property set
+ if (SUCCEEDED(result))
+ {
+ result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey);
+ }
+
+ // If the IPropertySet does not contain the required EglNativeWindowType key, the property set is
+ // considered invalid.
+ if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
+ {
+ ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
+ return false;
+ }
+
+ // The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType
+ if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
+ {
+ result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ if (propertySet != nullptr)
+ {
+ result = propSet.CopyTo(propertySet);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ if (eglNativeWindow != nullptr)
+ {
+ result = nativeWindow.CopyTo(eglNativeWindow);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// A Valid EGLNativeWindowType IInspectable can only be:
+//
+// ICoreWindow
+// IPropertySet
+//
+// Anything else will be rejected as an invalid IInspectable.
+bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
+{
+ return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window);
+}
+
+// Attempts to read an optional SIZE property value that is assumed to be in the form of
+// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
+// it to the caller.
+//
+// Possible return values are:
+// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
+// S_OK, valueExists == false - optional SIZE value was not found
+// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
+// * Incorrect property type ( must be PropertyType_Size)
+// * Invalid property value (width/height must be > 0)
+// Additional errors may be returned from IMap or IPropertyValue
+//
+HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
+{
+ if (!propertyMap || !propertyName || !value || !valueExists)
+ {
+ return false;
+ }
+
+ // Assume that the value does not exist
+ *valueExists = false;
+ *value = { 0, 0 };
+
+ ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
+ ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
+ Size sizeValue = { 0, 0 };
+ boolean hasKey = false;
+
+ HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
+ if (SUCCEEDED(result) && !hasKey)
+ {
+ // Value does not exist, so return S_OK and set the exists parameter to false to indicate
+ // that a the optional property does not exist.
+ *valueExists = false;
+ return S_OK;
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = propertyValue->get_Type(&propertyType);
+ }
+
+ // Check if the expected Size property is of PropertyType_Size type.
+ if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
+ {
+ if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
+ {
+ // A valid property value exists
+ *value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
+ *valueExists = true;
+ result = S_OK;
+ }
+ else
+ {
+ // An invalid Size property was detected. Width/Height values must > 0
+ result = E_INVALIDARG;
+ }
+ }
+ else
+ {
+ // An invalid property type was detected. Size property must be of PropertyType_Size
+ result = E_INVALIDARG;
+ }
+
+ return result;
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
new file mode 100644
index 0000000000..402941a788
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InspectableNativeWindow.h: Host specific implementation interface for
+// managing IInspectable native window types.
+
+#ifndef COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
+#define COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
+
+#include "common/platform.h"
+#include "common/NativeWindow.h"
+#include "angle_windowsstore.h"
+
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.media.dxinterop.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+namespace rx
+{
+class InspectableNativeWindow
+{
+ public:
+ InspectableNativeWindow() :
+ mSupportsSwapChainResize(true),
+ mRequiresSwapChainScaling(false),
+ mClientRectChanged(false),
+ mClientRect({0,0,0,0}),
+ mNewClientRect({0,0,0,0}),
+ mScaleFactor(1.0)
+ {
+ mSizeChangedEventToken.value = 0;
+ }
+ virtual ~InspectableNativeWindow(){}
+
+ virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0;
+ virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
+ virtual bool registerForSizeChangeEvents() = 0;
+ virtual void unregisterForSizeChangeEvents() = 0;
+ virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
+
+ bool getClientRect(RECT *rect)
+ {
+ if (mClientRectChanged && mSupportsSwapChainResize)
+ {
+ mClientRect = mNewClientRect;
+ mClientRectChanged = false;
+ }
+
+ *rect = mClientRect;
+
+ return true;
+ }
+
+ void setNewClientSize(const SIZE &newSize)
+ {
+ if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
+ {
+ mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
+ mClientRectChanged = true;
+ }
+
+ if (mRequiresSwapChainScaling)
+ {
+ scaleSwapChain(newSize);
+ }
+ }
+
+protected:
+ bool mSupportsSwapChainResize;
+ bool mRequiresSwapChainScaling;
+ RECT mClientRect;
+ RECT mNewClientRect;
+ bool mClientRectChanged;
+ DOUBLE mScaleFactor;
+
+ EventRegistrationToken mSizeChangedEventToken;
+};
+
+bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
+bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
+bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
+HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
+}
+#endif // COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
new file mode 100644
index 0000000000..268dfbd8f0
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
@@ -0,0 +1,226 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types.
+
+#include "common/winrt/SwapChainPanelNativeWindow.h"
+#include <algorithm>
+#include <math.h>
+using namespace ABI::Windows::Foundation::Collections;
+
+namespace rx
+{
+SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
+{
+ unregisterForSizeChangeEvents();
+}
+
+bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+{
+ ComPtr<IPropertySet> props = propertySet;
+ ComPtr<IInspectable> win = window;
+ SIZE swapChainSize = {};
+ bool swapChainSizeSpecified = false;
+ HRESULT result = S_OK;
+
+ // IPropertySet is an optional parameter and can be null.
+ // If one is specified, cache as an IMap and read the properties
+ // used for initial host initialization.
+ if (propertySet)
+ {
+ result = props.As(&mPropertyMap);
+ if (SUCCEEDED(result))
+ {
+ // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = win.As(&mSwapChainPanel);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // If a swapchain size is specfied, then the automatic resize
+ // behaviors implemented by the host should be disabled. The swapchain
+ // will be still be scaled when being rendered to fit the bounds
+ // of the host.
+ // Scaling of the swapchain output needs to be handled by the
+ // host for swapchain panels even though the scaling mode setting
+ // DXGI_SCALING_STRETCH is configured on the swapchain.
+ if (swapChainSizeSpecified)
+ {
+ mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
+
+ // Enable host swapchain scaling
+ mRequiresSwapChainScaling = true;
+ }
+ else
+ {
+ result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ mNewClientRect = mClientRect;
+ mClientRectChanged = false;
+ return registerForSizeChangeEvents();
+ }
+
+ return false;
+}
+
+bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
+{
+ ComPtr<ABI::Windows::UI::Xaml::ISizeChangedEventHandler> sizeChangedHandler;
+ ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
+ HRESULT result = Microsoft::WRL::MakeAndInitialize<SwapChainPanelSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
+
+ if (SUCCEEDED(result))
+ {
+ result = mSwapChainPanel.As(&frameworkElement);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents()
+{
+ ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
+ if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
+ {
+ (void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
+ }
+
+ mSizeChangedEventToken.value = 0;
+}
+
+HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+ if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+
+ *swapChain = nullptr;
+
+ ComPtr<IDXGISwapChain1> newSwapChain;
+ ComPtr<ISwapChainPanelNative> swapChainPanelNative;
+ RECT currentPanelSize = {};
+
+ HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
+
+ if (SUCCEEDED(result))
+ {
+ result = mSwapChainPanel.As(&swapChainPanelNative);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = swapChainPanelNative->SetSwapChain(newSwapChain.Get());
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // The swapchain panel host requires an instance of the swapchain set on the SwapChainPanel
+ // to perform the runtime-scale behavior. This swapchain is cached here because there are
+ // no methods for retreiving the currently configured on from ISwapChainPanelNative.
+ mSwapChain = newSwapChain;
+ result = newSwapChain.CopyTo(swapChain);
+ }
+
+ // If the host is responsible for scaling the output of the swapchain, then
+ // scale it now before returning an instance to the caller. This is done by
+ // first reading the current size of the swapchain panel, then scaling
+ if (SUCCEEDED(result) && mRequiresSwapChainScaling)
+ {
+ result = GetSwapChainPanelSize(mSwapChainPanel, &currentPanelSize);
+ }
+
+ // Scale the swapchain to fit inside the contents of the panel.
+ if (SUCCEEDED(result) && mRequiresSwapChainScaling)
+ {
+ SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
+ result = scaleSwapChain(currentSize);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // If automatic swapchain resize behaviors have been disabled, then
+ // unregister for the resize change events.
+ if (mSupportsSwapChainResize == false)
+ {
+ unregisterForSizeChangeEvents();
+ }
+ }
+
+ return result;
+}
+
+HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
+{
+ ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
+ // Setup a scale matrix for the swap chain
+ DXGI_MATRIX_3X2_F scaleMatrix = {};
+ scaleMatrix._11 = renderScale.Width;
+ scaleMatrix._22 = renderScale.Height;
+
+ ComPtr<IDXGISwapChain2> swapChain2;
+ HRESULT result = mSwapChain.As(&swapChain2);
+ if (SUCCEEDED(result))
+ {
+ result = swapChain2->SetMatrixTransform(&scaleMatrix);
+ }
+
+ return result;
+}
+
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
+{
+ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
+ ABI::Windows::Foundation::Size renderSize = { 0, 0 };
+ HRESULT result = swapChainPanel.As(&uiElement);
+ if (SUCCEEDED(result))
+ {
+ result = uiElement->get_RenderSize(&renderSize);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
+ }
+
+ return result;
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
new file mode 100644
index 0000000000..5bbf274e64
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types.
+
+#ifndef COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+#define COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+
+#include "common/winrt/InspectableNativeWindow.h"
+
+namespace rx
+{
+class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<SwapChainPanelNativeWindow>
+{
+ public:
+ ~SwapChainPanelNativeWindow();
+
+ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
+ bool registerForSizeChangeEvents();
+ void unregisterForSizeChangeEvents();
+ HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+ HRESULT scaleSwapChain(const SIZE &newSize);
+
+ private:
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
+ ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
+ ComPtr<DXGISwapChain> mSwapChain;
+};
+
+[uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)]
+class SwapChainPanelSizeChangedHandler :
+ public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ABI::Windows::UI::Xaml::ISizeChangedEventHandler>
+{
+ public:
+ SwapChainPanelSizeChangedHandler() { }
+ HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
+ {
+ if (!host)
+ {
+ return E_INVALIDARG;
+ }
+
+ mHost = host;
+ return S_OK;
+ }
+
+ // ISizeChangedEventHandler
+ IFACEMETHOD(Invoke)(IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs)
+ {
+ std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
+ if (host)
+ {
+ // The size of the ISwapChainPanel control is returned in DIPs.
+ // We are keeping these in dips because the swapchain created for composition
+ // also uses dip units. This keeps dimensions, viewports, etc in the same unit.
+ // XAML Clients of the ISwapChainPanel are required to use dips to define their
+ // layout sizes as well.
+ ABI::Windows::Foundation::Size newSize;
+ HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
+ if (SUCCEEDED(result))
+ {
+ SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
+ host->setNewClientSize(windowSize);
+ }
+ }
+
+ return S_OK;
+ }
+
+ private:
+ std::weak_ptr<InspectableNativeWindow> mHost;
+};
+
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
+}
+#endif // COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
index 040b25c6a2..eec0d5e5f0 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
@@ -29,7 +29,8 @@ class DirectiveHandler
// Handle pragma of form: #pragma name[(value)]
virtual void handlePragma(const SourceLocation &loc,
const std::string &name,
- const std::string &value) = 0;
+ const std::string &value,
+ bool stdgl) = 0;
virtual void handleExtension(const SourceLocation &loc,
const std::string &name,
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
index 6434d5cb5c..7803ee845a 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -38,19 +38,19 @@ enum DirectiveType
DirectiveType getDirective(const pp::Token *token)
{
- static const std::string kDirectiveDefine("define");
- static const std::string kDirectiveUndef("undef");
- static const std::string kDirectiveIf("if");
- static const std::string kDirectiveIfdef("ifdef");
- static const std::string kDirectiveIfndef("ifndef");
- static const std::string kDirectiveElse("else");
- static const std::string kDirectiveElif("elif");
- static const std::string kDirectiveEndif("endif");
- static const std::string kDirectiveError("error");
- static const std::string kDirectivePragma("pragma");
- static const std::string kDirectiveExtension("extension");
- static const std::string kDirectiveVersion("version");
- static const std::string kDirectiveLine("line");
+ const char kDirectiveDefine[] = "define";
+ const char kDirectiveUndef[] = "undef";
+ const char kDirectiveIf[] = "if";
+ const char kDirectiveIfdef[] = "ifdef";
+ const char kDirectiveIfndef[] = "ifndef";
+ const char kDirectiveElse[] = "else";
+ const char kDirectiveElif[] = "elif";
+ const char kDirectiveEndif[] = "endif";
+ const char kDirectiveError[] = "error";
+ const char kDirectivePragma[] = "pragma";
+ const char kDirectiveExtension[] = "extension";
+ const char kDirectiveVersion[] = "version";
+ const char kDirectiveLine[] = "line";
if (token->type != pp::Token::IDENTIFIER)
return DIRECTIVE_NONE;
@@ -155,7 +155,7 @@ class DefinedParser : public Lexer
protected:
virtual void lex(Token *token)
{
- static const std::string kDefined("defined");
+ const char kDefined[] = "defined";
mLexer->lex(token);
if (token->type != Token::IDENTIFIER)
@@ -592,6 +592,11 @@ void DirectiveParser::parsePragma(Token *token)
int state = PRAGMA_NAME;
mTokenizer->lex(token);
+ bool stdgl = token->text == "STDGL";
+ if (stdgl)
+ {
+ mTokenizer->lex(token);
+ }
while ((token->type != '\n') && (token->type != Token::LAST))
{
switch(state++)
@@ -627,7 +632,7 @@ void DirectiveParser::parsePragma(Token *token)
}
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
{
- mDirectiveHandler->handlePragma(token->location, name, value);
+ mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
}
}
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
index d7e0c83465..69e2f39069 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
@@ -194,8 +194,8 @@ bool MacroExpander::expandMacro(const Macro &macro,
if (macro.predefined)
{
- static const std::string kLine = "__LINE__";
- static const std::string kFile = "__FILE__";
+ const char kLine[] = "__LINE__";
+ const char kFile[] = "__FILE__";
assert(replacements->size() == 1);
Token& repl = replacements->front();
diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
index 368cd2ae4a..5c62a64d10 100644
--- a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
@@ -29,24 +29,27 @@
bool IsWebGLBasedSpec(ShShaderSpec spec)
{
- return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
+ return (spec == SH_WEBGL_SPEC ||
+ spec == SH_CSS_SHADERS_SPEC ||
+ spec == SH_WEBGL2_SPEC);
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
{
// WebGL defines a max token legnth of 256, while ES2 leaves max token
// size undefined. ES3 defines a max size of 1024 characters.
- if (IsWebGLBasedSpec(spec))
+ switch (spec)
{
+ case SH_WEBGL_SPEC:
+ case SH_CSS_SHADERS_SPEC:
return 256;
- }
- else
- {
+ default:
return 1024;
}
}
namespace {
+
class TScopedPoolAllocator
{
public:
@@ -82,6 +85,24 @@ class TScopedSymbolTableLevel
private:
TSymbolTable* mTable;
};
+
+int MapSpecToShaderVersion(ShShaderSpec spec)
+{
+ switch (spec)
+ {
+ case SH_GLES2_SPEC:
+ case SH_WEBGL_SPEC:
+ case SH_CSS_SHADERS_SPEC:
+ return 100;
+ case SH_GLES3_SPEC:
+ case SH_WEBGL2_SPEC:
+ return 300;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
} // namespace
TShHandleBase::TShHandleBase()
@@ -178,9 +199,21 @@ bool TCompiler::compile(const char* const shaderStrings[],
(parseContext.treeRoot != NULL);
shaderVersion = parseContext.getShaderVersion();
+ if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
+ {
+ infoSink.info.prefix(EPrefixError);
+ infoSink.info << "unsupported shader version";
+ success = false;
+ }
if (success)
{
+ mPragma = parseContext.pragma();
+ if (mPragma.stdgl.invariantAll)
+ {
+ symbolTable.setGlobalInvariant();
+ }
+
TIntermNode* root = parseContext.treeRoot;
success = intermediate.postProcess(root);
@@ -360,7 +393,8 @@ void TCompiler::setResourceString()
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
- << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
+ << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
+ << ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
builtInResourcesString = strstream.str();
}
@@ -377,7 +411,6 @@ void TCompiler::clearResults()
uniforms.clear();
expandedUniforms.clear();
varyings.clear();
- expandedVaryings.clear();
interfaceBlocks.clear();
builtInFunctionEmulator.Cleanup();
@@ -507,13 +540,12 @@ void TCompiler::collectVariables(TIntermNode* root)
&uniforms,
&varyings,
&interfaceBlocks,
- hashFunction);
+ hashFunction,
+ symbolTable);
root->traverse(&collect);
- // For backwards compatiblity with ShGetVariableInfo, expand struct
- // uniforms and varyings into separate variables for each field.
- sh::ExpandVariables(uniforms, &expandedUniforms);
- sh::ExpandVariables(varyings, &expandedVaryings);
+ // This is for enforcePackingRestriction().
+ sh::ExpandUniforms(uniforms, &expandedUniforms);
}
bool TCompiler::enforcePackingRestrictions()
@@ -581,3 +613,10 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
{
return builtInFunctionEmulator;
}
+
+void TCompiler::writePragma()
+{
+ TInfoSinkBase &sink = infoSink.obj;
+ if (mPragma.stdgl.invariantAll)
+ sink << "#pragma STDGL invariant(all)\n";
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.h b/src/3rdparty/angle/src/compiler/translator/Compiler.h
index ca0c157884..b6c9d13ed0 100644
--- a/src/3rdparty/angle/src/compiler/translator/Compiler.h
+++ b/src/3rdparty/angle/src/compiler/translator/Compiler.h
@@ -18,6 +18,7 @@
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/HashNames.h"
#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "third_party/compiler/ArrayBoundsClamper.h"
@@ -71,9 +72,7 @@ class TCompiler : public TShHandleBase
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
- const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
- const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; }
@@ -81,7 +80,7 @@ class TCompiler : public TShHandleBase
TSymbolTable& getSymbolTable() { return symbolTable; }
ShShaderSpec getShaderSpec() const { return shaderSpec; }
ShShaderOutput getOutputType() const { return outputType; }
- std::string getBuiltInResourcesString() const { return builtInResourcesString; }
+ const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
@@ -131,6 +130,8 @@ class TCompiler : public TShHandleBase
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
+ const TPragma& getPragma() const { return mPragma; }
+ void writePragma();
const ArrayBoundsClamper& getArrayBoundsClamper() const;
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
@@ -141,7 +142,6 @@ class TCompiler : public TShHandleBase
std::vector<sh::Uniform> uniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings;
- std::vector<sh::ShaderVariable> expandedVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:
@@ -174,6 +174,8 @@ class TCompiler : public TShHandleBase
// name hashing.
ShHashFunction64 hashFunction;
NameMap nameMap;
+
+ TPragma mPragma;
};
//
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp
index 334eb0bfa8..f98d32b2b7 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp
@@ -14,6 +14,9 @@
namespace sh
{
+
+// Detect Loop Discontinuity
+
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
{
mLoopDepth = 0;
@@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node)
return detectLoopDiscontinuity.traverse(node);
}
+// Detect Any Loop
+
+bool DetectAnyLoop::traverse(TIntermNode *node)
+{
+ mHasLoop = false;
+ node->traverse(this);
+ return mHasLoop;
+}
+
+bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop)
+{
+ mHasLoop = true;
+ return false;
+}
+
+// The following definitions stop all traversal when we have found a loop
+bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *)
+{
+ return !mHasLoop;
+}
+
+bool containsAnyLoop(TIntermNode *node)
+{
+ DetectAnyLoop detectAnyLoop;
+ return detectAnyLoop.traverse(node);
+}
+
+// Detect Gradient Operation
+
bool DetectGradientOperation::traverse(TIntermNode *node)
{
mGradientOperation = false;
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
index 35d66cbc2e..67e37be398 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
+++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
@@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser
bool containsLoopDiscontinuity(TIntermNode *node);
+// Checks for the existence of any loop
+class DetectAnyLoop : public TIntermTraverser
+{
+public:
+ bool traverse(TIntermNode *node);
+
+protected:
+ bool visitBinary(Visit, TIntermBinary *);
+ bool visitUnary(Visit, TIntermUnary *);
+ bool visitSelection(Visit, TIntermSelection *);
+ bool visitAggregate(Visit, TIntermAggregate *);
+ bool visitLoop(Visit, TIntermLoop *);
+ bool visitBranch(Visit, TIntermBranch *);
+
+ bool mHasLoop;
+};
+
+bool containsAnyLoop(TIntermNode *node);
+
// Checks for intrinsic functions which compute gradients
class DetectGradientOperation : public TIntermTraverser
{
diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
index 59d2835f7b..f67a03aa93 100644
--- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
@@ -13,10 +13,10 @@
static TBehavior getBehavior(const std::string& str)
{
- static const std::string kRequire("require");
- static const std::string kEnable("enable");
- static const std::string kDisable("disable");
- static const std::string kWarn("warn");
+ const char kRequire[] = "require";
+ const char kEnable[] = "enable";
+ const char kDisable[] = "disable";
+ const char kWarn[] = "warn";
if (str == kRequire) return EBhRequire;
else if (str == kEnable) return EBhEnable;
@@ -46,50 +46,61 @@ void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
const std::string& name,
- const std::string& value)
+ const std::string& value,
+ bool stdgl)
{
- static const std::string kSTDGL("STDGL");
- static const std::string kOptimize("optimize");
- static const std::string kDebug("debug");
- static const std::string kOn("on");
- static const std::string kOff("off");
-
- bool invalidValue = false;
- if (name == kSTDGL)
+ if (stdgl)
{
+ const char kInvariant[] = "invariant";
+ const char kAll[] = "all";
+
+ if (name == kInvariant && value == kAll)
+ mPragma.stdgl.invariantAll = true;
// The STDGL pragma is used to reserve pragmas for use by future
- // revisions of GLSL. Ignore it.
+ // revisions of GLSL. Do not generate an error on unexpected
+ // name and value.
return;
}
- else if (name == kOptimize)
- {
- if (value == kOn) mPragma.optimize = true;
- else if (value == kOff) mPragma.optimize = false;
- else invalidValue = true;
- }
- else if (name == kDebug)
- {
- if (value == kOn) mPragma.debug = true;
- else if (value == kOff) mPragma.debug = false;
- else invalidValue = true;
- }
else
{
- mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
- return;
- }
+ const char kOptimize[] = "optimize";
+ const char kDebug[] = "debug";
+ const char kOn[] = "on";
+ const char kOff[] = "off";
- if (invalidValue)
- mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
- "invalid pragma value", value,
- "'on' or 'off' expected");
+ bool invalidValue = false;
+ if (name == kOptimize)
+ {
+ if (value == kOn) mPragma.optimize = true;
+ else if (value == kOff) mPragma.optimize = false;
+ else invalidValue = true;
+ }
+ else if (name == kDebug)
+ {
+ if (value == kOn) mPragma.debug = true;
+ else if (value == kOff) mPragma.debug = false;
+ else invalidValue = true;
+ }
+ else
+ {
+ mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
+ return;
+ }
+
+ if (invalidValue)
+ {
+ mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+ "invalid pragma value", value,
+ "'on' or 'off' expected");
+ }
+ }
}
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
const std::string& name,
const std::string& behavior)
{
- static const std::string kExtAll("all");
+ const char kExtAll[] = "all";
TBehavior behaviorVal = getBehavior(behavior);
if (behaviorVal == EBhUndefined)
diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
index 69418c277a..0433c3bf89 100644
--- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
+++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
@@ -29,7 +29,8 @@ class TDirectiveHandler : public pp::DirectiveHandler
virtual void handlePragma(const pp::SourceLocation& loc,
const std::string& name,
- const std::string& value);
+ const std::string& value,
+ bool stdgl);
virtual void handleExtension(const pp::SourceLocation& loc,
const std::string& name,
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
index b155545ad2..aa0f31d170 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
@@ -133,6 +133,14 @@ bool CompareStructure(const TType &leftNodeType,
//
////////////////////////////////////////////////////////////////
+void TIntermTyped::setTypePreservePrecision(const TType &t)
+{
+ TPrecision precision = getPrecision();
+ mType = t;
+ ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
+ mType.setPrecision(precision);
+}
+
#define REPLACE_IF_IS(node, type, original, replacement) \
if (node == original) { \
node = static_cast<type *>(replacement); \
@@ -237,6 +245,52 @@ void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) con
}
}
+void TIntermAggregate::setPrecisionFromChildren()
+{
+ if (getBasicType() == EbtBool)
+ {
+ mType.setPrecision(EbpUndefined);
+ return;
+ }
+
+ TPrecision precision = EbpUndefined;
+ TIntermSequence::iterator childIter = mSequence.begin();
+ while (childIter != mSequence.end())
+ {
+ TIntermTyped *typed = (*childIter)->getAsTyped();
+ if (typed)
+ precision = GetHigherPrecision(typed->getPrecision(), precision);
+ ++childIter;
+ }
+ mType.setPrecision(precision);
+}
+
+void TIntermAggregate::setBuiltInFunctionPrecision()
+{
+ // All built-ins returning bool should be handled as ops, not functions.
+ ASSERT(getBasicType() != EbtBool);
+
+ TPrecision precision = EbpUndefined;
+ TIntermSequence::iterator childIter = mSequence.begin();
+ while (childIter != mSequence.end())
+ {
+ TIntermTyped *typed = (*childIter)->getAsTyped();
+ // ESSL spec section 8: texture functions get their precision from the sampler.
+ if (typed && IsSampler(typed->getBasicType()))
+ {
+ precision = typed->getPrecision();
+ break;
+ }
+ ++childIter;
+ }
+ // ESSL 3.0 spec section 8: textureSize always gets highp precision.
+ // All other functions that take a sampler are assumed to be texture functions.
+ if (mName.find("textureSize") == 0)
+ mType.setPrecision(EbpHigh);
+ else
+ mType.setPrecision(precision);
+}
+
bool TIntermSelection::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -336,6 +390,7 @@ bool TIntermUnary::promote(TInfoSink &)
return false;
break;
case EOpNegative:
+ case EOpPositive:
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
@@ -1068,6 +1123,27 @@ TIntermTyped *TIntermConstantUnion::fold(
}
break;
+ case EOpPositive:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ tempConstArray[i].setFConst(unionArray[i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setIConst(unionArray[i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setUConst(static_cast<unsigned int>(
+ static_cast<int>(unionArray[i].getUConst())));
+ break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return NULL;
+ }
+ break;
+
case EOpLogicalNot:
// this code is written for possible future use,
// will not get executed currently
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.h b/src/3rdparty/angle/src/compiler/translator/IntermNode.h
index ec440da010..32c70f4671 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermNode.h
+++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.h
@@ -45,6 +45,7 @@ enum TOperator
//
EOpNegative,
+ EOpPositive,
EOpLogicalNot,
EOpVectorLogicalNot,
@@ -265,6 +266,7 @@ class TIntermTyped : public TIntermNode
virtual bool hasSideEffects() const = 0;
void setType(const TType &t) { mType = t; }
+ void setTypePreservePrecision(const TType &t);
const TType &getType() const { return mType; }
TType *getTypePointer() { return &mType; }
@@ -613,6 +615,9 @@ class TIntermAggregate : public TIntermOperator
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+ void setPrecisionFromChildren();
+ void setBuiltInFunctionPrecision();
+
protected:
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
diff --git a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
index ef4f83307c..e558683c55 100644
--- a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
@@ -198,6 +198,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
case EOpPostDecrement:
case EOpPreDecrement:
case EOpNegative:
+ case EOpPositive:
if (child->getType().getBasicType() == EbtStruct ||
child->getType().isArray())
{
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
index 6d07cccc04..ed590967b1 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -395,6 +395,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: preString = "(-"; break;
+ case EOpPositive: preString = "(+"; break;
case EOpVectorLogicalNot: preString = "not("; break;
case EOpLogicalNot: preString = "(!"; break;
@@ -574,7 +575,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
// Function declaration.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << hashName(node->getName());
+ out << " " << hashFunctionName(node->getName());
out << "(";
writeFunctionParameters(*(node->getSequence()));
@@ -649,17 +650,18 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
mDeclaringVariables = false;
}
break;
- case EOpInvariantDeclaration: {
- // Invariant declaration.
- ASSERT(visit == PreVisit);
+ case EOpInvariantDeclaration:
+ // Invariant declaration.
+ ASSERT(visit == PreVisit);
+ {
const TIntermSequence *sequence = node->getSequence();
ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol);
- out << "invariant " << symbol->getSymbol() << ";";
- visitChildren = false;
- break;
+ out << "invariant " << hashVariableName(symbol->getSymbol());
}
+ visitChildren = false;
+ break;
case EOpConstructFloat:
writeTriplet(visit, "float(", NULL, ")");
break;
@@ -741,7 +743,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
break;
case EOpComma:
- writeTriplet(visit, NULL, ", ", NULL);
+ writeTriplet(visit, "(", ", ", ")");
break;
case EOpMod:
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
index a5ea71599d..30bbbff0f5 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
@@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
mUniqueIndex = 0;
mContainsLoopDiscontinuity = false;
+ mContainsAnyLoop = false;
mOutputLod0Function = false;
mInsideDiscontinuousLoop = false;
mNestedLoopDepth = 0;
@@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL()
void OutputHLSL::output()
{
mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
+ mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
makeFlaggedStructMaps(flaggedStructs);
@@ -320,14 +322,22 @@ void OutputHLSL::header()
if (mUsesDiscardRewriting)
{
- out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
+ out << "#define ANGLE_USES_DISCARD_REWRITING\n";
}
if (mUsesNestedBreak)
{
- out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
+ out << "#define ANGLE_USES_NESTED_BREAK\n";
}
+ out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
+ "#define LOOP [loop]\n"
+ "#define FLATTEN [flatten]\n"
+ "#else\n"
+ "#define LOOP\n"
+ "#define FLATTEN\n"
+ "#endif\n";
+
if (mContext.shaderType == GL_FRAGMENT_SHADER)
{
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
@@ -1747,6 +1757,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
+ case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
@@ -1860,15 +1871,20 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
{
- if (!mInsideFunction)
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
{
- out << "static ";
- }
+ if (isSingleStatement(*sit))
+ {
+ mUnfoldShortCircuit->traverse(*sit);
+ }
- out << TypeString(variable->getType()) + " ";
+ if (!mInsideFunction)
+ {
+ out << "static ";
+ }
+
+ out << TypeString(variable->getType()) + " ";
- for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
- {
TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
if (symbol)
@@ -1884,7 +1900,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (*sit != sequence->back())
{
- out << ", ";
+ out << ";\n";
}
}
}
@@ -1925,7 +1941,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpPrototype:
if (visit == PreVisit)
{
- out << TypeString(node->getType()) << " " << Decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
+ out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "(");
TIntermSequence *arguments = node->getSequence();
@@ -2287,6 +2303,15 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{
mUnfoldShortCircuit->traverse(node->getCondition());
+ // D3D errors when there is a gradient operation in a loop in an unflattened if
+ // however flattening all the ifs in branch heavy shaders made D3D error too.
+ // As a temporary workaround we flatten the ifs only if there is at least a loop
+ // present somewhere in the shader.
+ if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
+ {
+ out << "FLATTEN ";
+ }
+
out << "if (";
node->getCondition()->traverse(this);
@@ -2367,14 +2392,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getType() == ELoopDoWhile)
{
- out << "{do\n";
+ out << "{LOOP do\n";
outputLineDirective(node->getLine().first_line);
out << "{\n";
}
else
{
- out << "{for(";
+ out << "{LOOP for(";
if (node->getInit())
{
@@ -2503,6 +2528,12 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node)
{
return false;
}
+ else if (aggregate->getOp() == EOpDeclaration)
+ {
+ // Declaring multiple comma-separated variables must be considered multiple statements
+ // because each individual declaration has side effects which are visible in the next.
+ return false;
+ }
else
{
for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
@@ -2675,7 +2706,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
// for(int index = initial; index < clampedLimit; index += increment)
- out << "for(";
+ out << "LOOP for(";
index->traverse(this);
out << " = ";
out << initial;
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
index bec02479bb..5525e6eaa6 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
@@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser
int mUniqueIndex; // For creating unique names
bool mContainsLoopDiscontinuity;
+ bool mContainsAnyLoop;
bool mOutputLod0Function;
bool mInsideDiscontinuousLoop;
int mNestedLoopDepth;
diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
index ff0a49667c..37969b5468 100644
--- a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
@@ -1004,12 +1004,12 @@ void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char*
directiveHandler.handleExtension(srcLoc, extName, behavior);
}
-void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
+void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
{
pp::SourceLocation srcLoc;
srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line;
- directiveHandler.handlePragma(srcLoc, name, value);
+ directiveHandler.handlePragma(srcLoc, name, value, stdgl);
}
/////////////////////////////////////////////////////////////////////////////////
@@ -1364,11 +1364,18 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
{
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
recover();
-
return NULL;
}
else
{
+ const TString kGlFrontFacing("gl_FrontFacing");
+ if (*identifier == kGlFrontFacing)
+ {
+ error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
+ recover();
+ return NULL;
+ }
+ symbolTable.addInvariantVarying(*identifier);
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
ASSERT(variable);
const TType &type = variable->getType();
diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.h b/src/3rdparty/angle/src/compiler/translator/ParseContext.h
index 1f4cbdeba9..414c475cbb 100644
--- a/src/3rdparty/angle/src/compiler/translator/ParseContext.h
+++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.h
@@ -116,7 +116,7 @@ struct TParseContext {
bool supportsExtension(const char* extension);
bool isExtensionEnabled(const char* extension) const;
void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior);
- void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value);
+ void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl);
bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode);
diff --git a/src/3rdparty/angle/src/compiler/translator/Pragma.h b/src/3rdparty/angle/src/compiler/translator/Pragma.h
index 2f744123b8..4a930a2962 100644
--- a/src/3rdparty/angle/src/compiler/translator/Pragma.h
+++ b/src/3rdparty/angle/src/compiler/translator/Pragma.h
@@ -7,13 +7,23 @@
#ifndef COMPILER_PRAGMA_H_
#define COMPILER_PRAGMA_H_
-struct TPragma {
+struct TPragma
+{
+ struct STDGL
+ {
+ STDGL() : invariantAll(false) { }
+
+ bool invariantAll;
+ };
+
+
// By default optimization is turned on and debug is turned off.
TPragma() : optimize(true), debug(false) { }
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
bool debug;
+ STDGL stdgl;
};
#endif // COMPILER_PRAGMA_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
index 20ce71605c..0d6a1d64cf 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
@@ -37,72 +37,6 @@ bool isInitialized = false;
// and the shading language compiler.
//
-static bool CheckVariableMaxLengths(const ShHandle handle,
- size_t expectedValue)
-{
- size_t activeUniformLimit = 0;
- ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
- size_t activeAttribLimit = 0;
- ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
- size_t varyingLimit = 0;
- ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
- return (expectedValue == activeUniformLimit &&
- expectedValue == activeAttribLimit &&
- expectedValue == varyingLimit);
-}
-
-bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
-{
- size_t mappedNameMaxLength = 0;
- ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
- return (expectedValue == mappedNameMaxLength);
-}
-
-template <typename VarT>
-const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
-{
- if (index < 0 || static_cast<size_t>(index) >= infoList.size())
- {
- return NULL;
- }
-
- return &infoList[index];
-}
-
-const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
-{
- switch (varType)
- {
- case SH_ACTIVE_ATTRIBUTES:
- return ReturnVariable(compiler->getAttributes(), index);
- case SH_ACTIVE_UNIFORMS:
- return ReturnVariable(compiler->getExpandedUniforms(), index);
- case SH_VARYINGS:
- return ReturnVariable(compiler->getExpandedVaryings(), index);
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-ShPrecisionType ConvertPrecision(sh::GLenum precision)
-{
- switch (precision)
- {
- case GL_HIGH_FLOAT:
- case GL_HIGH_INT:
- return SH_PRECISION_HIGHP;
- case GL_MEDIUM_FLOAT:
- case GL_MEDIUM_INT:
- return SH_PRECISION_MEDIUMP;
- case GL_LOW_FLOAT:
- case GL_LOW_INT:
- return SH_PRECISION_LOWP;
- default:
- return SH_PRECISION_UNDEFINED;
- }
-}
-
template <typename VarT>
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
@@ -150,32 +84,48 @@ const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariabl
return GetVariableList<VarT>(compiler, variableType);
}
+TCompiler *GetCompilerFromHandle(ShHandle handle)
+{
+ if (!handle)
+ return NULL;
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsCompiler();
}
+TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
+{
+ if (!handle)
+ return NULL;
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsTranslatorHLSL();
+}
+
+} // namespace anonymous
+
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
//
-int ShInitialize()
+bool ShInitialize()
{
if (!isInitialized)
{
isInitialized = InitProcess();
}
- return isInitialized ? 1 : 0;
+ return isInitialized;
}
//
// Cleanup symbol tables
//
-int ShFinalize()
+bool ShFinalize()
{
if (isInitialized)
{
DetachProcess();
isInitialized = false;
}
- return 1;
+ return true;
}
//
@@ -183,6 +133,9 @@ int ShFinalize()
//
void ShInitBuiltInResources(ShBuiltInResources* resources)
{
+ // Make comparable.
+ memset(resources, 0, sizeof(*resources));
+
// Constants.
resources->MaxVertexAttribs = 8;
resources->MaxVertexUniformVectors = 128;
@@ -201,6 +154,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
+ resources->NV_draw_buffers = 0;
+
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;
@@ -251,23 +206,13 @@ void ShDestruct(ShHandle handle)
DeleteCompiler(base->getAsCompiler());
}
-void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
+const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
{
- if (!handle || !outString)
- {
- return;
- }
-
- TShHandleBase *base = static_cast<TShHandleBase*>(handle);
- TCompiler *compiler = base->getAsCompiler();
- if (!compiler)
- {
- return;
- }
-
- strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
- outString[outStringLen - 1] = '\0';
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResourcesString();
}
+
//
// Do an actual compile on the given strings. The result is left
// in the given compile object.
@@ -275,219 +220,62 @@ void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, cha
// Return: The return value of ShCompile is really boolean, indicating
// success or failure.
//
-int ShCompile(
+bool ShCompile(
const ShHandle handle,
- const char* const shaderStrings[],
+ const char *const shaderStrings[],
size_t numStrings,
int compileOptions)
{
- if (handle == 0)
- return 0;
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (compiler == 0)
- return 0;
-
- bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
- return success ? 1 : 0;
+ return compiler->compile(shaderStrings, numStrings, compileOptions);
}
-void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
+int ShGetShaderVersion(const ShHandle handle)
{
- if (!handle || !params)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
+ TCompiler* compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getShaderVersion();
+}
- switch(pname)
- {
- case SH_INFO_LOG_LENGTH:
- *params = compiler->getInfoSink().info.size() + 1;
- break;
- case SH_OBJECT_CODE_LENGTH:
- *params = compiler->getInfoSink().obj.size() + 1;
- break;
- case SH_ACTIVE_UNIFORMS:
- *params = compiler->getExpandedUniforms().size();
- break;
- case SH_ACTIVE_UNIFORM_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_ACTIVE_ATTRIBUTES:
- *params = compiler->getAttributes().size();
- break;
- case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_VARYINGS:
- *params = compiler->getExpandedVaryings().size();
- break;
- case SH_VARYING_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_MAPPED_NAME_MAX_LENGTH:
- // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
- // handle array and struct dereferences.
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_NAME_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_HASHED_NAME_MAX_LENGTH:
- if (compiler->getHashFunction() == NULL) {
- *params = 0;
- } else {
- // 64 bits hashing output requires 16 bytes for hex
- // representation.
- const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
- (void)HashedNamePrefix;
- *params = 16 + sizeof(HashedNamePrefix);
- }
- break;
- case SH_HASHED_NAMES_COUNT:
- *params = compiler->getNameMap().size();
- break;
- case SH_SHADER_VERSION:
- *params = compiler->getShaderVersion();
- break;
- case SH_RESOURCES_STRING_LENGTH:
- *params = compiler->getBuiltInResourcesString().length() + 1;
- break;
- case SH_OUTPUT_TYPE:
- *params = compiler->getOutputType();
- break;
- default: UNREACHABLE();
- }
+ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
+{
+ TCompiler* compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getOutputType();
}
//
// Return any compiler log of messages for the application.
//
-void ShGetInfoLog(const ShHandle handle, char* infoLog)
+const std::string &ShGetInfoLog(const ShHandle handle)
{
- if (!handle || !infoLog)
- return;
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
-
- TInfoSink& infoSink = compiler->getInfoSink();
- strcpy(infoLog, infoSink.info.c_str());
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.info.str();
}
//
// Return any object code.
//
-void ShGetObjectCode(const ShHandle handle, char* objCode)
+const std::string &ShGetObjectCode(const ShHandle handle)
{
- if (!handle || !objCode)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
-
- TInfoSink& infoSink = compiler->getInfoSink();
- strcpy(objCode, infoSink.obj.c_str());
-}
-
-void ShGetVariableInfo(const ShHandle handle,
- ShShaderInfo varType,
- int index,
- size_t* length,
- int* size,
- sh::GLenum* type,
- ShPrecisionType* precision,
- int* staticUse,
- char* name,
- char* mappedName)
-{
- if (!handle || !size || !type || !precision || !staticUse || !name)
- return;
- ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
- (varType == SH_ACTIVE_UNIFORMS) ||
- (varType == SH_VARYINGS));
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (compiler == 0)
- return;
-
- const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
- if (!varInfo)
- {
- return;
- }
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
- if (length) *length = varInfo->name.size();
- *size = varInfo->elementCount();
- *type = varInfo->type;
- *precision = ConvertPrecision(varInfo->precision);
- *staticUse = varInfo->staticUse ? 1 : 0;
-
- // This size must match that queried by
- // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
- // in ShGetInfo, below.
- size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- ASSERT(CheckVariableMaxLengths(handle, variableLength));
- strncpy(name, varInfo->name.c_str(), variableLength);
- name[variableLength - 1] = 0;
- if (mappedName)
- {
- // This size must match that queried by
- // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
- size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
- strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
- mappedName[maxMappedNameLength - 1] = 0;
- }
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.str();
}
-void ShGetNameHashingEntry(const ShHandle handle,
- int index,
- char* name,
- char* hashedName)
+const std::map<std::string, std::string> *ShGetNameHashingMap(
+ const ShHandle handle)
{
- if (!handle || !name || !hashedName || index < 0)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
-
- const NameMap& nameMap = compiler->getNameMap();
- if (index >= static_cast<int>(nameMap.size()))
- return;
-
- NameMap::const_iterator it = nameMap.begin();
- for (int i = 0; i < index; ++i)
- ++it;
-
- size_t len = it->first.length() + 1;
- size_t max_len = 0;
- ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
- if (len > max_len) {
- ASSERT(false);
- len = max_len;
- }
- strncpy(name, it->first.c_str(), len);
- // To be on the safe side in case the source is longer than expected.
- name[len - 1] = '\0';
-
- len = it->second.length() + 1;
- max_len = 0;
- ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
- if (len > max_len) {
- ASSERT(false);
- len = max_len;
- }
- strncpy(hashedName, it->second.c_str(), len);
- // To be on the safe side in case the source is longer than expected.
- hashedName[len - 1] = '\0';
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return &(compiler->getNameMap());
}
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
@@ -515,11 +303,11 @@ const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handl
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
}
-int ShCheckVariablesWithinPackingLimits(
- int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
+bool ShCheckVariablesWithinPackingLimits(
+ int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
{
if (varInfoArraySize == 0)
- return 1;
+ return true;
ASSERT(varInfoArray);
std::vector<sh::ShaderVariable> variables;
for (size_t ii = 0; ii < varInfoArraySize; ++ii)
@@ -528,24 +316,17 @@ int ShCheckVariablesWithinPackingLimits(
variables.push_back(var);
}
VariablePacker packer;
- return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
+ return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
}
bool ShGetInterfaceBlockRegister(const ShHandle handle,
- const char *interfaceBlockName,
+ const std::string &interfaceBlockName,
unsigned int *indexOut)
{
- if (!handle || !interfaceBlockName || !indexOut)
- {
- return false;
- }
+ ASSERT(indexOut);
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TranslatorHLSL* translator = base->getAsTranslatorHLSL();
- if (!translator)
- {
- return false;
- }
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
if (!translator->hasInterfaceBlock(interfaceBlockName))
{
@@ -557,20 +338,12 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
}
bool ShGetUniformRegister(const ShHandle handle,
- const char *uniformName,
+ const std::string &uniformName,
unsigned int *indexOut)
{
- if (!handle || !uniformName || !indexOut)
- {
- return false;
- }
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TranslatorHLSL* translator = base->getAsTranslatorHLSL();
- if (!translator)
- {
- return false;
- }
+ ASSERT(indexOut);
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
if (!translator->hasUniform(uniformName))
{
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
index 822c558c9b..3098a7f0c9 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
@@ -9,6 +9,8 @@
#include <GLSLANG/ShaderLang.h>
+#include "compiler/translator/compilerdebug.h"
+
namespace sh
{
@@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
return *this;
}
+bool ShaderVariable::operator==(const ShaderVariable &other) const
+{
+ if (type != other.type ||
+ precision != other.precision ||
+ name != other.name ||
+ mappedName != other.mappedName ||
+ arraySize != other.arraySize ||
+ staticUse != other.staticUse ||
+ fields.size() != other.fields.size() ||
+ structName != other.structName)
+ {
+ return false;
+ }
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (fields[ii] != other.fields[ii])
+ return false;
+ }
+ return true;
+}
+
+bool ShaderVariable::findInfoByMappedName(
+ const std::string &mappedFullName,
+ const ShaderVariable **leafVar, std::string *originalFullName) const
+{
+ ASSERT(leafVar && originalFullName);
+ // There are three cases:
+ // 1) the top variable is of struct type;
+ // 2) the top variable is an array;
+ // 3) otherwise.
+ size_t pos = mappedFullName.find_first_of(".[");
+ std::string topName;
+
+ if (pos == std::string::npos)
+ {
+ // Case 3.
+ if (mappedFullName != this->mappedName)
+ return false;
+ *originalFullName = this->name;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ std::string topName = mappedFullName.substr(0, pos);
+ if (topName != this->mappedName)
+ return false;
+ std::string originalName = this->name;
+ std::string remaining;
+ if (mappedFullName[pos] == '[')
+ {
+ // Case 2.
+ size_t closePos = mappedFullName.find_first_of(']');
+ if (closePos < pos || closePos == std::string::npos)
+ return false;
+ // Append '[index]'.
+ originalName += mappedFullName.substr(pos, closePos - pos + 1);
+ if (closePos + 1 == mappedFullName.size())
+ {
+ *originalFullName = originalName;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ // In the form of 'a[0].b', so after ']', '.' is expected.
+ if (mappedFullName[closePos + 1] != '.')
+ return false;
+ remaining = mappedFullName.substr(closePos + 2); // Skip "]."
+ }
+ }
+ else
+ {
+ // Case 1.
+ remaining = mappedFullName.substr(pos + 1); // Skip "."
+ }
+ for (size_t ii = 0; ii < this->fields.size(); ++ii)
+ {
+ const ShaderVariable *fieldVar = NULL;
+ std::string originalFieldName;
+ bool found = fields[ii].findInfoByMappedName(
+ remaining, &fieldVar, &originalFieldName);
+ if (found)
+ {
+ *originalFullName = originalName + "." + originalFieldName;
+ *leafVar = fieldVar;
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+bool ShaderVariable::isSameVariableAtLinkTime(
+ const ShaderVariable &other, bool matchPrecision) const
+{
+ if (type != other.type)
+ return false;
+ if (matchPrecision && precision != other.precision)
+ return false;
+ if (name != other.name)
+ return false;
+ ASSERT(mappedName == other.mappedName);
+ if (arraySize != other.arraySize)
+ return false;
+ if (fields.size() != other.fields.size())
+ return false;
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
+ matchPrecision))
+ {
+ return false;
+ }
+ }
+ if (structName != other.structName)
+ return false;
+ return true;
+}
+
Uniform::Uniform()
{}
@@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other)
return *this;
}
+bool Uniform::operator==(const Uniform &other) const
+{
+ return ShaderVariable::operator==(other);
+}
+
+bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
+{
+ return ShaderVariable::isSameVariableAtLinkTime(other, true);
+}
+
Attribute::Attribute()
: location(-1)
{}
@@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other)
return *this;
}
+bool Attribute::operator==(const Attribute &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ location == other.location);
+}
+
InterfaceBlockField::InterfaceBlockField()
: isRowMajorLayout(false)
{}
@@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o
return *this;
}
+bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ isRowMajorLayout == other.isRowMajorLayout);
+}
+
+bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
+ const InterfaceBlockField &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
+ isRowMajorLayout == other.isRowMajorLayout);
+}
+
Varying::Varying()
: interpolation(INTERPOLATION_SMOOTH),
isInvariant(false)
@@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other)
return *this;
}
+bool Varying::operator==(const Varying &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ interpolation == other.interpolation &&
+ isInvariant == other.isInvariant);
+}
+
+bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
+ interpolation == other.interpolation &&
+ isInvariant == other.isInvariant);
+}
+
InterfaceBlock::InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),
diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
index 6b0e0c0a03..9cd74218dc 100644
--- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
+++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
@@ -31,6 +31,7 @@
//
#include <assert.h>
+#include <set>
#include "common/angleutils.h"
#include "compiler/translator/InfoSink.h"
@@ -299,19 +300,21 @@ class TSymbolTableLevel
tLevel level;
};
-enum ESymbolLevel
-{
- COMMON_BUILTINS = 0,
- ESSL1_BUILTINS = 1,
- ESSL3_BUILTINS = 2,
- LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
- GLOBAL_LEVEL = 3
-};
+// Define ESymbolLevel as int rather than an enum since level can go
+// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
+// compiler optimizes the >= of the last element to ==.
+typedef int ESymbolLevel;
+const int COMMON_BUILTINS = 0;
+const int ESSL1_BUILTINS = 1;
+const int ESSL3_BUILTINS = 2;
+const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
+const int GLOBAL_LEVEL = 3;
class TSymbolTable
{
public:
TSymbolTable()
+ : mGlobalInvariant(false)
{
// The symbol table cannot be used until push() is called, but
// the lack of an initial call to push() can be used to detect
@@ -408,6 +411,25 @@ class TSymbolTable
// for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type) const;
+ // This records invariant varyings declared through
+ // "invariant varying_name;".
+ void addInvariantVarying(const TString &originalName)
+ {
+ mInvariantVaryings.insert(originalName);
+ }
+ // If this returns false, the varying could still be invariant
+ // if it is set as invariant during the varying variable
+ // declaration - this piece of information is stored in the
+ // variable's type, not here.
+ bool isVaryingInvariant(const TString &originalName) const
+ {
+ return (mGlobalInvariant ||
+ mInvariantVaryings.count(originalName) > 0);
+ }
+
+ void setGlobalInvariant() { mGlobalInvariant = true; }
+ bool getGlobalInvariant() const { return mGlobalInvariant; }
+
static int nextUniqueId()
{
return ++uniqueIdCounter;
@@ -423,6 +445,9 @@ class TSymbolTable
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector< PrecisionStackLevel *> precisionStack;
+ std::set<TString> mInvariantVaryings;
+ bool mGlobalInvariant;
+
static int uniqueIdCounter;
};
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
index 5b99fea948..dcbf3cea1d 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
@@ -16,6 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
void TranslatorESSL::translate(TIntermNode* root) {
TInfoSinkBase& sink = getInfoSink().obj;
+ writePragma();
+
// Write built-in extension behaviors.
writeExtensionBehavior();
@@ -37,8 +39,13 @@ void TranslatorESSL::writeExtensionBehavior() {
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
iter != extensionBehavior.end(); ++iter) {
if (iter->second != EBhUndefined) {
- sink << "#extension " << iter->first << " : "
- << getBehaviorString(iter->second) << "\n";
+ if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
+ sink << "#extension GL_NV_draw_buffers : "
+ << getBehaviorString(iter->second) << "\n";
+ } else {
+ sink << "#extension " << iter->first << " : "
+ << getBehaviorString(iter->second) << "\n";
+ }
}
}
}
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
index 4b2aecab33..6acbf7c5a8 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -9,18 +9,6 @@
#include "compiler/translator/OutputGLSL.h"
#include "compiler/translator/VersionGLSL.h"
-static void writeVersion(sh::GLenum type, TIntermNode* root,
- TInfoSinkBase& sink) {
- TVersionGLSL versionGLSL(type);
- root->traverse(&versionGLSL);
- int version = versionGLSL.getVersion();
- // We need to write version directive only if it is greater than 110.
- // If there is no version directive in the shader, 110 is implied.
- if (version > 110) {
- sink << "#version " << version << "\n";
- }
-}
-
TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_GLSL_OUTPUT) {
}
@@ -29,7 +17,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
TInfoSinkBase& sink = getInfoSink().obj;
// Write GLSL version.
- writeVersion(getShaderType(), root, sink);
+ writeVersion(root);
+
+ writePragma();
// Write extension behaviour as needed
writeExtensionBehavior();
@@ -46,6 +36,20 @@ void TranslatorGLSL::translate(TIntermNode* root) {
root->traverse(&outputGLSL);
}
+void TranslatorGLSL::writeVersion(TIntermNode *root)
+{
+ TVersionGLSL versionGLSL(getShaderType(), getPragma());
+ root->traverse(&versionGLSL);
+ int version = versionGLSL.getVersion();
+ // We need to write version directive only if it is greater than 110.
+ // If there is no version directive in the shader, 110 is implied.
+ if (version > 110)
+ {
+ TInfoSinkBase& sink = getInfoSink().obj;
+ sink << "#version " << version << "\n";
+ }
+}
+
void TranslatorGLSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
index 3c6c2e426a..766d8d910e 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
@@ -9,14 +9,16 @@
#include "compiler/translator/Compiler.h"
-class TranslatorGLSL : public TCompiler {
-public:
+class TranslatorGLSL : public TCompiler
+{
+ public:
TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
-protected:
- virtual void translate(TIntermNode* root);
+ protected:
+ virtual void translate(TIntermNode *root);
-private:
+ private:
+ void writeVersion(TIntermNode *root);
void writeExtensionBehavior();
};
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
index c1a7b7524f..896e1cd7a0 100644
--- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
@@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op)
case EOpLogicalXor: return "^^";
case EOpLogicalAnd: return "&&";
case EOpNegative: return "-";
+ case EOpPositive: return "+";
case EOpVectorLogicalNot: return "not";
case EOpLogicalNot: return "!";
case EOpPostIncrement: return "++";
diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
index f26c1566ac..d8e13788b7 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
@@ -5,6 +5,7 @@
//
#include "angle_gl.h"
+#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "compiler/translator/util.h"
#include "common/utilities.h"
@@ -131,7 +132,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
std::vector<sh::InterfaceBlock> *interfaceBlocks,
- ShHashFunction64 hashFunction)
+ ShHashFunction64 hashFunction,
+ const TSymbolTable &symbolTable)
: mAttribs(attribs),
mOutputVariables(outputVariables),
mUniforms(uniforms),
@@ -140,7 +142,10 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mPointCoordAdded(false),
mFrontFacingAdded(false),
mFragCoordAdded(false),
- mHashFunction(hashFunction)
+ mPositionAdded(false),
+ mPointSizeAdded(false),
+ mHashFunction(hashFunction),
+ mSymbolTable(symbolTable)
{
}
@@ -200,12 +205,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mFragCoordAdded)
{
Varying info;
- info.name = "gl_FragCoord";
- info.mappedName = "gl_FragCoord";
+ const char kName[] = "gl_FragCoord";
+ info.name = kName;
+ info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
- info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFragCoordAdded = true;
}
@@ -214,12 +221,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mFrontFacingAdded)
{
Varying info;
- info.name = "gl_FrontFacing";
- info.mappedName = "gl_FrontFacing";
+ const char kName[] = "gl_FrontFacing";
+ info.name = kName;
+ info.mappedName = kName;
info.type = GL_BOOL;
info.arraySize = 0;
info.precision = GL_NONE;
info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFrontFacingAdded = true;
}
@@ -228,16 +237,50 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mPointCoordAdded)
{
Varying info;
- info.name = "gl_PointCoord";
- info.mappedName = "gl_PointCoord";
+ const char kName[] = "gl_PointCoord";
+ info.name = kName;
+ info.mappedName = kName;
info.type = GL_FLOAT_VEC2;
info.arraySize = 0;
- info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPointCoordAdded = true;
}
return;
+ case EvqPosition:
+ if (!mPositionAdded)
+ {
+ Varying info;
+ const char kName[] = "gl_Position";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_FLOAT_VEC4;
+ info.arraySize = 0;
+ info.precision = GL_HIGH_FLOAT; // Defined by spec.
+ info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+ mVaryings->push_back(info);
+ mPositionAdded = true;
+ }
+ return;
+ case EvqPointSize:
+ if (!mPointSizeAdded)
+ {
+ Varying info;
+ const char kName[] = "gl_PointSize";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_FLOAT;
+ info.arraySize = 0;
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
+ info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+ mVaryings->push_back(info);
+ mPointSizeAdded = true;
+ }
+ return;
default:
break;
}
@@ -251,8 +294,10 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
class NameHashingTraverser : public GetVariableTraverser
{
public:
- NameHashingTraverser(ShHashFunction64 hashFunction)
- : mHashFunction(hashFunction)
+ NameHashingTraverser(ShHashFunction64 hashFunction,
+ const TSymbolTable &symbolTable)
+ : GetVariableTraverser(symbolTable),
+ mHashFunction(hashFunction)
{}
private:
@@ -312,7 +357,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
const TType &fieldType = *field.type();
- GetVariableTraverser traverser;
+ GetVariableTraverser traverser(mSymbolTable);
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
@@ -325,7 +370,7 @@ template <typename VarT>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<VarT> *infoList) const
{
- NameHashingTraverser traverser(mHashFunction);
+ NameHashingTraverser traverser(mHashFunction, mSymbolTable);
traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
}
@@ -421,9 +466,8 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
return true;
}
-template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact,
- std::vector<ShaderVariable> *expanded)
+void ExpandUniforms(const std::vector<Uniform> &compact,
+ std::vector<ShaderVariable> *expanded)
{
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
{
@@ -432,7 +476,4 @@ void ExpandVariables(const std::vector<VarT> &compact,
}
}
-template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
-template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
-
}
diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
index 5ac4c46baa..92d376d879 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
+++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
@@ -11,6 +11,8 @@
#include "compiler/translator/IntermNode.h"
+class TSymbolTable;
+
namespace sh
{
@@ -23,7 +25,8 @@ class CollectVariables : public TIntermTraverser
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
- ShHashFunction64 hashFunction);
+ ShHashFunction64 hashFunction,
+ const TSymbolTable &symbolTable);
virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node);
@@ -48,13 +51,17 @@ class CollectVariables : public TIntermTraverser
bool mFrontFacingAdded;
bool mFragCoordAdded;
+ bool mPositionAdded;
+ bool mPointSizeAdded;
+
ShHashFunction64 mHashFunction;
+
+ const TSymbolTable &mSymbolTable;
};
-// Expand struct variables to flattened lists of split variables
-template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact,
- std::vector<ShaderVariable> *expanded);
+// Expand struct uniforms to flattened lists of split variables
+void ExpandUniforms(const std::vector<Uniform> &compact,
+ std::vector<ShaderVariable> *expanded);
}
diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
index 8edbd009b0..05b111a7a7 100644
--- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
@@ -26,18 +26,12 @@ static const int GLSL_VERSION_120 = 120;
// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
// are built-in types, entire structures or arrays... are all l-values."
//
-// TODO(alokp): The following two cases of invariant decalaration get lost
-// during parsing - they do not get carried over to the intermediate tree.
-// Handle these cases:
-// 1. When a pragma is used to force all output variables to be invariant:
-// - #pragma STDGL invariant(all)
-// 2. When a previously decalared or built-in variable is marked invariant:
-// - invariant gl_Position;
-// - varying vec3 color; invariant color;
-//
-TVersionGLSL::TVersionGLSL(sh::GLenum type)
- : mVersion(GLSL_VERSION_110)
+TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma)
{
+ if (pragma.stdgl.invariantAll)
+ mVersion = GLSL_VERSION_120;
+ else
+ mVersion = GLSL_VERSION_110;
}
void TVersionGLSL::visitSymbol(TIntermSymbol *node)
diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
index 30f5a138a0..72368e39d6 100644
--- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
@@ -9,6 +9,8 @@
#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Pragma.h"
+
// Traverses the intermediate tree to return the minimum GLSL version
// required to legally access all built-in features used in the shader.
// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
@@ -27,7 +29,7 @@
class TVersionGLSL : public TIntermTraverser
{
public:
- TVersionGLSL(sh::GLenum type);
+ TVersionGLSL(sh::GLenum type, const TPragma &pragma);
// Returns 120 if the following is used the shader:
// - "invariant",
diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.y b/src/3rdparty/angle/src/compiler/translator/glslang.y
index 5c945ad5ad..e271de978c 100644
--- a/src/3rdparty/angle/src/compiler/translator/glslang.y
+++ b/src/3rdparty/angle/src/compiler/translator/glslang.y
@@ -354,6 +354,15 @@ function_call
// Treat it like a built-in unary operator.
//
$$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
+ const TType& returnType = fnCandidate->getReturnType();
+ if (returnType.getBasicType() == EbtBool) {
+ // Bool types should not have precision, so we'll override any precision
+ // that might have been set by addUnaryMath.
+ $$->setType(returnType);
+ } else {
+ // addUnaryMath has set the precision of the node based on the operand.
+ $$->setTypePreservePrecision(returnType);
+ }
if ($$ == 0) {
std::stringstream extraInfoStream;
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
@@ -362,20 +371,29 @@ function_call
YYERROR;
}
} else {
- $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+ TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+ aggregate->setType(fnCandidate->getReturnType());
+ aggregate->setPrecisionFromChildren();
+ $$ = aggregate;
}
} else {
// This is a real function call
- $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
- $$->setType(fnCandidate->getReturnType());
+ TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
+ aggregate->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user defined function
// if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
// if builtIn == true, it's definitely a builtIn function with EOpNull
if (!builtIn)
- $$->getAsAggregate()->setUserDefined();
- $$->getAsAggregate()->setName(fnCandidate->getMangledName());
+ aggregate->setUserDefined();
+ aggregate->setName(fnCandidate->getMangledName());
+
+ // This needs to happen after the name is set
+ if (builtIn)
+ aggregate->setBuiltInFunctionPrecision();
+
+ $$ = aggregate;
TQualifier qual;
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
@@ -388,7 +406,6 @@ function_call
}
}
}
- $$->setType(fnCandidate->getReturnType());
} else {
// error message was put out by PaFindFunction()
// Put on a dummy node for error recovery
@@ -500,6 +517,7 @@ unary_expression
const char* errorOp = "";
switch($1.op) {
case EOpNegative: errorOp = "-"; break;
+ case EOpPositive: errorOp = "+"; break;
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
@@ -514,7 +532,7 @@ unary_expression
// Grammar Note: No traditional style type casts.
unary_operator
- : PLUS { $$.op = EOpNull; }
+ : PLUS { $$.op = EOpPositive; }
| DASH { $$.op = EOpNegative; }
| BANG { $$.op = EOpLogicalNot; }
;
@@ -762,7 +780,7 @@ declaration
TIntermAggregate *prototype = new TIntermAggregate;
prototype->setType(function.getReturnType());
- prototype->setName(function.getName());
+ prototype->setName(function.getMangledName());
for (size_t i = 0; i < function.getParamCount(); i++)
{
diff --git a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
index 56340c6f9e..00780f0454 100644
--- a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
@@ -62,7 +62,9 @@ TString TType::getCompleteString() const
TStringStream stream;
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
- stream << getQualifierString() << " " << getPrecisionString() << " ";
+ stream << getQualifierString() << " ";
+ if (precision != EbpUndefined)
+ stream << getPrecisionString() << " ";
if (array)
stream << "array[" << getArraySize() << "] of ";
if (isMatrix())
@@ -221,6 +223,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: out << "Negate value"; break;
+ case EOpPositive: out << "Positive sign"; break;
case EOpVectorLogicalNot:
case EOpLogicalNot: out << "Negate conditional"; break;
@@ -292,6 +295,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpFunction: out << "Function Definition: " << node->getName(); break;
case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
case EOpParameters: out << "Function Parameters: "; break;
+ case EOpPrototype: out << "Function Prototype: " << node->getName(); break;
case EOpConstructFloat: out << "Construct float"; break;
case EOpConstructVec2: out << "Construct vec2"; break;
diff --git a/src/3rdparty/angle/src/compiler/translator/util.cpp b/src/3rdparty/angle/src/compiler/translator/util.cpp
index f74c7d1173..8cc06a658a 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/util.cpp
@@ -9,6 +9,7 @@
#include <limits>
#include "compiler/preprocessor/numeric_lex.h"
+#include "compiler/translator/SymbolTable.h"
#include "common/utilities.h"
bool atof_clamp(const char *str, float *value)
@@ -281,8 +282,47 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
}
+GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
+ : mSymbolTable(symbolTable)
+{
+}
+
+template void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, InterfaceBlockField *variable);
+template void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, ShaderVariable *variable);
+template void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, Uniform *variable);
+
+template<>
+void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, Varying *variable)
+{
+ ASSERT(variable);
+ switch (type.getQualifier())
+ {
+ case EvqInvariantVaryingIn:
+ case EvqInvariantVaryingOut:
+ variable->isInvariant = true;
+ break;
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ if (mSymbolTable.isVaryingInvariant(name))
+ {
+ variable->isInvariant = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ variable->interpolation = GetInterpolationType(type.getQualifier());
+}
+
template <typename VarT>
-void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
+void GetVariableTraverser::traverse(const TType &type,
+ const TString &name,
+ std::vector<VarT> *output)
{
const TStructure *structure = type.getStruct();
@@ -309,15 +349,16 @@ void GetVariableTraverser::traverse(const TType &type, const TString &name, std:
traverse(*field->type(), field->name(), &variable.fields);
}
}
-
+ setTypeSpecificInfo(type, name, &variable);
visitVariable(&variable);
ASSERT(output);
output->push_back(variable);
}
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
}
diff --git a/src/3rdparty/angle/src/compiler/translator/util.h b/src/3rdparty/angle/src/compiler/translator/util.h
index 241e2cc1c2..fb5308759e 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.h
+++ b/src/3rdparty/angle/src/compiler/translator/util.h
@@ -24,6 +24,8 @@ extern bool atof_clamp(const char *str, float *value);
// Return false if overflow happens.
extern bool atoi_clamp(const char *str, int *value);
+class TSymbolTable;
+
namespace sh
{
@@ -38,7 +40,7 @@ TString ArrayString(const TType &type);
class GetVariableTraverser
{
public:
- GetVariableTraverser() {}
+ GetVariableTraverser(const TSymbolTable &symbolTable);
template <typename VarT>
void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
@@ -48,6 +50,14 @@ class GetVariableTraverser
virtual void visitVariable(ShaderVariable *newVar) {}
private:
+ // Helper function called by traverse() to fill specific fields
+ // for attributes/varyings/uniforms.
+ template <typename VarT>
+ void setTypeSpecificInfo(
+ const TType &type, const TString &name, VarT *variable) {}
+
+ const TSymbolTable &mSymbolTable;
+
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
};
diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.cpp b/src/3rdparty/angle/src/libEGL/AttributeMap.cpp
new file mode 100644
index 0000000000..28dd3d842e
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/AttributeMap.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "libEGL/AttributeMap.h"
+
+namespace egl
+{
+
+AttributeMap::AttributeMap()
+{
+}
+
+AttributeMap::AttributeMap(const EGLint *attributes)
+{
+ for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ insert(curAttrib[0], curAttrib[1]);
+ }
+}
+
+void AttributeMap::insert(EGLint key, EGLint value)
+{
+ mAttributes[key] = value;
+}
+
+bool AttributeMap::contains(EGLint key) const
+{
+ return (mAttributes.find(key) != mAttributes.end());
+}
+
+EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const
+{
+ std::map<EGLint, EGLint>::const_iterator iter = mAttributes.find(key);
+ return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.h b/src/3rdparty/angle/src/libEGL/AttributeMap.h
new file mode 100644
index 0000000000..f2f082fe21
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/AttributeMap.h
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef LIBEGL_ATTRIBUTEMAP_H_
+#define LIBEGL_ATTRIBUTEMAP_H_
+
+#include <EGL/egl.h>
+
+#include <map>
+
+namespace egl
+{
+
+class AttributeMap
+{
+ public:
+ AttributeMap();
+ explicit AttributeMap(const EGLint *attributes);
+
+ virtual void insert(EGLint key, EGLint value);
+ virtual bool contains(EGLint key) const;
+ virtual EGLint get(EGLint key, EGLint defaultValue) const;
+
+ private:
+ std::map<EGLint, EGLint> mAttributes;
+};
+
+}
+
+#endif // LIBEGL_ATTRIBUTEMAP_H_
diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
index 5a50e4baf5..eea93b1d87 100644
--- a/src/3rdparty/angle/src/libEGL/Display.cpp
+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
@@ -35,32 +35,36 @@ static DisplayMap *GetDisplayMap()
return &displays;
}
-egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType)
+egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
{
+ Display *display = NULL;
+
DisplayMap *displays = GetDisplayMap();
DisplayMap::const_iterator iter = displays->find(displayId);
if (iter != displays->end())
{
- return iter->second;
+ display = iter->second;
+ }
+ else
+ {
+ display = new egl::Display(displayId);
+ displays->insert(std::make_pair(displayId, display));
}
-
- // FIXME: Check if displayId is a valid display device context
- egl::Display *display = new egl::Display(displayId, displayType);
- displays->insert(std::make_pair(displayId, display));
+ // Apply new attributes if the display is not initialized yet.
+ if (!display->isInitialized())
+ {
+ display->setAttributes(attribMap);
+ }
return display;
}
-Display::Display(EGLNativeDisplayType displayId, EGLint displayType)
+Display::Display(EGLNativeDisplayType displayId)
: mDisplayId(displayId),
- mRequestedDisplayType(displayType),
+ mAttributeMap(),
mRenderer(NULL)
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mDisplayId)
- mDisplayId->AddRef();
-#endif
}
Display::~Display()
@@ -73,28 +77,29 @@ Display::~Display()
{
displays->erase(iter);
}
+}
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mDisplayId)
- mDisplayId->Release();
-#endif
+void Display::setAttributes(const AttributeMap &attribMap)
+{
+ mAttributeMap = attribMap;
}
-bool Display::initialize()
+Error Display::initialize()
{
if (isInitialized())
{
- return true;
+ return Error(EGL_SUCCESS);
}
- mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType);
+ mRenderer = glCreateRenderer(this, mDisplayId, mAttributeMap);
if (!mRenderer)
{
terminate();
- return error(EGL_NOT_INITIALIZED, false);
+ return Error(EGL_NOT_INITIALIZED);
}
+ //TODO(jmadill): should be part of caps?
EGLint minSwapInterval = mRenderer->getMinSwapInterval();
EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
@@ -125,13 +130,13 @@ bool Display::initialize()
if (!isInitialized())
{
terminate();
- return false;
+ return Error(EGL_NOT_INITIALIZED);
}
initDisplayExtensionString();
initVendorString();
- return true;
+ return Error(EGL_SUCCESS);
}
void Display::terminate()
@@ -148,6 +153,8 @@ void Display::terminate()
glDestroyRenderer(mRenderer);
mRenderer = NULL;
+
+ mConfigSet.mSet.clear();
}
bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
@@ -202,7 +209,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
-EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
+Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface)
{
const Config *configuration = mConfigSet.get(config);
EGLint postSubBufferSupported = EGL_FALSE;
@@ -223,9 +230,9 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
case EGL_BACK_BUFFER:
break;
case EGL_SINGLE_BUFFER:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported
+ return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
@@ -241,11 +248,11 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
fixedSize = attribList[1];
break;
case EGL_VG_COLORSPACE:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
case EGL_VG_ALPHA_FORMAT:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
attribList += 2;
@@ -254,7 +261,7 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
if (width < 0 || height < 0)
{
- return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ return Error(EGL_BAD_PARAMETER);
}
if (!fixedSize)
@@ -265,29 +272,33 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
if (hasExistingWindowSurface(window))
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ALLOC);
}
if (mRenderer->testDeviceLost(false))
{
- if (!restoreLostDevice())
- return EGL_NO_SURFACE;
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
}
Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported);
-
- if (!surface->initialize())
+ Error error = surface->initialize();
+ if (error.isError())
{
- delete surface;
- return EGL_NO_SURFACE;
+ SafeDelete(surface);
+ return error;
}
mSurfaceSet.insert(surface);
- return success(surface);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
}
-EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
+Error Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface)
{
EGLint width = 0, height = 0;
EGLenum textureFormat = EGL_NO_TEXTURE;
@@ -319,7 +330,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
textureFormat = attribList[1];
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_TEXTURE_TARGET:
@@ -330,19 +341,19 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
textureTarget = attribList[1];
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_MIPMAP_TEXTURE:
if (attribList[1] != EGL_FALSE)
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
break;
case EGL_VG_COLORSPACE:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
case EGL_VG_ALPHA_FORMAT:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
attribList += 2;
@@ -351,88 +362,100 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
if (width < 0 || height < 0)
{
- return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ return Error(EGL_BAD_PARAMETER);
}
if (width == 0 || height == 0)
{
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
{
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
}
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
{
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
}
if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
{
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
}
if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
(textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
{
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
if (mRenderer->testDeviceLost(false))
{
- if (!restoreLostDevice())
- return EGL_NO_SURFACE;
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
}
Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
-
- if (!surface->initialize())
+ Error error = surface->initialize();
+ if (error.isError())
{
- delete surface;
- return EGL_NO_SURFACE;
+ SafeDelete(surface);
+ return error;
}
mSurfaceSet.insert(surface);
- return success(surface);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
}
-EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
+Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
+ bool robustAccess, EGLContext *outContext)
{
if (!mRenderer)
{
- return EGL_NO_CONTEXT;
+ *outContext = EGL_NO_CONTEXT;
+ return Error(EGL_SUCCESS);
}
else if (mRenderer->testDeviceLost(false)) // Lost device
{
- if (!restoreLostDevice())
+ Error error = restoreLostDevice();
+ if (error.isError())
{
- return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
+ return error;
}
}
+ //TODO(jmadill): shader model is not cross-platform
if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4)
{
- return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ return Error(EGL_BAD_CONFIG);
}
gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
mContextSet.insert(context);
- return success(context);
+ *outContext = context;
+ return Error(EGL_SUCCESS);
}
-bool Display::restoreLostDevice()
+Error Display::restoreLostDevice()
{
for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
{
if ((*ctx)->isResetNotificationEnabled())
- return false; // If reset notifications have been requested, application must delete all contexts first
+ {
+ // If reset notifications have been requested, application must delete all contexts first
+ return Error(EGL_CONTEXT_LOST);
+ }
}
-
+
// Release surface resources to make the Reset() succeed
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
@@ -441,16 +464,20 @@ bool Display::restoreLostDevice()
if (!mRenderer->resetDevice())
{
- return error(EGL_BAD_ALLOC, false);
+ return Error(EGL_BAD_ALLOC);
}
// Restore any surfaces that may have been lost
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
- (*surface)->resetSwapChain();
+ Error error = (*surface)->resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
}
- return true;
+ return Error(EGL_SUCCESS);
}
@@ -472,7 +499,6 @@ void Display::notifyDeviceLost()
{
(*context)->markContextLost();
}
- egl::error(EGL_CONTEXT_LOST);
}
void Display::recreateSwapChains()
@@ -604,10 +630,11 @@ void Display::initVendorString()
LUID adapterLuid = {0};
+ //TODO(jmadill): LUID is not cross-platform
if (mRenderer && mRenderer->getLUID(&adapterLuid))
{
char adapterLuidString[64];
- snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
+ sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
mVendorString += adapterLuidString;
}
diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
index 73ba7673ff..b3ffcc84c5 100644
--- a/src/3rdparty/angle/src/libEGL/Display.h
+++ b/src/3rdparty/angle/src/libEGL/Display.h
@@ -14,7 +14,9 @@
#include <set>
#include <vector>
+#include "libEGL/Error.h"
#include "libEGL/Config.h"
+#include "libEGL/AttributeMap.h"
namespace gl
{
@@ -30,10 +32,10 @@ class Display
public:
~Display();
- bool initialize();
+ Error initialize();
void terminate();
- static egl::Display *getDisplay(EGLNativeDisplayType displayId, EGLint displayType);
+ static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap);
static const char *getExtensionString(egl::Display *display);
@@ -43,9 +45,10 @@ class Display
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
- EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
- EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
- EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+ Error createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface);
+ Error createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface);
+ Error createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
+ bool robustAccess, EGLContext *outContext);
void destroySurface(egl::Surface *surface);
void destroyContext(gl::Context *context);
@@ -64,18 +67,19 @@ class Display
const char *getExtensionString() const;
const char *getVendorString() const;
-
EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
private:
DISALLOW_COPY_AND_ASSIGN(Display);
- Display(EGLNativeDisplayType displayId, EGLint displayType);
+ Display(EGLNativeDisplayType displayId);
+
+ void setAttributes(const AttributeMap &attribMap);
- bool restoreLostDevice();
+ Error restoreLostDevice();
EGLNativeDisplayType mDisplayId;
- EGLint mRequestedDisplayType;
+ AttributeMap mAttributeMap;
typedef std::set<Surface*> SurfaceSet;
SurfaceSet mSurfaceSet;
diff --git a/src/3rdparty/angle/src/libEGL/Error.cpp b/src/3rdparty/angle/src/libEGL/Error.cpp
new file mode 100644
index 0000000000..df5f163d32
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/Error.cpp
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Error.cpp: Implements the egl::Error class which encapsulates an EGL error
+// and optional error message.
+
+#include "libEGL/Error.h"
+
+#include "common/angleutils.h"
+
+#include <cstdarg>
+
+namespace egl
+{
+
+Error::Error(EGLint errorCode)
+ : mCode(errorCode),
+ mMessage()
+{
+}
+
+Error::Error(EGLint errorCode, const char *msg, ...)
+ : mCode(errorCode),
+ mMessage()
+{
+ va_list vararg;
+ va_start(vararg, msg);
+ mMessage = FormatString(msg, vararg);
+ va_end(vararg);
+}
+
+Error::Error(const Error &other)
+ : mCode(other.mCode),
+ mMessage(other.mMessage)
+{
+}
+
+Error &Error::operator=(const Error &other)
+{
+ mCode = other.mCode;
+ mMessage = other.mMessage;
+ return *this;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libEGL/Error.h b/src/3rdparty/angle/src/libEGL/Error.h
new file mode 100644
index 0000000000..71805d2fb7
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/Error.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Error.h: Defines the egl::Error class which encapsulates an EGL error
+// and optional error message.
+
+#ifndef LIBEGL_ERROR_H_
+#define LIBEGL_ERROR_H_
+
+#include <EGL/egl.h>
+
+#include <string>
+
+namespace egl
+{
+
+class Error
+{
+ public:
+ explicit Error(EGLint errorCode);
+ Error(EGLint errorCode, const char *msg, ...);
+ Error(const Error &other);
+ Error &operator=(const Error &other);
+
+ EGLint getCode() const { return mCode; }
+ bool isError() const { return (mCode != EGL_SUCCESS); }
+
+ const std::string &getMessage() const { return mMessage; }
+
+ private:
+ EGLint mCode;
+ std::string mMessage;
+};
+
+}
+
+#endif // LIBEGL_ERROR_H_
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
index fa7996152a..b664a8530e 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
@@ -22,23 +22,19 @@
#include "libEGL/main.h"
#include "libEGL/Display.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-# include "wrl.h"
-# include "windows.graphics.display.h"
-# include "windows.ui.core.h"
-using namespace ABI::Windows::Graphics::Display;
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::UI::Core;
-using namespace Microsoft::WRL;
-#endif
+#include "common/NativeWindow.h"
+
+//TODO(jmadill): phase this out
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
namespace egl
{
-Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
- : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
+Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
+ : mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported)
{
- mRenderer = mDisplay->getRenderer();
+ //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
+ mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
mSwapChain = NULL;
mShareHandle = NULL;
mTexture = NULL;
@@ -51,27 +47,19 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
mSwapInterval = -1;
mWidth = width;
mHeight = height;
+ mFixedWidth = mWidth;
+ mFixedHeight = mHeight;
setSwapInterval(1);
mFixedSize = fixedSize;
- mSwapFlags = rx::SWAP_NORMAL;
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mWindow)
- mWindow->AddRef();
- mScaleFactor = 1.0;
- mSizeToken.value = 0;
- mDpiToken.value = 0;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- mOrientationToken.value = 0;
-# endif
-#endif
subclassWindow();
}
Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
- : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
+ : mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
{
- mRenderer = mDisplay->getRenderer();
+ //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
+ mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
mSwapChain = NULL;
mWindowSubclassed = false;
mTexture = NULL;
@@ -85,90 +73,33 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
setSwapInterval(1);
// This constructor is for offscreen surfaces, which are always fixed-size.
mFixedSize = EGL_TRUE;
- mSwapFlags = rx::SWAP_NORMAL;
-#if defined(ANGLE_PLATFORM_WINRT)
- mScaleFactor = 1.0;
- mSizeToken.value = 0;
- mDpiToken.value = 0;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- mOrientationToken.value = 0;
-# endif
-#endif
+ mFixedWidth = mWidth;
+ mFixedHeight = mHeight;
}
Surface::~Surface()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mSizeToken.value) {
- ComPtr<ICoreWindow> coreWindow;
- HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = coreWindow->remove_SizeChanged(mSizeToken);
- ASSERT(SUCCEEDED(hr));
- }
- if (mDpiToken.value) {
- ComPtr<IDisplayInformation> displayInformation;
- HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = displayInformation->remove_DpiChanged(mDpiToken);
- ASSERT(SUCCEEDED(hr));
- }
-# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- if (mOrientationToken.value) {
- ComPtr<IDisplayInformation> displayInformation;
- HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = displayInformation->remove_OrientationChanged(mOrientationToken);
- ASSERT(SUCCEEDED(hr));
- }
-# endif
-#endif
unsubclassWindow();
release();
}
-bool Surface::initialize()
-{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (!mFixedSize) {
- HRESULT hr;
- ComPtr<IDisplayInformation> displayInformation;
- hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
- onDpiChanged(displayInformation.Get(), 0);
- hr = displayInformation->add_DpiChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onDpiChanged).Get(),
- &mDpiToken);
- ASSERT(SUCCEEDED(hr));
-
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- onOrientationChanged(displayInformation.Get(), 0);
- hr = displayInformation->add_OrientationChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onOrientationChanged).Get(),
- &mOrientationToken);
- ASSERT(SUCCEEDED(hr));
-# endif
-
- ComPtr<ICoreWindow> coreWindow;
- hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- Rect rect;
- hr = coreWindow->get_Bounds(&rect);
- ASSERT(SUCCEEDED(hr));
- mWidth = rect.Width * mScaleFactor;
- mHeight = rect.Height * mScaleFactor;
- hr = coreWindow->add_SizeChanged(Callback<ITypedEventHandler<CoreWindow *, WindowSizeChangedEventArgs *>>(this, &Surface::onSizeChanged).Get(),
- &mSizeToken);
- ASSERT(SUCCEEDED(hr));
+Error Surface::initialize()
+{
+ if (mNativeWindow.getNativeWindow())
+ {
+ if (!mNativeWindow.initialize())
+ {
+ return Error(EGL_BAD_SURFACE);
+ }
}
-#endif
- if (!resetSwapChain())
- return false;
+ Error error = resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
- return true;
+ return Error(EGL_SUCCESS);
}
void Surface::release()
@@ -181,85 +112,80 @@ void Surface::release()
mTexture->releaseTexImage();
mTexture = NULL;
}
-
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mWindow)
- mWindow->Release();
-#endif
}
-bool Surface::resetSwapChain()
+Error Surface::resetSwapChain()
{
ASSERT(!mSwapChain);
int width;
int height;
-#if !defined(ANGLE_PLATFORM_WINRT)
if (!mFixedSize)
{
RECT windowRect;
- if (!GetClientRect(getWindowHandle(), &windowRect))
+ if (!mNativeWindow.getClientRect(&windowRect))
{
ASSERT(false);
- ERR("Could not retrieve the window dimensions");
- return error(EGL_BAD_SURFACE, false);
+ return Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions");
}
width = windowRect.right - windowRect.left;
height = windowRect.bottom - windowRect.top;
}
else
-#endif
{
// non-window surface - size is determined at creation
width = mWidth;
height = mHeight;
}
- mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
+ mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle,
mConfig->mRenderTargetFormat,
mConfig->mDepthStencilFormat);
if (!mSwapChain)
{
- return error(EGL_BAD_ALLOC, false);
+ return Error(EGL_BAD_ALLOC);
}
- if (!resetSwapChain(width, height))
+ Error error = resetSwapChain(width, height);
+ if (error.isError())
{
- delete mSwapChain;
- mSwapChain = NULL;
- return false;
+ SafeDelete(mSwapChain);
+ return error;
}
- return true;
+ return Error(EGL_SUCCESS);
}
-bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
{
- ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
ASSERT(mSwapChain);
- EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight));
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ backbufferWidth = std::max(1, backbufferWidth);
+ backbufferHeight = std::max(1, backbufferHeight);
+#endif
+ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
if (status == EGL_CONTEXT_LOST)
{
mDisplay->notifyDeviceLost();
- return false;
+ return Error(status);
}
else if (status != EGL_SUCCESS)
{
- return error(status, false);
+ return Error(status);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
- return true;
+ return Error(EGL_SUCCESS);
}
-bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+Error Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
ASSERT(mSwapChain);
@@ -269,69 +195,71 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
if (status == EGL_CONTEXT_LOST)
{
mRenderer->notifyDeviceLost();
- return false;
+ return Error(status);
}
else if (status != EGL_SUCCESS)
{
- return error(status, false);
+ return Error(status);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
mSwapIntervalDirty = false;
- return true;
+ return Error(EGL_SUCCESS);
}
-bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
- return true;
+ return Error(EGL_SUCCESS);
}
- if (x + width > mWidth)
+ if (x + width > abs(mWidth))
{
- width = mWidth - x;
+ width = abs(mWidth) - x;
}
- if (y + height > mHeight)
+ if (y + height > abs(mHeight))
{
- height = mHeight - y;
+ height = abs(mHeight) - y;
}
if (width == 0 || height == 0)
{
- return true;
+ return Error(EGL_SUCCESS);
}
- EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
if (status == EGL_CONTEXT_LOST)
{
mRenderer->notifyDeviceLost();
- return false;
+ return Error(status);
}
else if (status != EGL_SUCCESS)
{
- return error(status, false);
+ return Error(status);
}
checkForOutOfDateSwapChain();
- return true;
+ return Error(EGL_SUCCESS);
}
EGLNativeWindowType Surface::getWindowHandle()
{
- return mWindow;
+ return mNativeWindow.getNativeWindow();
}
-
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
-#if !defined(ANGLE_PLATFORM_WINRT)
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
@@ -349,45 +277,50 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
void Surface::subclassWindow()
{
-#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mWindow)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
{
return;
}
DWORD processId;
- DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
+ DWORD threadId = GetWindowThreadProcessId(window, &processId);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
{
return;
}
SetLastError(0);
- LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
+ LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
{
mWindowSubclassed = false;
return;
}
- SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
- SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
-#else
- mWindowSubclassed = false;
#endif
}
void Surface::unsubclassWindow()
{
-#if !defined(ANGLE_PLATFORM_WINRT)
if(!mWindowSubclassed)
{
return;
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
+ {
+ return;
+ }
+
// un-subclass
- LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
+ LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc));
// Check the windowproc is still SurfaceWindowProc.
// If this assert fails, then it is likely the application has subclassed the
@@ -396,29 +329,28 @@ void Surface::unsubclassWindow()
// EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc)
{
- LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
+ LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
UNUSED_ASSERTION_VARIABLE(prevWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
}
- RemoveProp(mWindow, kSurfaceProperty);
- RemoveProp(mWindow, kParentWndProc);
- mWindowSubclassed = false;
+ RemoveProp(window, kSurfaceProperty);
+ RemoveProp(window, kParentWndProc);
#endif
+ mWindowSubclassed = false;
}
bool Surface::checkForOutOfDateSwapChain()
{
+ RECT client;
int clientWidth = getWidth();
int clientHeight = getHeight();
bool sizeDirty = false;
-#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mFixedSize && !IsIconic(getWindowHandle()))
+ if (!mFixedSize && !mNativeWindow.isIconic())
{
- RECT client;
// The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized
// because that's not a useful size to render to.
- if (!GetClientRect(getWindowHandle(), &client))
+ if (!mNativeWindow.getClientRect(&client))
{
ASSERT(false);
return false;
@@ -429,7 +361,13 @@ bool Surface::checkForOutOfDateSwapChain()
clientHeight = client.bottom - client.top;
sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
}
-#endif
+
+ if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
+ {
+ clientWidth = mFixedWidth;
+ clientHeight = mFixedHeight;
+ sizeDirty = true;
+ }
bool wasDirty = (mSwapIntervalDirty || sizeDirty);
@@ -455,17 +393,17 @@ bool Surface::checkForOutOfDateSwapChain()
return false;
}
-bool Surface::swap()
+Error Surface::swap()
{
- return swapRect(0, 0, mWidth, mHeight);
+ return swapRect(0, 0, abs(mWidth), abs(mHeight));
}
-bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mPostSubBufferSupported)
{
// Spec is not clear about how this should be handled.
- return true;
+ return Error(EGL_SUCCESS);
}
return swapRect(x, y, width, height);
@@ -550,77 +488,18 @@ EGLint Surface::isFixedSize() const
return mFixedSize;
}
-EGLenum Surface::getFormat() const
+void Surface::setFixedWidth(EGLint width)
{
- return mConfig->mRenderTargetFormat;
+ mFixedWidth = width;
}
-#if defined(ANGLE_PLATFORM_WINRT)
-
-HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
+void Surface::setFixedHeight(EGLint height)
{
- HRESULT hr;
- Size size;
- hr = args->get_Size(&size);
- ASSERT(SUCCEEDED(hr));
-
- resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5),
- std::floor(size.Height * mScaleFactor + 0.5));
-
- if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
- {
- glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
- }
-
- return S_OK;
-}
-
-HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *)
-{
- HRESULT hr;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- ComPtr<IDisplayInformation2> displayInformation2;
- hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
- ASSERT(SUCCEEDED(hr));
-# else
- ResolutionScale resolutionScale;
- hr = displayInformation->get_ResolutionScale(&resolutionScale);
- ASSERT(SUCCEEDED(hr));
-
- mScaleFactor = double(resolutionScale) / 100.0;
-# endif
- return S_OK;
-}
-
-# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
-HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *)
-{
- HRESULT hr;
- DisplayOrientations orientation;
- hr = displayInformation->get_CurrentOrientation(&orientation);
- ASSERT(SUCCEEDED(hr));
- switch (orientation) {
- default:
- case DisplayOrientations_Portrait:
- mSwapFlags = rx::SWAP_NORMAL;
- break;
- case DisplayOrientations_Landscape:
- mSwapFlags = rx::SWAP_ROTATE_90;
- break;
- case DisplayOrientations_LandscapeFlipped:
- mSwapFlags = rx::SWAP_ROTATE_270;
- break;
- case DisplayOrientations_PortraitFlipped:
- mSwapFlags = rx::SWAP_ROTATE_180;
- break;
- }
- return S_OK;
+ mFixedHeight = height;
}
-# endif
-
-#endif
+EGLenum Surface::getFormat() const
+{
+ return mConfig->mRenderTargetFormat;
+}
}
diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
index ebffce8fed..46382d06e1 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ b/src/3rdparty/angle/src/libEGL/Surface.h
@@ -11,23 +11,12 @@
#ifndef LIBEGL_SURFACE_H_
#define LIBEGL_SURFACE_H_
+#include "libEGL/Error.h"
+
#include <EGL/egl.h>
#include "common/angleutils.h"
-
-#if defined(ANGLE_PLATFORM_WINRT)
-#include <EventToken.h>
-namespace ABI { namespace Windows {
- namespace UI { namespace Core {
- struct ICoreWindow;
- struct IWindowSizeChangedEventArgs;
- } }
- namespace Graphics { namespace Display {
- struct IDisplayInformation;
- } }
-} }
-struct IInspectable;
-#endif
+#include "common/NativeWindow.h"
namespace gl
{
@@ -35,8 +24,8 @@ class Texture2D;
}
namespace rx
{
-class Renderer;
class SwapChain;
+class RendererD3D; //TODO(jmadill): remove this
}
namespace egl
@@ -52,13 +41,13 @@ class Surface
virtual ~Surface();
- bool initialize();
+ Error initialize();
void release();
- bool resetSwapChain();
+ Error resetSwapChain();
EGLNativeWindowType getWindowHandle();
- bool swap();
- bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+ Error swap();
+ Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
virtual EGLint isPostSubBufferSupported() const;
@@ -81,35 +70,31 @@ class Surface
virtual gl::Texture2D *getBoundTexture() const;
EGLint isFixedSize() const;
+ void setFixedWidth(EGLint width);
+ void setFixedHeight(EGLint height);
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(Surface);
-#if defined(ANGLE_PLATFORM_WINRT)
- HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
- HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-# endif
-#endif
-
Display *const mDisplay;
- rx::Renderer *mRenderer;
+ rx::RendererD3D *mRenderer;
HANDLE mShareHandle;
rx::SwapChain *mSwapChain;
void subclassWindow();
void unsubclassWindow();
- bool resizeSwapChain(int backbufferWidth, int backbufferHeight);
- bool resetSwapChain(int backbufferWidth, int backbufferHeight);
- bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+ Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
+ Error resetSwapChain(int backbufferWidth, int backbufferHeight);
+ Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
- const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
EGLint mWidth; // Width of surface
+ EGLint mFixedHeight; // Pending height of the surface
+ EGLint mFixedWidth; // Pending width of the surface
// EGLint horizontalResolution; // Horizontal dot pitch
// EGLint verticalResolution; // Vertical dot pitch
// EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
@@ -126,18 +111,9 @@ private:
EGLint mSwapInterval;
EGLint mPostSubBufferSupported;
EGLint mFixedSize;
- EGLint mSwapFlags;
bool mSwapIntervalDirty;
gl::Texture2D *mTexture;
-#if defined(ANGLE_PLATFORM_WINRT)
- double mScaleFactor;
- EventRegistrationToken mSizeToken;
- EventRegistrationToken mDpiToken;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- EventRegistrationToken mOrientationToken;
-# endif
-#endif
};
}
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
index c2e0fd6d3d..68399d63a4 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -13,7 +13,6 @@
#include "common/debug.h"
#include "common/version.h"
-#include "common/platform.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/main.h"
@@ -26,16 +25,20 @@
#include "libEGL/Display.h"
#include "libEGL/Surface.h"
+#include "common/NativeWindow.h"
+
bool validateDisplay(egl::Display *display)
{
if (display == EGL_NO_DISPLAY)
{
- return egl::error(EGL_BAD_DISPLAY, false);
+ recordError(egl::Error(EGL_BAD_DISPLAY));
+ return false;
}
if (!display->isInitialized())
{
- return egl::error(EGL_NOT_INITIALIZED, false);
+ recordError(egl::Error(EGL_NOT_INITIALIZED));
+ return false;
}
return true;
@@ -50,7 +53,8 @@ bool validateConfig(egl::Display *display, EGLConfig config)
if (!display->isValidConfig(config))
{
- return egl::error(EGL_BAD_CONFIG, false);
+ recordError(egl::Error(EGL_BAD_CONFIG));
+ return false;
}
return true;
@@ -65,7 +69,8 @@ bool validateContext(egl::Display *display, gl::Context *context)
if (!display->isValidContext(context))
{
- return egl::error(EGL_BAD_CONTEXT, false);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return false;
}
return true;
@@ -80,7 +85,8 @@ bool validateSurface(egl::Display *display, egl::Surface *surface)
if (!display->isValidSurface(surface))
{
- return egl::error(EGL_BAD_SURFACE, false);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return false;
}
return true;
@@ -93,12 +99,7 @@ EGLint __stdcall eglGetError(void)
EVENT("()");
EGLint error = egl::getCurrentError();
-
- if (error != EGL_SUCCESS)
- {
- egl::setCurrentError(EGL_SUCCESS);
- }
-
+ recordError(egl::Error(EGL_SUCCESS));
return error;
}
@@ -106,7 +107,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
{
EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
- return egl::Display::getDisplay(display_id, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ return egl::Display::getDisplay(display_id, egl::AttributeMap());
}
EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
@@ -120,19 +121,26 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
break;
default:
- return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY);
+ recordError(egl::Error(EGL_BAD_CONFIG));
+ return EGL_NO_DISPLAY;
}
EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
-#if !defined(ANGLE_PLATFORM_WINRT)
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
// Validate the display device context
if (WindowFromDC(displayId) == NULL)
{
- return egl::success(EGL_NO_DISPLAY);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
}
#endif
- EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+ EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+ bool majorVersionSpecified = false;
+ bool minorVersionSpecified = false;
+ bool requestedWARP = false;
+
if (attrib_list)
{
for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
@@ -140,7 +148,69 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
switch (curAttrib[0])
{
case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
- requestedDisplayType = curAttrib[1];
+ switch (curAttrib[1])
+ {
+ case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
+ if (!egl::Display::supportsPlatformD3D())
+ {
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
+ if (!egl::Display::supportsPlatformOpenGL())
+ {
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
+ }
+ break;
+
+ default:
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
+ }
+ platformType = curAttrib[1];
+ break;
+
+ case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
+ if (curAttrib[1] != EGL_DONT_CARE)
+ {
+ majorVersionSpecified = true;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
+ if (curAttrib[1] != EGL_DONT_CARE)
+ {
+ minorVersionSpecified = true;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_USE_WARP_ANGLE:
+ if (!egl::Display::supportsPlatformD3D())
+ {
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
+ }
+
+ switch (curAttrib[1])
+ {
+ case EGL_FALSE:
+ case EGL_TRUE:
+ break;
+
+ default:
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
+ }
+
+ requestedWARP = (curAttrib[1] == EGL_TRUE);
break;
default:
@@ -149,33 +219,20 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
}
}
- switch (requestedDisplayType)
+ if (!majorVersionSpecified && minorVersionSpecified)
{
- case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
- break;
-
- case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE:
- if (!egl::Display::supportsPlatformD3D())
- {
- return egl::success(EGL_NO_DISPLAY);
- }
- break;
-
- case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
- if (!egl::Display::supportsPlatformOpenGL())
- {
- return egl::success(EGL_NO_DISPLAY);
- }
- break;
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
- default:
- return egl::success(EGL_NO_DISPLAY);
+ if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE && requestedWARP)
+ {
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
}
- return egl::Display::getDisplay(displayId, requestedDisplayType);
+ recordError(egl::Error(EGL_SUCCESS));
+ return egl::Display::getDisplay(displayId, egl::AttributeMap(attrib_list));
}
EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
@@ -185,20 +242,24 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
if (dpy == EGL_NO_DISPLAY)
{
- return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
- if (!display->initialize())
+ egl::Error error = display->initialize();
+ if (error.isError())
{
- return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
+ recordError(error);
+ return EGL_FALSE;
}
if (major) *major = 1;
if (minor) *minor = 4;
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
@@ -207,14 +268,16 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
if (dpy == EGL_NO_DISPLAY)
{
- return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
display->terminate();
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
@@ -227,19 +290,28 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
return NULL;
}
+ const char *result;
switch (name)
{
case EGL_CLIENT_APIS:
- return egl::success("OpenGL_ES");
+ result = "OpenGL_ES";
+ break;
case EGL_EXTENSIONS:
- return egl::success(egl::Display::getExtensionString(display));
+ result = egl::Display::getExtensionString(display);
+ break;
case EGL_VENDOR:
- return egl::success(display->getVendorString());
+ result = display->getVendorString();
+ break;
case EGL_VERSION:
- return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")");
+ result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
+ break;
default:
- return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return NULL;
}
+
+ recordError(egl::Error(EGL_SUCCESS));
+ return result;
}
EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@@ -257,17 +329,20 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
if (!num_config)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
const EGLint attribList[] = {EGL_NONE};
if (!display->getConfigs(configs, attribList, config_size, num_config))
{
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@@ -285,7 +360,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
if (!num_config)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
const EGLint attribList[] = {EGL_NONE};
@@ -297,7 +373,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
display->getConfigs(configs, attrib_list, config_size, num_config);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
@@ -314,10 +391,12 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
if (!display->getConfigAttrib(config, attribute, value))
{
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
@@ -332,16 +411,21 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
return EGL_NO_SURFACE;
}
-#if !defined(ANGLE_PLATFORM_WINRT)
- HWND window = (HWND)win;
+ if (!rx::IsValidEGLNativeWindowType(win))
+ {
+ recordError(egl::Error(EGL_BAD_NATIVE_WINDOW));
+ return EGL_NO_SURFACE;
+ }
- if (!IsWindow(window))
+ EGLSurface surface = EGL_NO_SURFACE;
+ egl::Error error = display->createWindowSurface(win, config, attrib_list, &surface);
+ if (error.isError())
{
- return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ recordError(error);
+ return EGL_NO_SURFACE;
}
-#endif
- return display->createWindowSurface(win, config, attrib_list);
+ return surface;
}
EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
@@ -356,7 +440,15 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
return EGL_NO_SURFACE;
}
- return display->createOffscreenSurface(config, NULL, attrib_list);
+ EGLSurface surface = EGL_NO_SURFACE;
+ egl::Error error = display->createOffscreenSurface(config, NULL, attrib_list, &surface);
+ if (error.isError())
+ {
+ recordError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return surface;
}
EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
@@ -373,7 +465,8 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
UNIMPLEMENTED(); // FIXME
- return egl::success(EGL_NO_SURFACE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_SURFACE;
}
EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
@@ -390,12 +483,14 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
display->destroySurface((egl::Surface*)surface);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
@@ -413,7 +508,8 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
switch (attribute)
@@ -473,10 +569,12 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
*value = eglSurface->isFixedSize();
break;
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
@@ -498,7 +596,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
rx::SwapChain *swapchain = eglSurface->getSwapChain();
@@ -522,7 +621,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
if (renderer->getMajorShaderModel() < 4)
{
- return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return EGL_FALSE;
}
*value = static_cast<rx::Renderer11*>(renderer)->getDevice();
@@ -530,10 +630,12 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
break;
#endif
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglBindAPI(EGLenum api)
@@ -544,16 +646,19 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
{
case EGL_OPENGL_API:
case EGL_OPENVG_API:
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE; // Not supported by this implementation
case EGL_OPENGL_ES_API:
break;
default:
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
egl::setCurrentAPI(api);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLenum __stdcall eglQueryAPI(void)
@@ -562,7 +667,8 @@ EGLenum __stdcall eglQueryAPI(void)
EGLenum API = egl::getCurrentAPI();
- return egl::success(API);
+ recordError(egl::Error(EGL_SUCCESS));
+ return API;
}
EGLBoolean __stdcall eglWaitClient(void)
@@ -571,7 +677,8 @@ EGLBoolean __stdcall eglWaitClient(void)
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglReleaseThread(void)
@@ -580,7 +687,8 @@ EGLBoolean __stdcall eglReleaseThread(void)
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
@@ -598,10 +706,19 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_NO_SURFACE;
+ }
+
+ EGLSurface surface = EGL_NO_SURFACE;
+ egl::Error error = display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list, &surface);
+ if (error.isError())
+ {
+ recordError(error);
+ return EGL_NO_SURFACE;
}
- return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
+ return surface;
}
EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
@@ -617,9 +734,30 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
return EGL_FALSE;
}
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ if (!eglSurface->isFixedSize() || !value) {
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+ eglSurface->setFixedWidth(value);
+ return EGL_TRUE;
+ case EGL_HEIGHT:
+ if (!eglSurface->isFixedSize() || !value) {
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+ eglSurface->setFixedHeight(value);
+ return EGL_TRUE;
+ default:
+ break;
+ }
+
UNIMPLEMENTED(); // FIXME
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
@@ -636,30 +774,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
if (buffer != EGL_BACK_BUFFER)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
if (eglSurface->getBoundTexture())
{
- return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ACCESS));
+ return EGL_FALSE;
}
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
if (!glBindTexImage(eglSurface))
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
@@ -676,17 +820,20 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
if (buffer != EGL_BACK_BUFFER)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
gl::Texture2D *texture = eglSurface->getBoundTexture();
@@ -696,7 +843,8 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
texture->releaseTexImage();
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
@@ -714,12 +862,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
if (draw_surface == NULL)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
draw_surface->setSwapInterval(interval);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
@@ -744,27 +894,38 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
if (attribute[1] == EGL_TRUE)
{
- return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
+ recordError(egl::Error(EGL_BAD_CONFIG)); // Unimplemented
+ return EGL_NO_CONTEXT;
// robust_access = true;
}
else if (attribute[1] != EGL_FALSE)
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ {
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_CONTEXT;
+ }
break;
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
+ {
reset_notification = true;
+ }
else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ {
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_CONTEXT;
+ }
break;
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_CONTEXT;
}
}
}
if (client_version != 2 && client_version != 3)
{
- return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_CONFIG));
+ return EGL_NO_CONTEXT;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -775,18 +936,21 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
{
- return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_NO_CONTEXT;
}
if (sharedGLContext->getClientVersion() != client_version)
{
- return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return EGL_NO_CONTEXT;
}
// Can not share contexts between displays
if (sharedGLContext->getRenderer() != display->getRenderer())
{
- return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_NO_CONTEXT;
}
}
@@ -795,7 +959,16 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return EGL_NO_CONTEXT;
}
- return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
+ EGLContext context = EGL_NO_CONTEXT;
+ egl::Error error = display->createContext(config, client_version, static_cast<gl::Context*>(share_context),
+ reset_notification, robust_access, &context);
+ if (error.isError())
+ {
+ recordError(error);
+ return EGL_NO_CONTEXT;
+ }
+
+ return context;
}
EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
@@ -812,12 +985,14 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
if (ctx == EGL_NO_CONTEXT)
{
- return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return EGL_FALSE;
}
display->destroyContext(context);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
@@ -832,7 +1007,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
if (noContext != noSurface)
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
@@ -850,7 +1026,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
if (renderer->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
}
@@ -871,7 +1048,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLContext __stdcall eglGetCurrentContext(void)
@@ -880,7 +1058,8 @@ EGLContext __stdcall eglGetCurrentContext(void)
EGLContext context = glGetCurrentContext();
- return egl::success(context);
+ recordError(egl::Error(EGL_SUCCESS));
+ return context;
}
EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
@@ -889,17 +1068,18 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
if (readdraw == EGL_READ)
{
- EGLSurface read = egl::getCurrentReadSurface();
- return egl::success(read);
+ recordError(egl::Error(EGL_SUCCESS));
+ return egl::getCurrentReadSurface();
}
else if (readdraw == EGL_DRAW)
{
- EGLSurface draw = egl::getCurrentDrawSurface();
- return egl::success(draw);
+ recordError(egl::Error(EGL_SUCCESS));
+ return egl::getCurrentDrawSurface();
}
else
{
- return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_NO_SURFACE;
}
}
@@ -909,7 +1089,8 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
EGLDisplay dpy = egl::getCurrentDisplay();
- return egl::success(dpy);
+ recordError(egl::Error(EGL_SUCCESS));
+ return dpy;
}
EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
@@ -927,7 +1108,8 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglWaitGL(void)
@@ -936,7 +1118,8 @@ EGLBoolean __stdcall eglWaitGL(void)
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglWaitNative(EGLint engine)
@@ -945,7 +1128,8 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
@@ -962,20 +1146,25 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
if (display->getRenderer()->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
- if (eglSurface->swap())
+ egl::Error error = eglSurface->swap();
+ if (error.isError())
{
- return egl::success(EGL_TRUE);
+ recordError(error);
+ return EGL_FALSE;
}
- return EGL_FALSE;
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
@@ -992,12 +1181,14 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
if (display->getRenderer()->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
@@ -1006,7 +1197,8 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
if (x < 0 || y < 0 || width < 0 || height < 0)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -1019,20 +1211,25 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
if (display->getRenderer()->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
- if (eglSurface->postSubBuffer(x, y, width, height))
+ egl::Error error = eglSurface->postSubBuffer(x, y, width, height);
+ if (error.isError())
{
- return egl::success(EGL_TRUE);
+ recordError(error);
+ return EGL_FALSE;
}
- return EGL_FALSE;
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index e74737eaba..e88cad775f 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -11,9 +11,6 @@
#include "common/debug.h"
#include "common/tls.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-__declspec(thread)
-#endif
static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
namespace egl
@@ -21,12 +18,6 @@ namespace egl
Current *AllocateCurrent()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- currentTLS = CreateTLSIndex();
- }
-#endif
ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
if (currentTLS == TLS_OUT_OF_INDEXES)
{
@@ -51,12 +42,6 @@ Current *AllocateCurrent()
void DeallocateCurrent()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- return;
- }
-#endif
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
SafeDelete(current);
SetTLSValue(currentTLS, NULL);
@@ -72,7 +57,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
{
case DLL_PROCESS_ATTACH:
{
-#if defined(ANGLE_ENABLE_TRACE)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
if (debug)
@@ -87,15 +72,15 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
}
#endif
-#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
- return DisableThreadLibraryCalls(instance);
-#endif
-
currentTLS = CreateTLSIndex();
if (currentTLS == TLS_OUT_OF_INDEXES)
{
return FALSE;
}
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+ gl::InitializeDebugAnnotations();
+#endif
}
// Fall through to initialize index
case DLL_THREAD_ATTACH:
@@ -105,15 +90,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
-#if !defined(ANGLE_PLATFORM_WINRT)
egl::DeallocateCurrent();
-#endif
}
break;
case DLL_PROCESS_DETACH:
{
egl::DeallocateCurrent();
DestroyTLSIndex(currentTLS);
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+ gl::UninitializeDebugAnnotations();
+#endif
}
break;
default:
@@ -143,11 +130,11 @@ Current *GetCurrentData()
#endif
}
-void setCurrentError(EGLint error)
+void recordError(const Error &error)
{
Current *current = GetCurrentData();
- current->error = error;
+ current->error = error.getCode();
}
EGLint getCurrentError()
@@ -213,9 +200,4 @@ EGLSurface getCurrentReadSurface()
return current->readSurface;
}
-void error(EGLint errorCode)
-{
- egl::setCurrentError(errorCode);
-}
-
}
diff --git a/src/3rdparty/angle/src/libEGL/main.h b/src/3rdparty/angle/src/libEGL/main.h
index 07f5b9e675..e5361a4a5e 100644
--- a/src/3rdparty/angle/src/libEGL/main.h
+++ b/src/3rdparty/angle/src/libEGL/main.h
@@ -9,6 +9,8 @@
#ifndef LIBEGL_MAIN_H_
#define LIBEGL_MAIN_H_
+#include "libEGL/Error.h"
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -23,7 +25,7 @@ struct Current
EGLSurface readSurface;
};
-void setCurrentError(EGLint error);
+void recordError(const Error &error);
EGLint getCurrentError();
void setCurrentAPI(EGLenum API);
@@ -38,24 +40,6 @@ EGLSurface getCurrentDrawSurface();
void setCurrentReadSurface(EGLSurface surface);
EGLSurface getCurrentReadSurface();
-void error(EGLint errorCode);
-
-template<class T>
-const T &error(EGLint errorCode, const T &returnValue)
-{
- error(errorCode);
-
- return returnValue;
-}
-
-template<class T>
-const T &success(const T &returnValue)
-{
- egl::setCurrentError(EGL_SUCCESS);
-
- return returnValue;
-}
-
}
#endif // LIBEGL_MAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
index 4d7dde04e1..4f7f5f2c85 100644
--- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
+++ b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
@@ -15,6 +15,7 @@
#include <cstddef>
#include <string>
#include <vector>
+#include <stdint.h>
namespace gl
{
@@ -26,7 +27,7 @@ class BinaryInputStream
{
mError = false;
mOffset = 0;
- mData = static_cast<const char*>(data);
+ mData = static_cast<const uint8_t*>(data);
mLength = length;
}
@@ -85,7 +86,7 @@ class BinaryInputStream
return;
}
- v->assign(mData + mOffset, length);
+ v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
mOffset += length;
}
@@ -115,11 +116,16 @@ class BinaryInputStream
return mOffset == mLength;
}
+ const uint8_t *data()
+ {
+ return mData;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
bool mError;
size_t mOffset;
- const char *mData;
+ const uint8_t *mData;
size_t mLength;
template <typename T>
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
index 35a6767502..daa862ca0d 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
@@ -19,7 +19,6 @@
namespace rx
{
-class Renderer;
class BufferImpl;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
index 5342de1331..b87689cd3f 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
@@ -9,10 +9,8 @@
#include "libGLESv2/Context.h"
-#include "libGLESv2/main.h"
#include "common/utilities.h"
#include "common/platform.h"
-#include "libGLESv2/formatutils.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Fence.h"
#include "libGLESv2/Framebuffer.h"
@@ -21,14 +19,15 @@
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Query.h"
-#include "libGLESv2/Texture.h"
#include "libGLESv2/ResourceManager.h"
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Sampler.h"
-#include "libGLESv2/validationES.h"
+#include "libGLESv2/Texture.h"
#include "libGLESv2/TransformFeedback.h"
+#include "libGLESv2/VertexArray.h"
+#include "libGLESv2/formatutils.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/validationES.h"
+#include "libGLESv2/renderer/Renderer.h"
#include "libEGL/Surface.h"
@@ -38,7 +37,7 @@
namespace gl
{
-Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
+Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
: mRenderer(renderer)
{
ASSERT(robustAccess == false); // Unimplemented
@@ -66,22 +65,24 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
- bindTexture(GL_TEXTURE_2D, 0);
+ Texture2D *zeroTexture2D = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0);
+ mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
- mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
- bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ TextureCubeMap *zeroTextureCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0);
+ mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
if (mClientVersion >= 3)
{
// TODO: These could also be enabled via extension
- mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
- bindTexture(GL_TEXTURE_3D, 0);
+ Texture3D *zeroTexture3D = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0);
+ mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
- mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
- bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+ Texture2DArray *zeroTexture2DArray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0);
+ mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
}
+ mState.initializeZeroTextures(mZeroTextures);
+
bindVertexArray(0);
bindArrayBuffer(0);
bindElementArrayBuffer(0);
@@ -91,13 +92,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
bindRenderbuffer(0);
bindGenericUniformBuffer(0);
- for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+ for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
{
bindIndexedUniformBuffer(0, i, 0, -1);
}
bindGenericTransformFeedbackBuffer(0);
- for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (unsigned int i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++)
{
bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
}
@@ -119,8 +120,6 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
-
- mState.setContext(this);
}
Context::~Context()
@@ -175,7 +174,10 @@ Context::~Context()
}
mZeroTextures.clear();
- mResourceManager->release();
+ if (mResourceManager)
+ {
+ mResourceManager->release();
+ }
}
void Context::makeCurrent(egl::Surface *surface)
@@ -194,14 +196,11 @@ void Context::makeCurrent(egl::Surface *surface)
// Wrap the existing swapchain resources into GL objects and assign them to the '0' names
rx::SwapChain *swapchain = surface->getSwapChain();
- Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
- DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
- Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
+ rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false);
+ rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true);
+ Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
setFramebufferZero(framebufferZero);
-
- // Store the current client version in the renderer
- mRenderer->setCurrentClientVersion(mClientVersion);
}
// NOTE: this function should not assume that this context is current!
@@ -229,7 +228,7 @@ GLuint Context::createProgram()
GLuint Context::createShader(GLenum type)
{
- return mResourceManager->createShader(type);
+ return mResourceManager->createShader(getData(), type);
}
GLuint Context::createTexture()
@@ -242,15 +241,10 @@ GLuint Context::createRenderbuffer()
return mResourceManager->createRenderbuffer();
}
-GLsync Context::createFenceSync(GLenum condition)
+GLsync Context::createFenceSync()
{
GLuint handle = mResourceManager->createFenceSync();
- gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
- ASSERT(fenceSync);
-
- fenceSync->set(condition);
-
return reinterpret_cast<GLsync>(handle);
}
@@ -294,7 +288,7 @@ GLuint Context::createFenceNV()
{
GLuint handle = mFenceNVHandleAllocator.allocate();
- mFenceNVMap[handle] = new FenceNV(mRenderer);
+ mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
return handle;
}
@@ -355,12 +349,12 @@ void Context::deleteFenceSync(GLsync fenceSync)
// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
// and since our API is currently designed for being called from a single thread, we can delete
// the fence immediately.
- mResourceManager->deleteFenceSync(uintptr_t(fenceSync));
+ mResourceManager->deleteFenceSync(reinterpret_cast<uintptr_t>(fenceSync));
}
void Context::deleteVertexArray(GLuint vertexArray)
{
- auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
+ VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray);
if (vertexArrayObject != mVertexArrayMap.end())
{
@@ -461,12 +455,12 @@ Renderbuffer *Context::getRenderbuffer(GLuint handle)
FenceSync *Context::getFenceSync(GLsync handle) const
{
- return mResourceManager->getFenceSync(uintptr_t(handle));
+ return mResourceManager->getFenceSync(reinterpret_cast<uintptr_t>(handle));
}
VertexArray *Context::getVertexArray(GLuint handle) const
{
- auto vertexArray = mVertexArrayMap.find(handle);
+ VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle);
if (vertexArray == mVertexArrayMap.end())
{
@@ -515,18 +509,30 @@ void Context::bindElementArrayBuffer(unsigned int buffer)
mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
}
-void Context::bindTexture(GLenum target, GLuint texture)
+void Context::bindTexture(GLenum target, GLuint handle)
{
- mResourceManager->checkTextureAllocation(texture, target);
+ Texture *texture = NULL;
+
+ if (handle == 0)
+ {
+ texture = mZeroTextures[target].get();
+ }
+ else
+ {
+ mResourceManager->checkTextureAllocation(handle, target);
+ texture = getTexture(handle);
+ }
- mState.setSamplerTexture(target, getTexture(texture));
+ ASSERT(texture);
+
+ mState.setSamplerTexture(target, texture);
}
void Context::bindReadFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
+ mFramebufferMap[framebuffer] = new Framebuffer(framebuffer);
}
mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
@@ -536,7 +542,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
+ mFramebufferMap[framebuffer] = new Framebuffer(framebuffer);
}
mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
@@ -640,33 +646,44 @@ void Context::useProgram(GLuint program)
}
}
-void Context::linkProgram(GLuint program)
+Error Context::linkProgram(GLuint program)
{
Program *programObject = mResourceManager->getProgram(program);
- bool linked = programObject->link(getCaps());
+ Error error = programObject->link(getData());
+ if (error.isError())
+ {
+ return error;
+ }
// if the current program was relinked successfully we
// need to install the new executables
- if (linked && program == mState.getCurrentProgramId())
+ if (programObject->isLinked() && program == mState.getCurrentProgramId())
{
mState.setCurrentProgramBinary(programObject->getProgramBinary());
}
+
+ return Error(GL_NO_ERROR);
}
-void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
{
Program *programObject = mResourceManager->getProgram(program);
- bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
+ Error error = programObject->setProgramBinary(binaryFormat, binary, length);
+ if (error.isError())
+ {
+ return error;
+ }
// if the current program was reloaded successfully we
// need to install the new executables
- if (loaded && program == mState.getCurrentProgramId())
+ if (programObject->isLinked() && program == mState.getCurrentProgramId())
{
mState.setCurrentProgramBinary(programObject->getProgramBinary());
}
+ return Error(GL_NO_ERROR);
}
void Context::bindTransformFeedback(GLuint transformFeedback)
@@ -724,33 +741,6 @@ void Context::setFramebufferZero(Framebuffer *buffer)
mFramebufferMap[0] = buffer;
}
-void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
-{
- ASSERT(getTextureCaps().get(internalformat).renderable);
-
- RenderbufferStorage *renderbuffer = NULL;
-
- const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
- if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
- {
- renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
- }
- else if (formatInfo.depthBits > 0)
- {
- renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
- }
- else if (formatInfo.stencilBits > 0)
- {
- renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
- }
- else
- {
- renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples);
- }
-
- mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
-}
-
Framebuffer *Context::getFramebuffer(unsigned int handle) const
{
FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
@@ -837,14 +827,7 @@ Texture2DArray *Context::getTexture2DArray() const
Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- if (mState.getSamplerTextureId(sampler, type) == 0)
- {
- return mZeroTextures.at(type).get();
- }
- else
- {
- return mState.getSamplerTexture(sampler, type);
- }
+ return mState.getSamplerTexture(sampler, type);
}
void Context::getBooleanv(GLenum pname, GLboolean *params)
@@ -962,7 +945,7 @@ void Context::getIntegerv(GLenum pname, GLint *params)
*params = static_cast<GLint>(mExtensionStrings.size());
break;
default:
- mState.getIntegerv(pname, params);
+ mState.getIntegerv(getData(), pname, params);
break;
}
}
@@ -1309,309 +1292,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
return false;
}
-// Applies the render target surface, depth stencil surface, viewport rectangle and
-// scissor rectangle to the renderer
-Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
-{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
- ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
-
- gl::Error error = mRenderer->applyRenderTarget(framebufferObject);
- if (error.isError())
- {
- return error;
- }
-
- float nearZ, farZ;
- mState.getDepthRange(&nearZ, &farZ);
- mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
- ignoreViewport);
-
- mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
-
- return gl::Error(GL_NO_ERROR);
-}
-
-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
-Error Context::applyState(GLenum drawMode)
-{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
- int samples = framebufferObject->getSamples();
-
- RasterizerState rasterizer = mState.getRasterizerState();
- rasterizer.pointDrawMode = (drawMode == GL_POINTS);
- rasterizer.multiSample = (samples != 0);
-
- Error error = mRenderer->setRasterizerState(rasterizer);
- if (error.isError())
- {
- return error;
- }
-
- unsigned int mask = 0;
- if (mState.isSampleCoverageEnabled())
- {
- GLclampf coverageValue;
- bool coverageInvert = false;
- mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
- if (coverageValue != 0)
- {
- float threshold = 0.5f;
-
- for (int i = 0; i < samples; ++i)
- {
- mask <<= 1;
-
- if ((i + 1) * coverageValue >= threshold)
- {
- threshold += 1.0f;
- mask |= 1;
- }
- }
- }
-
- if (coverageInvert)
- {
- mask = ~mask;
- }
- }
- else
- {
- mask = 0xFFFFFFFF;
- }
- error = mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
- if (error.isError())
- {
- return error;
- }
-
- error = mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
- rasterizer.frontFace == GL_CCW);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-// Applies the shaders and shader constants to the Direct3D 9 device
-Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
-{
- const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
-
- VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
- VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
-
- const Framebuffer *fbo = mState.getDrawFramebuffer();
-
- Error error = mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- return programBinary->applyUniforms();
-}
-
-Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
-{
- size_t samplerRange = programBinary->getUsedSamplerRange(type);
-
- for (size_t i = 0; i < samplerRange; i++)
- {
- GLenum textureType = programBinary->getSamplerTextureType(type, i);
- GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
- if (textureUnit != -1)
- {
- Texture* texture = getSamplerTexture(textureUnit, textureType);
- if (texture->getSamplerState().swizzleRequired())
- {
- Error error = mRenderer->generateSwizzle(texture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::generateSwizzles(ProgramBinary *programBinary)
-{
- Error error = generateSwizzles(programBinary, SAMPLER_VERTEX);
- if (error.isError())
- {
- return error;
- }
-
- error = generateSwizzles(programBinary, SAMPLER_PIXEL);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-// For each Direct3D sampler of either the pixel or vertex stage,
-// looks up the corresponding OpenGL texture image unit and texture type,
-// and sets the texture and its addressing/filtering state (or NULL when inactive).
-Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
- const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
-{
- size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
- for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
- {
- GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
- GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
- if (textureUnit != -1)
- {
- SamplerState sampler;
- Texture* texture = getSamplerTexture(textureUnit, textureType);
- texture->getSamplerStateWithNativeOffset(&sampler);
-
- Sampler *samplerObject = mState.getSampler(textureUnit);
- if (samplerObject)
- {
- samplerObject->getState(&sampler);
- }
-
- // TODO: std::binary_search may become unavailable using older versions of GCC
- if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
- !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
- {
- Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
- if (error.isError())
- {
- return error;
- }
-
- error = mRenderer->setTexture(shaderType, samplerIndex, texture);
- if (error.isError())
- {
- return error;
- }
- }
- else
- {
- // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
- Texture *incompleteTexture = getIncompleteTexture(textureType);
- gl::Error error = mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- else
- {
- // No texture bound to this slot even though it is used by the shader, bind a NULL texture
- Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
- }
-
- // Set all the remaining textures to NULL
- size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
- : mCaps.maxVertexTextureImageUnits;
- for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
- {
- Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::applyTextures(ProgramBinary *programBinary)
-{
- FramebufferTextureSerialArray framebufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
-
- Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::applyUniformBuffers()
-{
- Program *programObject = getProgram(mState.getCurrentProgramId());
- ProgramBinary *programBinary = programObject->getProgramBinary();
-
- std::vector<Buffer*> boundBuffers;
-
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
- {
- GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
-
- if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
- {
- // undefined behaviour
- return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
- }
- else
- {
- Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
- ASSERT(uniformBuffer);
- boundBuffers.push_back(uniformBuffer);
- }
- }
-
- return programBinary->applyUniformBuffers(boundBuffers, getCaps());
-}
-
-bool Context::applyTransformFeedbackBuffers()
-{
- TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
- {
- Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
- {
- transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
- transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
- }
- mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void Context::markTransformFeedbackUsage()
-{
- for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
- {
- Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
- if (buffer)
- {
- buffer->markTransformFeedbackUsage();
- }
- }
-}
-
Error Context::clear(GLbitfield mask)
{
if (mState.isRasterizerDiscardEnabled())
@@ -1619,290 +1299,71 @@ Error Context::clear(GLbitfield mask)
return Error(GL_NO_ERROR);
}
- ClearParameters clearParams = mState.getClearParameters(mask);
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(getData(), mask);
}
-Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
+Error Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferfv can be called to clear the color buffer or depth buffer
- ClearParameters clearParams = mState.getClearParameters(0);
-
- if (buffer == GL_COLOR)
- {
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_FLOAT;
- }
-
- if (buffer == GL_DEPTH)
- {
- clearParams.clearDepth = true;
- clearParams.depthClearValue = values[0];
- }
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferfv(getData(), buffer, drawbuffer, values);
}
-Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
+Error Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferuv can only be called to clear a color buffer
- ClearParameters clearParams = mState.getClearParameters(0);
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_UNSIGNED_INT;
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferuiv(getData(), buffer, drawbuffer, values);
}
-Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
+Error Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferfv can be called to clear the color buffer or stencil buffer
- ClearParameters clearParams = mState.getClearParameters(0);
-
- if (buffer == GL_COLOR)
- {
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_INT;
- }
-
- if (buffer == GL_STENCIL)
- {
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = values[1];
- }
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferiv(getData(), buffer, drawbuffer, values);
}
-Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
+Error Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferfi can only be called to clear a depth stencil buffer
- ClearParameters clearParams = mState.getClearParameters(0);
- clearParams.clearDepth = true;
- clearParams.depthClearValue = depth;
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = stencil;
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferfi(getData(), buffer, drawbuffer, depth, stencil);
}
Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
- Framebuffer *framebuffer = mState.getReadFramebuffer();
-
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
- const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
- GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
-
- return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
- reinterpret_cast<uint8_t*>(pixels));
+ return mRenderer->readPixels(getData(), x, y, width, height, format, type, bufSize, pixels);
}
Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
- ASSERT(mState.getCurrentProgramId() != 0);
-
- ProgramBinary *programBinary = mState.getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- Error error = generateSwizzles(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- if (!mRenderer->applyPrimitiveType(mode, count))
- {
- return Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(mode);
- if (error.isError())
- {
- return error;
- }
-
- error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers();
-
- error = applyShaders(programBinary, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers();
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(mode))
- {
- error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- if (transformFeedbackActive)
- {
- markTransformFeedbackUsage();
- }
- }
-
- return gl::Error(GL_NO_ERROR);
+ return mRenderer->drawArrays(getData(), mode, first, count, instances);
}
Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange)
{
- ASSERT(mState.getCurrentProgramId() != 0);
-
- ProgramBinary *programBinary = mState.getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- Error error = generateSwizzles(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- if (!mRenderer->applyPrimitiveType(mode, count))
- {
- return Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(mode);
- if (error.isError())
- {
- return error;
- }
-
- VertexArray *vao = mState.getVertexArray();
- rx::TranslatedIndexData indexInfo;
- indexInfo.indexRange = indexRange;
- error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
- if (error.isError())
- {
- return error;
- }
-
- GLsizei vertexCount = indexInfo.indexRange.length() + 1;
- error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
- mState.getVertexAttribCurrentValues(),
- indexInfo.indexRange.start, vertexCount, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers();
- // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
- // layer.
- ASSERT(!transformFeedbackActive);
-
- error = applyShaders(programBinary, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers();
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(mode))
- {
- error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(GL_NO_ERROR);
+ return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange);
}
// Implements glFlush when block is false, glFinish when block is true
-void Context::sync(bool block)
+Error Context::sync(bool block)
{
- mRenderer->sync(block);
+ return mRenderer->sync(block);
}
void Context::recordError(const Error &error)
@@ -1931,6 +1392,7 @@ GLenum Context::getError()
GLenum Context::getResetStatus()
{
+ //TODO(jmadill): needs MANGLE reworking
if (mResetStatus == GL_NO_ERROR && !mContextLost)
{
// mResetStatus will be set by the markContextLost callback
@@ -1981,7 +1443,7 @@ const Extensions &Context::getExtensions() const
void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
{
Framebuffer *framebuffer = mState.getReadFramebuffer();
- ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
+ ASSERT(framebuffer && framebuffer->completeness(getData()) == GL_FRAMEBUFFER_COMPLETE);
FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
ASSERT(attachment);
@@ -2000,7 +1462,7 @@ void Context::detachTexture(GLuint texture)
// allocation map management either here or in the resource manager at detach time.
// Zero textures are held by the Context, and we don't attempt to request them from
// the State.
- mState.detachTexture(texture);
+ mState.detachTexture(mZeroTextures, texture);
}
void Context::detachBuffer(GLuint buffer)
@@ -2072,95 +1534,6 @@ void Context::detachSampler(GLuint sampler)
mState.detachSampler(sampler);
}
-Texture *Context::getIncompleteTexture(GLenum type)
-{
- if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
- {
- const GLubyte color[] = { 0, 0, 0, 255 };
- const PixelUnpackState incompleteUnpackState(1);
-
- Texture* t = NULL;
- switch (type)
- {
- default:
- UNREACHABLE();
- // default falls through to TEXTURE_2D
-
- case GL_TEXTURE_2D:
- {
- Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
- incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- t = incomplete2d;
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP:
- {
- TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
-
- incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incompleteCube;
- }
- break;
-
- case GL_TEXTURE_3D:
- {
- Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
- incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incomplete3d;
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
- incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incomplete2darray;
- }
- break;
- }
-
- mIncompleteTextures[type].set(t);
- }
-
- return mIncompleteTextures[type].get();
-}
-
-bool Context::skipDraw(GLenum drawMode)
-{
- if (drawMode == GL_POINTS)
- {
- // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
- // which affects varying interpolation. Since the value of gl_PointSize is
- // undefined when not written, just skip drawing to avoid unexpected results.
- if (!mState.getCurrentProgramBinary()->usesPointSize())
- {
- // This is stictly speaking not an error, but developers should be
- // notified of risking undefined behavior.
- ERR("Point rendering without writing to gl_PointSize.");
-
- return true;
- }
- }
- else if (IsTriangleMode(drawMode))
- {
- if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
- {
- return true;
- }
- }
-
- return false;
-}
-
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
@@ -2293,63 +1666,12 @@ size_t Context::getExtensionStringCount() const
return mExtensionStrings.size();
}
-size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
+Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
{
- size_t serialCount = 0;
-
- Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
- {
- FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
- if (attachment && attachment->isTexture())
- {
- Texture *texture = attachment->getTexture();
- (*outSerialArray)[serialCount++] = texture->getTextureSerial();
- }
- }
-
- FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
- if (depthStencilAttachment && depthStencilAttachment->isTexture())
- {
- Texture *depthStencilTexture = depthStencilAttachment->getTexture();
- (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
- }
-
- std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
-
- return serialCount;
-}
-
-void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- Framebuffer *readFramebuffer = mState.getReadFramebuffer();
- Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
-
- bool blitRenderTarget = false;
- bool blitDepth = false;
- bool blitStencil = false;
- if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
- {
- blitRenderTarget = true;
- }
- if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
- {
- blitStencil = true;
- }
- if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
- {
- blitDepth = true;
- }
-
- Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
- Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
- if (blitRenderTarget || blitDepth || blitStencil)
- {
- const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
- mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
- blitRenderTarget, blitDepth, blitStencil, filter);
- }
+ return mRenderer->blitFramebuffer(getData(), srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void Context::releaseShaderCompiler()
@@ -2416,6 +1738,11 @@ void Context::initCaps(GLuint clientVersion)
mExtensions.maxSamples = maxSamples;
}
+Data Context::getData() const
+{
+ return Data(mClientVersion, mState, mCaps, mTextureCaps, mExtensions, mResourceManager);
+}
+
}
extern "C"
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
index 1b888aec83..1e890de3ef 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.h
+++ b/src/3rdparty/angle/src/libGLESv2/Context.h
@@ -13,12 +13,12 @@
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/Caps.h"
+#include "libGLESv2/Constants.h"
+#include "libGLESv2/Data.h"
#include "libGLESv2/Error.h"
#include "libGLESv2/HandleAllocator.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/State.h"
+#include "libGLESv2/angletypes.h"
#include "angle_gl.h"
@@ -50,11 +50,6 @@ class Texture3D;
class Texture2DArray;
class Framebuffer;
class Renderbuffer;
-class RenderbufferStorage;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
class FenceNV;
class FenceSync;
class Query;
@@ -68,7 +63,7 @@ class TransformFeedback;
class Context
{
public:
- Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
+ Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
virtual ~Context();
@@ -86,7 +81,7 @@ class Context
GLuint createRenderbuffer();
GLuint createSampler();
GLuint createTransformFeedback();
- GLsync createFenceSync(GLenum condition);
+ GLsync createFenceSync();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
@@ -115,7 +110,7 @@ class Context
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
- void bindTexture(GLenum target, GLuint texture);
+ void bindTexture(GLenum target, GLuint handle);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
@@ -130,8 +125,8 @@ class Context
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
- void linkProgram(GLuint program);
- void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+ Error linkProgram(GLuint program);
+ Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
Error beginQuery(GLenum target, GLuint query);
@@ -139,8 +134,6 @@ class Context
void setFramebufferZero(Framebuffer *framebuffer);
- void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
-
void setVertexAttribDivisor(GLuint index, GLuint divisor);
void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
@@ -183,17 +176,17 @@ class Context
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
Error clear(GLbitfield mask);
- Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
- Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
- Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
- Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
+ Error clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values);
+ Error clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values);
+ Error clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values);
+ Error clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
Error drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange);
- void sync(bool block); // flush/finish
+ Error sync(bool block); // flush/finish
void recordError(const Error &error);
@@ -215,32 +208,21 @@ class Context
void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type);
- void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
+ Error blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
rx::Renderer *getRenderer() { return mRenderer; }
State &getState() { return mState; }
const State &getState() const { return mState; }
+ Data getData() const;
+
void releaseShaderCompiler();
private:
DISALLOW_COPY_AND_ASSIGN(Context);
- // TODO: std::array may become unavailable using older versions of GCC
- typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
-
- Error applyRenderTarget(GLenum drawMode, bool ignoreViewport);
- Error applyState(GLenum drawMode);
- Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
- Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
- size_t framebufferSerialCount);
- Error applyTextures(ProgramBinary *programBinary);
- Error applyUniformBuffers();
- bool applyTransformFeedbackBuffers();
- void markTransformFeedbackUsage();
-
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
@@ -249,18 +231,9 @@ class Context
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
- Error generateSwizzles(ProgramBinary *programBinary, SamplerType type);
- Error generateSwizzles(ProgramBinary *programBinary);
-
- Texture *getIncompleteTexture(GLenum type);
-
- bool skipDraw(GLenum drawMode);
-
void initRendererString();
void initExtensionStrings();
- size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
-
void initCaps(GLuint clientVersion);
// Caps to use for validation
@@ -273,7 +246,6 @@ class Context
int mClientVersion;
- typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
TextureMap mZeroTextures;
TextureMap mIncompleteTextures;
diff --git a/src/3rdparty/angle/src/libGLESv2/Data.cpp b/src/3rdparty/angle/src/libGLESv2/Data.cpp
new file mode 100644
index 0000000000..3ddf591d77
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Data.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Data.cpp: Container class for all GL relevant state, caps and objects
+
+#include "libGLESv2/Data.h"
+#include "libGLESv2/ResourceManager.h"
+
+namespace gl
+{
+
+Data::Data(GLint clientVersionIn, const State &stateIn, const Caps &capsIn,
+ const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn,
+ const ResourceManager *resourceManagerIn)
+ : clientVersion(clientVersionIn),
+ state(&stateIn),
+ caps(&capsIn),
+ textureCaps(&textureCapsIn),
+ extensions(&extensionsIn),
+ resourceManager(resourceManagerIn)
+{}
+
+Data::~Data()
+{
+}
+
+Data::Data(const Data &other)
+ : clientVersion(other.clientVersion),
+ state(other.state),
+ caps(other.caps),
+ textureCaps(other.textureCaps),
+ extensions(other.extensions),
+ resourceManager(other.resourceManager)
+{
+}
+
+Data &Data::operator=(const Data &other)
+{
+ clientVersion = other.clientVersion;
+ state = other.state;
+ caps = other.caps;
+ textureCaps = other.textureCaps;
+ extensions = other.extensions;
+ resourceManager = other.resourceManager;
+ return *this;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h
new file mode 100644
index 0000000000..9234403e13
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Data.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Data.h: Container class for all GL relevant state, caps and objects
+
+#ifndef LIBGLESV2_DATA_H_
+#define LIBGLESV2_DATA_H_
+
+#include "libGLESv2/State.h"
+
+namespace gl
+{
+
+struct Data
+{
+ public:
+ Data(GLint clientVersion, const State &state, const Caps &caps,
+ const TextureCapsMap &textureCaps, const Extensions &extensions,
+ const ResourceManager *resourceManager);
+ ~Data();
+
+ Data(const Data &other);
+ Data &operator=(const Data &other);
+
+ GLint clientVersion;
+ const State *state;
+ const Caps *caps;
+ const TextureCapsMap *textureCaps;
+ const Extensions *extensions;
+ const ResourceManager *resourceManager;
+};
+
+}
+
+#endif // LIBGLESV2_DATA_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
index ee9a07a5c4..966a327de5 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
@@ -4,191 +4,113 @@
// found in the LICENSE file.
//
-// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
-
-// Important note on accurate timers in Windows:
-//
-// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
-// as timeGetTime on laptops and "jumping" during certain hardware events.
-//
-// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
-// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
-//
-// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
-// from buggy implementations.
+// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
+// extension and GLES3 sync objects.
#include "libGLESv2/Fence.h"
#include "libGLESv2/renderer/FenceImpl.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/main.h"
+#include "common/utilities.h"
#include "angle_gl.h"
namespace gl
{
-FenceNV::FenceNV(rx::Renderer *renderer)
+FenceNV::FenceNV(rx::FenceNVImpl *impl)
+ : mFence(impl),
+ mIsSet(false),
+ mStatus(GL_FALSE),
+ mCondition(GL_NONE)
{
- mFence = renderer->createFence();
}
FenceNV::~FenceNV()
{
- delete mFence;
+ SafeDelete(mFence);
}
GLboolean FenceNV::isFence() const
{
// GL_NV_fence spec:
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
- return (mFence->isSet() ? GL_TRUE : GL_FALSE);
+ return (mIsSet ? GL_TRUE : GL_FALSE);
}
-void FenceNV::setFence(GLenum condition)
+Error FenceNV::setFence(GLenum condition)
{
- mFence->set();
+ Error error = mFence->set();
+ if (error.isError())
+ {
+ return error;
+ }
mCondition = condition;
mStatus = GL_FALSE;
-}
-
-GLboolean FenceNV::testFence()
-{
- // Flush the command buffer by default
- bool result = mFence->test(true);
+ mIsSet = true;
- mStatus = (result ? GL_TRUE : GL_FALSE);
- return mStatus;
+ return Error(GL_NO_ERROR);
}
-void FenceNV::finishFence()
+Error FenceNV::testFence(GLboolean *outResult)
{
- ASSERT(mFence->isSet());
-
- while (!mFence->test(true))
+ // Flush the command buffer by default
+ Error error = mFence->test(true, &mStatus);
+ if (error.isError())
{
- Sleep(0);
+ return error;
}
-}
-
-GLint FenceNV::getFencei(GLenum pname)
-{
- ASSERT(mFence->isSet());
- switch (pname)
- {
- case GL_FENCE_STATUS_NV:
- {
- // GL_NV_fence spec:
- // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
- // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
- if (mStatus == GL_TRUE)
- {
- return GL_TRUE;
- }
-
- mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE);
- return mStatus;
- }
-
- case GL_FENCE_CONDITION_NV:
- return mCondition;
-
- default: UNREACHABLE(); return 0;
- }
+ *outResult = mStatus;
+ return Error(GL_NO_ERROR);
}
-FenceSync::FenceSync(rx::Renderer *renderer, GLuint id)
- : RefCountObject(id)
+Error FenceNV::finishFence()
{
- mFence = renderer->createFence();
-
- LARGE_INTEGER counterFreqency = { 0 };
- BOOL success = QueryPerformanceFrequency(&counterFreqency);
- UNUSED_ASSERTION_VARIABLE(success);
- ASSERT(success);
+ ASSERT(mIsSet);
- mCounterFrequency = counterFreqency.QuadPart;
+ return mFence->finishFence(&mStatus);
}
-FenceSync::~FenceSync()
+FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
+ : RefCountObject(id),
+ mFence(impl),
+ mCondition(GL_NONE)
{
- delete mFence;
}
-void FenceSync::set(GLenum condition)
+FenceSync::~FenceSync()
{
- mCondition = condition;
- mFence->set();
+ SafeDelete(mFence);
}
-GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
+Error FenceSync::set(GLenum condition)
{
- ASSERT(mFence->isSet());
-
- bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
-
- if (mFence->test(flushCommandBuffer))
+ Error error = mFence->set();
+ if (error.isError())
{
- return GL_ALREADY_SIGNALED;
+ return error;
}
- if (mFence->hasError())
- {
- return GL_WAIT_FAILED;
- }
-
- if (timeout == 0)
- {
- return GL_TIMEOUT_EXPIRED;
- }
-
- LARGE_INTEGER currentCounter = { 0 };
- BOOL success = QueryPerformanceCounter(&currentCounter);
- UNUSED_ASSERTION_VARIABLE(success);
- ASSERT(success);
-
- LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
- LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
-
- while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer))
- {
- Sleep(0);
- BOOL success = QueryPerformanceCounter(&currentCounter);
- UNUSED_ASSERTION_VARIABLE(success);
- ASSERT(success);
- }
-
- if (mFence->hasError())
- {
- return GL_WAIT_FAILED;
- }
-
- if (currentCounter.QuadPart >= endCounter)
- {
- return GL_TIMEOUT_EXPIRED;
- }
-
- return GL_CONDITION_SATISFIED;
+ mCondition = condition;
+ return Error(GL_NO_ERROR);
}
-void FenceSync::serverWait()
+Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
{
- // Because our API is currently designed to be called from a single thread, we don't need to do
- // extra work for a server-side fence. GPU commands issued after the fence is created will always
- // be processed after the fence is signaled.
+ ASSERT(mCondition != GL_NONE);
+ return mFence->clientWait(flags, timeout, outResult);
}
-GLenum FenceSync::getStatus() const
+Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
{
- if (mFence->test(false))
- {
- // The spec does not specify any way to report errors during the status test (e.g. device lost)
- // so we report the fence is unblocked in case of error or signaled.
- return GL_SIGNALED;
- }
+ return mFence->serverWait(flags, timeout);
+}
- return GL_UNSIGNALED;
+Error FenceSync::getStatus(GLint *outResult) const
+{
+ return mFence->getStatus(outResult);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.h b/src/3rdparty/angle/src/libGLESv2/Fence.h
index 291edb3de1..fd565e96a6 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.h
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.h
@@ -4,18 +4,21 @@
// found in the LICENSE file.
//
-// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
+// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
+// extension and GLES3 sync objects.
#ifndef LIBGLESV2_FENCE_H_
#define LIBGLESV2_FENCE_H_
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
#include "common/RefCountObject.h"
namespace rx
{
-class Renderer;
-class FenceImpl;
+class FenceNVImpl;
+class FenceSyncImpl;
}
namespace gl
@@ -24,14 +27,13 @@ namespace gl
class FenceNV
{
public:
- explicit FenceNV(rx::Renderer *renderer);
+ explicit FenceNV(rx::FenceNVImpl *impl);
virtual ~FenceNV();
GLboolean isFence() const;
- void setFence(GLenum condition);
- GLboolean testFence();
- void finishFence();
- GLint getFencei(GLenum pname);
+ Error setFence(GLenum condition);
+ Error testFence(GLboolean *outResult);
+ Error finishFence();
GLboolean getStatus() const { return mStatus; }
GLuint getCondition() const { return mCondition; }
@@ -39,7 +41,9 @@ class FenceNV
private:
DISALLOW_COPY_AND_ASSIGN(FenceNV);
- rx::FenceImpl *mFence;
+ rx::FenceNVImpl *mFence;
+
+ bool mIsSet;
GLboolean mStatus;
GLenum mCondition;
@@ -48,21 +52,20 @@ class FenceNV
class FenceSync : public RefCountObject
{
public:
- explicit FenceSync(rx::Renderer *renderer, GLuint id);
+ explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id);
virtual ~FenceSync();
- void set(GLenum condition);
- GLenum clientWait(GLbitfield flags, GLuint64 timeout);
- void serverWait();
- GLenum getStatus() const;
+ Error set(GLenum condition);
+ Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
+ Error serverWait(GLbitfield flags, GLuint64 timeout);
+ Error getStatus(GLint *outResult) const;
GLuint getCondition() const { return mCondition; }
private:
DISALLOW_COPY_AND_ASSIGN(FenceSync);
- rx::FenceImpl *mFence;
- LONGLONG mCounterFrequency;
+ rx::FenceSyncImpl *mFence;
GLenum mCondition;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
index 5b21433f90..3d57262e3c 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
@@ -16,13 +16,18 @@
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
#include "common/utilities.h"
namespace rx
{
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+// TODO: Move these functions, and the D3D-specific header inclusions above,
+// to FramebufferD3D.
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
{
if (attachment->isTexture())
{
@@ -31,14 +36,16 @@ RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
const gl::ImageIndex *index = attachment->getTextureImageIndex();
ASSERT(index);
- return textureD3D->getRenderTarget(*index);
+ return textureD3D->getRenderTarget(*index, outRT);
+ }
+ else
+ {
+ gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+ ASSERT(renderbuffer);
+ RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
+ *outRT = renderbufferD3D->getRenderTarget();
+ return gl::Error(GL_NO_ERROR);
}
-
- gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
- ASSERT(renderbuffer);
-
- // TODO: cast to RenderbufferD3D
- return renderbuffer->getStorage()->getRenderTarget();
}
// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
@@ -56,9 +63,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
ASSERT(renderbuffer);
-
- // TODO: cast to RenderbufferD3D
- return renderbuffer->getStorage()->getSerial();
+ RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
+ return renderbufferD3D->getRenderTargetSerial();
}
}
@@ -66,9 +72,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
namespace gl
{
-Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id)
- : mRenderer(renderer),
- mId(id),
+Framebuffer::Framebuffer(GLuint id)
+ : mId(id),
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
mDepthbuffer(NULL),
mStencilbuffer(NULL)
@@ -91,124 +96,6 @@ Framebuffer::~Framebuffer()
SafeDelete(mStencilbuffer);
}
-FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
-{
- if (handle == 0)
- {
- return NULL;
- }
-
- gl::Context *context = gl::getContext();
-
- switch (type)
- {
- case GL_NONE:
- return NULL;
-
- case GL_RENDERBUFFER:
- return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
-
- case GL_TEXTURE_2D:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_2D)
- {
- return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
- }
- else
- {
- return NULL;
- }
- }
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
- {
- return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
- }
- else
- {
- return NULL;
- }
- }
-
- case GL_TEXTURE_3D:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_3D)
- {
- return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
- }
- else
- {
- return NULL;
- }
- }
-
- case GL_TEXTURE_2D_ARRAY:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
- {
- return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
- }
- else
- {
- return NULL;
- }
- }
-
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
-{
- ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
- SafeDelete(mColorbuffers[colorAttachment]);
- GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
- mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
-}
-
-void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
-{
- SafeDelete(mDepthbuffer);
- mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
-}
-
-void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
-{
- SafeDelete(mStencilbuffer);
- mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
-}
-
-void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
-{
- FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
-
- SafeDelete(mDepthbuffer);
- SafeDelete(mStencilbuffer);
-
- // ensure this is a legitimate depth+stencil format
- if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
- {
- mDepthbuffer = attachment;
-
- // Make a new attachment object to ensure we do not double-delete
- // See angle issue 686
- mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
- }
-}
-
void Framebuffer::detachTexture(GLuint textureId)
{
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
@@ -382,14 +269,13 @@ bool Framebuffer::usingExtendedDrawBuffers() const
return false;
}
-GLenum Framebuffer::completeness() const
+GLenum Framebuffer::completeness(const gl::Data &data) const
{
int width = 0;
int height = 0;
unsigned int colorbufferSize = 0;
int samples = -1;
bool missingAttachment = true;
- GLuint clientVersion = mRenderer->getCurrentClientVersion();
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
@@ -403,8 +289,7 @@ GLenum Framebuffer::completeness() const
}
GLenum internalformat = colorbuffer->getInternalFormat();
- // TODO(geofflang): use context's texture caps
- const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (colorbuffer->isTexture())
{
@@ -443,7 +328,7 @@ GLenum Framebuffer::completeness() const
// in GLES 2.0, all color attachments attachments must have the same number of bitplanes
// in GLES 3.0, there is no such restriction
- if (clientVersion < 3)
+ if (data.clientVersion < 3)
{
if (formatInfo.pixelBytes != colorbufferSize)
{
@@ -483,14 +368,12 @@ GLenum Framebuffer::completeness() const
}
GLenum internalformat = mDepthbuffer->getInternalFormat();
- // TODO(geofflang): use context's texture caps
- const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mDepthbuffer->isTexture())
{
// depth texture attachments require OES/ANGLE_depth_texture
- // TODO(geofflang): use context's extensions
- if (!mRenderer->getRendererExtensions().depthTextures)
+ if (!data.extensions->depthTextures)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -538,15 +421,13 @@ GLenum Framebuffer::completeness() const
}
GLenum internalformat = mStencilbuffer->getInternalFormat();
- // TODO(geofflang): use context's texture caps
- const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mStencilbuffer->isTexture())
{
// texture stencil attachments come along as part
// of OES_packed_depth_stencil + OES/ANGLE_depth_texture
- // TODO(geofflang): use context's extensions
- if (!mRenderer->getRendererExtensions().depthTextures)
+ if (!data.extensions->depthTextures)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -602,42 +483,44 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_COMPLETE;
}
-void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
+Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
{
GLuint maxDimension = caps.maxRenderbufferSize;
- invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+ return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
}
-void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
- GLint x, GLint y, GLsizei width, GLsizei height)
+Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
{
- ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
{
GLenum attachmentTarget = attachments[attachIndex];
- gl::FramebufferAttachment *attachment =
- (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
- getAttachment(attachmentTarget);
+ FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
+ : getAttachment(attachmentTarget);
if (attachment)
{
- rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
- if (renderTarget)
+ rx::RenderTarget *renderTarget = NULL;
+ Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- renderTarget->invalidate(x, y, width, height);
+ return error;
}
+
+ renderTarget->invalidate(x, y, width, height);
}
}
+
+ return Error(GL_NO_ERROR);
}
-DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
- : Framebuffer(renderer, 0)
+DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
+ : Framebuffer(0)
{
- Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
+ Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
- Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
+ Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
// Make a new attachment objects to ensure we do not double-delete
// See angle issue 686
@@ -648,9 +531,9 @@ DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colo
mReadBufferState = GL_BACK;
}
-int Framebuffer::getSamples() const
+int Framebuffer::getSamples(const gl::Data &data) const
{
- if (completeness() == GL_FRAMEBUFFER_COMPLETE)
+ if (completeness(data) == GL_FRAMEBUFFER_COMPLETE)
{
// for a complete framebuffer, all attachments must have the same sample count
// in this case return the first nonzero sample size
@@ -675,7 +558,7 @@ bool Framebuffer::hasValidDepthStencil() const
mDepthbuffer->id() == mStencilbuffer->id());
}
-ColorbufferInfo Framebuffer::getColorbuffersForRender() const
+ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const
{
ColorbufferInfo colorbuffersForRender;
@@ -689,18 +572,78 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender() const
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
colorbuffersForRender.push_back(colorbuffer);
}
-#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
- else
+ else if (!workarounds.mrtPerfWorkaround)
{
colorbuffersForRender.push_back(NULL);
}
-#endif
}
return colorbuffersForRender;
}
-GLenum DefaultFramebuffer::completeness() const
+void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex)
+{
+ setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex));
+}
+
+void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer)
+{
+ setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer));
+}
+
+void Framebuffer::setNULLAttachment(GLenum attachment)
+{
+ setAttachment(attachment, NULL);
+}
+
+void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
+{
+ if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS))
+ {
+ size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
+ SafeDelete(mColorbuffers[colorAttachment]);
+ mColorbuffers[colorAttachment] = attachmentObj;
+ }
+ else if (attachment == GL_DEPTH_ATTACHMENT)
+ {
+ SafeDelete(mDepthbuffer);
+ mDepthbuffer = attachmentObj;
+ }
+ else if (attachment == GL_STENCIL_ATTACHMENT)
+ {
+ SafeDelete(mStencilbuffer);
+ mStencilbuffer = attachmentObj;
+ }
+ else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+ {
+ SafeDelete(mDepthbuffer);
+ SafeDelete(mStencilbuffer);
+
+ // ensure this is a legitimate depth+stencil format
+ if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
+ {
+ mDepthbuffer = attachmentObj;
+
+ // Make a new attachment object to ensure we do not double-delete
+ // See angle issue 686
+ if (attachmentObj->isTexture())
+ {
+ mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
+ *attachmentObj->getTextureImageIndex());
+ }
+ else
+ {
+ mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
+ }
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+GLenum DefaultFramebuffer::completeness(const gl::Data &) const
{
// The default framebuffer *must* always be complete, though it may not be
// subject to the same rules as application FBOs. ie, it could have 0x0 size.
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
index cc12d22953..d0fe8935ea 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
@@ -10,41 +10,44 @@
#ifndef LIBGLESV2_FRAMEBUFFER_H_
#define LIBGLESV2_FRAMEBUFFER_H_
-#include <vector>
+#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include "common/RefCountObject.h"
-#include "constants.h"
+#include "Constants.h"
+
+#include <vector>
namespace rx
{
-class Renderer;
+class RenderbufferImpl;
+struct Workarounds;
}
namespace gl
{
class FramebufferAttachment;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
+class Texture;
+class Renderbuffer;
+struct ImageIndex;
struct Caps;
+struct Extensions;
+class TextureCapsMap;
+struct Data;
typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
class Framebuffer
{
public:
- Framebuffer(rx::Renderer *renderer, GLuint id);
-
+ Framebuffer(GLuint id);
virtual ~Framebuffer();
GLuint id() const { return mId; }
- void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer);
- void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer);
- void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer);
- void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer);
+ void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex);
+ void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer);
+ void setNULLAttachment(GLenum attachment);
void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer);
@@ -66,24 +69,21 @@ class Framebuffer
bool isEnabledColorAttachment(unsigned int colorAttachment) const;
bool hasEnabledColorAttachment() const;
bool hasStencil() const;
- int getSamples() const;
+ int getSamples(const gl::Data &data) const;
bool usingExtendedDrawBuffers() const;
- virtual GLenum completeness() const;
+ virtual GLenum completeness(const gl::Data &data) const;
bool hasValidDepthStencil() const;
- void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
- void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
- GLint x, GLint y, GLsizei width, GLsizei height);
+ Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
+ Error invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
// Use this method to retrieve the color buffer map when doing rendering.
// It will apply a workaround for poor shader performance on some systems
// by compacting the list to skip NULL values.
- ColorbufferInfo getColorbuffersForRender() const;
+ ColorbufferInfo getColorbuffersForRender(const rx::Workarounds &workarounds) const;
protected:
- rx::Renderer *mRenderer;
-
GLuint mId;
FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
@@ -96,15 +96,15 @@ class Framebuffer
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
- FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const;
+ void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
};
class DefaultFramebuffer : public Framebuffer
{
public:
- DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+ DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil);
- virtual GLenum completeness() const;
+ GLenum completeness(const gl::Data &data) const override;
virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
private:
@@ -118,7 +118,7 @@ namespace rx
class RenderTarget;
// TODO: place this in FramebufferD3D.h
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT);
unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
}
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
index 540ede1cd2..894884a6d8 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
@@ -187,7 +187,7 @@ GLenum RenderbufferAttachment::getActualFormat() const
GLsizei RenderbufferAttachment::getSamples() const
{
- return mRenderbuffer->getStorage()->getSamples();
+ return mRenderbuffer->getSamples();
}
GLuint RenderbufferAttachment::id() const
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
index c18ef7364d..8d2dafa7ee 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
+++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
@@ -16,13 +16,6 @@
#include "angle_gl.h"
-namespace rx
-{
-class Renderer;
-class RenderTarget;
-class TextureStorage;
-}
-
namespace gl
{
class Renderbuffer;
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
index 3522b997e8..b45cd9c169 100644
--- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
@@ -48,10 +48,101 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
}
+ImageIndex ImageIndex::MakeInvalid()
+{
+ return ImageIndex(GL_NONE, -1, -1);
+}
+
ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
: type(typeIn),
mipIndex(mipIndexIn),
layerIndex(layerIndexIn)
{}
+ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(GL_TEXTURE_2D, rx::Range<GLint>(minMip, maxMip),
+ rx::Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(0, 6), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip,
+ GLint minLayer, GLint maxLayer)
+{
+ return ImageIndexIterator(GL_TEXTURE_3D, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(minLayer, maxLayer), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
+ const GLsizei *layerCounts)
+{
+ return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range<GLint>(minMip, maxMip),
+ rx::Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts);
+}
+
+ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
+ const rx::Range<GLint> &layerRange, const GLsizei *layerCounts)
+ : mType(type),
+ mMipRange(mipRange),
+ mLayerRange(layerRange),
+ mLayerCounts(layerCounts),
+ mCurrentMip(mipRange.start),
+ mCurrentLayer(layerRange.start)
+{}
+
+GLint ImageIndexIterator::maxLayer() const
+{
+ return (mLayerCounts ? static_cast<GLint>(mLayerCounts[mCurrentMip]) : mLayerRange.end);
+}
+
+ImageIndex ImageIndexIterator::next()
+{
+ ASSERT(hasNext());
+
+ ImageIndex value = current();
+
+ // Iterate layers in the inner loop for now. We can add switchable
+ // layer or mip iteration if we need it.
+
+ if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL)
+ {
+ if (mCurrentLayer < maxLayer()-1)
+ {
+ mCurrentLayer++;
+ }
+ else if (mCurrentMip < mMipRange.end-1)
+ {
+ mCurrentMip++;
+ mCurrentLayer = mLayerRange.start;
+ }
+ }
+ else if (mCurrentMip < mMipRange.end-1)
+ {
+ mCurrentMip++;
+ mCurrentLayer = mLayerRange.start;
+ }
+
+ return value;
+}
+
+ImageIndex ImageIndexIterator::current() const
+{
+ ImageIndex value(mType, mCurrentMip, mCurrentLayer);
+
+ if (mType == GL_TEXTURE_CUBE_MAP)
+ {
+ value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer);
+ }
+
+ return value;
+}
+
+bool ImageIndexIterator::hasNext() const
+{
+ return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer());
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
index 9f2df88061..8bb14fd555 100644
--- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
+++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_IMAGE_INDEX_H_
#include "angle_gl.h"
+#include "common/mathutil.h"
namespace gl
{
@@ -20,6 +21,7 @@ struct ImageIndex
GLint mipIndex;
GLint layerIndex;
+ ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
ImageIndex(const ImageIndex &other);
ImageIndex &operator=(const ImageIndex &other);
@@ -29,11 +31,36 @@ struct ImageIndex
static ImageIndex MakeCube(GLenum target, GLint mipIndex);
static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
+ static ImageIndex MakeInvalid();
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
+};
+
+class ImageIndexIterator
+{
+ public:
+ static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
+ static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
+ static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
+ static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
+
+ ImageIndex next();
+ ImageIndex current() const;
+ bool hasNext() const;
private:
- ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
+
+ ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
+ const rx::Range<GLint> &layerRange, const GLsizei *layerCounts);
+
+ GLint maxLayer() const;
+
+ GLenum mType;
+ rx::Range<GLint> mMipRange;
+ rx::Range<GLint> mLayerRange;
+ const GLsizei *mLayerCounts;
+ GLint mCurrentMip;
+ GLint mCurrentLayer;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp
index 9bfda09a64..3faa8c56f6 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Program.cpp
@@ -244,7 +244,7 @@ void Program::bindAttributeLocation(GLuint index, const char *name)
// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
// compiling them into binaries, determining the attribute mappings, and collecting
// a list of uniforms
-bool Program::link(const Caps &caps)
+Error Program::link(const Data &data)
{
unlink(false);
@@ -252,10 +252,15 @@ bool Program::link(const Caps &caps)
resetUniformBlockBindings();
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
- mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
+ LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
+ mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
+ if (result.error.isError())
+ {
+ return result.error;
+ }
- return mLinked;
+ mLinked = result.linkSuccess;
+ return gl::Error(GL_NO_ERROR);
}
int AttributeBindings::getAttributeBinding(const std::string &name) const
@@ -303,21 +308,22 @@ ProgramBinary* Program::getProgramBinary() const
return mProgramBinary.get();
}
-bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
+Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
{
unlink(false);
mInfoLog.reset();
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
-
- if (!mLinked)
+ LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
+ if (result.error.isError())
{
mProgramBinary.set(NULL);
+ return result.error;
}
- return mLinked;
+ mLinked = result.linkSuccess;
+ return Error(GL_NO_ERROR);
}
void Program::release()
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h
index 6528dd1191..b92349eeef 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.h
+++ b/src/3rdparty/angle/src/libGLESv2/Program.h
@@ -29,6 +29,7 @@ class Renderer;
namespace gl
{
struct Caps;
+struct Data;
class ResourceManager;
class Shader;
@@ -77,9 +78,9 @@ class Program
void bindAttributeLocation(GLuint index, const char *name);
- bool link(const Caps &caps);
+ Error link(const Data &data);
bool isLinked();
- bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
+ Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
ProgramBinary *getProgramBinary() const;
int getInfoLogLength() const;
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
index 3f6d9e0ef9..6d64b38b56 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
@@ -23,13 +23,11 @@
#include "libGLESv2/Shader.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/renderer/ProgramImpl.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
#include "common/blocklayout.h"
+#include "common/features.h"
namespace gl
{
@@ -37,36 +35,6 @@ namespace gl
namespace
{
-GLenum GetTextureType(GLenum samplerType)
-{
- switch (samplerType)
- {
- case GL_SAMPLER_2D:
- case GL_INT_SAMPLER_2D:
- case GL_UNSIGNED_INT_SAMPLER_2D:
- case GL_SAMPLER_2D_SHADOW:
- return GL_TEXTURE_2D;
- case GL_SAMPLER_3D:
- case GL_INT_SAMPLER_3D:
- case GL_UNSIGNED_INT_SAMPLER_3D:
- return GL_TEXTURE_3D;
- case GL_SAMPLER_CUBE:
- case GL_SAMPLER_CUBE_SHADOW:
- return GL_TEXTURE_CUBE_MAP;
- case GL_INT_SAMPLER_CUBE:
- case GL_UNSIGNED_INT_SAMPLER_CUBE:
- return GL_TEXTURE_CUBE_MAP;
- case GL_SAMPLER_2D_ARRAY:
- case GL_INT_SAMPLER_2D_ARRAY:
- case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
- case GL_SAMPLER_2D_ARRAY_SHADOW:
- return GL_TEXTURE_2D_ARRAY;
- default: UNREACHABLE();
- }
-
- return GL_TEXTURE_2D;
-}
-
unsigned int ParseAndStripArrayIndex(std::string* name)
{
unsigned int subscript = GL_INVALID_INDEX;
@@ -83,52 +51,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
return subscript;
}
-void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
-{
- size_t layoutIndex = 0;
- for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
- {
- ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS);
-
- const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
-
- if (shaderAttr.type != GL_NONE)
- {
- GLenum transposedType = TransposeMatrixType(shaderAttr.type);
-
- for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++)
- {
- VertexFormat *defaultFormat = &inputLayout[layoutIndex];
-
- defaultFormat->mType = VariableComponentType(transposedType);
- defaultFormat->mNormalized = false;
- defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
- defaultFormat->mComponents = VariableColumnCount(transposedType);
- }
- }
- }
-}
-
-std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
-{
- std::vector<GLenum> defaultPixelOutput(1);
-
- ASSERT(!shaderOutputVars.empty());
- defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
-
- return defaultPixelOutput;
-}
-
-bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
-{
- return var.isRowMajorLayout;
-}
-
-bool IsRowMajorLayout(const sh::ShaderVariable &var)
-{
- return false;
-}
-
}
VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
@@ -136,47 +58,6 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element
{
}
-ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[],
- const GLenum signature[],
- rx::ShaderExecutable *shaderExecutable)
- : mShaderExecutable(shaderExecutable)
-{
- for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- mInputs[attributeIndex] = inputLayout[attributeIndex];
- mSignature[attributeIndex] = signature[attributeIndex];
- }
-}
-
-ProgramBinary::VertexExecutable::~VertexExecutable()
-{
- SafeDelete(mShaderExecutable);
-}
-
-bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const
-{
- for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (mSignature[attributeIndex] != signature[attributeIndex])
- {
- return false;
- }
- }
-
- return true;
-}
-
-ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable)
- : mOutputSignature(outputSignature),
- mShaderExecutable(shaderExecutable)
-{
-}
-
-ProgramBinary::PixelExecutable::~PixelExecutable()
-{
- SafeDelete(mShaderExecutable);
-}
-
LinkedVarying::LinkedVarying()
{
}
@@ -187,17 +68,17 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size,
{
}
+LinkResult::LinkResult(bool linkSuccess, const Error &error)
+ : linkSuccess(linkSuccess),
+ error(error)
+{
+}
+
unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0),
mProgram(impl),
- mGeometryExecutable(NULL),
- mUsedVertexSamplerRange(0),
- mUsedPixelSamplerRange(0),
- mUsesPointSize(false),
- mShaderVersion(100),
- mDirtySamplerMapping(true),
mValidated(false),
mSerial(issueSerial())
{
@@ -220,103 +101,11 @@ unsigned int ProgramBinary::getSerial() const
return mSerial;
}
-int ProgramBinary::getShaderVersion() const
-{
- return mShaderVersion;
-}
-
unsigned int ProgramBinary::issueSerial()
{
return mCurrentSerial++;
}
-rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
-{
- std::vector<GLenum> outputs;
-
- const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
-
- for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
- {
- const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
-
- if (colorbuffer)
- {
- outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
- }
- else
- {
- outputs.push_back(GL_NONE);
- }
- }
-
- return getPixelExecutableForOutputLayout(outputs);
-}
-
-rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
-{
- for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
- {
- if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
- {
- return mPixelExecutables[executableIndex]->shaderExecutable();
- }
- }
-
- InfoLog tempInfoLog;
- rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
- mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!pixelExecutable)
- {
- std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
- tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
- ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
- }
- else
- {
- mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
- }
-
- return pixelExecutable;
-}
-
-rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
-{
- GLenum signature[MAX_VERTEX_ATTRIBS];
- mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
-
- for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
- {
- if (mVertexExecutables[executableIndex]->matchesSignature(signature))
- {
- return mVertexExecutables[executableIndex]->shaderExecutable();
- }
- }
-
- InfoLog tempInfoLog;
- rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
- mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!vertexExecutable)
- {
- std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
- tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
- ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
- }
- else
- {
- mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
- }
-
- return vertexExecutable;
-}
-
-rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const
-{
- return mGeometryExecutable;
-}
-
GLuint ProgramBinary::getAttributeLocation(const char *name)
{
if (name)
@@ -343,157 +132,42 @@ int ProgramBinary::getSemanticIndex(int attributeIndex)
// Returns one more than the highest sampler index used.
GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
{
- switch (type)
- {
- case SAMPLER_PIXEL:
- return mUsedPixelSamplerRange;
- case SAMPLER_VERTEX:
- return mUsedVertexSamplerRange;
- default:
- UNREACHABLE();
- return 0;
- }
+ return mProgram->getUsedSamplerRange(type);
}
bool ProgramBinary::usesPointSize() const
{
- return mUsesPointSize;
-}
-
-bool ProgramBinary::usesPointSpriteEmulation() const
-{
- return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
-}
-
-bool ProgramBinary::usesGeometryShader() const
-{
- return usesPointSpriteEmulation();
+ return mProgram->usesPointSize();
}
GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
{
- GLint logicalTextureUnit = -1;
-
- switch (type)
- {
- case SAMPLER_PIXEL:
- ASSERT(samplerIndex < caps.maxTextureImageUnits);
- if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
- {
- logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
- }
- break;
- case SAMPLER_VERTEX:
- ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
- if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
- {
- logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
- }
- break;
- default: UNREACHABLE();
- }
-
- if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
- {
- return logicalTextureUnit;
- }
-
- return -1;
+ return mProgram->getSamplerMapping(type, samplerIndex, caps);
}
-// Returns the texture type for a given Direct3D 9 sampler type and
-// index (0-15 for the pixel shader and 0-3 for the vertex shader).
GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
- switch (type)
- {
- case SAMPLER_PIXEL:
- ASSERT(samplerIndex < mSamplersPS.size());
- ASSERT(mSamplersPS[samplerIndex].active);
- return mSamplersPS[samplerIndex].textureType;
- case SAMPLER_VERTEX:
- ASSERT(samplerIndex < mSamplersVS.size());
- ASSERT(mSamplersVS[samplerIndex].active);
- return mSamplersVS[samplerIndex].textureType;
- default: UNREACHABLE();
- }
-
- return GL_TEXTURE_2D;
+ return mProgram->getSamplerTextureType(type, samplerIndex);
}
GLint ProgramBinary::getUniformLocation(std::string name)
{
- unsigned int subscript = ParseAndStripArrayIndex(&name);
-
- unsigned int numUniforms = mUniformIndex.size();
- for (unsigned int location = 0; location < numUniforms; location++)
- {
- if (mUniformIndex[location].name == name)
- {
- const int index = mUniformIndex[location].index;
- const bool isArray = mUniforms[index]->isArray();
-
- if ((isArray && mUniformIndex[location].element == subscript) ||
- (subscript == GL_INVALID_INDEX))
- {
- return location;
- }
- }
- }
-
- return -1;
+ return mProgram->getUniformLocation(name);
}
GLuint ProgramBinary::getUniformIndex(std::string name)
{
- unsigned int subscript = ParseAndStripArrayIndex(&name);
-
- // The app is not allowed to specify array indices other than 0 for arrays of basic types
- if (subscript != 0 && subscript != GL_INVALID_INDEX)
- {
- return GL_INVALID_INDEX;
- }
-
- unsigned int numUniforms = mUniforms.size();
- for (unsigned int index = 0; index < numUniforms; index++)
- {
- if (mUniforms[index]->name == name)
- {
- if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
- {
- return index;
- }
- }
- }
-
- return GL_INVALID_INDEX;
+ return mProgram->getUniformIndex(name);
}
GLuint ProgramBinary::getUniformBlockIndex(std::string name)
{
- unsigned int subscript = ParseAndStripArrayIndex(&name);
-
- unsigned int numUniformBlocks = mUniformBlocks.size();
- for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
- {
- const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
- if (uniformBlock.name == name)
- {
- const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
- if (subscript == uniformBlock.elementIndex || arrayElementZero)
- {
- return blockIndex;
- }
- }
- }
-
- return GL_INVALID_INDEX;
+ return mProgram->getUniformBlockIndex(name);
}
UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
{
- ASSERT(blockIndex < mUniformBlocks.size());
- return mUniformBlocks[blockIndex];
+ return mProgram->getUniformBlockByIndex(blockIndex);
}
GLint ProgramBinary::getFragDataLocation(const char *name) const
@@ -517,524 +191,129 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const
size_t ProgramBinary::getTransformFeedbackVaryingCount() const
{
- return mTransformFeedbackLinkedVaryings.size();
+ return mProgram->getTransformFeedbackLinkedVaryings().size();
}
const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
{
- return mTransformFeedbackLinkedVaryings[idx];
+ return mProgram->getTransformFeedbackLinkedVaryings()[idx];
}
GLenum ProgramBinary::getTransformFeedbackBufferMode() const
{
- return mTransformFeedbackBufferMode;
-}
-
-template <typename T>
-static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
-{
- ASSERT(dest != NULL);
- ASSERT(dirtyFlag != NULL);
-
- *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0);
- *dest = source;
-}
-
-template <typename T>
-void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
-{
- const int components = VariableComponentCount(targetUniformType);
- const GLenum targetBoolType = VariableBoolVectorType(targetUniformType);
-
- LinkedUniform *targetUniform = getUniformByLocation(location);
-
- int elementCount = targetUniform->elementCount();
-
- count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-
- if (targetUniform->type == targetUniformType)
- {
- T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- T *dest = target + (i * 4);
- const T *source = v + (i * components);
-
- for (int c = 0; c < components; c++)
- {
- SetIfDirty(dest + c, source[c], &targetUniform->dirty);
- }
- for (int c = components; c < 4; c++)
- {
- SetIfDirty(dest + c, T(0), &targetUniform->dirty);
- }
- }
- }
- else if (targetUniform->type == targetBoolType)
- {
- GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- GLint *dest = boolParams + (i * 4);
- const T *source = v + (i * components);
-
- for (int c = 0; c < components; c++)
- {
- SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
- }
- for (int c = components; c < 4; c++)
- {
- SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
- }
- }
- }
- else if (IsSampler(targetUniform->type))
- {
- ASSERT(targetUniformType == GL_INT);
-
- GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
- bool wasDirty = targetUniform->dirty;
-
- for (int i = 0; i < count; i++)
- {
- GLint *dest = target + (i * 4);
- const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
-
- SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
- SetIfDirty(dest + 1, 0, &targetUniform->dirty);
- SetIfDirty(dest + 2, 0, &targetUniform->dirty);
- SetIfDirty(dest + 3, 0, &targetUniform->dirty);
- }
-
- if (!wasDirty && targetUniform->dirty)
- {
- mDirtySamplerMapping = true;
- }
- }
- else UNREACHABLE();
-}
-
-void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
- setUniform(location, count, v, GL_FLOAT);
+ return mProgram->getTransformFeedbackBufferMode();
}
-void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
-{
- setUniform(location, count, v, GL_FLOAT_VEC2);
-}
-
-void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
-{
- setUniform(location, count, v, GL_FLOAT_VEC3);
-}
-
-void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
-{
- setUniform(location, count, v, GL_FLOAT_VEC4);
-}
-
-template<typename T>
-bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
-{
- bool dirty = false;
- int copyWidth = std::min(targetHeight, srcWidth);
- int copyHeight = std::min(targetWidth, srcHeight);
-
- for (int x = 0; x < copyWidth; x++)
- {
- for (int y = 0; y < copyHeight; y++)
- {
- SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty);
- }
- }
- // clear unfilled right side
- for (int y = 0; y < copyWidth; y++)
- {
- for (int x = copyHeight; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
- // clear unfilled bottom.
- for (int y = copyWidth; y < targetHeight; y++)
- {
- for (int x = 0; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
-
- return dirty;
-}
-
-template<typename T>
-bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
-{
- bool dirty = false;
- int copyWidth = std::min(targetWidth, srcWidth);
- int copyHeight = std::min(targetHeight, srcHeight);
-
- for (int y = 0; y < copyHeight; y++)
- {
- for (int x = 0; x < copyWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty);
- }
- }
- // clear unfilled right side
- for (int y = 0; y < copyHeight; y++)
- {
- for (int x = copyWidth; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
- // clear unfilled bottom.
- for (int y = copyHeight; y < targetHeight; y++)
- {
- for (int x = 0; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
-
- return dirty;
+void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform1fv(location, count, v);
}
-template <int cols, int rows>
-void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
-{
- LinkedUniform *targetUniform = getUniformByLocation(location);
-
- int elementCount = targetUniform->elementCount();
-
- count = std::min(elementCount - (int)mUniformIndex[location].element, count);
- const unsigned int targetMatrixStride = (4 * rows);
- GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
-
- for (int i = 0; i < count; i++)
- {
- // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
- if (transpose == GL_FALSE)
- {
- targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty;
- }
- else
- {
- targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty;
- }
- target += targetMatrixStride;
- value += cols * rows;
- }
+void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform2fv(location, count, v);
}
-void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
+void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform3fv(location, count, v);
}
-void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
+void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform4fv(location, count, v);
}
-void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
+void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform1iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
+void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform2iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
+void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform3iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
+void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform4iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
+void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform1uiv(location, count, v);
}
-void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
+void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform2uiv(location, count, v);
}
-void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
+void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform3uiv(location, count, v);
}
-void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT);
+void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform4uiv(location, count, v);
}
-void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT_VEC2);
+void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix2fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT_VEC3);
+void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix3fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT_VEC4);
+void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix4fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT);
+void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT_VEC2);
+void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT_VEC3);
+void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
+void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
}
-template <typename T>
-void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
-{
- LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
-
- if (IsMatrixType(targetUniform->type))
- {
- const int rows = VariableRowCount(targetUniform->type);
- const int cols = VariableColumnCount(targetUniform->type);
- transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
- }
- else if (uniformType == VariableComponentType(targetUniform->type))
- {
- unsigned int size = VariableComponentCount(targetUniform->type);
- memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
- size * sizeof(T));
- }
- else
- {
- unsigned int size = VariableComponentCount(targetUniform->type);
- switch (VariableComponentType(targetUniform->type))
- {
- case GL_BOOL:
- {
- GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
- }
- }
- break;
-
- case GL_FLOAT:
- {
- GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = static_cast<T>(floatParams[i]);
- }
- }
- break;
-
- case GL_INT:
- {
- GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = static_cast<T>(intParams[i]);
- }
- }
- break;
-
- case GL_UNSIGNED_INT:
- {
- GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = static_cast<T>(uintParams[i]);
- }
- }
- break;
-
- default: UNREACHABLE();
- }
- }
+void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
}
-void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
-{
- getUniformv(location, params, GL_FLOAT);
+void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
}
-void ProgramBinary::getUniformiv(GLint location, GLint *params)
-{
- getUniformv(location, params, GL_INT);
+void ProgramBinary::getUniformfv(GLint location, GLfloat *v) {
+ mProgram->getUniformfv(location, v);
}
-void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
-{
- getUniformv(location, params, GL_UNSIGNED_INT);
+void ProgramBinary::getUniformiv(GLint location, GLint *v) {
+ mProgram->getUniformiv(location, v);
}
-void ProgramBinary::dirtyAllUniforms()
-{
- unsigned int numUniforms = mUniforms.size();
- for (unsigned int index = 0; index < numUniforms; index++)
- {
- mUniforms[index]->dirty = true;
- }
+void ProgramBinary::getUniformuiv(GLint location, GLuint *v) {
+ mProgram->getUniformuiv(location, v);
}
void ProgramBinary::updateSamplerMapping()
{
- if (!mDirtySamplerMapping)
- {
- return;
- }
-
- mDirtySamplerMapping = false;
-
- // Retrieve sampler uniform values
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- LinkedUniform *targetUniform = mUniforms[uniformIndex];
-
- if (targetUniform->dirty)
- {
- if (IsSampler(targetUniform->type))
- {
- int count = targetUniform->elementCount();
- GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
-
- if (targetUniform->isReferencedByFragmentShader())
- {
- unsigned int firstIndex = targetUniform->psRegisterIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < mSamplersPS.size())
- {
- ASSERT(mSamplersPS[samplerIndex].active);
- mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
- }
- }
- }
-
- if (targetUniform->isReferencedByVertexShader())
- {
- unsigned int firstIndex = targetUniform->vsRegisterIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < mSamplersVS.size())
- {
- ASSERT(mSamplersVS[samplerIndex].active);
- mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
- }
- }
- }
- }
- }
- }
+ return mProgram->updateSamplerMapping();
}
// Applies all the uniforms set for this program object to the renderer
Error ProgramBinary::applyUniforms()
{
- updateSamplerMapping();
-
- Error error = mProgram->getRenderer()->applyUniforms(*this);
- if (error.isError())
- {
- return error;
- }
-
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- mUniforms[uniformIndex]->dirty = false;
- }
-
- return gl::Error(GL_NO_ERROR);
+ return mProgram->applyUniforms();
}
Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
{
- const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
- const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
-
- const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers();
- const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers();
-
- ASSERT(boundBuffers.size() == mUniformBlocks.size());
-
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
- {
- UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
- gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
-
- ASSERT(uniformBlock && uniformBuffer);
-
- if (uniformBuffer->getSize() < uniformBlock->dataSize)
- {
- // undefined behaviour
- return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
- }
-
- // Unnecessary to apply an unreferenced standard or shared UBO
- if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
- {
- continue;
- }
-
- if (uniformBlock->isReferencedByVertexShader())
- {
- unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
- ASSERT(vertexUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < caps.maxVertexUniformBlocks);
- vertexUniformBuffers[registerIndex] = uniformBuffer;
- }
-
- if (uniformBlock->isReferencedByFragmentShader())
- {
- unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
- ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
- fragmentUniformBuffers[registerIndex] = uniformBuffer;
- }
- }
-
- return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+ return mProgram->applyUniformBuffers(boundBuffers, caps);
}
bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
@@ -1082,10 +361,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade
return true;
}
-bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
+LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
{
-#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
- return false;
+#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_DISABLED
+ return LinkResult(false, Error(GL_NO_ERROR));
#else
ASSERT(binaryFormat == mProgram->getBinaryFormat());
@@ -1097,7 +376,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (format != mProgram->getBinaryFormat())
{
infoLog.append("Invalid program binary format.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
int majorVersion = stream.readInt<int>();
@@ -1105,7 +384,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
{
infoLog.append("Invalid program binary version.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
@@ -1113,250 +392,38 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
{
infoLog.append("Invalid program binary version.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
int compileFlags = stream.readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{
infoLog.append("Mismatched compilation flags.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
stream.readInt(&mLinkedAttribute[i].type);
stream.readString(&mLinkedAttribute[i].name);
- stream.readInt(&mShaderAttributes[i].type);
- stream.readString(&mShaderAttributes[i].name);
+ stream.readInt(&mProgram->getShaderAttributes()[i].type);
+ stream.readString(&mProgram->getShaderAttributes()[i].name);
stream.readInt(&mSemanticIndex[i]);
}
initAttributesByLayout();
- const unsigned int psSamplerCount = stream.readInt<unsigned int>();
- for (unsigned int i = 0; i < psSamplerCount; ++i)
- {
- Sampler sampler;
- stream.readBool(&sampler.active);
- stream.readInt(&sampler.logicalTextureUnit);
- stream.readInt(&sampler.textureType);
- mSamplersPS.push_back(sampler);
- }
- const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
- for (unsigned int i = 0; i < vsSamplerCount; ++i)
- {
- Sampler sampler;
- stream.readBool(&sampler.active);
- stream.readInt(&sampler.logicalTextureUnit);
- stream.readInt(&sampler.textureType);
- mSamplersVS.push_back(sampler);
- }
-
- stream.readInt(&mUsedVertexSamplerRange);
- stream.readInt(&mUsedPixelSamplerRange);
- stream.readBool(&mUsesPointSize);
- stream.readInt(&mShaderVersion);
-
- const unsigned int uniformCount = stream.readInt<unsigned int>();
- if (stream.error())
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mUniforms.resize(uniformCount);
- for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
- {
- GLenum type = stream.readInt<GLenum>();
- GLenum precision = stream.readInt<GLenum>();
- std::string name = stream.readString();
- unsigned int arraySize = stream.readInt<unsigned int>();
- int blockIndex = stream.readInt<int>();
-
- int offset = stream.readInt<int>();
- int arrayStride = stream.readInt<int>();
- int matrixStride = stream.readInt<int>();
- bool isRowMajorMatrix = stream.readBool();
-
- const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
-
- LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
-
- stream.readInt(&uniform->psRegisterIndex);
- stream.readInt(&uniform->vsRegisterIndex);
- stream.readInt(&uniform->registerCount);
- stream.readInt(&uniform->registerElement);
-
- mUniforms[uniformIndex] = uniform;
- }
-
- unsigned int uniformBlockCount = stream.readInt<unsigned int>();
- if (stream.error())
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mUniformBlocks.resize(uniformBlockCount);
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
- {
- std::string name = stream.readString();
- unsigned int elementIndex = stream.readInt<unsigned int>();
- unsigned int dataSize = stream.readInt<unsigned int>();
-
- UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize);
-
- stream.readInt(&uniformBlock->psRegisterIndex);
- stream.readInt(&uniformBlock->vsRegisterIndex);
-
- unsigned int numMembers = stream.readInt<unsigned int>();
- uniformBlock->memberUniformIndexes.resize(numMembers);
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
- {
- stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
- }
-
- mUniformBlocks[uniformBlockIndex] = uniformBlock;
- }
-
- const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
- if (stream.error())
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mUniformIndex.resize(uniformIndexCount);
- for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
- {
- stream.readString(&mUniformIndex[uniformIndexIndex].name);
- stream.readInt(&mUniformIndex[uniformIndexIndex].element);
- stream.readInt(&mUniformIndex[uniformIndexIndex].index);
- }
-
- stream.readInt(&mTransformFeedbackBufferMode);
- const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>();
- mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
- for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
- {
- LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
-
- stream.readString(&varying.name);
- stream.readInt(&varying.type);
- stream.readInt(&varying.size);
- stream.readString(&varying.semanticName);
- stream.readInt(&varying.semanticIndex);
- stream.readInt(&varying.semanticIndexCount);
- }
-
- const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
- for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
- {
- VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
-
- for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
- {
- VertexFormat *vertexInput = &inputLayout[inputIndex];
- stream.readInt(&vertexInput->mType);
- stream.readInt(&vertexInput->mNormalized);
- stream.readInt(&vertexInput->mComponents);
- stream.readBool(&vertexInput->mPureInteger);
- }
-
- unsigned int vertexShaderSize = stream.readInt<unsigned int>();
- const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
- vertexShaderSize, rx::SHADER_VERTEX,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
- if (!shaderExecutable)
- {
- infoLog.append("Could not create vertex shader.");
- return false;
- }
-
- // generated converted input layout
- GLenum signature[MAX_VERTEX_ATTRIBS];
- mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
-
- // add new binary
- mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
-
- stream.skip(vertexShaderSize);
- }
-
- const size_t pixelShaderCount = stream.readInt<unsigned int>();
- for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
+ LinkResult result = mProgram->load(infoLog, &stream);
+ if (result.error.isError() || !result.linkSuccess)
{
- const size_t outputCount = stream.readInt<unsigned int>();
- std::vector<GLenum> outputs(outputCount);
- for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
- {
- stream.readInt(&outputs[outputIndex]);
- }
-
- const size_t pixelShaderSize = stream.readInt<unsigned int>();
- const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::Renderer *renderer = mProgram->getRenderer();
- rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
- rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!shaderExecutable)
- {
- infoLog.append("Could not create pixel shader.");
- return false;
- }
-
- // add new binary
- mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
-
- stream.skip(pixelShaderSize);
+ return result;
}
- unsigned int geometryShaderSize = stream.readInt<unsigned int>();
-
- if (geometryShaderSize > 0)
- {
- const char *geometryShaderFunction = (const char*) binary + stream.offset();
- rx::Renderer *renderer = mProgram->getRenderer();
- mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
- geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!mGeometryExecutable)
- {
- infoLog.append("Could not create geometry shader.");
- return false;
- }
- stream.skip(geometryShaderSize);
- }
-
- if (!mProgram->load(infoLog, &stream))
- {
- return false;
- }
-
- const char *ptr = (const char*) binary + stream.offset();
-
- const GUID *binaryIdentifier = (const GUID *) ptr;
- ptr += sizeof(GUID);
-
- GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
- if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mProgram->initializeUniformStorage(mUniforms);
-
- return true;
-#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
+ return LinkResult(true, Error(GL_NO_ERROR));
+#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
}
-bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
+Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
{
if (binaryFormat)
{
@@ -1375,168 +442,27 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
{
stream.writeInt(mLinkedAttribute[i].type);
stream.writeString(mLinkedAttribute[i].name);
- stream.writeInt(mShaderAttributes[i].type);
- stream.writeString(mShaderAttributes[i].name);
+ stream.writeInt(mProgram->getShaderAttributes()[i].type);
+ stream.writeString(mProgram->getShaderAttributes()[i].name);
stream.writeInt(mSemanticIndex[i]);
}
- stream.writeInt(mSamplersPS.size());
- for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
- {
- stream.writeInt(mSamplersPS[i].active);
- stream.writeInt(mSamplersPS[i].logicalTextureUnit);
- stream.writeInt(mSamplersPS[i].textureType);
- }
-
- stream.writeInt(mSamplersVS.size());
- for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
- {
- stream.writeInt(mSamplersVS[i].active);
- stream.writeInt(mSamplersVS[i].logicalTextureUnit);
- stream.writeInt(mSamplersVS[i].textureType);
- }
-
- stream.writeInt(mUsedVertexSamplerRange);
- stream.writeInt(mUsedPixelSamplerRange);
- stream.writeInt(mUsesPointSize);
- stream.writeInt(mShaderVersion);
-
- stream.writeInt(mUniforms.size());
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
- {
- const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
- stream.writeInt(uniform.type);
- stream.writeInt(uniform.precision);
- stream.writeString(uniform.name);
- stream.writeInt(uniform.arraySize);
- stream.writeInt(uniform.blockIndex);
-
- stream.writeInt(uniform.blockInfo.offset);
- stream.writeInt(uniform.blockInfo.arrayStride);
- stream.writeInt(uniform.blockInfo.matrixStride);
- stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
-
- stream.writeInt(uniform.psRegisterIndex);
- stream.writeInt(uniform.vsRegisterIndex);
- stream.writeInt(uniform.registerCount);
- stream.writeInt(uniform.registerElement);
- }
-
- stream.writeInt(mUniformBlocks.size());
- for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
- {
- const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
-
- stream.writeString(uniformBlock.name);
- stream.writeInt(uniformBlock.elementIndex);
- stream.writeInt(uniformBlock.dataSize);
-
- stream.writeInt(uniformBlock.memberUniformIndexes.size());
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
- {
- stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
- }
-
- stream.writeInt(uniformBlock.psRegisterIndex);
- stream.writeInt(uniformBlock.vsRegisterIndex);
- }
-
- stream.writeInt(mUniformIndex.size());
- for (size_t i = 0; i < mUniformIndex.size(); ++i)
- {
- stream.writeString(mUniformIndex[i].name);
- stream.writeInt(mUniformIndex[i].element);
- stream.writeInt(mUniformIndex[i].index);
- }
-
- stream.writeInt(mTransformFeedbackBufferMode);
- stream.writeInt(mTransformFeedbackLinkedVaryings.size());
- for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
- {
- const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
-
- stream.writeString(varying.name);
- stream.writeInt(varying.type);
- stream.writeInt(varying.size);
- stream.writeString(varying.semanticName);
- stream.writeInt(varying.semanticIndex);
- stream.writeInt(varying.semanticIndexCount);
- }
-
- stream.writeInt(mVertexExecutables.size());
- for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
- {
- VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
-
- for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
- {
- const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
- stream.writeInt(vertexInput.mType);
- stream.writeInt(vertexInput.mNormalized);
- stream.writeInt(vertexInput.mComponents);
- stream.writeInt(vertexInput.mPureInteger);
- }
-
- size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
- stream.writeInt(vertexShaderSize);
-
- const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
- stream.writeBytes(vertexBlob, vertexShaderSize);
- }
-
- stream.writeInt(mPixelExecutables.size());
- for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
- {
- PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
-
- const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
- stream.writeInt(outputs.size());
- for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
- {
- stream.writeInt(outputs[outputIndex]);
- }
-
- size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
- stream.writeInt(pixelShaderSize);
-
- const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
- stream.writeBytes(pixelBlob, pixelShaderSize);
- }
-
- size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
- stream.writeInt(geometryShaderSize);
-
- if (mGeometryExecutable != NULL && geometryShaderSize > 0)
- {
- const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
- stream.writeBytes(geometryBlob, geometryShaderSize);
- }
-
- if (!mProgram->save(&stream))
- {
- if (length)
- {
- *length = 0;
- }
-
- return false;
- }
-
- GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
+ mProgram->save(&stream);
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
- GLsizei totalLength = streamLength + sizeof(GUID);
- if (totalLength > bufSize)
+ if (streamLength > bufSize)
{
if (length)
{
*length = 0;
}
- return false;
+ // TODO: This should be moved to the validation layer but computing the size of the binary before saving
+ // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate
+ // sizes and then copy it.
+ return Error(GL_INVALID_OPERATION);
}
if (binary)
@@ -1546,129 +472,197 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
memcpy(ptr, streamData, streamLength);
ptr += streamLength;
- memcpy(ptr, &identifier, sizeof(GUID));
- ptr += sizeof(GUID);
-
- ASSERT(ptr - totalLength == binary);
+ ASSERT(ptr - streamLength == binary);
}
if (length)
{
- *length = totalLength;
+ *length = streamLength;
}
- return true;
+ return Error(GL_NO_ERROR);
}
GLint ProgramBinary::getLength()
{
GLint length;
- if (save(NULL, NULL, INT_MAX, &length))
- {
- return length;
- }
- else
+ Error error = save(NULL, NULL, INT_MAX, &length);
+ if (error.isError())
{
return 0;
}
+
+ return length;
}
-bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
+LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
+ Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode)
{
if (!fragmentShader || !fragmentShader->isCompiled())
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled())
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
reset();
- mSamplersPS.resize(caps.maxTextureImageUnits);
- mSamplersVS.resize(caps.maxVertexTextureImageUnits);
+ int registers;
+ std::vector<LinkedVarying> linkedVaryings;
+ LinkResult result = mProgram->link(data, infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
+ &registers, &linkedVaryings, &mOutputVariables);
+ if (result.error.isError() || !result.linkSuccess)
+ {
+ return result;
+ }
- mTransformFeedbackBufferMode = transformFeedbackBufferMode;
+ if (!linkAttributes(infoLog, attributeBindings, vertexShader))
+ {
+ return LinkResult(false, Error(GL_NO_ERROR));
+ }
- rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
- rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+ if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps))
+ {
+ return LinkResult(false, Error(GL_NO_ERROR));
+ }
- mShaderVersion = vertexShaderD3D->getShaderVersion();
+ if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps))
+ {
+ return LinkResult(false, Error(GL_NO_ERROR));
+ }
- int registers;
- std::vector<LinkedVarying> linkedVaryings;
- if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables))
+ if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
+ transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
- mUsesPointSize = vertexShaderD3D->usesPointSize();
+ // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
+ // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
+ result = mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers);
+ if (result.error.isError() || !result.linkSuccess)
+ {
+ infoLog.append("Failed to create D3D shaders.");
+ reset();
+ return result;
+ }
- bool success = true;
+ return LinkResult(true, Error(GL_NO_ERROR));
+}
- if (!linkAttributes(infoLog, attributeBindings, vertexShader))
+bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::Caps &caps)
+{
+ const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
+ const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
+
+ // Check that interface blocks defined in the vertex and fragment shaders are identical
+ typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
+ UniformBlockMap linkedUniformBlocks;
+
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
{
- success = false;
+ const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
+ linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
}
- if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
- success = false;
+ const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
+ UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
+ if (entry != linkedUniformBlocks.end())
+ {
+ const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
+ if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
+ {
+ return false;
+ }
+ }
}
- // special case for gl_DepthRange, the only built-in uniform (also a struct)
- if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
{
- const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
+ const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
- mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
- mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
- mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+ {
+ return false;
+ }
+ }
}
- if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
- success = false;
+ const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+ {
+ return false;
+ }
+ }
}
- if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
+ return true;
+}
+
+bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+ const sh::InterfaceBlock &fragmentInterfaceBlock)
+{
+ const char* blockName = vertexInterfaceBlock.name.c_str();
+
+ // validate blocks for the same member types
+ if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
{
- success = false;
+ infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
+ return false;
}
- if (success)
+ if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
{
- VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
- GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
- rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
+ infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
- std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
- rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
+ if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
+ {
+ infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
- if (usesGeometryShader())
+ const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+ {
+ const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
+ const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
+
+ if (vertexMember.name != fragmentMember.name)
{
- std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
- mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(),
- rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- rx::ANGLE_D3D_WORKAROUND_NONE);
+ infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
+ blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
+ return false;
}
- if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+ std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+ if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
{
- infoLog.append("Failed to create D3D shaders.");
- success = false;
- reset();
+ return false;
}
}
- return success;
+ return true;
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
@@ -1688,7 +682,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
- mShaderAttributes[attributeIndex] = attribute;
+ mProgram->getShaderAttributes()[attributeIndex] = attribute;
if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
{
@@ -1708,7 +702,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
// In GLSL 3.00, attribute aliasing produces a link error
// In GLSL 1.00, attribute aliasing is allowed
- if (mShaderVersion >= 300)
+ if (mProgram->getShaderVersion() >= 300)
{
if (!linkedAttribute.name.empty())
{
@@ -1856,346 +850,6 @@ bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std
return true;
}
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
-{
- const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
- const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
-
- const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
- const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
-
- // Check that uniforms defined in the vertex and fragment shaders are identical
- typedef std::map<std::string, const sh::Uniform*> UniformMap;
- UniformMap linkedUniforms;
-
- for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
- {
- const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
- linkedUniforms[vertexUniform.name] = &vertexUniform;
- }
-
- for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
- {
- const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
- UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
- if (entry != linkedUniforms.end())
- {
- const sh::Uniform &vertexUniform = *entry->second;
- const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
- if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
- {
- return false;
- }
- }
- }
-
- for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
- {
- const sh::Uniform &uniform = vertexUniforms[uniformIndex];
-
- if (uniform.staticUse)
- {
- defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
- }
- }
-
- for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
- {
- const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
-
- if (uniform.staticUse)
- {
- defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
- }
- }
-
- if (!indexUniforms(infoLog, caps))
- {
- return false;
- }
-
- mProgram->initializeUniformStorage(mUniforms);
-
- return true;
-}
-
-void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
-{
- ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
- sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
- encoder.skipRegisters(uniformRegister);
-
- defineUniform(shader, uniform, uniform.name, &encoder);
-}
-
-void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
- const std::string &fullName, sh::HLSLBlockEncoder *encoder)
-{
- if (uniform.isStruct())
- {
- for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
- {
- const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
-
- encoder->enterAggregateType();
-
- for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
- {
- const sh::ShaderVariable &field = uniform.fields[fieldIndex];
- const std::string &fieldFullName = (fullName + elementString + "." + field.name);
-
- defineUniform(shader, field, fieldFullName, encoder);
- }
-
- encoder->exitAggregateType();
- }
- }
- else // Not a struct
- {
- // Arrays are treated as aggregate types
- if (uniform.isArray())
- {
- encoder->enterAggregateType();
- }
-
- LinkedUniform *linkedUniform = getUniformByName(fullName);
-
- if (!linkedUniform)
- {
- linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
- -1, sh::BlockMemberInfo::getDefaultBlockInfo());
- ASSERT(linkedUniform);
- linkedUniform->registerElement = encoder->getCurrentElement();
- mUniforms.push_back(linkedUniform);
- }
-
- ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
-
- if (shader == GL_FRAGMENT_SHADER)
- {
- linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
- }
- else if (shader == GL_VERTEX_SHADER)
- {
- linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
- }
- else UNREACHABLE();
-
- // Advance the uniform offset, to track registers allocation for structs
- encoder->encodeType(uniform.type, uniform.arraySize, false);
-
- // Arrays are treated as aggregate types
- if (uniform.isArray())
- {
- encoder->exitAggregateType();
- }
- }
-}
-
-bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
-{
- ASSERT(IsSampler(uniform.type));
- ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
-
- if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
- {
- if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
- &mUsedVertexSamplerRange))
- {
- infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
- mSamplersVS.size());
- return false;
- }
-
- unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
- if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
- {
- infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
- caps.maxVertexUniformVectors);
- return false;
- }
- }
-
- if (uniform.psRegisterIndex != GL_INVALID_INDEX)
- {
- if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
- &mUsedPixelSamplerRange))
- {
- infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
- mSamplersPS.size());
- return false;
- }
-
- unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
- if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
- {
- infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
- caps.maxFragmentUniformVectors);
- return false;
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
-{
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
- if (IsSampler(uniform.type))
- {
- if (!indexSamplerUniform(uniform, infoLog, caps))
- {
- return false;
- }
- }
-
- for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
- {
- mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
- GLenum samplerType,
- unsigned int samplerCount,
- std::vector<Sampler> &outSamplers,
- GLuint *outUsedRange)
-{
- unsigned int samplerIndex = startSamplerIndex;
-
- do
- {
- if (samplerIndex < outSamplers.size())
- {
- Sampler& sampler = outSamplers[samplerIndex];
- sampler.active = true;
- sampler.textureType = GetTextureType(samplerType);
- sampler.logicalTextureUnit = 0;
- *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
- }
- else
- {
- return false;
- }
-
- samplerIndex++;
- } while (samplerIndex < startSamplerIndex + samplerCount);
-
- return true;
-}
-
-bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock)
-{
- const char* blockName = vertexInterfaceBlock.name.c_str();
-
- // validate blocks for the same member types
- if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
- {
- infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
- return false;
- }
-
- if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
- {
- infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
- return false;
- }
-
- if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
- {
- infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
- return false;
- }
-
- const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
- {
- const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
- const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
-
- if (vertexMember.name != fragmentMember.name)
- {
- infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
- blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
- return false;
- }
-
- std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
- if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
-{
- const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
- const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
-
- // Check that interface blocks defined in the vertex and fragment shaders are identical
- typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
- UniformBlockMap linkedUniformBlocks;
-
- for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
- linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
- }
-
- for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
- UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
- if (entry != linkedUniformBlocks.end())
- {
- const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
- if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
- {
- return false;
- }
- }
- }
-
- for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
-
- // Note: shared and std140 layouts are always considered active
- if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
- {
- if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
- {
- return false;
- }
- }
- }
-
- for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
- {
- const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
-
- // Note: shared and std140 layouts are always considered active
- if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
- {
- if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
@@ -2253,142 +907,6 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
return true;
}
-template <typename VarT>
-void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
- bool inRowMajorLayout)
-{
- for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
- {
- const VarT &field = fields[uniformIndex];
- const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
-
- if (field.isStruct())
- {
- bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
-
- for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
- {
- encoder->enterAggregateType();
-
- const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
- defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
-
- encoder->exitAggregateType();
- }
- }
- else
- {
- bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout);
-
- sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
-
- LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
- blockIndex, memberInfo);
-
- // add to uniform list, but not index, since uniform block uniforms have no location
- blockUniformIndexes->push_back(mUniforms.size());
- mUniforms.push_back(newUniform);
- }
- }
-}
-
-bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps)
-{
- const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation());
-
- // create uniform block entries if they do not exist
- if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
- {
- std::vector<unsigned int> blockUniformIndexes;
- const unsigned int blockIndex = mUniformBlocks.size();
-
- // define member uniforms
- sh::BlockLayoutEncoder *encoder = NULL;
-
- if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
- {
- encoder = new sh::Std140BlockEncoder;
- }
- else
- {
- encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
- }
- ASSERT(encoder);
-
- defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
-
- size_t dataSize = encoder->getBlockSize();
-
- // create all the uniform blocks
- if (interfaceBlock.arraySize > 0)
- {
- for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
- {
- UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
- newUniformBlock->memberUniformIndexes = blockUniformIndexes;
- mUniformBlocks.push_back(newUniformBlock);
- }
- }
- else
- {
- UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
- newUniformBlock->memberUniformIndexes = blockUniformIndexes;
- mUniformBlocks.push_back(newUniformBlock);
- }
- }
-
- if (interfaceBlock.staticUse)
- {
- // Assign registers to the uniform blocks
- const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
- const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
- ASSERT(blockIndex != GL_INVALID_INDEX);
- ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
-
- unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
-
- for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
- {
- UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
- ASSERT(uniformBlock->name == interfaceBlock.name);
-
- if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
- interfaceBlockRegister + uniformBlockElement, caps))
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps)
-{
- if (shader == GL_VERTEX_SHADER)
- {
- uniformBlock->vsRegisterIndex = registerIndex;
- if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
- {
- infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
- return false;
- }
- }
- else if (shader == GL_FRAGMENT_SHADER)
- {
- uniformBlock->psRegisterIndex = registerIndex;
- if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
- {
- infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
- return false;
- }
- }
- else UNREACHABLE();
-
- return true;
-}
-
bool ProgramBinary::isValidated() const
{
return mValidated;
@@ -2464,13 +982,13 @@ GLint ProgramBinary::getActiveAttributeMaxLength() const
void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
{
- ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount()
+ ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
if (bufsize > 0)
{
- std::string string = mUniforms[index]->name;
+ std::string string = mProgram->getUniforms()[index]->name;
- if (mUniforms[index]->isArray())
+ if (mProgram->getUniforms()[index]->isArray())
{
string += "[0]";
}
@@ -2484,27 +1002,27 @@ void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *len
}
}
- *size = mUniforms[index]->elementCount();
+ *size = mProgram->getUniforms()[index]->elementCount();
- *type = mUniforms[index]->type;
+ *type = mProgram->getUniforms()[index]->type;
}
GLint ProgramBinary::getActiveUniformCount() const
{
- return mUniforms.size();
+ return mProgram->getUniforms().size();
}
GLint ProgramBinary::getActiveUniformMaxLength() const
{
int maxLength = 0;
- unsigned int numUniforms = mUniforms.size();
+ unsigned int numUniforms = mProgram->getUniforms().size();
for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
- if (!mUniforms[uniformIndex]->name.empty())
+ if (!mProgram->getUniforms()[uniformIndex]->name.empty())
{
- int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
- if (mUniforms[uniformIndex]->isArray())
+ int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
+ if (mProgram->getUniforms()[uniformIndex]->isArray())
{
length += 3; // Counting in "[0]".
}
@@ -2517,7 +1035,7 @@ GLint ProgramBinary::getActiveUniformMaxLength() const
GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
{
- const gl::LinkedUniform& uniform = *mUniforms[index];
+ const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
switch (pname)
{
@@ -2540,34 +1058,25 @@ GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
bool ProgramBinary::isValidUniformLocation(GLint location) const
{
- ASSERT(rx::IsIntegerCastSafe<GLint>(mUniformIndex.size()));
- return (location >= 0 && location < static_cast<GLint>(mUniformIndex.size()));
+ ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
+ return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
}
LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const
{
- ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
- return mUniforms[mUniformIndex[location].index];
+ return mProgram->getUniformByLocation(location);
}
LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const
{
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- if (mUniforms[uniformIndex]->name == name)
- {
- return mUniforms[uniformIndex];
- }
- }
-
- return NULL;
+ return mProgram->getUniformByName(name);
}
void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
{
- ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
- const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
if (bufSize > 0)
{
@@ -2590,9 +1099,9 @@ void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei
void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
{
- ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
- const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
switch (pname)
{
@@ -2625,17 +1134,17 @@ void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pna
GLuint ProgramBinary::getActiveUniformBlockCount() const
{
- return mUniformBlocks.size();
+ return mProgram->getUniformBlocks().size();
}
GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
{
unsigned int maxLength = 0;
- unsigned int numUniformBlocks = mUniformBlocks.size();
+ unsigned int numUniformBlocks = mProgram->getUniformBlocks().size();
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
{
- const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
if (!uniformBlock.name.empty())
{
const unsigned int length = uniformBlock.name.length() + 1;
@@ -2665,88 +1174,7 @@ void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
- // if any two active samplers in a program are of different types, but refer to the same
- // texture image unit, and this is the current program, then ValidateProgram will fail, and
- // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
- updateSamplerMapping();
-
- std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
-
- for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
- {
- if (mSamplersPS[i].active)
- {
- unsigned int unit = mSamplersPS[i].logicalTextureUnit;
-
- if (unit >= textureUnitTypes.size())
- {
- if (infoLog)
- {
- infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
- }
-
- return false;
- }
-
- if (textureUnitTypes[unit] != GL_NONE)
- {
- if (mSamplersPS[i].textureType != textureUnitTypes[unit])
- {
- if (infoLog)
- {
- infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
- }
-
- return false;
- }
- }
- else
- {
- textureUnitTypes[unit] = mSamplersPS[i].textureType;
- }
- }
- }
-
- for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
- {
- if (mSamplersVS[i].active)
- {
- unsigned int unit = mSamplersVS[i].logicalTextureUnit;
-
- if (unit >= textureUnitTypes.size())
- {
- if (infoLog)
- {
- infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
- }
-
- return false;
- }
-
- if (textureUnitTypes[unit] != GL_NONE)
- {
- if (mSamplersVS[i].textureType != textureUnitTypes[unit])
- {
- if (infoLog)
- {
- infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
- }
-
- return false;
- }
- }
- else
- {
- textureUnitTypes[unit] = mSamplersVS[i].textureType;
- }
- }
- }
-
- return true;
-}
-
-ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
-{
+ return mProgram->validateSamplers(infoLog, caps);
}
struct AttributeSorter
@@ -2795,26 +1223,6 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
void ProgramBinary::reset()
{
- SafeDeleteContainer(mVertexExecutables);
- SafeDeleteContainer(mPixelExecutables);
-
- SafeDelete(mGeometryExecutable);
-
- mTransformFeedbackBufferMode = GL_NONE;
- mTransformFeedbackLinkedVaryings.clear();
-
- mSamplersPS.clear();
- mSamplersVS.clear();
-
- mUsedVertexSamplerRange = 0;
- mUsedPixelSamplerRange = 0;
- mUsesPointSize = false;
- mShaderVersion = 0;
- mDirtySamplerMapping = true;
-
- SafeDeleteContainer(mUniforms);
- SafeDeleteContainer(mUniformBlocks);
- mUniformIndex.clear();
mOutputVariables.clear();
mProgram->reset();
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
index ad470d417b..3142d66c6d 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
@@ -24,11 +24,6 @@
#include <string>
#include <vector>
-// TODO(jmadill): place this in workarounds library
-#define ANGLE_WORKAROUND_ENABLED 1
-#define ANGLE_WORKAROUND_DISABLED 2
-#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED
-
namespace sh
{
class HLSLBlockEncoder;
@@ -44,7 +39,6 @@ class HLSLBlockEncoder;
namespace rx
{
class ShaderExecutable;
-class Renderer;
struct TranslatedAttribute;
class UniformStorage;
class ProgramImpl;
@@ -58,6 +52,7 @@ class InfoLog;
class AttributeBindings;
class Buffer;
class Framebuffer;
+struct Data;
// Struct used for correlating uniforms/elements of uniform arrays to handles
struct VariableLocation
@@ -91,6 +86,14 @@ struct LinkedVarying
unsigned int semanticIndexCount;
};
+struct LinkResult
+{
+ bool linkSuccess;
+ Error error;
+
+ LinkResult(bool linkSuccess, const Error &error);
+};
+
// This is the result of linking a program. It is the state that would be passed to ProgramBinary.
class ProgramBinary : public RefCountObject
{
@@ -101,11 +104,6 @@ class ProgramBinary : public RefCountObject
rx::ProgramImpl *getImplementation() { return mProgram; }
const rx::ProgramImpl *getImplementation() const { return mProgram; }
- rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo);
- rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
- rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]);
- rx::ShaderExecutable *getGeometryExecutable() const;
-
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
@@ -113,8 +111,6 @@ class ProgramBinary : public RefCountObject
GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
- bool usesPointSpriteEmulation() const;
- bool usesGeometryShader() const;
GLint getUniformLocation(std::string name);
GLuint getUniformIndex(std::string name);
@@ -145,18 +141,17 @@ class ProgramBinary : public RefCountObject
void getUniformiv(GLint location, GLint *params);
void getUniformuiv(GLint location, GLuint *params);
- void dirtyAllUniforms();
-
Error applyUniforms();
Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
- bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
- bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
+ LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
+ Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
GLint getLength();
- bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps);
- void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
+ LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
+ Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode);
void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
GLint getActiveAttributeCount() const;
@@ -188,30 +183,23 @@ class ProgramBinary : public RefCountObject
void updateSamplerMapping();
unsigned int getSerial() const;
- int getShaderVersion() const;
void initAttributesByLayout();
void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
- const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; }
-
static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
+ static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
+ static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
private:
DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
- struct Sampler
- {
- Sampler();
-
- bool active;
- GLint logicalTextureUnit;
- GLenum textureType;
- };
-
void reset();
bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
+ bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
+ bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+ const sh::InterfaceBlock &fragmentInterfaceBlock);
static bool linkValidateVariablesBase(InfoLog &infoLog,
const std::string &variableName,
@@ -219,102 +207,21 @@ class ProgramBinary : public RefCountObject
const sh::ShaderVariable &fragmentVariable,
bool validatePrecision);
- static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
- static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
- bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
- void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
- void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
- bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps);
- bool indexUniforms(InfoLog &infoLog, const Caps &caps);
- static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
- std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
- bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
- bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
const Caps &caps) const;
- template <typename VarT>
- void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
- bool inRowMajorLayout);
- bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps);
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
void defineOutputVariables(Shader *fragmentShader);
- template <typename T>
- void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
-
- template <int cols, int rows>
- void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
-
- template <typename T>
- void getUniformv(GLint location, T *params, GLenum uniformType);
-
- class VertexExecutable
- {
- public:
- VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS],
- const GLenum signature[MAX_VERTEX_ATTRIBS],
- rx::ShaderExecutable *shaderExecutable);
- ~VertexExecutable();
-
- bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const;
-
- const VertexFormat *inputs() const { return mInputs; }
- const GLenum *signature() const { return mSignature; }
- rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
-
- private:
- VertexFormat mInputs[MAX_VERTEX_ATTRIBS];
- GLenum mSignature[MAX_VERTEX_ATTRIBS];
- rx::ShaderExecutable *mShaderExecutable;
- };
-
- class PixelExecutable
- {
- public:
- PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
- ~PixelExecutable();
-
- bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
-
- const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
- rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
-
- private:
- std::vector<GLenum> mOutputSignature;
- rx::ShaderExecutable *mShaderExecutable;
- };
-
rx::ProgramImpl *mProgram;
- std::vector<VertexExecutable *> mVertexExecutables;
- std::vector<PixelExecutable *> mPixelExecutables;
-
- rx::ShaderExecutable *mGeometryExecutable;
-
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
- sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
- GLenum mTransformFeedbackBufferMode;
- std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
-
- std::vector<Sampler> mSamplersPS;
- std::vector<Sampler> mSamplersVS;
- GLuint mUsedVertexSamplerRange;
- GLuint mUsedPixelSamplerRange;
- bool mUsesPointSize;
- int mShaderVersion;
- bool mDirtySamplerMapping;
-
- std::vector<LinkedUniform*> mUniforms;
- std::vector<UniformBlock*> mUniformBlocks;
- std::vector<VariableLocation> mUniformIndex;
std::map<int, VariableLocation> mOutputVariables;
bool mValidated;
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
index 9406fce58d..911a389dfa 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
@@ -4,77 +4,86 @@
// found in the LICENSE file.
//
-// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes
-// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
+// GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
#include "common/utilities.h"
namespace gl
{
-unsigned int RenderbufferStorage::mCurrentSerial = 1;
-
-Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage)
+Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
: RefCountObject(id),
- mStorage(newStorage)
+ mRenderbuffer(impl)
{
- ASSERT(mStorage);
+ ASSERT(mRenderbuffer);
+
+ mWidth = mRenderbuffer->getWidth();
+ mHeight = mRenderbuffer->getHeight();
+ mInternalFormat = mRenderbuffer->getInternalFormat();
+ mActualFormat = mRenderbuffer->getActualFormat();
+ mSamples = mRenderbuffer->getSamples();
}
Renderbuffer::~Renderbuffer()
{
- SafeDelete(mStorage);
+ SafeDelete(mRenderbuffer);
}
-void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
{
- ASSERT(newStorage);
+ Error error = mRenderbuffer->setStorage(width, height, internalformat, samples);
+ if (error.isError())
+ {
+ return error;
+ }
- SafeDelete(mStorage);
- mStorage = newStorage;
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = internalformat;
+ mSamples = samples;
+ mActualFormat = mRenderbuffer->getActualFormat();
+
+ return Error(GL_NO_ERROR);
}
-RenderbufferStorage *Renderbuffer::getStorage()
+rx::RenderbufferImpl *Renderbuffer::getImplementation()
{
- ASSERT(mStorage);
- return mStorage;
+ ASSERT(mRenderbuffer);
+ return mRenderbuffer;
}
GLsizei Renderbuffer::getWidth() const
{
- ASSERT(mStorage);
- return mStorage->getWidth();
+ return mWidth;
}
GLsizei Renderbuffer::getHeight() const
{
- ASSERT(mStorage);
- return mStorage->getHeight();
+ return mHeight;
}
GLenum Renderbuffer::getInternalFormat() const
{
- ASSERT(mStorage);
- return mStorage->getInternalFormat();
+ return mInternalFormat;
}
GLenum Renderbuffer::getActualFormat() const
{
- ASSERT(mStorage);
- return mStorage->getActualFormat();
+ return mActualFormat;
}
GLsizei Renderbuffer::getSamples() const
{
- ASSERT(mStorage);
- return mStorage->getSamples();
+ return mSamples;
}
GLuint Renderbuffer::getRedSize() const
@@ -107,176 +116,4 @@ GLuint Renderbuffer::getStencilSize() const
return GetInternalFormatInfo(getActualFormat()).stencilBits;
}
-RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1))
-{
- mWidth = 0;
- mHeight = 0;
- mInternalFormat = GL_RGBA4;
- mActualFormat = GL_RGBA8_OES;
- mSamples = 0;
-}
-
-RenderbufferStorage::~RenderbufferStorage()
-{
-}
-
-rx::RenderTarget *RenderbufferStorage::getRenderTarget()
-{
- return NULL;
-}
-
-GLsizei RenderbufferStorage::getWidth() const
-{
- return mWidth;
-}
-
-GLsizei RenderbufferStorage::getHeight() const
-{
- return mHeight;
-}
-
-GLenum RenderbufferStorage::getInternalFormat() const
-{
- return mInternalFormat;
-}
-
-GLenum RenderbufferStorage::getActualFormat() const
-{
- return mActualFormat;
-}
-
-GLsizei RenderbufferStorage::getSamples() const
-{
- return mSamples;
-}
-
-unsigned int RenderbufferStorage::getSerial() const
-{
- return mSerial;
-}
-
-unsigned int RenderbufferStorage::issueSerials(unsigned int count)
-{
- unsigned int firstSerial = mCurrentSerial;
- mCurrentSerial += count;
- return firstSerial;
-}
-
-bool RenderbufferStorage::isTexture() const
-{
- return false;
-}
-
-unsigned int RenderbufferStorage::getTextureSerial() const
-{
- return -1;
-}
-
-Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
-{
- mRenderTarget = renderer->createRenderTarget(swapChain, false);
-
- if (mRenderTarget)
- {
- mWidth = mRenderTarget->getWidth();
- mHeight = mRenderTarget->getHeight();
- mInternalFormat = mRenderTarget->getInternalFormat();
- mActualFormat = mRenderTarget->getActualFormat();
- mSamples = mRenderTarget->getSamples();
- }
-}
-
-Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
-{
- mRenderTarget = renderer->createRenderTarget(width, height, format, samples);
-
- if (mRenderTarget)
- {
- mWidth = width;
- mHeight = height;
- mInternalFormat = format;
- mActualFormat = mRenderTarget->getActualFormat();
- mSamples = mRenderTarget->getSamples();
- }
-}
-
-Colorbuffer::~Colorbuffer()
-{
- if (mRenderTarget)
- {
- delete mRenderTarget;
- }
-}
-
-rx::RenderTarget *Colorbuffer::getRenderTarget()
-{
- return mRenderTarget;
-}
-
-DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
-{
- mDepthStencil = renderer->createRenderTarget(swapChain, true);
- if (mDepthStencil)
- {
- mWidth = mDepthStencil->getWidth();
- mHeight = mDepthStencil->getHeight();
- mInternalFormat = mDepthStencil->getInternalFormat();
- mSamples = mDepthStencil->getSamples();
- mActualFormat = mDepthStencil->getActualFormat();
- }
-}
-
-DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples)
-{
-
- mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples);
-
- mWidth = mDepthStencil->getWidth();
- mHeight = mDepthStencil->getHeight();
- mInternalFormat = GL_DEPTH24_STENCIL8_OES;
- mActualFormat = mDepthStencil->getActualFormat();
- mSamples = mDepthStencil->getSamples();
-}
-
-DepthStencilbuffer::~DepthStencilbuffer()
-{
- if (mDepthStencil)
- {
- delete mDepthStencil;
- }
-}
-
-rx::RenderTarget *DepthStencilbuffer::getRenderTarget()
-{
- return mDepthStencil;
-}
-
-Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
-{
- if (mDepthStencil)
- {
- mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
-}
-
-Depthbuffer::~Depthbuffer()
-{
-}
-
-Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
-{
- if (mDepthStencil)
- {
- mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
-}
-
-Stencilbuffer::~Stencilbuffer()
-{
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
index 71bcb0e1f8..e9f12af3ce 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
@@ -4,30 +4,27 @@
// found in the LICENSE file.
//
-// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer.
+// Implements GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
#ifndef LIBGLESV2_RENDERBUFFER_H_
#define LIBGLESV2_RENDERBUFFER_H_
#include "angle_gl.h"
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
#include "common/RefCountObject.h"
namespace rx
{
-class Renderer;
-class SwapChain;
-class RenderTarget;
-class TextureStorage;
+class RenderbufferImpl;
}
namespace gl
{
-class RenderbufferStorage;
class FramebufferAttachment;
// A GL renderbuffer object is usually used as a depth or stencil buffer attachment
@@ -38,11 +35,12 @@ class FramebufferAttachment;
class Renderbuffer : public RefCountObject
{
public:
- Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
+ Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
virtual ~Renderbuffer();
- void setStorage(RenderbufferStorage *newStorage);
- RenderbufferStorage *getStorage();
+ Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
+
+ rx::RenderbufferImpl *getImplementation();
GLsizei getWidth() const;
GLsizei getHeight() const;
@@ -57,102 +55,15 @@ class Renderbuffer : public RefCountObject
GLuint getStencilSize() const;
private:
- RenderbufferStorage *mStorage;
-};
-
-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
-// is called. The specific concrete type depends on whether the internal format is
-// colour depth, stencil or packed depth/stencil.
-class RenderbufferStorage
-{
- public:
- RenderbufferStorage();
+ DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
- virtual ~RenderbufferStorage() = 0;
+ rx::RenderbufferImpl *mRenderbuffer;
- virtual rx::RenderTarget *getRenderTarget();
-
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
- virtual GLsizei getSamples() const;
-
- virtual unsigned int getSerial() const;
-
- virtual bool isTexture() const;
- virtual unsigned int getTextureSerial() const;
-
- static unsigned int issueSerials(unsigned int count);
-
- protected:
GLsizei mWidth;
GLsizei mHeight;
GLenum mInternalFormat;
GLenum mActualFormat;
GLsizei mSamples;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
-
- const unsigned int mSerial;
-
- static unsigned int mCurrentSerial;
-};
-
-class Colorbuffer : public RenderbufferStorage
-{
- public:
- Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
- Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
-
- virtual ~Colorbuffer();
-
- virtual rx::RenderTarget *getRenderTarget();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
-
- rx::RenderTarget *mRenderTarget;
-};
-
-class DepthStencilbuffer : public RenderbufferStorage
-{
- public:
- DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
- DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
- ~DepthStencilbuffer();
-
- virtual rx::RenderTarget *getRenderTarget();
-
- protected:
- rx::RenderTarget *mDepthStencil;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
-};
-
-class Depthbuffer : public DepthStencilbuffer
-{
- public:
- Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
- virtual ~Depthbuffer();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
-};
-
-class Stencilbuffer : public DepthStencilbuffer
-{
- public:
- Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
- virtual ~Stencilbuffer();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
index 9121de1750..38d53cad81 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
@@ -21,9 +21,9 @@
namespace gl
{
ResourceManager::ResourceManager(rx::Renderer *renderer)
+ : mRenderer(renderer),
+ mRefCount(1)
{
- mRefCount = 1;
- mRenderer = renderer;
}
ResourceManager::~ResourceManager()
@@ -88,13 +88,13 @@ GLuint ResourceManager::createBuffer()
}
// Returns an unused shader/program name
-GLuint ResourceManager::createShader(GLenum type)
+GLuint ResourceManager::createShader(const gl::Data &data, GLenum type)
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
{
- mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
+ mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle);
}
else UNREACHABLE();
@@ -146,7 +146,7 @@ GLuint ResourceManager::createFenceSync()
{
GLuint handle = mFenceSyncHandleAllocator.allocate();
- FenceSync *fenceSync = new FenceSync(mRenderer, handle);
+ FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle);
fenceSync->addRef();
mFenceSyncMap[handle] = fenceSync;
@@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle)
}
}
-Program *ResourceManager::getProgram(unsigned int handle)
+Program *ResourceManager::getProgram(unsigned int handle) const
{
- ProgramMap::iterator program = mProgramMap.find(handle);
+ ProgramMap::const_iterator program = mProgramMap.find(handle);
if (program == mProgramMap.end())
{
@@ -403,7 +403,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
{
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
{
- Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
+ Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer);
mRenderbufferMap[renderbuffer] = renderbufferObject;
renderbufferObject->addRef();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
index 7d53bd4854..acad29b51d 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
@@ -32,6 +32,7 @@ class Texture;
class Renderbuffer;
class Sampler;
class FenceSync;
+struct Data;
class ResourceManager
{
@@ -43,7 +44,7 @@ class ResourceManager
void release();
GLuint createBuffer();
- GLuint createShader(GLenum type);
+ GLuint createShader(const gl::Data &data, GLenum type);
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
@@ -60,7 +61,7 @@ class ResourceManager
Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle);
- Program *getProgram(GLuint handle);
+ Program *getProgram(GLuint handle) const;
Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
@@ -78,8 +79,8 @@ class ResourceManager
private:
DISALLOW_COPY_AND_ASSIGN(ResourceManager);
- std::size_t mRefCount;
rx::Renderer *mRenderer;
+ std::size_t mRefCount;
typedef std::unordered_map<GLuint, Buffer*> BufferMap;
BufferMap mBufferMap;
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
index e3da2b1a9e..1cc17a0501 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
@@ -37,6 +37,7 @@ Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLui
Shader::~Shader()
{
+ SafeDelete(mShader);
}
GLuint Shader::getHandle() const
@@ -117,9 +118,15 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
}
-void Shader::compile()
+void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
{
- mCompiled = mShader->compile(mSource);
+ std::string debugInfo(mShader->getDebugInfo());
+ getSourceImpl(debugInfo, bufSize, length, buffer);
+}
+
+void Shader::compile(const gl::Data &data)
+{
+ mCompiled = mShader->compile(data, mSource);
}
void Shader::addRef()
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h
index 7ba3bd165c..904217dab8 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.h
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.h
@@ -31,6 +31,7 @@ class ShaderImpl;
namespace gl
{
class ResourceManager;
+struct Data;
struct PackedVarying : public sh::Varying
{
@@ -73,8 +74,9 @@ class Shader
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength() const;
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
+ void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const;
- void compile();
+ void compile(const gl::Data &data);
bool isCompiled() const { return mCompiled; }
void addRef();
diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp
index 3c03b90e56..b5b62f5848 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/State.cpp
@@ -10,18 +10,20 @@
#include "libGLESv2/Context.h"
#include "libGLESv2/Caps.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/Query.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/Query.h"
+#include "libGLESv2/VertexArray.h"
#include "libGLESv2/formatutils.h"
+#include "libGLESv2/renderer/RenderTarget.h"
namespace gl
{
State::State()
{
+ mMaxDrawBuffers = 0;
+ mMaxCombinedTextureImageUnits = 0;
}
State::~State()
@@ -31,7 +33,8 @@ State::~State()
void State::initialize(const Caps& caps, GLuint clientVersion)
{
- mContext = NULL;
+ mMaxDrawBuffers = caps.maxDrawBuffers;
+ mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -111,11 +114,15 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
mActiveSampler = 0;
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
- for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
+ mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
+ for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
{
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
}
+ mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
+ mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
+
mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
if (clientVersion >= 3)
@@ -153,12 +160,6 @@ void State::reset()
mSamplers[samplerIdx].set(NULL);
}
- const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
- for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
- {
- mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
- }
-
mArrayBuffer.set(NULL);
mRenderbuffer.set(NULL);
@@ -170,15 +171,15 @@ void State::reset()
}
mGenericUniformBuffer.set(NULL);
- for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+ mGenericTransformFeedbackBuffer.set(NULL);
+ for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
{
- mUniformBuffers[i].set(NULL);
+ bufItr->set(NULL);
}
- mGenericTransformFeedbackBuffer.set(NULL);
- for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
{
- mTransformFeedbackBuffers[i].set(NULL);
+ bufItr->set(NULL);
}
mCopyReadBuffer.set(NULL);
@@ -485,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert)
mSampleCoverageInvert = invert;
}
-void State::getSampleCoverageParams(GLclampf *value, bool *invert)
+void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
{
ASSERT(value != NULL && invert != NULL);
@@ -612,14 +613,7 @@ void State::setSamplerTexture(GLenum type, Texture *texture)
Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
-
- if (binding.id() == 0) // Special case: 0 refers to default textures held by Context
- {
- return NULL;
- }
-
- return binding.get();
+ return mSamplerTextures.at(type)[sampler].get();
}
GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
@@ -627,7 +621,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
return mSamplerTextures.at(type)[sampler].id();
}
-void State::detachTexture(GLuint texture)
+void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
{
// Textures have a detach method on State rather than a simple
// removeBinding, because the zero/null texture objects are managed
@@ -640,13 +634,15 @@ void State::detachTexture(GLuint texture)
for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{
+ GLenum textureType = bindingVec->first;
TextureBindingVector &textureVector = bindingVec->second;
for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
{
BindingPointer<Texture> &binding = textureVector[textureIdx];
if (binding.id() == texture)
{
- binding.set(NULL);
+ // Zero textures are the "default" textures instead of NULL
+ binding.set(zeroTextures.at(textureType).get());
}
}
}
@@ -667,6 +663,19 @@ void State::detachTexture(GLuint texture)
}
}
+void State::initializeZeroTextures(const TextureMap &zeroTextures)
+{
+ for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++)
+ {
+ TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first];
+
+ for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
+ {
+ samplerTextureArray[textureUnit].set(i->second.get());
+ }
+ }
+}
+
void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
{
mSamplers[textureUnit].set(sampler);
@@ -947,14 +956,14 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt
GLuint State::getIndexedUniformBufferId(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
return mUniformBuffers[index].id();
}
Buffer *State::getIndexedUniformBuffer(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
return mUniformBuffers[index].get();
}
@@ -971,25 +980,30 @@ void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffe
GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].id();
}
Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].get();
}
GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].getOffset();
}
+size_t State::getTransformFeedbackBufferIndexRange() const
+{
+ return mTransformFeedbackBuffers.size();
+}
+
void State::setCopyReadBufferBinding(Buffer *buffer)
{
mCopyReadBuffer.set(buffer);
@@ -1033,19 +1047,19 @@ void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
void State::setVertexAttribf(GLuint index, const GLfloat values[4])
{
- ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setFloatValues(values);
}
void State::setVertexAttribu(GLuint index, const GLuint values[4])
{
- ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
}
void State::setVertexAttribi(GLuint index, const GLint values[4])
{
- ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setIntValues(values);
}
@@ -1062,15 +1076,10 @@ const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
{
- ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
return mVertexAttribCurrentValues[attribNum];
}
-const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
-{
- return mVertexAttribCurrentValues;
-}
-
const void *State::getVertexAttribPointer(unsigned int attribNum) const
{
return getVertexArray()->getVertexAttribute(attribNum).pointer;
@@ -1180,12 +1189,12 @@ void State::getFloatv(GLenum pname, GLfloat *params)
}
}
-void State::getIntegerv(GLenum pname, GLint *params)
+void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
{
if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
{
unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
- ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
+ ASSERT(colorAttachment < mMaxDrawBuffers);
Framebuffer *framebuffer = mDrawFramebuffer;
*params = framebuffer->getDrawBufferState(colorAttachment);
return;
@@ -1238,12 +1247,12 @@ void State::getIntegerv(GLenum pname, GLint *params)
case GL_SAMPLES:
{
gl::Framebuffer *framebuffer = mDrawFramebuffer;
- if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE)
{
switch (pname)
{
case GL_SAMPLE_BUFFERS:
- if (framebuffer->getSamples() != 0)
+ if (framebuffer->getSamples(data) != 0)
{
*params = 1;
}
@@ -1253,7 +1262,7 @@ void State::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_SAMPLES:
- *params = framebuffer->getSamples();
+ *params = framebuffer->getSamples(data);
break;
}
}
@@ -1332,19 +1341,19 @@ void State::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_TEXTURE_BINDING_2D:
- ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
- ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_3D:
- ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_2D_ARRAY:
- ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
break;
case GL_UNIFORM_BUFFER_BINDING:
@@ -1376,13 +1385,13 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+ if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].id();
}
break;
case GL_UNIFORM_BUFFER_BINDING:
- if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+ if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].id();
}
@@ -1399,25 +1408,25 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
- if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+ if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].getOffset();
}
break;
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
- if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+ if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].getSize();
}
break;
case GL_UNIFORM_BUFFER_START:
- if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+ if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].getOffset();
}
break;
case GL_UNIFORM_BUFFER_SIZE:
- if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+ if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].getSize();
}
@@ -1433,9 +1442,9 @@ bool State::hasMappedBuffer(GLenum target) const
{
if (target == GL_ARRAY_BUFFER)
{
- for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
+ for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
{
- const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
+ const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
{
diff --git a/src/3rdparty/angle/src/libGLESv2/State.h b/src/3rdparty/angle/src/libGLESv2/State.h
index 5f0433136c..c3e6106bd8 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.h
+++ b/src/3rdparty/angle/src/libGLESv2/State.h
@@ -25,6 +25,9 @@ class Query;
class VertexArray;
class Context;
struct Caps;
+struct Data;
+
+typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
class State
{
@@ -35,8 +38,6 @@ class State
void initialize(const Caps& caps, GLuint clientVersion);
void reset();
- void setContext(Context *context) { mContext = context; }
-
// State chunk getters
const RasterizerState &getRasterizerState() const;
const BlendState &getBlendState() const;
@@ -100,7 +101,7 @@ class State
bool isSampleCoverageEnabled() const;
void setSampleCoverage(bool enabled);
void setSampleCoverageParams(GLclampf value, bool invert);
- void getSampleCoverageParams(GLclampf *value, bool *invert);
+ void getSampleCoverageParams(GLclampf *value, bool *invert) const;
// Scissor test state toggle & query
bool isScissorTestEnabled() const;
@@ -133,7 +134,8 @@ class State
void setSamplerTexture(GLenum type, Texture *texture);
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
- void detachTexture(GLuint texture);
+ void detachTexture(const TextureMap &zeroTextures, GLuint texture);
+ void initializeZeroTextures(const TextureMap &zeroTextures);
// Sampler object binding manipulation
void setSamplerBinding(GLuint textureUnit, Sampler *sampler);
@@ -199,6 +201,7 @@ class State
GLuint getIndexedTransformFeedbackBufferId(GLuint index) const;
Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const;
GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const;
+ size_t getTransformFeedbackBufferIndexRange() const;
// GL_COPY_[READ/WRITE]_BUFFER
void setCopyReadBufferBinding(Buffer *buffer);
@@ -220,7 +223,6 @@ class State
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
- const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const;
const void *getVertexAttribPointer(unsigned int attribNum) const;
// Pixel pack state manipulation
@@ -238,7 +240,7 @@ class State
// State query functions
void getBooleanv(GLenum pname, GLboolean *params);
void getFloatv(GLenum pname, GLfloat *params);
- void getIntegerv(GLenum pname, GLint *params);
+ void getIntegerv(const gl::Data &data, GLenum pname, GLint *params);
bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
@@ -247,7 +249,9 @@ class State
private:
DISALLOW_COPY_AND_ASSIGN(State);
- Context *mContext;
+ // Cached values from Context's caps
+ GLuint mMaxDrawBuffers;
+ GLuint mMaxCombinedTextureImageUnits;
ColorF mColorClearValue;
GLclampf mDepthClearValue;
@@ -283,7 +287,8 @@ class State
GLuint mCurrentProgramId;
BindingPointer<ProgramBinary> mCurrentProgramBinary;
- VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
+ typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
+ VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
VertexArray *mVertexArray;
// Texture and sampler bindings
@@ -300,11 +305,12 @@ class State
ActiveQueryMap mActiveQueries;
BindingPointer<Buffer> mGenericUniformBuffer;
- OffsetBindingPointer<Buffer> mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
+ typedef std::vector< OffsetBindingPointer<Buffer> > BufferVector;
+ BufferVector mUniformBuffers;
BindingPointer<TransformFeedback> mTransformFeedback;
BindingPointer<Buffer> mGenericTransformFeedbackBuffer;
- OffsetBindingPointer<Buffer> mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+ BufferVector mTransformFeedbackBuffers;
BindingPointer<Buffer> mCopyReadBuffer;
BindingPointer<Buffer> mCopyWriteBuffer;
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
index 3ec492de07..cd4fc4e32a 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
@@ -47,11 +47,14 @@ bool IsPointSampled(const gl::SamplerState &samplerState)
return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
}
+unsigned int Texture::mCurrentTextureSerial = 1;
+
Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
: RefCountObject(id),
mTexture(impl),
+ mTextureSerial(issueTextureSerial()),
mUsage(GL_NONE),
- mImmutable(false),
+ mImmutableLevelCount(0),
mTarget(target)
{
}
@@ -72,16 +75,6 @@ void Texture::setUsage(GLenum usage)
getImplementation()->setUsage(usage);
}
-void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
-{
- *sampler = mSamplerState;
-
- // Offset the effective base level by the texture storage's top level
- rx::TextureStorage *texture = getNativeTexture();
- int topLevel = texture ? texture->getTopLevel() : 0;
- sampler->baseLevel = topLevel + mSamplerState.baseLevel;
-}
-
GLenum Texture::getUsage() const
{
return mUsage;
@@ -138,35 +131,35 @@ GLenum Texture::getActualFormat(const ImageIndex &index) const
return image->getActualFormat();
}
-rx::TextureStorage *Texture::getNativeTexture()
+Error Texture::generateMipmaps()
{
- return getImplementation()->getNativeTexture();
+ return getImplementation()->generateMipmaps();
}
-void Texture::generateMipmaps()
+Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- getImplementation()->generateMipmaps();
+ return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
}
-void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+unsigned int Texture::getTextureSerial() const
{
- getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
+ return mTextureSerial;
}
-unsigned int Texture::getTextureSerial()
+unsigned int Texture::issueTextureSerial()
{
- rx::TextureStorage *texture = getNativeTexture();
- return texture ? texture->getTextureSerial() : 0;
+ return mCurrentTextureSerial++;
}
bool Texture::isImmutable() const
{
- return mImmutable;
+ return (mImmutableLevelCount > 0);
}
int Texture::immutableLevelCount()
{
- return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
+ return mImmutableLevelCount;
}
int Texture::mipLevels() const
@@ -226,11 +219,11 @@ GLenum Texture2D::getActualFormat(GLint level) const
return GL_NONE;
}
-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
releaseTexImage();
- mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void Texture2D::bindTexImage(egl::Surface *surface)
@@ -254,35 +247,44 @@ void Texture2D::releaseTexImage()
}
}
-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
+ const PixelUnpackState &unpack, const void *pixels)
{
releaseTexImage();
- mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
}
-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
+ return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
}
-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
}
-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
+ Framebuffer *source)
{
releaseTexImage();
- mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
+ return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
}
-void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mImmutableLevelCount = levels;
- mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
+ return Error(GL_NO_ERROR);
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
@@ -359,11 +361,11 @@ bool Texture2D::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void Texture2D::generateMipmaps()
+Error Texture2D::generateMipmaps()
{
releaseTexImage();
- mTexture->generateMipmaps();
+ return mTexture->generateMipmaps();
}
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -467,49 +469,27 @@ GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
return GL_NONE;
}
-void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
-void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
+ return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
}
-void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
+ return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
}
-void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
-{
- mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
+ return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
}
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -549,16 +529,23 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const
return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
}
-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
+ GLsizei width, GLsizei height, Framebuffer *source)
{
- mTexture->copyImage(target, level, format, x, y, width, height, source);
+ return mTexture->copyImage(target, level, format, x, y, width, height, source);
}
-void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
+Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mImmutableLevelCount = levels;
- mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
+ return Error(GL_NO_ERROR);
}
// Tests for texture sampling completeness
@@ -734,31 +721,40 @@ bool Texture3D::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
}
-void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels);
}
-void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
+ return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
}
-void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
}
-void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
+ if (error.isError())
+ {
+ return error;
+ }
- mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
+ mImmutableLevelCount = levels;
+
+ return Error(GL_NO_ERROR);
}
bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
@@ -892,31 +888,40 @@ bool Texture2DArray::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
}
-void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels);
}
-void Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
+ return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
}
-void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
}
-void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mImmutableLevelCount = levels;
- mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
+ return Error(GL_NO_ERROR);
}
bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h
index ca5686fde3..66d4df8015 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.h
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.h
@@ -14,7 +14,7 @@
#include "common/debug.h"
#include "common/RefCountObject.h"
#include "libGLESv2/angletypes.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "libGLESv2/renderer/TextureImpl.h"
#include "libGLESv2/Caps.h"
@@ -52,7 +52,6 @@ class Texture : public RefCountObject
const SamplerState &getSamplerState() const { return mSamplerState; }
SamplerState &getSamplerState() { return mSamplerState; }
- void getSamplerStateWithNativeOffset(SamplerState *sampler);
void setUsage(GLenum usage);
GLenum getUsage() const;
@@ -69,15 +68,16 @@ class Texture : public RefCountObject
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
- rx::TextureStorage *getNativeTexture();
+ virtual Error generateMipmaps();
- virtual void generateMipmaps();
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+ virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- unsigned int getTextureSerial();
+ // Texture serials provide a unique way of identifying a Texture that isn't a raw pointer.
+ // "id" is not good enough, as Textures can be deleted, then re-allocated with the same id.
+ unsigned int getTextureSerial() const;
bool isImmutable() const;
- int immutableLevelCount();
+ GLsizei immutableLevelCount();
rx::TextureImpl *getImplementation() { return mTexture; }
const rx::TextureImpl *getImplementation() const { return mTexture; }
@@ -86,17 +86,20 @@ class Texture : public RefCountObject
protected:
int mipLevels() const;
+ const rx::Image *getBaseLevelImage() const;
+ static unsigned int issueTextureSerial();
rx::TextureImpl *mTexture;
SamplerState mSamplerState;
GLenum mUsage;
- bool mImmutable;
+ GLsizei mImmutableLevelCount;
GLenum mTarget;
- const rx::Image *getBaseLevelImage() const;
+ const unsigned int mTextureSerial;
+ static unsigned int mCurrentTextureSerial;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
@@ -116,18 +119,18 @@ class Texture2D : public Texture
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
- void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
- void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
- void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ Error setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+ Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
+ virtual Error generateMipmaps();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
@@ -152,19 +155,12 @@ class TextureCubeMap : public Texture
bool isCompressed(GLenum target, GLint level) const;
bool isDepth(GLenum target, GLint level) const;
- void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
-
- void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
-
- void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
- void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- void storage(GLsizei levels, GLenum internalformat, GLsizei size);
+ Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+ Error storage(GLsizei levels, GLenum internalformat, GLsizei size);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
@@ -195,11 +191,11 @@ class Texture3D : public Texture
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
- void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
@@ -225,11 +221,11 @@ class Texture2DArray : public Texture
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
- void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
+ Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
+ Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.h b/src/3rdparty/angle/src/libGLESv2/VertexArray.h
index 993ba042cf..a724c0be1c 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexArray.h
+++ b/src/3rdparty/angle/src/libGLESv2/VertexArray.h
@@ -14,14 +14,13 @@
#define LIBGLESV2_VERTEXARRAY_H_
#include "common/RefCountObject.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
#include <vector>
namespace rx
{
-class Renderer;
class VertexArrayImpl;
}
@@ -44,7 +43,7 @@ class VertexArray
void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
- const VertexAttribute* getVertexAttributes() const { return mVertexAttributes.data(); }
+ const VertexAttribute* getVertexAttributes() const { return &mVertexAttributes[0]; }
Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
void setElementArrayBuffer(Buffer *buffer);
GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); }
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
index bb6425df64..5a0cfc5ad9 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
@@ -9,6 +9,10 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
+#include "libGLESv2/State.h"
+#include "libGLESv2/VertexArray.h"
+
+#include <float.h>
namespace gl
{
@@ -148,16 +152,16 @@ VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueTyp
void VertexFormat::GetInputLayout(VertexFormat *inputLayout,
ProgramBinary *programBinary,
- const VertexAttribute *attributes,
- const gl::VertexAttribCurrentValueData *currentValues)
+ const State &state)
{
+ const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
int semanticIndex = programBinary->getSemanticIndex(attributeIndex);
if (semanticIndex != -1)
{
- inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type);
+ inputLayout[semanticIndex] = VertexFormat(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex).Type);
}
}
}
@@ -192,4 +196,15 @@ bool VertexFormat::operator<(const VertexFormat& other) const
return mPureInteger < other.mPureInteger;
}
+bool Box::operator==(const Box &other) const
+{
+ return (x == other.x && y == other.y && z == other.z &&
+ width == other.width && height == other.height && depth == other.depth);
+}
+
+bool Box::operator!=(const Box &other) const
+{
+ return !(*this == other);
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h
index 642a6ec266..78fe6b0e26 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.h
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h
@@ -9,13 +9,13 @@
#ifndef LIBGLESV2_ANGLETYPES_H_
#define LIBGLESV2_ANGLETYPES_H_
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "common/RefCountObject.h"
-#include <float.h>
namespace gl
{
class Buffer;
+class State;
class ProgramBinary;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@@ -66,6 +66,8 @@ struct Box
Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { }
Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { }
+ bool operator==(const Box &other) const;
+ bool operator!=(const Box &other) const;
};
struct Extents
@@ -230,8 +232,7 @@ struct VertexFormat
static void GetInputLayout(VertexFormat *inputLayout,
ProgramBinary *programBinary,
- const VertexAttribute *attributes,
- const gl::VertexAttribCurrentValueData *currentValues);
+ const State& currentValues);
bool operator==(const VertexFormat &other) const;
bool operator!=(const VertexFormat &other) const;
@@ -251,13 +252,6 @@ enum VertexConversionType
VERTEX_CONVERT_BOTH = 3
};
-enum D3DWorkaroundType
-{
- ANGLE_D3D_WORKAROUND_NONE,
- ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION,
- ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION
-};
-
}
#endif // LIBGLESV2_ANGLETYPES_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
index 07f5d47473..587950a139 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
@@ -34,13 +34,12 @@
#include "libGLESv2/validationES3.h"
#include "libGLESv2/queryconversions.h"
-
extern "C"
{
// OpenGL ES 2.0 functions
-void __stdcall glActiveTexture(GLenum texture)
+void GL_APIENTRY glActiveTexture(GLenum texture)
{
EVENT("(GLenum texture = 0x%X)", texture);
@@ -57,7 +56,7 @@ void __stdcall glActiveTexture(GLenum texture)
}
}
-void __stdcall glAttachShader(GLuint program, GLuint shader)
+void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
{
EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
@@ -103,7 +102,7 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
}
}
-void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
+void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id)
{
EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
@@ -124,7 +123,7 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
}
}
-void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
@@ -163,7 +162,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar*
}
}
-void __stdcall glBindBuffer(GLenum target, GLuint buffer)
+void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
{
EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
@@ -210,7 +209,7 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer)
}
}
-void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
+void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
{
EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
@@ -235,7 +234,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
}
}
-void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
@@ -252,7 +251,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
}
}
-void __stdcall glBindTexture(GLenum target, GLuint texture)
+void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
{
EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
@@ -291,7 +290,7 @@ void __stdcall glBindTexture(GLenum target, GLuint texture)
}
}
-void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
red, green, blue, alpha);
@@ -304,12 +303,12 @@ void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
}
}
-void __stdcall glBlendEquation(GLenum mode)
+void GL_APIENTRY glBlendEquation(GLenum mode)
{
glBlendEquationSeparate(mode, mode);
}
-void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
@@ -348,12 +347,12 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
}
}
-void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
+void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
{
glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
}
-void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
srcRGB, dstRGB, srcAlpha, dstAlpha);
@@ -488,7 +487,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
}
}
-void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
target, size, data, usage);
@@ -550,7 +549,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
}
}
-void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
target, offset, size, data);
@@ -611,7 +610,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
}
}
-GLenum __stdcall glCheckFramebufferStatus(GLenum target)
+GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
@@ -626,13 +625,14 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer);
- return framebuffer->completeness();
+
+ return framebuffer->completeness(context->getData());
}
return 0;
}
-void __stdcall glClear(GLbitfield mask)
+void GL_APIENTRY glClear(GLbitfield mask)
{
EVENT("(GLbitfield mask = 0x%X)", mask);
@@ -640,8 +640,9 @@ void __stdcall glClear(GLbitfield mask)
if (context)
{
gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
- if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (framebufferObject->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return;
@@ -662,7 +663,7 @@ void __stdcall glClear(GLbitfield mask)
}
}
-void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
red, green, blue, alpha);
@@ -674,7 +675,7 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
}
}
-void __stdcall glClearDepthf(GLclampf depth)
+void GL_APIENTRY glClearDepthf(GLclampf depth)
{
EVENT("(GLclampf depth = %f)", depth);
@@ -685,7 +686,7 @@ void __stdcall glClearDepthf(GLclampf depth)
}
}
-void __stdcall glClearStencil(GLint s)
+void GL_APIENTRY glClearStencil(GLint s)
{
EVENT("(GLint s = %d)", s);
@@ -696,7 +697,7 @@ void __stdcall glClearStencil(GLint s)
}
}
-void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
red, green, blue, alpha);
@@ -708,7 +709,7 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo
}
}
-void __stdcall glCompileShader(GLuint shader)
+void GL_APIENTRY glCompileShader(GLuint shader)
{
EVENT("(GLuint shader = %d)", shader);
@@ -731,11 +732,11 @@ void __stdcall glCompileShader(GLuint shader)
}
}
- shaderObject->compile();
+ shaderObject->compile(context->getData());
}
}
-void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid* data)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
@@ -771,7 +772,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -783,7 +789,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+ gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -794,7 +805,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
}
}
-void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize, const GLvoid* data)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
@@ -831,7 +842,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -843,7 +859,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -854,7 +875,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
}
}
-void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
"GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
@@ -884,7 +905,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+ gl::Error error = texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -896,7 +922,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
+ gl::Error error = texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -907,7 +938,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
}
}
-void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
"GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
@@ -937,7 +968,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+ gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -949,7 +985,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+ gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -960,7 +1001,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
}
}
-GLuint __stdcall glCreateProgram(void)
+GLuint GL_APIENTRY glCreateProgram(void)
{
EVENT("()");
@@ -973,7 +1014,7 @@ GLuint __stdcall glCreateProgram(void)
return 0;
}
-GLuint __stdcall glCreateShader(GLenum type)
+GLuint GL_APIENTRY glCreateShader(GLenum type)
{
EVENT("(GLenum type = 0x%X)", type);
@@ -995,7 +1036,7 @@ GLuint __stdcall glCreateShader(GLenum type)
return 0;
}
-void __stdcall glCullFace(GLenum mode)
+void GL_APIENTRY glCullFace(GLenum mode)
{
EVENT("(GLenum mode = 0x%X)", mode);
@@ -1018,7 +1059,7 @@ void __stdcall glCullFace(GLenum mode)
}
}
-void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
+void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
@@ -1038,7 +1079,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
}
}
-void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
+void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
{
EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
@@ -1058,7 +1099,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
}
}
-void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
@@ -1081,7 +1122,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
}
}
-void __stdcall glDeleteProgram(GLuint program)
+void GL_APIENTRY glDeleteProgram(GLuint program)
{
EVENT("(GLuint program = %d)", program);
@@ -1111,7 +1152,7 @@ void __stdcall glDeleteProgram(GLuint program)
}
}
-void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
+void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
{
EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
@@ -1131,7 +1172,7 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
}
}
-void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
@@ -1151,7 +1192,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
}
}
-void __stdcall glDeleteShader(GLuint shader)
+void GL_APIENTRY glDeleteShader(GLuint shader)
{
EVENT("(GLuint shader = %d)", shader);
@@ -1181,7 +1222,7 @@ void __stdcall glDeleteShader(GLuint shader)
}
}
-void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
+void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
{
EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
@@ -1204,7 +1245,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
}
}
-void __stdcall glDepthFunc(GLenum func)
+void GL_APIENTRY glDepthFunc(GLenum func)
{
EVENT("(GLenum func = 0x%X)", func);
@@ -1231,7 +1272,7 @@ void __stdcall glDepthFunc(GLenum func)
}
}
-void __stdcall glDepthMask(GLboolean flag)
+void GL_APIENTRY glDepthMask(GLboolean flag)
{
EVENT("(GLboolean flag = %u)", flag);
@@ -1242,7 +1283,7 @@ void __stdcall glDepthMask(GLboolean flag)
}
}
-void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
+void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
{
EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
@@ -1253,7 +1294,7 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
}
}
-void __stdcall glDetachShader(GLuint program, GLuint shader)
+void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
{
EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
@@ -1302,7 +1343,7 @@ void __stdcall glDetachShader(GLuint program, GLuint shader)
}
}
-void __stdcall glDisable(GLenum cap)
+void GL_APIENTRY glDisable(GLenum cap)
{
EVENT("(GLenum cap = 0x%X)", cap);
@@ -1319,7 +1360,7 @@ void __stdcall glDisable(GLenum cap)
}
}
-void __stdcall glDisableVertexAttribArray(GLuint index)
+void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
{
EVENT("(GLuint index = %d)", index);
@@ -1336,7 +1377,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
}
}
-void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
+void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
@@ -1357,7 +1398,7 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
}
}
-void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
@@ -1378,7 +1419,7 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
}
}
-void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
mode, count, type, indices);
@@ -1401,7 +1442,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
}
}
-void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
+void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
{
EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
mode, count, type, indices, primcount);
@@ -1424,7 +1465,7 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
}
}
-void __stdcall glEnable(GLenum cap)
+void GL_APIENTRY glEnable(GLenum cap)
{
EVENT("(GLenum cap = 0x%X)", cap);
@@ -1441,7 +1482,7 @@ void __stdcall glEnable(GLenum cap)
}
}
-void __stdcall glEnableVertexAttribArray(GLuint index)
+void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
{
EVENT("(GLuint index = %d)", index);
@@ -1458,7 +1499,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
}
}
-void __stdcall glEndQueryEXT(GLenum target)
+void GL_APIENTRY glEndQueryEXT(GLenum target)
{
EVENT("GLenum target = 0x%X)", target);
@@ -1479,7 +1520,7 @@ void __stdcall glEndQueryEXT(GLenum target)
}
}
-void __stdcall glFinishFenceNV(GLuint fence)
+void GL_APIENTRY glFinishFenceNV(GLuint fence)
{
EVENT("(GLuint fence = %d)", fence);
@@ -1504,29 +1545,39 @@ void __stdcall glFinishFenceNV(GLuint fence)
}
}
-void __stdcall glFinish(void)
+void GL_APIENTRY glFinish(void)
{
EVENT("()");
gl::Context *context = gl::getNonLostContext();
if (context)
{
- context->sync(true);
+ gl::Error error = context->sync(true);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glFlush(void)
+void GL_APIENTRY glFlush(void)
{
EVENT("()");
gl::Context *context = gl::getNonLostContext();
if (context)
{
- context->sync(false);
+ gl::Error error = context->sync(false);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
"GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
@@ -1548,33 +1599,19 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer);
- if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ if (renderbuffer != 0)
{
- unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
- framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0);
+ gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+ framebuffer->setRenderbufferAttachment(attachment, renderbufferObject);
}
else
{
- switch (attachment)
- {
- case GL_DEPTH_ATTACHMENT:
- framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
- break;
- case GL_STENCIL_ATTACHMENT:
- framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
- break;
- case GL_DEPTH_STENCIL_ATTACHMENT:
- framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0);
- break;
- default:
- UNREACHABLE();
- break;
- }
+ framebuffer->setNULLAttachment(attachment);
}
}
}
-void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
"GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
@@ -1587,31 +1624,23 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
return;
}
- if (texture == 0)
- {
- textarget = GL_NONE;
- }
-
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
- if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ if (texture != 0)
{
- const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
- framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0);
+ gl::Texture *textureObj = context->getTexture(texture);
+ gl::ImageIndex index(textarget, level, gl::ImageIndex::ENTIRE_LEVEL);
+ framebuffer->setTextureAttachment(attachment, textureObj, index);
}
else
{
- switch (attachment)
- {
- case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, 0); break;
- case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, 0); break;
- case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break;
- }
+ framebuffer->setNULLAttachment(attachment);
}
}
}
-void __stdcall glFrontFace(GLenum mode)
+void GL_APIENTRY glFrontFace(GLenum mode)
{
EVENT("(GLenum mode = 0x%X)", mode);
@@ -1631,7 +1660,7 @@ void __stdcall glFrontFace(GLenum mode)
}
}
-void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
+void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
{
EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
@@ -1651,7 +1680,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
}
}
-void __stdcall glGenerateMipmap(GLenum target)
+void GL_APIENTRY glGenerateMipmap(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
@@ -1721,11 +1750,16 @@ void __stdcall glGenerateMipmap(GLenum target)
}
}
- texture->generateMipmaps();
+ gl::Error error = texture->generateMipmaps();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
+void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
{
EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
@@ -1745,7 +1779,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
}
}
-void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
@@ -1765,7 +1799,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
}
}
-void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
+void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
{
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
@@ -1785,7 +1819,7 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
}
}
-void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
@@ -1805,7 +1839,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
}
}
-void __stdcall glGenTextures(GLsizei n, GLuint* textures)
+void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
{
EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
@@ -1825,7 +1859,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures)
}
}
-void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
"GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
@@ -1866,7 +1900,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
}
}
-void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
"GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
@@ -1908,7 +1942,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
}
}
-void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
program, maxcount, count, shaders);
@@ -1942,7 +1976,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c
}
}
-GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
+GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
{
EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
@@ -1978,7 +2012,7 @@ GLint __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
return -1;
}
-void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
+void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
{
EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
@@ -2003,7 +2037,7 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
}
}
-void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
@@ -2056,7 +2090,7 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params
}
}
-GLenum __stdcall glGetError(void)
+GLenum GL_APIENTRY glGetError(void)
{
EVENT("()");
@@ -2070,7 +2104,7 @@ GLenum __stdcall glGetError(void)
return GL_NO_ERROR;
}
-void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
{
EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
@@ -2094,19 +2128,40 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
switch (pname)
{
case GL_FENCE_STATUS_NV:
+ {
+ // GL_NV_fence spec:
+ // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
+ // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+ GLboolean status = GL_TRUE;
+ if (fenceObject->getStatus() != GL_TRUE)
+ {
+ gl::Error error = fenceObject->testFence(&status);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ *params = status;
+ break;
+ }
+
case GL_FENCE_CONDITION_NV:
- break;
+ {
+ *params = fenceObject->getCondition();
+ break;
+ }
default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM));
+ return;
+ }
}
-
- params[0] = fenceObject->getFencei(pname);
}
}
-void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
+void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
{
EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
@@ -2131,7 +2186,7 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
}
}
-void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
target, attachment, pname, params);
@@ -2214,6 +2269,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
+ ASSERT(framebuffer);
if (framebufferHandle == 0)
{
@@ -2428,7 +2484,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
}
}
-GLenum __stdcall glGetGraphicsResetStatusEXT(void)
+GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
{
EVENT("()");
@@ -2442,7 +2498,7 @@ GLenum __stdcall glGetGraphicsResetStatusEXT(void)
return GL_NO_ERROR;
}
-void __stdcall glGetIntegerv(GLenum pname, GLint* params)
+void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
{
EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
@@ -2468,7 +2524,7 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params)
}
}
-void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
@@ -2552,7 +2608,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
}
}
-void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
program, bufsize, length, infolog);
@@ -2578,7 +2634,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len
}
}
-void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
{
EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
@@ -2604,7 +2660,7 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
}
}
-void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
+void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
{
EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
@@ -2656,7 +2712,7 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
}
}
-void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
@@ -2705,7 +2761,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
}
}
-void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
@@ -2748,7 +2804,7 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
}
}
-void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
shader, bufsize, length, infolog);
@@ -2774,7 +2830,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt
}
}
-void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
shadertype, precisiontype, range, precision);
@@ -2821,7 +2877,7 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp
}
}
-void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
shader, bufsize, length, source);
@@ -2847,7 +2903,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length
}
}
-void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
shader, bufsize, length, source);
@@ -2869,11 +2925,12 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize,
return;
}
- shaderObject->getTranslatedSource(bufsize, length, source);
+ // Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined
+ shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
}
}
-const GLubyte* __stdcall glGetString(GLenum name)
+const GLubyte* GL_APIENTRY glGetString(GLenum name)
{
EVENT("(GLenum name = 0x%X)", name);
@@ -2919,7 +2976,7 @@ const GLubyte* __stdcall glGetString(GLenum name)
}
}
-void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
@@ -3051,7 +3108,7 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
}
}
-void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
@@ -3098,7 +3155,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
context->recordError(gl::Error(GL_INVALID_ENUM));
return;
}
- *params = texture->immutableLevelCount();
+ *params = static_cast<GLint>(texture->immutableLevelCount());
break;
case GL_TEXTURE_USAGE_ANGLE:
*params = texture->getUsage();
@@ -3183,7 +3240,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
}
}
-void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
{
EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
program, location, bufSize, params);
@@ -3205,7 +3262,7 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz
}
}
-void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
@@ -3226,7 +3283,7 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
}
}
-void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
+void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
{
EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
program, location, bufSize, params);
@@ -3248,7 +3305,7 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz
}
}
-void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
+void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
{
EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
@@ -3269,7 +3326,7 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
}
}
-GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
+GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
{
EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
@@ -3310,7 +3367,7 @@ GLint __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
return -1;
}
-void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
@@ -3344,7 +3401,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
}
}
-void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
@@ -3380,7 +3437,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
}
}
-void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
{
EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
@@ -3403,7 +3460,7 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po
}
}
-void __stdcall glHint(GLenum target, GLenum mode)
+void GL_APIENTRY glHint(GLenum target, GLenum mode)
{
EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
@@ -3439,7 +3496,7 @@ void __stdcall glHint(GLenum target, GLenum mode)
}
}
-GLboolean __stdcall glIsBuffer(GLuint buffer)
+GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
{
EVENT("(GLuint buffer = %d)", buffer);
@@ -3457,7 +3514,7 @@ GLboolean __stdcall glIsBuffer(GLuint buffer)
return GL_FALSE;
}
-GLboolean __stdcall glIsEnabled(GLenum cap)
+GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
{
EVENT("(GLenum cap = 0x%X)", cap);
@@ -3476,7 +3533,7 @@ GLboolean __stdcall glIsEnabled(GLenum cap)
return false;
}
-GLboolean __stdcall glIsFenceNV(GLuint fence)
+GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
{
EVENT("(GLuint fence = %d)", fence);
@@ -3496,7 +3553,7 @@ GLboolean __stdcall glIsFenceNV(GLuint fence)
return GL_FALSE;
}
-GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
+GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
{
EVENT("(GLuint framebuffer = %d)", framebuffer);
@@ -3514,7 +3571,7 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
return GL_FALSE;
}
-GLboolean __stdcall glIsProgram(GLuint program)
+GLboolean GL_APIENTRY glIsProgram(GLuint program)
{
EVENT("(GLuint program = %d)", program);
@@ -3532,7 +3589,7 @@ GLboolean __stdcall glIsProgram(GLuint program)
return GL_FALSE;
}
-GLboolean __stdcall glIsQueryEXT(GLuint id)
+GLboolean GL_APIENTRY glIsQueryEXT(GLuint id)
{
EVENT("(GLuint id = %d)", id);
@@ -3545,7 +3602,7 @@ GLboolean __stdcall glIsQueryEXT(GLuint id)
return GL_FALSE;
}
-GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
+GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
{
EVENT("(GLuint renderbuffer = %d)", renderbuffer);
@@ -3563,7 +3620,7 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
return GL_FALSE;
}
-GLboolean __stdcall glIsShader(GLuint shader)
+GLboolean GL_APIENTRY glIsShader(GLuint shader)
{
EVENT("(GLuint shader = %d)", shader);
@@ -3581,7 +3638,7 @@ GLboolean __stdcall glIsShader(GLuint shader)
return GL_FALSE;
}
-GLboolean __stdcall glIsTexture(GLuint texture)
+GLboolean GL_APIENTRY glIsTexture(GLuint texture)
{
EVENT("(GLuint texture = %d)", texture);
@@ -3599,7 +3656,7 @@ GLboolean __stdcall glIsTexture(GLuint texture)
return GL_FALSE;
}
-void __stdcall glLineWidth(GLfloat width)
+void GL_APIENTRY glLineWidth(GLfloat width)
{
EVENT("(GLfloat width = %f)", width);
@@ -3616,7 +3673,7 @@ void __stdcall glLineWidth(GLfloat width)
}
}
-void __stdcall glLinkProgram(GLuint program)
+void GL_APIENTRY glLinkProgram(GLuint program)
{
EVENT("(GLuint program = %d)", program);
@@ -3639,11 +3696,16 @@ void __stdcall glLinkProgram(GLuint program)
}
}
- context->linkProgram(program);
+ gl::Error error = context->linkProgram(program);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glPixelStorei(GLenum pname, GLint param)
+void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
{
EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
@@ -3699,7 +3761,7 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
}
}
-void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
+void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
{
EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
@@ -3710,7 +3772,7 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
}
}
-void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei bufSize,
GLvoid *data)
{
@@ -3742,7 +3804,7 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
}
}
-void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid* pixels)
{
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
@@ -3773,7 +3835,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
}
}
-void __stdcall glReleaseShaderCompiler(void)
+void GL_APIENTRY glReleaseShaderCompiler(void)
{
EVENT("()");
@@ -3785,7 +3847,7 @@ void __stdcall glReleaseShaderCompiler(void)
}
}
-void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, samples, internalformat, width, height);
@@ -3799,16 +3861,22 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp
return;
}
- context->setRenderbufferStorage(width, height, internalformat, samples);
+ gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+ gl::Error error = renderbuffer->setStorage(width, height, internalformat, samples);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
}
-void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
+void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
{
EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert);
@@ -3820,7 +3888,7 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
}
}
-void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
+void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
{
EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
@@ -3841,11 +3909,16 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
return;
}
- fenceObject->setFence(condition);
+ gl::Error error = fenceObject->setFence(condition);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
@@ -3862,7 +3935,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
}
}
-void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
"const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
@@ -3883,7 +3956,7 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor
}
}
-void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
+void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
{
EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
shader, count, string, length);
@@ -3917,12 +3990,12 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const*
}
}
-void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
+void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
{
glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
}
-void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
{
EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
@@ -3970,12 +4043,12 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint
}
}
-void __stdcall glStencilMask(GLuint mask)
+void GL_APIENTRY glStencilMask(GLuint mask)
{
glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
}
-void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
+void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
{
EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
@@ -4006,12 +4079,12 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
}
}
-void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
{
glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
}
-void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
face, fail, zfail, zpass);
@@ -4094,7 +4167,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
}
}
-GLboolean __stdcall glTestFenceNV(GLuint fence)
+GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
{
EVENT("(GLuint fence = %d)", fence);
@@ -4115,13 +4188,21 @@ GLboolean __stdcall glTestFenceNV(GLuint fence)
return GL_TRUE;
}
- return fenceObject->testFence();
+ GLboolean result;
+ gl::Error error = fenceObject->testFence(&result);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return GL_TRUE;
+ }
+
+ return result;
}
return GL_TRUE;
}
-void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
@@ -4150,51 +4231,38 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
+
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setImagePosX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- }
- break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setImageNegX(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- }
- break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setImagePosY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- }
- break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setImageNegY(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- }
- break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setImagePosZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- }
- break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setImageNegZ(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->setImage(target, level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
+
default: UNREACHABLE();
}
}
}
-void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
@@ -4238,12 +4306,12 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
}
}
-void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
glTexParameterf(target, pname, (GLfloat)*params);
}
-void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
+void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
@@ -4287,12 +4355,12 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
}
}
-void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
{
glTexParameteri(target, pname, *params);
}
-void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, levels, internalformat, width, height);
@@ -4323,14 +4391,24 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
case GL_TEXTURE_2D:
{
gl::Texture2D *texture2d = context->getTexture2D();
- texture2d->storage(levels, internalformat, width, height);
+ gl::Error error = texture2d->storage(levels, internalformat, width, height);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_CUBE_MAP:
{
gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
- textureCube->storage(levels, internalformat, width);
+ gl::Error error = textureCube->storage(levels, internalformat, width);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -4341,7 +4419,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
}
}
-void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid* pixels)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
@@ -4377,7 +4455,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -4389,7 +4472,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -4399,12 +4487,12 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
}
}
-void __stdcall glUniform1f(GLint location, GLfloat x)
+void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
{
glUniform1fv(location, 1, &x);
}
-void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
@@ -4421,12 +4509,12 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
}
}
-void __stdcall glUniform1i(GLint location, GLint x)
+void GL_APIENTRY glUniform1i(GLint location, GLint x)
{
glUniform1iv(location, 1, &x);
}
-void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
+void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
@@ -4443,14 +4531,14 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
}
}
-void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
+void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
{
GLfloat xy[2] = {x, y};
glUniform2fv(location, 1, xy);
}
-void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
@@ -4467,14 +4555,14 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
}
}
-void __stdcall glUniform2i(GLint location, GLint x, GLint y)
+void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
{
GLint xy[2] = {x, y};
glUniform2iv(location, 1, xy);
}
-void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
+void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
@@ -4491,14 +4579,14 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
}
}
-void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
GLfloat xyz[3] = {x, y, z};
glUniform3fv(location, 1, xyz);
}
-void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
@@ -4515,14 +4603,14 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
}
}
-void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
+void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
{
GLint xyz[3] = {x, y, z};
glUniform3iv(location, 1, xyz);
}
-void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
+void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
@@ -4539,14 +4627,14 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
}
}
-void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GLfloat xyzw[4] = {x, y, z, w};
glUniform4fv(location, 1, xyzw);
}
-void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
@@ -4563,14 +4651,14 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
}
}
-void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
{
GLint xyzw[4] = {x, y, z, w};
glUniform4iv(location, 1, xyzw);
}
-void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
+void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
@@ -4587,7 +4675,7 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
}
}
-void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -4605,7 +4693,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
}
}
-void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -4623,7 +4711,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
}
}
-void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -4641,7 +4729,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
}
}
-void __stdcall glUseProgram(GLuint program)
+void GL_APIENTRY glUseProgram(GLuint program)
{
EVENT("(GLuint program = %d)", program);
@@ -4674,7 +4762,7 @@ void __stdcall glUseProgram(GLuint program)
}
}
-void __stdcall glValidateProgram(GLuint program)
+void GL_APIENTRY glValidateProgram(GLuint program)
{
EVENT("(GLuint program = %d)", program);
@@ -4701,7 +4789,7 @@ void __stdcall glValidateProgram(GLuint program)
}
}
-void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
+void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
{
EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
@@ -4719,7 +4807,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
}
}
-void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
@@ -4737,7 +4825,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
}
}
-void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
{
EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
@@ -4755,7 +4843,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
}
}
-void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
@@ -4773,7 +4861,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
}
}
-void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
@@ -4791,7 +4879,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
}
}
-void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
@@ -4809,7 +4897,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
}
}
-void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
@@ -4827,7 +4915,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G
}
}
-void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
{
EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
@@ -4844,7 +4932,7 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
}
}
-void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
@@ -4861,7 +4949,7 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
}
}
-void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
"GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
@@ -4936,7 +5024,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
}
}
-void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
@@ -4955,7 +5043,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
// OpenGL ES 3.0 functions
-void __stdcall glReadBuffer(GLenum mode)
+void GL_APIENTRY glReadBuffer(GLenum mode)
{
EVENT("(GLenum mode = 0x%X)", mode);
@@ -4973,7 +5061,7 @@ void __stdcall glReadBuffer(GLenum mode)
}
}
-void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
+void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
{
EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
"const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
@@ -4992,7 +5080,7 @@ void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize
}
}
-void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
"GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
@@ -5020,14 +5108,24 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL
case GL_TEXTURE_3D:
{
gl::Texture3D *texture = context->getTexture3D();
- texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_2D_ARRAY:
{
gl::Texture2DArray *texture = context->getTexture2DArray();
- texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -5038,7 +5136,7 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL
}
}
-void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
+void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
"GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
@@ -5073,14 +5171,24 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint
case GL_TEXTURE_3D:
{
gl::Texture3D *texture = context->getTexture3D();
- texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_2D_ARRAY:
{
gl::Texture2DArray *texture = context->getTexture2DArray();
- texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
+ gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -5091,7 +5199,7 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint
}
}
-void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
"GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
@@ -5129,11 +5237,16 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL
return;
}
- texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+ gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
+void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
"GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
@@ -5168,14 +5281,24 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna
case GL_TEXTURE_3D:
{
gl::Texture3D *texture = context->getTexture3D();
- texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_2D_ARRAY:
{
gl::Texture2DArray *texture = context->getTexture2DArray();
- texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -5186,7 +5309,7 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna
}
}
-void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
+void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
"GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
@@ -5233,16 +5356,26 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs
case GL_TEXTURE_3D:
{
gl::Texture3D *texture = context->getTexture3D();
- texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
+ format, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_2D_ARRAY:
{
gl::Texture2DArray *texture = context->getTexture2DArray();
- texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
+ format, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -5253,7 +5386,7 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs
}
}
-void __stdcall glGenQueries(GLsizei n, GLuint* ids)
+void GL_APIENTRY glGenQueries(GLsizei n, GLuint* ids)
{
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
@@ -5279,7 +5412,7 @@ void __stdcall glGenQueries(GLsizei n, GLuint* ids)
}
}
-void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids)
+void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint* ids)
{
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
@@ -5305,7 +5438,7 @@ void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids)
}
}
-GLboolean __stdcall glIsQuery(GLuint id)
+GLboolean GL_APIENTRY glIsQuery(GLuint id)
{
EVENT("(GLuint id = %u)", id);
@@ -5324,7 +5457,7 @@ GLboolean __stdcall glIsQuery(GLuint id)
return GL_FALSE;
}
-void __stdcall glBeginQuery(GLenum target, GLuint id)
+void GL_APIENTRY glBeginQuery(GLenum target, GLuint id)
{
EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
@@ -5351,7 +5484,7 @@ void __stdcall glBeginQuery(GLenum target, GLuint id)
}
}
-void __stdcall glEndQuery(GLenum target)
+void GL_APIENTRY glEndQuery(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
@@ -5378,7 +5511,7 @@ void __stdcall glEndQuery(GLenum target)
}
}
-void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params)
+void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint* params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
@@ -5410,7 +5543,7 @@ void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params)
}
}
-void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
+void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
{
EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
@@ -5468,7 +5601,7 @@ void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
}
}
-GLboolean __stdcall glUnmapBuffer(GLenum target)
+GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
@@ -5487,7 +5620,7 @@ GLboolean __stdcall glUnmapBuffer(GLenum target)
return GL_FALSE;
}
-void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
+void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
@@ -5504,7 +5637,7 @@ void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
}
}
-void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs)
+void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum* bufs)
{
gl::Context *context = gl::getNonLostContext();
if (context)
@@ -5519,7 +5652,7 @@ void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs)
}
}
-void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -5537,7 +5670,7 @@ void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean tra
}
}
-void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -5555,7 +5688,7 @@ void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean tra
}
}
-void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -5573,7 +5706,7 @@ void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean tra
}
}
-void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -5591,7 +5724,7 @@ void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean tra
}
}
-void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -5609,7 +5742,7 @@ void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean tra
}
}
-void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
location, count, transpose, value);
@@ -5627,7 +5760,7 @@ void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra
}
}
-void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, "
"GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
@@ -5649,12 +5782,17 @@ void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr
return;
}
- context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
- mask, filter);
+ gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, samples, internalformat, width, height);
@@ -5674,11 +5812,12 @@ void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
return;
}
- context->setRenderbufferStorage(width, height, internalformat, samples);
+ gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+ renderbuffer->setStorage(width, height, internalformat, samples);
}
}
-void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
target, attachment, texture, level, layer);
@@ -5695,27 +5834,20 @@ void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuin
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer);
- gl::Texture *textureObject = context->getTexture(texture);
- GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE;
-
- if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ if (texture != 0)
{
- const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
- framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer);
+ gl::Texture *textureObject = context->getTexture(texture);
+ gl::ImageIndex index(textureObject->getTarget(), level, layer);
+ framebuffer->setTextureAttachment(attachment, textureObject, index);
}
else
{
- switch (attachment)
- {
- case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, layer); break;
- case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, layer); break;
- case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break;
- }
+ framebuffer->setNULLAttachment(attachment);
}
}
}
-GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+GLvoid* GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
target, offset, length, access);
@@ -5735,7 +5867,7 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le
return NULL;
}
-void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
{
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
@@ -5752,7 +5884,7 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip
}
}
-void __stdcall glBindVertexArray(GLuint array)
+void GL_APIENTRY glBindVertexArray(GLuint array)
{
EVENT("(GLuint array = %u)", array);
@@ -5779,7 +5911,7 @@ void __stdcall glBindVertexArray(GLuint array)
}
}
-void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
+void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
{
EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
@@ -5808,7 +5940,7 @@ void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
}
}
-void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays)
+void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint* arrays)
{
EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
@@ -5834,7 +5966,7 @@ void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays)
}
}
-GLboolean __stdcall glIsVertexArray(GLuint array)
+GLboolean GL_APIENTRY glIsVertexArray(GLuint array)
{
EVENT("(GLuint array = %u)", array);
@@ -5860,7 +5992,7 @@ GLboolean __stdcall glIsVertexArray(GLuint array)
return GL_FALSE;
}
-void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
+void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
{
EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
target, index, data);
@@ -5941,7 +6073,7 @@ void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
}
}
-void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
+void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode)
{
EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
@@ -5986,7 +6118,7 @@ void __stdcall glBeginTransformFeedback(GLenum primitiveMode)
}
}
-void __stdcall glEndTransformFeedback(void)
+void GL_APIENTRY glEndTransformFeedback(void)
{
EVENT("(void)");
@@ -6012,7 +6144,7 @@ void __stdcall glEndTransformFeedback(void)
}
}
-void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
target, index, buffer, offset, size);
@@ -6090,7 +6222,7 @@ void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi
}
}
-void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
target, index, buffer);
@@ -6146,7 +6278,7 @@ void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
}
}
-void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
+void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
{
EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
program, count, varyings, bufferMode);
@@ -6195,7 +6327,7 @@ void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const
}
}
-void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
{
EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, "
"GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
@@ -6234,7 +6366,7 @@ void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz
}
}
-void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
index, size, type, stride, pointer);
@@ -6304,7 +6436,7 @@ void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs
}
}
-void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
+void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
{
EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
index, pname, params);
@@ -6346,7 +6478,7 @@ void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
}
}
-void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
+void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
{
EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
index, pname, params);
@@ -6388,7 +6520,7 @@ void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
}
}
-void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
{
EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
index, x, y, z, w);
@@ -6413,7 +6545,7 @@ void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint
}
}
-void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
{
EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
index, x, y, z, w);
@@ -6438,7 +6570,7 @@ void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GL
}
}
-void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v)
+void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint* v)
{
EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
@@ -6461,7 +6593,7 @@ void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v)
}
}
-void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v)
+void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint* v)
{
EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
@@ -6484,7 +6616,7 @@ void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v)
}
}
-void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params)
+void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint* params)
{
EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
program, location, params);
@@ -6506,7 +6638,7 @@ void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params)
}
}
-GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name)
+GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name)
{
EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
program, name);
@@ -6547,30 +6679,30 @@ GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name)
return 0;
}
-void __stdcall glUniform1ui(GLint location, GLuint v0)
+void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)
{
glUniform1uiv(location, 1, &v0);
}
-void __stdcall glUniform2ui(GLint location, GLuint v0, GLuint v1)
+void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)
{
const GLuint xy[] = { v0, v1 };
glUniform2uiv(location, 1, xy);
}
-void __stdcall glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
{
const GLuint xyz[] = { v0, v1, v2 };
glUniform3uiv(location, 1, xyz);
}
-void __stdcall glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
const GLuint xyzw[] = { v0, v1, v2, v3 };
glUniform4uiv(location, 1, xyzw);
}
-void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value)
+void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
location, count, value);
@@ -6588,7 +6720,7 @@ void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value)
}
}
-void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value)
+void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
location, count, value);
@@ -6606,7 +6738,7 @@ void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value)
}
}
-void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value)
+void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
location, count, value);
@@ -6624,7 +6756,7 @@ void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value)
}
}
-void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value)
+void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint* value)
{
EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
location, count, value);
@@ -6642,7 +6774,7 @@ void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value)
}
}
-void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
+void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
{
EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)",
buffer, drawbuffer, value);
@@ -6687,7 +6819,7 @@ void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val
}
}
-void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
+void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
{
EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)",
buffer, drawbuffer, value);
@@ -6724,7 +6856,7 @@ void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v
}
}
-void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
+void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
{
EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)",
buffer, drawbuffer, value);
@@ -6769,7 +6901,7 @@ void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v
}
}
-void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)",
buffer, drawbuffer, depth, stencil);
@@ -6806,7 +6938,7 @@ void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G
}
}
-const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index)
+const GLubyte* GL_APIENTRY glGetStringi(GLenum name, GLuint index)
{
EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
@@ -6837,7 +6969,7 @@ const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index)
return NULL;
}
-void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
+void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
{
EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
readTarget, writeTarget, readOffset, writeOffset, size);
@@ -6851,7 +6983,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
return;
}
- if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget))
+ if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, writeTarget))
{
context->recordError(gl::Error(GL_INVALID_ENUM));
return;
@@ -6881,7 +7013,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
return;
}
- if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size)
+ if (readBuffer == writeBuffer && std::abs(readOffset - writeOffset) < size)
{
context->recordError(gl::Error(GL_INVALID_VALUE));
return;
@@ -6900,7 +7032,7 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
}
}
-void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
+void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
{
EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)",
program, uniformCount, uniformNames, uniformIndices);
@@ -6954,7 +7086,7 @@ void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const G
}
}
-void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
+void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
{
EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
program, uniformCount, uniformIndices, pname, params);
@@ -7034,7 +7166,7 @@ void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const
}
}
-GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
+GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
{
EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
@@ -7075,7 +7207,7 @@ GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlo
return 0;
}
-void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
+void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
{
EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
program, uniformBlockIndex, pname, params);
@@ -7134,7 +7266,7 @@ void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde
}
}
-void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
+void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
{
EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)",
program, uniformBlockIndex, bufSize, length, uniformBlockName);
@@ -7176,7 +7308,7 @@ void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn
}
}
-void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
program, uniformBlockIndex, uniformBlockBinding);
@@ -7225,7 +7357,7 @@ void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G
}
}
-void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{
EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
mode, first, count, instanceCount);
@@ -7244,7 +7376,7 @@ void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GL
}
}
-void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount)
+void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount)
{
EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)",
mode, count, type, indices, instanceCount);
@@ -7263,7 +7395,7 @@ void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
}
}
-GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags)
+GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
{
EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
@@ -7288,13 +7420,24 @@ GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags)
return 0;
}
- return context->createFenceSync(condition);
+ GLsync fenceSync = context->createFenceSync();
+
+ gl::FenceSync *fenceSyncObject = context->getFenceSync(fenceSync);
+ gl::Error error = fenceSyncObject->set(condition);
+ if (error.isError())
+ {
+ context->deleteFenceSync(fenceSync);
+ context->recordError(error);
+ return NULL;
+ }
+
+ return fenceSync;
}
return NULL;
}
-GLboolean __stdcall glIsSync(GLsync sync)
+GLboolean GL_APIENTRY glIsSync(GLsync sync)
{
EVENT("(GLsync sync = 0x%0.8p)", sync);
@@ -7313,7 +7456,7 @@ GLboolean __stdcall glIsSync(GLsync sync)
return GL_FALSE;
}
-void __stdcall glDeleteSync(GLsync sync)
+void GL_APIENTRY glDeleteSync(GLsync sync)
{
EVENT("(GLsync sync = 0x%0.8p)", sync);
@@ -7336,7 +7479,7 @@ void __stdcall glDeleteSync(GLsync sync)
}
}
-GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
sync, flags, timeout);
@@ -7364,13 +7507,21 @@ GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeou
return GL_WAIT_FAILED;
}
- return fenceSync->clientWait(flags, timeout);
+ GLenum result = GL_WAIT_FAILED;
+ gl::Error error = fenceSync->clientWait(flags, timeout, &result);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return GL_WAIT_FAILED;
+ }
+
+ return result;
}
return GL_FALSE;
}
-void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
sync, flags, timeout);
@@ -7404,11 +7555,15 @@ void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
return;
}
- fenceSync->serverWait();
+ gl::Error error = fenceSync->serverWait(flags, timeout);
+ if (error.isError())
+ {
+ context->recordError(error);
+ }
}
}
-void __stdcall glGetInteger64v(GLenum pname, GLint64* params)
+void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64* params)
{
EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
pname, params);
@@ -7440,7 +7595,7 @@ void __stdcall glGetInteger64v(GLenum pname, GLint64* params)
}
}
-void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
+void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
{
EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)",
sync, pname, bufSize, length, values);
@@ -7471,10 +7626,20 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei*
switch (pname)
{
case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break;
- case GL_SYNC_STATUS: values[0] = static_cast<GLint>(fenceSync->getStatus()); break;
case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break;
case GL_SYNC_FLAGS: values[0] = 0; break;
+ case GL_SYNC_STATUS:
+ {
+ gl::Error error = fenceSync->getStatus(values);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ break;
+ }
+
default:
context->recordError(gl::Error(GL_INVALID_ENUM));
return;
@@ -7482,7 +7647,7 @@ void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei*
}
}
-void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
+void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
{
EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)",
target, index, data);
@@ -7558,7 +7723,7 @@ void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
}
}
-void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
+void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
target, pname, params);
@@ -7618,7 +7783,7 @@ void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa
}
}
-void __stdcall glGenSamplers(GLsizei count, GLuint* samplers)
+void GL_APIENTRY glGenSamplers(GLsizei count, GLuint* samplers)
{
EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
@@ -7644,7 +7809,7 @@ void __stdcall glGenSamplers(GLsizei count, GLuint* samplers)
}
}
-void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers)
+void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint* samplers)
{
EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
@@ -7670,7 +7835,7 @@ void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers)
}
}
-GLboolean __stdcall glIsSampler(GLuint sampler)
+GLboolean GL_APIENTRY glIsSampler(GLuint sampler)
{
EVENT("(GLuint sampler = %u)", sampler);
@@ -7689,7 +7854,7 @@ GLboolean __stdcall glIsSampler(GLuint sampler)
return GL_FALSE;
}
-void __stdcall glBindSampler(GLuint unit, GLuint sampler)
+void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler)
{
EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
@@ -7718,7 +7883,7 @@ void __stdcall glBindSampler(GLuint unit, GLuint sampler)
}
}
-void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
@@ -7751,12 +7916,12 @@ void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
}
}
-void __stdcall glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
+void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
{
glSamplerParameteri(sampler, pname, *param);
}
-void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
@@ -7789,12 +7954,12 @@ void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
}
}
-void __stdcall glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
+void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
{
glSamplerParameterf(sampler, pname, *param);
}
-void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
+void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
{
EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
@@ -7822,7 +7987,7 @@ void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* para
}
}
-void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
{
EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
@@ -7850,7 +8015,7 @@ void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* pa
}
}
-void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor)
+void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
{
EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
@@ -7873,7 +8038,7 @@ void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor)
}
}
-void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
+void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
{
EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
@@ -7916,7 +8081,7 @@ void __stdcall glBindTransformFeedback(GLenum target, GLuint id)
}
}
-void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
+void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
{
EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
@@ -7936,7 +8101,7 @@ void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
}
}
-void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids)
+void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids)
{
EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
@@ -7956,7 +8121,7 @@ void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids)
}
}
-GLboolean __stdcall glIsTransformFeedback(GLuint id)
+GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)
{
EVENT("(GLuint id = %u)", id);
@@ -7975,7 +8140,7 @@ GLboolean __stdcall glIsTransformFeedback(GLuint id)
return GL_FALSE;
}
-void __stdcall glPauseTransformFeedback(void)
+void GL_APIENTRY glPauseTransformFeedback(void)
{
EVENT("(void)");
@@ -8002,7 +8167,7 @@ void __stdcall glPauseTransformFeedback(void)
}
}
-void __stdcall glResumeTransformFeedback(void)
+void GL_APIENTRY glResumeTransformFeedback(void)
{
EVENT("(void)");
@@ -8029,7 +8194,7 @@ void __stdcall glResumeTransformFeedback(void)
}
}
-void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
+void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
{
EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)",
program, bufSize, length, binaryFormat, binary);
@@ -8048,7 +8213,7 @@ void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* leng
}
}
-void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
+void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
{
EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
program, binaryFormat, binary, length);
@@ -8067,7 +8232,7 @@ void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid
}
}
-void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value)
+void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
{
EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)",
program, pname, value);
@@ -8086,7 +8251,7 @@ void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value)
}
}
-void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
+void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
{
EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)",
target, numAttachments, attachments);
@@ -8106,14 +8271,21 @@ void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, co
}
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ ASSERT(framebuffer);
+
+ if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE)
{
- framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+ gl::Error error = framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
}
-void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, "
"GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
@@ -8134,14 +8306,21 @@ void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
}
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- if (framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ ASSERT(framebuffer);
+
+ if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE)
{
- framebuffer->invalidateSub(context->getCaps(), numAttachments, attachments, x, y, width, height);
+ gl::Error error = framebuffer->invalidateSub(numAttachments, attachments, x, y, width, height);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
}
-void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, levels, internalformat, width, height);
@@ -8165,14 +8344,24 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform
case GL_TEXTURE_2D:
{
gl::Texture2D *texture2d = context->getTexture2D();
- texture2d->storage(levels, internalformat, width, height);
+ gl::Error error = texture2d->storage(levels, internalformat, width, height);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_CUBE_MAP:
{
gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
- textureCube->storage(levels, internalformat, width);
+ gl::Error error = textureCube->storage(levels, internalformat, width);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -8183,7 +8372,7 @@ void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalform
}
}
-void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
"GLsizei height = %d, GLsizei depth = %d)",
@@ -8208,14 +8397,24 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform
case GL_TEXTURE_3D:
{
gl::Texture3D *texture3d = context->getTexture3D();
- texture3d->storage(levels, internalformat, width, height, depth);
+ gl::Error error = texture3d->storage(levels, internalformat, width, height, depth);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
case GL_TEXTURE_2D_ARRAY:
{
gl::Texture2DArray *texture2darray = context->getTexture2DArray();
- texture2darray->storage(levels, internalformat, width, height, depth);
+ gl::Error error = texture2darray->storage(levels, internalformat, width, height, depth);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -8225,7 +8424,7 @@ void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalform
}
}
-void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
{
EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, "
"GLint* params = 0x%0.8p)",
@@ -8281,7 +8480,7 @@ void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenu
// Extension functions
-void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
@@ -8299,12 +8498,17 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
return;
}
- context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
- mask, filter);
+ gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ mask, filter);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
@@ -8315,7 +8519,7 @@ void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat
UNIMPLEMENTED(); // FIXME
}
-void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
+void GL_APIENTRY glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
GLenum *binaryFormat, void *binary)
{
EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
@@ -8340,15 +8544,16 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l
return;
}
- if (!programBinary->save(binaryFormat, binary, bufSize, length))
+ gl::Error error = programBinary->save(binaryFormat, binary, bufSize, length);
+ if (error.isError())
{
- context->recordError(gl::Error(GL_INVALID_OPERATION));
+ context->recordError(error);
return;
}
}
}
-void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
+void GL_APIENTRY glProgramBinaryOES(GLuint program, GLenum binaryFormat,
const void *binary, GLint length)
{
EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
@@ -8371,11 +8576,16 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
return;
}
- context->setProgramBinary(program, binaryFormat, binary, length);
+ gl::Error error = context->setProgramBinary(program, binaryFormat, binary, length);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
}
-void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
{
EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
@@ -8388,6 +8598,8 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
return;
}
+ ASSERT(context->getState().getDrawFramebuffer());
+
if (context->getState().getDrawFramebuffer()->id() == 0)
{
if (n != 1)
@@ -8416,6 +8628,7 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
}
gl::Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+ ASSERT(framebuffer);
for (unsigned int colorAttachment = 0; colorAttachment < static_cast<unsigned int>(n); colorAttachment++)
{
@@ -8429,7 +8642,7 @@ void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
}
}
-void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params)
+void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, void** params)
{
EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
@@ -8461,7 +8674,7 @@ void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params
}
}
-void * __stdcall glMapBufferOES(GLenum target, GLenum access)
+void * GL_APIENTRY glMapBufferOES(GLenum target, GLenum access)
{
EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
@@ -8507,7 +8720,7 @@ void * __stdcall glMapBufferOES(GLenum target, GLenum access)
return NULL;
}
-GLboolean __stdcall glUnmapBufferOES(GLenum target)
+GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
@@ -8543,7 +8756,7 @@ GLboolean __stdcall glUnmapBufferOES(GLenum target)
return GL_FALSE;
}
-void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
target, offset, length, access);
@@ -8638,7 +8851,7 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr
return NULL;
}
-void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length)
+void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length)
{
EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
@@ -8686,7 +8899,7 @@ void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsi
}
}
-__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname)
{
struct Extension
{
@@ -8744,7 +8957,7 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
// Non-public functions used by EGL
-bool __stdcall glBindTexImage(egl::Surface *surface)
+bool EGLAPIENTRY glBindTexImage(egl::Surface *surface)
{
EVENT("(egl::Surface* surface = 0x%0.8p)",
surface);
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 51447e273a..00f63ae079 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
@@ -11,24 +11,42 @@
#include "common/tls.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-__declspec(thread)
-#endif
-static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
+static TLSIndex currentTLS = TLS_INVALID_INDEX;
namespace gl
{
-Current *AllocateCurrent()
+// TODO(kbr): figure out how these are going to be managed on
+// non-Windows platforms. These routines would need to be exported
+// from ANGLE and called cooperatively when users create and destroy
+// threads -- or the initialization of the TLS index, and allocation
+// of thread-local data, will have to be done lazily. Will have to use
+// destructor function with pthread_create_key on POSIX platforms to
+// clean up thread-local data.
+
+// Call this exactly once at process startup.
+bool CreateThreadLocalIndex()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (currentTLS == TLS_OUT_OF_INDEXES)
+ currentTLS = CreateTLSIndex();
+ if (currentTLS == TLS_INVALID_INDEX)
{
- currentTLS = CreateTLSIndex();
+ return false;
}
-#endif
- ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
- if (currentTLS == TLS_OUT_OF_INDEXES)
+ return true;
+}
+
+// Call this exactly once at process shutdown.
+void DestroyThreadLocalIndex()
+{
+ DestroyTLSIndex(currentTLS);
+ currentTLS = TLS_INVALID_INDEX;
+}
+
+// Call this upon thread startup.
+Current *AllocateCurrent()
+{
+ ASSERT(currentTLS != TLS_INVALID_INDEX);
+ if (currentTLS == TLS_INVALID_INDEX)
{
return NULL;
}
@@ -46,14 +64,9 @@ Current *AllocateCurrent()
return current;
}
+// Call this upon thread shutdown.
void DeallocateCurrent()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- return;
- }
-#endif
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
SafeDelete(current);
SetTLSValue(currentTLS, NULL);
@@ -61,22 +74,21 @@ void DeallocateCurrent()
}
-#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
-
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
{
-#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
- return DisableThreadLibraryCalls(instance);
-#endif
- currentTLS = CreateTLSIndex();
- if (currentTLS == TLS_OUT_OF_INDEXES)
+ if (!gl::CreateThreadLocalIndex())
{
return FALSE;
}
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+ gl::InitializeDebugAnnotations();
+#endif
}
// Fall through to initialize index
case DLL_THREAD_ATTACH:
@@ -91,9 +103,11 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_PROCESS_DETACH:
{
-#if !defined(ANGLE_PLATFORM_WINRT)
gl::DeallocateCurrent();
- DestroyTLSIndex(currentTLS);
+ gl::DestroyThreadLocalIndex();
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+ gl::UninitializeDebugAnnotations();
#endif
}
break;
@@ -103,8 +117,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE;
}
-
-#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
+#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC
namespace gl
{
@@ -152,7 +165,7 @@ Context *getNonLostContext()
{
if (context->isContextLost())
{
- gl::error(GL_OUT_OF_MEMORY);
+ context->recordError(Error(GL_OUT_OF_MEMORY, "Context has been lost."));
return NULL;
}
else
@@ -170,32 +183,4 @@ egl::Display *getDisplay()
return current->display;
}
-// Records an error code
-void error(GLenum errorCode)
-{
- gl::Context *context = glGetCurrentContext();
- context->recordError(Error(errorCode));
-
- switch (errorCode)
- {
- case GL_INVALID_ENUM:
- TRACE("\t! Error generated: invalid enum\n");
- break;
- case GL_INVALID_VALUE:
- TRACE("\t! Error generated: invalid value\n");
- break;
- case GL_INVALID_OPERATION:
- TRACE("\t! Error generated: invalid operation\n");
- break;
- case GL_OUT_OF_MEMORY:
- TRACE("\t! Error generated: out of memory\n");
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- TRACE("\t! Error generated: invalid framebuffer operation\n");
- break;
- default: UNREACHABLE();
- }
-}
-
}
-
diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h
index c30ad3375c..dff02787f5 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.h
+++ b/src/3rdparty/angle/src/libGLESv2/main.h
@@ -14,14 +14,11 @@
#include <GLES2/gl2.h>
#include <EGL/egl.h>
-#ifndef Sleep
-#define Sleep(ms) WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE)
-#endif
-
namespace egl
{
class Display;
class Surface;
+class AttributeMap;
}
namespace gl
@@ -40,16 +37,6 @@ Context *getContext();
Context *getNonLostContext();
egl::Display *getDisplay();
-void error(GLenum errorCode);
-
-template<class T>
-const T &error(GLenum errorCode, const T &returnValue)
-{
- error(errorCode);
-
- return returnValue;
-}
-
}
namespace rx
@@ -64,11 +51,11 @@ gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext,
void glDestroyContext(gl::Context *context);
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
gl::Context *glGetCurrentContext();
-rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType);
+rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap);
void glDestroyRenderer(rx::Renderer *renderer);
-__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
-bool __stdcall glBindTexImage(egl::Surface *surface);
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname);
+bool EGLAPIENTRY glBindTexImage(egl::Surface *surface);
}
#endif // LIBGLESV2_MAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h
index f0b5f02227..c031effabd 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h
@@ -12,6 +12,8 @@
#include "common/angleutils.h"
#include "libGLESv2/Buffer.h"
+#include <cstdint>
+
namespace rx
{
@@ -21,7 +23,6 @@ class BufferImpl
virtual ~BufferImpl() { }
virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0;
- virtual void *getData() = 0;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0;
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
index d54e6becd3..1dd46785d9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
@@ -4,29 +4,47 @@
// found in the LICENSE file.
//
-// FenceImpl.h: Defines the rx::FenceImpl class.
+// FenceImpl.h: Defines the rx::FenceNVImpl and rx::FenceSyncImpl classes.
#ifndef LIBGLESV2_RENDERER_FENCEIMPL_H_
#define LIBGLESV2_RENDERER_FENCEIMPL_H_
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
+#include "angle_gl.h"
+
namespace rx
{
-class FenceImpl
+class FenceNVImpl
+{
+ public:
+ FenceNVImpl() { };
+ virtual ~FenceNVImpl() { };
+
+ virtual gl::Error set() = 0;
+ virtual gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) = 0;
+ virtual gl::Error finishFence(GLboolean *outFinished) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FenceNVImpl);
+};
+
+class FenceSyncImpl
{
public:
- FenceImpl() { };
- virtual ~FenceImpl() { };
+ FenceSyncImpl() { };
+ virtual ~FenceSyncImpl() { };
- virtual bool isSet() const = 0;
- virtual void set() = 0;
- virtual bool test(bool flushCommandBuffer) = 0;
- virtual bool hasError() const = 0;
+ virtual gl::Error set() = 0;
+ virtual gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) = 0;
+ virtual gl::Error serverWait(GLbitfield flags, GLuint64 timeout) = 0;
+ virtual gl::Error getStatus(GLint *outResult) = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(FenceImpl);
+ DISALLOW_COPY_AND_ASSIGN(FenceSyncImpl);
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
index 370b086233..5b9b75f562 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
@@ -4,18 +4,20 @@
// found in the LICENSE file.
//
-// Image.h: Implements the rx::Image class, an abstract base class for the
+// Image.h: Implements the rx::Image class, an abstract base class for the
// renderer-specific classes which will define the interface to the underlying
// surfaces or resources.
#include "libGLESv2/renderer/Image.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/main.h"
namespace rx
{
Image::Image()
{
- mWidth = 0;
+ mWidth = 0;
mHeight = 0;
mDepth = 0;
mInternalFormat = GL_NONE;
@@ -25,4 +27,20 @@ Image::Image()
mDirty = false;
}
+gl::Error Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source)
+{
+ gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
+ ASSERT(colorbuffer);
+
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(renderTarget);
+ return copy(xoffset, yoffset, zoffset, area, renderTarget);
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h
index 3bfc663762..9071a88c67 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-// Image.h: Defines the rx::Image class, an abstract base class for the
+// Image.h: Defines the rx::Image class, an abstract base class for the
// renderer-specific classes which will define the interface to the underlying
// surfaces or resources.
@@ -12,18 +12,22 @@
#define LIBGLESV2_RENDERER_IMAGE_H_
#include "common/debug.h"
+#include "libGLESv2/Error.h"
#include <GLES2/gl2.h>
namespace gl
{
class Framebuffer;
+struct Rectangle;
+struct ImageIndex;
}
namespace rx
{
-
-class Renderer;
+class RendererD3D;
+class RenderTarget;
+class TextureStorage;
class Image
{
@@ -43,14 +47,17 @@ class Image
void markClean() {mDirty = false;}
virtual bool isDirty() const = 0;
- virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0;
+ virtual bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0;
- virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input) = 0;
- virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input) = 0;
+ virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input) = 0;
+ virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input) = 0;
- virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
+ gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0;
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0;
protected:
GLsizei mWidth;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
index f68ac383de..d472e1499e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
@@ -111,11 +111,7 @@ IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
{
-#if defined(_MSC_VER) && _MSC_VER < 1600
- return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
-#else
return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
-#endif
}
IndexRangeCache::IndexBounds::IndexBounds()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp
new file mode 100644
index 0000000000..f9fcad38a4
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp
@@ -0,0 +1,146 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#include "libGLESv2/renderer/ProgramImpl.h"
+
+#include "common/utilities.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+namespace
+{
+
+unsigned int ParseAndStripArrayIndex(std::string* name)
+{
+ unsigned int subscript = GL_INVALID_INDEX;
+
+ // Strip any trailing array operator and retrieve the subscript
+ size_t open = name->find_last_of('[');
+ size_t close = name->find_last_of(']');
+ if (open != std::string::npos && close == name->length() - 1)
+ {
+ subscript = atoi(name->substr(open + 1).c_str());
+ name->erase(open);
+ }
+
+ return subscript;
+}
+
+}
+
+ProgramImpl::~ProgramImpl()
+{
+ // Ensure that reset was called by the inherited class during destruction
+ ASSERT(mUniformIndex.size() == 0);
+}
+
+gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
+{
+ ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
+ return mUniforms[mUniformIndex[location].index];
+}
+
+gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ if (mUniforms[uniformIndex]->name == name)
+ {
+ return mUniforms[uniformIndex];
+ }
+ }
+
+ return NULL;
+}
+
+gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const
+{
+ ASSERT(blockIndex < mUniformBlocks.size());
+ return mUniformBlocks[blockIndex];
+}
+
+GLint ProgramImpl::getUniformLocation(std::string name)
+{
+ unsigned int subscript = ParseAndStripArrayIndex(&name);
+
+ unsigned int numUniforms = mUniformIndex.size();
+ for (unsigned int location = 0; location < numUniforms; location++)
+ {
+ if (mUniformIndex[location].name == name)
+ {
+ const int index = mUniformIndex[location].index;
+ const bool isArray = mUniforms[index]->isArray();
+
+ if ((isArray && mUniformIndex[location].element == subscript) ||
+ (subscript == GL_INVALID_INDEX))
+ {
+ return location;
+ }
+ }
+ }
+
+ return -1;
+}
+
+GLuint ProgramImpl::getUniformIndex(std::string name)
+{
+ unsigned int subscript = ParseAndStripArrayIndex(&name);
+
+ // The app is not allowed to specify array indices other than 0 for arrays of basic types
+ if (subscript != 0 && subscript != GL_INVALID_INDEX)
+ {
+ return GL_INVALID_INDEX;
+ }
+
+ unsigned int numUniforms = mUniforms.size();
+ for (unsigned int index = 0; index < numUniforms; index++)
+ {
+ if (mUniforms[index]->name == name)
+ {
+ if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
+ {
+ return index;
+ }
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+GLuint ProgramImpl::getUniformBlockIndex(std::string name) const
+{
+ unsigned int subscript = ParseAndStripArrayIndex(&name);
+
+ unsigned int numUniformBlocks = mUniformBlocks.size();
+ for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
+ {
+ const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
+ if (uniformBlock.name == name)
+ {
+ const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
+ if (subscript == uniformBlock.elementIndex || arrayElementZero)
+ {
+ return blockIndex;
+ }
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+void ProgramImpl::reset()
+{
+ SafeDeleteContainer(mUniforms);
+ mUniformIndex.clear();
+ SafeDeleteContainer(mUniformBlocks);
+ mTransformFeedbackLinkedVaryings.clear();
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h
index ba0955fdf8..6aaa23cf89 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h
@@ -13,44 +13,113 @@
#include "libGLESv2/BinaryStream.h"
#include "libGLESv2/Constants.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Shader.h"
+#include "libGLESv2/renderer/Renderer.h"
+
+#include <map>
namespace rx
{
-class DynamicHLSL;
-class Renderer;
-
class ProgramImpl
{
-public:
- virtual ~ProgramImpl() { }
+ public:
+ ProgramImpl() { }
+ virtual ~ProgramImpl();
+
+ const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
+ const std::vector<gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
+ const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
+ const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; }
+ const sh::Attribute *getShaderAttributes() const { return mShaderAttributes; }
+
+ std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
+ std::vector<gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
+ std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
+ std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
+ sh::Attribute *getShaderAttributes() { return mShaderAttributes; }
+
+ gl::LinkedUniform *getUniformByLocation(GLint location) const;
+ gl::LinkedUniform *getUniformByName(const std::string &name) const;
+ gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const;
- // TODO: Temporary interfaces to ease migration. Remove soon!
- virtual Renderer *getRenderer() = 0;
- virtual DynamicHLSL *getDynamicHLSL() = 0;
- virtual const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() = 0;
+ GLint getUniformLocation(std::string name);
+ GLuint getUniformIndex(std::string name);
+ GLuint getUniformBlockIndex(std::string name) const;
+
+ virtual bool usesPointSize() const = 0;
+ virtual int getShaderVersion() const = 0;
+ virtual GLenum getTransformFeedbackBufferMode() const = 0;
virtual GLenum getBinaryFormat() = 0;
- virtual bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
- virtual bool save(gl::BinaryOutputStream *stream) = 0;
-
- virtual rx::ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers) = 0;
- virtual rx::ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers) = 0;
-
- virtual bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int,
- gl::VariableLocation> *outputVariables) = 0;
-
- virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0;
-
- virtual void reset() = 0;
+ virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
+ virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
+
+ virtual gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables) = 0;
+
+ virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform1iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform2iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform3iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform4iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+
+ virtual void getUniformfv(GLint location, GLfloat *params) = 0;
+ virtual void getUniformiv(GLint location, GLint *params) = 0;
+ virtual void getUniformuiv(GLint location, GLuint *params) = 0;
+
+ virtual void reset();
+
+ // TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to
+ // determine if they can be removed from this interface.
+ virtual GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const = 0;
+ virtual GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const = 0;
+ virtual GLint getUsedSamplerRange(gl::SamplerType type) const = 0;
+ virtual void updateSamplerMapping() = 0;
+ virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0;
+
+ virtual gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers) = 0;
+
+ virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::Caps &caps) = 0;
+ virtual bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
+ const gl::Caps &caps) = 0;
+
+ virtual gl::Error applyUniforms() = 0;
+ virtual gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps) = 0;
+ virtual bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
+ unsigned int registerIndex, const gl::Caps &caps) = 0;
+
+ protected:
+ DISALLOW_COPY_AND_ASSIGN(ProgramImpl);
+
+ std::vector<gl::LinkedUniform*> mUniforms;
+ std::vector<gl::VariableLocation> mUniformIndex;
+ std::vector<gl::UniformBlock*> mUniformBlocks;
+ std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
+
+ sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS];
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp
new file mode 100644
index 0000000000..857fdc9dae
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget.cpp: Implements serial handling for rx::RenderTarget
+
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+unsigned int RenderTarget::mCurrentSerial = 1;
+
+RenderTarget::RenderTarget()
+ : mSerial(issueSerials(1))
+{
+}
+
+RenderTarget::~RenderTarget()
+{
+}
+
+unsigned int RenderTarget::getSerial() const
+{
+ return mSerial;
+}
+
+unsigned int RenderTarget::issueSerials(unsigned int count)
+{
+ unsigned int firstSerial = mCurrentSerial;
+ mCurrentSerial += count;
+ return firstSerial;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
index 44637ec7de..3bdfb0cc98 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
@@ -18,28 +18,22 @@ namespace rx
class RenderTarget
{
public:
- RenderTarget()
- {
- mWidth = 0;
- mHeight = 0;
- mDepth = 0;
- mInternalFormat = GL_NONE;
- mActualFormat = GL_NONE;
- mSamples = 0;
- }
+ RenderTarget();
+ virtual ~RenderTarget();
- virtual ~RenderTarget() {};
-
- GLsizei getWidth() const { return mWidth; }
- GLsizei getHeight() const { return mHeight; }
- GLsizei getDepth() const { return mDepth; }
- GLenum getInternalFormat() const { return mInternalFormat; }
- GLenum getActualFormat() const { return mActualFormat; }
- GLsizei getSamples() const { return mSamples; }
- gl::Extents getExtents() const { return gl::Extents(mWidth, mHeight, mDepth); }
+ virtual GLsizei getWidth() const = 0;
+ virtual GLsizei getHeight() const = 0;
+ virtual GLsizei getDepth() const = 0;
+ virtual GLenum getInternalFormat() const = 0;
+ virtual GLenum getActualFormat() const = 0;
+ virtual GLsizei getSamples() const = 0;
+ gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); }
virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
+ virtual unsigned int getSerial() const;
+ static unsigned int issueSerials(unsigned int count);
+
struct Desc {
GLsizei width;
GLsizei height;
@@ -47,16 +41,11 @@ class RenderTarget
GLenum format;
};
- protected:
- GLsizei mWidth;
- GLsizei mHeight;
- GLsizei mDepth;
- GLenum mInternalFormat;
- GLenum mActualFormat;
- GLsizei mSamples;
-
private:
DISALLOW_COPY_AND_ASSIGN(RenderTarget);
+
+ const unsigned int mSerial;
+ static unsigned int mCurrentSerial;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp
new file mode 100644
index 0000000000..770ae8e9c6
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferImpl.h: Implements the shared methods of the abstract class gl::RenderbufferImpl
+
+#include "libGLESv2/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+RenderbufferImpl::RenderbufferImpl()
+{
+}
+
+RenderbufferImpl::~RenderbufferImpl()
+{
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h
new file mode 100644
index 0000000000..52e070f1d3
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h
@@ -0,0 +1,41 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferImpl.h: Defines the abstract class gl::RenderbufferImpl
+
+#ifndef LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
+#define LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
+
+#include "angle_gl.h"
+
+#include "libGLESv2/Error.h"
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class RenderbufferImpl
+{
+ public:
+ RenderbufferImpl();
+ virtual ~RenderbufferImpl() = 0;
+
+ virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) = 0;
+
+ virtual GLsizei getWidth() const = 0;
+ virtual GLsizei getHeight() const = 0;
+ virtual GLenum getInternalFormat() const = 0;
+ virtual GLenum getActualFormat() const = 0;
+ virtual GLsizei getSamples() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderbufferImpl);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
index 910d0285f1..df3dae1e38 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
@@ -6,11 +6,12 @@
// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
+#include "common/utilities.h"
+#include "libEGL/AttributeMap.h"
#include "libGLESv2/main.h"
-#include "libGLESv2/Program.h"
#include "libGLESv2/renderer/Renderer.h"
-#include "common/utilities.h"
-#include "libGLESv2/Shader.h"
+
+#include <EGL/eglext.h>
#if defined (ANGLE_ENABLE_D3D9)
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
@@ -29,15 +30,12 @@
#define ANGLE_DEFAULT_D3D11 0
#endif
-#include <EGL/eglext.h>
-
namespace rx
{
-Renderer::Renderer(egl::Display *display)
- : mDisplay(display),
- mCapsInitialized(false),
- mCurrentClientVersion(2)
+Renderer::Renderer()
+ : mCapsInitialized(false),
+ mWorkaroundsInitialized(false)
{
}
@@ -78,12 +76,23 @@ const gl::Extensions &Renderer::getRendererExtensions() const
return mExtensions;
}
-typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, EGLint);
+const Workarounds &Renderer::getWorkarounds() const
+{
+ if (!mWorkaroundsInitialized)
+ {
+ mWorkarounds = generateWorkarounds();
+ mWorkaroundsInitialized = true;
+ }
+
+ return mWorkarounds;
+}
+
+typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, const egl::AttributeMap &);
template <typename RendererType>
-Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType)
+Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attributes)
{
- return new RendererType(display, nativeDisplay, requestedDisplayType);
+ return new RendererType(display, nativeDisplay, attributes);
}
}
@@ -91,15 +100,16 @@ Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDispl
extern "C"
{
-rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType)
+rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap)
{
std::vector<rx::CreateRendererFunction> rendererCreationFunctions;
+ EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+
# if defined(ANGLE_ENABLE_D3D11)
if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
- requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
- requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{
rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
}
@@ -138,7 +148,7 @@ rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativ
for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
{
- rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, requestedDisplayType);
+ rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, attribMap);
if (renderer->initialize() == EGL_SUCCESS)
{
return renderer;
@@ -155,7 +165,8 @@ rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativ
void glDestroyRenderer(rx::Renderer *renderer)
{
- delete renderer;
+ ASSERT(renderer);
+ SafeDelete(renderer);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
index b2249741ab..b85895a938 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
@@ -10,10 +10,13 @@
#ifndef LIBGLESV2_RENDERER_RENDERER_H_
#define LIBGLESV2_RENDERER_RENDERER_H_
-#include "libGLESv2/Uniform.h"
-#include "libGLESv2/angletypes.h"
#include "libGLESv2/Caps.h"
#include "libGLESv2/Error.h"
+#include "libGLESv2/Uniform.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/renderer/Workarounds.h"
+#include "common/NativeWindow.h"
+#include "common/mathutil.h"
#include <cstdint>
@@ -32,37 +35,26 @@ class Display;
namespace gl
{
-class InfoLog;
-class ProgramBinary;
-struct LinkedVarying;
-struct VertexAttribute;
class Buffer;
-class Texture;
class Framebuffer;
-struct VertexAttribCurrentValueData;
+struct Data;
}
namespace rx
{
-class TextureStorage;
-class VertexBuffer;
-class IndexBuffer;
class QueryImpl;
-class FenceImpl;
+class FenceNVImpl;
+class FenceSyncImpl;
class BufferImpl;
class VertexArrayImpl;
-class BufferStorage;
-struct TranslatedIndexData;
class ShaderImpl;
class ProgramImpl;
-class ShaderExecutable;
-class SwapChain;
-class RenderTarget;
-class Image;
-class TextureStorage;
-class UniformStorage;
class TextureImpl;
class TransformFeedbackImpl;
+class RenderbufferImpl;
+struct TranslatedIndexData;
+struct Workarounds;
+class SwapChain;
struct ConfigDesc
{
@@ -73,30 +65,10 @@ struct ConfigDesc
bool es3Capable;
};
-struct dx_VertexConstants
-{
- float depthRange[4];
- float viewAdjust[4];
-};
-
-struct dx_PixelConstants
-{
- float depthRange[4];
- float viewCoords[4];
- float depthFront[4];
-};
-
-enum ShaderType
-{
- SHADER_VERTEX,
- SHADER_PIXEL,
- SHADER_GEOMETRY
-};
-
class Renderer
{
public:
- explicit Renderer(egl::Display *display);
+ Renderer();
virtual ~Renderer();
virtual EGLint initialize() = 0;
@@ -105,163 +77,116 @@ class Renderer
virtual int generateConfigs(ConfigDesc **configDescList) = 0;
virtual void deleteConfigs(ConfigDesc *configDescList) = 0;
- virtual void sync(bool block) = 0;
-
- virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+ virtual gl::Error sync(bool block) = 0;
- virtual gl::Error generateSwizzle(gl::Texture *texture) = 0;
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
- virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+ virtual gl::Error drawArrays(const gl::Data &data, GLenum mode,
+ GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange) = 0;
- virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
+ virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0;
+ virtual gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0;
+ virtual gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0;
+ virtual gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values) = 0;
+ virtual gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0;
- virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0;
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask) = 0;
- virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
- int stencilBackRef, bool frontFaceCCW) = 0;
+ virtual gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels) = 0;
- virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
- virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
- bool ignoreViewport) = 0;
-
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
- bool rasterizerDiscard, bool transformFeedbackActive) = 0;
- virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary) = 0;
- virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
- virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances) = 0;
- virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
- virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0;
-
- virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
- virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
- gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
-
- virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
-
- virtual void markAllStateDirty() = 0;
-
- // lost device
- virtual void notifyDeviceLost() = 0;
- virtual bool isDeviceLost() = 0;
- virtual bool testDeviceLost(bool notify) = 0;
- virtual bool testDeviceResettable() = 0;
-
- // Renderer capabilities (virtual because it is used by egl::Display, do not override)
- virtual const gl::Caps &getRendererCaps() const;
- virtual const gl::TextureCapsMap &getRendererTextureCaps() const;
- virtual const gl::Extensions &getRendererExtensions() const;
-
- virtual DWORD getAdapterVendor() const = 0;
- virtual std::string getRendererDescription() const = 0;
- virtual GUID getAdapterIdentifier() const = 0;
+ virtual gl::Error blitFramebuffer(const gl::Data &data,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) = 0;
- virtual unsigned int getReservedVertexUniformVectors() const = 0;
- virtual unsigned int getReservedFragmentUniformVectors() const = 0;
- virtual unsigned int getReservedVertexUniformBuffers() const = 0;
- virtual unsigned int getReservedFragmentUniformBuffers() const = 0;
+ // TODO(jmadill): caps? and virtual for egl::Display
virtual bool getShareHandleSupport() const = 0;
virtual bool getPostSubBufferSupport() const = 0;
- virtual int getMajorShaderModel() const = 0;
- virtual int getMinSwapInterval() const = 0;
- virtual int getMaxSwapInterval() const = 0;
-
- // Pixel operations
- virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) = 0;
- virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) = 0;
- virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) = 0;
- virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) = 0;
-
- virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0;
- virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0;
- virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
- virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
-
- virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) = 0;
-
- virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
-
- // RenderTarget creation
- virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0;
- virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples) = 0;
-
// Shader creation
- virtual ShaderImpl *createShader(GLenum type) = 0;
+ virtual ShaderImpl *createShader(const gl::Data &data, GLenum type) = 0;
virtual ProgramImpl *createProgram() = 0;
// Shader operations
virtual void releaseShaderCompiler() = 0;
- virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers) = 0;
- virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround) = 0;
- virtual UniformStorage *createUniformStorage(size_t storageSize) = 0;
-
- // Image operations
- virtual Image *createImage() = 0;
- virtual void generateMipmap(Image *dest, Image *source) = 0;
- virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0;
- virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0;
- virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0;
- virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
- virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
// Texture creation
virtual TextureImpl *createTexture(GLenum target) = 0;
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer() = 0;
+ virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth) = 0;
+
// Buffer creation
virtual BufferImpl *createBuffer() = 0;
- virtual VertexBuffer *createVertexBuffer() = 0;
- virtual IndexBuffer *createIndexBuffer() = 0;
// Vertex Array creation
virtual VertexArrayImpl *createVertexArray() = 0;
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type) = 0;
- virtual FenceImpl *createFence() = 0;
+ virtual FenceNVImpl *createFenceNV() = 0;
+ virtual FenceSyncImpl *createFenceSync() = 0;
// Transform Feedback creation
- virtual TransformFeedbackImpl* createTransformFeedback() = 0;
+ virtual TransformFeedbackImpl *createTransformFeedback() = 0;
- // Current GLES client version
- void setCurrentClientVersion(int clientVersion) { mCurrentClientVersion = clientVersion; }
- int getCurrentClientVersion() const { return mCurrentClientVersion; }
+ // lost device
+ //TODO(jmadill): investigate if this stuff is necessary in GL
+ virtual void notifyDeviceLost() = 0;
+ virtual bool isDeviceLost() = 0;
+ virtual bool testDeviceLost(bool notify) = 0;
+ virtual bool testDeviceResettable() = 0;
- // Buffer-to-texture and Texture-to-buffer copies
- virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
- virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
+ virtual DWORD getAdapterVendor() const = 0;
+ virtual std::string getRendererDescription() const = 0;
+ virtual GUID getAdapterIdentifier() const = 0;
- virtual bool getLUID(LUID *adapterLuid) const = 0;
- virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0;
- virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
+ // Renderer capabilities (virtual because of egl::Display)
+ virtual const gl::Caps &getRendererCaps() const;
+ const gl::TextureCapsMap &getRendererTextureCaps() const;
+ virtual const gl::Extensions &getRendererExtensions() const;
+ const Workarounds &getWorkarounds() const;
- protected:
- egl::Display *mDisplay;
+ // TODO(jmadill): needed by egl::Display, probably should be removed
+ virtual int getMajorShaderModel() const = 0;
+ virtual int getMinSwapInterval() const = 0;
+ virtual int getMaxSwapInterval() const = 0;
+ virtual bool getLUID(LUID *adapterLuid) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Renderer);
virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0;
+ virtual Workarounds generateWorkarounds() const = 0;
mutable bool mCapsInitialized;
mutable gl::Caps mCaps;
mutable gl::TextureCapsMap mTextureCaps;
mutable gl::Extensions mExtensions;
- int mCurrentClientVersion;
+ mutable bool mWorkaroundsInitialized;
+ mutable Workarounds mWorkarounds;
+};
+
+struct dx_VertexConstants
+{
+ float depthRange[4];
+ float viewAdjust[4];
+};
+
+struct dx_PixelConstants
+{
+ float depthRange[4];
+ float viewCoords[4];
+ float depthFront[4];
+};
+
+enum ShaderType
+{
+ SHADER_VERTEX,
+ SHADER_PIXEL,
+ SHADER_GEOMETRY
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
index f17195673d..f1a96d74fb 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
@@ -40,10 +40,21 @@ class ShaderExecutable
return mFunctionBuffer.size();
}
+ const std::string &getDebugInfo() const
+ {
+ return mDebugInfo;
+ }
+
+ void appendDebugInfo(const std::string &info)
+ {
+ mDebugInfo += info;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(ShaderExecutable);
std::vector<uint8_t> mFunctionBuffer;
+ std::string mDebugInfo;
};
class UniformStorage
@@ -64,4 +75,4 @@ class UniformStorage
}
-#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
+#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h
index de5d30e6fe..cb0d360f0b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h
@@ -23,9 +23,10 @@ class ShaderImpl
ShaderImpl() { }
virtual ~ShaderImpl() { }
- virtual bool compile(const std::string &source) = 0;
+ virtual bool compile(const gl::Data &data, const std::string &source) = 0;
virtual const std::string &getInfoLog() const = 0;
virtual const std::string &getTranslatedSource() const = 0;
+ virtual std::string getDebugInfo() const = 0;
const std::vector<gl::PackedVarying> &getVaryings() const { return mVaryings; }
const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; }
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
index 1ec702f299..1417e0bdf6 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
@@ -11,28 +11,24 @@
#define LIBGLESV2_RENDERER_SWAPCHAIN_H_
#include "common/angleutils.h"
+#include "common/NativeWindow.h"
#include "common/platform.h"
#include <GLES2/gl2.h>
#include <EGL/egl.h>
-#include <EGL/eglplatform.h>
+
+#if !defined(ANGLE_FORCE_VSYNC_OFF)
+#define ANGLE_FORCE_VSYNC_OFF 0
+#endif
namespace rx
{
-enum SwapFlags
-{
- SWAP_NORMAL = 0,
- SWAP_ROTATE_90 = 1,
- SWAP_ROTATE_270 = 2,
- SWAP_ROTATE_180 = SWAP_ROTATE_90|SWAP_ROTATE_270,
-};
-
class SwapChain
{
public:
- SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
- : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
+ SwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mNativeWindow(nativeWindow), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
{
}
@@ -40,13 +36,16 @@ class SwapChain
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) = 0;
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
virtual void recreate() = 0;
+ GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; }
+ GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; }
+
virtual HANDLE getShareHandle() {return mShareHandle;};
protected:
- const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
const GLenum mBackBufferFormat;
const GLenum mDepthBufferFormat;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h
index e3cc50d680..3e662557e4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_TEXTUREIMPL_H_
#include "common/angleutils.h"
+#include "libGLESv2/Error.h"
#include "angle_gl.h"
@@ -31,19 +32,12 @@ namespace rx
{
class Image;
-class Renderer;
-class TextureStorage;
class TextureImpl
{
public:
virtual ~TextureImpl() {};
- // TODO: If this methods could go away that would be ideal;
- // TextureStorage should only be necessary for the D3D backend, and as such
- // higher level code should not rely on it.
- virtual TextureStorage *getNativeTexture() = 0;
-
// Deprecated in favour of the ImageIndex method
virtual Image *getImage(int level, int layer) const = 0;
virtual Image *getImage(const gl::ImageIndex &index) const = 0;
@@ -51,15 +45,15 @@ class TextureImpl
virtual void setUsage(GLenum usage) = 0;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) = 0;
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error generateMipmaps() = 0;
virtual void bindTexImage(egl::Surface *surface) = 0;
virtual void releaseTexImage() = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h
new file mode 100644
index 0000000000..20a166fb7a
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// angletypes.h: Workarounds for driver bugs and other issues.
+
+#ifndef LIBGLESV2_RENDERER_WORKAROUNDS_H_
+#define LIBGLESV2_RENDERER_WORKAROUNDS_H_
+
+// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate
+// independent of ANGLE's renderer. Workarounds should also be accessible
+// outside of the Renderer.
+
+namespace rx
+{
+
+enum D3DWorkaroundType
+{
+ ANGLE_D3D_WORKAROUND_NONE,
+ ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION,
+ ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION
+};
+
+struct Workarounds
+{
+ Workarounds()
+ : mrtPerfWorkaround(false),
+ setDataFasterThanImageUpload(false)
+ {}
+
+ bool mrtPerfWorkaround;
+ bool setDataFasterThanImageUpload;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_WORKAROUNDS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp
index 004223d70f..aabc9f04e9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp
@@ -6,7 +6,7 @@
// copyimage.cpp: Defines image copying functions
-#include "libGLESv2/renderer/copyImage.h"
+#include "libGLESv2/renderer/copyimage.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
index a34ef03fb8..dd0d3f52ad 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
@@ -9,7 +9,6 @@
#include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/renderer/d3d/VertexBuffer.h"
#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/main.h"
namespace rx
@@ -37,6 +36,13 @@ BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer)
return static_cast<BufferD3D*>(buffer);
}
+BufferD3D *BufferD3D::makeFromBuffer(gl::Buffer *buffer)
+{
+ BufferImpl *impl = buffer->getImplementation();
+ ASSERT(impl);
+ return makeBufferD3D(impl);
+}
+
void BufferD3D::updateSerial()
{
mSerial = mNextSerial++;
@@ -46,11 +52,11 @@ void BufferD3D::initializeStaticData()
{
if (!mStaticVertexBuffer)
{
- mStaticVertexBuffer = new rx::StaticVertexBufferInterface(getRenderer());
+ mStaticVertexBuffer = new StaticVertexBufferInterface(getRenderer());
}
if (!mStaticIndexBuffer)
{
- mStaticIndexBuffer = new rx::StaticIndexBufferInterface(getRenderer());
+ mStaticIndexBuffer = new StaticIndexBufferInterface(getRenderer());
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
index 44f14cee58..1a1308c545 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
@@ -12,10 +12,11 @@
#include "libGLESv2/renderer/BufferImpl.h"
#include "libGLESv2/angletypes.h"
+#include <cstdint>
+
namespace rx
{
-
-class Renderer;
+class RendererD3D;
class StaticIndexBufferInterface;
class StaticVertexBufferInterface;
@@ -26,15 +27,17 @@ class BufferD3D : public BufferImpl
virtual ~BufferD3D();
static BufferD3D *makeBufferD3D(BufferImpl *buffer);
+ static BufferD3D *makeFromBuffer(gl::Buffer *buffer);
unsigned int getSerial() const { return mSerial; }
+ virtual gl::Error getData(const uint8_t **outData) = 0;
virtual size_t getSize() const = 0;
virtual bool supportsDirectBinding() const = 0;
- virtual Renderer* getRenderer() = 0;
+ virtual RendererD3D *getRenderer() = 0;
- rx::StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
- rx::StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
+ StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
+ StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
void initializeStaticData();
void invalidateStaticData();
@@ -46,8 +49,8 @@ class BufferD3D : public BufferImpl
void updateSerial();
- rx::StaticVertexBufferInterface *mStaticVertexBuffer;
- rx::StaticIndexBufferInterface *mStaticIndexBuffer;
+ StaticVertexBufferInterface *mStaticVertexBuffer;
+ StaticIndexBufferInterface *mStaticIndexBuffer;
unsigned int mUnmodifiedDataUse;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index 13411ebe64..3d5bfe0cbe 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -8,10 +8,10 @@
#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/Shader.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Shader.h"
#include "libGLESv2/formatutils.h"
#include "common/utilities.h"
@@ -22,6 +22,9 @@ META_ASSERT(GL_INVALID_INDEX == UINT_MAX);
using namespace gl;
+namespace rx
+{
+
namespace
{
@@ -70,7 +73,7 @@ std::string HLSLTypeString(GLenum type)
return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type));
}
-const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::PixelShaderOutputVariable> &outputVariables,
+const PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables,
unsigned int location)
{
for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex)
@@ -85,15 +88,12 @@ const rx::PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<rx::P
return outputVariables[0];
}
-}
-
-namespace rx
-{
-
const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@";
-DynamicHLSL::DynamicHLSL(rx::Renderer *const renderer)
+}
+
+DynamicHLSL::DynamicHLSL(RendererD3D *const renderer)
: mRenderer(renderer)
{
}
@@ -225,8 +225,8 @@ static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, Var
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
-int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
- rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings)
+int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader,
+ ShaderD3D *vertexShader, const std::vector<std::string> &transformFeedbackVaryings)
{
// TODO (geofflang): Use context's caps
const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
@@ -262,6 +262,13 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad
for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++)
{
const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex];
+
+ if (transformFeedbackVarying == "gl_Position" || transformFeedbackVarying == "gl_PointSize")
+ {
+ // do not pack builtin XFB varyings
+ continue;
+ }
+
if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end())
{
bool found = false;
@@ -281,7 +288,7 @@ int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, rx::Shad
}
}
- if (!found && transformFeedbackVarying != "gl_Position" && transformFeedbackVarying != "gl_PointSize")
+ if (!found)
{
infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str());
return -1;
@@ -400,7 +407,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
// data reinterpretation (eg for pure integer->float, float->pure integer)
// TODO: issue warning with gl debug info extension, when supported
if (IsMatrixType(shaderAttribute.type) ||
- (mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0)
+ (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0)
{
initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute);
}
@@ -639,7 +646,7 @@ void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
}
}
-void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
+void DynamicHLSL::storeUserLinkedVaryings(const ShaderD3D *vertexShader,
std::vector<LinkedVarying> *linkedVaryings) const
{
const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize);
@@ -662,10 +669,11 @@ void DynamicHLSL::storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader,
}
}
-bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const VaryingPacking packing,
- std::string& pixelHLSL, std::string& vertexHLSL,
- rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings,
+bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, int registers,
+ const VaryingPacking packing,
+ std::string &pixelHLSL, std::string &vertexHLSL,
+ ShaderD3D *fragmentShader, ShaderD3D *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
std::vector<LinkedVarying> *linkedVaryings,
std::map<int, VariableLocation> *programOutputVars,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
@@ -691,21 +699,17 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
// Write the HLSL input/output declarations
const int shaderModel = mRenderer->getMajorShaderModel();
-
- // TODO (geofflang): Use context's caps
- const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors;
-
const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0);
// Two cases when writing to gl_FragColor and using ESSL 1.0:
// - with a 3.0 context, the output color is copied to channel 0
// - with a 2.0 context, the output color is broadcast to all channels
- const bool broadcast = (fragmentShader->mUsesFragColor && mRenderer->getCurrentClientVersion() < 3);
- const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getRendererCaps().maxDrawBuffers : 1);
+ const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3);
+ const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
int shaderVersion = vertexShader->getShaderVersion();
- if (registersNeeded > maxVaryingVectors)
+ if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
{
infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
return false;
@@ -772,7 +776,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
for (int row = 0; row < variableRows; row++)
{
- int r = varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row;
+ int r = varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row;
vertexHLSL += " output.v" + Str(r);
vertexHLSL += " = _" + varying.name;
@@ -920,7 +924,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType));
for (int row = 0; row < variableRows; row++)
{
- std::string n = Str(varying.registerIndex + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + elementIndex * variableRows + row);
+ std::string n = Str(varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row);
pixelHLSL += " _" + varying.name;
if (varying.isArray())
@@ -966,7 +970,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(InfoLog &infoLog, int registers, const
return true;
}
-void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
+void DynamicHLSL::defineOutputVariables(ShaderD3D *fragmentShader, std::map<int, VariableLocation> *programOutputVars) const
{
const std::vector<sh::Attribute> &shaderOutputVars = fragmentShader->getActiveOutputVariables();
@@ -994,14 +998,14 @@ void DynamicHLSL::defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<
}
}
-std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
+std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const
{
// for now we only handle point sprite emulation
ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4);
return generatePointSpriteHLSL(registers, fragmentShader, vertexShader);
}
-std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const
+std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const
{
ASSERT(registers >= 0);
ASSERT(vertexShader->mUsesPointSize);
@@ -1047,7 +1051,7 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, rx::ShaderD3D *f
"void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
"{\n"
" GS_OUTPUT output = (GS_OUTPUT)0;\n"
- " output.gl_Position = input[0].gl_Position;\n";
+ " output.gl_Position = input[0].gl_Position;\n"
" output.gl_PointSize = input[0].gl_PointSize;\n";
for (int r = 0; r < registers; r++)
@@ -1135,7 +1139,7 @@ void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLen
}
else
{
- bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & rx::VERTEX_CONVERT_GPU) != 0);
+ bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0);
signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
index f68ed98401..c46bbf6ce0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
@@ -10,18 +10,13 @@
#define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
#include "common/angleutils.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "angle_gl.h"
#include <vector>
#include <map>
-namespace rx
-{
-class Renderer;
-}
-
namespace sh
{
struct Attribute;
@@ -36,11 +31,12 @@ struct LinkedVarying;
struct VertexAttribute;
struct VertexFormat;
struct PackedVarying;
+struct Data;
}
namespace rx
{
-class Renderer;
+class RendererD3D;
class ShaderD3D;
typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4];
@@ -56,30 +52,31 @@ struct PixelShaderOutputVariable
class DynamicHLSL
{
public:
- explicit DynamicHLSL(rx::Renderer *const renderer);
+ explicit DynamicHLSL(RendererD3D *const renderer);
- int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, rx::ShaderD3D *fragmentShader,
- rx::ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
+ int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader,
+ ShaderD3D *vertexShader, const std::vector<std::string>& transformFeedbackVaryings);
std::string generateVertexShaderForInputLayout(const std::string &sourceShader, const gl::VertexFormat inputLayout[],
const sh::Attribute shaderAttributes[]) const;
std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector<PixelShaderOutputVariable> &outputVariables,
bool usesFragDepth, const std::vector<GLenum> &outputLayout) const;
- bool generateShaderLinkHLSL(gl::InfoLog &infoLog, int registers, const VaryingPacking packing,
- std::string& pixelHLSL, std::string& vertexHLSL,
- rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings,
+ bool generateShaderLinkHLSL(const gl::Data &data, gl::InfoLog &infoLog, int registers,
+ const VaryingPacking packing,
+ std::string &pixelHLSL, std::string &vertexHLSL,
+ ShaderD3D *fragmentShader, ShaderD3D *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
std::vector<gl::LinkedVarying> *linkedVaryings,
std::map<int, gl::VariableLocation> *programOutputVars,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const;
- std::string generateGeometryShaderHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
+ std::string generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const;
void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
private:
DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
struct SemanticInfo;
@@ -88,10 +85,10 @@ class DynamicHLSL
bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const;
- void storeUserLinkedVaryings(const rx::ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
+ void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const;
- void defineOutputVariables(rx::ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
- std::string generatePointSpriteHLSL(int registers, rx::ShaderD3D *fragmentShader, rx::ShaderD3D *vertexShader) const;
+ void defineOutputVariables(ShaderD3D *fragmentShader, std::map<int, gl::VariableLocation> *programOutputVars) const;
+ std::string generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const;
// Prepend an underscore
static std::string decorateVariable(const std::string &name);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
index d0131974ee..776d92b202 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
@@ -8,34 +8,116 @@
#include "libGLESv2/Program.h"
#include "libGLESv2/main.h"
+#include "common/features.h"
#include "common/utilities.h"
-#include "common/platform.h"
-#if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL)
+#ifndef QT_D3DCOMPILER_DLL
+#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
+#endif
+#ifndef D3DCOMPILE_RESERVED16
+#define D3DCOMPILE_RESERVED16 (1 << 16)
+#endif
+#ifndef D3DCOMPILE_RESERVED17
+#define D3DCOMPILE_RESERVED17 (1 << 17)
+#endif
-// Add define + typedefs for older MinGW-w64 headers (pre 5783)
+// Definitions local to the translation unit
+namespace
+{
-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
+#ifdef CREATE_COMPILER_FLAG_INFO
+ #undef CREATE_COMPILER_FLAG_INFO
+#endif
-HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
- const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
- const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
-typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const char *filename,
- const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
- const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+#define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag }
-#endif // __MINGW32__ && !D3DCOMPILER_DLL
+struct CompilerFlagInfo
+{
+ UINT mFlag;
+ const char *mName;
+};
-#ifndef QT_D3DCOMPILER_DLL
-#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
-#endif
+CompilerFlagInfo CompilerFlagInfos[] =
+{
+ // NOTE: The data below is copied from d3dcompiler.h
+ // If something changes there it should be changed here as well
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_DEBUG), // (1 << 0)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_VALIDATION), // (1 << 1)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_OPTIMIZATION), // (1 << 2)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR), // (1 << 3)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR), // (1 << 4)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PARTIAL_PRECISION), // (1 << 5)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT), // (1 << 6)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT), // (1 << 7)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_NO_PRESHADER), // (1 << 8)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_AVOID_FLOW_CONTROL), // (1 << 9)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PREFER_FLOW_CONTROL), // (1 << 10)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_STRICTNESS), // (1 << 11)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY), // (1 << 12)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_IEEE_STRICTNESS), // (1 << 13)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL0), // (1 << 14)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL1), // 0
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL2), // ((1 << 14) | (1 << 15))
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL3), // (1 << 15)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED16), // (1 << 16)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED17), // (1 << 17)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_WARNINGS_ARE_ERRORS) // (1 << 18)
+};
+
+#undef CREATE_COMPILER_FLAG_INFO
+
+bool IsCompilerFlagSet(UINT mask, UINT flag)
+{
+ bool isFlagSet = IsMaskFlagSet(mask, flag);
+
+ switch(flag)
+ {
+ case D3DCOMPILE_OPTIMIZATION_LEVEL0:
+ return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL3));
+
+ case D3DCOMPILE_OPTIMIZATION_LEVEL1:
+ return (mask & D3DCOMPILE_OPTIMIZATION_LEVEL2) == UINT(0);
+
+ case D3DCOMPILE_OPTIMIZATION_LEVEL3:
+ return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL0));
+
+ default:
+ return isFlagSet;
+ }
+}
+
+const char *GetCompilerFlagName(UINT mask, size_t flagIx)
+{
+ const CompilerFlagInfo &flagInfo = CompilerFlagInfos[flagIx];
+ if (IsCompilerFlagSet(mask, flagInfo.mFlag))
+ {
+ return flagInfo.mName;
+ }
+
+ return nullptr;
+}
+
+}
namespace rx
{
+CompileConfig::CompileConfig()
+ : flags(0),
+ name()
+{
+}
+
+CompileConfig::CompileConfig(UINT flags, const std::string &name)
+ : flags(flags),
+ name(name)
+{
+}
+
HLSLCompiler::HLSLCompiler()
: mD3DCompilerModule(NULL),
- mD3DCompileFunc(NULL)
+ mD3DCompileFunc(NULL),
+ mD3DDisassembleFunc(NULL)
{
}
@@ -46,7 +128,7 @@ HLSLCompiler::~HLSLCompiler()
bool HLSLCompiler::initialize()
{
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
// Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
@@ -85,15 +167,30 @@ bool HLSLCompiler::initialize()
if (!mD3DCompilerModule)
{
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
+ mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
+ }
+
+ if (!mD3DCompilerModule)
+ {
ERR("No D3D compiler module found - aborting!\n");
return false;
}
- mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
+ mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
ASSERT(mD3DCompileFunc);
+
+ mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(GetProcAddress(mD3DCompilerModule, "D3DDisassemble"));
+ ASSERT(mD3DDisassembleFunc);
+
#else
- mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(&D3DCompile);
+ // D3D Shader compiler is linked already into this module, so the export
+ // can be directly assigned.
+ mD3DCompilerModule = NULL;
+ mD3DCompileFunc = reinterpret_cast<pD3DCompile>(D3DCompile);
+ mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(D3DDisassemble);
#endif
+
return mD3DCompileFunc != NULL;
}
@@ -104,61 +201,133 @@ void HLSLCompiler::release()
FreeLibrary(mD3DCompilerModule);
mD3DCompilerModule = NULL;
mD3DCompileFunc = NULL;
+ mD3DDisassembleFunc = NULL;
}
}
-ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
- const UINT optimizationFlags[], const char *flagNames[], int attempts) const
+gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
+ const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
+ ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const
{
-#if !defined(ANGLE_PLATFORM_WINRT)
- ASSERT(mD3DCompilerModule && mD3DCompileFunc);
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ ASSERT(mD3DCompilerModule);
#endif
+ ASSERT(mD3DCompileFunc);
- if (!hlsl)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ if (gl::perfActive())
{
- return NULL;
+ std::string sourcePath = getTempPath();
+ std::string sourceText = FormatString("#line 2 \"%s\"\n\n%s", sourcePath.c_str(), hlsl.c_str());
+ writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
+#endif
+
+ const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL;
- pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
- for (int i = 0; i < attempts; ++i)
+ for (size_t i = 0; i < configs.size(); ++i)
{
ID3DBlob *errorMessage = NULL;
ID3DBlob *binary = NULL;
- HRESULT result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, "main", profile, optimizationFlags[i], 0, &binary, &errorMessage);
+ HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(),
+ configs[i].flags, 0, &binary, &errorMessage);
if (errorMessage)
{
- const char *message = (const char*)errorMessage->GetBufferPointer();
+ std::string message = reinterpret_cast<const char*>(errorMessage->GetBufferPointer());
+ SafeRelease(errorMessage);
- infoLog.appendSanitized(message);
- TRACE("\n%s", hlsl);
- TRACE("\n%s", message);
+ infoLog.appendSanitized(message.c_str());
+ TRACE("\n%s", hlsl.c_str());
+ TRACE("\n%s", message.c_str());
- SafeRelease(errorMessage);
+ if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute"
+ {
+ macros = NULL; // Disable [loop] and [flatten]
+
+ // Retry without changing compiler flags
+ i--;
+ continue;
+ }
}
if (SUCCEEDED(result))
{
- return (ShaderBlob*)binary;
+ *outCompiledBlob = binary;
+
+#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ (*outDebugInfo) += "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n";
+ (*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n";
+ (*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n";
+ for (size_t fIx = 0; fIx < ArraySize(CompilerFlagInfos); ++fIx)
+ {
+ const char *flagName = GetCompilerFlagName(configs[i].flags, fIx);
+ if (flagName != nullptr)
+ {
+ (*outDebugInfo) += std::string("// ") + flagName + "\n";
+ }
+ }
+
+ (*outDebugInfo) += "// Macros:\n";
+ if (macros == nullptr)
+ {
+ (*outDebugInfo) += "// - : -\n";
+ }
+ else
+ {
+ for (const D3D_SHADER_MACRO *mIt = macros; mIt->Name != nullptr; ++mIt)
+ {
+ (*outDebugInfo) += std::string("// ") + mIt->Name + " : " + mIt->Definition + "\n";
+ }
+ }
+
+ (*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n";
+#endif
+
+ return gl::Error(GL_NO_ERROR);
}
else
{
if (result == E_OUTOFMEMORY)
{
- return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*)NULL);
+ *outCompiledBlob = NULL;
+ return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result);
}
- infoLog.append("Warning: D3D shader compilation failed with %s flags.", flagNames[i]);
+ infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str());
- if (i + 1 < attempts)
+ if (i + 1 < configs.size())
{
- infoLog.append(" Retrying with %s.\n", flagNames[i + 1]);
+ infoLog.append(" Retrying with %s.\n", configs[i + 1].name.c_str());
}
}
}
- return NULL;
+ // None of the configurations succeeded in compiling this shader but the compiler is still intact
+ *outCompiledBlob = NULL;
+ return gl::Error(GL_NO_ERROR);
+}
+
+std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const
+{
+ // Retrieve disassembly
+ UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING;
+ ID3DBlob *disassembly = NULL;
+ pD3DDisassemble disassembleFunc = reinterpret_cast<pD3DDisassemble>(mD3DDisassembleFunc);
+ LPCVOID buffer = shaderBinary->GetBufferPointer();
+ SIZE_T bufSize = shaderBinary->GetBufferSize();
+ HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly);
+
+ std::string asmSrc;
+ if (SUCCEEDED(result))
+ {
+ asmSrc = reinterpret_cast<const char*>(disassembly->GetBufferPointer());
+ }
+
+ SafeRelease(disassembly);
+
+ return asmSrc;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
index 0ce9e44be5..ff56f8035a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
@@ -1,7 +1,13 @@
#ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
#define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
+#include "common/platform.h"
+
+#include <vector>
+#include <string>
namespace gl
{
@@ -11,8 +17,14 @@ class InfoLog;
namespace rx
{
-typedef void* ShaderBlob;
-typedef void(*CompileFuncPtr)();
+struct CompileConfig
+{
+ UINT flags;
+ std::string name;
+
+ CompileConfig();
+ CompileConfig(UINT flags, const std::string &name);
+};
class HLSLCompiler
{
@@ -23,14 +35,20 @@ class HLSLCompiler
bool initialize();
void release();
- ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
- const UINT optimizationFlags[], const char *flagNames[], int attempts) const;
+ // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL compiled blob
+ // even if no GL errors are returned.
+ gl::Error compileToBinary(gl::InfoLog &infoLog, const std::string &hlsl, const std::string &profile,
+ const std::vector<CompileConfig> &configs, const D3D_SHADER_MACRO *overrideMacros,
+ ID3DBlob **outCompiledBlob, std::string *outDebugInfo) const;
+
+ std::string disassembleBinary(ID3DBlob* shaderBinary) const;
private:
DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
HMODULE mD3DCompilerModule;
- CompileFuncPtr mD3DCompileFunc;
+ pD3DCompile mD3DCompileFunc;
+ pD3DDisassemble mD3DDisassembleFunc;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
index 0854b968da..12b919ab5a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
@@ -19,8 +19,8 @@ ImageD3D::ImageD3D()
ImageD3D *ImageD3D::makeImageD3D(Image *img)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::ImageD3D*, img));
- return static_cast<rx::ImageD3D*>(img);
+ ASSERT(HAS_DYNAMIC_TYPE(ImageD3D*, img));
+ return static_cast<ImageD3D*>(img);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
index 60a6ffdf37..554ca0cee0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
@@ -17,6 +17,8 @@
namespace gl
{
class Framebuffer;
+struct ImageIndex;
+struct Box;
}
namespace rx
@@ -33,14 +35,11 @@ class ImageD3D : public Image
virtual bool isDirty() const = 0;
- virtual void setManagedSurface2D(TextureStorage *storage, int level) {};
- virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level) {};
- virtual void setManagedSurface3D(TextureStorage *storage, int level) {};
- virtual void setManagedSurface2DArray(TextureStorage *storage, int layer, int level) {};
- virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
- virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
- virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) = 0;
- virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height) = 0;
+ virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ImageD3D);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
index 1dce1270d8..aa614f6cc4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
@@ -8,7 +8,7 @@
// class with derivations, classes that perform graphics API agnostic index buffer operations.
#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
namespace rx
{
@@ -35,7 +35,7 @@ void IndexBuffer::updateSerial()
}
-IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
+IndexBufferInterface::IndexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer)
{
mIndexBuffer = renderer->createIndexBuffer();
@@ -130,7 +130,7 @@ gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum in
}
}
-StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
+StreamingIndexBufferInterface::StreamingIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, true)
{
}
@@ -165,7 +165,7 @@ gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, G
}
-StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
+StaticIndexBufferInterface::StaticIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, false)
{
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
index 1bb5ae2c4a..a34d30bbf3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
@@ -16,7 +16,7 @@
namespace rx
{
-class Renderer;
+class RendererD3D;
class IndexBuffer
{
@@ -50,7 +50,7 @@ class IndexBuffer
class IndexBufferInterface
{
public:
- IndexBufferInterface(Renderer *renderer, bool dynamic);
+ IndexBufferInterface(RendererD3D *renderer, bool dynamic);
virtual ~IndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
@@ -76,7 +76,7 @@ class IndexBufferInterface
private:
DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
IndexBuffer* mIndexBuffer;
@@ -87,7 +87,7 @@ class IndexBufferInterface
class StreamingIndexBufferInterface : public IndexBufferInterface
{
public:
- StreamingIndexBufferInterface(Renderer *renderer);
+ StreamingIndexBufferInterface(RendererD3D *renderer);
~StreamingIndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
@@ -96,7 +96,7 @@ class StreamingIndexBufferInterface : public IndexBufferInterface
class StaticIndexBufferInterface : public IndexBufferInterface
{
public:
- explicit StaticIndexBufferInterface(Renderer *renderer);
+ explicit StaticIndexBufferInterface(RendererD3D *renderer);
~StaticIndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
index 8d455b4bf3..eddd9de887 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
@@ -10,7 +10,7 @@
#include "libGLESv2/renderer/d3d/IndexDataManager.h"
#include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/main.h"
#include "libGLESv2/formatutils.h"
@@ -57,7 +57,7 @@ static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void
else UNREACHABLE();
}
-IndexDataManager::IndexDataManager(Renderer *renderer)
+IndexDataManager::IndexDataManager(RendererD3D *renderer)
: mRenderer(renderer),
mStreamingBufferShort(NULL),
mStreamingBufferInt(NULL)
@@ -97,7 +97,14 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL;
@@ -183,7 +190,16 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
return error;
}
- ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
+ const uint8_t *dataPointer = reinterpret_cast<const uint8_t*>(indices);
+ if (staticBuffer)
+ {
+ error = storage->getData(&dataPointer);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ ConvertIndices(type, destinationIndexType, dataPointer, convertCount, output);
error = indexBuffer->unmapBuffer();
if (error.isError())
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
index 6d0b89e6d4..a1aee1588b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
@@ -33,7 +33,7 @@ class StaticIndexBufferInterface;
class StreamingIndexBufferInterface;
class IndexBuffer;
class BufferD3D;
-class Renderer;
+class RendererD3D;
struct TranslatedIndexData
{
@@ -50,7 +50,7 @@ struct TranslatedIndexData
class IndexDataManager
{
public:
- explicit IndexDataManager(Renderer *renderer);
+ explicit IndexDataManager(RendererD3D *renderer);
virtual ~IndexDataManager();
gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
@@ -60,7 +60,7 @@ class IndexDataManager
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
- Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
StreamingIndexBufferInterface *mStreamingBufferShort;
StreamingIndexBufferInterface *mStreamingBufferInt;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
index d7d97cc2bd..75da78110e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -8,27 +8,163 @@
#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+#include "common/features.h"
#include "common/utilities.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/main.h"
#include "libGLESv2/renderer/ShaderExecutable.h"
#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/main.h"
namespace rx
{
-ProgramD3D::ProgramD3D(rx::Renderer *renderer)
+namespace
+{
+
+GLenum GetTextureType(GLenum samplerType)
+{
+ switch (samplerType)
+ {
+ case GL_SAMPLER_2D:
+ case GL_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_SAMPLER_2D_SHADOW:
+ return GL_TEXTURE_2D;
+ case GL_SAMPLER_3D:
+ case GL_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ return GL_TEXTURE_3D;
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_SHADOW:
+ return GL_TEXTURE_CUBE_MAP;
+ case GL_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ return GL_TEXTURE_CUBE_MAP;
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ return GL_TEXTURE_2D_ARRAY;
+ default: UNREACHABLE();
+ }
+
+ return GL_TEXTURE_2D;
+}
+
+void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+{
+ size_t layoutIndex = 0;
+ for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
+ {
+ ASSERT(layoutIndex < gl::MAX_VERTEX_ATTRIBS);
+
+ const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
+
+ if (shaderAttr.type != GL_NONE)
+ {
+ GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
+
+ for (size_t rowIndex = 0; static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); rowIndex++, layoutIndex++)
+ {
+ gl::VertexFormat *defaultFormat = &inputLayout[layoutIndex];
+
+ defaultFormat->mType = gl::VariableComponentType(transposedType);
+ defaultFormat->mNormalized = false;
+ defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
+ defaultFormat->mComponents = gl::VariableColumnCount(transposedType);
+ }
+ }
+ }
+}
+
+std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<PixelShaderOutputVariable> &shaderOutputVars)
+{
+ std::vector<GLenum> defaultPixelOutput(1);
+
+ ASSERT(!shaderOutputVars.empty());
+ defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+
+ return defaultPixelOutput;
+}
+
+bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
+{
+ return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const sh::ShaderVariable &var)
+{
+ return false;
+}
+
+}
+
+ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[],
+ const GLenum signature[],
+ ShaderExecutable *shaderExecutable)
+ : mShaderExecutable(shaderExecutable)
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ mInputs[attributeIndex] = inputLayout[attributeIndex];
+ mSignature[attributeIndex] = signature[attributeIndex];
+ }
+}
+
+ProgramD3D::VertexExecutable::~VertexExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) const
+{
+ for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (mSignature[attributeIndex] != signature[attributeIndex])
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable)
+ : mOutputSignature(outputSignature),
+ mShaderExecutable(shaderExecutable)
+{
+}
+
+ProgramD3D::PixelExecutable::~PixelExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
+{
+}
+
+ProgramD3D::ProgramD3D(RendererD3D *renderer)
: ProgramImpl(),
mRenderer(renderer),
mDynamicHLSL(NULL),
- mVertexWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
- mPixelWorkarounds(rx::ANGLE_D3D_WORKAROUND_NONE),
+ mGeometryExecutable(NULL),
+ mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
+ mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
+ mUsesPointSize(false),
mVertexUniformStorage(NULL),
- mFragmentUniformStorage(NULL)
+ mFragmentUniformStorage(NULL),
+ mUsedVertexSamplerRange(0),
+ mUsedPixelSamplerRange(0),
+ mDirtySamplerMapping(true),
+ mShaderVersion(100)
{
- mDynamicHLSL = new rx::DynamicHLSL(renderer);
+ mDynamicHLSL = new DynamicHLSL(renderer);
}
ProgramD3D::~ProgramD3D()
@@ -49,13 +185,344 @@ const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
return static_cast<const ProgramD3D*>(impl);
}
-bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+bool ProgramD3D::usesPointSpriteEmulation() const
+{
+ return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+}
+
+bool ProgramD3D::usesGeometryShader() const
+{
+ return usesPointSpriteEmulation();
+}
+
+GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const
+{
+ GLint logicalTextureUnit = -1;
+
+ switch (type)
+ {
+ case gl::SAMPLER_PIXEL:
+ ASSERT(samplerIndex < caps.maxTextureImageUnits);
+ if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
+ {
+ logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
+ }
+ break;
+ case gl::SAMPLER_VERTEX:
+ ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
+ if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
+ {
+ logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
+ }
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
+ {
+ return logicalTextureUnit;
+ }
+
+ return -1;
+}
+
+// Returns the texture type for a given Direct3D 9 sampler type and
+// index (0-15 for the pixel shader and 0-3 for the vertex shader).
+GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const
+{
+ switch (type)
+ {
+ case gl::SAMPLER_PIXEL:
+ ASSERT(samplerIndex < mSamplersPS.size());
+ ASSERT(mSamplersPS[samplerIndex].active);
+ return mSamplersPS[samplerIndex].textureType;
+ case gl::SAMPLER_VERTEX:
+ ASSERT(samplerIndex < mSamplersVS.size());
+ ASSERT(mSamplersVS[samplerIndex].active);
+ return mSamplersVS[samplerIndex].textureType;
+ default: UNREACHABLE();
+ }
+
+ return GL_TEXTURE_2D;
+}
+
+GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const
+{
+ switch (type)
+ {
+ case gl::SAMPLER_PIXEL:
+ return mUsedPixelSamplerRange;
+ case gl::SAMPLER_VERTEX:
+ return mUsedVertexSamplerRange;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+void ProgramD3D::updateSamplerMapping()
+{
+ if (!mDirtySamplerMapping)
+ {
+ return;
+ }
+
+ mDirtySamplerMapping = false;
+
+ // Retrieve sampler uniform values
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ gl::LinkedUniform *targetUniform = mUniforms[uniformIndex];
+
+ if (targetUniform->dirty)
+ {
+ if (gl::IsSampler(targetUniform->type))
+ {
+ int count = targetUniform->elementCount();
+ GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
+
+ if (targetUniform->isReferencedByFragmentShader())
+ {
+ unsigned int firstIndex = targetUniform->psRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersPS.size())
+ {
+ ASSERT(mSamplersPS[samplerIndex].active);
+ mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
+
+ if (targetUniform->isReferencedByVertexShader())
+ {
+ unsigned int firstIndex = targetUniform->vsRegisterIndex;
+
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < mSamplersVS.size())
+ {
+ ASSERT(mSamplersVS[samplerIndex].active);
+ mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
+ // if any two active samplers in a program are of different types, but refer to the same
+ // texture image unit, and this is the current program, then ValidateProgram will fail, and
+ // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+ updateSamplerMapping();
+
+ std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
+
+ for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
+ {
+ if (mSamplersPS[i].active)
+ {
+ unsigned int unit = mSamplersPS[i].logicalTextureUnit;
+
+ if (unit >= textureUnitTypes.size())
+ {
+ if (infoLog)
+ {
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
+ }
+
+ return false;
+ }
+
+ if (textureUnitTypes[unit] != GL_NONE)
+ {
+ if (mSamplersPS[i].textureType != textureUnitTypes[unit])
+ {
+ if (infoLog)
+ {
+ infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+ }
+
+ return false;
+ }
+ }
+ else
+ {
+ textureUnitTypes[unit] = mSamplersPS[i].textureType;
+ }
+ }
+ }
+
+ for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
+ {
+ if (mSamplersVS[i].active)
+ {
+ unsigned int unit = mSamplersVS[i].logicalTextureUnit;
+
+ if (unit >= textureUnitTypes.size())
+ {
+ if (infoLog)
+ {
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
+ }
+
+ return false;
+ }
+
+ if (textureUnitTypes[unit] != GL_NONE)
+ {
+ if (mSamplersVS[i].textureType != textureUnitTypes[unit])
+ {
+ if (infoLog)
+ {
+ infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
+ }
+
+ return false;
+ }
+ }
+ else
+ {
+ textureUnitTypes[unit] = mSamplersVS[i].textureType;
+ }
+ }
+ }
+
+ return true;
+}
+
+gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+{
+ stream->readInt(&mShaderVersion);
+
+ const unsigned int psSamplerCount = stream->readInt<unsigned int>();
+ for (unsigned int i = 0; i < psSamplerCount; ++i)
+ {
+ Sampler sampler;
+ stream->readBool(&sampler.active);
+ stream->readInt(&sampler.logicalTextureUnit);
+ stream->readInt(&sampler.textureType);
+ mSamplersPS.push_back(sampler);
+ }
+ const unsigned int vsSamplerCount = stream->readInt<unsigned int>();
+ for (unsigned int i = 0; i < vsSamplerCount; ++i)
+ {
+ Sampler sampler;
+ stream->readBool(&sampler.active);
+ stream->readInt(&sampler.logicalTextureUnit);
+ stream->readInt(&sampler.textureType);
+ mSamplersVS.push_back(sampler);
+ }
+
+ stream->readInt(&mUsedVertexSamplerRange);
+ stream->readInt(&mUsedPixelSamplerRange);
+
+ const unsigned int uniformCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniforms.resize(uniformCount);
+ for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
+ {
+ GLenum type = stream->readInt<GLenum>();
+ GLenum precision = stream->readInt<GLenum>();
+ std::string name = stream->readString();
+ unsigned int arraySize = stream->readInt<unsigned int>();
+ int blockIndex = stream->readInt<int>();
+
+ int offset = stream->readInt<int>();
+ int arrayStride = stream->readInt<int>();
+ int matrixStride = stream->readInt<int>();
+ bool isRowMajorMatrix = stream->readBool();
+
+ const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
+
+ gl::LinkedUniform *uniform = new gl::LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
+
+ stream->readInt(&uniform->psRegisterIndex);
+ stream->readInt(&uniform->vsRegisterIndex);
+ stream->readInt(&uniform->registerCount);
+ stream->readInt(&uniform->registerElement);
+
+ mUniforms[uniformIndex] = uniform;
+ }
+
+ const unsigned int uniformIndexCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniformIndex.resize(uniformIndexCount);
+ for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
+ {
+ stream->readString(&mUniformIndex[uniformIndexIndex].name);
+ stream->readInt(&mUniformIndex[uniformIndexIndex].element);
+ stream->readInt(&mUniformIndex[uniformIndexIndex].index);
+ }
+
+ unsigned int uniformBlockCount = stream->readInt<unsigned int>();
+ if (stream->error())
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ mUniformBlocks.resize(uniformBlockCount);
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
+ {
+ std::string name = stream->readString();
+ unsigned int elementIndex = stream->readInt<unsigned int>();
+ unsigned int dataSize = stream->readInt<unsigned int>();
+
+ gl::UniformBlock *uniformBlock = new gl::UniformBlock(name, elementIndex, dataSize);
+
+ stream->readInt(&uniformBlock->psRegisterIndex);
+ stream->readInt(&uniformBlock->vsRegisterIndex);
+
+ unsigned int numMembers = stream->readInt<unsigned int>();
+ uniformBlock->memberUniformIndexes.resize(numMembers);
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
+ {
+ stream->readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
+ }
+
+ mUniformBlocks[uniformBlockIndex] = uniformBlock;
+ }
+
+ stream->readInt(&mTransformFeedbackBufferMode);
+ const unsigned int transformFeedbackVaryingCount = stream->readInt<unsigned int>();
+ mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
+ for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
+ {
+ gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
+
+ stream->readString(&varying.name);
+ stream->readInt(&varying.type);
+ stream->readInt(&varying.size);
+ stream->readString(&varying.semanticName);
+ stream->readInt(&varying.semanticIndex);
+ stream->readInt(&varying.semanticIndexCount);
+ }
+
stream->readString(&mVertexHLSL);
stream->readInt(&mVertexWorkarounds);
stream->readString(&mPixelHLSL);
stream->readInt(&mPixelWorkarounds);
stream->readBool(&mUsesFragDepth);
+ stream->readBool(&mUsesPointSize);
const size_t pixelShaderKeySize = stream->readInt<unsigned int>();
mPixelShaderKey.resize(pixelShaderKeySize);
@@ -67,109 +534,513 @@ bool ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
}
- return true;
+ const unsigned char* binary = reinterpret_cast<const unsigned char*>(stream->data());
+
+ const unsigned int vertexShaderCount = stream->readInt<unsigned int>();
+ for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
+ {
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ gl::VertexFormat *vertexInput = &inputLayout[inputIndex];
+ stream->readInt(&vertexInput->mType);
+ stream->readInt(&vertexInput->mNormalized);
+ stream->readInt(&vertexInput->mComponents);
+ stream->readBool(&vertexInput->mPureInteger);
+ }
+
+ unsigned int vertexShaderSize = stream->readInt<unsigned int>();
+ const unsigned char *vertexShaderFunction = binary + stream->offset();
+
+ ShaderExecutable *shaderExecutable = NULL;
+ gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
+ SHADER_VERTEX,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ &shaderExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create vertex shader.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ // generated converted input layout
+ GLenum signature[gl::MAX_VERTEX_ATTRIBS];
+ getInputLayoutSignature(inputLayout, signature);
+
+ // add new binary
+ mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
+
+ stream->skip(vertexShaderSize);
+ }
+
+ const size_t pixelShaderCount = stream->readInt<unsigned int>();
+ for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
+ {
+ const size_t outputCount = stream->readInt<unsigned int>();
+ std::vector<GLenum> outputs(outputCount);
+ for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
+ {
+ stream->readInt(&outputs[outputIndex]);
+ }
+
+ const size_t pixelShaderSize = stream->readInt<unsigned int>();
+ const unsigned char *pixelShaderFunction = binary + stream->offset();
+ ShaderExecutable *shaderExecutable = NULL;
+ gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ &shaderExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (!shaderExecutable)
+ {
+ infoLog.append("Could not create pixel shader.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ // add new binary
+ mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
+
+ stream->skip(pixelShaderSize);
+ }
+
+ unsigned int geometryShaderSize = stream->readInt<unsigned int>();
+
+ if (geometryShaderSize > 0)
+ {
+ const unsigned char *geometryShaderFunction = binary + stream->offset();
+ gl::Error error = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ &mGeometryExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (!mGeometryExecutable)
+ {
+ infoLog.append("Could not create geometry shader.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+ stream->skip(geometryShaderSize);
+ }
+
+ GUID binaryIdentifier = {0};
+ stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
+
+ GUID identifier = mRenderer->getAdapterIdentifier();
+ if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
+ {
+ infoLog.append("Invalid program binary.");
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
+ initializeUniformStorage();
+
+ return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
}
-bool ProgramD3D::save(gl::BinaryOutputStream *stream)
+gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
{
+ stream->writeInt(mShaderVersion);
+
+ stream->writeInt(mSamplersPS.size());
+ for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
+ {
+ stream->writeInt(mSamplersPS[i].active);
+ stream->writeInt(mSamplersPS[i].logicalTextureUnit);
+ stream->writeInt(mSamplersPS[i].textureType);
+ }
+
+ stream->writeInt(mSamplersVS.size());
+ for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
+ {
+ stream->writeInt(mSamplersVS[i].active);
+ stream->writeInt(mSamplersVS[i].logicalTextureUnit);
+ stream->writeInt(mSamplersVS[i].textureType);
+ }
+
+ stream->writeInt(mUsedVertexSamplerRange);
+ stream->writeInt(mUsedPixelSamplerRange);
+
+ stream->writeInt(mUniforms.size());
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
+ {
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+ stream->writeInt(uniform.type);
+ stream->writeInt(uniform.precision);
+ stream->writeString(uniform.name);
+ stream->writeInt(uniform.arraySize);
+ stream->writeInt(uniform.blockIndex);
+
+ stream->writeInt(uniform.blockInfo.offset);
+ stream->writeInt(uniform.blockInfo.arrayStride);
+ stream->writeInt(uniform.blockInfo.matrixStride);
+ stream->writeInt(uniform.blockInfo.isRowMajorMatrix);
+
+ stream->writeInt(uniform.psRegisterIndex);
+ stream->writeInt(uniform.vsRegisterIndex);
+ stream->writeInt(uniform.registerCount);
+ stream->writeInt(uniform.registerElement);
+ }
+
+ stream->writeInt(mUniformIndex.size());
+ for (size_t i = 0; i < mUniformIndex.size(); ++i)
+ {
+ stream->writeString(mUniformIndex[i].name);
+ stream->writeInt(mUniformIndex[i].element);
+ stream->writeInt(mUniformIndex[i].index);
+ }
+
+ stream->writeInt(mUniformBlocks.size());
+ for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
+ {
+ const gl::UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
+
+ stream->writeString(uniformBlock.name);
+ stream->writeInt(uniformBlock.elementIndex);
+ stream->writeInt(uniformBlock.dataSize);
+
+ stream->writeInt(uniformBlock.memberUniformIndexes.size());
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
+ {
+ stream->writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
+ }
+
+ stream->writeInt(uniformBlock.psRegisterIndex);
+ stream->writeInt(uniformBlock.vsRegisterIndex);
+ }
+
+ stream->writeInt(mTransformFeedbackBufferMode);
+ stream->writeInt(mTransformFeedbackLinkedVaryings.size());
+ for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
+ {
+ const gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
+
+ stream->writeString(varying.name);
+ stream->writeInt(varying.type);
+ stream->writeInt(varying.size);
+ stream->writeString(varying.semanticName);
+ stream->writeInt(varying.semanticIndex);
+ stream->writeInt(varying.semanticIndexCount);
+ }
+
stream->writeString(mVertexHLSL);
stream->writeInt(mVertexWorkarounds);
stream->writeString(mPixelHLSL);
stream->writeInt(mPixelWorkarounds);
stream->writeInt(mUsesFragDepth);
+ stream->writeInt(mUsesPointSize);
- const std::vector<rx::PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
+ const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
stream->writeInt(pixelShaderKey.size());
for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++)
{
- const rx::PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
+ const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
stream->writeInt(variable.type);
stream->writeString(variable.name);
stream->writeString(variable.source);
stream->writeInt(variable.outputIndex);
}
- return true;
+ stream->writeInt(mVertexExecutables.size());
+ for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
+ {
+ VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
+
+ for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
+ {
+ const gl::VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
+ stream->writeInt(vertexInput.mType);
+ stream->writeInt(vertexInput.mNormalized);
+ stream->writeInt(vertexInput.mComponents);
+ stream->writeInt(vertexInput.mPureInteger);
+ }
+
+ size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
+ stream->writeInt(vertexShaderSize);
+
+ const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(vertexBlob, vertexShaderSize);
+ }
+
+ stream->writeInt(mPixelExecutables.size());
+ for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
+ {
+ PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
+
+ const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
+ stream->writeInt(outputs.size());
+ for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
+ {
+ stream->writeInt(outputs[outputIndex]);
+ }
+
+ size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
+ stream->writeInt(pixelShaderSize);
+
+ const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(pixelBlob, pixelShaderSize);
+ }
+
+ size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
+ stream->writeInt(geometryShaderSize);
+
+ if (mGeometryExecutable != NULL && geometryShaderSize > 0)
+ {
+ const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
+ stream->writeBytes(geometryBlob, geometryShaderSize);
+ }
+
+ GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
+ stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
+
+ return gl::Error(GL_NO_ERROR);
}
-rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
+gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExecutable)
{
+ std::vector<GLenum> outputs;
+
+ const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(mRenderer->getWorkarounds());
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+ {
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
+ {
+ outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
+ }
+ else
+ {
+ outputs.push_back(GL_NONE);
+ }
+ }
+
+ return getPixelExecutableForOutputLayout(outputs, outExecutable);
+}
+
+gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature, ShaderExecutable **outExectuable)
+{
+ for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
+ {
+ if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
+ {
+ *outExectuable = mPixelExecutables[executableIndex]->shaderExecutable();
+ return gl::Error(GL_NO_ERROR);
+ }
+ }
+
std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
outputSignature);
// Generate new pixel executable
- rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
- transformFeedbackLinkedVaryings, separatedOutputBuffers,
- mPixelWorkarounds);
+ gl::InfoLog tempInfoLog;
+ ShaderExecutable *pixelExecutable = NULL;
+ gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ mPixelWorkarounds, &pixelExecutable);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!pixelExecutable)
+ {
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
+ }
+ else
+ {
+ mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
+ }
- return pixelExecutable;
+ *outExectuable = pixelExecutable;
+ return gl::Error(GL_NO_ERROR);
}
-rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers)
+gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable)
{
+ GLenum signature[gl::MAX_VERTEX_ATTRIBS];
+ getInputLayoutSignature(inputLayout, signature);
+
+ for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
+ {
+ if (mVertexExecutables[executableIndex]->matchesSignature(signature))
+ {
+ *outExectuable = mVertexExecutables[executableIndex]->shaderExecutable();
+ return gl::Error(GL_NO_ERROR);
+ }
+ }
+
// Generate new dynamic layout with attribute conversions
- std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes);
+ std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
// Generate new vertex executable
- rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(),
- rx::SHADER_VERTEX,
- transformFeedbackLinkedVaryings, separatedOutputBuffers,
- mVertexWorkarounds);
+ gl::InfoLog tempInfoLog;
+ ShaderExecutable *vertexExecutable = NULL;
+ gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL, SHADER_VERTEX,
+ mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ mVertexWorkarounds, &vertexExecutable);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!vertexExecutable)
+ {
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
+ }
+ else
+ {
+ mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
+ }
+
+ *outExectuable = vertexExecutable;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers)
+{
+ ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+
+ gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS];
+ GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
+ ShaderExecutable *defaultVertexExecutable = NULL;
+ gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
+ ShaderExecutable *defaultPixelExecutable = NULL;
+ error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+
+ if (usesGeometryShader())
+ {
+ std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
+
+
+ error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
+ (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
+ ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable);
+ if (error.isError())
+ {
+ return gl::LinkResult(false, error);
+ }
+ }
+
+#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ if (usesGeometryShader() && mGeometryExecutable)
+ {
+ // Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level
+ // For now the geometry shader debug info is pre-pended to the vertex shader, this is a bit of a clutch
+ vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
+ vertexShaderD3D->appendDebugInfo(mGeometryExecutable->getDebugInfo());
+ vertexShaderD3D->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n");
+ }
+
+ if (defaultVertexExecutable)
+ {
+ vertexShaderD3D->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
+ }
+
+ if (defaultPixelExecutable)
+ {
+ fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
+ }
+#endif
- return vertexExecutable;
+ bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
+ return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
-bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables)
+gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables)
{
- rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
- rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+ ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+
+ mSamplersPS.resize(data.caps->maxTextureImageUnits);
+ mSamplersVS.resize(data.caps->maxVertexTextureImageUnits);
+
+ mTransformFeedbackBufferMode = transformFeedbackBufferMode;
mPixelHLSL = fragmentShaderD3D->getTranslatedSource();
mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds();
mVertexHLSL = vertexShaderD3D->getTranslatedSource();
mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds();
+ mShaderVersion = vertexShaderD3D->getShaderVersion();
// Map the varyings to the register file
- rx::VaryingPacking packing = { NULL };
+ VaryingPacking packing = { NULL };
*registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings);
if (*registers < 0)
{
- return false;
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader))
{
- return false;
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
- if (!mDynamicHLSL->generateShaderLinkHLSL(infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
+ if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
{
- return false;
+ return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
}
- return true;
+ mUsesPointSize = vertexShaderD3D->usesPointSize();
+
+ return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
+}
+
+void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const
+{
+ mDynamicHLSL->getInputLayoutSignature(inputLayout, signature);
}
-void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms)
+void ProgramD3D::initializeUniformStorage()
{
// Compute total default block size
unsigned int vertexRegisters = 0;
unsigned int fragmentRegisters = 0;
- for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++)
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
{
- const gl::LinkedUniform &uniform = *uniforms[uniformIndex];
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
if (!gl::IsSampler(uniform.type))
{
@@ -188,18 +1059,867 @@ void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*>
mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
}
+gl::Error ProgramD3D::applyUniforms()
+{
+ updateSamplerMapping();
+
+ gl::Error error = mRenderer->applyUniforms(*this, mUniforms);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ mUniforms[uniformIndex]->dirty = false;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps)
+{
+ ASSERT(boundBuffers.size() == mUniformBlocks.size());
+
+ const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
+ const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
+
+ const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
+ const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
+ {
+ gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex];
+ gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
+
+ ASSERT(uniformBlock && uniformBuffer);
+
+ if (uniformBuffer->getSize() < uniformBlock->dataSize)
+ {
+ // undefined behaviour
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
+ }
+
+ // Unnecessary to apply an unreferenced standard or shared UBO
+ if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
+ {
+ continue;
+ }
+
+ if (uniformBlock->isReferencedByVertexShader())
+ {
+ unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
+ ASSERT(vertexUniformBuffers[registerIndex] == NULL);
+ ASSERT(registerIndex < caps.maxVertexUniformBlocks);
+ vertexUniformBuffers[registerIndex] = uniformBuffer;
+ }
+
+ if (uniformBlock->isReferencedByFragmentShader())
+ {
+ unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
+ ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
+ ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
+ fragmentUniformBuffers[registerIndex] = uniformBuffer;
+ }
+ }
+
+ return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+}
+
+bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
+ unsigned int registerIndex, const gl::Caps &caps)
+{
+ if (shader == GL_VERTEX_SHADER)
+ {
+ uniformBlock->vsRegisterIndex = registerIndex;
+ if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
+ {
+ infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
+ return false;
+ }
+ }
+ else if (shader == GL_FRAGMENT_SHADER)
+ {
+ uniformBlock->psRegisterIndex = registerIndex;
+ if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
+ {
+ infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
+ return false;
+ }
+ }
+ else UNREACHABLE();
+
+ return true;
+}
+
+void ProgramD3D::dirtyAllUniforms()
+{
+ unsigned int numUniforms = mUniforms.size();
+ for (unsigned int index = 0; index < numUniforms; index++)
+ {
+ mUniforms[index]->dirty = true;
+ }
+}
+
+void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ setUniform(location, count, v, GL_FLOAT);
+}
+
+void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniform(location, count, v, GL_FLOAT_VEC2);
+}
+
+void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniform(location, count, v, GL_FLOAT_VEC3);
+}
+
+void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniform(location, count, v, GL_FLOAT_VEC4);
+}
+
+void ProgramD3D::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
+}
+
+void ProgramD3D::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
+}
+
+void ProgramD3D::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
+}
+
+void ProgramD3D::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
+}
+
+void ProgramD3D::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
+}
+
+void ProgramD3D::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
+}
+
+void ProgramD3D::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
+}
+
+void ProgramD3D::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
+}
+
+void ProgramD3D::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+{
+ setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
+}
+
+void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT);
+}
+
+void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT_VEC2);
+}
+
+void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT_VEC3);
+}
+
+void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniform(location, count, v, GL_INT_VEC4);
+}
+
+void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT);
+}
+
+void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT_VEC2);
+}
+
+void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT_VEC3);
+}
+
+void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
+}
+
+void ProgramD3D::getUniformfv(GLint location, GLfloat *params)
+{
+ getUniformv(location, params, GL_FLOAT);
+}
+
+void ProgramD3D::getUniformiv(GLint location, GLint *params)
+{
+ getUniformv(location, params, GL_INT);
+}
+
+void ProgramD3D::getUniformuiv(GLint location, GLuint *params)
+{
+ getUniformv(location, params, GL_UNSIGNED_INT);
+}
+
+bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::Caps &caps)
+{
+ const ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
+ const ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
+
+ const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
+ const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
+
+ // Check that uniforms defined in the vertex and fragment shaders are identical
+ typedef std::map<std::string, const sh::Uniform*> UniformMap;
+ UniformMap linkedUniforms;
+
+ for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
+ {
+ const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
+ linkedUniforms[vertexUniform.name] = &vertexUniform;
+ }
+
+ for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
+ {
+ const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
+ UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
+ if (entry != linkedUniforms.end())
+ {
+ const sh::Uniform &vertexUniform = *entry->second;
+ const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
+ if (!gl::ProgramBinary::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
+ {
+ return false;
+ }
+ }
+ }
+
+ for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
+ {
+ const sh::Uniform &uniform = vertexUniforms[uniformIndex];
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
+ }
+ }
+
+ for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
+ {
+ const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
+
+ if (uniform.staticUse)
+ {
+ defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
+ }
+ }
+
+ if (!indexUniforms(infoLog, caps))
+ {
+ return false;
+ }
+
+ initializeUniformStorage();
+
+ // special case for gl_DepthRange, the only built-in uniform (also a struct)
+ if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
+ {
+ const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
+
+ mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
+ mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
+ mUniforms.push_back(new gl::LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
+ }
+
+ return true;
+}
+
+void ProgramD3D::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
+{
+ ShShaderOutput outputType = ShaderD3D::getCompilerOutputType(shader);
+ sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
+ encoder.skipRegisters(uniformRegister);
+
+ defineUniform(shader, uniform, uniform.name, &encoder);
+}
+
+void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
+ const std::string &fullName, sh::HLSLBlockEncoder *encoder)
+{
+ if (uniform.isStruct())
+ {
+ for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
+ {
+ const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
+
+ encoder->enterAggregateType();
+
+ for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
+ {
+ const sh::ShaderVariable &field = uniform.fields[fieldIndex];
+ const std::string &fieldFullName = (fullName + elementString + "." + field.name);
+
+ defineUniform(shader, field, fieldFullName, encoder);
+ }
+
+ encoder->exitAggregateType();
+ }
+ }
+ else // Not a struct
+ {
+ // Arrays are treated as aggregate types
+ if (uniform.isArray())
+ {
+ encoder->enterAggregateType();
+ }
+
+ gl::LinkedUniform *linkedUniform = getUniformByName(fullName);
+
+ if (!linkedUniform)
+ {
+ linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
+ -1, sh::BlockMemberInfo::getDefaultBlockInfo());
+ ASSERT(linkedUniform);
+ linkedUniform->registerElement = encoder->getCurrentElement();
+ mUniforms.push_back(linkedUniform);
+ }
+
+ ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
+
+ if (shader == GL_FRAGMENT_SHADER)
+ {
+ linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
+ }
+ else if (shader == GL_VERTEX_SHADER)
+ {
+ linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
+ }
+ else UNREACHABLE();
+
+ // Advance the uniform offset, to track registers allocation for structs
+ encoder->encodeType(uniform.type, uniform.arraySize, false);
+
+ // Arrays are treated as aggregate types
+ if (uniform.isArray())
+ {
+ encoder->exitAggregateType();
+ }
+ }
+}
+
+template <typename T>
+static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
+{
+ ASSERT(dest != NULL);
+ ASSERT(dirtyFlag != NULL);
+
+ *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0);
+ *dest = source;
+}
+
+template <typename T>
+void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
+{
+ const int components = gl::VariableComponentCount(targetUniformType);
+ const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType);
+
+ gl::LinkedUniform *targetUniform = getUniformByLocation(location);
+
+ int elementCount = targetUniform->elementCount();
+
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+
+ if (targetUniform->type == targetUniformType)
+ {
+ T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ for (int i = 0; i < count; i++)
+ {
+ T *dest = target + (i * 4);
+ const T *source = v + (i * components);
+
+ for (int c = 0; c < components; c++)
+ {
+ SetIfDirty(dest + c, source[c], &targetUniform->dirty);
+ }
+ for (int c = components; c < 4; c++)
+ {
+ SetIfDirty(dest + c, T(0), &targetUniform->dirty);
+ }
+ }
+ }
+ else if (targetUniform->type == targetBoolType)
+ {
+ GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ for (int i = 0; i < count; i++)
+ {
+ GLint *dest = boolParams + (i * 4);
+ const T *source = v + (i * components);
+
+ for (int c = 0; c < components; c++)
+ {
+ SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
+ }
+ for (int c = components; c < 4; c++)
+ {
+ SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
+ }
+ }
+ }
+ else if (gl::IsSampler(targetUniform->type))
+ {
+ ASSERT(targetUniformType == GL_INT);
+
+ GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
+
+ bool wasDirty = targetUniform->dirty;
+
+ for (int i = 0; i < count; i++)
+ {
+ GLint *dest = target + (i * 4);
+ const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
+
+ SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
+ SetIfDirty(dest + 1, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 2, 0, &targetUniform->dirty);
+ SetIfDirty(dest + 3, 0, &targetUniform->dirty);
+ }
+
+ if (!wasDirty && targetUniform->dirty)
+ {
+ mDirtySamplerMapping = true;
+ }
+ }
+ else UNREACHABLE();
+}
+
+template<typename T>
+bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
+{
+ bool dirty = false;
+ int copyWidth = std::min(targetHeight, srcWidth);
+ int copyHeight = std::min(targetWidth, srcHeight);
+
+ for (int x = 0; x < copyWidth; x++)
+ {
+ for (int y = 0; y < copyHeight; y++)
+ {
+ SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty);
+ }
+ }
+ // clear unfilled right side
+ for (int y = 0; y < copyWidth; y++)
+ {
+ for (int x = copyHeight; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+ // clear unfilled bottom.
+ for (int y = copyWidth; y < targetHeight; y++)
+ {
+ for (int x = 0; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+
+ return dirty;
+}
+
+template<typename T>
+bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
+{
+ bool dirty = false;
+ int copyWidth = std::min(targetWidth, srcWidth);
+ int copyHeight = std::min(targetHeight, srcHeight);
+
+ for (int y = 0; y < copyHeight; y++)
+ {
+ for (int x = 0; x < copyWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty);
+ }
+ }
+ // clear unfilled right side
+ for (int y = 0; y < copyHeight; y++)
+ {
+ for (int x = copyWidth; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+ // clear unfilled bottom.
+ for (int y = copyHeight; y < targetHeight; y++)
+ {
+ for (int x = 0; x < targetWidth; x++)
+ {
+ SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
+ }
+ }
+
+ return dirty;
+}
+
+template <int cols, int rows>
+void ProgramD3D::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
+{
+ gl::LinkedUniform *targetUniform = getUniformByLocation(location);
+
+ int elementCount = targetUniform->elementCount();
+
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+ const unsigned int targetMatrixStride = (4 * rows);
+ GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
+
+ for (int i = 0; i < count; i++)
+ {
+ // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
+ if (transpose == GL_FALSE)
+ {
+ targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty;
+ }
+ else
+ {
+ targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty;
+ }
+ target += targetMatrixStride;
+ value += cols * rows;
+ }
+}
+
+template <typename T>
+void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType)
+{
+ gl::LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
+
+ if (gl::IsMatrixType(targetUniform->type))
+ {
+ const int rows = gl::VariableRowCount(targetUniform->type);
+ const int cols = gl::VariableColumnCount(targetUniform->type);
+ transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
+ }
+ else if (uniformType == gl::VariableComponentType(targetUniform->type))
+ {
+ unsigned int size = gl::VariableComponentCount(targetUniform->type);
+ memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
+ size * sizeof(T));
+ }
+ else
+ {
+ unsigned int size = gl::VariableComponentCount(targetUniform->type);
+ switch (gl::VariableComponentType(targetUniform->type))
+ {
+ case GL_BOOL:
+ {
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
+ }
+ }
+ break;
+
+ case GL_FLOAT:
+ {
+ GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(floatParams[i]);
+ }
+ }
+ break;
+
+ case GL_INT:
+ {
+ GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(intParams[i]);
+ }
+ }
+ break;
+
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (unsigned int i = 0; i < size; i++)
+ {
+ params[i] = static_cast<T>(uintParams[i]);
+ }
+ }
+ break;
+
+ default: UNREACHABLE();
+ }
+ }
+}
+
+template <typename VarT>
+void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout)
+{
+ for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
+ {
+ const VarT &field = fields[uniformIndex];
+ const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
+
+ if (field.isStruct())
+ {
+ bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
+ for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
+ {
+ encoder->enterAggregateType();
+
+ const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
+ defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
+
+ encoder->exitAggregateType();
+ }
+ }
+ else
+ {
+ bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
+
+ sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
+
+ gl::LinkedUniform *newUniform = new gl::LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
+ blockIndex, memberInfo);
+
+ // add to uniform list, but not index, since uniform block uniforms have no location
+ blockUniformIndexes->push_back(mUniforms.size());
+ mUniforms.push_back(newUniform);
+ }
+ }
+}
+
+bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
+ const gl::Caps &caps)
+{
+ const ShaderD3D* shaderD3D = ShaderD3D::makeShaderD3D(shader.getImplementation());
+
+ // create uniform block entries if they do not exist
+ if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
+ {
+ std::vector<unsigned int> blockUniformIndexes;
+ const unsigned int blockIndex = mUniformBlocks.size();
+
+ // define member uniforms
+ sh::BlockLayoutEncoder *encoder = NULL;
+
+ if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
+ {
+ encoder = new sh::Std140BlockEncoder;
+ }
+ else
+ {
+ encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
+ }
+ ASSERT(encoder);
+
+ defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
+
+ size_t dataSize = encoder->getBlockSize();
+
+ // create all the uniform blocks
+ if (interfaceBlock.arraySize > 0)
+ {
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
+ {
+ gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
+ newUniformBlock->memberUniformIndexes = blockUniformIndexes;
+ mUniformBlocks.push_back(newUniformBlock);
+ }
+ }
+ else
+ {
+ gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
+ newUniformBlock->memberUniformIndexes = blockUniformIndexes;
+ mUniformBlocks.push_back(newUniformBlock);
+ }
+ }
+
+ if (interfaceBlock.staticUse)
+ {
+ // Assign registers to the uniform blocks
+ const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
+ const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
+ ASSERT(blockIndex != GL_INVALID_INDEX);
+ ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
+
+ unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
+
+ for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
+ {
+ gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
+ ASSERT(uniformBlock->name == interfaceBlock.name);
+
+ if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
+ interfaceBlockRegister + uniformBlockElement, caps))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex,
+ GLenum samplerType,
+ unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers,
+ GLuint *outUsedRange)
+{
+ unsigned int samplerIndex = startSamplerIndex;
+
+ do
+ {
+ if (samplerIndex < outSamplers.size())
+ {
+ Sampler& sampler = outSamplers[samplerIndex];
+ sampler.active = true;
+ sampler.textureType = GetTextureType(samplerType);
+ sampler.logicalTextureUnit = 0;
+ *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
+ }
+ else
+ {
+ return false;
+ }
+
+ samplerIndex++;
+ } while (samplerIndex < startSamplerIndex + samplerCount);
+
+ return true;
+}
+
+bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ ASSERT(gl::IsSampler(uniform.type));
+ ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
+
+ if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
+ {
+ if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
+ &mUsedVertexSamplerRange))
+ {
+ infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
+ mSamplersVS.size());
+ return false;
+ }
+
+ unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
+ if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
+ {
+ infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
+ caps.maxVertexUniformVectors);
+ return false;
+ }
+ }
+
+ if (uniform.psRegisterIndex != GL_INVALID_INDEX)
+ {
+ if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
+ &mUsedPixelSamplerRange))
+ {
+ infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
+ mSamplersPS.size());
+ return false;
+ }
+
+ unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
+ if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
+ {
+ infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
+ caps.maxFragmentUniformVectors);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
+
+ if (gl::IsSampler(uniform.type))
+ {
+ if (!indexSamplerUniform(uniform, infoLog, caps))
+ {
+ return false;
+ }
+ }
+
+ for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
+ {
+ mUniformIndex.push_back(gl::VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
+ }
+ }
+
+ return true;
+}
+
void ProgramD3D::reset()
{
+ ProgramImpl::reset();
+
+ SafeDeleteContainer(mVertexExecutables);
+ SafeDeleteContainer(mPixelExecutables);
+ SafeDelete(mGeometryExecutable);
+
+ mTransformFeedbackBufferMode = GL_NONE;
+
mVertexHLSL.clear();
- mVertexWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+ mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
+ mShaderVersion = 100;
mPixelHLSL.clear();
- mPixelWorkarounds = rx::ANGLE_D3D_WORKAROUND_NONE;
+ mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
mUsesFragDepth = false;
mPixelShaderKey.clear();
+ mUsesPointSize = false;
SafeDelete(mVertexUniformStorage);
SafeDelete(mFragmentUniformStorage);
+
+ mSamplersPS.clear();
+ mSamplersVS.clear();
+
+ mUsedVertexSamplerRange = 0;
+ mUsedPixelSamplerRange = 0;
+ mDirtySamplerMapping = true;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
index d645c57daa..4baab9aa19 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_PROGRAMD3D_H_
#include "libGLESv2/renderer/ProgramImpl.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include <string>
#include <vector>
@@ -23,63 +24,194 @@ struct VertexFormat;
namespace rx
{
-
+class RendererD3D;
class UniformStorage;
class ProgramD3D : public ProgramImpl
{
public:
- ProgramD3D(rx::Renderer *renderer);
+ ProgramD3D(RendererD3D *renderer);
virtual ~ProgramD3D();
static ProgramD3D *makeProgramD3D(ProgramImpl *impl);
static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl);
- Renderer *getRenderer() { return mRenderer; }
- DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; }
- const std::vector<rx::PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
-
- GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
- bool load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
- bool save(gl::BinaryOutputStream *stream);
+ const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
+ int getShaderVersion() const { return mShaderVersion; }
+ GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
- ShaderExecutable *getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
- ShaderExecutable *getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
- const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
- const sh::Attribute shaderAttributes[],
- const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
- bool separatedOutputBuffers);
+ GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
+ GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
+ GLint getUsedSamplerRange(gl::SamplerType type) const;
+ void updateSamplerMapping();
+ bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
- bool link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings, int *registers,
- std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables);
+ bool usesPointSize() const { return mUsesPointSize; }
+ bool usesPointSpriteEmulation() const;
+ bool usesGeometryShader() const;
- // D3D only
- void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms);
+ GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
+ gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
+ gl::Error save(gl::BinaryOutputStream *stream);
+
+ gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable);
+ gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutable **outExectuable);
+ gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable);
+ ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
+
+ gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers);
+
+ gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables);
+
+ void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
+
+ void initializeUniformStorage();
+ gl::Error applyUniforms();
+ gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps);
+ bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
+ unsigned int registerIndex, const gl::Caps &caps);
+ void dirtyAllUniforms();
+
+ void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
+ void setUniform1iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform2iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform3iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform4iv(GLint location, GLsizei count, const GLint *v);
+ void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
+ void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+ void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+
+ void getUniformfv(GLint location, GLfloat *params);
+ void getUniformiv(GLint location, GLint *params);
+ void getUniformuiv(GLint location, GLuint *params);
const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+ bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::Caps &caps);
+ bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
+
void reset();
private:
DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
- Renderer *mRenderer;
+ class VertexExecutable
+ {
+ public:
+ VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+ const GLenum signature[gl::MAX_VERTEX_ATTRIBS],
+ ShaderExecutable *shaderExecutable);
+ ~VertexExecutable();
+
+ bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const;
+
+ const gl::VertexFormat *inputs() const { return mInputs; }
+ const GLenum *signature() const { return mSignature; }
+ ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
+ GLenum mSignature[gl::MAX_VERTEX_ATTRIBS];
+ ShaderExecutable *mShaderExecutable;
+ };
+
+ class PixelExecutable
+ {
+ public:
+ PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable);
+ ~PixelExecutable();
+
+ bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
+
+ const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
+ ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ std::vector<GLenum> mOutputSignature;
+ ShaderExecutable *mShaderExecutable;
+ };
+
+ struct Sampler
+ {
+ Sampler();
+
+ bool active;
+ GLint logicalTextureUnit;
+ GLenum textureType;
+ };
+
+ void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
+ void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName,
+ sh::HLSLBlockEncoder *encoder);
+ bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
+ bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
+ static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
+
+ template <typename T>
+ void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
+
+ template <int cols, int rows>
+ void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
+
+ template <typename T>
+ void getUniformv(GLint location, T *params, GLenum uniformType);
+
+ template <typename VarT>
+ void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
+ sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
+ bool inRowMajorLayout);
+
+ RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL;
+ std::vector<VertexExecutable *> mVertexExecutables;
+ std::vector<PixelExecutable *> mPixelExecutables;
+ ShaderExecutable *mGeometryExecutable;
+
std::string mVertexHLSL;
- rx::D3DWorkaroundType mVertexWorkarounds;
+ D3DWorkaroundType mVertexWorkarounds;
std::string mPixelHLSL;
- rx::D3DWorkaroundType mPixelWorkarounds;
+ D3DWorkaroundType mPixelWorkarounds;
bool mUsesFragDepth;
- std::vector<rx::PixelShaderOutputVariable> mPixelShaderKey;
+ std::vector<PixelShaderOutputVariable> mPixelShaderKey;
+
+ bool mUsesPointSize;
UniformStorage *mVertexUniformStorage;
UniformStorage *mFragmentUniformStorage;
+
+ GLenum mTransformFeedbackBufferMode;
+
+ std::vector<Sampler> mSamplersPS;
+ std::vector<Sampler> mSamplersVS;
+ GLuint mUsedVertexSamplerRange;
+ GLuint mUsedPixelSamplerRange;
+ bool mDirtySamplerMapping;
+
+ int mShaderVersion;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
new file mode 100644
index 0000000000..cb4af367a2
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl
+
+
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
+
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+RenderbufferD3D::RenderbufferD3D(RendererD3D *renderer) : mRenderer(renderer)
+{
+ mRenderTarget = NULL;
+}
+
+RenderbufferD3D::~RenderbufferD3D()
+{
+ SafeDelete(mRenderTarget);
+}
+
+RenderbufferD3D *RenderbufferD3D::makeRenderbufferD3D(RenderbufferImpl *renderbuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RenderbufferD3D*, renderbuffer));
+ return static_cast<RenderbufferD3D*>(renderbuffer);
+}
+
+gl::Error RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
+{
+ // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage, but we should create depth and stencil buffers
+ // as DEPTH24_STENCIL8
+ GLenum creationFormat = internalformat;
+ if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8)
+ {
+ creationFormat = GL_DEPTH24_STENCIL8_OES;
+ }
+
+ RenderTarget *newRT = NULL;
+ gl::Error error = mRenderer->createRenderTarget(width, height, creationFormat, samples, &newRT);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ SafeDelete(mRenderTarget);
+ mRenderTarget = newRT;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RenderbufferD3D::setStorage(SwapChain *swapChain, bool depth)
+{
+ RenderTarget *newRT = NULL;
+ gl::Error error = mRenderer->createRenderTarget(swapChain, depth, &newRT);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ SafeDelete(mRenderTarget);
+ mRenderTarget = newRT;
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+GLsizei RenderbufferD3D::getWidth() const
+{
+ return (mRenderTarget ? mRenderTarget->getWidth() : 0);
+}
+
+GLsizei RenderbufferD3D::getHeight() const
+{
+ return (mRenderTarget ? mRenderTarget->getHeight() : 0);
+}
+
+GLenum RenderbufferD3D::getInternalFormat() const
+{
+ return (mRenderTarget ? mRenderTarget->getInternalFormat() : GL_RGBA4);
+}
+
+GLenum RenderbufferD3D::getActualFormat() const
+{
+ return (mRenderTarget ? mRenderTarget->getActualFormat() : GL_RGBA4);
+}
+
+GLsizei RenderbufferD3D::getSamples() const
+{
+ return (mRenderTarget ? mRenderTarget->getSamples() : 0);
+}
+
+RenderTarget *RenderbufferD3D::getRenderTarget()
+{
+ return mRenderTarget;
+}
+
+unsigned int RenderbufferD3D::getRenderTargetSerial() const
+{
+ return (mRenderTarget ? mRenderTarget->getSerial() : 0);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
new file mode 100644
index 0000000000..9440a449f2
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderbufferD3d.h: Defines the RenderbufferD3D class which implements RenderbufferImpl.
+
+#ifndef LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
+#define LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
+
+#include "angle_gl.h"
+
+#include "common/angleutils.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+class RendererD3D;
+class RenderTarget;
+class SwapChain;
+
+class RenderbufferD3D : public RenderbufferImpl
+{
+ public:
+ RenderbufferD3D(RendererD3D *renderer);
+ virtual ~RenderbufferD3D();
+
+ static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *renderbuffer);
+
+ virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) override;
+ gl::Error setStorage(SwapChain *swapChain, bool depth);
+
+ virtual GLsizei getWidth() const;
+ virtual GLsizei getHeight() const;
+ virtual GLenum getInternalFormat() const;
+ virtual GLenum getActualFormat() const;
+ virtual GLsizei getSamples() const;
+
+ RenderTarget *getRenderTarget();
+ unsigned int getRenderTargetSerial() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderbufferD3D);
+
+ RendererD3D *mRenderer;
+ RenderTarget *mRenderTarget;
+};
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
new file mode 100644
index 0000000000..97da6da7fd
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
@@ -0,0 +1,796 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RendererD3D.cpp: Implementation of the base D3D Renderer.
+
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
+
+#include "libGLESv2/renderer/d3d/IndexDataManager.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/FramebufferAttachment.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/State.h"
+#include "libGLESv2/VertexArray.h"
+#include "libGLESv2/formatutils.h"
+#include "common/utilities.h"
+
+namespace rx
+{
+
+RendererD3D::RendererD3D(egl::Display *display)
+ : mDisplay(display)
+{
+}
+
+RendererD3D::~RendererD3D()
+{
+ for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
+ {
+ i->second.set(NULL);
+ }
+ mIncompleteTextures.clear();
+}
+
+// static
+RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RendererD3D*, renderer));
+ return static_cast<RendererD3D*>(renderer);
+}
+
+gl::Error RendererD3D::drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange)
+{
+ ASSERT(data.state->getCurrentProgramId() != 0);
+
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ programBinary->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::VertexArray *vao = data.state->getVertexArray();
+ TranslatedIndexData indexInfo;
+ indexInfo.indexRange = indexRange;
+ error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+ error = applyVertexBuffer(*data.state, indexInfo.indexRange.start, vertexCount, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
+ // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
+ // layer.
+ ASSERT(!transformFeedbackActive);
+
+ error = applyShaders(data, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances)
+{
+ ASSERT(data.state->getCurrentProgramId() != 0);
+
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+ programBinary->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyVertexBuffer(*data.state, first, count, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
+
+ error = applyShaders(data, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawArrays(mode, count, instances, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (transformFeedbackActive)
+ {
+ markTransformFeedbackUsage(data);
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ size_t samplerRange = programBinary->getUsedSamplerRange(type);
+
+ for (size_t i = 0; i < samplerRange; i++)
+ {
+ GLenum textureType = programBinary->getSamplerTextureType(type, i);
+ GLint textureUnit = programBinary->getSamplerMapping(type, i, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ if (texture->getSamplerState().swizzleRequired())
+ {
+ gl::Error error = generateSwizzle(texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data)
+{
+ gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = generateSwizzles(data, gl::SAMPLER_PIXEL);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and
+// scissor rectangle to the renderer
+gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ ASSERT(framebufferObject && framebufferObject->completeness(data) == GL_FRAMEBUFFER_COMPLETE);
+
+ gl::Error error = applyRenderTarget(framebufferObject);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ float nearZ, farZ;
+ data.state->getDepthRange(&nearZ, &farZ);
+ setViewport(data.state->getViewport(), nearZ, farZ, drawMode,
+ data.state->getRasterizerState().frontFace, ignoreViewport);
+
+ setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device
+gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ int samples = framebufferObject->getSamples(data);
+
+ gl::RasterizerState rasterizer = data.state->getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+ rasterizer.multiSample = (samples != 0);
+
+ gl::Error error = setRasterizerState(rasterizer);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ unsigned int mask = 0;
+ if (data.state->isSampleCoverageEnabled())
+ {
+ GLclampf coverageValue;
+ bool coverageInvert = false;
+ data.state->getSampleCoverageParams(&coverageValue, &coverageInvert);
+ if (coverageValue != 0)
+ {
+ float threshold = 0.5f;
+
+ for (int i = 0; i < samples; ++i)
+ {
+ mask <<= 1;
+
+ if ((i + 1) * coverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
+ }
+ }
+
+ if (coverageInvert)
+ {
+ mask = ~mask;
+ }
+ }
+ else
+ {
+ mask = 0xFFFFFFFF;
+ }
+ error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(),
+ data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool RendererD3D::applyTransformFeedbackBuffers(const gl::Data &data)
+{
+ gl::TransformFeedback *curTransformFeedback = data.state->getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
+ {
+ applyTransformFeedbackBuffers(*data.state);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+// Applies the shaders and shader constants to the Direct3D device
+gl::Error RendererD3D::applyShaders(const gl::Data &data, bool transformFeedbackActive)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ gl::VertexFormat::GetInputLayout(inputLayout, programBinary, *data.state);
+
+ const gl::Framebuffer *fbo = data.state->getDrawFramebuffer();
+
+ gl::Error error = applyShaders(programBinary, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return programBinary->applyUniforms();
+}
+
+// For each Direct3D sampler of either the pixel or vertex stage,
+// looks up the corresponding OpenGL texture image unit and texture type,
+// and sets the texture and its addressing/filtering state (or NULL when inactive).
+gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
+{
+ gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
+
+ size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+ for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
+ {
+ GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ gl::SamplerState sampler = texture->getSamplerState();
+
+ gl::Sampler *samplerObject = data.state->getSampler(textureUnit);
+ if (samplerObject)
+ {
+ samplerObject->getState(&sampler);
+ }
+
+ // TODO: std::binary_search may become unavailable using older versions of GCC
+ if (texture->isSamplerComplete(sampler, *data.textureCaps, *data.extensions, data.clientVersion) &&
+ !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
+ {
+ gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setTexture(shaderType, samplerIndex, texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
+ gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
+ gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ // No texture bound to this slot even though it is used by the shader, bind a NULL texture
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+
+ // Set all the remaining textures to NULL
+ size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
+ : data.caps->maxVertexTextureImageUnits;
+ for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
+ {
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyTextures(const gl::Data &data)
+{
+ FramebufferTextureSerialArray framebufferSerials;
+ size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials);
+
+ gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyUniformBuffers(const gl::Data &data)
+{
+ gl::Program *programObject = data.resourceManager->getProgram(data.state->getCurrentProgramId());
+ gl::ProgramBinary *programBinary = programObject->getProgramBinary();
+
+ std::vector<gl::Buffer*> boundBuffers;
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
+ {
+ GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
+
+ if (data.state->getIndexedUniformBuffer(blockBinding)->id() == 0)
+ {
+ // undefined behaviour
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
+ }
+ else
+ {
+ gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(blockBinding);
+ ASSERT(uniformBuffer);
+ boundBuffers.push_back(uniformBuffer);
+ }
+ }
+
+ return programBinary->applyUniformBuffers(boundBuffers, *data.caps);
+}
+
+bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
+{
+ if (drawMode == GL_POINTS)
+ {
+ // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
+ // which affects varying interpolation. Since the value of gl_PointSize is
+ // undefined when not written, just skip drawing to avoid unexpected results.
+ if (!data.state->getCurrentProgramBinary()->usesPointSize())
+ {
+ // This is stictly speaking not an error, but developers should be
+ // notified of risking undefined behavior.
+ ERR("Point rendering without writing to gl_PointSize.");
+
+ return true;
+ }
+ }
+ else if (gl::IsTriangleMode(drawMode))
+ {
+ if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
+{
+ for (size_t i = 0; i < data.caps->maxTransformFeedbackSeparateAttributes; i++)
+ {
+ gl::Buffer *buffer = data.state->getIndexedTransformFeedbackBuffer(i);
+ if (buffer)
+ {
+ buffer->markTransformFeedbackUsage();
+ }
+ }
+}
+
+size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray)
+{
+ size_t serialCount = 0;
+
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
+ {
+ gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
+ if (attachment && attachment->isTexture())
+ {
+ gl::Texture *texture = attachment->getTexture();
+ (*outSerialArray)[serialCount++] = texture->getTextureSerial();
+ }
+ }
+
+ gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
+ if (depthStencilAttachment && depthStencilAttachment->isTexture())
+ {
+ gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+ (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
+ }
+
+ std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
+
+ return serialCount;
+}
+
+gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
+{
+ if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
+ {
+ const GLubyte color[] = { 0, 0, 0, 255 };
+ const gl::PixelUnpackState incompleteUnpackState(1);
+
+ gl::Texture* t = NULL;
+ switch (type)
+ {
+ default:
+ UNREACHABLE();
+ // default falls through to TEXTURE_2D
+
+ case GL_TEXTURE_2D:
+ {
+ gl::Texture2D *incomplete2d = new gl::Texture2D(createTexture(GL_TEXTURE_2D), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ t = incomplete2d;
+ }
+ break;
+
+ case GL_TEXTURE_CUBE_MAP:
+ {
+ gl::TextureCubeMap *incompleteCube = new gl::TextureCubeMap(createTexture(GL_TEXTURE_CUBE_MAP), gl::Texture::INCOMPLETE_TEXTURE_ID);
+
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incompleteCube;
+ }
+ break;
+
+ case GL_TEXTURE_3D:
+ {
+ gl::Texture3D *incomplete3d = new gl::Texture3D(createTexture(GL_TEXTURE_3D), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incomplete3d;
+ }
+ break;
+
+ case GL_TEXTURE_2D_ARRAY:
+ {
+ gl::Texture2DArray *incomplete2darray = new gl::Texture2DArray(createTexture(GL_TEXTURE_2D_ARRAY), gl::Texture::INCOMPLETE_TEXTURE_ID);
+ incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+
+ t = incomplete2darray;
+ }
+ break;
+ }
+
+ mIncompleteTextures[type].set(t);
+ }
+
+ return mIncompleteTextures[type].get();
+}
+
+gl::Error RendererD3D::clear(const gl::Data &data, GLbitfield mask)
+{
+ gl::ClearParameters clearParams = data.state->getClearParameters(mask);
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values)
+{
+ // glClearBufferfv can be called to clear the color buffer or depth buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_FLOAT;
+ }
+
+ if (buffer == GL_DEPTH)
+ {
+ clearParams.clearDepth = true;
+ clearParams.depthClearValue = values[0];
+ }
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values)
+{
+ // glClearBufferuiv can only be called to clear a color buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_UNSIGNED_INT;
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values)
+{
+ // glClearBufferiv can be called to clear the color buffer or stencil buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_INT;
+ }
+
+ if (buffer == GL_STENCIL)
+ {
+ clearParams.clearStencil = true;
+ clearParams.stencilClearValue = values[1];
+ }
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer,
+ GLfloat depth, GLint stencil)
+{
+ if (data.state->isRasterizerDiscardEnabled())
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ // glClearBufferfi can only be called to clear a depth stencil buffer
+ gl::ClearParameters clearParams = data.state->getClearParameters(0);
+ clearParams.clearDepth = true;
+ clearParams.depthClearValue = depth;
+ clearParams.clearStencil = true;
+ clearParams.stencilClearValue = stencil;
+
+ // Clips the clear to the scissor rectangle but not the viewport
+ gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return clear(clearParams, data.state->getDrawFramebuffer());
+}
+
+gl::Error RendererD3D::blitFramebuffer(const gl::Data &data,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ const gl::Framebuffer *readFramebuffer = data.state->getReadFramebuffer();
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
+
+ bool blitRenderTarget = false;
+ bool blitDepth = false;
+ bool blitStencil = false;
+ if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
+ {
+ blitRenderTarget = true;
+ }
+ if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
+ {
+ blitStencil = true;
+ }
+ if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
+ {
+ blitDepth = true;
+ }
+
+ gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+ if (blitRenderTarget || blitDepth || blitStencil)
+ {
+ const gl::Rectangle *scissor = data.state->isScissorTestEnabled() ? &data.state->getScissor() : NULL;
+ gl::Error error = blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
+ blitRenderTarget, blitDepth, blitStencil, filter);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+{
+ const gl::Framebuffer *framebuffer = data.state->getReadFramebuffer();
+
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
+ const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
+ GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, data.state->getPackAlignment());
+
+ return readPixels(framebuffer, x, y, width, height, format, type, outputPitch, data.state->getPackState(),
+ reinterpret_cast<uint8_t*>(pixels));
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
new file mode 100644
index 0000000000..9919207667
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
@@ -0,0 +1,195 @@
+
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RendererD3D.h: Defines a back-end specific class for the DirectX renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERERD3D_H_
+#define LIBGLESV2_RENDERER_RENDERERD3D_H_
+
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Data.h"
+
+//FIXME(jmadill): std::array is currently prohibited by Chromium style guide
+#include <array>
+
+namespace gl
+{
+class InfoLog;
+struct LinkedVarying;
+class Texture;
+}
+
+namespace rx
+{
+class TextureStorage;
+class VertexBuffer;
+class IndexBuffer;
+class ShaderExecutable;
+class SwapChain;
+class RenderTarget;
+class Image;
+class TextureStorage;
+class UniformStorage;
+
+class RendererD3D : public Renderer
+{
+ public:
+ explicit RendererD3D(egl::Display *display);
+ virtual ~RendererD3D();
+
+ static RendererD3D *makeRendererD3D(Renderer *renderer);
+
+ gl::Error drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances) override;
+
+ gl::Error drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange) override;
+
+ gl::Error clear(const gl::Data &data, GLbitfield mask) override;
+ gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLfloat *values) override;
+ gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLuint *values) override;
+ gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLint *values) override;
+ gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
+
+ gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels) override;
+
+ gl::Error blitFramebuffer(const gl::Data &data,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) override;
+
+ // Direct3D Specific methods
+ virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+
+ virtual gl::Error generateSwizzle(gl::Texture *texture) = 0;
+ virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
+ virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+
+ virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
+
+ virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0;
+ virtual gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) = 0;
+ virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW) = 0;
+
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
+ virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport) = 0;
+
+ virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
+ virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ bool rasterizerDiscard, bool transformFeedbackActive) = 0;
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
+ virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0;
+
+ virtual void markAllStateDirty() = 0;
+
+ virtual unsigned int getReservedVertexUniformVectors() const = 0;
+ virtual unsigned int getReservedFragmentUniformVectors() const = 0;
+ virtual unsigned int getReservedVertexUniformBuffers() const = 0;
+ virtual unsigned int getReservedFragmentUniformBuffers() const = 0;
+ virtual bool getShareHandleSupport() const = 0;
+ virtual bool getPostSubBufferSupport() const = 0;
+
+ // Pixel operations
+ virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0;
+ virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0;
+ virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
+ virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
+
+ virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
+
+ // RenderTarget creation
+ virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) = 0;
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0;
+
+ // Shader operations
+ virtual void releaseShaderCompiler() = 0;
+ virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0;
+ virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable) = 0;
+ virtual UniformStorage *createUniformStorage(size_t storageSize) = 0;
+
+ // Image operations
+ virtual Image *createImage() = 0;
+ virtual gl::Error generateMipmap(Image *dest, Image *source) = 0;
+ virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0;
+ virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0;
+ virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0;
+ virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
+ virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
+
+ // Buffer-to-texture and Texture-to-buffer copies
+ virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
+
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0;
+ virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
+
+ virtual VertexBuffer *createVertexBuffer() = 0;
+ virtual IndexBuffer *createIndexBuffer() = 0;
+
+ protected:
+ virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
+ virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
+ gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
+ virtual gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) = 0;
+ virtual gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter) = 0;
+
+ egl::Display *mDisplay;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RendererD3D);
+
+ //FIXME(jmadill): std::array is currently prohibited by Chromium style guide
+ typedef std::array<unsigned int, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
+
+ gl::Error generateSwizzles(const gl::Data &data, gl::SamplerType type);
+ gl::Error generateSwizzles(const gl::Data &data);
+
+ gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport);
+ gl::Error applyState(const gl::Data &data, GLenum drawMode);
+ bool applyTransformFeedbackBuffers(const gl::Data &data);
+ gl::Error applyShaders(const gl::Data &data, bool transformFeedbackActive);
+ gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount);
+ gl::Error applyTextures(const gl::Data &data);
+ gl::Error applyUniformBuffers(const gl::Data &data);
+
+ bool skipDraw(const gl::Data &data, GLenum drawMode);
+ void markTransformFeedbackUsage(const gl::Data &data);
+
+ size_t getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray);
+ gl::Texture *getIncompleteTexture(GLenum type);
+
+ gl::TextureMap mIncompleteTextures;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
index c472113eba..8a97579e16 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
@@ -6,13 +6,36 @@
// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
+#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "common/features.h"
#include "common/utilities.h"
+// Definitions local to the translation unit
+namespace
+{
+
+const char *GetShaderTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_VERTEX_SHADER:
+ return "VERTEX";
+
+ case GL_FRAGMENT_SHADER:
+ return "FRAGMENT";
+
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+}
+
namespace rx
{
@@ -44,13 +67,13 @@ const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableLis
return variableList;
}
-ShaderD3D::ShaderD3D(GLenum type, rx::Renderer *renderer)
+ShaderD3D::ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer)
: mType(type),
mRenderer(renderer),
mShaderVersion(100)
{
uncompile();
- initializeCompiler();
+ initializeCompiler(data);
}
ShaderD3D::~ShaderD3D()
@@ -69,23 +92,28 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl)
return static_cast<const ShaderD3D*>(impl);
}
+std::string ShaderD3D::getDebugInfo() const
+{
+ return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mType) + " SHADER END\n";
+}
+
// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void ShaderD3D::initializeCompiler()
+void ShaderD3D::initializeCompiler(const gl::Data &data)
{
if (!mFragmentCompiler)
{
- int result = ShInitialize();
+ bool result = ShInitialize();
if (result)
{
+ ShShaderSpec specVersion = (data.clientVersion >= 3) ? SH_GLES3_SPEC : SH_GLES2_SPEC;
ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
- // TODO(geofflang): use context's caps
- const gl::Caps &caps = mRenderer->getRendererCaps();
- const gl::Extensions &extensions = mRenderer->getRendererExtensions();
+ const gl::Caps &caps = *data.caps;
+ const gl::Extensions &extensions = *data.extensions;
resources.MaxVertexAttribs = caps.maxVertexAttributes;
resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
@@ -107,8 +135,8 @@ void ShaderD3D::initializeCompiler()
resources.MinProgramTexelOffset = caps.minProgramTexelOffset;
resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
- mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
- mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
+ mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, specVersion, hlslVersion, &resources);
+ mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, specVersion, hlslVersion, &resources);
}
}
}
@@ -126,7 +154,7 @@ void ShaderD3D::releaseCompiler()
void ShaderD3D::parseVaryings(void *compiler)
{
- if (!mHlsl.empty())
+ if (!mHlsl.empty())
{
const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
ASSERT(varyings);
@@ -183,21 +211,25 @@ void ShaderD3D::uncompile()
mInterfaceBlocks.clear();
mActiveAttributes.clear();
mActiveOutputVariables.clear();
+ mDebugInfo.clear();
}
-void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
+void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::string &source)
{
// ensure the compiler is loaded
- initializeCompiler();
+ initializeCompiler(data);
int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
std::string sourcePath;
+
+#if !defined (ANGLE_ENABLE_WINDOWS_STORE)
if (gl::perfActive())
{
sourcePath = getTempPath();
writeFile(sourcePath.c_str(), source.c_str(), source.length());
compileOptions |= SH_LINE_DIRECTIVES;
}
+#endif
int result;
if (sourcePath.empty())
@@ -220,25 +252,20 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH);
}
- size_t shaderVersion = 100;
- ShGetInfo(compiler, SH_SHADER_VERSION, &shaderVersion);
+ mShaderVersion = ShGetShaderVersion(compiler);
- mShaderVersion = static_cast<int>(shaderVersion);
-
- if (shaderVersion == 300 && mRenderer->getCurrentClientVersion() < 3)
+ if (mShaderVersion == 300 && data.clientVersion < 3)
{
mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
TRACE("\n%s", mInfoLog.c_str());
}
else if (result)
{
- size_t objCodeLen = 0;
- ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
-
- char* outputHLSL = new char[objCodeLen];
- ShGetObjectCode(compiler, outputHLSL);
+ mHlsl = ShGetObjectCode(compiler);
#ifdef _DEBUG
+ // Prefix hlsl shader with commented out glsl shader
+ // Useful in diagnostics tools like pix which capture the hlsl shaders
std::ostringstream hlslStream;
hlslStream << "// GLSL\n";
hlslStream << "//\n";
@@ -254,14 +281,10 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
}
hlslStream << "\n\n";
- hlslStream << outputHLSL;
+ hlslStream << mHlsl;
mHlsl = hlslStream.str();
-#else
- mHlsl = outputHLSL;
#endif
- SafeDeleteArray(outputHLSL);
-
mUniforms = *GetShaderVariables(ShGetUniforms(compiler));
for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
@@ -271,7 +294,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
if (uniform.staticUse)
{
unsigned int index = -1;
- bool result = ShGetUniformRegister(compiler, uniform.name.c_str(), &index);
+ bool result = ShGetUniformRegister(compiler, uniform.name, &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
@@ -288,7 +311,7 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
if (interfaceBlock.staticUse)
{
unsigned int index = -1;
- bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name.c_str(), &index);
+ bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(result);
@@ -298,24 +321,19 @@ void ShaderD3D::compileToHLSL(void *compiler, const std::string &source)
}
else
{
- size_t infoLogLen = 0;
- ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
-
- char* infoLog = new char[infoLogLen];
- ShGetInfoLog(compiler, infoLog);
- mInfoLog = infoLog;
+ mInfoLog = ShGetInfoLog(compiler);
TRACE("\n%s", mInfoLog.c_str());
}
}
-rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
+D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
{
if (mUsesDiscardRewriting)
{
// ANGLE issue 486:
// Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
- return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
+ return ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
}
if (mUsesNestedBreak)
@@ -323,10 +341,10 @@ rx::D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
// ANGLE issue 603:
// Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
// We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
- return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
+ return ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
}
- return rx::ANGLE_D3D_WORKAROUND_NONE;
+ return ANGLE_D3D_WORKAROUND_NONE;
}
// true if varying x has a higher priority in packing than y
@@ -387,19 +405,16 @@ ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader)
default: UNREACHABLE(); return SH_HLSL9_OUTPUT;
}
- size_t outputType = 0;
- ShGetInfo(compiler, SH_OUTPUT_TYPE, &outputType);
-
- return static_cast<ShShaderOutput>(outputType);
+ return ShGetShaderOutputType(compiler);
}
-bool ShaderD3D::compile(const std::string &source)
+bool ShaderD3D::compile(const gl::Data &data, const std::string &source)
{
uncompile();
void *compiler = getCompiler();
- compileToHLSL(compiler, source);
+ compileToHLSL(data, compiler, source);
if (mType == GL_VERTEX_SHADER)
{
@@ -420,6 +435,15 @@ bool ShaderD3D::compile(const std::string &source)
}
}
+#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ mDebugInfo += std::string("// ") + GetShaderTypeString(mType) + " SHADER BEGIN\n";
+ mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n";
+ mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n";
+ // Successive steps will append more info
+#else
+ mDebugInfo += getTranslatedSource();
+#endif
+
return !getTranslatedSource().empty();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
index 40e64cf36c..3c9aac2c12 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_RENDERER_SHADERD3D_H_
#include "libGLESv2/renderer/ShaderImpl.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/Shader.h"
#include <map>
@@ -17,22 +18,23 @@
namespace rx
{
class DynamicHLSL;
-class Renderer;
+class RendererD3D;
class ShaderD3D : public ShaderImpl
{
friend class DynamicHLSL;
public:
- ShaderD3D(GLenum type, rx::Renderer *renderer);
+ ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer);
virtual ~ShaderD3D();
static ShaderD3D *makeShaderD3D(ShaderImpl *impl);
static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl);
// ShaderImpl implementation
- const std::string &getInfoLog() const { return mInfoLog; }
- const std::string &getTranslatedSource() const { return mHlsl; }
+ virtual const std::string &getInfoLog() const { return mInfoLog; }
+ virtual const std::string &getTranslatedSource() const { return mHlsl; }
+ virtual std::string getDebugInfo() const;
// D3D-specific methods
virtual void uncompile();
@@ -40,8 +42,9 @@ class ShaderD3D : public ShaderImpl
unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
int getSemanticIndex(const std::string &attributeName) const;
+ void appendDebugInfo(const std::string &info) { mDebugInfo += info; }
- rx::D3DWorkaroundType getD3DWorkarounds() const;
+ D3DWorkaroundType getD3DWorkarounds() const;
int getShaderVersion() const { return mShaderVersion; }
bool usesDepthRange() const { return mUsesDepthRange; }
bool usesPointSize() const { return mUsesPointSize; }
@@ -49,15 +52,15 @@ class ShaderD3D : public ShaderImpl
static void releaseCompiler();
static ShShaderOutput getCompilerOutputType(GLenum shader);
- virtual bool compile(const std::string &source);
+ virtual bool compile(const gl::Data &data, const std::string &source);
private:
DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
- void compileToHLSL(void *compiler, const std::string &source);
+ void compileToHLSL(const gl::Data &data, void *compiler, const std::string &source);
void parseVaryings(void *compiler);
- void initializeCompiler();
+ void initializeCompiler(const gl::Data &data);
void parseAttributes(void *compiler);
void *getCompiler();
@@ -67,7 +70,7 @@ class ShaderD3D : public ShaderImpl
static void *mVertexCompiler;
GLenum mType;
- rx::Renderer *mRenderer;
+ RendererD3D *mRenderer;
int mShaderVersion;
@@ -85,6 +88,7 @@ class ShaderD3D : public ShaderImpl
std::string mHlsl;
std::string mInfoLog;
+ std::string mDebugInfo;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 96c84977cb..4a67701fdf 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -6,9 +6,6 @@
// TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
-#include "libGLESv2/renderer/d3d/ImageD3D.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/Texture.h"
@@ -16,7 +13,11 @@
#include "libGLESv2/formatutils.h"
#include "libGLESv2/renderer/BufferImpl.h"
#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libGLESv2/renderer/d3d/ImageD3D.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libEGL/Surface.h"
@@ -26,16 +27,51 @@
namespace rx
{
+namespace
+{
+
+gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixels, const uint8_t **pointerOut)
+{
+ if (unpack.pixelBuffer.id() != 0)
+ {
+ // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
+ gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
+ ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+
+ // TODO: this is the only place outside of renderer that asks for a buffers raw data.
+ // This functionality should be moved into renderer and the getData method of BufferImpl removed.
+ BufferD3D *bufferD3D = BufferD3D::makeBufferD3D(pixelBuffer->getImplementation());
+ ASSERT(bufferD3D);
+ const uint8_t *bufferData = NULL;
+ gl::Error error = bufferD3D->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *pointerOut = bufferData + offset;
+ }
+ else
+ {
+ *pointerOut = static_cast<const uint8_t *>(pixels);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
bool IsRenderTargetUsage(GLenum usage)
{
return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
}
-TextureD3D::TextureD3D(Renderer *renderer)
+}
+
+TextureD3D::TextureD3D(RendererD3D *renderer)
: mRenderer(renderer),
mUsage(GL_NONE),
mDirtyImages(true),
- mImmutable(false)
+ mImmutable(false),
+ mTexStorage(NULL)
{
}
@@ -54,13 +90,12 @@ TextureStorage *TextureD3D::getNativeTexture()
// ensure the underlying texture is created
initializeStorage(false);
- TextureStorage *storage = getBaseLevelStorage();
- if (storage)
+ if (mTexStorage)
{
updateStorage();
}
- return storage;
+ return mTexStorage;
}
GLint TextureD3D::getBaseLevelWidth() const
@@ -90,50 +125,79 @@ GLenum TextureD3D::getBaseLevelInternalFormat() const
return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
}
-void TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image)
+bool TextureD3D::shouldUseSetData(const Image *image) const
+{
+ if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload)
+ {
+ return false;
+ }
+
+ gl::InternalFormat internalFormat = gl::GetInternalFormatInfo(image->getInternalFormat());
+
+ // We can only handle full updates for depth-stencil textures, so to avoid complications
+ // disable them entirely.
+ if (internalFormat.depthBits > 0 || internalFormat.stencilBits > 0)
+ {
+ return false;
+ }
+
+ // TODO(jmadill): Handle compressed internal formats
+ return (mTexStorage && !internalFormat.compressed);
+}
+
+gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index)
{
+ Image *image = getImage(index);
+ ASSERT(image);
+
// No-op
if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
// From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
- const void *pixelData = pixels;
-
- if (unpack.pixelBuffer.id() != 0)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const void *bufferData = pixelBuffer->getImplementation()->getData();
- pixelData = static_cast<const unsigned char *>(bufferData) + offset;
+ return error;
}
if (pixelData != NULL)
{
- image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
+ gl::Error error(GL_NO_ERROR);
+
+ if (shouldUseSetData(image))
+ {
+ error = mTexStorage->setData(index, image, NULL, type, unpack, pixelData);
+ }
+ else
+ {
+ error = image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
+ }
+
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
+
+ return gl::Error(GL_NO_ERROR);
}
-bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
+gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
{
- const void *pixelData = pixels;
-
// CPU readback & copy where direct GPU copy is not supported
- if (unpack.pixelBuffer.id() != 0)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
{
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const void *bufferData = pixelBuffer->getImplementation()->getData();
- pixelData = static_cast<const unsigned char *>(bufferData) + offset;
+ return error;
}
if (pixelData != NULL)
@@ -141,32 +205,78 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w
Image *image = getImage(index);
ASSERT(image);
- image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
+ gl::Box region(xoffset, yoffset, zoffset, width, height, depth);
+ if (shouldUseSetData(image))
+ {
+ return mTexStorage->setData(index, image, &region, type, unpack, pixelData);
+ }
+
+ gl::Error error = image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment,
+ type, pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
+gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image)
{
- if (pixels != NULL)
+ // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
+ // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (pixelData != NULL)
{
- image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
+ gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
+
+ return gl::Error(GL_NO_ERROR);
}
-bool TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const void *pixels, Image *image)
+gl::Error TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image)
{
- if (pixels != NULL)
+ const uint8_t *pixelData = NULL;
+ gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (pixelData != NULL)
{
- image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
+ gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixelData);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat)
@@ -174,21 +284,28 @@ bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum siz
return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
}
-bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
- GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget)
+gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
+ GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget)
{
+ // No-op
if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
{
- return true;
+ return gl::Error(GL_NO_ERROR);
}
// In order to perform the fast copy through the shader, we must have the right format, and be able
// to create a render target.
ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
- ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+ uintptr_t offset = reinterpret_cast<uintptr_t>(pixels);
- return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
+ gl::Error error = mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
@@ -210,10 +327,192 @@ int TextureD3D::mipLevels() const
return gl::log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
}
+TextureStorage *TextureD3D::getStorage()
+{
+ ASSERT(mTexStorage);
+ return mTexStorage;
+}
-TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+Image *TextureD3D::getBaseLevelImage() const
+{
+ return getImage(getImageIndex(0, 0));
+}
+
+gl::Error TextureD3D::generateMipmaps()
+{
+ GLint mipCount = mipLevels();
+
+ if (mipCount == 1)
+ {
+ return gl::Error(GL_NO_ERROR); // no-op
+ }
+
+ // Set up proper mipmap chain in our Image array.
+ initMipmapsImages();
+
+ // We know that all layers have the same dimension, for the texture to be complete
+ GLint layerCount = static_cast<GLint>(getLayerCount(0));
+
+ // When making mipmaps with the setData workaround enabled, the texture storage has
+ // the image data already. For non-render-target storage, we have to pull it out into
+ // an image layer.
+ if (mRenderer->getWorkarounds().setDataFasterThanImageUpload && mTexStorage)
+ {
+ if (!mTexStorage->isRenderTarget())
+ {
+ // Copy from the storage mip 0 to Image mip 0
+ for (GLint layer = 0; layer < layerCount; ++layer)
+ {
+ gl::ImageIndex srcIndex = getImageIndex(0, layer);
+
+ Image *image = getImage(srcIndex);
+ gl::Rectangle area(0, 0, image->getWidth(), image->getHeight());
+ gl::Error error = image->copy(0, 0, 0, area, srcIndex, mTexStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ gl::Error error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+
+ bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget());
+
+ for (GLint layer = 0; layer < layerCount; ++layer)
+ {
+ for (GLint mip = 1; mip < mipCount; ++mip)
+ {
+ ASSERT(getLayerCount(mip) == layerCount);
+
+ gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer);
+ gl::ImageIndex destIndex = getImageIndex(mip, layer);
+
+ if (renderableStorage)
+ {
+ // GPU-side mipmapping
+ gl::Error error = mTexStorage->generateMipmap(sourceIndex, destIndex);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // CPU-side mipmapping
+ gl::Error error = mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex));
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool TextureD3D::isBaseImageZeroSize() const
+{
+ Image *baseImage = getBaseLevelImage();
+
+ if (!baseImage || baseImage->getWidth() <= 0)
+ {
+ return true;
+ }
+
+ if (!gl::IsCubemapTextureTarget(baseImage->getTarget()) && baseImage->getHeight() <= 0)
+ {
+ return true;
+ }
+
+ if (baseImage->getTarget() == GL_TEXTURE_3D && baseImage->getDepth() <= 0)
+ {
+ return true;
+ }
+
+ if (baseImage->getTarget() == GL_TEXTURE_2D_ARRAY && getLayerCount(0) <= 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+gl::Error TextureD3D::ensureRenderTarget()
+{
+ gl::Error error = initializeStorage(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!isBaseImageZeroSize())
+ {
+ ASSERT(mTexStorage);
+ if (!mTexStorage->isRenderTarget())
+ {
+ TextureStorage *newRenderTargetStorage = NULL;
+ error = createCompleteStorage(true, &newRenderTargetStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = mTexStorage->copyToStorage(newRenderTargetStorage);
+ if (error.isError())
+ {
+ SafeDelete(newRenderTargetStorage);
+ return error;
+ }
+
+ error = setCompleteTexStorage(newRenderTargetStorage);
+ if (error.isError())
+ {
+ SafeDelete(newRenderTargetStorage);
+ return error;
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
+{
+ Image *image = getImage(index);
+ bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
+ return (image->isRenderableFormat() && levelsComplete);
+}
+
+gl::Error TextureD3D::commitRegion(const gl::ImageIndex &index, const gl::Box &region)
+{
+ if (mTexStorage)
+ {
+ ASSERT(isValidIndex(index));
+ Image *image = getImage(index);
+ ImageD3D *imageD3D = ImageD3D::makeImageD3D(image);
+ gl::Error error = imageD3D->copyToStorage(mTexStorage, index, region);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ image->markClean();
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
@@ -292,7 +591,9 @@ bool TextureD3D_2D::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
@@ -302,142 +603,209 @@ void TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei
redefineImage(level, sizedInternalFormat, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
// Attempt a fast gpu copy of the pixel data to the surface
if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
{
- gl::ImageIndex index = gl::ImageIndex::Make2D(level);
-
// Will try to create RT storage if it does not exist
- RenderTarget *destRenderTarget = getRenderTarget(index);
+ RenderTarget *destRenderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
- if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
+ error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
-
- fastUnpacked = true;
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
if (!fastUnpacked)
{
- TextureD3D::setImage(unpack, type, pixels, mImageArray[level]);
+ gl::Error error = TextureD3D::setImage(unpack, type, pixels, index);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height);
- TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
}
-void TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
bool fastUnpacked = false;
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
{
- RenderTarget *renderTarget = getRenderTarget(index);
- gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
-
- if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget))
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &renderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
+ return error;
+ }
- fastUnpacked = true;
+ error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget);
+ if (error.isError())
+ {
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
- if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
+ if (!fastUnpacked)
{
- commitRect(level, xoffset, yoffset, width, height);
+ return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type,
+ unpack, pixels, index);
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
- if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[level]);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, width, height);
+ return error;
}
+
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box region(xoffset, yoffset, 0, width, height, 1);
+ return commitRegion(index, region);
}
-void TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
+ gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(level, sizedInternalFormat, width, height);
- if (!mImageArray[level]->isRenderableFormat())
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[level]->copy(0, 0, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[level]->copy(0, 0, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
mImageArray[level]->markClean();
if (width != 0 && height != 0 && isValidLevel(level))
{
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
-
- mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
+ gl::Error error = mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D && zoffset == 0);
// can only make our texture storage to a render target if level 0 is defined (with a width & height) and
// the current level we're copying to is defined (with appropriate format, width & height)
- bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
- if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidLevel(level))
{
- updateStorageLevel(level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageLevel(level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImage2D(source, sourceRect,
- gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, mTexStorage, level);
+ error = mRenderer->copyImage2D(source, sourceRect,
+ gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ xoffset, yoffset, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(target == GL_TEXTURE_2D && depth == 1);
@@ -453,11 +821,20 @@ void TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat
mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2D::bindTexImage(egl::Surface *surface)
@@ -489,7 +866,7 @@ void TextureD3D_2D::releaseTexImage()
}
}
-void TextureD3D_2D::generateMipmaps()
+void TextureD3D_2D::initMipmapsImages()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
@@ -499,42 +876,32 @@ void TextureD3D_2D::generateMipmaps()
std::max(getBaseLevelWidth() >> level, 1),
std::max(getBaseLevelHeight() >> level, 1));
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
- for (int level = 1; level < levelCount; level++)
- {
- mImageArray[level]->markClean();
- }
- }
- else
- {
- for (int level = 1; level < levelCount; level++)
- {
- mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
- }
- }
}
unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
{
ASSERT(!index.hasLayer());
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(!index.hasLayer());
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = updateStorageLevel(index.mipIndex);
+ if (error.isError())
{
- return NULL;
+ return error;
}
- updateStorageLevel(index.mipIndex);
- return mTexStorage->getRenderTarget(index);
+ return mTexStorage->getRenderTarget(index, outRT);
}
bool TextureD3D_2D::isValidLevel(int level) const
@@ -586,31 +953,55 @@ bool TextureD3D_2D::isLevelComplete(int level) const
return true;
}
+bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.mipIndex);
+}
+
// Constructs a native texture resource from the texture images
-void TextureD3D_2D::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_2D::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
@@ -621,26 +1012,35 @@ TextureStorage *TextureD3D_2D::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
- return mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
+ // TODO(geofflang): Determine if the texture creation succeeded
+ *outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
- SafeDelete(mTexStorage);
- mTexStorage = newCompleteTexStorage;
-
- if (mTexStorage && mTexStorage->isManaged())
+ if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
{
- for (int level = 0; level < mTexStorage->getLevelCount(); level++)
+ for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
{
- mImageArray[level]->setManagedSurface2D(mTexStorage, level);
+ gl::Error error = mImageArray[level]->setManagedSurface2D(newCompleteTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+ SafeDelete(mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+
mDirtyImages = true;
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::updateStorage()
+gl::Error TextureD3D_2D::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -648,54 +1048,34 @@ void TextureD3D_2D::updateStorage()
{
if (mImageArray[level]->isDirty() && isLevelComplete(level))
{
- updateStorageLevel(level);
- }
- }
-}
-
-bool TextureD3D_2D::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTarget2D(newRenderTargetStorage, mTexStorage))
+ gl::Error error = updateStorageLevel(level);
+ if (error.isError())
{
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-TextureStorage *TextureD3D_2D::getBaseLevelStorage()
-{
- return mTexStorage;
+ return gl::Error(GL_NO_ERROR);
}
-const ImageD3D *TextureD3D_2D::getBaseLevelImage() const
-{
- return mImageArray[0];
-}
-
-void TextureD3D_2D::updateStorageLevel(int level)
+gl::Error TextureD3D_2D::updateStorageLevel(int level)
{
ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
ASSERT(isLevelComplete(level));
if (mImageArray[level]->isDirty())
{
- commitRect(level, 0, 0, getWidth(level), getHeight(level));
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
@@ -727,22 +1107,25 @@ void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei wi
}
}
-void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::ImageIndexIterator TextureD3D_2D::imageIterator() const
{
- if (isValidLevel(level))
- {
- ImageD3D *image = mImageArray[level];
- if (image->copyToStorage2D(mTexStorage, level, xoffset, yoffset, width, height))
- {
- image->markClean();
- }
- }
+ return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
+}
+
+gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // "layer" does not apply to 2D Textures.
+ return gl::ImageIndex::Make2D(mip);
}
+bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.type == GL_TEXTURE_2D &&
+ index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
+}
-TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+TextureD3D_Cube::TextureD3D_Cube(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int i = 0; i < 6; i++)
{
@@ -802,19 +1185,23 @@ bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
}
-void TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(depth == 1);
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- redefineImage(faceIndex, level, sizedInternalFormat, width, height);
+ redefineImage(index.layerIndex, level, sizedInternalFormat, width, height);
- TextureD3D::setImage(unpack, type, pixels, mImageArray[faceIndex][level]);
+ return TextureD3D::setImage(unpack, type, pixels, index);
}
-void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1);
@@ -823,101 +1210,129 @@ void TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum form
redefineImage(faceIndex, level, format, width, height);
- TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[faceIndex][level]);
}
-void TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1 && zoffset == 0);
-
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
-
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
- {
- commitRect(faceIndex, level, xoffset, yoffset, width, height);
- }
+ return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index);
}
-void TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(depth == 1 && zoffset == 0);
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[index.layerIndex][level]);
+ if (error.isError())
{
- commitRect(faceIndex, level, xoffset, yoffset, width, height);
+ return error;
}
+
+ gl::Box region(xoffset, yoffset, 0, width, height, 1);
+ return commitRegion(index, region);
}
-void TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
+ GLsizei width, GLsizei height, gl::Framebuffer *source)
{
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(faceIndex, level, sizedInternalFormat, width, height);
- if (!mImageArray[faceIndex][level]->isRenderableFormat())
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
mImageArray[faceIndex][level]->markClean();
ASSERT(width == height);
if (width > 0 && isValidFaceLevel(faceIndex, level))
{
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
-
- mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+ error = mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
- // We can only make our texture storage to a render target if the level we're copying *to* is complete
- // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot
- // rely on the "getBaseLevel*" methods reliably otherwise.
- bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete();
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ if (!canCreateRenderTargetForImage(index))
{
- mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
+ gl::Error error =mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidFaceLevel(faceIndex, level))
{
- updateStorageFaceLevel(faceIndex, level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageFaceLevel(faceIndex, level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, mTexStorage, target, level);
+ error = mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ xoffset, yoffset, mTexStorage, target, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(width == height);
ASSERT(depth == 1);
@@ -939,11 +1354,20 @@ void TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalform
}
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorageCube(internalformat, renderTarget, width, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -984,7 +1408,7 @@ void TextureD3D_Cube::releaseTexImage()
}
-void TextureD3D_Cube::generateMipmaps()
+void TextureD3D_Cube::initMipmapsImages()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
@@ -996,74 +1420,76 @@ void TextureD3D_Cube::generateMipmaps()
redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
}
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < levelCount; level++)
- {
- mImageArray[faceIndex][level]->markClean();
- }
- }
- }
- else
- {
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < levelCount; level++)
- {
- mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
- }
- }
- }
}
unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(gl::IsCubemapTextureTarget(index.type));
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = updateStorageFaceLevel(index.layerIndex, index.mipIndex);
+ if (error.isError())
{
- return NULL;
+ return error;
}
- updateStorageFaceLevel(index.layerIndex, index.mipIndex);
- return mTexStorage->getRenderTarget(index);
+ return mTexStorage->getRenderTarget(index, outRT);
}
-void TextureD3D_Cube::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_Cube::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isFaceLevelComplete(0, 0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const
{
GLsizei size = getBaseLevelWidth();
@@ -1072,29 +1498,37 @@ TextureStorage *TextureD3D_Cube::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
- return mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
+ // TODO (geofflang): detect if storage creation succeeded
+ *outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
- SafeDelete(mTexStorage);
- mTexStorage = newCompleteTexStorage;
-
- if (mTexStorage && mTexStorage->isManaged())
+ if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
{
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- for (int level = 0; level < mTexStorage->getLevelCount(); level++)
+ for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
{
- mImageArray[faceIndex][level]->setManagedSurfaceCube(mTexStorage, faceIndex, level);
+ gl::Error error = mImageArray[faceIndex][level]->setManagedSurfaceCube(newCompleteTexStorage, faceIndex, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+ SafeDelete(mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+
mDirtyImages = true;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::updateStorage()
+gl::Error TextureD3D_Cube::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -1104,46 +1538,16 @@ void TextureD3D_Cube::updateStorage()
{
if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
{
- updateStorageFaceLevel(face, level);
- }
- }
- }
-}
-
-bool TextureD3D_Cube::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTargetCube(newRenderTargetStorage, mTexStorage))
- {
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ gl::Error error = updateStorageFaceLevel(face, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-TextureStorage *TextureD3D_Cube::getBaseLevelStorage()
-{
- return mTexStorage;
-}
-
-const ImageD3D *TextureD3D_Cube::getBaseLevelImage() const
-{
- // Note: if we are not cube-complete, there is no single base level image that can describe all
- // cube faces, so this method is only well-defined for a cube-complete base level.
- return mImageArray[0][0];
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
@@ -1191,15 +1595,29 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
return true;
}
-void TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
+bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isFaceLevelComplete(index.layerIndex, index.mipIndex);
+}
+
+gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
{
ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
ImageD3D *image = mImageArray[faceIndex][level];
if (image->isDirty())
{
- commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight());
+ GLenum faceTarget = gl::TextureCubeMap::layerIndexToTarget(faceIndex);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level);
+ gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
@@ -1235,20 +1653,25 @@ void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalf
}
}
-void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
{
- if (isValidFaceLevel(faceIndex, level))
- {
- ImageD3D *image = mImageArray[faceIndex][level];
- if (image->copyToStorageCube(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
- image->markClean();
- }
+ return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
}
+gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const
+{
+ // The "layer" of the image index corresponds to the cube face
+ return gl::ImageIndex::MakeCube(gl::TextureCubeMap::layerIndexToTarget(layer), mip);
+}
-TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && gl::IsCubemapTextureTarget(index.type) &&
+ index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
+}
+
+TextureD3D_3D::TextureD3D_3D(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
@@ -1327,7 +1750,9 @@ bool TextureD3D_3D::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
@@ -1336,40 +1761,60 @@ void TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei
bool fastUnpacked = false;
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, sizedInternalFormat))
{
// Will try to create RT storage if it does not exist
- gl::ImageIndex index = gl::ImageIndex::Make3D(level);
- RenderTarget *destRenderTarget = getRenderTarget(index);
+ RenderTarget *destRenderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
- if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
+ error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
-
- fastUnpacked = true;
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
if (!fastUnpacked)
{
- TextureD3D::setImage(unpack, type, pixels, mImageArray[level]);
+ gl::Error error = TextureD3D::setImage(unpack, type, pixels, index);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height,GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height, depth);
- TextureD3D::setCompressedImage(imageSize, pixels, mImageArray[level]);
+ return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
}
-void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
@@ -1380,74 +1825,108 @@ void TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yo
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, getInternalFormat(level)))
{
- RenderTarget *destRenderTarget = getRenderTarget(index);
- gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
-
- if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget))
+ RenderTarget *destRenderTarget = NULL;
+ gl::Error error = getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
+ return error;
+ }
- fastUnpacked = true;
+ gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
+ error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget);
+ if (error.isError())
+ {
+ return error;
}
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[level]->markClean();
+
+ fastUnpacked = true;
}
- if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index))
+ if (!fastUnpacked)
{
- commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
+ return TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type,
+ unpack, pixels, index);
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
- if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth,
+ format, imageSize, unpack, pixels, mImageArray[level]);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
+ return error;
}
+
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ gl::Box region(xoffset, yoffset, zoffset, width, height, depth);
+ return commitRegion(index, region);
}
-void TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
+ GLsizei width, GLsizei height, gl::Framebuffer *source)
{
UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented.");
}
-void TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_3D);
- // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
- // the current level we're copying to is defined (with appropriate format, width & height)
- bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
- if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ if (canCreateRenderTargetForImage(index))
{
- mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source);
+ gl::Error error = mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidLevel(level))
{
- updateStorageLevel(level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageLevel(level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImage3D(source, sourceRect,
- gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, zoffset, mTexStorage, level);
+ error = mRenderer->copyImage3D(source, sourceRect,
+ gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ xoffset, yoffset, zoffset, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(target == GL_TEXTURE_3D);
@@ -1464,11 +1943,20 @@ void TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat
mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true);
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_3D::bindTexImage(egl::Surface *surface)
@@ -1482,7 +1970,7 @@ void TextureD3D_3D::releaseTexImage()
}
-void TextureD3D_3D::generateMipmaps()
+void TextureD3D_3D::initMipmapsImages()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
@@ -1493,74 +1981,85 @@ void TextureD3D_3D::generateMipmaps()
std::max(getBaseLevelHeight() >> level, 1),
std::max(getBaseLevelDepth() >> level, 1));
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
-
- for (int level = 1; level < levelCount; level++)
- {
- mImageArray[level]->markClean();
- }
- }
- else
- {
- for (int level = 1; level < levelCount; level++)
- {
- mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
- }
- }
}
unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
{
- return NULL;
+ return error;
}
if (index.hasLayer())
{
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
else
{
- updateStorageLevel(index.mipIndex);
+ error = updateStorageLevel(index.mipIndex);
+ if (error.isError())
+ {
+ return error;
+ }
}
- return mTexStorage->getRenderTarget(index);
+ return mTexStorage->getRenderTarget(index, outRT);
}
-void TextureD3D_3D::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_3D::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
@@ -1572,10 +2071,13 @@ TextureStorage *TextureD3D_3D::createCompleteStorage(bool renderTarget) const
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
- return mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
+ // TODO: Verify creation of the storage succeeded
+ *outStorage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
@@ -1583,9 +2085,11 @@ void TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
// We do not support managed 3D storage, as that is D3D9/ES2-only
ASSERT(!mTexStorage->isManaged());
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::updateStorage()
+gl::Error TextureD3D_3D::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -1593,43 +2097,15 @@ void TextureD3D_3D::updateStorage()
{
if (mImageArray[level]->isDirty() && isLevelComplete(level))
{
- updateStorageLevel(level);
- }
- }
-}
-
-bool TextureD3D_3D::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTarget3D(newRenderTargetStorage, mTexStorage))
+ gl::Error error = updateStorageLevel(level);
+ if (error.isError())
{
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-TextureStorage *TextureD3D_3D::getBaseLevelStorage()
-{
- return mTexStorage;
-}
-
-const ImageD3D *TextureD3D_3D::getBaseLevelImage() const
-{
- return mImageArray[0];
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D_3D::isValidLevel(int level) const
@@ -1685,15 +2161,28 @@ bool TextureD3D_3D::isLevelComplete(int level) const
return true;
}
-void TextureD3D_3D::updateStorageLevel(int level)
+bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.mipIndex);
+}
+
+gl::Error TextureD3D_3D::updateStorageLevel(int level)
{
ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
ASSERT(isLevelComplete(level));
if (mImageArray[level]->isDirty())
{
- commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
@@ -1727,22 +2216,26 @@ void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei wi
}
}
-void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
+gl::ImageIndexIterator TextureD3D_3D::imageIterator() const
{
- if (isValidLevel(level))
- {
- ImageD3D *image = mImageArray[level];
- if (image->copyToStorage3D(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
- {
- image->markClean();
- }
- }
+ return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(),
+ gl::ImageIndex::ENTIRE_LEVEL, gl::ImageIndex::ENTIRE_LEVEL);
}
+gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // The "layer" here does not apply to 3D images. We use one Image per mip.
+ return gl::ImageIndex::Make3D(mip);
+}
-TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
- : TextureD3D(renderer),
- mTexStorage(NULL)
+bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.type == GL_TEXTURE_3D &&
+ index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
+}
+
+TextureD3D_2DArray::TextureD3D_2DArray(RendererD3D *renderer)
+ : TextureD3D(renderer)
{
for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
{
@@ -1791,11 +2284,6 @@ GLsizei TextureD3D_2DArray::getHeight(GLint level) const
return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0;
}
-GLsizei TextureD3D_2DArray::getLayers(GLint level) const
-{
- return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mLayerCounts[level] : 0;
-}
-
GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const
{
return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE;
@@ -1806,7 +2294,9 @@ bool TextureD3D_2DArray::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
+ const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1820,11 +2310,20 @@ void TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLs
for (int i = 0; i < depth; i++)
{
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- TextureD3D::setImage(unpack, type, layerPixels, mImageArray[level][i]);
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i);
+ gl::Error error = TextureD3D::setImage(unpack, type, layerPixels, index);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1837,11 +2336,19 @@ void TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum f
for (int i = 0; i < depth; i++)
{
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- TextureD3D::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]);
+ gl::Error error = TextureD3D::setCompressedImage(unpack, imageSize, layerPixels, mImageArray[level][i]);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1854,14 +2361,20 @@ void TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLi
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
- if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, index))
+ gl::Error error = TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type,
+ unpack, layerPixels, index);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, layer, width, height);
+ return error;
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
+gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1873,52 +2386,75 @@ void TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xo
int layer = zoffset + i;
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- if (TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer]))
+ gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, unpack, layerPixels, mImageArray[level][layer]);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Box region(xoffset, yoffset, 0, width, height, 1);
+ error = commitRegion(index, region);
+ if (error.isError())
{
- commitRect(level, xoffset, yoffset, layer, width, height);
+ return error;
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented.");
}
-void TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
- // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
- // the current level we're copying to is defined (with appropriate format, width & height)
- bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
+ gl::Rectangle sourceRect(x, y, width, height);
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zoffset);
- if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
+ if (canCreateRenderTargetForImage(index))
{
- mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source);
+ gl::Error error = mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
mDirtyImages = true;
}
else
{
- ensureRenderTarget();
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
+ {
+ return error;
+ }
if (isValidLevel(level))
{
- updateStorageLevel(level);
-
- gl::Rectangle sourceRect;
- sourceRect.x = x;
- sourceRect.width = width;
- sourceRect.y = y;
- sourceRect.height = height;
+ error = updateStorageLevel(level);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
- xoffset, yoffset, zoffset, mTexStorage, level);
+ error = mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
+ xoffset, yoffset, zoffset, mTexStorage, level);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
@@ -1945,11 +2481,20 @@ void TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalf
}
}
- mImmutable = true;
-
+ // TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels);
- setCompleteTexStorage(storage);
+
+ gl::Error error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
+ mImmutable = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2DArray::bindTexImage(egl::Surface *surface)
@@ -1963,7 +2508,7 @@ void TextureD3D_2DArray::releaseTexImage()
}
-void TextureD3D_2DArray::generateMipmaps()
+void TextureD3D_2DArray::initMipmapsImages()
{
int baseWidth = getBaseLevelWidth();
int baseHeight = getBaseLevelHeight();
@@ -1976,76 +2521,78 @@ void TextureD3D_2DArray::generateMipmaps()
{
redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
}
-
- if (mTexStorage && mTexStorage->isRenderTarget())
- {
- mTexStorage->generateMipmaps();
-
- for (int level = 1; level < levelCount; level++)
- {
- for (int layer = 0; layer < mLayerCounts[level]; layer++)
- {
- mImageArray[level][layer]->markClean();
- }
- }
- }
- else
- {
- for (int level = 1; level < levelCount; level++)
- {
- for (int layer = 0; layer < mLayerCounts[level]; layer++)
- {
- mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]);
- }
- }
- }
}
unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-RenderTarget *TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
// ensure the underlying texture is created
- if (!ensureRenderTarget())
+ gl::Error error = ensureRenderTarget();
+ if (error.isError())
{
- return NULL;
+ return error;
}
- updateStorageLevel(index.mipIndex);
- return mTexStorage->getRenderTarget(index);
+ error = updateStorageLevel(index.mipIndex);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return mTexStorage->getRenderTarget(index, outRT);
}
-void TextureD3D_2DArray::initializeStorage(bool renderTarget)
+gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget)
{
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
// do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
- setCompleteTexStorage(createCompleteStorage(createRenderTarget));
+ TextureStorage *storage = NULL;
+ gl::Error error = createCompleteStorage(createRenderTarget, &storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setCompleteTexStorage(storage);
+ if (error.isError())
+ {
+ SafeDelete(storage);
+ return error;
+ }
+
ASSERT(mTexStorage);
// flush image data to the storage
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) const
+gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
- GLsizei depth = getLayers(0);
+ GLsizei depth = getLayerCount(0);
GLenum internalFormat = getBaseLevelInternalFormat();
ASSERT(width > 0 && height > 0 && depth > 0);
@@ -2053,10 +2600,13 @@ TextureStorage *TextureD3D_2DArray::createCompleteStorage(bool renderTarget) con
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
- return mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
+ // TODO(geofflang): Verify storage creation succeeds
+ *outStorage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels);
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
+gl::Error TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage)
{
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
@@ -2064,9 +2614,11 @@ void TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexSto
// We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
ASSERT(!mTexStorage->isManaged());
+
+ return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2DArray::updateStorage()
+gl::Error TextureD3D_2DArray::updateStorage()
{
ASSERT(mTexStorage != NULL);
GLint storageLevels = mTexStorage->getLevelCount();
@@ -2074,43 +2626,15 @@ void TextureD3D_2DArray::updateStorage()
{
if (isLevelComplete(level))
{
- updateStorageLevel(level);
- }
- }
-}
-
-bool TextureD3D_2DArray::ensureRenderTarget()
-{
- initializeStorage(true);
-
- if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0)
- {
- ASSERT(mTexStorage);
- if (!mTexStorage->isRenderTarget())
- {
- TextureStorage *newRenderTargetStorage = createCompleteStorage(true);
-
- if (!mRenderer->copyToRenderTarget2DArray(newRenderTargetStorage, mTexStorage))
+ gl::Error error = updateStorageLevel(level);
+ if (error.isError())
{
- delete newRenderTargetStorage;
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- setCompleteTexStorage(newRenderTargetStorage);
}
}
- return (mTexStorage && mTexStorage->isRenderTarget());
-}
-
-const ImageD3D *TextureD3D_2DArray::getBaseLevelImage() const
-{
- return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL);
-}
-
-TextureStorage *TextureD3D_2DArray::getBaseLevelStorage()
-{
- return mTexStorage;
+ return gl::Error(GL_NO_ERROR);
}
bool TextureD3D_2DArray::isValidLevel(int level) const
@@ -2129,7 +2653,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
- GLsizei layers = getLayers(0);
+ GLsizei layers = getLayerCount(0);
if (width <= 0 || height <= 0 || layers <= 0)
{
@@ -2156,7 +2680,7 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
return false;
}
- if (getLayers(level) != layers)
+ if (getLayerCount(level) != layers)
{
return false;
}
@@ -2164,7 +2688,12 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
return true;
}
-void TextureD3D_2DArray::updateStorageLevel(int level)
+bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.mipIndex);
+}
+
+gl::Error TextureD3D_2DArray::updateStorageLevel(int level)
{
ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
ASSERT(isLevelComplete(level));
@@ -2174,9 +2703,17 @@ void TextureD3D_2DArray::updateStorageLevel(int level)
ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL);
if (mImageArray[level][layer]->isDirty())
{
- commitRect(level, 0, 0, layer, getWidth(level), getHeight(level));
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
+ gl::Error error = commitRegion(index, region);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
void TextureD3D_2DArray::deleteImages()
@@ -2198,7 +2735,7 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz
// If there currently is a corresponding storage texture image, it has these parameters
const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
- const int storageDepth = getLayers(0);
+ const int storageDepth = getLayerCount(0);
const GLenum storageFormat = getBaseLevelInternalFormat();
for (int layer = 0; layer < mLayerCounts[level]; layer++)
@@ -2245,16 +2782,32 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz
}
}
-void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height)
+gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts);
+}
+
+gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const
+{
+ return gl::ImageIndex::Make2DArray(mip, layer);
+}
+
+bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const
{
- if (isValidLevel(level) && layerTarget < getLayers(level))
+ // Check for having a storage and the right type of index
+ if (!mTexStorage || index.type != GL_TEXTURE_2D_ARRAY)
{
- ImageD3D *image = mImageArray[level][layerTarget];
- if (image->copyToStorage2DArray(mTexStorage, level, xoffset, yoffset, layerTarget, width, height))
- {
- image->markClean();
- }
+ return false;
}
+
+ // Check the mip index
+ if (index.mipIndex < 0 || index.mipIndex >= mTexStorage->getLevelCount())
+ {
+ return false;
+ }
+
+ // Check the layer index
+ return (!index.hasLayer() || (index.layerIndex >= 0 && index.layerIndex < mLayerCounts[index.mipIndex]));
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
index 41c73180de..083a6335b9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -11,7 +11,7 @@
#include "libGLESv2/renderer/TextureImpl.h"
#include "libGLESv2/angletypes.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
namespace gl
{
@@ -23,19 +23,19 @@ namespace rx
class Image;
class ImageD3D;
-class Renderer;
+class RendererD3D;
class RenderTarget;
class TextureStorage;
class TextureD3D : public TextureImpl
{
public:
- TextureD3D(Renderer *renderer);
+ TextureD3D(RendererD3D *renderer);
virtual ~TextureD3D();
static TextureD3D *makeTextureD3D(TextureImpl *texture);
- virtual TextureStorage *getNativeTexture();
+ TextureStorage *getNativeTexture();
virtual void setUsage(GLenum usage) { mUsage = usage; }
bool hasDirtyImages() const { return mDirtyImages; }
@@ -48,45 +48,68 @@ class TextureD3D : public TextureImpl
bool isImmutable() const { return mImmutable; }
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0;
+ // Returns an iterator over all "Images" for this particular Texture.
+ virtual gl::ImageIndexIterator imageIterator() const = 0;
+
+ // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for
+ // slices of their depth texures, so 3D textures ignore the layer parameter.
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const = 0;
+
+ virtual gl::Error generateMipmaps();
+ TextureStorage *getStorage();
+ Image *getBaseLevelImage() const;
+
protected:
- void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image);
- bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
- void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
- bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const void *pixels, Image *image);
+ gl::Error setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index);
+ gl::Error subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
+ gl::Error setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image);
+ gl::Error subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image);
bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat);
- bool fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
- GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
+ gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
+ GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
int mipLevels() const;
+ virtual void initMipmapsImages() = 0;
+ bool isBaseImageZeroSize() const;
+ virtual bool isImageComplete(const gl::ImageIndex &index) const = 0;
- Renderer *mRenderer;
+ bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const;
+ virtual gl::Error ensureRenderTarget();
+
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const = 0;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage) = 0;
+ gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box &region);
+
+ RendererD3D *mRenderer;
GLenum mUsage;
bool mDirtyImages;
bool mImmutable;
+ TextureStorage *mTexStorage;
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D);
- virtual void initializeStorage(bool renderTarget) = 0;
+ virtual gl::Error initializeStorage(bool renderTarget) = 0;
- virtual void updateStorage() = 0;
- virtual TextureStorage *getBaseLevelStorage() = 0;
- virtual const ImageD3D *getBaseLevelImage() const = 0;
+ virtual gl::Error updateStorage() = 0;
+
+ bool shouldUseSetData(const Image *image) const;
};
class TextureD3D_2D : public TextureD3D
{
public:
- TextureD3D_2D(Renderer *renderer);
+ TextureD3D_2D(RendererD3D *renderer);
virtual ~TextureD3D_2D();
virtual Image *getImage(int level, int layer) const;
@@ -99,50 +122,49 @@ class TextureD3D_2D : public TextureD3D
GLenum getActualFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
- void updateStorageLevel(int level);
+ gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
- void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- TextureStorage *mTexStorage;
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureD3D_Cube : public TextureD3D
{
public:
- TextureD3D_Cube(Renderer *renderer);
+ TextureD3D_Cube(RendererD3D *renderer);
virtual ~TextureD3D_Cube();
virtual Image *getImage(int level, int layer) const;
@@ -156,51 +178,49 @@ class TextureD3D_Cube : public TextureD3D
GLenum getInternalFormat(GLint level, GLint layer) const;
bool isDepth(GLint level, GLint layer) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidFaceLevel(int faceIndex, int level) const;
bool isFaceLevelComplete(int faceIndex, int level) const;
bool isCubeComplete() const;
- void updateStorageFaceLevel(int faceIndex, int level);
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
+ gl::Error updateStorageFaceLevel(int faceIndex, int level);
void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
- void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
- TextureStorage *mTexStorage;
};
class TextureD3D_3D : public TextureD3D
{
public:
- TextureD3D_3D(Renderer *renderer);
+ TextureD3D_3D(RendererD3D *renderer);
virtual ~TextureD3D_3D();
virtual Image *getImage(int level, int layer) const;
@@ -213,50 +233,48 @@ class TextureD3D_3D : public TextureD3D
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
- void updateStorageLevel(int level);
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
+ gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
- TextureStorage *mTexStorage;
};
class TextureD3D_2DArray : public TextureD3D
{
public:
- TextureD3D_2DArray(Renderer *renderer);
+ TextureD3D_2DArray(RendererD3D *renderer);
virtual ~TextureD3D_2DArray();
virtual Image *getImage(int level, int layer) const;
@@ -265,45 +283,44 @@ class TextureD3D_2DArray : public TextureD3D
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
- GLsizei getLayers(GLint level) const;
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- virtual void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- virtual void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual void storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
+ virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual void generateMipmaps();
-
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);
- virtual void initializeStorage(bool renderTarget);
- TextureStorage *createCompleteStorage(bool renderTarget) const;
- void setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
+ virtual gl::Error initializeStorage(bool renderTarget);
+ virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
+ virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
- virtual void updateStorage();
- bool ensureRenderTarget();
- virtual TextureStorage *getBaseLevelStorage();
- virtual const ImageD3D *getBaseLevelImage() const;
+ virtual gl::Error updateStorage();
+ virtual void initMipmapsImages();
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
- void updateStorageLevel(int level);
+ virtual bool isImageComplete(const gl::ImageIndex &index) const;
+ gl::Error updateStorageLevel(int level);
void deleteImages();
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
- void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
// Storing images as an array of single depth textures since D3D11 treats each array level of a
// Texture2D object as a separate subresource. Each layer would have to be looped over
@@ -311,8 +328,6 @@ class TextureD3D_2DArray : public TextureD3D
// sense for the Image class to not have to worry about layer subresource as well as mip subresources.
GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
- TextureStorage *mTexStorage;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
index dedd266c09..320b74b8ed 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
@@ -8,6 +8,7 @@
#include "libGLESv2/renderer/d3d/TextureStorage.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
+#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h"
@@ -18,17 +19,14 @@
namespace rx
{
-unsigned int TextureStorage::mCurrentTextureSerial = 1;
-
TextureStorage::TextureStorage()
- : mTextureSerial(issueTextureSerial()),
- mFirstRenderTargetSerial(0),
+ : mFirstRenderTargetSerial(0),
mRenderTargetSerialsLayerStride(0)
{}
void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride)
{
- mFirstRenderTargetSerial = gl::RenderbufferStorage::issueSerials(rtSerialsToReserve);
+ mFirstRenderTargetSerial = RenderTarget::issueSerials(rtSerialsToReserve);
mRenderTargetSerialsLayerStride = rtSerialsLayerStride;
}
@@ -38,14 +36,4 @@ unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index)
return mFirstRenderTargetSerial + static_cast<unsigned int>(index.mipIndex) + layerOffset;
}
-unsigned int TextureStorage::getTextureSerial() const
-{
- return mTextureSerial;
-}
-
-unsigned int TextureStorage::issueTextureSerial()
-{
- return mCurrentTextureSerial++;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
index 9cc2c2977b..da92be3c74 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
@@ -9,20 +9,26 @@
#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#include "libGLESv2/Error.h"
+
#include "common/debug.h"
+#include "libGLESv2/Error.h"
#include <GLES2/gl2.h>
+#include <cstdint>
namespace gl
{
struct ImageIndex;
+struct Box;
+struct PixelUnpackState;
}
namespace rx
{
-class Renderer;
class SwapChain;
class RenderTarget;
+class Image;
class TextureStorage
{
@@ -35,8 +41,12 @@ class TextureStorage
virtual bool isManaged() const = 0;
virtual int getLevelCount() const = 0;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
+
+ virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0;
+ virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0;
unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const;
unsigned int getTextureSerial() const;
@@ -47,11 +57,6 @@ class TextureStorage
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
- const unsigned int mTextureSerial;
- static unsigned int issueTextureSerial();
-
- static unsigned int mCurrentTextureSerial;
-
unsigned int mFirstRenderTargetSerial;
unsigned int mRenderTargetSerialsLayerStride;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
index 4f85eb94fa..73f0c79e19 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
@@ -9,7 +9,7 @@
#include "libGLESv2/renderer/d3d/VertexBuffer.h"
#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/VertexAttribute.h"
#include "common/mathutil.h"
@@ -38,7 +38,7 @@ unsigned int VertexBuffer::getSerial() const
return mSerial;
}
-VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
+VertexBufferInterface::VertexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer)
{
mDynamic = dynamic;
mWritePosition = 0;
@@ -127,7 +127,7 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute
mWritePosition += spaceRequired;
// Align to 16-byte boundary
- mWritePosition = rx::roundUp(mWritePosition, 16u);
+ mWritePosition = roundUp(mWritePosition, 16u);
return gl::Error(GL_NO_ERROR);
}
@@ -153,7 +153,7 @@ gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &a
mReservedSpace += requiredSpace;
// Align to 16-byte boundary
- mReservedSpace = rx::roundUp(mReservedSpace, 16u);
+ mReservedSpace = roundUp(mReservedSpace, 16u);
return gl::Error(GL_NO_ERROR);
}
@@ -197,7 +197,7 @@ bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &att
return !requiresConversion && isAligned;
}
-StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
{
setBufferSize(initialSize);
}
@@ -231,7 +231,7 @@ gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size)
return gl::Error(GL_NO_ERROR);
}
-StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
+StaticVertexBufferInterface::StaticVertexBufferInterface(RendererD3D *renderer) : VertexBufferInterface(renderer, false)
{
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
index fa747d9cb4..4b40818f8e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
@@ -26,7 +26,7 @@ struct VertexAttribCurrentValueData;
namespace rx
{
-class Renderer;
+class RendererD3D;
class VertexBuffer
{
@@ -60,7 +60,7 @@ class VertexBuffer
class VertexBufferInterface
{
public:
- VertexBufferInterface(rx::Renderer *renderer, bool dynamic);
+ VertexBufferInterface(RendererD3D *renderer, bool dynamic);
virtual ~VertexBufferInterface();
gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
@@ -90,7 +90,7 @@ class VertexBufferInterface
private:
DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
VertexBuffer* mVertexBuffer;
@@ -102,7 +102,7 @@ class VertexBufferInterface
class StreamingVertexBufferInterface : public VertexBufferInterface
{
public:
- StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize);
+ StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize);
~StreamingVertexBufferInterface();
protected:
@@ -112,7 +112,7 @@ class StreamingVertexBufferInterface : public VertexBufferInterface
class StaticVertexBufferInterface : public VertexBufferInterface
{
public:
- explicit StaticVertexBufferInterface(rx::Renderer *renderer);
+ explicit StaticVertexBufferInterface(RendererD3D *renderer);
~StaticVertexBufferInterface();
gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
index 7034b78eab..8d3df31c8b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
@@ -14,6 +14,7 @@
#include "libGLESv2/Buffer.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
+#include "libGLESv2/State.h"
namespace
{
@@ -51,7 +52,7 @@ static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int ve
return vertexDrawCount;
}
-VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
+VertexDataManager::VertexDataManager(RendererD3D *renderer) : mRenderer(renderer)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
@@ -82,8 +83,8 @@ VertexDataManager::~VertexDataManager()
}
}
-gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
- gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
+gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count,
+ TranslatedAttribute *translated, GLsizei instances)
{
if (!mStreamingBuffer)
{
@@ -93,20 +94,22 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
// Invalidate static buffers that don't contain matching attributes
for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ translated[attributeIndex].active = (state.getCurrentProgramBinary()->getSemanticIndex(attributeIndex) != -1);
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(attributeIndex);
- if (translated[attributeIndex].active && attribs[attributeIndex].enabled)
+ if (translated[attributeIndex].active && curAttrib.enabled)
{
- invalidateMatchingStaticData(attribs[attributeIndex], currentValues[attributeIndex]);
+ invalidateMatchingStaticData(curAttrib, state.getVertexAttribCurrentValue(attributeIndex));
}
}
// Reserve the required space in the buffers
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- if (translated[i].active && attribs[i].enabled)
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
+ if (translated[i].active && curAttrib.enabled)
{
- gl::Error error = reserveSpaceForAttrib(attribs[i], currentValues[i], count, instances);
+ gl::Error error = reserveSpaceForAttrib(curAttrib, state.getVertexAttribCurrentValue(i), count, instances);
if (error.isError())
{
return error;
@@ -117,12 +120,14 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
// Perform the vertex data translations
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
if (translated[i].active)
{
- if (attribs[i].enabled)
+ if (curAttrib.enabled)
{
- gl::Error error = storeAttribute(attribs[i], currentValues[i], &translated[i],
- start, count, instances);
+ gl::Error error = storeAttribute(curAttrib, state.getVertexAttribCurrentValue(i),
+ &translated[i], start, count, instances);
+
if (error.isError())
{
return error;
@@ -135,7 +140,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
}
- gl::Error error = storeCurrentValue(attribs[i], currentValues[i], &translated[i],
+ gl::Error error = storeCurrentValue(curAttrib, state.getVertexAttribCurrentValue(i), &translated[i],
&mCurrentValue[i], &mCurrentValueOffsets[i],
mCurrentValueBuffer[i]);
if (error.isError())
@@ -148,14 +153,15 @@ gl::Error VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- if (translated[i].active && attribs[i].enabled)
+ const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
+ if (translated[i].active && curAttrib.enabled)
{
- gl::Buffer *buffer = attribs[i].buffer.get();
+ gl::Buffer *buffer = curAttrib.buffer.get();
if (buffer)
{
BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
- bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(attribs[i]));
+ bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(curAttrib));
}
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
index 7728722246..64ef653221 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
@@ -16,8 +16,9 @@
namespace gl
{
-struct VertexAttribute;
class ProgramBinary;
+class State;
+struct VertexAttribute;
struct VertexAttribCurrentValueData;
}
@@ -26,7 +27,7 @@ namespace rx
class BufferD3D;
class StreamingVertexBufferInterface;
class VertexBuffer;
-class Renderer;
+class RendererD3D;
struct TranslatedAttribute
{
@@ -49,11 +50,11 @@ struct TranslatedAttribute
class VertexDataManager
{
public:
- VertexDataManager(rx::Renderer *renderer);
+ VertexDataManager(RendererD3D *renderer);
virtual ~VertexDataManager();
- gl::Error prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
- gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
+ gl::Error prepareVertexData(const gl::State &state, GLint start, GLsizei count,
+ TranslatedAttribute *outAttribs, GLsizei instances);
private:
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
@@ -80,7 +81,7 @@ class VertexDataManager
size_t *cachedOffset,
StreamingVertexBufferInterface *buffer);
- rx::Renderer *const mRenderer;
+ RendererD3D *const mRenderer;
StreamingVertexBufferInterface *mStreamingBuffer;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
index d43e65ea78..06aea9befe 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
@@ -172,7 +172,7 @@ static void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &source
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
-Blit11::Blit11(rx::Renderer11 *renderer)
+Blit11::Blit11(Renderer11 *renderer)
: mRenderer(renderer), mBlitShaderMap(compareBlitParameters), mSwizzleShaderMap(compareSwizzleParameters),
mVertexBuffer(NULL), mPointSampler(NULL), mLinearSampler(NULL), mScissorEnabledRasterizerState(NULL),
mScissorDisabledRasterizerState(NULL), mDepthStencilState(NULL),
@@ -209,7 +209,7 @@ Blit11::Blit11(rx::Renderer11 *renderer)
pointSamplerDesc.BorderColor[2] = 0.0f;
pointSamplerDesc.BorderColor[3] = 0.0f;
pointSamplerDesc.MinLOD = 0.0f;
- pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f;
+ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
ASSERT(SUCCEEDED(result));
@@ -228,7 +228,7 @@ Blit11::Blit11(rx::Renderer11 *renderer)
linearSamplerDesc.BorderColor[2] = 0.0f;
linearSamplerDesc.BorderColor[3] = 0.0f;
linearSamplerDesc.MinLOD = 0.0f;
- linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f;
+ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
ASSERT(SUCCEEDED(result));
@@ -468,8 +468,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
- ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
@@ -485,7 +484,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &source);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler);
@@ -494,7 +493,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
@@ -507,9 +506,9 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT
return gl::Error(GL_NO_ERROR);
}
-bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, GLenum destFormat, GLenum filter)
+gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, GLenum destFormat, GLenum filter)
{
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -531,7 +530,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
if (i == mBlitShaderMap.end())
{
UNREACHABLE();
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Could not find appropriate shader for internal texture blit.");
}
const Shader& shader = i->second;
@@ -541,8 +540,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
- ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result);
}
UINT stride = 0;
@@ -587,8 +585,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
- ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
@@ -604,7 +601,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &source);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
ID3D11SamplerState *sampler = NULL;
@@ -612,7 +609,10 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
{
case GL_NEAREST: sampler = mPointSampler; break;
case GL_LINEAR: sampler = mLinearSampler; break;
- default: UNREACHABLE(); return false;
+
+ default:
+ UNREACHABLE();
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal error, unknown blit filter mode.");
}
deviceContext->PSSetSamplers(0, 1, &sampler);
@@ -620,7 +620,7 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
@@ -630,21 +630,21 @@ bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &source
mRenderer->markAllStateDirty();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor)
+gl::Error Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
{
return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize,
dest, destSubresource, destArea, destSize,
scissor, true);
}
-bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor)
+gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
{
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -654,8 +654,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
- ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result);
}
UINT stride = 0;
@@ -700,8 +699,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
deviceContext->GSSetShader(NULL, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
- ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
// Apply render target
deviceContext->OMSetRenderTargets(0, NULL, dest);
@@ -717,7 +715,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &source);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source);
// Apply samplers
deviceContext->PSSetSamplers(0, 1, &mPointSampler);
@@ -726,7 +724,7 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
@@ -736,21 +734,21 @@ bool Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceAr
mRenderer->markAllStateDirty();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor)
+gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
{
return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize,
dest, destSubresource, destArea, destSize,
scissor, false);
}
-bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, bool stencilOnly)
+gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, bool stencilOnly)
{
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
@@ -764,7 +762,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso
{
SafeRelease(sourceStaging);
SafeRelease(destStaging);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging textures for depth stencil blit.");
}
DXGI_FORMAT format = GetTextureFormat(source);
@@ -785,23 +783,23 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso
dxgiFormatInfo.depthBits % 8 == 0);
}
- D3D11_MAPPED_SUBRESOURCE sourceMapping, destMapping;
- deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping);
- deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping);
+ D3D11_MAPPED_SUBRESOURCE sourceMapping;
+ HRESULT result = deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping);
+ if (FAILED(result))
+ {
+ SafeRelease(sourceStaging);
+ SafeRelease(destStaging);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.", result);
+ }
- if (!sourceMapping.pData || !destMapping.pData)
+ D3D11_MAPPED_SUBRESOURCE destMapping;
+ result = deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping);
+ if (FAILED(result))
{
- if (!sourceMapping.pData)
- {
- deviceContext->Unmap(sourceStaging, 0);
- }
- if (!destMapping.pData)
- {
- deviceContext->Unmap(destStaging, 0);
- }
+ deviceContext->Unmap(sourceStaging, 0);
SafeRelease(sourceStaging);
SafeRelease(destStaging);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal destination staging texture for depth stencil blit, HRESULT: 0x%X.", result);
}
gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
@@ -880,7 +878,7 @@ bool Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubreso
SafeRelease(sourceStaging);
SafeRelease(destStaging);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b)
@@ -1001,12 +999,12 @@ void Blit11::buildShaderMap()
add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
- add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" ));
add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" ));
- add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
+ add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" ));
add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" ));
+ add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" ));
add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" ));
add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
index d6a0b795f4..821fa9d0cc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
@@ -19,12 +19,6 @@ namespace rx
{
class Renderer11;
-enum Filter
-{
- Point,
- Linear,
-};
-
class Blit11
{
public:
@@ -34,24 +28,24 @@ class Blit11
gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size,
GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
- bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, GLenum destFormat, GLenum filter);
-
- bool copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor);
+ gl::Error copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, GLenum destFormat, GLenum filter);
- bool copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor);
-
- bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
const gl::Rectangle *scissor);
+ gl::Error copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor);
+
+ gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor);
+
private:
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
struct BlitParameters
{
@@ -60,9 +54,9 @@ class Blit11
bool m3DBlit;
};
- bool copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
- ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
- const gl::Rectangle *scissor, bool stencilOnly);
+ gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize,
+ ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize,
+ const gl::Rectangle *scissor, bool stencilOnly);
static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
index ecd4d4672b..5aab37938f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
@@ -86,7 +86,7 @@ class Buffer11::BufferStorage11
virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
size_t size, size_t destOffset) = 0;
- virtual bool resize(size_t size, bool preserveData) = 0;
+ virtual gl::Error resize(size_t size, bool preserveData) = 0;
virtual void *map(size_t offset, size_t length, GLbitfield access) = 0;
virtual void unmap() = 0;
@@ -112,17 +112,17 @@ class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11
virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
size_t size, size_t destOffset);
- virtual bool resize(size_t size, bool preserveData);
+ virtual gl::Error resize(size_t size, bool preserveData);
virtual void *map(size_t offset, size_t length, GLbitfield access);
virtual void unmap();
- bool setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset);
+ gl::Error setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset);
private:
ID3D11Buffer *mNativeBuffer;
- static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize);
+ static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize);
};
// Pack storage represents internal storage for pack buffers. We implement pack buffers
@@ -135,7 +135,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
size_t size, size_t destOffset);
- virtual bool resize(size_t size, bool preserveData);
+ virtual gl::Error resize(size_t size, bool preserveData);
virtual void *map(size_t offset, size_t length, GLbitfield access);
virtual void unmap();
@@ -144,7 +144,7 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
private:
- void flushQueuedPackCommand();
+ gl::Error flushQueuedPackCommand();
ID3D11Texture2D *mStagingTexture;
DXGI_FORMAT mTextureFormat;
@@ -195,14 +195,14 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
return error;
}
-void *Buffer11::getData()
+gl::Error Buffer11::getData(const uint8_t **outData)
{
NativeBuffer11 *stagingBuffer = getStagingBuffer();
if (!stagingBuffer)
{
// Out-of-memory
- return NULL;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get internal staging buffer.");
}
if (stagingBuffer->getDataRevision() > mResolvedDataRevision)
@@ -211,7 +211,7 @@ void *Buffer11::getData()
{
if (!mResolvedData.resize(stagingBuffer->getSize()))
{
- return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer.");
}
}
@@ -221,7 +221,7 @@ void *Buffer11::getData()
HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource);
if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result);
}
memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize());
@@ -238,13 +238,14 @@ void *Buffer11::getData()
{
if (!mResolvedData.resize(mSize))
{
- return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer.");
}
}
ASSERT(mResolvedData.size() >= mSize);
- return mResolvedData.data();
+ *outData = mResolvedData.data();
+ return gl::Error(GL_NO_ERROR);
}
gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
@@ -265,15 +266,17 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
if (stagingBuffer->getSize() < requiredSize)
{
bool preserveData = (offset > 0);
- if (!stagingBuffer->resize(requiredSize, preserveData))
+ gl::Error error = stagingBuffer->resize(requiredSize, preserveData);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer.");
+ return error;
}
}
- if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset))
+ gl::Error error = stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer.");
+ return error;
}
stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
@@ -411,7 +414,7 @@ void Buffer11::markBufferUsage()
}
}
-Renderer* Buffer11::getRenderer()
+RendererD3D* Buffer11::getRenderer()
{
return mRenderer;
}
@@ -527,7 +530,7 @@ Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage)
// resize buffer
if (directBuffer->getSize() < mSize)
{
- if (!directBuffer->resize(mSize, true))
+ if (directBuffer->resize(mSize, true).isError())
{
// Out of memory error
return NULL;
@@ -667,6 +670,9 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s
// Offset bounds are validated at the API layer
ASSERT(sourceOffset + size <= destOffset + mBufferSize);
memcpy(destPointer, sourcePointer, size);
+
+ context->Unmap(mNativeBuffer, 0);
+ source->unmap();
}
else
{
@@ -689,7 +695,7 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s
return createBuffer;
}
-bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
+gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
{
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -702,7 +708,7 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result);
}
if (mNativeBuffer && preserveData)
@@ -727,10 +733,10 @@ bool Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
mBufferSize = bufferDesc.ByteWidth;
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer,
+void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer,
BufferUsage usage, unsigned int bufferSize)
{
bufferDesc->ByteWidth = bufferSize;
@@ -748,7 +754,7 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
- if (!static_cast<Renderer11 *>(renderer)->isLevel9())
+ if (!renderer->isLevel9())
bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
bufferDesc->CPUAccessFlags = 0;
break;
@@ -797,7 +803,7 @@ void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield acc
return static_cast<GLubyte*>(mappedResource.pData) + offset;
}
-bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset)
+gl::Error Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset)
{
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -805,7 +811,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s
HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource);
if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result);
}
uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset;
@@ -813,7 +819,7 @@ bool Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, s
context->Unmap(mNativeBuffer, 0);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
void Buffer11::NativeBuffer11::unmap()
@@ -847,18 +853,18 @@ bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t so
return false;
}
-bool Buffer11::PackStorage11::resize(size_t size, bool preserveData)
+gl::Error Buffer11::PackStorage11::resize(size_t size, bool preserveData)
{
if (size != mBufferSize)
{
if (!mMemoryBuffer.resize(size))
{
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer storage.");
}
mBufferSize = size;
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access)
@@ -869,7 +875,12 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce
// and if D3D packs the staging texture memory identically to how we would fill
// the pack buffer according to the current pack state.
- flushQueuedPackCommand();
+ gl::Error error = flushQueuedPackCommand();
+ if (error.isError())
+ {
+ return NULL;
+ }
+
mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
return mMemoryBuffer.data() + offset;
@@ -882,7 +893,12 @@ void Buffer11::PackStorage11::unmap()
gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
{
- flushQueuedPackCommand();
+ gl::Error error = flushQueuedPackCommand();
+ if (error.isError())
+ {
+ return error;
+ }
+
mQueuedPackCommand = new PackPixelsParams(params);
D3D11_TEXTURE2D_DESC textureDesc;
@@ -947,15 +963,21 @@ gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT s
return gl::Error(GL_NO_ERROR);
}
-void Buffer11::PackStorage11::flushQueuedPackCommand()
+gl::Error Buffer11::PackStorage11::flushQueuedPackCommand()
{
ASSERT(mMemoryBuffer.size() > 0);
if (mQueuedPackCommand)
{
- mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
+ gl::Error error = mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data());
SafeDelete(mQueuedPackCommand);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
index 5f24fb4e2d..1c06bbf88a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
@@ -47,7 +47,7 @@ typedef size_t DataRevision;
class Buffer11 : public BufferD3D
{
public:
- Buffer11(rx::Renderer11 *renderer);
+ Buffer11(Renderer11 *renderer);
virtual ~Buffer11();
static Buffer11 *makeBuffer11(BufferImpl *buffer);
@@ -60,11 +60,11 @@ class Buffer11 : public BufferD3D
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const;
- virtual Renderer* getRenderer();
+ RendererD3D *getRenderer() override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
- virtual void *getData();
+ gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
@@ -78,7 +78,7 @@ class Buffer11 : public BufferD3D
class NativeBuffer11;
class PackStorage11;
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
size_t mSize;
BufferStorage11 *mMappedStorage;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
index 765d34fd3f..7185a05506 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer)
rsDesc.DepthBias = 0;
rsDesc.DepthBiasClamp = 0.0f;
rsDesc.SlopeScaledDepthBias = 0.0f;
- rsDesc.DepthClipEnable = mRenderer->isLevel9();
+ rsDesc.DepthClipEnable = renderer->isLevel9();
rsDesc.ScissorEnable = FALSE;
rsDesc.MultisampleEnable = FALSE;
rsDesc.AntialiasedLineEnable = FALSE;
@@ -119,7 +119,6 @@ Clear11::Clear11(Renderer11 *renderer)
memset(&mIntClearShader, 0, sizeof(ClearShader));
return;
}
-
mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
}
@@ -154,7 +153,7 @@ Clear11::~Clear11()
SafeRelease(mRasterizerState);
}
-gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
// First determine if a scissored clear is needed, this will always require drawing a quad.
//
@@ -217,10 +216,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::
gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment);
if (attachment)
{
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
- if (!renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
+ return error;
}
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
@@ -290,10 +290,11 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::
gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
if (attachment)
{
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(attachment);
- if (!renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
+ return error;
}
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
index be8e187c40..a7e8fea56a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
@@ -32,7 +32,7 @@ class Clear11
~Clear11();
// Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied.
- gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+ gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer);
private:
Renderer11 *mRenderer;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
index a841b52862..f44d934056 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
@@ -4,67 +4,229 @@
// found in the LICENSE file.
//
-// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
+// Fence11.cpp: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl.
#include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/main.h"
+#include "common/utilities.h"
+
namespace rx
{
-Fence11::Fence11(rx::Renderer11 *renderer)
+//
+// Template helpers for set and test operations.
+//
+
+template<class FenceClass>
+gl::Error FenceSetHelper(FenceClass *fence)
{
- mRenderer = renderer;
- mQuery = NULL;
+ if (!fence->mQuery)
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
+
+ HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
+ }
+ }
+
+ fence->mRenderer->getDeviceContext()->End(fence->mQuery);
+ return gl::Error(GL_NO_ERROR);
}
-Fence11::~Fence11()
+template <class FenceClass>
+gl::Error FenceTestHelper(FenceClass *fence, bool flushCommandBuffer, GLboolean *outFinished)
+{
+ ASSERT(fence->mQuery);
+
+ UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);
+ HRESULT result = fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, NULL, 0, getDataFlags);
+
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result);
+ }
+ else if (fence->mRenderer->isDeviceLost())
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query.");
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
+ return gl::Error(GL_NO_ERROR);
+}
+
+//
+// FenceNV11
+//
+
+FenceNV11::FenceNV11(Renderer11 *renderer)
+ : FenceNVImpl(),
+ mRenderer(renderer),
+ mQuery(NULL)
+{
+}
+
+FenceNV11::~FenceNV11()
{
SafeRelease(mQuery);
}
-bool Fence11::isSet() const
+gl::Error FenceNV11::set()
{
- return mQuery != NULL;
+ return FenceSetHelper(this);
}
-void Fence11::set()
+gl::Error FenceNV11::test(bool flushCommandBuffer, GLboolean *outFinished)
{
- if (!mQuery)
- {
- D3D11_QUERY_DESC queryDesc;
- queryDesc.Query = D3D11_QUERY_EVENT;
- queryDesc.MiscFlags = 0;
+ return FenceTestHelper(this, flushCommandBuffer, outFinished);
+}
+
+gl::Error FenceNV11::finishFence(GLboolean *outFinished)
+{
+ ASSERT(outFinished);
- if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
+ while (*outFinished != GL_TRUE)
+ {
+ gl::Error error = test(true, outFinished);
+ if (error.isError())
{
- return gl::error(GL_OUT_OF_MEMORY);
+ return error;
}
+
+ Sleep(0);
}
- mRenderer->getDeviceContext()->End(mQuery);
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence11::test(bool flushCommandBuffer)
+//
+// FenceSync11
+//
+
+// Important note on accurate timers in Windows:
+//
+// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
+// as timeGetTime on laptops and "jumping" during certain hardware events.
+//
+// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
+// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
+//
+// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
+// from buggy implementations.
+
+FenceSync11::FenceSync11(Renderer11 *renderer)
+ : FenceSyncImpl(),
+ mRenderer(renderer),
+ mQuery(NULL)
{
- ASSERT(mQuery);
+ LARGE_INTEGER counterFreqency = { 0 };
+ BOOL success = QueryPerformanceFrequency(&counterFreqency);
+ UNUSED_ASSERTION_VARIABLE(success);
+ ASSERT(success);
- UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);
- HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, getDataFlags);
+ mCounterFrequency = counterFreqency.QuadPart;
+}
- if (mRenderer->isDeviceLost())
+FenceSync11::~FenceSync11()
+{
+ SafeRelease(mQuery);
+}
+
+gl::Error FenceSync11::set()
+{
+ return FenceSetHelper(this);
+}
+
+gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
+{
+ ASSERT(outResult);
+
+ bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
+
+ GLboolean result = GL_FALSE;
+ gl::Error error = FenceTestHelper(this, flushCommandBuffer, &result);
+ if (error.isError())
{
- return gl::error(GL_OUT_OF_MEMORY, true);
+ *outResult = GL_WAIT_FAILED;
+ return error;
}
- ASSERT(result == S_OK || result == S_FALSE);
- return (result == S_OK);
+ if (result == GL_TRUE)
+ {
+ *outResult = GL_ALREADY_SIGNALED;
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ if (timeout == 0)
+ {
+ *outResult = GL_TIMEOUT_EXPIRED;
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ LARGE_INTEGER currentCounter = { 0 };
+ BOOL success = QueryPerformanceCounter(&currentCounter);
+ UNUSED_ASSERTION_VARIABLE(success);
+ ASSERT(success);
+
+ LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
+ LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
+
+ while (currentCounter.QuadPart < endCounter && !result)
+ {
+ Sleep(0);
+ BOOL success = QueryPerformanceCounter(&currentCounter);
+ UNUSED_ASSERTION_VARIABLE(success);
+ ASSERT(success);
+
+ error = FenceTestHelper(this, flushCommandBuffer, &result);
+ if (error.isError())
+ {
+ *outResult = GL_WAIT_FAILED;
+ return error;
+ }
+ }
+
+ if (currentCounter.QuadPart >= endCounter)
+ {
+ *outResult = GL_TIMEOUT_EXPIRED;
+ }
+ else
+ {
+ *outResult = GL_CONDITION_SATISFIED;
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence11::hasError() const
+gl::Error FenceSync11::serverWait(GLbitfield flags, GLuint64 timeout)
{
- return mRenderer->isDeviceLost();
+ // Because our API is currently designed to be called from a single thread, we don't need to do
+ // extra work for a server-side fence. GPU commands issued after the fence is created will always
+ // be processed after the fence is signaled.
+ return gl::Error(GL_NO_ERROR);
}
+gl::Error FenceSync11::getStatus(GLint *outResult)
+{
+ GLboolean result = GL_FALSE;
+ gl::Error error = FenceTestHelper(this, false, &result);
+ if (error.isError())
+ {
+ // The spec does not specify any way to report errors during the status test (e.g. device lost)
+ // so we report the fence is unblocked in case of error or signaled.
+ *outResult = GL_SIGNALED;
+
+ return error;
+ }
+
+ *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED);
+ return gl::Error(GL_NO_ERROR);
}
+
+} // namespace rx
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
index 50c7621776..1223a53b90 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
@@ -4,10 +4,10 @@
// found in the LICENSE file.
//
-// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl.
+// Fence11.h: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl.
-#ifndef LIBGLESV2_RENDERER_Fence11_H_
-#define LIBGLESV2_RENDERER_Fence11_H_
+#ifndef LIBGLESV2_RENDERER_FENCE11_H_
+#define LIBGLESV2_RENDERER_FENCE11_H_
#include "libGLESv2/renderer/FenceImpl.h"
@@ -15,22 +15,46 @@ namespace rx
{
class Renderer11;
-class Fence11 : public FenceImpl
+class FenceNV11 : public FenceNVImpl
{
public:
- explicit Fence11(rx::Renderer11 *renderer);
- virtual ~Fence11();
+ explicit FenceNV11(Renderer11 *renderer);
+ virtual ~FenceNV11();
- bool isSet() const;
- void set();
- bool test(bool flushCommandBuffer);
- bool hasError() const;
+ gl::Error set();
+ gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
+ gl::Error finishFence(GLboolean *outFinished);
private:
- DISALLOW_COPY_AND_ASSIGN(Fence11);
+ DISALLOW_COPY_AND_ASSIGN(FenceNV11);
- rx::Renderer11 *mRenderer;
+ template<class T> friend gl::Error FenceSetHelper(T *fence);
+ template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished);
+
+ Renderer11 *mRenderer;
+ ID3D11Query *mQuery;
+};
+
+class FenceSync11 : public FenceSyncImpl
+{
+ public:
+ explicit FenceSync11(Renderer11 *renderer);
+ virtual ~FenceSync11();
+
+ gl::Error set();
+ gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
+ gl::Error serverWait(GLbitfield flags, GLuint64 timeout);
+ gl::Error getStatus(GLint *outResult);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FenceSync11);
+
+ template<class T> friend gl::Error FenceSetHelper(T *fence);
+ template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished);
+
+ Renderer11 *mRenderer;
ID3D11Query *mQuery;
+ LONGLONG mCounterFrequency;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
index 7536713af4..e6f3e90683 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
@@ -9,6 +9,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
@@ -22,15 +23,16 @@ namespace rx
{
Image11::Image11()
+ : mRenderer(NULL),
+ mDXGIFormat(DXGI_FORMAT_UNKNOWN),
+ mStagingTexture(NULL),
+ mStagingSubresource(0),
+ mRecoverFromStorage(false),
+ mAssociatedStorage(NULL),
+ mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()),
+ mRecoveredFromStorageCount(0)
+
{
- mStagingTexture = NULL;
- mRenderer = NULL;
- mDXGIFormat = DXGI_FORMAT_UNKNOWN;
- mRecoverFromStorage = false;
- mAssociatedStorage = NULL;
- mAssociatedStorageLevel = 0;
- mAssociatedStorageLayerTarget = 0;
- mRecoveredFromStorageCount = 0;
}
Image11::~Image11()
@@ -41,11 +43,11 @@ Image11::~Image11()
Image11 *Image11::makeImage11(Image *img)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
- return static_cast<rx::Image11*>(img);
+ ASSERT(HAS_DYNAMIC_TYPE(Image11*, img));
+ return static_cast<Image11*>(img);
}
-void Image11::generateMipmap(Image11 *dest, Image11 *src)
+gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src)
{
ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
@@ -55,21 +57,18 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src)
ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL);
D3D11_MAPPED_SUBRESOURCE destMapped;
- HRESULT destMapResult = dest->map(D3D11_MAP_WRITE, &destMapped);
- if (FAILED(destMapResult))
+ gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped);
+ if (error.isError())
{
- ERR("Failed to map destination image for mip map generation. HRESULT:0x%X", destMapResult);
- return;
+ return error;
}
D3D11_MAPPED_SUBRESOURCE srcMapped;
- HRESULT srcMapResult = src->map(D3D11_MAP_READ, &srcMapped);
- if (FAILED(srcMapResult))
+ error = src->map(D3D11_MAP_READ, &srcMapped);
+ if (error.isError())
{
- ERR("Failed to map source image for mip map generation. HRESULT:0x%X", srcMapResult);
-
dest->unmap();
- return;
+ return error;
}
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData);
@@ -83,6 +82,8 @@ void Image11::generateMipmap(Image11 *dest, Image11 *src)
src->unmap();
dest->markDirty();
+
+ return gl::Error(GL_NO_ERROR);
}
bool Image11::isDirty() const
@@ -99,32 +100,10 @@ bool Image11::isDirty() const
return mDirty;
}
-bool Image11::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region)
{
- TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
- return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
-}
+ TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(storage);
-bool Image11::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
- TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
- return copyToStorageImpl(storage11, level, face, xoffset, yoffset, width, height);
-}
-
-bool Image11::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
-{
- TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
- return copyToStorageImpl(storage11, level, 0, xoffset, yoffset, width, height);
-}
-
-bool Image11::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height)
-{
- TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
- return copyToStorageImpl(storage11, level, arrayLayer, xoffset, yoffset, width, height);
-}
-
-bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
// If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times,
// then we should just keep the staging texture around to prevent the copying from impacting perf.
// We allow the Image11 to copy its data to/from TextureStorage once.
@@ -134,23 +113,38 @@ bool Image11::copyToStorageImpl(TextureStorage11 *storage11, int level, int laye
if (attemptToReleaseStagingTexture)
{
// If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it.
- storage11->releaseAssociatedImage(level, layerTarget, this);
+ gl::Error error = storage11->releaseAssociatedImage(index, this);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ ID3D11Resource *stagingTexture = NULL;
+ unsigned int stagingSubresourceIndex = 0;
+ gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
+ if (error.isError())
+ {
+ return error;
}
- bool updateSubresourceSuccess = storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, layerTarget, xoffset, yoffset, 0, width, height, 1);
+ error = storage11->updateSubresourceLevel(stagingTexture, stagingSubresourceIndex, index, region);
+ if (error.isError())
+ {
+ return error;
+ }
// Once the image data has been copied into the Storage, we can release it locally.
- if (attemptToReleaseStagingTexture && updateSubresourceSuccess)
+ if (attemptToReleaseStagingTexture)
{
- storage11->associateImage(this, level, layerTarget);
+ storage11->associateImage(this, index);
releaseStagingTexture();
mRecoverFromStorage = true;
mAssociatedStorage = storage11;
- mAssociatedStorageLevel = level;
- mAssociatedStorageLayerTarget = layerTarget;
+ mAssociatedImageIndex = index;
}
- return updateSubresourceSuccess;
+ return gl::Error(GL_NO_ERROR);
}
bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const
@@ -158,13 +152,17 @@ bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const
return (mAssociatedStorage == textureStorage);
}
-bool Image11::recoverFromAssociatedStorage()
+gl::Error Image11::recoverFromAssociatedStorage()
{
if (mRecoverFromStorage)
{
- createStagingTexture();
+ gl::Error error = createStagingTexture();
+ if (error.isError())
+ {
+ return error;
+ }
- bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
+ bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this);
// This means that the cached TextureStorage has been modified after this Image11 released its copy of its data.
// This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten.
@@ -173,17 +171,21 @@ bool Image11::recoverFromAssociatedStorage()
if (textureStorageCorrect)
{
// CopySubResource from the Storage to the Staging texture
- mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedStorageLevel, mAssociatedStorageLayerTarget, 0, 0, 0, mWidth, mHeight, mDepth);
+ gl::Box region(0, 0, 0, mWidth, mHeight, mDepth);
+ error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region);
+ if (error.isError())
+ {
+ return error;
+ }
+
mRecoveredFromStorageCount += 1;
}
// Reset all the recovery parameters, even if the texture storage association is broken.
disassociateStorage();
-
- return textureStorageCorrect;
}
- return false;
+ return gl::Error(GL_NO_ERROR);
}
void Image11::disassociateStorage()
@@ -191,16 +193,15 @@ void Image11::disassociateStorage()
if (mRecoverFromStorage)
{
// Make the texturestorage release the Image11 too
- mAssociatedStorage->disassociateImage(mAssociatedStorageLevel, mAssociatedStorageLayerTarget, this);
+ mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this);
mRecoverFromStorage = false;
mAssociatedStorage = NULL;
- mAssociatedStorageLevel = 0;
- mAssociatedStorageLayerTarget = 0;
+ mAssociatedImageIndex = gl::ImageIndex::MakeInvalid();
}
}
-bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
+bool Image11::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
{
if (mWidth != width ||
mHeight != height ||
@@ -227,7 +228,7 @@ bool Image11::redefine(Renderer *renderer, GLenum target, GLenum internalformat,
mActualFormat = dxgiFormatInfo.internalFormat;
mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
- SafeRelease(mStagingTexture);
+ releaseStagingTexture();
mDirty = (formatInfo.dataInitializerFunction != NULL);
return true;
@@ -247,8 +248,8 @@ DXGI_FORMAT Image11::getDXGIFormat() const
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle.
-void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input)
+gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
@@ -261,11 +262,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
D3D11_MAPPED_SUBRESOURCE mappedImage;
- HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
- if (FAILED(result))
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
{
- ERR("Could not map image for loading.");
- return;
+ return error;
}
uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
@@ -274,10 +274,12 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei widt
offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
unmap();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input)
+gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
@@ -295,11 +297,10 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
D3D11_MAPPED_SUBRESOURCE mappedImage;
- HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
- if (FAILED(result))
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
{
- ERR("Could not map image for loading.");
- return;
+ return error;
}
uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
@@ -311,81 +312,130 @@ void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GL
offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
unmap();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
{
- gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
+ RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source);
+ ASSERT(sourceRenderTarget->getTexture());
- if (colorbuffer && colorbuffer->getActualFormat() == mActualFormat)
+ UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex();
+ ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(sourceRenderTarget->getTexture());
+
+ if (!sourceTexture2D)
{
- // No conversion needed-- use copyback fastpath
- ID3D11Texture2D *colorBufferTexture = NULL;
- unsigned int subresourceIndex = 0;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source RenderTarget.");
+ }
+
+ gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
+
+ SafeRelease(sourceTexture2D);
+
+ return error;
+}
+
+gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source)
+{
+ TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source);
+
+ UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex);
+ ID3D11Resource *resource = NULL;
+ gl::Error error = sourceStorage11->getResource(&resource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
+
+ if (!sourceTexture2D)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage.");
+ }
+
+ error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
+
+ SafeRelease(sourceTexture2D);
+
+ return error;
+}
+
+gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource)
+{
+ D3D11_TEXTURE2D_DESC textureDesc;
+ source->GetDesc(&textureDesc);
- if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+ if (textureDesc.Format == mDXGIFormat)
+ {
+ // No conversion needed-- use copyback fastpath
+ ID3D11Resource *stagingTexture = NULL;
+ unsigned int stagingSubresourceIndex = 0;
+ gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex);
+ if (error.isError())
{
- D3D11_TEXTURE2D_DESC textureDesc;
- colorBufferTexture->GetDesc(&textureDesc);
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- ID3D11Texture2D* srcTex = NULL;
- if (textureDesc.SampleDesc.Count > 1)
- {
- D3D11_TEXTURE2D_DESC resolveDesc;
- resolveDesc.Width = textureDesc.Width;
- resolveDesc.Height = textureDesc.Height;
- resolveDesc.MipLevels = 1;
- resolveDesc.ArraySize = 1;
- resolveDesc.Format = textureDesc.Format;
- resolveDesc.SampleDesc.Count = 1;
- resolveDesc.SampleDesc.Quality = 0;
- resolveDesc.Usage = D3D11_USAGE_DEFAULT;
- resolveDesc.BindFlags = 0;
- resolveDesc.CPUAccessFlags = 0;
- resolveDesc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
- if (FAILED(result))
- {
- ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
- return;
- }
-
- deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
- subresourceIndex = 0;
- }
- else
+ UINT subresourceAfterResolve = sourceSubResource;
+
+ ID3D11Texture2D* srcTex = NULL;
+ if (textureDesc.SampleDesc.Count > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = textureDesc.Width;
+ resolveDesc.Height = textureDesc.Height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureDesc.Format;
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+ if (FAILED(result))
{
- srcTex = colorBufferTexture;
- srcTex->AddRef();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
}
- D3D11_BOX srcBox;
- srcBox.left = x;
- srcBox.right = x + width;
- srcBox.top = y;
- srcBox.bottom = y + height;
- srcBox.front = 0;
- srcBox.back = 1;
+ deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format);
+ subresourceAfterResolve = 0;
+ }
+ else
+ {
+ srcTex = source;
+ }
- deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, zoffset, srcTex, subresourceIndex, &srcBox);
+ D3D11_BOX srcBox;
+ srcBox.left = sourceArea.x;
+ srcBox.right = sourceArea.x + sourceArea.width;
+ srcBox.top = sourceArea.y;
+ srcBox.bottom = sourceArea.y + sourceArea.height;
+ srcBox.front = 0;
+ srcBox.back = 1;
+ deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox);
+
+ if (textureDesc.SampleDesc.Count > 1)
+ {
SafeRelease(srcTex);
- SafeRelease(colorBufferTexture);
}
}
else
{
// This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
D3D11_MAPPED_SUBRESOURCE mappedImage;
- HRESULT result = map(D3D11_MAP_WRITE, &mappedImage);
- if (FAILED(result))
+ gl::Error error = map(D3D11_MAP_WRITE, &mappedImage);
+ if (error.isError())
{
- ERR("Failed to map texture for Image11::copy, HRESULT: 0x%X.", result);
- return;
+ return error;
}
// determine the offset coordinate into the destination buffer
@@ -394,17 +444,32 @@ void Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- mRenderer->readPixels(source, x, y, width, height, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
+ error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
unmap();
+
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ mDirty = true;
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *Image11::getStagingTexture()
+gl::Error Image11::getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex)
{
- createStagingTexture();
+ gl::Error error = createStagingTexture();
+ if (error.isError())
+ {
+ return error;
+ }
- return mStagingTexture;
+ *outStagingTexture = mStagingTexture;
+ *outSubresourceIndex = mStagingSubresource;
+ return gl::Error(GL_NO_ERROR);
}
void Image11::releaseStagingTexture()
@@ -412,149 +477,149 @@ void Image11::releaseStagingTexture()
SafeRelease(mStagingTexture);
}
-unsigned int Image11::getStagingSubresource()
-{
- createStagingTexture();
-
- return mStagingSubresource;
-}
-
-void Image11::createStagingTexture()
+gl::Error Image11::createStagingTexture()
{
if (mStagingTexture)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
+ ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0);
+
const DXGI_FORMAT dxgiFormat = getDXGIFormat();
- if (mWidth > 0 && mHeight > 0 && mDepth > 0)
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- int lodOffset = 1;
- GLsizei width = mWidth;
- GLsizei height = mHeight;
+ int lodOffset = 1;
+ GLsizei width = mWidth;
+ GLsizei height = mHeight;
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
- if (mTarget == GL_TEXTURE_3D)
+ if (mTarget == GL_TEXTURE_3D)
+ {
+ ID3D11Texture3D *newTexture = NULL;
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.Depth = mDepth;
+ desc.MipLevels = lodOffset + 1;
+ desc.Format = dxgiFormat;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
{
- ID3D11Texture3D *newTexture = NULL;
-
- D3D11_TEXTURE3D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.Depth = mDepth;
- desc.MipLevels = lodOffset + 1;
- desc.Format = dxgiFormat;
- desc.Usage = D3D11_USAGE_STAGING;
- desc.BindFlags = 0;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- desc.MiscFlags = 0;
-
- if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
- {
- std::vector<D3D11_SUBRESOURCE_DATA> initialData;
- std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
- lodOffset + 1, &initialData, &textureData);
+ std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+ std::vector< std::vector<BYTE> > textureData;
+ d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
+ lodOffset + 1, &initialData, &textureData);
- result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
- }
- else
- {
- result = device->CreateTexture3D(&desc, NULL, &newTexture);
- }
-
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
-
- mStagingTexture = newTexture;
- mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
}
- else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
+ else
{
- ID3D11Texture2D *newTexture = NULL;
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = lodOffset + 1;
- desc.ArraySize = 1;
- desc.Format = dxgiFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_STAGING;
- desc.BindFlags = 0;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
- desc.MiscFlags = 0;
-
- if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
- {
- std::vector<D3D11_SUBRESOURCE_DATA> initialData;
- std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
- lodOffset + 1, &initialData, &textureData);
+ result = device->CreateTexture3D(&desc, NULL, &newTexture);
+ }
- result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
- }
- else
- {
- result = device->CreateTexture2D(&desc, NULL, &newTexture);
- }
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
+ }
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
+ mStagingTexture = newTexture;
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ }
+ else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP)
+ {
+ ID3D11Texture2D *newTexture = NULL;
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = lodOffset + 1;
+ desc.ArraySize = 1;
+ desc.Format = dxgiFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
+ {
+ std::vector<D3D11_SUBRESOURCE_DATA> initialData;
+ std::vector< std::vector<BYTE> > textureData;
+ d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
+ lodOffset + 1, &initialData, &textureData);
- mStagingTexture = newTexture;
- mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
}
else
{
- UNREACHABLE();
+ result = device->CreateTexture2D(&desc, NULL, &newTexture);
}
+
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result);
+ }
+
+ mStagingTexture = newTexture;
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ }
+ else
+ {
+ UNREACHABLE();
}
mDirty = false;
+ return gl::Error(GL_NO_ERROR);
}
-HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
+gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
{
- createStagingTexture();
-
// We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
- recoverFromAssociatedStorage();
-
- HRESULT result = E_FAIL;
+ gl::Error error = recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
- if (mStagingTexture)
+ ID3D11Resource *stagingTexture = NULL;
+ unsigned int subresourceIndex = 0;
+ error = getStagingTexture(&stagingTexture, &subresourceIndex);
+ if (error.isError())
{
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
+ return error;
+ }
- // this can fail if the device is removed (from TDR)
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- }
- else if (SUCCEEDED(result))
- {
- mDirty = true;
- }
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ ASSERT(mStagingTexture);
+ HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map);
+
+ // this can fail if the device is removed (from TDR)
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ }
+ else if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result);
}
- return result;
+ mDirty = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void Image11::unmap()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
index a76a61f036..a936e6d7b2 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
@@ -11,6 +11,7 @@
#define LIBGLESV2_RENDERER_IMAGE11_H_
#include "libGLESv2/renderer/d3d/ImageD3D.h"
+#include "libGLESv2/ImageIndex.h"
#include "common/debug.h"
@@ -21,7 +22,6 @@ class Framebuffer;
namespace rx
{
-class Renderer;
class Renderer11;
class TextureStorage11;
@@ -33,42 +33,41 @@ class Image11 : public ImageD3D
static Image11 *makeImage11(Image *img);
- static void generateMipmap(Image11 *dest, Image11 *src);
+ static gl::Error generateMipmap(Image11 *dest, Image11 *src);
virtual bool isDirty() const;
- virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
- virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint arrayLayer, GLsizei width, GLsizei height);
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
- virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
+ bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override;
DXGI_FORMAT getDXGIFormat() const;
-
- virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input);
- virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input);
- virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input);
+ virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input);
- bool recoverFromAssociatedStorage();
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ const gl::ImageIndex &sourceIndex, TextureStorage *source);
+
+ gl::Error recoverFromAssociatedStorage();
bool isAssociatedStorageValid(TextureStorage11* textureStorage) const;
void disassociateStorage();
protected:
- HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
+ gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
void unmap();
private:
DISALLOW_COPY_AND_ASSIGN(Image11);
- bool copyToStorageImpl(TextureStorage11 *storage11, int level, int layerTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box &region);
+ gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource);
- ID3D11Resource *getStagingTexture();
- unsigned int getStagingSubresource();
- void createStagingTexture();
+ gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex);
+ gl::Error createStagingTexture();
void releaseStagingTexture();
Renderer11 *mRenderer;
@@ -79,8 +78,7 @@ class Image11 : public ImageD3D
bool mRecoverFromStorage;
TextureStorage11 *mAssociatedStorage;
- int mAssociatedStorageLevel;
- int mAssociatedStorageLayerTarget;
+ gl::ImageIndex mAssociatedImageIndex;
unsigned int mRecoveredFromStorageCount;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
index f7c2b38e7e..3351df5ec1 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
@@ -40,7 +40,7 @@ class IndexBuffer11 : public IndexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(IndexBuffer11);
- rx::Renderer11 *const mRenderer;
+ Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
index d835e4fa68..ff90a6a69a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -12,6 +12,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
@@ -137,7 +138,16 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
{
gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetInputLayout(attributes, shaderInputLayout);
- ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutableForInputLayout(shaderInputLayout));
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+
+ ShaderExecutable *shader = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *shader11 = ShaderExecutable11::makeShaderExecutable11(shader);
D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
for (unsigned int j = 0; j < ilKey.elementCount; ++j)
@@ -145,7 +155,7 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
descs[j] = ilKey.elements[j].desc;
}
- HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
+ HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
index a4e84f91c2..6a3d3475ee 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -33,12 +33,38 @@ namespace rx
PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
: mRenderer(renderer),
+ mResourcesLoaded(false),
mBufferToTextureVS(NULL),
mBufferToTextureGS(NULL),
mParamsConstantBuffer(NULL),
mCopyRasterizerState(NULL),
mCopyDepthStencilState(NULL)
{
+}
+
+PixelTransfer11::~PixelTransfer11()
+{
+ for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
+ {
+ SafeRelease(shaderMapIt->second);
+ }
+
+ mBufferToTexturePSMap.clear();
+
+ SafeRelease(mBufferToTextureVS);
+ SafeRelease(mBufferToTextureGS);
+ SafeRelease(mParamsConstantBuffer);
+ SafeRelease(mCopyRasterizerState);
+ SafeRelease(mCopyDepthStencilState);
+}
+
+gl::Error PixelTransfer11::loadResources()
+{
+ if (mResourcesLoaded)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
HRESULT result = S_OK;
ID3D11Device *device = mRenderer->getDevice();
@@ -56,6 +82,10 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer rasterizer state, result: 0x%X.", result);
+ }
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
depthStencilDesc.DepthEnable = true;
@@ -75,9 +105,13 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer depth stencil state, result: 0x%X.", result);
+ }
D3D11_BUFFER_DESC constantBufferDesc = { 0 };
- constantBufferDesc.ByteWidth = rx::roundUp<UINT>(sizeof(CopyShaderParams), 32u);
+ constantBufferDesc.ByteWidth = roundUp<UINT>(sizeof(CopyShaderParams), 32u);
constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@@ -86,34 +120,39 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer constant buffer, result: 0x%X.", result);
+ }
d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer");
- StructZero(&mParamsData);
-
// init shaders
- if (mRenderer->isLevel9())
- return;
-
mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS");
- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+ if (!mBufferToTextureVS)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader.");
+ }
- buildShaderMap();
-}
+ if (!mRenderer->isLevel9())
+ {
+ mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+ if (!mBufferToTextureGS)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
+ }
+ }
-PixelTransfer11::~PixelTransfer11()
-{
- for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
+ gl::Error error = buildShaderMap();
+ if (error.isError())
{
- SafeRelease(shaderMapIt->second);
+ return error;
}
- mBufferToTexturePSMap.clear();
+ StructZero(&mParamsData);
- SafeRelease(mBufferToTextureVS);
- SafeRelease(mBufferToTextureGS);
- SafeRelease(mParamsConstantBuffer);
- SafeRelease(mCopyRasterizerState);
- SafeRelease(mCopyDepthStencilState);
+ mResourcesLoaded = true;
+
+ return gl::Error(GL_NO_ERROR);
}
void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat,
@@ -138,18 +177,21 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons
parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height);
}
-bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
+gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
- gl::Extents destSize = destRenderTarget->getExtents();
-
- if (destArea.x < 0 || destArea.x + destArea.width > destSize.width ||
- destArea.y < 0 || destArea.y + destArea.height > destSize.height ||
- destArea.z < 0 || destArea.z + destArea.depth > destSize.depth )
+ gl::Error error = loadResources();
+ if (error.isError())
{
- return false;
+ return error;
}
+ gl::Extents destSize = destRenderTarget->getExtents();
+
+ ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width &&
+ destArea.y >= 0 && destArea.y + destArea.height <= destSize.height &&
+ destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth );
+
const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
@@ -177,7 +219,6 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- ID3D11ShaderResourceView *nullSRV = NULL;
ID3D11Buffer *nullBuffer = NULL;
UINT zero = 0;
@@ -187,7 +228,7 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un
deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0);
deviceContext->GSSetShader(geometryShader, NULL, 0);
deviceContext->PSSetShader(pixelShader, NULL, 0);
- deviceContext->PSSetShaderResources(0, 1, &bufferSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV);
deviceContext->IASetInputLayout(NULL);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
@@ -220,21 +261,32 @@ bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, un
deviceContext->Draw(numPixels, 0);
// Unbind textures and render targets and vertex buffer
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
mRenderer->markAllStateDirty();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-void PixelTransfer11::buildShaderMap()
+gl::Error PixelTransfer11::buildShaderMap()
{
ID3D11Device *device = mRenderer->getDevice();
mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps");
mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps");
mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps");
+
+ // Check that all the shaders were created successfully
+ for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
+ {
+ if (shaderMapIt->second == NULL)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture pixel shader.");
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
index ed1a3ae1d0..29552140bb 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
@@ -11,6 +11,8 @@
#ifndef LIBGLESV2_PIXELTRANSFER11_H_
#define LIBGLESV2_PIXELTRANSFER11_H_
+#include "libGLESv2/Error.h"
+
#include "common/platform.h"
#include <GLES2/gl2.h>
@@ -38,15 +40,13 @@ class PixelTransfer11
explicit PixelTransfer11(Renderer11 *renderer);
~PixelTransfer11();
- static bool supportsBufferToTextureCopy(GLenum internalFormat);
-
// unpack: the source buffer is stored in the unpack state, and buffer strides
// offset: the start of the data within the unpack buffer
// destRenderTarget: individual slice/layer of a target texture
// destinationFormat/sourcePixelsType: determines shaders + shader parameters
// destArea: the sub-section of destRenderTarget to copy to
- bool copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
private:
@@ -65,11 +65,13 @@ class PixelTransfer11
static void setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat,
const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut);
- void buildShaderMap();
+ gl::Error loadResources();
+ gl::Error buildShaderMap();
ID3D11PixelShader *findBufferToTexturePS(GLenum internalFormat) const;
Renderer11 *mRenderer;
+ bool mResourcesLoaded;
std::map<GLenum, ID3D11PixelShader *> mBufferToTexturePSMap;
ID3D11VertexShader *mBufferToTextureVS;
ID3D11GeometryShader *mBufferToTextureGS;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
index 7109be3e28..17ab1f8ab3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
@@ -10,13 +10,14 @@
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
#include "libGLESv2/main.h"
+#include "common/utilities.h"
#include <GLES2/gl2ext.h>
namespace rx
{
-Query11::Query11(rx::Renderer11 *renderer, GLenum type)
+Query11::Query11(Renderer11 *renderer, GLenum type)
: QueryImpl(type),
mResult(0),
mQueryFinished(false),
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
index 822f2542ee..f9ff467873 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
@@ -18,7 +18,7 @@ class Renderer11;
class Query11 : public QueryImpl
{
public:
- Query11(rx::Renderer11 *renderer, GLenum type);
+ Query11(Renderer11 *renderer, GLenum type);
virtual ~Query11();
virtual gl::Error begin();
@@ -35,7 +35,7 @@ class Query11 : public QueryImpl
bool mQueryFinished;
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
ID3D11Query *mQuery;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
index 71b931f27e..ab4f60bd98 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -38,11 +38,14 @@ const unsigned int RenderStateCache::kMaxRasterizerStates = 4096;
const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096;
const unsigned int RenderStateCache::kMaxSamplerStates = 4096;
-RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0),
- mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
- mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
- mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
- mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
+RenderStateCache::RenderStateCache(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mDevice(NULL),
+ mCounter(0),
+ mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
+ mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
+ mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
+ mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
{
}
@@ -89,7 +92,7 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co
bool mrt = false;
- const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
+ const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(mRenderer->getWorkarounds());
BlendStateKey key = { 0 };
key.blendState = blendState;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
index d5471a3061..dfd1d84265 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
@@ -28,7 +28,7 @@ class Renderer11;
class RenderStateCache
{
public:
- RenderStateCache();
+ RenderStateCache(Renderer11 *renderer);
virtual ~RenderStateCache();
void initialize(ID3D11Device *device);
@@ -42,6 +42,7 @@ class RenderStateCache
private:
DISALLOW_COPY_AND_ASSIGN(RenderStateCache);
+ Renderer11 *mRenderer;
unsigned long long mCounter;
// Blend state cache
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
index 3041f21faa..aff3453492 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -10,6 +10,7 @@
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/main.h"
@@ -176,276 +177,228 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth
return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
}
-RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource,
- ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
+RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RenderTarget11*, target));
+ return static_cast<RenderTarget11*>(target);
+}
+
+void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
{
- mRenderer = Renderer11::makeRenderer11(renderer);
+ // Currently a no-op
+}
- mTexture = resource;
+TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mActualFormat(internalFormat),
+ mSamples(samples),
+ mSubresourceIndex(0),
+ mTexture(resource),
+ mRenderTarget(rtv),
+ mDepthStencil(NULL),
+ mShaderResource(srv)
+{
if (mTexture)
{
mTexture->AddRef();
}
- mRenderTarget = rtv;
if (mRenderTarget)
{
mRenderTarget->AddRef();
}
- mDepthStencil = NULL;
-
- mShaderResource = srv;
if (mShaderResource)
{
mShaderResource->AddRef();
}
- mSubresourceIndex = 0;
-
if (mRenderTarget && mTexture)
{
+ mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
+
D3D11_RENDER_TARGET_VIEW_DESC desc;
mRenderTarget->GetDesc(&desc);
- unsigned int mipLevels, samples;
- getTextureProperties(mTexture, &mipLevels, &samples);
-
- mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
- mWidth = width;
- mHeight = height;
- mDepth = depth;
- mSamples = samples;
-
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
- mInternalFormat = dxgiFormatInfo.internalFormat;
mActualFormat = dxgiFormatInfo.internalFormat;
}
}
-RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
- ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
+TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mActualFormat(internalFormat),
+ mSamples(samples),
+ mSubresourceIndex(0),
+ mTexture(resource),
+ mRenderTarget(NULL),
+ mDepthStencil(dsv),
+ mShaderResource(srv)
{
- mRenderer = Renderer11::makeRenderer11(renderer);
-
- mTexture = resource;
if (mTexture)
{
mTexture->AddRef();
}
- mRenderTarget = NULL;
-
- mDepthStencil = dsv;
if (mDepthStencil)
{
mDepthStencil->AddRef();
}
- mShaderResource = srv;
if (mShaderResource)
{
mShaderResource->AddRef();
}
- mSubresourceIndex = 0;
-
if (mDepthStencil && mTexture)
{
+ mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
+
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
mDepthStencil->GetDesc(&desc);
- unsigned int mipLevels, samples;
- getTextureProperties(mTexture, &mipLevels, &samples);
-
- mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
- mWidth = width;
- mHeight = height;
- mDepth = depth;
- mSamples = samples;
-
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
- mInternalFormat = dxgiFormatInfo.internalFormat;
mActualFormat = dxgiFormatInfo.internalFormat;
}
}
-RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
+TextureRenderTarget11::~TextureRenderTarget11()
{
- mRenderer = Renderer11::makeRenderer11(renderer);
- mTexture = NULL;
- mRenderTarget = NULL;
- mDepthStencil = NULL;
- mShaderResource = NULL;
+ SafeRelease(mTexture);
+ SafeRelease(mRenderTarget);
+ SafeRelease(mDepthStencil);
+ SafeRelease(mShaderResource);
+}
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
+ID3D11Resource *TextureRenderTarget11::getTexture() const
+{
+ return mTexture;
+}
- const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
- GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+ID3D11RenderTargetView *TextureRenderTarget11::getRenderTargetView() const
+{
+ return mRenderTarget;
+}
- if (width > 0 && height > 0)
- {
- // Create texture resource
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = 1;
- desc.ArraySize = 1;
- desc.Format = formatInfo.texFormat;
- desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- // If a rendertarget or depthstencil format exists for this texture format,
- // we'll flag it to allow binding that way. Shader resource views are a little
- // more complicated.
- bool bindRTV = false, bindDSV = false, bindSRV = false;
- bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
- bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
- if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
- {
- // Multisample targets flagged for binding as depth stencil cannot also be
- // flagged for binding as SRV, so make certain not to add the SRV flag for
- // these targets.
- bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
- }
-
- desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
- (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
- (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
-
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11Texture2D *texture = NULL;
- HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
- mTexture = texture;
-
- if (result == E_OUTOFMEMORY)
- {
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
-
- if (bindSRV)
- {
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = formatInfo.srvFormat;
- srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
- srvDesc.Texture2D.MostDetailedMip = 0;
- srvDesc.Texture2D.MipLevels = 1;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(mTexture);
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
- }
-
- if (bindDSV)
- {
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = formatInfo.dsvFormat;
- dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
- dsvDesc.Texture2D.MipSlice = 0;
- dsvDesc.Flags = 0;
- result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(mTexture);
- SafeRelease(mShaderResource);
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
- }
-
- if (bindRTV)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = formatInfo.rtvFormat;
- rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
- rtvDesc.Texture2D.MipSlice = 0;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(mTexture);
- SafeRelease(mShaderResource);
- SafeRelease(mDepthStencil);
- gl::error(GL_OUT_OF_MEMORY);
- return;
- }
- ASSERT(SUCCEEDED(result));
-
- if (formatInfo.dataInitializerFunction != NULL)
- {
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
-
- const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
- context->ClearRenderTargetView(mRenderTarget, clearValues);
- }
- }
- }
+ID3D11DepthStencilView *TextureRenderTarget11::getDepthStencilView() const
+{
+ return mDepthStencil;
+}
+ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const
+{
+ return mShaderResource;
+}
- mWidth = width;
- mHeight = height;
- mDepth = 1;
- mInternalFormat = internalFormat;
- mSamples = supportedSamples;
- mActualFormat = dxgiFormatInfo.internalFormat;
- mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
+GLsizei TextureRenderTarget11::getWidth() const
+{
+ return mWidth;
}
-RenderTarget11::~RenderTarget11()
+GLsizei TextureRenderTarget11::getHeight() const
{
- SafeRelease(mTexture);
- SafeRelease(mRenderTarget);
- SafeRelease(mDepthStencil);
- SafeRelease(mShaderResource);
+ return mHeight;
}
-RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+GLsizei TextureRenderTarget11::getDepth() const
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
- return static_cast<rx::RenderTarget11*>(target);
+ return mDepth;
}
-void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
+GLenum TextureRenderTarget11::getInternalFormat() const
{
- // Currently a no-op
+ return mInternalFormat;
}
-ID3D11Resource *RenderTarget11::getTexture() const
+GLenum TextureRenderTarget11::getActualFormat() const
{
- return mTexture;
+ return mActualFormat;
}
-ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
+GLsizei TextureRenderTarget11::getSamples() const
{
- return mRenderTarget;
+ return mSamples;
}
-ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
+unsigned int TextureRenderTarget11::getSubresourceIndex() const
{
- return mDepthStencil;
+ return mSubresourceIndex;
}
-ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
+
+SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth)
+ : mSwapChain(swapChain),
+ mDepth(depth)
{
- return mShaderResource;
+ ASSERT(mSwapChain);
}
-unsigned int RenderTarget11::getSubresourceIndex() const
+SurfaceRenderTarget11::~SurfaceRenderTarget11()
{
- return mSubresourceIndex;
+}
+
+GLsizei SurfaceRenderTarget11::getWidth() const
+{
+ return mSwapChain->getWidth();
+}
+
+GLsizei SurfaceRenderTarget11::getHeight() const
+{
+ return mSwapChain->getHeight();
+}
+
+GLsizei SurfaceRenderTarget11::getDepth() const
+{
+ return 1;
+}
+
+GLenum SurfaceRenderTarget11::getInternalFormat() const
+{
+ return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
+}
+
+GLenum SurfaceRenderTarget11::getActualFormat() const
+{
+ return d3d11::GetDXGIFormatInfo(d3d11::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat;
+}
+
+GLsizei SurfaceRenderTarget11::getSamples() const
+{
+ // Our EGL surfaces do not support multisampling.
+ return 0;
+}
+
+ID3D11Resource *SurfaceRenderTarget11::getTexture() const
+{
+ return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture());
+}
+
+ID3D11RenderTargetView *SurfaceRenderTarget11::getRenderTargetView() const
+{
+ return (mDepth ? NULL : mSwapChain->getRenderTarget());
+}
+
+ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const
+{
+ return (mDepth ? mSwapChain->getDepthStencil() : NULL);
+}
+
+ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const
+{
+ return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource());
+}
+
+unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
+{
+ return 0;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
index 82182957af..c7babdda3f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
@@ -14,39 +14,95 @@
namespace rx
{
-class Renderer;
-class Renderer11;
+class SwapChain11;
class RenderTarget11 : public RenderTarget
{
public:
- // RenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them
- RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth);
- RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth);
- RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples);
- virtual ~RenderTarget11();
+ RenderTarget11() { }
+ virtual ~RenderTarget11() { }
static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget);
- virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height);
+ void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override;
- ID3D11Resource *getTexture() const;
- ID3D11RenderTargetView *getRenderTargetView() const;
- ID3D11DepthStencilView *getDepthStencilView() const;
- ID3D11ShaderResourceView *getShaderResourceView() const;
+ virtual ID3D11Resource *getTexture() const = 0;
+ virtual ID3D11RenderTargetView *getRenderTargetView() const = 0;
+ virtual ID3D11DepthStencilView *getDepthStencilView() const = 0;
+ virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0;
- unsigned int getSubresourceIndex() const;
+ virtual unsigned int getSubresourceIndex() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(RenderTarget11);
+};
+
+class TextureRenderTarget11 : public RenderTarget11
+{
+ public:
+ // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them
+ TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples);
+ TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples);
+ virtual ~TextureRenderTarget11();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ ID3D11Resource *getTexture() const override;
+ ID3D11RenderTargetView *getRenderTargetView() const override;
+ ID3D11DepthStencilView *getDepthStencilView() const override;
+ ID3D11ShaderResourceView *getShaderResourceView() const override;
+
+ unsigned int getSubresourceIndex() const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget11);
+
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ GLenum mActualFormat;
+ GLsizei mSamples;
unsigned int mSubresourceIndex;
ID3D11Resource *mTexture;
ID3D11RenderTargetView *mRenderTarget;
ID3D11DepthStencilView *mDepthStencil;
ID3D11ShaderResourceView *mShaderResource;
+};
+
+class SurfaceRenderTarget11 : public RenderTarget11
+{
+ public:
+ SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth);
+ virtual ~SurfaceRenderTarget11();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ ID3D11Resource *getTexture() const override;
+ ID3D11RenderTargetView *getRenderTargetView() const override;
+ ID3D11DepthStencilView *getDepthStencilView() const override;
+ ID3D11ShaderResourceView *getShaderResourceView() const override;
+
+ unsigned int getSubresourceIndex() const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget11);
- Renderer11 *mRenderer;
+ SwapChain11 *mSwapChain;
+ bool mDepth;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index b29b2ef910..e6d7f3025b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -6,12 +6,12 @@
// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
-#include "common/platform.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/State.h"
#include "libGLESv2/renderer/d3d/ProgramD3D.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
@@ -36,10 +36,12 @@
#include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
#include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h"
#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
#include "libEGL/Display.h"
#include "common/utilities.h"
+#include "common/tls.h"
#include <EGL/eglext.h>
@@ -59,6 +61,9 @@
namespace rx
{
+
+namespace
+{
static const DXGI_FORMAT RenderTargetFormats[] =
{
DXGI_FORMAT_B8G8R8A8_UNORM,
@@ -77,10 +82,22 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
};
-Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
- : Renderer(display),
+// Does *not* increment the resource ref count!!
+ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv)
+{
+ ID3D11Resource *resource = NULL;
+ ASSERT(srv);
+ srv->GetResource(&resource);
+ resource->Release();
+ return resource;
+}
+
+}
+
+Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
+ : RendererD3D(display),
mDc(hDc),
- mRequestedDisplay(requestedDisplay)
+ mStateCache(this)
{
mVertexDataManager = NULL;
mIndexDataManager = NULL;
@@ -112,6 +129,50 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint r
mAppliedGeometryShader = NULL;
mCurPointGeometryShader = NULL;
mAppliedPixelShader = NULL;
+
+ EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
+ EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0);
+ }
+ }
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0);
+ }
+ }
+
+#if !defined(ANGLE_ENABLE_D3D9)
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
+ }
+ }
+#endif
+
+ mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP
+ : D3D_DRIVER_TYPE_HARDWARE;
}
Renderer11::~Renderer11()
@@ -121,8 +182,8 @@ Renderer11::~Renderer11()
Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
- return static_cast<rx::Renderer11*>(renderer);
+ ASSERT(HAS_DYNAMIC_TYPE(Renderer11*, renderer));
+ return static_cast<Renderer11*>(renderer);
}
#ifndef __d3d11_1_h__
@@ -136,7 +197,7 @@ EGLint Renderer11::initialize()
return EGL_NOT_INITIALIZED;
}
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
@@ -157,33 +218,14 @@ EGLint Renderer11::initialize()
}
#endif
- D3D_FEATURE_LEVEL featureLevels[] =
- {
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
-#if !defined(ANGLE_ENABLE_D3D9)
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1,
-#endif
- };
-
- D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;
- if (mRequestedDisplay == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
- {
- driverType = D3D_DRIVER_TYPE_WARP;
- }
-
HRESULT result = S_OK;
-
#ifdef _DEBUG
result = D3D11CreateDevice(NULL,
- driverType,
+ mDriverType,
NULL,
D3D11_CREATE_DEVICE_DEBUG,
- featureLevels,
- ArraySize(featureLevels),
+ mAvailableFeatureLevels.data(),
+ mAvailableFeatureLevels.size(),
D3D11_SDK_VERSION,
&mDevice,
&mFeatureLevel,
@@ -198,11 +240,11 @@ EGLint Renderer11::initialize()
#endif
{
result = D3D11CreateDevice(NULL,
- driverType,
+ mDriverType,
NULL,
0,
- featureLevels,
- ArraySize(featureLevels),
+ mAvailableFeatureLevels.data(),
+ mAvailableFeatureLevels.size(),
D3D11_SDK_VERSION,
&mDevice,
&mFeatureLevel,
@@ -215,7 +257,18 @@ EGLint Renderer11::initialize()
}
}
-#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
+ if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
+ {
+ ID3D10Multithread *multithread;
+ result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread));
+ ASSERT(SUCCEEDED(result));
+ result = multithread->SetMultithreadProtected(true);
+ ASSERT(SUCCEEDED(result));
+ multithread->Release();
+ }
+#if !ANGLE_SKIP_DXGI_1_2_CHECK
// In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
// The easiest way to check is to query for a IDXGIDevice2.
bool requireDXGI1_2 = false;
@@ -244,13 +297,10 @@ EGLint Renderer11::initialize()
SafeRelease(dxgiDevice2);
}
#endif
+#endif
-#if !defined(ANGLE_PLATFORM_WINRT)
IDXGIDevice *dxgiDevice = NULL;
-#else
- IDXGIDevice1 *dxgiDevice = NULL;
-#endif
- result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
if (FAILED(result))
{
@@ -281,9 +331,9 @@ EGLint Renderer11::initialize()
}
// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
-#if !defined(__MINGW32__) && defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
ID3D11InfoQueue *infoQueue;
- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
+ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
if (SUCCEEDED(result))
{
@@ -301,19 +351,6 @@ EGLint Renderer11::initialize()
}
#endif
-#if !defined(ANGLE_PLATFORM_WINRT)
- static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
- if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
- {
- ID3D10Multithread *multithread;
- result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread));
- ASSERT(SUCCEEDED(result));
- result = multithread->SetMultithreadProtected(true);
- ASSERT(SUCCEEDED(result));
- multithread->Release();
- }
-#endif
-
initializeDevice();
return EGL_SUCCESS;
@@ -394,7 +431,7 @@ void Renderer11::deleteConfigs(ConfigDesc *configDescList)
delete [] (configDescList);
}
-void Renderer11::sync(bool block)
+gl::Error Renderer11::sync(bool block)
{
if (block)
{
@@ -408,6 +445,10 @@ void Renderer11::sync(bool block)
result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
+ }
}
mDeviceContext->End(mSyncQuery);
@@ -416,13 +457,17 @@ void Renderer11::sync(bool block)
do
{
result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
+ }
// Keep polling, but allow other threads to do something useful first
Sleep(0);
if (testDeviceLost(true))
{
- return;
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync.");
}
}
while (result == S_FALSE);
@@ -431,22 +476,26 @@ void Renderer11::sync(bool block)
{
mDeviceContext->Flush();
}
+
+ return gl::Error(GL_NO_ERROR);
}
-SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChain *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
- return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
}
gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
{
if (texture)
{
- TextureStorage *texStorage = texture->getNativeTexture();
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ ASSERT(textureD3D);
+
+ TextureStorage *texStorage = textureD3D->getNativeTexture();
if (texStorage)
{
TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
-
gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
texture->getSamplerState().swizzleGreen,
texture->getSamplerState().swizzleBlue,
@@ -461,16 +510,21 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
+gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam)
{
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ gl::SamplerState samplerStateInternal = samplerStateParam;
+ samplerStateInternal.baseLevel += textureD3D->getNativeTexture()->getTopLevel();
+
if (type == gl::SAMPLER_PIXEL)
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
- if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
+ gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
if (error.isError())
{
return error;
@@ -479,7 +533,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
ASSERT(dxSamplerState != NULL);
mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
- mCurPixelSamplerStates[index] = samplerState;
+ mCurPixelSamplerStates[index] = samplerStateInternal;
}
mForceSetPixelSamplerStates[index] = false;
@@ -488,10 +542,10 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
{
ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
- if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState);
+ gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
if (error.isError())
{
return error;
@@ -500,7 +554,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
ASSERT(dxSamplerState != NULL);
mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
- mCurVertexSamplerStates[index] = samplerState;
+ mCurVertexSamplerStates[index] = samplerStateInternal;
}
mForceSetVertexSamplerStates[index] = false;
@@ -513,50 +567,36 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, const gl:
gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
{
ID3D11ShaderResourceView *textureSRV = NULL;
- bool forceSetTexture = false;
if (texture)
{
- TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureD3D *textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
TextureStorage *texStorage = textureImpl->getNativeTexture();
ASSERT(texStorage != NULL);
TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
- gl::SamplerState samplerState;
- texture->getSamplerStateWithNativeOffset(&samplerState);
- textureSRV = storage11->getSRV(samplerState);
+
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ gl::SamplerState samplerState = texture->getSamplerState();
+ samplerState.baseLevel += storage11->getTopLevel();
+
+ gl::Error error = storage11->getSRV(samplerState, &textureSRV);
+ if (error.isError())
+ {
+ return error;
+ }
// If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
// missing the shader resource view
ASSERT(textureSRV != NULL);
- forceSetTexture = textureImpl->hasDirtyImages();
textureImpl->resetDirty();
}
- if (type == gl::SAMPLER_PIXEL)
- {
- ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
-
- if (forceSetTexture || mCurPixelSRVs[index] != textureSRV)
- {
- mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
- }
-
- mCurPixelSRVs[index] = textureSRV;
- }
- else if (type == gl::SAMPLER_VERTEX)
- {
- ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
-
- if (forceSetTexture || mCurVertexSRVs[index] != textureSRV)
- {
- mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
- }
+ ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
+ (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
- mCurVertexSRVs[index] = textureSRV;
- }
- else UNREACHABLE();
+ setShaderResource(type, index, textureSRV);
return gl::Error(GL_NO_ERROR);
}
@@ -631,7 +671,7 @@ gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{
if (mForceSetBlendState ||
@@ -831,7 +871,22 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
return count >= minCount;
}
-gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
+void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource)
+{
+ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
+ {
+ ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex];
+
+ if (srv && GetSRVResource(srv) == resource)
+ {
+ setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
+ }
+ }
+}
+
+gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
// Get the color render buffer and serial
// Also extract the render target dimensions and view
@@ -842,7 +897,7 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
bool missingColorRenderTarget = true;
- const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender();
+ const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(getWorkarounds());
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
@@ -863,17 +918,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer);
// Extract the render target dimensions and view
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
+ return error;
}
+ ASSERT(renderTarget);
framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
- if (!framebufferRTVs[colorAttachment])
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
- }
+ ASSERT(framebufferRTVs[colorAttachment]);
if (missingColorRenderTarget)
{
@@ -883,8 +937,12 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
missingColorRenderTarget = false;
}
- // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent
- // D3D11 warnings.
+#if !defined(NDEBUG)
+ // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
+ ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+ unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource);
+ unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource);
+#endif
}
}
@@ -905,19 +963,17 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
ID3D11DepthStencilView* framebufferDSV = NULL;
if (depthStencil)
{
- RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil);
- if (!depthStencilRenderTarget)
+ RenderTarget11 *depthStencilRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+ if (error.isError())
{
SafeRelease(framebufferRTVs);
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
+ return error;
}
+ ASSERT(depthStencilRenderTarget);
framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
- if (!framebufferDSV)
- {
- SafeRelease(framebufferRTVs);
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
- }
+ ASSERT(framebufferDSV);
// If there is no render buffer, the width, height and format values come from
// the depth stencil
@@ -964,17 +1020,16 @@ gl::Error Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
+ gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
if (error.isError())
{
return error;
}
- return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
+ return mInputLayoutCache.applyVertexBuffers(attributes, state.getCurrentProgramBinary());
}
gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
@@ -1011,28 +1066,25 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
return gl::Error(GL_NO_ERROR);
}
-void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
+void Renderer11::applyTransformFeedbackBuffers(const gl::State& state)
{
- ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+ size_t numXFBBindings = state.getTransformFeedbackBufferIndexRange();
+ ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+
bool requiresUpdate = false;
- for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (size_t i = 0; i < numXFBBindings; i++)
{
- if (transformFeedbackBuffers[i])
+ gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
+ GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
+ ID3D11Buffer *d3dBuffer = NULL;
+ if (curXFBBuffer)
{
- Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation());
- ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
-
- d3dBuffers[i] = buffer;
- d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1;
- }
- else
- {
- d3dBuffers[i] = NULL;
- d3dOffsets[i] = 0;
+ Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
}
- if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i])
+ // TODO: mAppliedTFBuffers and friends should also be kept in a vector.
+ if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i])
{
requiresUpdate = true;
}
@@ -1040,12 +1092,29 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff
if (requiresUpdate)
{
- mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets);
- for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (size_t i = 0; i < numXFBBindings; ++i)
{
- mAppliedTFBuffers[i] = d3dBuffers[i];
- mAppliedTFOffsets[i] = offsets[i];
+ gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
+ GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
+
+ if (curXFBBuffer)
+ {
+ Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+
+ mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer && mAppliedTFOffsets[i] != curXFBOffset) ?
+ static_cast<UINT>(curXFBOffset) : -1;
+ mAppliedTFBuffers[i] = d3dBuffer;
+ }
+ else
+ {
+ mAppliedTFBuffers[i] = NULL;
+ mCurrentD3DOffsets[i] = 0;
+ }
+ mAppliedTFOffsets[i] = curXFBOffset;
}
+
+ mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets);
}
}
@@ -1129,7 +1198,6 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
return gl::Error(GL_NO_ERROR);
}
}
-
template<typename T>
static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
{
@@ -1213,10 +1281,17 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- gl::Buffer *indexBuffer = elementArrayBuffer;
- BufferImpl *storage = indexBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
// TODO: some level 9 hardware supports 32-bit indices; test and store support instead
@@ -1291,10 +1366,17 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- gl::Buffer *indexBuffer = elementArrayBuffer;
- BufferImpl *storage = indexBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
@@ -1376,9 +1458,23 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
- ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
- ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
- ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+
+ ShaderExecutable *vertexExe = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *pixelExe = NULL;
+ error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *geometryExe = programD3D->getGeometryExecutable();
ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
@@ -1433,16 +1529,14 @@ gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::V
if (dirtyUniforms)
{
- programBinary->dirtyAllUniforms();
+ programD3D->dirtyAllUniforms();
}
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
+gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
{
- const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms();
-
unsigned int totalRegisterCountVS = 0;
unsigned int totalRegisterCountPS = 0;
@@ -1466,7 +1560,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
}
}
- const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation());
+ const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(&program);
const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
@@ -1598,7 +1692,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer);
if (error.isError())
@@ -1626,14 +1720,12 @@ void Renderer11::markAllStateDirty()
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{
mForceSetVertexSamplerStates[vsamplerId] = true;
- mCurVertexSRVs[vsamplerId] = NULL;
}
ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
{
mForceSetPixelSamplerStates[fsamplerId] = true;
- mCurPixelSRVs[fsamplerId] = NULL;
}
mForceSetBlendState = true;
@@ -1746,32 +1838,20 @@ bool Renderer11::testDeviceResettable()
return false;
}
- D3D_FEATURE_LEVEL featureLevels[] =
- {
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
-#if !defined(ANGLE_ENABLE_D3D9)
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1,
-#endif
- };
-
ID3D11Device* dummyDevice;
D3D_FEATURE_LEVEL dummyFeatureLevel;
ID3D11DeviceContext* dummyContext;
HRESULT result = D3D11CreateDevice(NULL,
- D3D_DRIVER_TYPE_HARDWARE,
+ mDriverType,
NULL,
#if defined(_DEBUG)
D3D11_CREATE_DEVICE_DEBUG,
#else
0,
#endif
- featureLevels,
- ArraySize(featureLevels),
+ mAvailableFeatureLevels.data(),
+ mAvailableFeatureLevels.size(),
D3D11_SDK_VERSION,
&dummyDevice,
&dummyFeatureLevel,
@@ -1939,119 +2019,37 @@ int Renderer11::getMaxSwapInterval() const
return 4;
}
-bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source);
- TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source);
- TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source);
- TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source)
-{
- if (source && dest)
- {
- TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source);
- TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest);
-
- mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
-
- dest11->invalidateSwizzleCache();
-
- return true;
- }
-
- return false;
-}
-
-bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
- if (!storage11)
- {
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2061,59 +2059,48 @@ bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
- if (!storage11)
- {
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2123,59 +2110,48 @@ bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
- if (!storage11)
- {
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2185,61 +2161,48 @@ bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- if (!colorbuffer)
- {
- ERR("Failed to retrieve the color buffer from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(colorbuffer);
- RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (!sourceRenderTarget)
+ RenderTarget11 *sourceRenderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target from the frame buffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(sourceRenderTarget);
ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
- if (!source)
- {
- ERR("Failed to retrieve the render target view from the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(source);
TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
- if (!storage11)
- {
- SafeRelease(source);
- ERR("Failed to retrieve the texture storage from the destination.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset);
- RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index));
- if (!destRenderTarget)
+ RenderTarget *destRenderTarget = NULL;
+ error = storage11->getRenderTarget(index, &destRenderTarget);
+ if (error.isError())
{
- SafeRelease(source);
- ERR("Failed to retrieve the render target from the destination storage.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(destRenderTarget);
- ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
- if (!dest)
- {
- ERR("Failed to retrieve the render target view from the destination render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
- }
+ ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest);
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
@@ -2249,12 +2212,15 @@ bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectan
// Use nearest filtering because source and destination are the same size for the direct
// copy
- bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
- destFormat, GL_NEAREST);
+ error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
+ if (error.isError())
+ {
+ return error;
+ }
storage11->invalidateSwizzleCacheLevel(level);
- return ret;
+ return gl::Error(GL_NO_ERROR);
}
void Renderer11::unapplyRenderTargets()
@@ -2277,39 +2243,150 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView
}
}
-RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
+gl::Error Renderer11::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
{
SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
- RenderTarget11 *renderTarget = NULL;
+ *outRT = new SurfaceRenderTarget11(swapChain11, depth);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
+{
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format);
- if (depth)
+ const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
+ GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+
+ if (width > 0 && height > 0)
{
- // Note: depth stencil may be NULL for 0 sized surfaces
- renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(),
- swapChain11->getDepthStencilTexture(),
- swapChain11->getDepthStencilShaderResource(),
- swapChain11->getWidth(), swapChain11->getHeight(), 1);
+ // Create texture resource
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = formatInfo.texFormat;
+ desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ // If a rendertarget or depthstencil format exists for this texture format,
+ // we'll flag it to allow binding that way. Shader resource views are a little
+ // more complicated.
+ bool bindRTV = false, bindDSV = false, bindSRV = false;
+ bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
+ bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+ if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ // Multisample targets flagged for binding as depth stencil cannot also be
+ // flagged for binding as SRV, so make certain not to add the SRV flag for
+ // these targets.
+ bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
+ }
+
+ desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
+ (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
+ (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
+
+ // The format must be either an RTV or a DSV
+ ASSERT(bindRTV != bindDSV);
+
+ ID3D11Texture2D *texture = NULL;
+ HRESULT result = mDevice->CreateTexture2D(&desc, NULL, &texture);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result);
+ }
+
+ ID3D11ShaderResourceView *srv = NULL;
+ if (bindSRV)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = formatInfo.srvFormat;
+ srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+
+ result = mDevice->CreateShaderResourceView(texture, &srvDesc, &srv);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ SafeRelease(texture);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result);
+ }
+ }
+
+ if (bindDSV)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = formatInfo.dsvFormat;
+ dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.Flags = 0;
+
+ ID3D11DepthStencilView *dsv = NULL;
+ result = mDevice->CreateDepthStencilView(texture, &dsvDesc, &dsv);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ SafeRelease(texture);
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result);
+ }
+
+ *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples);
+
+ SafeRelease(dsv);
+ }
+ else if (bindRTV)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = formatInfo.rtvFormat;
+ rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ rtvDesc.Texture2D.MipSlice = 0;
+
+ ID3D11RenderTargetView *rtv = NULL;
+ result = mDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv);
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ SafeRelease(texture);
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result);
+ }
+
+ if (formatInfo.dataInitializerFunction != NULL)
+ {
+ const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ mDeviceContext->ClearRenderTargetView(rtv, clearValues);
+ }
+
+ *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples);
+
+ SafeRelease(rtv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ SafeRelease(texture);
+ SafeRelease(srv);
}
else
{
- // Note: render target may be NULL for 0 sized surfaces
- renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(),
- swapChain11->getOffscreenTexture(),
- swapChain11->getRenderTargetShaderResource(),
- swapChain11->getWidth(), swapChain11->getHeight(), 1);
+ *outRT = new TextureRenderTarget11(reinterpret_cast<ID3D11RenderTargetView*>(NULL), NULL, NULL, format, width, height, 1, supportedSamples);
}
- return renderTarget;
-}
-RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples)
-{
- RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples);
- return renderTarget;
+ return gl::Error(GL_NO_ERROR);
}
-ShaderImpl *Renderer11::createShader(GLenum type)
+ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type)
{
- return new ShaderD3D(type, this);
+ return new ShaderD3D(data, type, this);
}
ProgramImpl *Renderer11::createProgram()
@@ -2322,22 +2399,23 @@ void Renderer11::releaseShaderCompiler()
ShaderD3D::releaseCompiler();
}
-ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers)
+gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable)
{
- ShaderExecutable11 *executable = NULL;
- HRESULT result;
-
switch (type)
{
- case rx::SHADER_VERTEX:
+ case SHADER_VERTEX:
{
ID3D11VertexShader *vertexShader = NULL;
ID3D11GeometryShader *streamOutShader = NULL;
- result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
+ HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result);
+ }
if (transformFeedbackVaryings.size() > 0)
{
@@ -2363,99 +2441,116 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(),
NULL, 0, 0, NULL, &streamOutShader);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create steam output shader, result: 0x%X.", result);
+ }
}
- if (vertexShader)
- {
- executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
- }
+ *outExecutable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
}
break;
- case rx::SHADER_PIXEL:
+ case SHADER_PIXEL:
{
ID3D11PixelShader *pixelShader = NULL;
- result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
+ HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
ASSERT(SUCCEEDED(result));
-
- if (pixelShader)
+ if (FAILED(result))
{
- executable = new ShaderExecutable11(function, length, pixelShader);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader, result: 0x%X.", result);
}
+
+ *outExecutable = new ShaderExecutable11(function, length, pixelShader);
}
break;
- case rx::SHADER_GEOMETRY:
+ case SHADER_GEOMETRY:
{
ID3D11GeometryShader *geometryShader = NULL;
- result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
+ HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
ASSERT(SUCCEEDED(result));
-
- if (geometryShader)
+ if (FAILED(result))
{
- executable = new ShaderExecutable11(function, length, geometryShader);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create geometry shader, result: 0x%X.", result);
}
+
+ *outExecutable = new ShaderExecutable11(function, length, geometryShader);
}
break;
default:
UNREACHABLE();
- break;
+ return gl::Error(GL_INVALID_OPERATION);
}
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround)
+gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable)
{
const char *profileType = NULL;
switch (type)
{
- case rx::SHADER_VERTEX:
+ case SHADER_VERTEX:
profileType = "vs";
break;
- case rx::SHADER_PIXEL:
+ case SHADER_PIXEL:
profileType = "ps";
break;
- case rx::SHADER_GEOMETRY:
+ case SHADER_GEOMETRY:
profileType = "gs";
break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
}
- const char *profileVersion = NULL;
+ unsigned int profileMajorVersion = 0;
+ unsigned int profileMinorVersion = 0;
+ const char *profileSuffix = NULL;
switch (mFeatureLevel)
{
case D3D_FEATURE_LEVEL_11_0:
- profileVersion = "5_0";
+ profileMajorVersion = 5;
+ profileMinorVersion = 0;
break;
case D3D_FEATURE_LEVEL_10_1:
- profileVersion = "4_1";
+ profileMajorVersion = 4;
+ profileMinorVersion = 1;
break;
case D3D_FEATURE_LEVEL_10_0:
- profileVersion = "4_0";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
break;
case D3D_FEATURE_LEVEL_9_3:
- profileVersion = "4_0_level_9_3";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
+ profileSuffix = "_level_9_3";
break;
case D3D_FEATURE_LEVEL_9_2:
- profileVersion = "4_0_level_9_2";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
+ profileSuffix = "_level_9_2";
break;
case D3D_FEATURE_LEVEL_9_1:
- profileVersion = "4_0_level_9_1";
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
+ profileSuffix = "_level_9_1";
break;
+ break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
}
- char profile[32];
- snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion);
+ std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
+ if (profileSuffix)
+ profile += profileSuffix;
- UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0;
+ UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
if (gl::perfActive())
{
@@ -2464,44 +2559,51 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
#endif
flags |= D3DCOMPILE_DEBUG;
-
- std::string sourcePath = getTempPath();
- std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
- writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
- const UINT extraFlags[] =
- {
- flags,
- flags | D3DCOMPILE_SKIP_VALIDATION,
- flags | D3DCOMPILE_SKIP_OPTIMIZATION
- };
+ std::vector<CompileConfig> configs;
+ configs.push_back(CompileConfig(flags, "default" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization"));
- const static char *extraFlagNames[] =
- {
- "default",
- "skip validation",
- "skip optimization"
- };
+ D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} };
- int attempts = ArraySize(extraFlags);
+ ID3DBlob *binary = NULL;
+ std::string debugInfo;
+ gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo);
+ if (error.isError())
+ {
+ return error;
+ }
- ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
+ // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL
+ // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK.
if (!binary)
{
- return NULL;
+ *outExectuable = NULL;
+ return gl::Error(GL_NO_ERROR);
}
- ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type,
- transformFeedbackVaryings, separatedOutputBuffers);
+ error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
+ transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
+
SafeRelease(binary);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!debugInfo.empty())
+ {
+ (*outExectuable)->appendDebugInfo(debugInfo);
+ }
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
+UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
{
return new UniformStorage11(this, storageSize);
}
@@ -2531,9 +2633,14 @@ QueryImpl *Renderer11::createQuery(GLenum type)
return new Query11(this, type);
}
-FenceImpl *Renderer11::createFence()
+FenceNVImpl *Renderer11::createFenceNV()
{
- return new Fence11(this);
+ return new FenceNV11(this);
+}
+
+FenceSyncImpl *Renderer11::createFenceSync()
+{
+ return new FenceSync11(this);
}
TransformFeedbackImpl* Renderer11::createTransformFeedback()
@@ -2576,82 +2683,77 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
return true;
}
-bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
+gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
}
-bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
+gl::Error Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut)
+
{
- ASSERT(colorbuffer != NULL);
+ ASSERT(colorbuffer);
- RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer);
- if (renderTarget)
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
{
- *subresourceIndex = renderTarget->getSubresourceIndex();
+ return error;
+ }
- ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView();
- if (colorBufferRTV)
- {
- ID3D11Resource *textureResource = NULL;
- colorBufferRTV->GetResource(&textureResource);
+ ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+ ASSERT(renderTargetResource);
- if (textureResource)
- {
- HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource);
- SafeRelease(textureResource);
+ *subresourceIndexOut = renderTarget->getSubresourceIndex();
+ *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource);
- if (SUCCEEDED(result))
- {
- return true;
- }
- else
- {
- ERR("Failed to extract the ID3D11Texture2D from the render target resource, "
- "HRESULT: 0x%X.", result);
- }
- }
- }
+ if (!(*texture2DOut))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget");
}
- return false;
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
+gl::Error Renderer11::blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter)
{
if (blitRenderTarget)
{
gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
+ ASSERT(readBuffer);
- if (!readBuffer)
+ RenderTarget *readRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the read buffer from the read framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
-
- RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
+ ASSERT(readRenderTarget);
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
if (drawTarget->isEnabledColorAttachment(colorAttachment))
{
gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
+ ASSERT(drawBuffer);
- if (!drawBuffer)
+ RenderTarget *drawRenderTarget = NULL;
+ error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the draw buffer from the draw framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawRenderTarget);
- RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
-
- if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
- blitRenderTarget, false, false))
+ error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget,
+ false, false);
+ if (error.isError())
{
- return false;
+ return error;
}
}
}
@@ -2660,78 +2762,88 @@ bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &read
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
- gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
+ ASSERT(readBuffer);
- if (!readBuffer)
+ RenderTarget *readRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(readRenderTarget);
- if (!drawBuffer)
+ gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
+ ASSERT(drawBuffer);
+
+ RenderTarget *drawRenderTarget = NULL;
+ error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawRenderTarget);
- RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer);
- RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer);
- ASSERT(readRenderTarget && drawRenderTarget);
-
- if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
- false, blitDepth, blitStencil))
+ error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false,
+ blitDepth, blitStencil);
+ if (error.isError())
{
- return false;
+ return error;
}
}
invalidateFramebufferSwizzles(drawTarget);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+gl::Error Renderer11::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
ID3D11Texture2D *colorBufferTexture = NULL;
unsigned int subresourceIndex = 0;
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
+ ASSERT(colorbuffer);
- if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+ gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture);
+ if (error.isError())
{
- gl::Rectangle area;
- area.x = x;
- area.y = y;
- area.width = width;
- area.height = height;
+ return error;
+ }
- gl::Buffer *packBuffer = pack.pixelBuffer.get();
- if (packBuffer != NULL)
- {
- rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
- PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
+ gl::Rectangle area;
+ area.x = x;
+ area.y = y;
+ area.width = width;
+ area.height = height;
- gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
- if (error.isError())
- {
- return error;
- }
+ gl::Buffer *packBuffer = pack.pixelBuffer.get();
+ if (packBuffer != NULL)
+ {
+ Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
+ PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
- packBuffer->getIndexRangeCache()->clear();
- }
- else
+ error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+ if (error.isError())
{
- gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
- if (error.isError())
- {
- return error;
- }
+ SafeRelease(colorBufferTexture);
+ return error;
}
- SafeRelease(colorBufferTexture);
+ packBuffer->getIndexRangeCache()->clear();
+ }
+ else
+ {
+ error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+ if (error.isError())
+ {
+ SafeRelease(colorBufferTexture);
+ return error;
+ }
}
+ SafeRelease(colorBufferTexture);
+
return gl::Error(GL_NO_ERROR);
}
@@ -2740,11 +2852,11 @@ Image *Renderer11::createImage()
return new Image11();
}
-void Renderer11::generateMipmap(Image *dest, Image *src)
+gl::Error Renderer11::generateMipmap(Image *dest, Image *src)
{
Image11 *dest11 = Image11::makeImage11(dest);
Image11 *src11 = Image11::makeImage11(src);
- Image11::generateMipmap(dest11, src11);
+ return Image11::generateMipmap(dest11, src11);
}
TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
@@ -2788,6 +2900,19 @@ TextureImpl *Renderer11::createTexture(GLenum target)
return NULL;
}
+RenderbufferImpl *Renderer11::createRenderbuffer()
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ return renderbuffer;
+}
+
+RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth)
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ renderbuffer->setStorage(swapChain, depth);
+ return renderbuffer;
+}
+
gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
@@ -2882,22 +3007,25 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub
SafeRelease(srcTex);
PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
- packPixels(stagingTex, packParams, pixels);
+ gl::Error error = packPixels(stagingTex, packParams, pixels);
SafeRelease(stagingTex);
- return gl::Error(GL_NO_ERROR);
+ return error;
}
-void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
+gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
{
D3D11_TEXTURE2D_DESC textureDesc;
readTexture->GetDesc(&textureDesc);
D3D11_MAPPED_SUBRESOURCE mapping;
HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
- UNUSED_ASSERTION_VARIABLE(hr);
- ASSERT(SUCCEEDED(hr));
+ if (FAILED(hr))
+ {
+ ASSERT(hr == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr);
+ }
uint8_t *source;
int inputPitch;
@@ -2968,24 +3096,23 @@ void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams
}
mDeviceContext->Unmap(readTexture, 0);
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
- RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
- bool colorBlit, bool depthBlit, bool stencilBlit)
+gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
+ RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
+ bool colorBlit, bool depthBlit, bool stencilBlit)
{
// Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
// it should never be the case that both color and depth/stencil need to be blitted at
// at the same time.
ASSERT(colorBlit != (depthBlit || stencilBlit));
- bool result = true;
-
RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
if (!drawRenderTarget)
{
- ERR("Failed to retrieve the draw render target from the draw framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer.");
}
ID3D11Resource *drawTexture = drawRenderTarget11->getTexture();
@@ -2996,8 +3123,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
if (!readRenderTarget)
{
- ERR("Failed to retrieve the read render target from the read framebuffer.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer.");
}
ID3D11Resource *readTexture = NULL;
@@ -3019,7 +3145,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
if (FAILED(hresult))
{
SafeRelease(readTexture);
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer.");
}
}
}
@@ -3036,8 +3162,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
{
SafeRelease(readTexture);
SafeRelease(readSRV);
- ERR("Failed to retrieve the read render target view from the read render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target.");
}
gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
@@ -3063,6 +3188,8 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat());
bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit);
+ gl::Error result(GL_NO_ERROR);
+
if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() &&
!stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
(!(depthBlit || stencilBlit) || wholeBufferCopy))
@@ -3109,7 +3236,7 @@ bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::R
mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0,
readTexture, readSubresource, pSrcBox);
- result = true;
+ result = gl::Error(GL_NO_ERROR);
}
else
{
@@ -3190,7 +3317,8 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta
ASSERT(attachment->isTexture());
gl::Texture *texture = attachment->getTexture();
- TextureStorage *texStorage = texture->getNativeTexture();
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureStorage *texStorage = textureD3D->getNativeTexture();
if (texStorage)
{
TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
@@ -3204,7 +3332,7 @@ void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *atta
}
}
-void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer)
+void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer)
{
for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
@@ -3248,7 +3376,7 @@ bool Renderer11::getLUID(LUID *adapterLuid) const
return true;
}
-rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
+VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
{
return d3d11::GetVertexFormatInfo(vertexFormat).conversionType;
}
@@ -3263,4 +3391,30 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC
d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions);
}
+Workarounds Renderer11::generateWorkarounds() const
+{
+ return d3d11::GenerateWorkarounds();
+}
+
+void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
+{
+ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
+
+ if (currentSRVs[resourceSlot] != srv)
+ {
+ if (shaderType == gl::SAMPLER_VERTEX)
+ {
+ mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
+ }
+ else
+ {
+ mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
+ }
+
+ currentSRVs[resourceSlot] = srv;
+ }
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 2a53fa1672..d44bd2fd30 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -13,12 +13,14 @@
#include "libGLESv2/angletypes.h"
#include "common/mathutil.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h"
#include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
+#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/RenderTarget.h"
+#include "libEGL/AttributeMap.h"
+
namespace gl
{
class FramebufferAttachment;
@@ -33,6 +35,7 @@ class StreamingIndexBufferInterface;
class Blit11;
class Clear11;
class PixelTransfer11;
+class RenderTarget11;
struct PackPixelsParams;
enum
@@ -41,10 +44,10 @@ enum
MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
};
-class Renderer11 : public Renderer
+class Renderer11 : public RendererD3D
{
public:
- Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay);
+ Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes);
virtual ~Renderer11();
static Renderer11 *makeRenderer11(Renderer *renderer);
@@ -55,19 +58,19 @@ class Renderer11 : public Renderer
virtual int generateConfigs(ConfigDesc **configDescList);
virtual void deleteConfigs(ConfigDesc *configDescList);
- virtual void sync(bool block);
+ virtual gl::Error sync(bool block);
- virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
virtual gl::Error generateSwizzle(gl::Texture *texture);
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask);
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
@@ -76,32 +79,32 @@ class Renderer11 : public Renderer
bool ignoreViewport);
virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer);
+ gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
- virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary);
- virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances);
+
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
+ virtual void applyTransformFeedbackBuffers(const gl::State &state);
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
- virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+ gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
virtual void markAllStateDirty();
// lost device
- void notifyDeviceLost();
- virtual bool isDeviceLost();
- virtual bool testDeviceLost(bool notify);
- virtual bool testDeviceResettable();
+ void notifyDeviceLost() override;
+ bool isDeviceLost() override;
+ bool testDeviceLost(bool notify) override;
+ bool testDeviceResettable() override;
- virtual DWORD getAdapterVendor() const;
- virtual std::string getRendererDescription() const;
- virtual GUID getAdapterIdentifier() const;
+ DWORD getAdapterVendor() const override;
+ std::string getRendererDescription() const override;
+ GUID getAdapterIdentifier() const override;
virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const;
@@ -115,47 +118,43 @@ class Renderer11 : public Renderer
virtual int getMaxSwapInterval() const;
// Pixel operations
- virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source);
-
- virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
- virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter);
+ gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) override;
- virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
// RenderTarget creation
- virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
- virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples);
+ virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
// Shader creation
- virtual ShaderImpl *createShader(GLenum type);
+ virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
virtual ProgramImpl *createProgram();
// Shader operations
- virtual void releaseShaderCompiler();
- virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers);
- virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround);
+ void releaseShaderCompiler() override;
+ virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable);
+ virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable);
virtual UniformStorage *createUniformStorage(size_t storageSize);
// Image operations
virtual Image *createImage();
- virtual void generateMipmap(Image *dest, Image *source);
+ gl::Error generateMipmap(Image *dest, Image *source) override;
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
@@ -165,6 +164,10 @@ class Renderer11 : public Renderer
// Texture creation
virtual TextureImpl *createTexture(GLenum target);
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer();
+ virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
+
// Buffer creation
virtual BufferImpl *createBuffer();
virtual VertexBuffer *createVertexBuffer();
@@ -175,7 +178,8 @@ class Renderer11 : public Renderer
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
- virtual FenceImpl *createFence();
+ virtual FenceNVImpl *createFenceNV();
+ virtual FenceSyncImpl *createFenceSync();
// Transform Feedback creation
virtual TransformFeedbackImpl* createTransformFeedback();
@@ -183,48 +187,54 @@ class Renderer11 : public Renderer
// D3D11-renderer specific methods
ID3D11Device *getDevice() { return mDevice; }
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
- IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+ DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; }
Blit11 *getBlitter() { return mBlit; }
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
- virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+
+ gl::Error getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut);
- bool getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
void unapplyRenderTargets();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
- void packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
+ gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
virtual bool getLUID(LUID *adapterLuid) const;
- virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
+ gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
+ GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
+
+ void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
+
private:
DISALLOW_COPY_AND_ASSIGN(Renderer11);
- virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const;
+ void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
+ Workarounds generateWorkarounds() const override;
gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
- gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
-
- bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
- RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
- bool colorBlit, bool depthBlit, bool stencilBlit);
+ gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
+ RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
+ bool colorBlit, bool depthBlit, bool stencilBlit);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
+ void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource);
static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
- static void invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer);
+ static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer);
HMODULE mD3d11Module;
HMODULE mDxgiModule;
EGLNativeDisplayType mDc;
- EGLint mRequestedDisplay;
+ std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
+ D3D_DRIVER_TYPE mDriverType;
HLSLCompiler mCompiler;
@@ -243,7 +253,7 @@ class Renderer11 : public Renderer
unsigned int mAppliedStencilbufferSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
- rx::RenderTarget::Desc mRenderTargetDesc;
+ RenderTarget::Desc mRenderTargetDesc;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
@@ -292,8 +302,14 @@ class Renderer11 : public Renderer
unsigned int mAppliedIBOffset;
// Currently applied transform feedback buffers
- ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+ ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers
+ // in use for streamout
+ GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified
+ // buffer offsets to transform feedback
+ // buffers
+ UINT mCurrentD3DOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the D3D buffer offsets,
+ // which may differ from GLs, due
+ // to different append behavior
// Currently applied shaders
ID3D11VertexShader *mAppliedVertexShader;
@@ -339,7 +355,7 @@ class Renderer11 : public Renderer
IDXGIAdapter *mDxgiAdapter;
DXGI_ADAPTER_DESC mAdapterDescription;
char mDescription[128];
- IDXGIFactory *mDxgiFactory;
+ DXGIFactory *mDxgiFactory;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
index 4b29be055d..52c8a81633 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
@@ -6,7 +6,6 @@
// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
-#include "common/platform.h"
#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
@@ -16,12 +15,16 @@
#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
+#include "common/features.h"
+#include "common/NativeWindow.h"
+
namespace rx
{
-SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
- : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+ : mRenderer(renderer),
+ SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
{
mSwapChain = NULL;
mBackBufferTexture = NULL;
@@ -39,8 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDL
mPassThroughPS = NULL;
mWidth = -1;
mHeight = -1;
- mViewportWidth = -1;
- mViewportHeight = -1;
+ mRotateL = false;
+ mRotateR = false;
mSwapInterval = 0;
mAppCreatedShareHandle = mShareHandle != NULL;
mPassThroughResourcesInit = false;
@@ -91,11 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
ASSERT(device != NULL);
// D3D11 does not allow zero size textures
- ASSERT(backbufferWidth >= 1);
- ASSERT(backbufferHeight >= 1);
+ ASSERT(backbufferWidth != 0);
+ ASSERT(backbufferHeight != 0);
// Preserve the render target content
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
if (previousOffscreenTexture)
{
@@ -137,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
mOffscreenTexture->GetDesc(&offscreenTextureDesc);
- if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
- offscreenTextureDesc.Height != (UINT)backbufferHeight ||
+ if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) ||
+ offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) ||
offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
offscreenTextureDesc.MipLevels != 1 ||
offscreenTextureDesc.ArraySize != 1)
@@ -150,11 +153,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
}
else
{
- const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
+ const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
- offscreenTextureDesc.Width = backbufferWidth;
- offscreenTextureDesc.Height = backbufferHeight;
+ offscreenTextureDesc.Width = abs(backbufferWidth);
+ offscreenTextureDesc.Height = abs(backbufferHeight);
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
offscreenTextureDesc.MipLevels = 1;
offscreenTextureDesc.ArraySize = 1;
@@ -234,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
if (mDepthBufferFormat != GL_NONE)
{
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
- depthStencilTextureDesc.Width = backbufferWidth;
- depthStencilTextureDesc.Height = backbufferHeight;
+ depthStencilTextureDesc.Width = abs(backbufferWidth);
+ depthStencilTextureDesc.Height = abs(backbufferHeight);
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
depthStencilTextureDesc.MipLevels = 1;
depthStencilTextureDesc.ArraySize = 1;
@@ -286,12 +289,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
mWidth = backbufferWidth;
mHeight = backbufferHeight;
-#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
- mViewportWidth = backbufferWidth;
- mViewportHeight = backbufferHeight;
-#endif
-#if !defined(ANGLE_PLATFORM_WINRT)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
if (previousOffscreenTexture != NULL)
{
D3D11_BOX sourceBox = {0};
@@ -310,7 +309,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
if (mSwapChain)
{
- swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL);
+ swapRect(0, 0, mWidth, mHeight);
}
}
#endif
@@ -327,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_BAD_ACCESS;
}
+ // Windows Phone works around the rotation limitation by using negative values for the swap chain size
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape
+ mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape
+ backbufferWidth = abs(backbufferWidth);
+ backbufferHeight = abs(backbufferHeight);
+#endif
+
// EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
- if (backbufferWidth < 1 || backbufferHeight < 1)
+ if (backbufferWidth == 0 || backbufferHeight == 0)
{
return EGL_SUCCESS;
}
@@ -336,19 +343,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
// Can only call resize if we have already created our swap buffer and resources
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone
SafeRelease(mBackBufferTexture);
SafeRelease(mBackBufferRTView);
// Resize swap chain
- HRESULT result;
-#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is
-#if !defined(ANGLE_PLATFORM_WINRT)
- const int bufferCount = 1;
-#else
- const int bufferCount = 2;
-#endif
+ DXGI_SWAP_CHAIN_DESC desc;
+ mSwapChain->GetDesc(&desc);
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
- result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
+ HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
if (FAILED(result))
{
@@ -364,7 +367,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_BAD_ALLOC;
}
}
-#endif
result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
ASSERT(SUCCEEDED(result));
@@ -379,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
{
d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
}
+#endif
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
}
@@ -412,62 +415,14 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
return EGL_SUCCESS;
}
- if (mWindow)
+ if (mNativeWindow.getNativeWindow())
{
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
- IDXGIFactory *factory = mRenderer->getDxgiFactory();
-
-#if !defined(ANGLE_PLATFORM_WINRT)
- DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
- swapChainDesc.BufferDesc.Width = backbufferWidth;
- swapChainDesc.BufferDesc.Height = backbufferHeight;
- swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
- swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
- swapChainDesc.BufferDesc.Format = backbufferFormatInfo.texFormat;
- swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
- swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.BufferCount = 1;
- swapChainDesc.OutputWindow = mWindow;
- swapChainDesc.Windowed = TRUE;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
- swapChainDesc.Flags = 0;
-
- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
-#else
- IDXGIFactory2 *factory2;
- HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2));
- ASSERT(SUCCEEDED(result));
-
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
- swapChainDesc.Width = 0;
- swapChainDesc.Height = 0;
- swapChainDesc.Format = backbufferFormatInfo.texFormat;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.Stereo = FALSE;
- swapChainDesc.Flags = 0;
-#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
- swapChainDesc.Scaling = DXGI_SCALING_NONE;
- swapChainDesc.BufferCount = 2;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
-#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- swapChainDesc.BufferCount = 1;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
-#endif
+ HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(),
+ backbufferFormatInfo.texFormat,
+ backbufferWidth, backbufferHeight, &mSwapChain);
- IDXGISwapChain1 *swapChain;
- result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
- mSwapChain = swapChain;
- HRESULT hr = swapChain->GetDesc1(&swapChainDesc);
- ASSERT(SUCCEEDED(hr));
- mViewportWidth = swapChainDesc.Width;
- mViewportHeight = swapChainDesc.Height;
-#endif
if (FAILED(result))
{
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
@@ -537,7 +492,7 @@ void SwapChain11::initPassThroughResources()
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
samplerDesc.MinLOD = 0;
- samplerDesc.MaxLOD = FLT_MAX;
+ samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
ASSERT(SUCCEEDED(result));
@@ -563,7 +518,7 @@ void SwapChain11::initPassThroughResources()
}
// parameters should be validated/clamped by caller
-EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags)
+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
@@ -573,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- // Set vertices
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
- if (FAILED(result))
- {
- return EGL_BAD_ACCESS;
- }
-
- d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
-
// Create a quad in homogeneous coordinates
float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
@@ -594,8 +539,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
- const int rotateL = flags & SWAP_ROTATE_90;
- const int rotateR = flags & SWAP_ROTATE_270;
+ const bool rotateL = mRotateL;
+ const bool rotateR = mRotateR;
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
@@ -628,22 +583,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
// Set the viewport
D3D11_VIEWPORT viewport;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
- viewport.Width = mViewportWidth;
- viewport.Height = mViewportHeight;
+ viewport.TopLeftX = 0.0f;
+ viewport.TopLeftY = 0.0f;
+ const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR);
+ viewport.Width = FLOAT(invertViewport ? mHeight : mWidth);
+ viewport.Height = FLOAT(invertViewport ? mWidth : mHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
- deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView);
deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
// Draw
deviceContext->Draw(4, 0);
-#ifdef ANGLE_FORCE_VSYNC_OFF
+#if ANGLE_VSYNC == ANGLE_DISABLED
result = mSwapChain->Present(0, 0);
#else
result = mSwapChain->Present(mSwapInterval, 0);
@@ -667,8 +623,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EG
}
// Unbind
- static ID3D11ShaderResourceView *const nullSRV = NULL;
- deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+ mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL);
mRenderer->unapplyRenderTargets();
mRenderer->markAllStateDirty();
@@ -708,8 +663,8 @@ ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
- return static_cast<rx::SwapChain11*>(swapChain);
+ ASSERT(HAS_DYNAMIC_TYPE(SwapChain11*, swapChain));
+ return static_cast<SwapChain11*>(swapChain);
}
void SwapChain11::recreate()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
index b30b78568a..77509edcd3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
@@ -19,13 +19,13 @@ class Renderer11;
class SwapChain11 : public SwapChain
{
public:
- SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+ SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain11();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags);
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
virtual ID3D11Texture2D *getOffscreenTexture();
@@ -52,13 +52,13 @@ class SwapChain11 : public SwapChain
Renderer11 *mRenderer;
EGLint mHeight;
EGLint mWidth;
- EGLint mViewportWidth;
- EGLint mViewportHeight;
+ bool mRotateL;
+ bool mRotateR;
bool mAppCreatedShareHandle;
unsigned int mSwapInterval;
bool mPassThroughResourcesInit;
- IDXGISwapChain *mSwapChain;
+ DXGISwapChain *mSwapChain;
ID3D11Texture2D *mBackBufferTexture;
ID3D11RenderTargetView *mBackBufferRTView;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
index 91e7147da6..74af27e8b3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -8,6 +8,9 @@
// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
+
+#include <tuple>
+
#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
@@ -15,6 +18,7 @@
#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
+#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "libGLESv2/main.h"
#include "libGLESv2/ImageIndex.h"
@@ -52,46 +56,16 @@ TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
{
}
-bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const
-{
- return baseLevel == rhs.baseLevel &&
- mipLevels == rhs.mipLevels &&
- swizzle == rhs.swizzle;
-}
-
-TextureStorage11::SRVCache::~SRVCache()
+bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const
{
- for (size_t i = 0; i < cache.size(); i++)
- {
- SafeRelease(cache[i].srv);
- }
+ return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle);
}
-ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const
-{
- for (size_t i = 0; i < cache.size(); i++)
- {
- if (cache[i].key == key)
- {
- return cache[i].srv;
- }
- }
-
- return NULL;
-}
-
-ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv)
-{
- SRVPair pair = {key, srv};
- cache.push_back(pair);
-
- return srv;
-}
-
-TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
+TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags)
: mBindFlags(bindFlags),
mTopLevel(0),
mMipLevels(0),
+ mInternalFormat(GL_NONE),
mTextureFormat(DXGI_FORMAT_UNKNOWN),
mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
@@ -114,6 +88,12 @@ TextureStorage11::~TextureStorage11()
{
SafeRelease(mLevelSRVs[level]);
}
+
+ for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++)
+ {
+ SafeRelease(i->second);
+ }
+ mSrvCache.clear();
}
TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
@@ -183,17 +163,16 @@ int TextureStorage11::getLevelDepth(int mipLevel) const
return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
}
-UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
+UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const
{
- UINT index = 0;
- if (getResource())
- {
- index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels);
- }
- return index;
+ UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel);
+ UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
+ UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ return subresource;
}
-ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
+gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV)
{
bool swizzleRequired = samplerState.swizzleRequired();
bool mipmapping = gl::IsMipmapFiltered(samplerState);
@@ -206,38 +185,71 @@ ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &sampl
{
verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
}
-
- SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
- ID3D11ShaderResourceView *srv = srvCache.find(key);
- if(srv)
+ SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
+ SRVCache::const_iterator iter = mSrvCache.find(key);
+ if (iter != mSrvCache.end())
{
- return srv;
+ *outSRV = iter->second;
}
+ else
+ {
+ ID3D11Resource *texture = NULL;
+ if (swizzleRequired)
+ {
+ gl::Error error = getSwizzleTexture(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
- DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
- ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource();
+ ID3D11ShaderResourceView *srv = NULL;
+ DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
+ gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mSrvCache.insert(std::make_pair(key, srv));
+ *outSRV = srv;
+ }
- srv = createSRV(samplerState.baseLevel, mipLevels, format, texture);
-
- return srvCache.add(key, srv);
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel)
+gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ if (!mLevelSRVs[mipLevel])
{
- if (!mLevelSRVs[mipLevel])
+ ID3D11Resource *resource = NULL;
+ gl::Error error = getResource(&resource);
+ if (error.isError())
{
- mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource());
+ return error;
}
- return mLevelSRVs[mipLevel];
- }
- else
- {
- return NULL;
+ error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ *outSRV = mLevelSRVs[mipLevel];
+
+ return gl::Error(GL_NO_ERROR);
}
gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -249,14 +261,25 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr
if (mSwizzleCache[level] != swizzleTarget)
{
// Need to re-render the swizzle for this level
- ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level);
- ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level);
+ ID3D11ShaderResourceView *sourceSRV = NULL;
+ gl::Error error = getSRVLevel(level, &sourceSRV);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11RenderTargetView *destRTV = NULL;
+ error = getSwizzleRenderTarget(level, &destRTV);
+ if (error.isError())
+ {
+ return error;
+ }
gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
Blit11 *blitter = mRenderer->getBlitter();
- gl::Error error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
+ error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
if (error.isError())
{
return error;
@@ -287,104 +310,120 @@ void TextureStorage11::invalidateSwizzleCache()
}
}
-bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
- int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
+ const gl::ImageIndex &index, const gl::Box &copyArea)
{
- if (srcTexture)
- {
- invalidateSwizzleCacheLevel(level);
+ ASSERT(srcTexture);
- gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
- gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth);
+ GLint level = index.mipIndex;
- bool fullCopy = copyArea.x == 0 &&
- copyArea.y == 0 &&
- copyArea.z == 0 &&
- copyArea.width == texSize.width &&
- copyArea.height == texSize.height &&
- copyArea.depth == texSize.depth;
+ invalidateSwizzleCacheLevel(level);
- ID3D11Resource *dstTexture = getResource();
- unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+ gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
- ASSERT(dstTexture);
+ bool fullCopy = copyArea.x == 0 &&
+ copyArea.y == 0 &&
+ copyArea.z == 0 &&
+ copyArea.width == texSize.width &&
+ copyArea.height == texSize.height &&
+ copyArea.depth == texSize.depth;
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
- {
- // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
- Blit11 *blitter = mRenderer->getBlitter();
+ ID3D11Resource *dstTexture = NULL;
+ gl::Error error = getResource(&dstTexture);
+ if (error.isError())
+ {
+ return error;
+ }
- return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
- dstTexture, dstSubresource, copyArea, texSize,
- NULL);
- }
- else
- {
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ unsigned int dstSubresource = getSubresourceIndex(index);
- D3D11_BOX srcBox;
- srcBox.left = copyArea.x;
- srcBox.top = copyArea.y;
- srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth);
- srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight);
- srcBox.front = copyArea.z;
- srcBox.back = copyArea.z + copyArea.depth;
+ ASSERT(dstTexture);
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
+ if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
+ {
+ // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
+ Blit11 *blitter = mRenderer->getBlitter();
- context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
- srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
- return true;
- }
+ return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
+ dstTexture, dstSubresource, copyArea, texSize,
+ NULL);
}
+ else
+ {
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- return false;
+ D3D11_BOX srcBox;
+ srcBox.left = copyArea.x;
+ srcBox.top = copyArea.y;
+ srcBox.right = copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatInfo.blockWidth);
+ srcBox.bottom = copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatInfo.blockHeight);
+ srcBox.front = copyArea.z;
+ srcBox.back = copyArea.z + copyArea.depth;
+
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
+ srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
+ return gl::Error(GL_NO_ERROR);
+ }
}
-bool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
- int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
+ const gl::ImageIndex &index, const gl::Box &region)
{
- if (dstTexture)
+ ASSERT(dstTexture);
+
+ ID3D11Resource *srcTexture = NULL;
+ gl::Error error = getResource(&srcTexture);
+ if (error.isError())
{
- ID3D11Resource *srcTexture = getResource();
- unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
+ return error;
+ }
- ASSERT(srcTexture);
+ ASSERT(srcTexture);
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ unsigned int srcSubresource = getSubresourceIndex(index);
- context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset,
- srcTexture, srcSubresource, NULL);
- return true;
- }
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z,
+ srcTexture, srcSubresource, NULL);
- return false;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
+gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- if (source && dest)
+ ASSERT(sourceIndex.layerIndex == destIndex.layerIndex);
+
+ invalidateSwizzleCacheLevel(destIndex.mipIndex);
+
+ RenderTarget *source = NULL;
+ gl::Error error = getRenderTarget(sourceIndex, &source);
+ if (error.isError())
{
- ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
- ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
+ return error;
+ }
- if (sourceSRV && destRTV)
- {
- gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
- gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
+ RenderTarget *dest = NULL;
+ error = getRenderTarget(destIndex, &dest);
+ if (error.isError())
+ {
+ return error;
+ }
- gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
- gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+ ID3D11ShaderResourceView *sourceSRV = RenderTarget11::makeRenderTarget11(source)->getShaderResourceView();
+ ID3D11RenderTargetView *destRTV = RenderTarget11::makeRenderTarget11(dest)->getRenderTargetView();
- Blit11 *blitter = mRenderer->getBlitter();
+ gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
+ gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
- blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
- gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
- }
- }
+ gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
+ gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+
+ Blit11 *blitter = mRenderer->getBlitter();
+ return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
+ gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
}
void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
@@ -396,7 +435,112 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree
}
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
+gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ ID3D11Resource *sourceResouce = NULL;
+ gl::Error error = getResource(&sourceResouce);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ TextureStorage11 *dest11 = TextureStorage11::makeTextureStorage11(destStorage);
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource, sourceResouce);
+
+ dest11->invalidateSwizzleCache();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
+{
+ ID3D11Resource *resource = NULL;
+ gl::Error error = getResource(&resource);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(resource);
+
+ UINT destSubresource = getSubresourceIndex(index);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat());
+
+ bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth));
+ ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
+
+ // TODO(jmadill): Handle compressed formats
+ // Compressed formats have different load syntax, so we'll have to handle them with slightly
+ // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
+ // with compressed formats in the calling logic.
+ ASSERT(!internalFormatInfo.compressed);
+
+ int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
+ int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
+ int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
+ UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment);
+ UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+
+ const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat());
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
+
+ size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
+
+ UINT bufferRowPitch = outputPixelSize * width;
+ UINT bufferDepthPitch = bufferRowPitch * height;
+
+ MemoryBuffer conversionBuffer;
+ if (!conversionBuffer.resize(bufferDepthPitch * depth))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
+ }
+
+ // TODO: fast path
+ LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
+ loadFunction(width, height, depth,
+ pixelData, srcRowPitch, srcDepthPitch,
+ conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ if (!fullUpdate)
+ {
+ ASSERT(destBox);
+
+ D3D11_BOX destD3DBox;
+ destD3DBox.left = destBox->x;
+ destD3DBox.right = destBox->x + destBox->width;
+ destD3DBox.top = destBox->y;
+ destD3DBox.bottom = destBox->y + destBox->height;
+ destD3DBox.front = 0;
+ destD3DBox.back = 1;
+
+ immediateContext->UpdateSubresource(resource, destSubresource,
+ &destD3DBox, conversionBuffer.data(),
+ bufferRowPitch, bufferDepthPitch);
+ }
+ else
+ {
+ immediateContext->UpdateSubresource(resource, destSubresource,
+ NULL, conversionBuffer.data(),
+ bufferRowPitch, bufferDepthPitch);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
: TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
mTexture(swapchain->getOffscreenTexture()),
mSwizzleTexture(NULL)
@@ -418,6 +562,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
mTextureHeight = texDesc.Height;
mTextureDepth = 1;
+ mInternalFormat = swapchain->GetBackBufferInternalFormat();
+
ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srv->GetDesc(&srvDesc);
@@ -439,7 +585,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
initializeSerials(1, 1);
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
mTexture(NULL),
mSwizzleTexture(NULL)
@@ -451,6 +597,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
mSwizzleRenderTargets[i] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -460,51 +608,11 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width; // Compressed texture size constraints?
- desc.Height = height;
- desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = 1;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = 1;
- }
- }
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = 1;
initializeSerials(getLevelCount(), 1);
}
@@ -521,7 +629,11 @@ TextureStorage11_2D::~TextureStorage11_2D()
if (imageAssociationCorrect)
{
// We must let the Images recover their data before we delete it from the TextureStorage.
- mAssociatedImages[i]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ // TODO: Find a way to report this back to the context
+ }
}
}
}
@@ -542,8 +654,10 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage
return static_cast<TextureStorage11_2D*>(storage);
}
-void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -552,8 +666,10 @@ void TextureStorage11_2D::associateImage(Image11* image, int level, int layerTar
}
}
-bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -566,8 +682,10 @@ bool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Ima
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -582,8 +700,10 @@ void TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11*
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -599,137 +719,168 @@ void TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Ima
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2D::getResource() const
+gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth; // Compressed texture size constraints?
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels;
+ desc.ArraySize = 1;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(!index.hasLayer());
int level = index.mipIndex;
+ ASSERT(level >= 0 && level < getLevelCount());
- if (level >= 0 && level < getLevelCount())
+ if (!mRenderTarget[level])
{
- if (!mRenderTarget[level])
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
{
- ID3D11ShaderResourceView *srv = getSRVLevel(level);
- if (!srv)
- {
- return NULL;
- }
-
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- ID3D11Device *device = mRenderer->getDevice();
+ return error;
+ }
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+ ID3D11ShaderResourceView *srv = NULL;
+ error = getSRVLevel(level, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
- ID3D11RenderTargetView *rtv;
- HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + level;
- mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- }
- else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- ID3D11Device *device = mRenderer->getDevice();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = mDepthStencilFormat;
- dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
- dsvDesc.Texture2D.MipSlice = mTopLevel + level;
- dsvDesc.Flags = 0;
+ mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
- ID3D11DepthStencilView *dsv;
- HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = mTopLevel + level;
+ dsvDesc.Flags = 0;
- mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11DepthStencilView *dsv;
+ HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
- // RenderTarget will take ownership of these resources
- SafeRelease(dsv);
- }
- else
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
- }
- return mRenderTarget[level];
- }
- else
- {
- return NULL;
+ mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(dsv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[level];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
- srvDesc.Texture2D.MipLevels = mipLevels;
-
- ID3D11ShaderResourceView *SRV = NULL;
+ srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels;
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11_2D::generateMipmaps()
+gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture)
{
- // Base level must already be defined
-
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
-
- gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ ASSERT(outTexture);
- generateMipmapLayer(source, dest);
- }
-}
-
-ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
-{
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -749,52 +900,52 @@ ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
- rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
- }
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
+ }
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
mTexture = NULL;
@@ -803,13 +954,15 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
mSwizzleRenderTargets[level] = NULL;
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
mAssociatedImages[face][level] = NULL;
mRenderTarget[face][level] = NULL;
}
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -819,56 +972,23 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internal
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- // adjust size if needed for compressed textures
- int height = size;
- d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
+ // adjust size if needed for compressed textures
+ int height = size;
+ d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = size;
- desc.Height = size;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = 6;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = 1;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mTextureDepth = 1;
- initializeSerials(getLevelCount() * 6, 6);
+ initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
-
TextureStorage11_Cube::~TextureStorage11_Cube()
{
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
if (mAssociatedImages[face][level] != NULL)
{
@@ -890,7 +1010,7 @@ TextureStorage11_Cube::~TextureStorage11_Cube()
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
SafeRelease(mSwizzleRenderTargets[level]);
- for (unsigned int face = 0; face < 6; face++)
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
{
SafeDelete(mRenderTarget[face][level]);
}
@@ -903,25 +1023,31 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS
return static_cast<TextureStorage11_Cube*>(storage);
}
-void TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
mAssociatedImages[layerTarget][level] = image;
}
}
}
-bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
@@ -934,14 +1060,17 @@ bool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, I
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
@@ -954,14 +1083,17 @@ void TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image1
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(0 <= layerTarget && layerTarget < 6);
+ ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT);
if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
{
- if (0 <= layerTarget && layerTarget < 6)
+ if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT)
{
// No need to let the old Image recover its data, if it is also the incoming Image.
if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
@@ -974,114 +1106,165 @@ void TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, I
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_Cube::getResource() const
+gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = CUBE_FACE_COUNT;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
int faceIndex = index.layerIndex;
int level = index.mipIndex;
- if (level >= 0 && level < getLevelCount())
- {
- if (!mRenderTarget[faceIndex][level])
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ASSERT(level >= 0 && level < getLevelCount());
+ ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT);
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
- srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
- srvDesc.Texture2DArray.MipLevels = 1;
- srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- srvDesc.Texture2DArray.ArraySize = 1;
+ if (!mRenderTarget[faceIndex][level])
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- ID3D11ShaderResourceView *srv;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
- rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- rtvDesc.Texture2DArray.ArraySize = 1;
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ rtvDesc.Texture2DArray.ArraySize = 1;
- mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
- else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
- dsvDesc.Format = mDepthStencilFormat;
- dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
- dsvDesc.Flags = 0;
- dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
- dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
- dsvDesc.Texture2DArray.ArraySize = 1;
-
- ID3D11DepthStencilView *dsv;
- result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
-
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
- mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
+ mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
- // RenderTarget will take ownership of these resources
- SafeRelease(dsv);
- SafeRelease(srv);
- }
- else
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ SafeRelease(srv);
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Flags = 0;
+ dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ dsvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11DepthStencilView *dsv;
+ result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv);
+
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result);
}
- }
- return mRenderTarget[faceIndex][level];
- }
- else
- {
- return NULL;
+ mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(dsv);
+ SafeRelease(srv);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[faceIndex][level];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
@@ -1093,7 +1276,7 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi
srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = 0;
- srvDesc.Texture2DArray.ArraySize = 6;
+ srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
}
else
{
@@ -1102,43 +1285,22 @@ ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mi
srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
}
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage11_Cube::generateMipmaps()
+gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture)
{
- // Base level must already be defined
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
- {
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
-
- gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ ASSERT(outTexture);
- generateMipmapLayer(source, dest);
- }
- }
-}
-
-ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
-{
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -1147,7 +1309,7 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
desc.Width = mTextureWidth;
desc.Height = mTextureHeight;
desc.MipLevels = mMipLevels;
- desc.ArraySize = 6;
+ desc.ArraySize = CUBE_FACE_COUNT;
desc.Format = mSwizzleTextureFormat;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
@@ -1158,55 +1320,54 @@ ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = 0;
- rtvDesc.Texture2DArray.ArraySize = 6;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
+TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
@@ -1220,6 +1381,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform
mSwizzleRenderTargets[i] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -1229,49 +1392,13 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalform
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // If the width, height or depth are not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0 && depth > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE3D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.Depth = depth;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.Format = mTextureFormat;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = desc.Depth;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
initializeSerials(getLevelCount() * depth, depth);
}
@@ -1315,8 +1442,10 @@ TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage
return static_cast<TextureStorage11_3D*>(storage);
}
-void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1325,8 +1454,10 @@ void TextureStorage11_3D::associateImage(Image11* image, int level, int layerTar
}
}
-bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -1339,8 +1470,10 @@ bool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Ima
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+
ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1355,8 +1488,10 @@ void TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11*
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+
ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1372,148 +1507,188 @@ void TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Ima
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[level]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_3D::getResource() const
+gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // If the width, height or depth are not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.Depth = mTextureDepth;
+ desc.MipLevels = mMipLevels;
+ desc.Format = mTextureFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
+ ASSERT(outSRV);
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
srvDesc.Texture3D.MostDetailedMip = baseLevel;
srvDesc.Texture3D.MipLevels = mipLevels;
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
int mipLevel = index.mipIndex;
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
- if (mipLevel >= 0 && mipLevel < getLevelCount())
- {
- ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
+ ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
- if (!index.hasLayer())
+ if (!index.hasLayer())
+ {
+ if (!mLevelRenderTargets[mipLevel])
{
- if (!mLevelRenderTargets[mipLevel])
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
{
- ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
- if (!srv)
- {
- return NULL;
- }
-
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
-
- ID3D11RenderTargetView *rtv;
- HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ID3D11ShaderResourceView *srv = NULL;
+ error = getSRVLevel(mipLevel, &srv);
+ if (error.isError())
+ {
+ return error;
+ }
- mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
+ ID3D11Device *device = mRenderer->getDevice();
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- }
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = -1;
- return mLevelRenderTargets[mipLevel];
- }
- else
- {
- int layer = index.layerIndex;
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- LevelLayerKey key(mipLevel, layer);
- if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
-
- // TODO, what kind of SRV is expected here?
- ID3D11ShaderResourceView *srv = NULL;
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = layer;
- rtvDesc.Texture3D.WSize = 1;
+ mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(outRT);
+ *outRT = mLevelRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ int layer = index.layerIndex;
- mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+ LevelLayerKey key(mipLevel, layer);
+ if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- SafeRelease(srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
}
- return mLevelLayerRenderTargets[key];
- }
- }
+ // TODO, what kind of SRV is expected here?
+ ID3D11ShaderResourceView *srv = NULL;
- return NULL;
-}
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = layer;
+ rtvDesc.Texture3D.WSize = 1;
-void TextureStorage11_3D::generateMipmaps()
-{
- // Base level must already be defined
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- for (int level = 1; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
+ ASSERT(SUCCEEDED(result));
- gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1);
- gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level);
+ mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
- generateMipmapLayer(source, dest);
+ ASSERT(outRT);
+ *outRT = mLevelLayerRenderTargets[key];
+ return gl::Error(GL_NO_ERROR);
}
}
-ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
+gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture)
{
+ ASSERT(outTexture);
+
if (!mSwizzleTexture)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -1531,55 +1706,54 @@ ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
- rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = -1;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
+TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
: TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
{
@@ -1591,6 +1765,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in
mSwizzleRenderTargets[level] = NULL;
}
+ mInternalFormat = internalformat;
+
const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
@@ -1600,51 +1776,13 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum in
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
- // if the width, height or depth is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0 && depth > 0)
- {
- // adjust size if needed for compressed textures
- d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
- ID3D11Device *device = mRenderer->getDevice();
-
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
- desc.ArraySize = depth;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
- desc.SampleDesc.Quality = 0;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = getBindFlags();
- desc.CPUAccessFlags = 0;
- desc.MiscFlags = 0;
-
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
-
- // this can happen from windows TDR
- if (d3d11::isDeviceLostError(result))
- {
- mRenderer->notifyDeviceLost();
- gl::error(GL_OUT_OF_MEMORY);
- }
- else if (FAILED(result))
- {
- ASSERT(result == E_OUTOFMEMORY);
- ERR("Creating image failed.");
- gl::error(GL_OUT_OF_MEMORY);
- }
- else
- {
- mTexture->GetDesc(&desc);
- mMipLevels = desc.MipLevels;
- mTextureWidth = desc.Width;
- mTextureHeight = desc.Height;
- mTextureDepth = desc.ArraySize;
- }
- }
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
initializeSerials(getLevelCount() * depth, depth);
}
@@ -1685,8 +1823,11 @@ TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray
return static_cast<TextureStorage11_2DArray*>(storage);
}
-void TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget)
+void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
ASSERT(0 <= level && level < getLevelCount());
if (0 <= level && level < getLevelCount())
@@ -1696,8 +1837,11 @@ void TextureStorage11_2DArray::associateImage(Image11* image, int level, int lay
}
}
-bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
+bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
// This validation check should never return false. It means the Image/TextureStorage association is broken.
@@ -1707,8 +1851,11 @@ bool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget
}
// disassociateImage allows an Image to end its association with a Storage.
-void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage)
+void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
@@ -1721,8 +1868,11 @@ void TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Ima
}
// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
-void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
+gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage)
{
+ GLint level = index.mipIndex;
+ GLint layerTarget = index.layerIndex;
+
LevelLayerKey key(level, layerTarget);
ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
@@ -1739,18 +1889,62 @@ void TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget
{
// Force the image to recover from storage before its data is overwritten.
// This will reset mAssociatedImages[level] to NULL too.
- mAssociatedImages[key]->recoverFromAssociatedStorage();
+ gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2DArray::getResource() const
+gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource)
{
- return mTexture;
+ // if the width, height or depth is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = mTextureDepth;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result);
+ }
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
+gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = format;
@@ -1760,112 +1954,94 @@ ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.ArraySize = mTextureDepth;
- ID3D11ShaderResourceView *SRV = NULL;
-
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
- return SRV;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
{
ASSERT(index.hasLayer());
int mipLevel = index.mipIndex;
int layer = index.layerIndex;
- if (mipLevel >= 0 && mipLevel < getLevelCount())
- {
- LevelLayerKey key(mipLevel, layer);
- if (mRenderTargets.find(key) == mRenderTargets.end())
- {
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result;
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
- D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
- srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
- srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
- srvDesc.Texture2DArray.MipLevels = 1;
- srvDesc.Texture2DArray.FirstArraySlice = layer;
- srvDesc.Texture2DArray.ArraySize = 1;
+ LevelLayerKey key(mipLevel, layer);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
- ID3D11ShaderResourceView *srv;
- result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+ ID3D11Resource *texture = NULL;
+ gl::Error error = getResource(&texture);
+ if (error.isError())
+ {
+ return error;
+ }
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = layer;
+ srvDesc.Texture2DArray.ArraySize = 1;
- if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
- {
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = layer;
- rtvDesc.Texture2DArray.ArraySize = 1;
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
- ID3D11RenderTargetView *rtv;
- result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result);
+ }
- if (result == E_OUTOFMEMORY)
- {
- SafeRelease(srv);
- return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = layer;
+ rtvDesc.Texture2DArray.ArraySize = 1;
- mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
- // RenderTarget will take ownership of these resources
- SafeRelease(rtv);
- SafeRelease(srv);
- }
- else
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- UNREACHABLE();
+ SafeRelease(srv);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
}
- }
-
- return mRenderTargets[key];
- }
- else
- {
- return NULL;
- }
-}
-void TextureStorage11_2DArray::generateMipmaps()
-{
- // Base level must already be defined
+ mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0);
- for (int level = 0; level < getLevelCount(); level++)
- {
- invalidateSwizzleCacheLevel(level);
- for (unsigned int layer = 0; layer < mTextureDepth; layer++)
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ SafeRelease(srv);
+ }
+ else
{
- gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer);
- gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer);
-
- RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex));
- RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
-
- generateMipmapLayer(source, dest);
+ UNREACHABLE();
}
}
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[key];
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
+gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture)
{
if (!mSwizzleTexture)
{
@@ -1886,52 +2062,51 @@ ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
- if (result == E_OUTOFMEMORY)
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
{
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result);
}
- ASSERT(SUCCEEDED(result));
}
- return mSwizzleTexture;
+ *outTexture = mSwizzleTexture;
+ return gl::Error(GL_NO_ERROR);
}
-ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel)
+gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV)
{
- if (mipLevel >= 0 && mipLevel < getLevelCount())
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel])
{
- if (!mSwizzleRenderTargets[mipLevel])
+ ID3D11Resource *swizzleTexture = NULL;
+ gl::Error error = getSwizzleTexture(&swizzleTexture);
+ if (error.isError())
{
- ID3D11Resource *swizzleTexture = getSwizzleTexture();
- if (!swizzleTexture)
- {
- return NULL;
- }
+ return error;
+ }
- ID3D11Device *device = mRenderer->getDevice();
+ ID3D11Device *device = mRenderer->getDevice();
- D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
- rtvDesc.Format = mSwizzleRenderTargetFormat;
- rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
- rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
- rtvDesc.Texture2DArray.FirstArraySlice = 0;
- rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mSwizzleRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
- HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
+ HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
- if (result == E_OUTOFMEMORY)
- {
- return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
- }
- ASSERT(SUCCEEDED(result));
+ ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result);
}
-
- return mSwizzleRenderTargets[mipLevel];
- }
- else
- {
- return NULL;
}
+
+ *outRTV = mSwizzleRenderTargets[mipLevel];
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
index 9d63b2699d..930300a63d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
@@ -25,7 +25,6 @@ namespace rx
{
class RenderTarget;
class RenderTarget11;
-class Renderer;
class Renderer11;
class SwapChain11;
class Image11;
@@ -41,47 +40,49 @@ class TextureStorage11 : public TextureStorage
UINT getBindFlags() const;
- virtual ID3D11Resource *getResource() const = 0;
- virtual ID3D11ShaderResourceView *getSRV(const gl::SamplerState &samplerState);
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
+ virtual gl::Error getResource(ID3D11Resource **outResource) = 0;
+ virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
virtual int getLevelCount() const;
- UINT getSubresourceIndex(int mipLevel, int layerTarget) const;
+ UINT getSubresourceIndex(const gl::ImageIndex &index) const;
gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
void invalidateSwizzleCacheLevel(int mipLevel);
void invalidateSwizzleCache();
- bool updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, int level,
- int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource,
+ const gl::ImageIndex &index, const gl::Box &copyArea);
- bool copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, int level,
- int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
+ const gl::ImageIndex &index, const gl::Box &region);
- virtual void associateImage(Image11* image, int level, int layerTarget) = 0;
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage) = 0;
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage) = 0;
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage) = 0;
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index) = 0;
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) = 0;
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) = 0;
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) = 0;
+
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
+ virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
protected:
- TextureStorage11(Renderer *renderer, UINT bindFlags);
- void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest);
+ TextureStorage11(Renderer11 *renderer, UINT bindFlags);
int getLevelWidth(int mipLevel) const;
int getLevelHeight(int mipLevel) const;
int getLevelDepth(int mipLevel) const;
- virtual ID3D11Resource *getSwizzleTexture() = 0;
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel) = 0;
- ID3D11ShaderResourceView *getSRVLevel(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0;
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0;
+ gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture) = 0;
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const = 0;
void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
@@ -89,6 +90,7 @@ class TextureStorage11 : public TextureStorage
int mTopLevel;
unsigned int mMipLevels;
+ GLenum mInternalFormat;
DXGI_FORMAT mTextureFormat;
DXGI_FORMAT mShaderResourceFormat;
DXGI_FORMAT mRenderTargetFormat;
@@ -115,69 +117,53 @@ class TextureStorage11 : public TextureStorage
};
SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
+
+ const UINT mBindFlags;
+
struct SRVKey
{
SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false);
- bool operator==(const SRVKey &rhs) const;
+ bool operator<(const SRVKey &rhs) const;
int baseLevel;
int mipLevels;
bool swizzle;
};
+ typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache;
- struct SRVPair
- {
- SRVKey key;
- ID3D11ShaderResourceView *srv;
- };
-
- struct SRVCache
- {
- ~SRVCache();
-
- ID3D11ShaderResourceView *find(const SRVKey &key) const;
- ID3D11ShaderResourceView *add(const SRVKey &key, ID3D11ShaderResourceView *srv);
-
- std::vector<SRVPair> cache;
- };
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
-
- const UINT mBindFlags;
-
- SRVCache srvCache;
+ SRVCache mSrvCache;
ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureStorage11_2D : public TextureStorage11
{
public:
- TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain);
- TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
+ TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain);
+ TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual ~TextureStorage11_2D();
static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
ID3D11Texture2D *mTexture;
RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
@@ -191,68 +177,68 @@ class TextureStorage11_2D : public TextureStorage11
class TextureStorage11_Cube : public TextureStorage11
{
public:
- TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
+ TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
virtual ~TextureStorage11_Cube();
static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
+
+ static const size_t CUBE_FACE_COUNT = 6;
ID3D11Texture2D *mTexture;
- RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ RenderTarget11 *mRenderTarget[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
ID3D11Texture2D *mSwizzleTexture;
ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
- Image11 *mAssociatedImages[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ Image11 *mAssociatedImages[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
class TextureStorage11_3D : public TextureStorage11
{
public:
- TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
+ TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual ~TextureStorage11_3D();
static TextureStorage11_3D *makeTextureStorage11_3D(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
+ virtual gl::Error getResource(ID3D11Resource **outResource);
// Handles both layer and non-layer RTs
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
typedef std::pair<int, int> LevelLayerKey;
typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap;
@@ -270,30 +256,29 @@ class TextureStorage11_3D : public TextureStorage11
class TextureStorage11_2DArray : public TextureStorage11
{
public:
- TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
+ TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual ~TextureStorage11_2DArray();
static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage);
- virtual ID3D11Resource *getResource() const;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
-
- virtual void generateMipmaps();
+ virtual gl::Error getResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
- virtual void associateImage(Image11* image, int level, int layerTarget);
- virtual void disassociateImage(int level, int layerTarget, Image11* expectedImage);
- virtual bool isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage);
- virtual void releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage);
+ virtual void associateImage(Image11* image, const gl::ImageIndex &index);
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
+ virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
protected:
- virtual ID3D11Resource *getSwizzleTexture();
- virtual ID3D11RenderTargetView *getSwizzleRenderTarget(int mipLevel);
+ virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
+ virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray);
- virtual ID3D11ShaderResourceView *createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture);
+ virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
+ ID3D11ShaderResourceView **outSRV) const;
typedef std::pair<int, int> LevelLayerKey;
typedef std::map<LevelLayerKey, RenderTarget11*> RenderTargetMap;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
index 590cb9f05a..70bc3bb26f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
@@ -19,7 +19,7 @@ class Renderer11;
class VertexArray11 : public VertexArrayImpl
{
public:
- VertexArray11(rx::Renderer11 *renderer)
+ VertexArray11(Renderer11 *renderer)
: VertexArrayImpl(),
mRenderer(renderer)
{
@@ -34,7 +34,7 @@ class VertexArray11 : public VertexArrayImpl
private:
DISALLOW_COPY_AND_ASSIGN(VertexArray11);
- rx::Renderer11 *mRenderer;
+ Renderer11 *mRenderer;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
index 9bc5b1d2d1..a9d6fa2ca4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -16,7 +16,7 @@
namespace rx
{
-VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
+VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
{
mBuffer = NULL;
mBufferSize = 0;
@@ -91,8 +91,13 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
{
if (buffer)
{
- Buffer11 *storage = Buffer11::makeBuffer11(buffer->getImplementation());
- input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
+ BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
+ gl::Error error = storage->getData(&input);
+ if (error.isError())
+ {
+ return error;
+ }
+ input += static_cast<int>(attrib.offset);
}
else
{
@@ -132,7 +137,7 @@ gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GL
else
{
// Round up to divisor, if possible
- elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+ elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
gl::VertexFormat vertexFormat(attrib);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
index 0e10da1df8..a9bbac98fa 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
@@ -18,7 +18,7 @@ class Renderer11;
class VertexBuffer11 : public VertexBuffer
{
public:
- explicit VertexBuffer11(rx::Renderer11 *const renderer);
+ explicit VertexBuffer11(Renderer11 *const renderer);
virtual ~VertexBuffer11();
virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
@@ -40,7 +40,7 @@ class VertexBuffer11 : public VertexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
- rx::Renderer11 *const mRenderer;
+ Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
index c07828757d..90a879e170 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
@@ -795,7 +795,7 @@ static D3D11ES3FormatMap BuildD3D11FormatMap()
// From GL_EXT_texture_storage
// | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
+ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
index 2af97e73f0..121aa3bbad 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -10,6 +10,7 @@
#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Framebuffer.h"
@@ -95,9 +96,6 @@
#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
#endif
-#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT
-# define D3D11_VS_OUTPUT_REGISTER_COUNT 32
-#endif
namespace rx
{
@@ -357,7 +355,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -377,7 +375,7 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
@@ -399,7 +397,7 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -421,7 +419,7 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -441,7 +439,7 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -466,7 +464,7 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -486,7 +484,7 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
@@ -506,7 +504,7 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
@@ -526,7 +524,7 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
@@ -546,7 +544,7 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
@@ -566,7 +564,7 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
@@ -586,7 +584,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
@@ -612,7 +610,7 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -636,7 +634,7 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -655,7 +653,7 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
@@ -677,7 +675,7 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
@@ -704,7 +702,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
@@ -733,7 +731,7 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
@@ -754,7 +752,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
@@ -778,7 +776,7 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
@@ -805,7 +803,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
@@ -826,7 +824,7 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
@@ -847,7 +845,7 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
@@ -868,7 +866,7 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
@@ -889,7 +887,7 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
@@ -914,7 +912,7 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
@@ -935,7 +933,7 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
@@ -951,11 +949,11 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
}
}
-static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel)
+static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -971,14 +969,14 @@ static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL fea
}
}
-static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel)
+static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if _MSC_VER >= 1700
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
#endif
- case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) /
+ case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
GetMaximumStreamOutputBuffers(featureLevel);
@@ -1087,9 +1085,9 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
// Transform feedback limits
- caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel);
+ caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponents(featureLevel);
caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
- caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel);
+ caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateComponents(featureLevel);
// GL extension support
extensions->setTextureExtensionSupport(*textureCapsMap);
@@ -1198,17 +1196,31 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
{
-#if !defined(__MINGW32__) && defined(_DEBUG)
+#if defined(_DEBUG) && !defined(__MINGW32__)
return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
#else
return S_OK;
#endif
}
-RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT)
+{
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ *outRT = RenderTarget11::makeRenderTarget11(renderTarget);
+ return gl::Error(GL_NO_ERROR);
+}
+
+Workarounds GenerateWorkarounds()
{
- RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
- return RenderTarget11::makeRenderTarget11(renderTarget);
+ Workarounds workarounds;
+ workarounds.mrtPerfWorkaround = true;
+ workarounds.setDataFasterThanImageUpload = true;
+ return workarounds;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
index 4c05eb9256..9df9c95763 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
@@ -12,6 +12,7 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
#include <vector>
@@ -23,6 +24,7 @@ class FramebufferAttachment;
namespace rx
{
class RenderTarget11;
+struct Workarounds;
namespace gl_d3d11
{
@@ -176,7 +178,9 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu
context->Unmap(constantBuffer, 0);
}
-RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT);
+
+Workarounds GenerateWorkarounds();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
index f061a32c52..2ca7a9cf8a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
@@ -46,10 +46,16 @@ const size_t g_shaderSize[] =
namespace rx
{
-Blit9::Blit9(rx::Renderer9 *renderer)
- : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL)
+
+Blit9::Blit9(Renderer9 *renderer)
+ : mRenderer(renderer),
+ mGeometryLoaded(false),
+ mQuadVertexBuffer(NULL),
+ mQuadVertexDeclaration(NULL),
+ mSavedStateBlock(NULL),
+ mSavedRenderTarget(NULL),
+ mSavedDepthStencil(NULL)
{
- initGeometry();
memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
}
@@ -65,8 +71,13 @@ Blit9::~Blit9()
}
}
-void Blit9::initGeometry()
+gl::Error Blit9::initialize()
{
+ if (mGeometryLoaded)
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
static const float quad[] =
{
-1, -1,
@@ -82,7 +93,7 @@ void Blit9::initGeometry()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal blit vertex shader, result: 0x%X.", result);
}
void *lockPtr = NULL;
@@ -91,7 +102,8 @@ void Blit9::initGeometry()
if (FAILED(result) || lockPtr == NULL)
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY);
+ SafeRelease(mQuadVertexBuffer);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex shader, result: 0x%X.", result);
}
memcpy(lockPtr, quad, sizeof(quad));
@@ -108,14 +120,18 @@ void Blit9::initGeometry()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY);
+ SafeRelease(mQuadVertexBuffer);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex declaration, result: 0x%X.", result);
}
+
+ mGeometryLoaded = true;
+ return gl::Error(GL_NO_ERROR);
}
template <class D3DShaderType>
-bool Blit9::setShader(ShaderId source, const char *profile,
- D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length),
- HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
+gl::Error Blit9::setShader(ShaderId source, const char *profile,
+ gl::Error (Renderer9::*createShader)(const DWORD *, size_t length, D3DShaderType **outShader),
+ HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
{
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -130,35 +146,32 @@ bool Blit9::setShader(ShaderId source, const char *profile,
const BYTE* shaderCode = g_shaderCode[source];
size_t shaderSize = g_shaderSize[source];
- shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
- if (!shader)
+ gl::Error error = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize, &shader);
+ if (error.isError())
{
- ERR("Failed to create shader for blit operation");
- return false;
+ return error;
}
mCompiledShaders[source] = shader;
}
HRESULT hr = (device->*setShader)(shader);
-
if (FAILED(hr))
{
- ERR("Failed to set shader for blit operation");
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to set shader for blit operation, result: 0x%X.", hr);
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit9::setVertexShader(ShaderId shader)
+gl::Error Blit9::setVertexShader(ShaderId shader)
{
- return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
+ return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
}
-bool Blit9::setPixelShader(ShaderId shader)
+gl::Error Blit9::setPixelShader(ShaderId shader)
{
- return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
+ return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
}
RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const
@@ -175,12 +188,19 @@ RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const
return rect;
}
-bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
- IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
- if (!texture)
+ gl::Error error = initialize();
+ if (error.isError())
{
- return false;
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = NULL;
+ error = copySurfaceToTexture(source, getSurfaceRect(source), &texture);
+ if (error.isError())
+ {
+ return error;
}
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -205,87 +225,90 @@ bool Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
restoreState();
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-bool Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
{
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *source = NULL;
- gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
-
- if (colorbuffer)
+ gl::Error error = initialize();
+ if (error.isError())
{
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+ return error;
}
- if (renderTarget)
- {
- source = renderTarget->getSurface();
- }
+ gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+ ASSERT(colorbuffer);
- if (!source)
+ RenderTarget9 *renderTarget9 = NULL;
+ error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(renderTarget9);
- TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
- bool result = false;
+ IDirect3DSurface9 *source = renderTarget9->getSurface();
+ ASSERT(source);
- if (destSurface)
+ IDirect3DSurface9 *destSurface = NULL;
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
+ error = storage9->getSurfaceLevel(level, true, &destSurface);
+ if (error.isError())
{
- result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
- SafeRelease(destSurface);
+ return error;
}
+ ASSERT(destSurface);
+
+ gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ SafeRelease(destSurface);
SafeRelease(source);
+
return result;
}
-bool Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
{
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *source = NULL;
- gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
-
- if (colorbuffer)
+ gl::Error error = initialize();
+ if (error.isError())
{
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
+ return error;
}
- if (renderTarget)
- {
- source = renderTarget->getSurface();
- }
+ gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+ ASSERT(colorbuffer);
- if (!source)
+ RenderTarget9 *renderTarget9 = NULL;
+ error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget9);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(renderTarget9);
- TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
- bool result = false;
+ IDirect3DSurface9 *source = renderTarget9->getSurface();
+ ASSERT(source);
- if (destSurface)
+ IDirect3DSurface9 *destSurface = NULL;
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
+ error = storage9->getCubeMapSurface(target, level, true, &destSurface);
+ if (error.isError())
{
- result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
- SafeRelease(destSurface);
+ return error;
}
+ ASSERT(destSurface);
+
+ gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ SafeRelease(destSurface);
SafeRelease(source);
+
return result;
}
-bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
{
- if (!dest)
- {
- return false;
- }
+ ASSERT(source != NULL && dest != NULL);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -303,22 +326,30 @@ bool Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destF
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit between textures, StretchRect result: 0x%X.", result);
}
+
+ return gl::Error(GL_NO_ERROR);
}
else
{
return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
}
- return true;
}
-bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
{
- IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
- if (!texture)
+ gl::Error error = initialize();
+ if (error.isError())
{
- return false;
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = NULL;
+ error = copySurfaceToTexture(source, sourceRect, &texture);
+ if (error.isError())
+ {
+ return error;
}
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -331,7 +362,9 @@ bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLe
setViewport(sourceRect, xoffset, yoffset);
setCommonBlitState();
- if (setFormatConvertShaders(destFormat))
+
+ error = setFormatConvertShaders(destFormat);
+ if (!error.isError())
{
render();
}
@@ -340,12 +373,16 @@ bool Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLe
restoreState();
- return true;
+ return error;
}
-bool Blit9::setFormatConvertShaders(GLenum destFormat)
+gl::Error Blit9::setFormatConvertShaders(GLenum destFormat)
{
- bool okay = setVertexShader(SHADER_VS_STANDARD);
+ gl::Error error = setVertexShader(SHADER_VS_STANDARD);
+ if (error.isError())
+ {
+ return error;
+ }
switch (destFormat)
{
@@ -356,18 +393,18 @@ bool Blit9::setFormatConvertShaders(GLenum destFormat)
case GL_RG_EXT:
case GL_RED_EXT:
case GL_ALPHA:
- okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
+ error = setPixelShader(SHADER_PS_COMPONENTMASK);
break;
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
- okay = okay && setPixelShader(SHADER_PS_LUMINANCE);
+ error = setPixelShader(SHADER_PS_LUMINANCE);
break;
}
- if (!okay)
+ if (error.isError())
{
- return false;
+ return error;
}
enum { X = 0, Y = 1, Z = 2, W = 3 };
@@ -463,15 +500,12 @@ bool Blit9::setFormatConvertShaders(GLenum destFormat)
mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
+gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture)
{
- if (!surface)
- {
- return NULL;
- }
+ ASSERT(surface);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -485,7 +519,7 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for blit, result: 0x%X.", result);
}
IDirect3DSurface9 *textureSurface;
@@ -495,7 +529,7 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(texture);
- return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query surface of internal blit texture, result: 0x%X.", result);
}
mRenderer->endScene();
@@ -507,10 +541,11 @@ IDirect3DTexture9 *Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(texture);
- return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy between internal blit textures, result: 0x%X.", result);
}
- return texture;
+ *outTexture = texture;
+ return gl::Error(GL_NO_ERROR);
}
void Blit9::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
index 46a3ee1cf3..5c7a76ce05 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_BLIT9_H_
#include "common/angleutils.h"
+#include "libGLESv2/Error.h"
#include <GLES2/gl2.h>
@@ -29,32 +30,33 @@ class Blit9
explicit Blit9(Renderer9 *renderer);
~Blit9();
+ gl::Error initialize();
+
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
- bool copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- bool copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ gl::Error copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+ gl::Error copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
// source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0.
- bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
// 2x2 box filter sample from source to dest.
// Requires that source is RGB(A) and dest has the same format as source.
- bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+ gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
private:
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
+ bool mGeometryLoaded;
IDirect3DVertexBuffer9 *mQuadVertexBuffer;
IDirect3DVertexDeclaration9 *mQuadVertexDeclaration;
- void initGeometry();
-
- bool setFormatConvertShaders(GLenum destFormat);
+ gl::Error setFormatConvertShaders(GLenum destFormat);
- bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
- IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect);
+ gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture);
void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset);
void setCommonBlitState();
RECT getSurfaceRect(IDirect3DSurface9 *surface) const;
@@ -74,12 +76,12 @@ class Blit9
IUnknown *mCompiledShaders[SHADER_COUNT];
template <class D3DShaderType>
- bool setShader(ShaderId source, const char *profile,
- D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length),
- HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*));
+ gl::Error setShader(ShaderId source, const char *profile,
+ gl::Error (Renderer9::*createShader)(const DWORD *, size_t length, D3DShaderType **outShader),
+ HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*));
- bool setVertexShader(ShaderId shader);
- bool setPixelShader(ShaderId shader);
+ gl::Error setVertexShader(ShaderId shader);
+ gl::Error setPixelShader(ShaderId shader);
void render();
void saveState();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
index c02db515a2..430fe81e50 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
@@ -13,7 +13,7 @@
namespace rx
{
-Buffer9::Buffer9(rx::Renderer9 *renderer)
+Buffer9::Buffer9(Renderer9 *renderer)
: BufferD3D(),
mRenderer(renderer),
mSize(0)
@@ -41,7 +41,7 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
}
mSize = size;
- if (data)
+ if (data && size > 0)
{
memcpy(mMemory.data(), data, size);
}
@@ -56,9 +56,10 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
return gl::Error(GL_NO_ERROR);
}
-void *Buffer9::getData()
+gl::Error Buffer9::getData(const uint8_t **outData)
{
- return mMemory.data();
+ *outData = mMemory.data();
+ return gl::Error(GL_NO_ERROR);
}
gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset)
@@ -72,7 +73,7 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset)
}
mSize = std::max(mSize, offset + size);
- if (data)
+ if (data && size > 0)
{
memcpy(mMemory.data() + offset, data, size);
}
@@ -113,7 +114,7 @@ void Buffer9::markTransformFeedbackUsage()
UNREACHABLE();
}
-Renderer* Buffer9::getRenderer()
+RendererD3D *Buffer9::getRenderer()
{
return mRenderer;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
index e78182f905..c80b009738 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
@@ -20,7 +20,7 @@ class Renderer9;
class Buffer9 : public BufferD3D
{
public:
- Buffer9(rx::Renderer9 *renderer);
+ Buffer9(Renderer9 *renderer);
virtual ~Buffer9();
static Buffer9 *makeBuffer9(BufferImpl *buffer);
@@ -28,11 +28,11 @@ class Buffer9 : public BufferD3D
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const { return false; }
- virtual Renderer* getRenderer();
+ RendererD3D *getRenderer() override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
- virtual void *getData();
+ gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
@@ -42,7 +42,7 @@ class Buffer9 : public BufferD3D
private:
DISALLOW_COPY_AND_ASSIGN(Buffer9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
MemoryBuffer mMemory;
size_t mSize;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
index e352a5f50a..66263fe110 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-// Fence9.cpp: Defines the rx::Fence9 class.
+// Fence9.cpp: Defines the rx::FenceNV9 class.
#include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
@@ -14,39 +14,41 @@
namespace rx
{
-Fence9::Fence9(rx::Renderer9 *renderer)
+FenceNV9::FenceNV9(Renderer9 *renderer)
+ : FenceNVImpl(),
+ mRenderer(renderer),
+ mQuery(NULL)
{
- mRenderer = renderer;
- mQuery = NULL;
}
-Fence9::~Fence9()
+FenceNV9::~FenceNV9()
{
SafeRelease(mQuery);
}
-bool Fence9::isSet() const
-{
- return mQuery != NULL;
-}
-
-void Fence9::set()
+gl::Error FenceNV9::set()
{
if (!mQuery)
{
- mQuery = mRenderer->allocateEventQuery();
- if (!mQuery)
+ gl::Error error = mRenderer->allocateEventQuery(&mQuery);
+ if (error.isError())
{
- return gl::error(GL_OUT_OF_MEMORY);
+ return error;
}
}
HRESULT result = mQuery->Issue(D3DISSUE_END);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ SafeRelease(mQuery);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to end event query, result: 0x%X.", result);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence9::test(bool flushCommandBuffer)
+gl::Error FenceNV9::test(bool flushCommandBuffer, GLboolean *outFinished)
{
ASSERT(mQuery);
@@ -56,17 +58,34 @@ bool Fence9::test(bool flushCommandBuffer)
if (d3d9::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
- return gl::error(GL_OUT_OF_MEMORY, true);
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query.");
+ }
+ else if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result);
}
ASSERT(result == S_OK || result == S_FALSE);
-
- return (result == S_OK);
+ *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
+ return gl::Error(GL_NO_ERROR);
}
-bool Fence9::hasError() const
+gl::Error FenceNV9::finishFence(GLboolean *outFinished)
{
- return mRenderer->isDeviceLost();
+ ASSERT(outFinished);
+
+ while (*outFinished != GL_TRUE)
+ {
+ gl::Error error = test(true, outFinished);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ Sleep(0);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
index e923a2178c..d7873d5264 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl.
+// Fence9.h: Defines the rx::FenceNV9 class which implements rx::FenceNVImpl.
#ifndef LIBGLESV2_RENDERER_FENCE9_H_
#define LIBGLESV2_RENDERER_FENCE9_H_
@@ -15,21 +15,20 @@ namespace rx
{
class Renderer9;
-class Fence9 : public FenceImpl
+class FenceNV9 : public FenceNVImpl
{
public:
- explicit Fence9(rx::Renderer9 *renderer);
- virtual ~Fence9();
+ explicit FenceNV9(Renderer9 *renderer);
+ virtual ~FenceNV9();
- bool isSet() const;
- void set();
- bool test(bool flushCommandBuffer);
- bool hasError() const;
+ gl::Error set();
+ gl::Error test(bool flushCommandBuffer, GLboolean *outFinished);
+ gl::Error finishFence(GLboolean *outFinished);
private:
- DISALLOW_COPY_AND_ASSIGN(Fence9);
+ DISALLOW_COPY_AND_ASSIGN(FenceNV9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
IDirect3DQuery9 *mQuery;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
index 18383fba78..2a06d12942 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
@@ -17,7 +17,7 @@
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Renderbuffer.h"
-
+#include "common/utilities.h"
namespace rx
{
@@ -36,15 +36,23 @@ Image9::~Image9()
SafeRelease(mSurface);
}
-void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
+gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
{
D3DSURFACE_DESC destDesc;
HRESULT result = destSurface->GetDesc(&destDesc);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the source surface description for mipmap generation, result: 0x%X.", result);
+ }
D3DSURFACE_DESC sourceDesc;
result = sourceSurface->GetDesc(&sourceDesc);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the destination surface description for mipmap generation, result: 0x%X.", result);
+ }
ASSERT(sourceDesc.Format == destDesc.Format);
ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
@@ -56,74 +64,111 @@ void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sour
D3DLOCKED_RECT sourceLocked = {0};
result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface for mipmap generation, result: 0x%X.", result);
+ }
D3DLOCKED_RECT destLocked = {0};
result = destSurface->LockRect(&destLocked, NULL, 0);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ sourceSurface->UnlockRect();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface for mipmap generation, result: 0x%X.", result);
+ }
const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(sourceLocked.pBits);
uint8_t *destData = reinterpret_cast<uint8_t*>(destLocked.pBits);
- if (sourceData && destData)
- {
- d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
- destData, destLocked.Pitch, 0);
- }
+ ASSERT(sourceData && destData);
+
+ d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0,
+ destData, destLocked.Pitch, 0);
destSurface->UnlockRect();
sourceSurface->UnlockRect();
+
+ return gl::Error(GL_NO_ERROR);
}
Image9 *Image9::makeImage9(Image *img)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img));
- return static_cast<rx::Image9*>(img);
+ ASSERT(HAS_DYNAMIC_TYPE(Image9*, img));
+ return static_cast<Image9*>(img);
}
-void Image9::generateMipmap(Image9 *dest, Image9 *source)
+gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source)
{
- IDirect3DSurface9 *sourceSurface = source->getSurface();
- if (sourceSurface == NULL)
- return gl::error(GL_OUT_OF_MEMORY);
+ IDirect3DSurface9 *sourceSurface = NULL;
+ gl::Error error = source->getSurface(&sourceSurface);
+ if (error.isError())
+ {
+ return error;
+ }
- IDirect3DSurface9 *destSurface = dest->getSurface();
- generateMip(destSurface, sourceSurface);
+ IDirect3DSurface9 *destSurface = NULL;
+ error = dest->getSurface(&destSurface);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = generateMip(destSurface, sourceSurface);
+ if (error.isError())
+ {
+ return error;
+ }
dest->markDirty();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
+gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
{
D3DLOCKED_RECT sourceLock = {0};
D3DLOCKED_RECT destLock = {0};
- source->LockRect(&sourceLock, NULL, 0);
- dest->LockRect(&destLock, NULL, 0);
+ HRESULT result;
+
+ result = source->LockRect(&sourceLock, NULL, 0);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result);
+ }
- if (sourceLock.pBits && destLock.pBits)
+ result = dest->LockRect(&destLock, NULL, 0);
+ if (FAILED(result))
{
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
+ source->UnlockRect();
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result);
+ }
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
- unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
+ ASSERT(sourceLock.pBits && destLock.pBits);
- unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
- ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
- bytes <= static_cast<unsigned int>(destLock.Pitch));
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
- for(unsigned int i = 0; i < rows; i++)
- {
- memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
- }
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+ unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
- source->UnlockRect();
- dest->UnlockRect();
+ unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
+ ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
+ bytes <= static_cast<unsigned int>(destLock.Pitch));
+
+ for(unsigned int i = 0; i < rows; i++)
+ {
+ memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
}
- else UNREACHABLE();
+
+ source->UnlockRect();
+ dest->UnlockRect();
+
+ return gl::Error(GL_NO_ERROR);
}
-bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
+bool Image9::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
{
// 3D textures are not supported by the D3D9 backend.
ASSERT(depth <= 1);
@@ -160,11 +205,11 @@ bool Image9::redefine(rx::Renderer *renderer, GLenum target, GLenum internalform
return false;
}
-void Image9::createSurface()
+gl::Error Image9::createSurface()
{
- if(mSurface)
+ if (mSurface)
{
- return;
+ return gl::Error(GL_NO_ERROR);
}
IDirect3DTexture9 *newTexture = NULL;
@@ -187,8 +232,7 @@ void Image9::createSurface()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- ERR("Creating image surface failed.");
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create image surface, result: 0x%X.", result);
}
newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
@@ -206,35 +250,51 @@ void Image9::createSurface()
D3DLOCKED_RECT lockedRect;
result = newSurface->LockRect(&lockedRect, &entireRect, 0);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result);
+ }
d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast<uint8_t*>(lockedRect.pBits),
lockedRect.Pitch, 0);
result = newSurface->UnlockRect();
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock image surface, result: 0x%X.", result);
+ }
}
}
mSurface = newSurface;
mDirty = false;
mD3DPool = poolToUse;
+
+ return gl::Error(GL_NO_ERROR);
}
-HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
+gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect)
{
- createSurface();
-
- HRESULT result = D3DERR_INVALIDCALL;
+ gl::Error error = createSurface();
+ if (error.isError())
+ {
+ return error;
+ }
if (mSurface)
{
- result = mSurface->LockRect(lockedRect, rect, 0);
+ HRESULT result = mSurface->LockRect(lockedRect, &rect, 0);
ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result);
+ }
mDirty = true;
}
- return result;
+ return gl::Error(GL_NO_ERROR);
}
void Image9::unlock()
@@ -263,26 +323,43 @@ bool Image9::isDirty() const
return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty;
}
-IDirect3DSurface9 *Image9::getSurface()
+gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface)
{
- createSurface();
+ gl::Error error = createSurface();
+ if (error.isError())
+ {
+ return error;
+ }
- return mSurface;
+ *outSurface = mSurface;
+ return gl::Error(GL_NO_ERROR);
}
-void Image9::setManagedSurface2D(TextureStorage *storage, int level)
+gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level)
{
+ IDirect3DSurface9 *surface = NULL;
TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- setManagedSurface(storage9->getSurfaceLevel(level, false));
+ gl::Error error = storage9->getSurfaceLevel(level, false, &surface);
+ if (error.isError())
+ {
+ return error;
+ }
+ return setManagedSurface(surface);
}
-void Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
+gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level)
{
+ IDirect3DSurface9 *surface = NULL;
TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
+ gl::Error error = storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface);
+ if (error.isError())
+ {
+ return error;
+ }
+ return setManagedSurface(surface);
}
-void Image9::setManagedSurface(IDirect3DSurface9 *surface)
+gl::Error Image9::setManagedSurface(IDirect3DSurface9 *surface)
{
D3DSURFACE_DESC desc;
surface->GetDesc(&desc);
@@ -292,97 +369,119 @@ void Image9::setManagedSurface(IDirect3DSurface9 *surface)
{
if (mSurface)
{
- copyLockableSurfaces(surface, mSurface);
+ gl::Error error = copyLockableSurfaces(surface, mSurface);
SafeRelease(mSurface);
+ if (error.isError())
+ {
+ return error;
+ }
}
mSurface = surface;
mD3DPool = desc.Pool;
}
-}
-bool Image9::copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
- ASSERT(getSurface() != NULL);
- TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- return copyToSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
+ return gl::Error(GL_NO_ERROR);
}
-bool Image9::copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region)
{
- ASSERT(getSurface() != NULL);
- TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- return copyToSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
-}
+ gl::Error error = createSurface();
+ if (error.isError())
+ {
+ return error;
+ }
-bool Image9::copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
-{
- // 3D textures are not supported by the D3D9 backend.
- UNREACHABLE();
- return false;
-}
+ IDirect3DSurface9 *destSurface = NULL;
-bool Image9::copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height)
-{
- // 2D array textures are not supported by the D3D9 backend.
- UNREACHABLE();
- return false;
+ if (index.type == GL_TEXTURE_2D)
+ {
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
+ gl::Error error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ ASSERT(gl::IsCubemapTextureTarget(index.type));
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
+ gl::Error error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ error = copyToSurface(destSurface, region.x, region.y, region.width, region.height);
+ SafeRelease(destSurface);
+ return error;
}
-bool Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
ASSERT(width > 0 && height > 0);
+ ASSERT(destSurface);
- if (!destSurface)
- return false;
+ IDirect3DSurface9 *sourceSurface = NULL;
+ gl::Error error = getSurface(&sourceSurface);
+ if (error.isError())
+ {
+ return error;
+ }
- IDirect3DSurface9 *sourceSurface = getSurface();
+ ASSERT(sourceSurface && sourceSurface != destSurface);
- if (sourceSurface && sourceSurface != destSurface)
- {
- RECT rect;
- rect.left = xoffset;
- rect.top = yoffset;
- rect.right = xoffset + width;
- rect.bottom = yoffset + height;
+ RECT rect;
+ rect.left = xoffset;
+ rect.top = yoffset;
+ rect.right = xoffset + width;
+ rect.bottom = yoffset + height;
- POINT point = {rect.left, rect.top};
+ POINT point = {rect.left, rect.top};
- IDirect3DDevice9 *device = mRenderer->getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
- if (mD3DPool == D3DPOOL_MANAGED)
- {
- D3DSURFACE_DESC desc;
- sourceSurface->GetDesc(&desc);
+ if (mD3DPool == D3DPOOL_MANAGED)
+ {
+ D3DSURFACE_DESC desc;
+ sourceSurface->GetDesc(&desc);
- IDirect3DSurface9 *surf = 0;
- HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ IDirect3DSurface9 *surf = 0;
+ HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal CreateOffscreenPlainSurface call failed, result: 0x%X.", result);
+ }
- if (SUCCEEDED(result))
- {
- copyLockableSurfaces(surf, sourceSurface);
- result = device->UpdateSurface(surf, &rect, destSurface, &point);
- ASSERT(SUCCEEDED(result));
- SafeRelease(surf);
- }
+ copyLockableSurfaces(surf, sourceSurface);
+ result = device->UpdateSurface(surf, &rect, destSurface, &point);
+ SafeRelease(surf);
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result);
}
- else
+ }
+ else
+ {
+ // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
+ HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
- HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result);
}
}
- SafeRelease(destSurface);
- return true;
+ return gl::Error(GL_NO_ERROR);
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle.
-void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input)
+gl::Error Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input)
{
// 3D textures are not supported by the D3D9 backend.
ASSERT(zoffset == 0 && depth == 1);
@@ -400,10 +499,10 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
};
D3DLOCKED_RECT locked;
- HRESULT result = lock(&locked, &lockRect);
- if (FAILED(result))
+ gl::Error error = lock(&locked, lockRect);
+ if (error.isError())
{
- return;
+ return error;
}
d3dFormatInfo.loadFunction(width, height, depth,
@@ -411,10 +510,12 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock();
+
+ return gl::Error(GL_NO_ERROR);
}
-void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input)
+gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input)
{
// 3D textures are not supported by the D3D9 backend.
ASSERT(zoffset == 0 && depth == 1);
@@ -437,10 +538,10 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
};
D3DLOCKED_RECT locked;
- HRESULT result = lock(&locked, &lockRect);
- if (FAILED(result))
+ gl::Error error = lock(&locked, lockRect);
+ if (error.isError())
{
- return;
+ return error;
}
d3d9FormatInfo.loadFunction(width, height, depth,
@@ -448,33 +549,22 @@ void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLs
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
unlock();
+
+ return gl::Error(GL_NO_ERROR);
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
-void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
{
+ ASSERT(source);
+
// ES3.0 only behaviour to copy into a 3d texture
ASSERT(zoffset == 0);
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *surface = NULL;
- gl::FramebufferAttachment *colorbuffer = source->getColorbuffer(0);
-
- if (colorbuffer)
- {
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
- }
-
- if (renderTarget)
- {
- surface = renderTarget->getSurface();
- }
+ RenderTarget9 *renderTarget = RenderTarget9::makeRenderTarget9(source);
- if (!surface)
- {
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
+ IDirect3DSurface9 *surface = renderTarget->getSurface();
+ ASSERT(surface);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -486,212 +576,200 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
if (FAILED(result))
{
- ERR("Could not create matching destination surface.");
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Could not create matching destination surface, result: 0x%X.", result);
}
result = device->GetRenderTargetData(surface, renderTargetData);
if (FAILED(result))
{
- ERR("GetRenderTargetData unexpectedly failed.");
SafeRelease(renderTargetData);
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "GetRenderTargetData unexpectedly failed, result: 0x%X.", result);
}
- RECT sourceRect = {x, y, x + width, y + height};
- RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
+ int width = sourceArea.width;
+ int height = sourceArea.height;
+
+ RECT sourceRect = { sourceArea.x, sourceArea.y, sourceArea.x + width, sourceArea.y + height };
+ RECT destRect = { xoffset, yoffset, xoffset + width, yoffset + height };
D3DLOCKED_RECT sourceLock = {0};
result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
if (FAILED(result))
{
- ERR("Failed to lock the source surface (rectangle might be invalid).");
SafeRelease(renderTargetData);
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface (rectangle might be invalid), result: 0x%X.", result);
}
D3DLOCKED_RECT destLock = {0};
- result = lock(&destLock, &destRect);
-
- if (FAILED(result))
+ gl::Error error = lock(&destLock, destRect);
+ if (error.isError())
{
- ERR("Failed to lock the destination surface (rectangle might be invalid).");
renderTargetData->UnlockRect();
SafeRelease(renderTargetData);
SafeRelease(surface);
- return gl::error(GL_OUT_OF_MEMORY);
+ return error;
}
- if (destLock.pBits && sourceLock.pBits)
- {
- unsigned char *source = (unsigned char*)sourceLock.pBits;
- unsigned char *dest = (unsigned char*)destLock.pBits;
+ ASSERT(destLock.pBits && sourceLock.pBits);
- switch (description.Format)
+ unsigned char *sourcePixels = (unsigned char*)sourceLock.pBits;
+ unsigned char *destPixels = (unsigned char*)destLock.pBits;
+
+ switch (description.Format)
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ switch (getD3DFormat())
{
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
- switch(getD3DFormat())
+ for (int y = 0; y < height; y++)
{
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A8R8G8B8:
- for(int y = 0; y < height; y++)
+ memcpy(destPixels, sourcePixels, 4 * width);
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- memcpy(dest, source, 4 * width);
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ destPixels[x] = sourcePixels[x * 4 + 2];
}
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- dest[x] = source[x * 4 + 2];
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_A8L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- dest[x * 2 + 0] = source[x * 4 + 2];
- dest[x * 2 + 1] = source[x * 4 + 3];
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ destPixels[x * 2 + 0] = sourcePixels[x * 4 + 2];
+ destPixels[x * 2 + 1] = sourcePixels[x * 4 + 3];
}
- break;
- default:
- UNREACHABLE();
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
}
break;
- case D3DFMT_R5G6B5:
- switch(getD3DFormat())
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_R5G6B5:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for (int y = 0; y < height; y++)
{
- case D3DFMT_X8R8G8B8:
- for(int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned short rgb = ((unsigned short*)source)[x];
- unsigned char red = (rgb & 0xF800) >> 8;
- unsigned char green = (rgb & 0x07E0) >> 3;
- unsigned char blue = (rgb & 0x001F) << 3;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 6);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = 0xFF;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned short rgb = ((unsigned short*)sourcePixels)[x];
+ unsigned char red = (rgb & 0xF800) >> 8;
+ unsigned char green = (rgb & 0x07E0) >> 3;
+ unsigned char blue = (rgb & 0x001F) << 3;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 6);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = 0xFF;
}
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0xF8;
- dest[x] = red | (red >> 5);
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned char red = sourcePixels[x * 2 + 1] & 0xF8;
+ destPixels[x] = red | (red >> 5);
}
- break;
- default:
- UNREACHABLE();
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
}
break;
- case D3DFMT_A1R5G5B5:
- switch(getD3DFormat())
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_A1R5G5B5:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for (int y = 0; y < height; y++)
{
- case D3DFMT_X8R8G8B8:
- for(int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned short argb = ((unsigned short*)source)[x];
- unsigned char red = (argb & 0x7C00) >> 7;
- unsigned char green = (argb & 0x03E0) >> 2;
- unsigned char blue = (argb & 0x001F) << 3;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 5);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = 0xFF;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned short argb = ((unsigned short*)sourcePixels)[x];
+ unsigned char red = (argb & 0x7C00) >> 7;
+ unsigned char green = (argb & 0x03E0) >> 2;
+ unsigned char blue = (argb & 0x001F) << 3;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 5);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = 0xFF;
}
- break;
- case D3DFMT_A8R8G8B8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned short argb = ((unsigned short*)source)[x];
- unsigned char red = (argb & 0x7C00) >> 7;
- unsigned char green = (argb & 0x03E0) >> 2;
- unsigned char blue = (argb & 0x001F) << 3;
- unsigned char alpha = (signed short)argb >> 15;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 5);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = alpha;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned short argb = ((unsigned short*)sourcePixels)[x];
+ unsigned char red = (argb & 0x7C00) >> 7;
+ unsigned char green = (argb & 0x03E0) >> 2;
+ unsigned char blue = (argb & 0x001F) << 3;
+ unsigned char alpha = (signed short)argb >> 15;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 5);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = alpha;
}
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0x7C;
- dest[x] = (red << 1) | (red >> 4);
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
+ destPixels[x] = (red << 1) | (red >> 4);
}
- break;
- case D3DFMT_A8L8:
- for(int y = 0; y < height; y++)
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
{
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0x7C;
- dest[x * 2 + 0] = (red << 1) | (red >> 4);
- dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
+ unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
+ destPixels[x * 2 + 0] = (red << 1) | (red >> 4);
+ destPixels[x * 2 + 1] = (signed char)sourcePixels[x * 2 + 1] >> 7;
}
- break;
- default:
- UNREACHABLE();
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
}
break;
default:
UNREACHABLE();
}
+ break;
+ default:
+ UNREACHABLE();
}
unlock();
@@ -701,6 +779,14 @@ void Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
SafeRelease(surface);
mDirty = true;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage)
+{
+ // Currently unreachable, due to only being used in a D3D11-only workaround
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
index 08d8ee3545..8cc2258859 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
@@ -20,7 +20,6 @@ class Framebuffer;
namespace rx
{
-class Renderer;
class Renderer9;
class Image9 : public ImageD3D
@@ -31,41 +30,41 @@ class Image9 : public ImageD3D
static Image9 *makeImage9(Image *img);
- static void generateMipmap(Image9 *dest, Image9 *source);
- static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
- static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
+ static gl::Error generateMipmap(Image9 *dest, Image9 *source);
+ static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
+ static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
- virtual bool redefine(Renderer *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease);
+ bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override;
D3DFORMAT getD3DFormat() const;
virtual bool isDirty() const;
- IDirect3DSurface9 *getSurface();
- virtual void setManagedSurface2D(TextureStorage *storage, int level);
- virtual void setManagedSurfaceCube(TextureStorage *storage, int face, int level);
- virtual bool copyToStorage2D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorageCube(TextureStorage *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- virtual bool copyToStorage3D(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
- virtual bool copyToStorage2DArray(TextureStorage *storage, int level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height);
+ virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level);
+ virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level);
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
- virtual void loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input);
- virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input);
+ virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ GLint unpackAlignment, GLenum type, const void *input);
+ virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
+ const void *input);
- virtual void copy(GLint xoffset, GLint yoffset, GLint zoffset,GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
+ virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ const gl::ImageIndex &sourceIndex, TextureStorage *source);
private:
DISALLOW_COPY_AND_ASSIGN(Image9);
- void createSurface();
- void setManagedSurface(IDirect3DSurface9 *surface);
- bool copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ gl::Error getSurface(IDirect3DSurface9 **outSurface);
- HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
+ gl::Error createSurface();
+ gl::Error setManagedSurface(IDirect3DSurface9 *surface);
+ gl::Error copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+ gl::Error lock(D3DLOCKED_RECT *lockedRect, const RECT &rect);
void unlock();
-
+
Renderer9 *mRenderer;
D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
index d0970d6ac5..2375fcf4b0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
@@ -40,7 +40,7 @@ class IndexBuffer9 : public IndexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(IndexBuffer9);
- rx::Renderer9 *const mRenderer;
+ Renderer9 *const mRenderer;
IDirect3DIndexBuffer9 *mIndexBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
index 815fc01a9b..a3cab578be 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
@@ -15,7 +15,7 @@
namespace rx
{
-Query9::Query9(rx::Renderer9 *renderer, GLenum type)
+Query9::Query9(Renderer9 *renderer, GLenum type)
: QueryImpl(type),
mResult(GL_FALSE),
mQueryFinished(false),
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
index 513e0ba6fd..36851c6c6c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
@@ -18,7 +18,7 @@ class Renderer9;
class Query9 : public QueryImpl
{
public:
- Query9(rx::Renderer9 *renderer, GLenum type);
+ Query9(Renderer9 *renderer, GLenum type);
virtual ~Query9();
virtual gl::Error begin();
@@ -34,7 +34,7 @@ class Query9 : public QueryImpl
GLuint mResult;
bool mQueryFinished;
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
IDirect3DQuery9 *mQuery;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
index 13321ac8cd..53d1f752fa 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
@@ -10,115 +10,83 @@
#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
#include "libGLESv2/main.h"
namespace rx
{
+RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RenderTarget9*, target));
+ return static_cast<RenderTarget9*>(target);
+}
+
+void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ // Currently a no-op
+}
+
// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given.
-RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
+TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mActualFormat(internalFormat),
+ mSamples(samples),
+ mRenderTarget(surface)
{
- mRenderer = Renderer9::makeRenderer9(renderer);
- mRenderTarget = surface;
+ ASSERT(mDepth == 1);
if (mRenderTarget)
{
D3DSURFACE_DESC description;
mRenderTarget->GetDesc(&description);
- mWidth = description.Width;
- mHeight = description.Height;
- mDepth = 1;
-
const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
- mInternalFormat = d3dFormatInfo.internalFormat;
mActualFormat = d3dFormatInfo.internalFormat;
- mSamples = d3d9_gl::GetSamplesCount(description.MultiSampleType);
}
}
-RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
+TextureRenderTarget9::~TextureRenderTarget9()
{
- mRenderer = Renderer9::makeRenderer9(renderer);
- mRenderTarget = NULL;
-
- const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.renderFormat);
-
- const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
- GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+ SafeRelease(mRenderTarget);
+}
- HRESULT result = D3DERR_INVALIDCALL;
+GLsizei TextureRenderTarget9::getWidth() const
+{
+ return mWidth;
+}
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
-
- bool requiresInitialization = false;
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
- if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
- {
- result = device->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
- gl_d3d9::GetMultisampleType(supportedSamples),
- 0, FALSE, &mRenderTarget, NULL);
- }
- else
- {
- requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
- result = device->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
- gl_d3d9::GetMultisampleType(supportedSamples),
- 0, FALSE, &mRenderTarget, NULL);
- }
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- gl::error(GL_OUT_OF_MEMORY);
-
- return;
- }
-
- ASSERT(SUCCEEDED(result));
-
- if (requiresInitialization)
- {
- // This format requires that the data be initialized before the render target can be used
- // Unfortunately this requires a Get call on the d3d device but it is far better than having
- // to mark the render target as lockable and copy data to the gpu.
- IDirect3DSurface9 *prevRenderTarget = NULL;
- device->GetRenderTarget(0, &prevRenderTarget);
- device->SetRenderTarget(0, mRenderTarget);
- device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
- device->SetRenderTarget(0, prevRenderTarget);
- }
- }
+GLsizei TextureRenderTarget9::getHeight() const
+{
+ return mHeight;
+}
- mWidth = width;
- mHeight = height;
- mDepth = 1;
- mInternalFormat = internalFormat;
- mSamples = supportedSamples;
- mActualFormat = d3dFormatInfo.internalFormat;
+GLsizei TextureRenderTarget9::getDepth() const
+{
+ return mDepth;
}
-RenderTarget9::~RenderTarget9()
+GLenum TextureRenderTarget9::getInternalFormat() const
{
- SafeRelease(mRenderTarget);
+ return mInternalFormat;
}
-RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+GLenum TextureRenderTarget9::getActualFormat() const
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target));
- return static_cast<rx::RenderTarget9*>(target);
+ return mActualFormat;
}
-void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
+GLsizei TextureRenderTarget9::getSamples() const
{
- // Currently a no-op
+ return mSamples;
}
-IDirect3DSurface9 *RenderTarget9::getSurface()
+IDirect3DSurface9 *TextureRenderTarget9::getSurface()
{
// Caller is responsible for releasing the returned surface reference.
// TODO: remove the AddRef to match RenderTarget11
@@ -130,4 +98,51 @@ IDirect3DSurface9 *RenderTarget9::getSurface()
return mRenderTarget;
}
+
+SurfaceRenderTarget9::SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth)
+ : mSwapChain(swapChain),
+ mDepth(depth)
+{
+}
+
+SurfaceRenderTarget9::~SurfaceRenderTarget9()
+{
+}
+
+GLsizei SurfaceRenderTarget9::getWidth() const
+{
+ return mSwapChain->getWidth();
+}
+
+GLsizei SurfaceRenderTarget9::getHeight() const
+{
+ return mSwapChain->getHeight();
+}
+
+GLsizei SurfaceRenderTarget9::getDepth() const
+{
+ return 1;
+}
+
+GLenum SurfaceRenderTarget9::getInternalFormat() const
+{
+ return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
+}
+
+GLenum SurfaceRenderTarget9::getActualFormat() const
+{
+ return d3d9::GetD3DFormatInfo(d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat;
+}
+
+GLsizei SurfaceRenderTarget9::getSamples() const
+{
+ // Our EGL surfaces do not support multisampling.
+ return 0;
+}
+
+IDirect3DSurface9 *SurfaceRenderTarget9::getSurface()
+{
+ return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget());
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
index 68d7adb49e..4585697f4c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
@@ -14,28 +14,74 @@
namespace rx
{
-class Renderer;
class Renderer9;
+class SwapChain9;
class RenderTarget9 : public RenderTarget
{
public:
- RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface);
- RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples);
- virtual ~RenderTarget9();
+ RenderTarget9() { }
+ virtual ~RenderTarget9() { }
static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget);
- virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height);
+ void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override;
- IDirect3DSurface9 *getSurface();
+ virtual IDirect3DSurface9 *getSurface() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(RenderTarget9);
+};
+
+class TextureRenderTarget9 : public RenderTarget9
+{
+ public:
+ TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei samples);
+ virtual ~TextureRenderTarget9();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ IDirect3DSurface9 *getSurface() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget9);
+
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ GLenum mActualFormat;
+ GLsizei mSamples;
IDirect3DSurface9 *mRenderTarget;
+};
+
+class SurfaceRenderTarget9 : public RenderTarget9
+{
+ public:
+ SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth);
+ virtual ~SurfaceRenderTarget9();
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLenum getActualFormat() const override;
+ GLsizei getSamples() const override;
+
+ IDirect3DSurface9 *getSurface() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget9);
- Renderer9 *mRenderer;
+ SwapChain9 *mSwapChain;
+ bool mDepth;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index d63f9b8582..601cd24b10 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -26,6 +26,7 @@
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
#include "libGLESv2/renderer/d3d/TextureD3D.h"
#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Texture.h"
@@ -33,10 +34,12 @@
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/State.h"
#include "libGLESv2/angletypes.h"
#include "libEGL/Display.h"
+#include "common/features.h"
#include "common/utilities.h"
#include <sstream>
@@ -44,14 +47,6 @@
// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
#define REF_RAST 0
-// The "Debug This Pixel..." feature in PIX often fails when using the
-// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
-// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file.
-#if !defined(ANGLE_ENABLE_D3D9EX)
-// Enables use of the IDirect3D9Ex interface, when available
-#define ANGLE_ENABLE_D3D9EX 1
-#endif // !defined(ANGLE_ENABLE_D3D9EX)
-
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
@@ -96,8 +91,8 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
};
-Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay)
- : Renderer(display),
+Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
+ : RendererD3D(display),
mDc(hDc)
{
mD3d9Module = NULL;
@@ -177,8 +172,8 @@ void Renderer9::release()
Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer));
- return static_cast<rx::Renderer9*>(renderer);
+ ASSERT(HAS_DYNAMIC_TYPE(Renderer9*, renderer));
+ return static_cast<Renderer9*>(renderer);
}
EGLint Renderer9::initialize()
@@ -202,7 +197,7 @@ EGLint Renderer9::initialize()
// Use Direct3D9Ex if available. Among other things, this version is less
// inclined to report a lost context, for example when the user switches
// desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
- if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
+ if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
{
ASSERT(mD3d9Ex);
mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
@@ -386,10 +381,13 @@ void Renderer9::initializeDevice()
mSceneStarted = false;
- ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager);
+ ASSERT(!mBlit);
mBlit = new Blit9(this);
- mVertexDataManager = new rx::VertexDataManager(this);
- mIndexDataManager = new rx::IndexDataManager(this);
+ mBlit->initialize();
+
+ ASSERT(!mVertexDataManager && !mIndexDataManager);
+ mVertexDataManager = new VertexDataManager(this);
+ mIndexDataManager = new IndexDataManager(this);
}
D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
@@ -481,68 +479,92 @@ void Renderer9::endScene()
}
}
-void Renderer9::sync(bool block)
+gl::Error Renderer9::sync(bool block)
{
- HRESULT result;
+ IDirect3DQuery9* query = NULL;
+ gl::Error error = allocateEventQuery(&query);
+ if (error.isError())
+ {
+ return error;
+ }
- IDirect3DQuery9* query = allocateEventQuery();
- if (!query)
+ HRESULT result = query->Issue(D3DISSUE_END);
+ if (FAILED(result))
{
- return;
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result);
}
- result = query->Issue(D3DISSUE_END);
- ASSERT(SUCCEEDED(result));
+ // Grab the query data once in blocking and non-blocking case
+ result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
+ if (FAILED(result))
+ {
+ if (d3d9::isDeviceLostError(result))
+ {
+ notifyDeviceLost();
+ }
+
+ freeEventQuery(query);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
+ }
- do
+ // If blocking, loop until the query completes
+ while (block && result == S_FALSE)
{
+ // Keep polling, but allow other threads to do something useful first
+ Sleep(0);
+
result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
- if(block && result == S_FALSE)
+ // explicitly check for device loss
+ // some drivers seem to return S_FALSE even if the device is lost
+ // instead of D3DERR_DEVICELOST like they should
+ if (result == S_FALSE && testDeviceLost(false))
{
- // Keep polling, but allow other threads to do something useful first
- Sleep(0);
- // explicitly check for device loss
- // some drivers seem to return S_FALSE even if the device is lost
- // instead of D3DERR_DEVICELOST like they should
- if (testDeviceLost(false))
+ result = D3DERR_DEVICELOST;
+ }
+
+ if (FAILED(result))
+ {
+ if (d3d9::isDeviceLostError(result))
{
- result = D3DERR_DEVICELOST;
+ notifyDeviceLost();
}
+
+ freeEventQuery(query);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
}
+
}
- while(block && result == S_FALSE);
freeEventQuery(query);
- if (d3d9::isDeviceLostError(result))
- {
- notifyDeviceLost();
- }
+ return gl::Error(GL_NO_ERROR);
}
-SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChain *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
- return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
}
-IDirect3DQuery9* Renderer9::allocateEventQuery()
+gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery)
{
- IDirect3DQuery9 *query = NULL;
-
if (mEventQueryPool.empty())
{
- HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, outQuery);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate event query, result: 0x%X.", result);
+ }
}
else
{
- query = mEventQueryPool.back();
+ *outQuery = mEventQueryPool.back();
mEventQueryPool.pop_back();
}
- return query;
+ return gl::Error(GL_NO_ERROR);
}
void Renderer9::freeEventQuery(IDirect3DQuery9* query)
@@ -557,14 +579,14 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query)
}
}
-IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length)
+gl::Error Renderer9::createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader)
{
- return mVertexShaderCache.create(function, length);
+ return mVertexShaderCache.create(function, length, outShader);
}
-IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length)
+gl::Error Renderer9::createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader)
{
- return mPixelShaderCache.create(function, length);
+ return mPixelShaderCache.create(function, length, outShader);
}
HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer)
@@ -604,9 +626,16 @@ QueryImpl *Renderer9::createQuery(GLenum type)
return new Query9(this, type);
}
-FenceImpl *Renderer9::createFence()
+FenceNVImpl *Renderer9::createFenceNV()
+{
+ return new FenceNV9(this);
+}
+
+FenceSyncImpl *Renderer9::createFenceSync()
{
- return new Fence9(this);
+ // Renderer9 doesn't support ES 3.0 and its sync objects.
+ UNREACHABLE();
+ return NULL;
}
TransformFeedbackImpl* Renderer9::createTransformFeedback()
@@ -620,12 +649,12 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const
return false;
}
-bool Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
+gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
// Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3.
UNREACHABLE();
- return false;
+ return gl::Error(GL_INVALID_OPERATION);
}
gl::Error Renderer9::generateSwizzle(gl::Texture *texture)
@@ -635,7 +664,7 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture)
return gl::Error(GL_INVALID_OPERATION);
}
-gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
+gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState)
{
std::vector<bool> &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
std::vector<gl::SamplerState> &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
@@ -645,6 +674,10 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::
int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
int d3dSampler = index + d3dSamplerOffset;
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ DWORD baseLevel = samplerState.baseLevel + textureD3D->getNativeTexture()->getTopLevel();
+
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
@@ -653,7 +686,7 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::
gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.baseLevel);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel);
if (getRendererExtensions().textureFilterAnisotropic)
{
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
@@ -684,7 +717,12 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te
if (texStorage)
{
TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage);
- d3dTexture = storage9->getBaseTexture();
+
+ gl::Error error = storage9->getBaseTexture(&d3dTexture);
+ if (error.isError())
+ {
+ return error;
+ }
}
// If we get NULL back from getBaseTexture here, something went wrong
// in the texture class and we're unexpectedly missing the d3d texture
@@ -751,7 +789,7 @@ gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
unsigned int sampleMask)
{
bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0;
@@ -1097,13 +1135,9 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
}
-gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer)
+gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer)
{
- if (!depthbuffer)
- {
- ERR("Unexpected null depthbuffer for depth-only FBO.");
- return NULL;
- }
+ ASSERT(depthbuffer);
GLsizei width = depthbuffer->getWidth();
GLsizei height = depthbuffer->getHeight();
@@ -1116,11 +1150,19 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme
mNullColorbufferCache[i].height == height)
{
mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU;
- return mNullColorbufferCache[i].buffer;
+ *outColorBuffer = mNullColorbufferCache[i].buffer;
+ return gl::Error(GL_NO_ERROR);
}
}
- gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+ gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0);
+ gl::Error error = nullRenderbuffer->setStorage(width, height, GL_NONE, 0);
+ if (error.isError())
+ {
+ SafeDelete(nullRenderbuffer);
+ return error;
+ }
+
gl::RenderbufferAttachment *nullbuffer = new gl::RenderbufferAttachment(GL_NONE, nullRenderbuffer);
// add nullbuffer to the cache
@@ -1139,40 +1181,40 @@ gl::FramebufferAttachment *Renderer9::getNullColorbuffer(gl::FramebufferAttachme
oldest->width = width;
oldest->height = height;
- return nullbuffer;
+ *outColorBuffer = nullbuffer;
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
+gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
{
// if there is no color attachment we must synthesize a NULL colorattachment
// to keep the D3D runtime happy. This should only be possible if depth texturing.
gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0);
if (!attachment)
{
- attachment = getNullColorbuffer(framebuffer->getDepthbuffer());
- }
- if (!attachment)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Unable to locate renderbuffer for FBO.");
+ gl::Error error = getNullColorbuffer(framebuffer->getDepthbuffer(), &attachment);
+ if (error.isError())
+ {
+ return error;
+ }
}
+ ASSERT(attachment);
bool renderTargetChanged = false;
unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
// Apply the render target on the device
- IDirect3DSurface9 *renderTargetSurface = NULL;
-
- RenderTarget9 *renderTarget = d3d9::GetAttachmentRenderTarget(attachment);
- if (renderTarget)
+ RenderTarget9 *renderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- renderTargetSurface = renderTarget->getSurface();
+ return error;
}
+ ASSERT(renderTarget);
- if (!renderTargetSurface)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target pointer unexpectedly null.");
- }
+ IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface();
+ ASSERT(renderTargetSurface);
mDevice->SetRenderTarget(0, renderTargetSurface);
SafeRelease(renderTargetSurface);
@@ -1204,18 +1246,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
// Apply the depth stencil on the device
if (depthStencil)
{
- IDirect3DSurface9 *depthStencilSurface = NULL;
- rx::RenderTarget9 *depthStencilRenderTarget = d3d9::GetAttachmentRenderTarget(depthStencil);
-
- if (depthStencilRenderTarget)
+ RenderTarget9 *depthStencilRenderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+ if (error.isError())
{
- depthStencilSurface = depthStencilRenderTarget->getSurface();
+ return error;
}
+ ASSERT(depthStencilRenderTarget);
- if (!depthStencilSurface)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil pointer unexpectedly null.");
- }
+ IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface();
+ ASSERT(depthStencilSurface);
mDevice->SetDepthStencilSurface(depthStencilSurface);
SafeRelease(depthStencilSurface);
@@ -1260,17 +1300,16 @@ gl::Error Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
+ gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
if (error.isError())
{
return error;
}
- return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw);
+ return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getCurrentProgramBinary(), instances, &mRepeatDraw);
}
// Applies the indices and element array bindings to the Direct3D 9 device
@@ -1296,7 +1335,7 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element
return gl::Error(GL_NO_ERROR);
}
-void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
+void Renderer9::applyTransformFeedbackBuffers(const gl::State& state)
{
UNREACHABLE();
}
@@ -1373,10 +1412,15 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- gl::Buffer *indexBuffer = elementArrayBuffer;
- BufferImpl *storage = indexBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+ indices = bufferData + offset;
}
unsigned int startIndex = 0;
@@ -1570,9 +1614,17 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid
if (elementArrayBuffer)
{
- BufferImpl *storage = elementArrayBuffer->getImplementation();
+ BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+
+ const uint8_t *bufferData = NULL;
+ gl::Error error = storage->getData(&bufferData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ indices = bufferData + offset;
}
switch (type)
@@ -1662,8 +1714,21 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard);
- ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
- ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer);
+ ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+
+ ShaderExecutable *vertexExe = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutable *pixelExe = NULL;
+ error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
+ if (error.isError())
+ {
+ return error;
+ }
IDirect3DVertexShader9 *vertexShader = (vertexExe ? ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader() : NULL);
IDirect3DPixelShader9 *pixelShader = (pixelExe ? ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader() : NULL);
@@ -1688,7 +1753,7 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
unsigned int programSerial = programBinary->getSerial();
if (programSerial != mAppliedProgramSerial)
{
- programBinary->dirtyAllUniforms();
+ programD3D->dirtyAllUniforms();
mDxUniformsDirty = true;
mAppliedProgramSerial = programSerial;
}
@@ -1696,10 +1761,8 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyUniforms(const gl::ProgramBinary &programBinary)
+gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
{
- const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms();
-
for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
{
gl::LinkedUniform *targetUniform = uniformArray[uniformIndex];
@@ -1797,7 +1860,7 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v
applyUniformnfv(targetUniform, (GLfloat*)vector);
}
-gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
{
if (clearParams.colorClearType != GL_FLOAT)
{
@@ -2219,7 +2282,7 @@ bool Renderer9::isRemovedDeviceResettable() const
{
bool success = false;
-#ifdef ANGLE_ENABLE_D3D9EX
+#if ANGLE_D3D9EX == ANGLE_ENABLED
IDirect3D9Ex *d3d9Ex = NULL;
typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
@@ -2330,82 +2393,6 @@ int Renderer9::getMaxSwapInterval() const
return mMaxSwapInterval;
}
-bool Renderer9::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source)
-{
- bool result = false;
-
- if (source && dest)
- {
- TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source);
- TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest);
-
- int levels = source9->getLevelCount();
- for (int i = 0; i < levels; ++i)
- {
- IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false);
- IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false);
-
- result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
-
- SafeRelease(srcSurf);
- SafeRelease(dstSurf);
-
- if (!result)
- {
- return false;
- }
- }
- }
-
- return result;
-}
-
-bool Renderer9::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source)
-{
- bool result = false;
-
- if (source && dest)
- {
- TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source);
- TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest);
- int levels = source9->getLevelCount();
- for (int f = 0; f < 6; f++)
- {
- for (int i = 0; i < levels; i++)
- {
- IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
- IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
-
- result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
-
- SafeRelease(srcSurf);
- SafeRelease(dstSurf);
-
- if (!result)
- {
- return false;
- }
- }
- }
- }
-
- return result;
-}
-
-bool Renderer9::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source)
-{
- // 3D textures are not available in the D3D9 backend.
- UNREACHABLE();
- return false;
-}
-
-bool Renderer9::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source)
-{
- // 2D array textures are not supported by the D3D9 backend.
- UNREACHABLE();
- return false;
-}
-
D3DPOOL Renderer9::getBufferPool(DWORD usage) const
{
if (mD3d9Ex != NULL)
@@ -2423,8 +2410,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const
return D3DPOOL_DEFAULT;
}
-bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
{
RECT rect;
rect.left = sourceRect.x;
@@ -2435,8 +2422,8 @@ bool Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &s
return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
}
-bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
{
RECT rect;
rect.left = sourceRect.x;
@@ -2447,24 +2434,26 @@ bool Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle
return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
}
-bool Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
// 3D textures are not available in the D3D9 backend.
UNREACHABLE();
- return false;
+ return gl::Error(GL_INVALID_OPERATION);
}
-bool Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
{
// 2D array textures are not available in the D3D9 backend.
UNREACHABLE();
- return false;
+ return gl::Error(GL_INVALID_OPERATION);
}
-bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
+gl::Error Renderer9::blitRect(const gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter)
{
ASSERT(filter == GL_NEAREST);
@@ -2473,35 +2462,33 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
if (blitRenderTarget)
{
gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0);
- gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
- RenderTarget9 *readRenderTarget = NULL;
- RenderTarget9 *drawRenderTarget = NULL;
- IDirect3DSurface9* readSurface = NULL;
- IDirect3DSurface9* drawSurface = NULL;
+ ASSERT(readBuffer);
- if (readBuffer)
- {
- readRenderTarget = d3d9::GetAttachmentRenderTarget(readBuffer);
- }
- if (drawBuffer)
+ RenderTarget9 *readRenderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
{
- drawRenderTarget = d3d9::GetAttachmentRenderTarget(drawBuffer);
+ return error;
}
+ ASSERT(readRenderTarget);
- if (readRenderTarget)
- {
- readSurface = readRenderTarget->getSurface();
- }
- if (drawRenderTarget)
- {
- drawSurface = drawRenderTarget->getSurface();
- }
+ gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
+ ASSERT(drawBuffer);
- if (!readSurface || !drawSurface)
+ RenderTarget9 *drawRenderTarget = NULL;
+ error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawRenderTarget);
+
+ // The getSurface calls do an AddRef so save them until after no errors are possible
+ IDirect3DSurface9* readSurface = readRenderTarget->getSurface();
+ ASSERT(readSurface);
+
+ IDirect3DSurface9* drawSurface = drawRenderTarget->getSurface();
+ ASSERT(drawSurface);
gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
@@ -2594,43 +2581,40 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
if (FAILED(result))
{
- ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
if (blitDepth || blitStencil)
{
gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer();
- gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
- RenderTarget9 *readDepthStencil = NULL;
- RenderTarget9 *drawDepthStencil = NULL;
- IDirect3DSurface9* readSurface = NULL;
- IDirect3DSurface9* drawSurface = NULL;
+ ASSERT(readBuffer);
- if (readBuffer)
- {
- readDepthStencil = d3d9::GetAttachmentRenderTarget(readBuffer);
- }
- if (drawBuffer)
+ RenderTarget9 *readDepthStencil = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
+ if (error.isError())
{
- drawDepthStencil = d3d9::GetAttachmentRenderTarget(drawBuffer);
+ return error;
}
+ ASSERT(readDepthStencil);
- if (readDepthStencil)
- {
- readSurface = readDepthStencil->getSurface();
- }
- if (drawDepthStencil)
- {
- drawSurface = drawDepthStencil->getSurface();
- }
+ gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
+ ASSERT(drawBuffer);
- if (!readSurface || !drawSurface)
+ RenderTarget9 *drawDepthStencil = NULL;
+ error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
+ if (error.isError())
{
- ERR("Failed to retrieve the render target.");
- return gl::error(GL_OUT_OF_MEMORY, false);
+ return error;
}
+ ASSERT(drawDepthStencil);
+
+ // The getSurface calls do an AddRef so save them until after no errors are possible
+ IDirect3DSurface9* readSurface = readDepthStencil->getSurface();
+ ASSERT(readDepthStencil);
+
+ IDirect3DSurface9* drawSurface = drawDepthStencil->getSurface();
+ ASSERT(drawDepthStencil);
HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
@@ -2639,38 +2623,31 @@ bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &
if (FAILED(result))
{
- ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
- return false;
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
}
}
- return true;
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+gl::Error Renderer9::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
ASSERT(pack.pixelBuffer.get() == NULL);
- RenderTarget9 *renderTarget = NULL;
- IDirect3DSurface9 *surface = NULL;
gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
+ ASSERT(colorbuffer);
- if (colorbuffer)
- {
- renderTarget = d3d9::GetAttachmentRenderTarget(colorbuffer);
- }
-
- if (renderTarget)
+ RenderTarget9 *renderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
{
- surface = renderTarget->getSurface();
+ return error;
}
+ ASSERT(renderTarget);
- if (!surface)
- {
- // context must be lost
- return gl::Error(GL_NO_ERROR);
- }
+ IDirect3DSurface9 *surface = renderTarget->getSurface();
+ ASSERT(surface);
D3DSURFACE_DESC desc;
surface->GetDesc(&desc);
@@ -2825,33 +2802,67 @@ gl::Error Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y,
return gl::Error(GL_NO_ERROR);
}
-RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth)
+gl::Error Renderer9::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
{
SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
- IDirect3DSurface9 *surface = NULL;
- if (depth)
- {
- surface = swapChain9->getDepthStencil();
- }
- else
+ *outRT = new SurfaceRenderTarget9(swapChain9, depth);
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
+{
+ const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
+
+ const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
+ GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+
+ IDirect3DSurface9 *renderTarget = NULL;
+ if (width > 0 && height > 0)
{
- surface = swapChain9->getRenderTarget();
- }
+ bool requiresInitialization = false;
+ HRESULT result = D3DERR_INVALIDCALL;
+
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ result = mDevice->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat,
+ gl_d3d9::GetMultisampleType(supportedSamples),
+ 0, FALSE, &renderTarget, NULL);
+ }
+ else
+ {
+ requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL);
+ result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
+ gl_d3d9::GetMultisampleType(supportedSamples),
+ 0, FALSE, &renderTarget, NULL);
+ }
- RenderTarget9 *renderTarget = new RenderTarget9(this, surface);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target, result: 0x%X.", result);
+ }
- return renderTarget;
-}
+ if (requiresInitialization)
+ {
+ // This format requires that the data be initialized before the render target can be used
+ // Unfortunately this requires a Get call on the d3d device but it is far better than having
+ // to mark the render target as lockable and copy data to the gpu.
+ IDirect3DSurface9 *prevRenderTarget = NULL;
+ mDevice->GetRenderTarget(0, &prevRenderTarget);
+ mDevice->SetRenderTarget(0, renderTarget);
+ mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
+ mDevice->SetRenderTarget(0, prevRenderTarget);
+ }
+ }
-RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples)
-{
- RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples);
- return renderTarget;
+ *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples);
+ return gl::Error(GL_NO_ERROR);
}
-ShaderImpl *Renderer9::createShader(GLenum type)
+ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type)
{
- return new ShaderD3D(type, this);
+ return new ShaderD3D(data, type, this);
}
ProgramImpl *Renderer9::createProgram()
@@ -2864,64 +2875,69 @@ void Renderer9::releaseShaderCompiler()
ShaderD3D::releaseCompiler();
}
-ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers)
+gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable)
{
// Transform feedback is not supported in ES2 or D3D9
ASSERT(transformFeedbackVaryings.size() == 0);
- ShaderExecutable9 *executable = NULL;
-
switch (type)
{
- case rx::SHADER_VERTEX:
+ case SHADER_VERTEX:
{
- IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length);
- if (vshader)
+ IDirect3DVertexShader9 *vshader = NULL;
+ gl::Error error = createVertexShader((DWORD*)function, length, &vshader);
+ if (error.isError())
{
- executable = new ShaderExecutable9(function, length, vshader);
+ return error;
}
+ *outExecutable = new ShaderExecutable9(function, length, vshader);
}
break;
- case rx::SHADER_PIXEL:
+ case SHADER_PIXEL:
{
- IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length);
- if (pshader)
+ IDirect3DPixelShader9 *pshader = NULL;
+ gl::Error error = createPixelShader((DWORD*)function, length, &pshader);
+ if (error.isError())
{
- executable = new ShaderExecutable9(function, length, pshader);
+ return error;
}
+ *outExecutable = new ShaderExecutable9(function, length, pshader);
}
break;
default:
UNREACHABLE();
- break;
+ return gl::Error(GL_INVALID_OPERATION);
}
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround)
+gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable)
{
// Transform feedback is not supported in ES2 or D3D9
ASSERT(transformFeedbackVaryings.size() == 0);
- const char *profile = NULL;
-
+ const char *profileType = NULL;
switch (type)
{
- case rx::SHADER_VERTEX:
- profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0";
+ case SHADER_VERTEX:
+ profileType = "vs";
break;
- case rx::SHADER_PIXEL:
- profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0";
+ case SHADER_PIXEL:
+ profileType = "ps";
break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
}
+ unsigned int profileMajorVersion = (getMajorShaderModel() >= 3) ? 3 : 2;
+ unsigned int profileMinorVersion = 0;
+ std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
@@ -2942,49 +2958,54 @@ ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const cha
#endif
flags |= D3DCOMPILE_DEBUG;
-
- std::string sourcePath = getTempPath();
- std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
- writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
}
// Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
// Try the default flags first and if compilation fails, try some alternatives.
- const UINT extraFlags[] =
+ std::vector<CompileConfig> configs;
+ configs.push_back(CompileConfig(flags, "default" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control" ));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control"));
+
+ ID3DBlob *binary = NULL;
+ std::string debugInfo;
+ gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo);
+ if (error.isError())
{
- flags,
- flags | D3DCOMPILE_AVOID_FLOW_CONTROL,
- flags | D3DCOMPILE_PREFER_FLOW_CONTROL
- };
+ return error;
+ }
- const static char *extraFlagNames[] =
+ // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL
+ // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK.
+ if (!binary)
{
- "default",
- "avoid flow control",
- "prefer flow control"
- };
+ *outExectuable = NULL;
+ return gl::Error(GL_NO_ERROR);
+ }
- int attempts = ArraySize(extraFlags);
+ error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
+ transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
- ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
- if (!binary)
+ SafeRelease(binary);
+ if (error.isError())
{
- return NULL;
+ return error;
}
- ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
- transformFeedbackVaryings, separatedOutputBuffers);
- SafeRelease(binary);
+ if (!debugInfo.empty())
+ {
+ (*outExectuable)->appendDebugInfo(debugInfo);
+ }
- return executable;
+ return gl::Error(GL_NO_ERROR);
}
-rx::UniformStorage *Renderer9::createUniformStorage(size_t storageSize)
+UniformStorage *Renderer9::createUniformStorage(size_t storageSize)
{
return new UniformStorage(storageSize);
}
-bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
return mBlit->boxFilter(source, dest);
}
@@ -3006,41 +3027,40 @@ D3DPOOL Renderer9::getTexturePool(DWORD usage) const
return D3DPOOL_DEFAULT;
}
-bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
+gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
{
- if (source && dest)
- {
- HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
+ ASSERT(source && dest);
- if (fromManaged)
- {
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
+ HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
- IDirect3DSurface9 *surf = 0;
- result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ if (fromManaged)
+ {
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
- if (SUCCEEDED(result))
- {
- Image9::copyLockableSurfaces(surf, source);
- result = mDevice->UpdateSurface(surf, NULL, dest, NULL);
- SafeRelease(surf);
- }
- }
- else
- {
- endScene();
- result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
- }
+ IDirect3DSurface9 *surf = 0;
+ result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
- if (FAILED(result))
+ if (SUCCEEDED(result))
{
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return false;
+ Image9::copyLockableSurfaces(surf, source);
+ result = mDevice->UpdateSurface(surf, NULL, dest, NULL);
+ SafeRelease(surf);
}
}
+ else
+ {
+ endScene();
+ result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
+ }
- return true;
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit internal texture, result: 0x%X.", result);
+ }
+
+ return gl::Error(GL_NO_ERROR);
}
Image *Renderer9::createImage()
@@ -3048,11 +3068,11 @@ Image *Renderer9::createImage()
return new Image9();
}
-void Renderer9::generateMipmap(Image *dest, Image *src)
+gl::Error Renderer9::generateMipmap(Image *dest, Image *src)
{
Image9 *src9 = Image9::makeImage9(src);
Image9 *dst9 = Image9::makeImage9(dest);
- Image9::generateMipmap(dst9, src9);
+ return Image9::generateMipmap(dst9, src9);
}
TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain)
@@ -3099,6 +3119,19 @@ TextureImpl *Renderer9::createTexture(GLenum target)
return NULL;
}
+RenderbufferImpl *Renderer9::createRenderbuffer()
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ return renderbuffer;
+}
+
+RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth)
+{
+ RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
+ renderbuffer->setStorage(swapChain, depth);
+ return renderbuffer;
+}
+
bool Renderer9::getLUID(LUID *adapterLuid) const
{
adapterLuid->HighPart = 0;
@@ -3113,7 +3146,7 @@ bool Renderer9::getLUID(LUID *adapterLuid) const
return false;
}
-rx::VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
+VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
{
return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType;
}
@@ -3128,4 +3161,9 @@ void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCa
d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, outExtensions);
}
+Workarounds Renderer9::generateWorkarounds() const
+{
+ return d3d9::GenerateWorkarounds();
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index dd5f30268a..10d2fb11e8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -11,10 +11,10 @@
#include "common/angleutils.h"
#include "common/mathutil.h"
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
#include "libGLESv2/renderer/d3d/d3d9/ShaderCache.h"
#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/RenderTarget.h"
namespace gl
@@ -22,6 +22,11 @@ namespace gl
class FramebufferAttachment;
}
+namespace egl
+{
+class AttributeMap;
+}
+
namespace rx
{
class VertexDataManager;
@@ -31,10 +36,10 @@ class StaticIndexBufferInterface;
struct TranslatedAttribute;
class Blit9;
-class Renderer9 : public Renderer
+class Renderer9 : public RendererD3D
{
public:
- Renderer9(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay);
+ Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes);
virtual ~Renderer9();
static Renderer9 *makeRenderer9(Renderer *renderer);
@@ -48,27 +53,27 @@ class Renderer9 : public Renderer
void startScene();
void endScene();
- virtual void sync(bool block);
+ virtual gl::Error sync(bool block);
- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
- IDirect3DQuery9* allocateEventQuery();
+ gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery);
void freeEventQuery(IDirect3DQuery9* query);
// resource creation
- IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length);
- IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
+ gl::Error createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader);
+ gl::Error createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader);
HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer);
virtual gl::Error generateSwizzle(gl::Texture *texture);
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
- virtual gl::Error setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
- unsigned int sampleMask);
+ gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
+ unsigned int sampleMask) override;
virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
int stencilBackRef, bool frontFaceCCW);
@@ -76,35 +81,35 @@ class Renderer9 : public Renderer
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport);
- virtual gl::Error applyRenderTarget(gl::Framebuffer *frameBuffer);
+ gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
- virtual gl::Error applyUniforms(const gl::ProgramBinary &programBinary);
+ virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
- virtual gl::Error applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[],
- GLint first, GLsizei count, GLsizei instances);
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
+ virtual void applyTransformFeedbackBuffers(const gl::State& state);
virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
- virtual gl::Error clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+ gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
virtual void markAllStateDirty();
// lost device
- void notifyDeviceLost();
- virtual bool isDeviceLost();
- virtual bool testDeviceLost(bool notify);
- virtual bool testDeviceResettable();
+ void notifyDeviceLost() override;
+ bool isDeviceLost() override;
+ bool testDeviceLost(bool notify) override;
+ bool testDeviceResettable() override;
+
+ DWORD getAdapterVendor() const override;
+ std::string getRendererDescription() const override;
+ GUID getAdapterIdentifier() const override;
IDirect3DDevice9 *getDevice() { return mDevice; }
- virtual DWORD getAdapterVendor() const;
- virtual std::string getRendererDescription() const;
- virtual GUID getAdapterIdentifier() const;
virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const;
@@ -119,47 +124,45 @@ class Renderer9 : public Renderer
virtual int getMaxSwapInterval() const;
// Pixel operations
- virtual bool copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source);
- virtual bool copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source);
-
- virtual bool copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- virtual bool copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
- virtual bool copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter);
+ gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
+ const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter) override;
- virtual gl::Error readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+ virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
// RenderTarget creation
- virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
- virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples);
+ virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
// Shader creation
- virtual ShaderImpl *createShader(GLenum type);
+ virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
virtual ProgramImpl *createProgram();
// Shader operations
- virtual void releaseShaderCompiler();
- virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers);
- virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
- const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround);
+ void releaseShaderCompiler() override;
+ virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, ShaderExecutable **outExecutable);
+ virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
+ const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
+ bool separatedOutputBuffers, D3DWorkaroundType workaround,
+ ShaderExecutable **outExectuable);
virtual UniformStorage *createUniformStorage(size_t storageSize);
// Image operations
virtual Image *createImage();
- virtual void generateMipmap(Image *dest, Image *source);
+ gl::Error generateMipmap(Image *dest, Image *source) override;
virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
@@ -169,6 +172,10 @@ class Renderer9 : public Renderer
// Texture creation
virtual TextureImpl *createTexture(GLenum target);
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer();
+ virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
+
// Buffer creation
virtual BufferImpl *createBuffer();
virtual VertexBuffer *createVertexBuffer();
@@ -179,29 +186,33 @@ class Renderer9 : public Renderer
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
- virtual FenceImpl *createFence();
+ virtual FenceNVImpl *createFenceNV();
+ virtual FenceSyncImpl *createFenceSync();
// Transform Feedback creation
virtual TransformFeedbackImpl* createTransformFeedback();
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
- virtual bool fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
- GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
// D3D9-renderer specific methods
- bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+ gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
D3DPOOL getTexturePool(DWORD usage) const;
virtual bool getLUID(LUID *adapterLuid) const;
- virtual rx::VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
+ gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
+
private:
DISALLOW_COPY_AND_ASSIGN(Renderer9);
- virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const;
+ void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
+ Workarounds generateWorkarounds() const override;
void release();
@@ -214,8 +225,7 @@ class Renderer9 : public Renderer
gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
- bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
- gl::FramebufferAttachment *getNullColorbuffer(gl::FramebufferAttachment *depthbuffer);
+ gl::Error getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer);
D3DPOOL getBufferPool(DWORD usage) const;
@@ -263,7 +273,7 @@ class Renderer9 : public Renderer
unsigned int mAppliedStencilbufferSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
- rx::RenderTarget::Desc mRenderTargetDesc;
+ RenderTarget::Desc mRenderTargetDesc;
unsigned int mCurStencilSize;
unsigned int mCurDepthSize;
@@ -310,8 +320,8 @@ class Renderer9 : public Renderer
IDirect3DPixelShader9 *mAppliedPixelShader;
unsigned int mAppliedProgramSerial;
- rx::dx_VertexConstants mVertexConstants;
- rx::dx_PixelConstants mPixelConstants;
+ dx_VertexConstants mVertexConstants;
+ dx_PixelConstants mPixelConstants;
bool mDxUniformsDirty;
// A pool of event queries that are currently unused.
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
index 2ad3022839..6d7d2d648f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
@@ -10,6 +10,8 @@
#ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
#define LIBGLESV2_RENDERER_SHADER_CACHE_H_
+#include "libGLESv2/Error.h"
+
#include "common/debug.h"
#include <cstddef>
@@ -37,21 +39,22 @@ class ShaderCache
mDevice = device;
}
- ShaderObject *create(const DWORD *function, size_t length)
+ gl::Error create(const DWORD *function, size_t length, ShaderObject **outShaderObject)
{
std::string key(reinterpret_cast<const char*>(function), length);
typename Map::iterator it = mMap.find(key);
if (it != mMap.end())
{
it->second->AddRef();
- return it->second;
+ *outShaderObject = it->second;
+ return gl::Error(GL_NO_ERROR);
}
ShaderObject *shader;
HRESULT result = createShader(function, &shader);
if (FAILED(result))
{
- return NULL;
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader, result: 0x%X.", result);
}
// Random eviction policy.
@@ -64,7 +67,8 @@ class ShaderCache
shader->AddRef();
mMap[key] = shader;
- return shader;
+ *outShaderObject = shader;
+ return gl::Error(GL_NO_ERROR);
}
void clear()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
index 0aeaabb1ca..95eb1a4371 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
@@ -11,12 +11,15 @@
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "common/features.h"
+
namespace rx
{
-SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
- : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+ : mRenderer(renderer),
+ SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
{
mSwapChain = NULL;
mBackBuffer = NULL;
@@ -41,7 +44,7 @@ void SwapChain9::release()
SafeRelease(mRenderTarget);
SafeRelease(mOffscreenTexture);
- if (mWindow)
+ if (mNativeWindow.getNativeWindow())
{
mShareHandle = NULL;
}
@@ -49,7 +52,7 @@ void SwapChain9::release()
static DWORD convertInterval(EGLint interval)
{
-#ifdef ANGLE_FORCE_VSYNC_OFF
+#if ANGLE_VSYNC == ANGLE_DISABLED
return D3DPRESENT_INTERVAL_IMMEDIATE;
#else
switch(interval)
@@ -95,7 +98,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
SafeRelease(mDepthStencil);
HANDLE *pShareHandle = NULL;
- if (!mWindow && mRenderer->getShareHandleSupport())
+ if (!mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport())
{
pShareHandle = &mShareHandle;
}
@@ -152,7 +155,8 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
const d3d9::TextureFormat &depthBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mDepthBufferFormat);
- if (mWindow)
+ EGLNativeWindowType window = mNativeWindow.getNativeWindow();
+ if (window)
{
D3DPRESENT_PARAMETERS presentParameters = {0};
presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
@@ -160,7 +164,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat;
presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = mWindow;
+ presentParameters.hDeviceWindow = window;
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
presentParameters.PresentationInterval = convertInterval(swapInterval);
@@ -203,7 +207,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
ASSERT(SUCCEEDED(result));
- InvalidateRect(mWindow, NULL, FALSE);
+ InvalidateRect(window, NULL, FALSE);
}
if (mDepthBufferFormat != GL_NONE)
@@ -238,7 +242,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
}
// parameters should be validated/clamped by caller
-EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint)
+EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
@@ -379,8 +383,8 @@ IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
{
- ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain));
- return static_cast<rx::SwapChain9*>(swapChain);
+ ASSERT(HAS_DYNAMIC_TYPE(SwapChain9*, swapChain));
+ return static_cast<SwapChain9*>(swapChain);
}
void SwapChain9::recreate()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
index 4d756f80d1..cb33bfbc0c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
@@ -19,19 +19,22 @@ class Renderer9;
class SwapChain9 : public SwapChain
{
public:
- SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+ SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain9();
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint);
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
virtual IDirect3DTexture9 *getOffscreenTexture();
+ EGLint getWidth() const { return mWidth; }
+ EGLint getHeight() const { return mHeight; }
+
static SwapChain9 *makeSwapChain9(SwapChain *swapChain);
private:
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
index f44e33db18..0ff4fd3b0f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -20,8 +20,13 @@
namespace rx
{
-TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage)
: mTopLevel(0),
+ mMipLevels(0),
+ mTextureWidth(0),
+ mTextureHeight(0),
+ mInternalFormat(GL_NONE),
+ mTextureFormat(D3DFMT_UNKNOWN),
mRenderer(Renderer9::makeRenderer9(renderer)),
mD3DUsage(usage),
mD3DPool(mRenderer->getTexturePool(usage))
@@ -84,44 +89,52 @@ int TextureStorage9::getTopLevel() const
int TextureStorage9::getLevelCount() const
{
- return getBaseTexture() ? (getBaseTexture()->GetLevelCount() - getTopLevel()) : 0;
+ return mMipLevels - mTopLevel;
}
-TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain)
+gl::Error TextureStorage9::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
+{
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain)
: TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
{
IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
mTexture = surfaceTexture;
+ mMipLevels = surfaceTexture->GetLevelCount();
+
+ mInternalFormat = swapchain->GetBackBufferInternalFormat();
+
+ D3DSURFACE_DESC surfaceDesc;
+ surfaceTexture->GetLevelDesc(0, &surfaceDesc);
+ mTextureWidth = surfaceDesc.Width;
+ mTextureHeight = surfaceDesc.Height;
+ mTextureFormat = surfaceDesc.Format;
+
mRenderTarget = NULL;
- initializeRenderTarget();
initializeSerials(1, 1);
}
-TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
mRenderTarget = NULL;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
- UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
- HRESULT result = device->CreateTexture(width, height, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
+ mInternalFormat = internalformat;
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- gl::error(GL_OUT_OF_MEMORY);
- }
- }
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
+
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mMipLevels = mTopLevel + levels;
- initializeRenderTarget();
initializeSerials(getLevelCount(), 1);
}
@@ -139,104 +152,168 @@ TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *s
// Increments refcount on surface.
// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty)
+gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface)
{
- IDirect3DSurface9 *surface = NULL;
+ IDirect3DBaseTexture9 *baseTexture = NULL;
+ gl::Error error = getBaseTexture(&baseTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DTexture9 *texture = static_cast<IDirect3DTexture9*>(baseTexture);
- if (mTexture)
+ HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface);
+
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- HRESULT result = mTexture->GetSurfaceLevel(level + mTopLevel, &surface);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result);
+ }
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level + mTopLevel != 0 && isManaged() && dirty)
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level + mTopLevel != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(NULL);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTarget **outRT)
+{
+ if (!mRenderTarget && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+ gl::Error error = getSurfaceLevel(0, false, &surface);
+ if (error.isError())
{
- mTexture->AddDirtyRect(NULL);
+ return error;
}
+
+ mRenderTarget = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0);
}
- return surface;
+ ASSERT(outRT);
+ *outRT = mRenderTarget;
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/)
+gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- return mRenderTarget;
+ IDirect3DSurface9 *upper = NULL;
+ gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DSurface9 *lower = NULL;
+ error = getSurfaceLevel(destIndex.mipIndex, true, &lower);
+ if (error.isError())
+ {
+ SafeRelease(upper);
+ return error;
+ }
+
+ ASSERT(upper && lower);
+ error = mRenderer->boxFilter(upper, lower);
+
+ SafeRelease(upper);
+ SafeRelease(lower);
+
+ return error;
}
-void TextureStorage9_2D::generateMipmaps()
+gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
{
- // Base level must already be defined
-
- for (int level = 1; level < getLevelCount(); level++)
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
- IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+ ASSERT(mMipLevels > 0);
- if (upper != NULL && lower != NULL)
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat,
+ getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
{
- mRenderer->boxFilter(upper, lower);
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result);
}
-
- SafeRelease(upper);
- SafeRelease(lower);
}
-}
-IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const
-{
- return mTexture;
+ *outTexture = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage9_2D::initializeRenderTarget()
+gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage)
{
- ASSERT(mRenderTarget == NULL);
+ ASSERT(destStorage);
+
+ TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(destStorage);
- if (mTexture != NULL && isRenderTarget())
+ int levels = getLevelCount();
+ for (int i = 0; i < levels; ++i)
{
- IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+ IDirect3DSurface9 *srcSurf = NULL;
+ gl::Error error = getSurfaceLevel(i, false, &srcSurf);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderTarget = new RenderTarget9(mRenderer, surface);
+ IDirect3DSurface9 *dstSurf = NULL;
+ error = dest9->getSurfaceLevel(i, true, &dstSurf);
+ if (error.isError())
+ {
+ SafeRelease(srcSurf);
+ return error;
+ }
+
+ error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
+
+ SafeRelease(srcSurf);
+ SafeRelease(dstSurf);
+
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return gl::Error(GL_NO_ERROR);
}
-TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
- for (int i = 0; i < 6; ++i)
+ for (int i = 0; i < CUBE_FACE_COUNT; ++i)
{
mRenderTarget[i] = NULL;
}
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- IDirect3DDevice9 *device = mRenderer->getDevice();
- int height = size;
- const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
- UINT creationLevels = (levels == 0) ? 0 : mTopLevel + levels;
+ mInternalFormat = internalformat;
- HRESULT result = device->CreateCubeTexture(size, creationLevels, getUsage(), d3dFormatInfo.texFormat, getPool(), &mTexture, NULL);
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- gl::error(GL_OUT_OF_MEMORY);
- }
- }
+ int height = size;
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mMipLevels = mTopLevel + levels;
- initializeRenderTarget();
- initializeSerials(getLevelCount() * 6, 6);
+ initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
TextureStorage9_Cube::~TextureStorage9_Cube()
{
SafeRelease(mTexture);
- for (int i = 0; i < 6; ++i)
+ for (int i = 0; i < CUBE_FACE_COUNT; ++i)
{
SafeDelete(mRenderTarget[i]);
}
@@ -250,74 +327,146 @@ TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStor
// Increments refcount on surface.
// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface)
{
- IDirect3DSurface9 *surface = NULL;
+ IDirect3DBaseTexture9 *baseTexture = NULL;
+ gl::Error error = getBaseTexture(&baseTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DCubeTexture9 *texture = static_cast<IDirect3DCubeTexture9*>(baseTexture);
- if (mTexture)
+ D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+ HRESULT result = texture->GetCubeMapSurface(face, level + mTopLevel, outSurface);
+
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
- HRESULT result = mTexture->GetCubeMapSurface(face, level + mTopLevel, &surface);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(SUCCEEDED(result));
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result);
+ }
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(face, NULL);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+{
+ ASSERT(outRT);
+ ASSERT(index.mipIndex == 0);
+ ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT);
+
+ if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+ gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, 0, false, &surface);
+ if (error.isError())
{
- mTexture->AddDirtyRect(face, NULL);
+ return error;
}
+
+ mRenderTarget[index.layerIndex] = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0);
}
- return surface;
+ *outRT = mRenderTarget[index.layerIndex];
+ return gl::Error(GL_NO_ERROR);
}
-RenderTarget *TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index)
+gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex)
{
- return mRenderTarget[index.layerIndex];
+ IDirect3DSurface9 *upper = NULL;
+ gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ IDirect3DSurface9 *lower = NULL;
+ error = getCubeMapSurface(destIndex.type, destIndex.mipIndex, true, &lower);
+ if (error.isError())
+ {
+ SafeRelease(upper);
+ return error;
+ }
+
+ ASSERT(upper && lower);
+ error = mRenderer->boxFilter(upper, lower);
+
+ SafeRelease(upper);
+ SafeRelease(lower);
+
+ return error;
}
-void TextureStorage9_Cube::generateMipmaps()
+gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture)
{
- // Base level must already be defined
-
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- for (int level = 1; level < getLevelCount(); level++)
- {
- IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1, false);
- IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, true);
+ ASSERT(mMipLevels > 0);
+ ASSERT(mTextureWidth == mTextureHeight);
- if (upper != NULL && lower != NULL)
- {
- mRenderer->boxFilter(upper, lower);
- }
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateCubeTexture(mTextureWidth, mMipLevels, getUsage(), mTextureFormat, getPool(),
+ &mTexture, NULL);
- SafeRelease(upper);
- SafeRelease(lower);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube storage texture, result: 0x%X.", result);
}
}
-}
-IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const
-{
- return mTexture;
+ *outTexture = mTexture;
+ return gl::Error(GL_NO_ERROR);
}
-void TextureStorage9_Cube::initializeRenderTarget()
+gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage)
{
- if (mTexture != NULL && isRenderTarget())
- {
- IDirect3DSurface9 *surface = NULL;
+ ASSERT(destStorage);
+
+ TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(destStorage);
- for (int i = 0; i < 6; ++i)
+ int levels = getLevelCount();
+ for (int f = 0; f < CUBE_FACE_COUNT; f++)
+ {
+ for (int i = 0; i < levels; i++)
{
- ASSERT(mRenderTarget[i] == NULL);
+ IDirect3DSurface9 *srcSurf = NULL;
+ gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf);
+ if (error.isError())
+ {
+ return error;
+ }
- surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+ IDirect3DSurface9 *dstSurf = NULL;
+ error = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf);
+ if (error.isError())
+ {
+ SafeRelease(srcSurf);
+ return error;
+ }
+
+ error = mRenderer->copyToRenderTarget(dstSurf, srcSurf, isManaged());
- mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+ SafeRelease(srcSurf);
+ SafeRelease(dstSurf);
+
+ if (error.isError())
+ {
+ return error;
+ }
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
index e698c7dd56..da0e1f2f18 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
@@ -33,20 +33,28 @@ class TextureStorage9 : public TextureStorage
D3DPOOL getPool() const;
DWORD getUsage() const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
- virtual void generateMipmaps() = 0;
+ virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
virtual int getLevelCount() const;
+ virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
+
protected:
int mTopLevel;
+ size_t mMipLevels;
+ size_t mTextureWidth;
+ size_t mTextureHeight;
+ GLenum mInternalFormat;
+ D3DFORMAT mTextureFormat;
+
Renderer9 *mRenderer;
- TextureStorage9(Renderer *renderer, DWORD usage);
+ TextureStorage9(Renderer9 *renderer, DWORD usage);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
@@ -58,22 +66,21 @@ class TextureStorage9 : public TextureStorage
class TextureStorage9_2D : public TextureStorage9
{
public:
- TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain);
- TextureStorage9_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
+ TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain);
+ TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
virtual ~TextureStorage9_2D();
static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
- IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
- virtual void generateMipmaps();
+ gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D);
- void initializeRenderTarget();
-
IDirect3DTexture9 *mTexture;
RenderTarget9 *mRenderTarget;
};
@@ -81,23 +88,24 @@ class TextureStorage9_2D : public TextureStorage9
class TextureStorage9_Cube : public TextureStorage9
{
public:
- TextureStorage9_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
+ TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
virtual ~TextureStorage9_Cube();
static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
- IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
- virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
- virtual void generateMipmaps();
+ gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
+ virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube);
- void initializeRenderTarget();
+ static const size_t CUBE_FACE_COUNT = 6;
IDirect3DCubeTexture9 *mTexture;
- RenderTarget9 *mRenderTarget[6];
+ RenderTarget9 *mRenderTarget[CUBE_FACE_COUNT];
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
index 66a6c64d81..791c108462 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
@@ -19,7 +19,7 @@ class Renderer9;
class VertexArray9 : public VertexArrayImpl
{
public:
- VertexArray9(rx::Renderer9 *renderer)
+ VertexArray9(Renderer9 *renderer)
: VertexArrayImpl(),
mRenderer(renderer)
{
@@ -35,7 +35,7 @@ class VertexArray9 : public VertexArrayImpl
private:
DISALLOW_COPY_AND_ASSIGN(VertexArray9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
index 4cf7779118..b90133097c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -10,14 +10,14 @@
#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
#include "libGLESv2/renderer/vertexconversion.h"
-#include "libGLESv2/renderer/BufferImpl.h"
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
#include "libGLESv2/VertexAttribute.h"
#include "libGLESv2/Buffer.h"
namespace rx
{
-VertexBuffer9::VertexBuffer9(rx::Renderer9 *renderer) : mRenderer(renderer)
+VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer)
{
mVertexBuffer = NULL;
mBufferSize = 0;
@@ -97,8 +97,14 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib
{
if (buffer)
{
- BufferImpl *storage = buffer->getImplementation();
- input = static_cast<const uint8_t*>(storage->getData()) + static_cast<int>(attrib.offset);
+ BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
+ ASSERT(storage);
+ gl::Error error = storage->getData(&input);
+ if (error.isError())
+ {
+ return error;
+ }
+ input += static_cast<int>(attrib.offset);
}
else
{
@@ -203,7 +209,7 @@ gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::s
else
{
// Round up to divisor, if possible
- elementCount = rx::UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
+ elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
index bdcf4bb64a..9af2b98a6e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
@@ -18,7 +18,7 @@ class Renderer9;
class VertexBuffer9 : public VertexBuffer
{
public:
- explicit VertexBuffer9(rx::Renderer9 *renderer);
+ explicit VertexBuffer9(Renderer9 *renderer);
virtual ~VertexBuffer9();
virtual gl::Error initialize(unsigned int size, bool dynamicUsage);
@@ -39,7 +39,7 @@ class VertexBuffer9 : public VertexBuffer
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
- rx::Renderer9 *mRenderer;
+ Renderer9 *mRenderer;
IDirect3DVertexBuffer9 *mVertexBuffer;
unsigned int mBufferSize;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
index e7a91e62d6..a98b2081f3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -9,6 +9,7 @@
#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
+#include "libGLESv2/renderer/Workarounds.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
@@ -390,8 +391,9 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
caps->maxVertexUniformBlocks = 0;
- const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 10;
- const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 8;
+ // SM3 only supports 11 output variables, with a special 12th register for PSIZE.
+ const size_t MAX_VERTEX_OUTPUT_VECTORS_SM3 = 9;
+ const size_t MAX_VERTEX_OUTPUT_VECTORS_SM2 = 7;
caps->maxVertexOutputComponents = ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3
: MAX_VERTEX_OUTPUT_VECTORS_SM2) * 4;
@@ -459,7 +461,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
!(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
!(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
- !(isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
+ !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
}
else
{
@@ -531,10 +533,24 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize
*levelOffset = upsampleCount;
}
-RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT)
{
- RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
- return RenderTarget9::makeRenderTarget9(renderTarget);
+ RenderTarget *renderTarget = NULL;
+ gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ *outRT = RenderTarget9::makeRenderTarget9(renderTarget);
+ return gl::Error(GL_NO_ERROR);
+}
+
+Workarounds GenerateWorkarounds()
+{
+ Workarounds workarounds;
+ workarounds.mrtPerfWorkaround = true;
+ workarounds.setDataFasterThanImageUpload = false;
+ return workarounds;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
index b0a940e60a..9760b9735a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
@@ -12,6 +12,7 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/Caps.h"
+#include "libGLESv2/Error.h"
namespace gl
{
@@ -21,6 +22,7 @@ class FramebufferAttachment;
namespace rx
{
class RenderTarget9;
+struct Workarounds;
namespace gl_d3d9
{
@@ -74,7 +76,8 @@ inline bool isDeviceLostError(HRESULT errorCode)
}
}
-RenderTarget9 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT);
+Workarounds GenerateWorkarounds();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
index f777b30be6..159b4c7e9f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
@@ -10,10 +10,6 @@
#include "libGLESv2/renderer/loadimage.h"
-#if !defined(__SSE2__) && (defined(_M_X64) || _M_IX86_FP == 2)
-#define __SSE2__
-#endif
-
namespace rx
{
@@ -21,7 +17,12 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{
-#ifdef __SSE2__
+#if defined(_M_ARM)
+ // Ensure that this function is reported as not implemented for ARM builds because
+ // the instructions below are not present for that architecture.
+ UNIMPLEMENTED();
+ return;
+#else
__m128i zeroWide = _mm_setzero_si128();
for (size_t z = 0; z < depth; z++)
@@ -66,7 +67,12 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{
-#ifdef __SSE2__
+#if defined(_M_ARM)
+ // Ensure that this function is reported as not implemented for ARM builds because
+ // the instructions below are not present for that architecture.
+ UNIMPLEMENTED();
+ return;
+#else
__m128i brMask = _mm_set1_epi32(0x00ff00ff);
for (size_t z = 0; z < depth; z++)
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.cpp b/src/3rdparty/angle/src/libGLESv2/validationES.cpp
index f79bc97e4f..265f4b4fba 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/validationES.cpp
@@ -24,6 +24,9 @@
#include "common/mathutil.h"
#include "common/utilities.h"
+// FIXME(jmadill): remove this when we support buffer data caching
+#include "libGLESv2/renderer/d3d/BufferD3D.h"
+
namespace gl
{
@@ -497,14 +500,26 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
gl::Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
- if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
- !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+
+ if (!readFramebuffer || !drawFramebuffer)
+ {
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
+ }
+
+ if (!readFramebuffer->completeness(context->getData()))
+ {
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return false;
+ }
+
+ if (!drawFramebuffer->completeness(context->getData()))
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (drawFramebuffer->getSamples() != 0)
+ if (drawFramebuffer->getSamples(context->getData()) != 0)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -588,16 +603,20 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
return false;
}
- if (attachment->getActualFormat() != readColorBuffer->getActualFormat())
+ // Return an error if the destination formats do not match
+ if (attachment->getInternalFormat() != readColorBuffer->getInternalFormat())
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
}
}
- if (readFramebuffer->getSamples() != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer,
- srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1))
+
+ int readSamples = readFramebuffer->getSamples(context->getData());
+
+ if (readSamples != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer,
+ srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -912,13 +931,14 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
ASSERT(framebuffer);
- if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
+ if (context->getState().getReadFramebuffer()->id() != 0 &&
+ framebuffer->getSamples(context->getData()) != 0)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1172,7 +1192,7 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
{
Framebuffer *framebuffer = context->getState().getReadFramebuffer();
ASSERT(framebuffer);
- if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1236,13 +1256,13 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
}
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
- if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
+ if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples(context->getData()) != 0)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1441,7 +1461,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
}
const gl::Framebuffer *fbo = state.getDrawFramebuffer();
- if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (!fbo || fbo->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
@@ -1667,11 +1687,20 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
// TODO: also disable index checking on back-ends that are robust to out-of-range accesses.
if (elementArrayBuffer)
{
- GLint64 offset = reinterpret_cast<GLint64>(indices);
+ uintptr_t offset = reinterpret_cast<uintptr_t>(indices);
if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL))
{
- const void *dataPointer = elementArrayBuffer->getImplementation()->getData();
- const uint8_t *offsetPointer = static_cast<const uint8_t *>(dataPointer) + offset;
+ // FIXME(jmadill): Use buffer data caching instead of the D3D back-end
+ rx::BufferD3D *bufferD3D = rx::BufferD3D::makeBufferD3D(elementArrayBuffer->getImplementation());
+ const uint8_t *dataPointer = NULL;
+ Error error = bufferD3D->getData(&dataPointer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return false;
+ }
+
+ const uint8_t *offsetPointer = dataPointer + offset;
*indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count);
}
}
@@ -1850,6 +1879,11 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
return false;
}
+ if (!ValidProgram(context, program))
+ {
+ return false;
+ }
+
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp b/src/3rdparty/angle/src/libGLESv2/validationES3.cpp
index 251c6ad2c4..2d3a039e13 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/validationES3.cpp
@@ -542,7 +542,8 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
return false;
}
- size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat);
+ size_t copyBytes = formatInfo.computeBlockSize(type, width, height);
size_t offset = reinterpret_cast<size_t>(pixels);
if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
@@ -555,12 +556,15 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
// ...data is not evenly divisible into the number of bytes needed to store in memory a datum
// indicated by type.
- size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
-
- if ((offset % dataBytesPerPixel) != 0)
+ if (!isCompressed)
{
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
+ size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes);
+
+ if ((offset % dataBytesPerPixel) != 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
// ...the buffer object's data store is currently mapped.
@@ -872,13 +876,14 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
- if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
+ if (context->getState().getReadFramebuffer()->id() != 0 &&
+ framebuffer->getSamples(context->getData()) != 0)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1258,7 +1263,7 @@ bool ValidateClearBuffer(Context *context)
}
const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
- if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (!fbo || fbo->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
diff --git a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp
index 19a9644d70..97dfcaac51 100644
--- a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp
+++ b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp
@@ -24,6 +24,7 @@
*/
#include <windows.h>
+#include "common/platform.h"
#if _WIN32_WINNT_WINBLUE
#include <versionhelpers.h>
@@ -52,7 +53,11 @@ bool isWindowsVistaOrGreater()
if (!initialized) {
initialized = true;
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ cachedIsWindowsVistaOrGreater = true;
+#else
cachedIsWindowsVistaOrGreater = IsWindowsVistaOrGreater();
+#endif
}
return cachedIsWindowsVistaOrGreater;
}
diff --git a/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch b/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch
new file mode 100644
index 0000000000..ac7580d5c4
--- /dev/null
+++ b/src/3rdparty/freebsd/0001-Patch-the-FreeBSD-strto-u-ll-functions-to-work-insid.patch
@@ -0,0 +1,149 @@
+From 81a2d1a38becdeed2cd8b963e190aedf197e39c6 Mon Sep 17 00:00:00 2001
+From: Thiago Macieira <thiago.macieira@intel.com>
+Date: Thu, 2 Oct 2014 22:03:19 -0700
+Subject: [PATCH 1/1] Patch the FreeBSD strto(u)ll functions to work inside
+ QtCore
+
+Changes:
+ - remove the #includes and the SCCSID
+ - rename from strtoxx_l to qt_strtoxx (merging the two functions)
+ - remove __restrict
+ - remove the locale_t parameter and use ascii_isspace instead of isspace_l
+
+Change-Id: I1e522e12da90eb35eefcf4025102dc11b22c60a5
+---
+ src/3rdparty/freebsd/strtoll.c | 27 +++++----------------------
+ src/3rdparty/freebsd/strtoull.c | 27 +++++----------------------
+ 2 files changed, 10 insertions(+), 44 deletions(-)
+
+diff --git a/src/3rdparty/freebsd/strtoll.c b/src/3rdparty/freebsd/strtoll.c
+index 16a8196..0ded267 100644
+--- a/src/3rdparty/freebsd/strtoll.c
++++ b/src/3rdparty/freebsd/strtoll.c
+@@ -32,18 +32,6 @@
+ * SUCH DAMAGE.
+ */
+
+-#if defined(LIBC_SCCS) && !defined(lint)
+-static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93";
+-#endif /* LIBC_SCCS and not lint */
+-#include <sys/cdefs.h>
+-__FBSDID("$FreeBSD$");
+-
+-#include <limits.h>
+-#include <errno.h>
+-#include <ctype.h>
+-#include <stdlib.h>
+-#include "xlocale_private.h"
+-
+ /*
+ * Convert a string to a long long integer.
+ *
+@@ -51,15 +39,15 @@ __FBSDID("$FreeBSD$");
+ * alphabets and digits are each contiguous.
+ */
+ long long
+-strtoll_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+- locale_t locale)
++qt_strtoll(const char * nptr, char **endptr, int base)
+ {
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+- FIX_LOCALE(locale);
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+@@ -69,7 +55,7 @@ strtoll_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+ s = nptr;
+ do {
+ c = *s++;
+- } while (isspace_l((unsigned char)c, locale));
++ } while (ascii_isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+@@ -141,13 +127,8 @@ strtoll_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+ noconv:
+ errno = EINVAL;
+ } else if (neg)
+- acc = -acc;
++ acc = (unsigned long long) -(long long)acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+ }
+-long long
+-strtoll(const char * __restrict nptr, char ** __restrict endptr, int base)
+-{
+- return strtoll_l(nptr, endptr, base, __get_locale());
+-}
+diff --git a/src/3rdparty/freebsd/strtoull.c b/src/3rdparty/freebsd/strtoull.c
+index dc40e0e..cb04adb 100644
+--- a/src/3rdparty/freebsd/strtoull.c
++++ b/src/3rdparty/freebsd/strtoull.c
+@@ -32,18 +32,6 @@
+ * SUCH DAMAGE.
+ */
+
+-#if defined(LIBC_SCCS) && !defined(lint)
+-static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
+-#endif /* LIBC_SCCS and not lint */
+-#include <sys/cdefs.h>
+-__FBSDID("$FreeBSD$");
+-
+-#include <limits.h>
+-#include <errno.h>
+-#include <ctype.h>
+-#include <stdlib.h>
+-#include "xlocale_private.h"
+-
+ /*
+ * Convert a string to an unsigned long long integer.
+ *
+@@ -51,15 +39,15 @@ __FBSDID("$FreeBSD$");
+ * alphabets and digits are each contiguous.
+ */
+ unsigned long long
+-strtoull_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+- locale_t locale)
++qt_strtoull(const char * nptr, char **endptr, int base)
+ {
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+- FIX_LOCALE(locale);
+
+ /*
+ * See strtoq for comments as to the logic used.
+@@ -67,7 +53,7 @@ strtoull_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+ s = nptr;
+ do {
+ c = *s++;
+- } while (isspace_l((unsigned char)c, locale));
++ } while (ascii_isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+@@ -119,13 +105,8 @@ strtoull_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+ noconv:
+ errno = EINVAL;
+ } else if (neg)
+- acc = -acc;
++ acc = (unsigned long long) -(long long)acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+ }
+-unsigned long long
+-strtoull(const char * __restrict nptr, char ** __restrict endptr, int base)
+-{
+- return strtoull_l(nptr, endptr, base, __get_locale());
+-}
+--
+1.8.4.5
+
diff --git a/src/3rdparty/freebsd/strtoll.c b/src/3rdparty/freebsd/strtoll.c
new file mode 100644
index 0000000000..6f06e03dc8
--- /dev/null
+++ b/src/3rdparty/freebsd/strtoll.c
@@ -0,0 +1,134 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 THE REGENTS OR 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.
+ */
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long long
+qt_strtoll(const char * nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (ascii_isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for quads is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set 'any' if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
+ : LLONG_MAX;
+ cutlim = cutoff % base;
+ cutoff /= base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LLONG_MIN : LLONG_MAX;
+ errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
+ } else if (neg)
+ acc = (unsigned long long) -(long long)acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/src/3rdparty/freebsd/strtoull.c b/src/3rdparty/freebsd/strtoull.c
new file mode 100644
index 0000000000..7cb97f02f4
--- /dev/null
+++ b/src/3rdparty/freebsd/strtoull.c
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 THE REGENTS OR 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.
+ */
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long long
+qt_strtoull(const char * nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (ascii_isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ cutoff = ULLONG_MAX / base;
+ cutlim = ULLONG_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULLONG_MAX;
+ errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
+ } else if (neg)
+ acc = (unsigned long long) -(long long)acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
index 653705f6ca..9a2726c935 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
@@ -276,7 +276,9 @@ static sljit_si cpu_has_sse2 = -1;
#endif
static sljit_si cpu_has_cmov = -1;
-#if defined(_MSC_VER) && _MSC_VER >= 1400
+#ifdef _WIN32_WCE
+#include <cmnintrin.h>
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
#include <intrin.h>
#endif
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
index 0eda08c9d9..a8583cde17 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -49,6 +49,7 @@ import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
@@ -67,6 +68,7 @@ import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.PorterDuff;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ClipDrawable;
@@ -94,8 +96,11 @@ public class ExtractStyle {
native static int[] extractChunkInfo20(byte[] chunkData);
native static int[] extractNativeChunkInfo20(long nativeChunk);
+ Class<?> styleableClass = getClass("android.R$styleable");
+ Class<?> rippleDrawableClass = getClass("android.graphics.drawable.RippleDrawable");
+ Class<?> animatedStateListDrawableClass = getClass("android.graphics.drawable.AnimatedStateListDrawable");
+ Class<?> vectorDrawableClass = getClass("android.graphics.drawable.VectorDrawable");
- Class<?> styleableClass = getStylableClass();
final int[] EMPTY_STATE_SET = {};
final int[] ENABLED_STATE_SET = {android.R.attr.state_enabled};
final int[] FOCUSED_STATE_SET = {android.R.attr.state_focused};
@@ -386,15 +391,44 @@ public class ExtractStyle {
return null;
}
- private Class<?> getStylableClass() {
+ private Class<?> getClass(String className) {
try {
- return Class.forName("android.R$styleable");
+ return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
+ Field getAccessibleField(Class<?> clazz, String fieldName) {
+ try {
+ Field f = clazz.getDeclaredField(fieldName);
+ f.setAccessible(true);
+ return f;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ Field tryGetAccessibleField(Class<?> clazz, String fieldName) {
+ if (clazz == null)
+ return null;
+
+ try {
+ Field f = clazz.getDeclaredField(fieldName);
+ f.setAccessible(true);
+ return f;
+ } catch (Exception e) {
+ for (Class<?> c : clazz.getInterfaces()) {
+ Field f = tryGetAccessibleField(c, fieldName);
+ if (f != null)
+ return f;
+ }
+ }
+ return tryGetAccessibleField(clazz.getSuperclass(), fieldName);
+ }
+
int getField(Class<?> clazz, String fieldName)
{
try {
@@ -619,10 +653,9 @@ public class ExtractStyle {
JSONObject stateJson = new JSONObject();
final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE).invoke(stateList, i);
final int [] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE).invoke(stateList, i);
- if (states == null)
- continue;
- stateJson.put("states", getStatesList(states));
- stateJson.put("drawable", getDrawable(d, filename+"__"+getStatesName(states), null));
+ if (states != null)
+ stateJson.put("states", getStatesList(states));
+ stateJson.put("drawable", getDrawable(d, filename+"__" + (states != null ? getStatesName(states) : ("state_pos_" + i)), null));
array.put(stateJson);
}
json.put("type", "stateslist");
@@ -647,7 +680,8 @@ public class ExtractStyle {
GradientDrawable.Orientation orientation=(Orientation) gradientStateClass.getField("mOrientation").get(obj);
json.put("orientation",orientation.name());
int [] intArray=(int[]) gradientStateClass.getField("mColors").get(obj);
- json.put("colors",getJsonArray(intArray, 0, intArray.length));
+ if (intArray != null)
+ json.put("colors",getJsonArray(intArray, 0, intArray.length));
json.put("positions",getJsonArray((float[]) gradientStateClass.getField("mPositions").get(obj)));
json.put("strokeWidth",gradientStateClass.getField("mStrokeWidth").getInt(obj));
json.put("strokeDashWidth",gradientStateClass.getField("mStrokeDashWidth").getFloat(obj));
@@ -681,27 +715,13 @@ public class ExtractStyle {
json.put("type", "rotate");
Object obj = drawable.getConstantState();
Class<?> rotateStateClass = obj.getClass();
- Field f = rotateStateClass.getDeclaredField("mDrawable");
- f.setAccessible(true);
- json.put("drawable", getDrawable(f.get(obj), filename, null));
- f = rotateStateClass.getDeclaredField("mPivotX");
- f.setAccessible(true);
- json.put("pivotX", f.getFloat(obj));
- f = rotateStateClass.getDeclaredField("mPivotXRel");
- f.setAccessible(true);
- json.put("pivotXRel", f.getBoolean(obj));
- f = rotateStateClass.getDeclaredField("mPivotY");
- f.setAccessible(true);
- json.put("pivotY", f.getFloat(obj));
- f = rotateStateClass.getDeclaredField("mPivotYRel");
- f.setAccessible(true);
- json.put("pivotYRel", f.getBoolean(obj));
- f = rotateStateClass.getDeclaredField("mFromDegrees");
- f.setAccessible(true);
- json.put("fromDegrees", f.getFloat(obj));
- f = rotateStateClass.getDeclaredField("mToDegrees");
- f.setAccessible(true);
- json.put("toDegrees", f.getFloat(obj));
+ json.put("drawable", getDrawable(getAccessibleField(rotateStateClass, "mDrawable").get(obj), filename, null));
+ json.put("pivotX", getAccessibleField(rotateStateClass, "mPivotX").getFloat(obj));
+ json.put("pivotXRel", getAccessibleField(rotateStateClass, "mPivotXRel").getBoolean(obj));
+ json.put("pivotY", getAccessibleField(rotateStateClass, "mPivotY").getFloat(obj));
+ json.put("pivotYRel", getAccessibleField(rotateStateClass, "mPivotYRel").getBoolean(obj));
+ json.put("fromDegrees", getAccessibleField(rotateStateClass, "mFromDegrees").getFloat(obj));
+ json.put("toDegrees", getAccessibleField(rotateStateClass, "mToDegrees").getFloat(obj));
} catch (Exception e) {
e.printStackTrace();
}
@@ -772,22 +792,14 @@ public class ExtractStyle {
private JSONObject findPatchesMarings(Drawable d) throws JSONException, NoSuchFieldException, IllegalAccessException
{
- Field mNinePatch = ((NinePatchDrawable)d).getClass().getDeclaredField("mNinePatch");
- mNinePatch.setAccessible(true);
- NinePatch np = (NinePatch) mNinePatch.get(d);
+ NinePatch np = (NinePatch) getAccessibleField(NinePatchDrawable.class, "mNinePatch").get(d);
if (Build.VERSION.SDK_INT < 19)
- {
- Field mChunk = np.getClass().getDeclaredField("mChunk");
- mChunk.setAccessible(true);
- return getJsonChunkInfo(extractChunkInfo((byte[]) mChunk.get(np)));
- }
+ return getJsonChunkInfo(extractChunkInfo((byte[]) getAccessibleField(np.getClass(), "mChunk").get(np)));
else
{
- Field mNativeChunk = np.getClass().getDeclaredField("mNativeChunk");
- mNativeChunk.setAccessible(true);
if (Build.VERSION.SDK_INT > 19)
- return getJsonChunkInfo(extractNativeChunkInfo20(mNativeChunk.getLong(np)));
- return getJsonChunkInfo(extractNativeChunkInfo(mNativeChunk.getInt(np)));
+ return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np)));
+ return getJsonChunkInfo(extractNativeChunkInfo(getAccessibleField(np.getClass(), "mNativeChunk").getInt(np)));
}
}
@@ -803,8 +815,177 @@ public class ExtractStyle {
}
private HashMap<String, DrawableCache> m_drawableCache = new HashMap<String, DrawableCache>();
+ private JSONObject getRippleDrawable(Object drawable, String filename, Rect padding)
+ {
+ JSONObject json = getLayerDrawable(drawable, filename);
+ JSONObject ripple = new JSONObject();
+ try {
+ final Object mState = getAccessibleField(rippleDrawableClass, "mState").get(drawable);
+ ripple.put("mask", getDrawable((Drawable)getAccessibleField(rippleDrawableClass, "mMask").get(drawable), filename, padding));
+ ripple.put("maxRadius", getAccessibleField(mState.getClass(), "mMaxRadius").getInt(mState));
+ ripple.put("color", getColorStateList((ColorStateList)getAccessibleField(mState.getClass(), "mColor").get(mState)));
+ json.put("ripple", ripple);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private HashMap<Long, Long> getStateTransitions(Object sa) throws Exception
+ {
+ HashMap<Long, Long> transitions = new HashMap<Long, Long>();
+ final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa);
+ long[] keys = (long[]) getAccessibleField(sa.getClass(), "mKeys").get(sa);
+ long[] values = (long[]) getAccessibleField(sa.getClass(), "mValues").get(sa);
+ for (int i = 0; i < sz; i++) {
+ transitions.put(keys[i], values[i]);
+ }
+ return transitions;
+ }
+
+ private HashMap<Integer, Integer> getStateIds(Object sa) throws Exception
+ {
+ HashMap<Integer, Integer> states = new HashMap<Integer, Integer>();
+ final int sz = getAccessibleField(sa.getClass(), "mSize").getInt(sa);
+ int[] keys = (int[]) getAccessibleField(sa.getClass(), "mKeys").get(sa);
+ int[] values = (int[]) getAccessibleField(sa.getClass(), "mValues").get(sa);
+ for (int i = 0; i < sz; i++) {
+ states.put(keys[i], values[i]);
+ }
+ return states;
+ }
+
+ private int findStateIndex(int id, HashMap<Integer, Integer> stateIds)
+ {
+ for (Map.Entry<Integer, Integer> s : stateIds.entrySet()) {
+ if (id == s.getValue())
+ return s.getKey();
+ }
+ return -1;
+ }
+
+ private JSONObject getAnimatedStateListDrawable(Object drawable, String filename)
+ {
+ JSONObject json = getStateListDrawable(drawable, filename);
+ try {
+ Object state = getAccessibleField(animatedStateListDrawableClass, "mState").get(drawable);
+
+ HashMap<Integer, Integer> stateIds = getStateIds(getAccessibleField(state.getClass(), "mStateIds").get(state));
+ HashMap<Long, Long> transitions = getStateTransitions(getAccessibleField(state.getClass(), "mTransitions").get(state));
+
+ for (Map.Entry<Long, Long> t : transitions.entrySet()) {
+ final int toState = findStateIndex(t.getKey().intValue(), stateIds);
+ final int fromState = findStateIndex((int) (t.getKey() >> 32), stateIds);
+
+ JSONObject transition = new JSONObject();
+ transition.put("from", fromState);
+ transition.put("to", toState);
+ transition.put("reverse", (t.getValue() >> 32) != 0);
+
+ JSONArray stateslist = json.getJSONArray("stateslist");
+ JSONObject stateobj = stateslist.getJSONObject(t.getValue().intValue());
+ stateobj.put("transition", transition);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
+ private JSONObject getVPath(Object path) throws Exception
+ {
+ JSONObject json = new JSONObject();
+ final Class<?> pathClass = path.getClass();
+ json.put("type", "path");
+ json.put("name", tryGetAccessibleField(pathClass, "mPathName").get(path));
+ Object[] mNodes = (Object[]) tryGetAccessibleField(pathClass, "mNodes").get(path);
+ JSONArray nodes = new JSONArray();
+ for (Object n: mNodes) {
+ JSONObject node = new JSONObject();
+ node.put("type", String.valueOf(getAccessibleField(n.getClass(), "mType").getChar(n)));
+ node.put("params", getJsonArray((float[])getAccessibleField(n.getClass(), "mParams").get(n)));
+ nodes.put(node);
+ }
+ json.put("nodes", nodes);
+ json.put("isClip", (Boolean) pathClass.getMethod("isClipPath").invoke(path));
+
+ if (tryGetAccessibleField(pathClass, "mStrokeColor") == null)
+ return json; // not VFullPath
+
+ json.put("strokeColor", getAccessibleField(pathClass, "mStrokeColor").getInt(path));
+ json.put("strokeWidth", getAccessibleField(pathClass, "mStrokeWidth").getFloat(path));
+ json.put("fillColor", getAccessibleField(pathClass, "mFillColor").getInt(path));
+ json.put("strokeAlpha", getAccessibleField(pathClass, "mStrokeAlpha").getFloat(path));
+ json.put("fillRule", getAccessibleField(pathClass, "mFillRule").getInt(path));
+ json.put("fillAlpha", getAccessibleField(pathClass, "mFillAlpha").getFloat(path));
+ json.put("trimPathStart", getAccessibleField(pathClass, "mTrimPathStart").getFloat(path));
+ json.put("trimPathEnd", getAccessibleField(pathClass, "mTrimPathEnd").getFloat(path));
+ json.put("trimPathOffset", getAccessibleField(pathClass, "mTrimPathOffset").getFloat(path));
+ json.put("strokeLineCap", (Paint.Cap) getAccessibleField(pathClass, "mStrokeLineCap").get(path));
+ json.put("strokeLineJoin", (Paint.Join) getAccessibleField(pathClass, "mStrokeLineJoin").get(path));
+ json.put("strokeMiterlimit", getAccessibleField(pathClass, "mStrokeMiterlimit").getFloat(path));
+ return json;
+ }
+
+ @SuppressWarnings("unchecked")
+ private JSONObject getVGroup(Object group) throws Exception
+ {
+ JSONObject json = new JSONObject();
+ json.put("type", "group");
+ final Class<?> groupClass = group.getClass();
+ json.put("name", getAccessibleField(groupClass, "mGroupName").get(group));
+ json.put("rotate", getAccessibleField(groupClass, "mRotate").getFloat(group));
+ json.put("pivotX", getAccessibleField(groupClass, "mPivotX").getFloat(group));
+ json.put("pivotY", getAccessibleField(groupClass, "mPivotY").getFloat(group));
+ json.put("scaleX", getAccessibleField(groupClass, "mScaleX").getFloat(group));
+ json.put("scaleY", getAccessibleField(groupClass, "mScaleY").getFloat(group));
+ json.put("translateX", getAccessibleField(groupClass, "mTranslateX").getFloat(group));
+ json.put("translateY", getAccessibleField(groupClass, "mTranslateY").getFloat(group));
+
+ ArrayList<Object> mChildren = (ArrayList<Object>) getAccessibleField(groupClass, "mChildren").get(group);
+ JSONArray children = new JSONArray();
+ for (Object c: mChildren) {
+ if (groupClass.isInstance(c))
+ children.put(getVGroup(c));
+ else
+ children.put(getVPath(c));
+ }
+ json.put("children", children);
+ return json;
+ }
+
+ private JSONObject getVectorDrawable(Object drawable, String filename, Rect padding)
+ {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("type", "vector");
+ final Object state = getAccessibleField(vectorDrawableClass, "mVectorState").get(drawable);
+ final Class<?> stateClass = state.getClass();
+ final ColorStateList mTint = (ColorStateList) getAccessibleField(stateClass, "mTint").get(state);
+ if (mTint != null) {
+ json.put("tintList", getColorStateList(mTint));
+ json.put("tintMode", (PorterDuff.Mode) getAccessibleField(stateClass, "mTintMode").get(state));
+ }
+ final Object mVPathRenderer = getAccessibleField(stateClass, "mVPathRenderer").get(state);
+ final Class<?> VPathRendererClass = mVPathRenderer.getClass();
+ json.put("baseWidth", getAccessibleField(VPathRendererClass, "mBaseWidth").getFloat(mVPathRenderer));
+ json.put("baseHeight", getAccessibleField(VPathRendererClass, "mBaseHeight").getFloat(mVPathRenderer));
+ json.put("viewportWidth", getAccessibleField(VPathRendererClass, "mViewportWidth").getFloat(mVPathRenderer));
+ json.put("viewportHeight", getAccessibleField(VPathRendererClass, "mViewportHeight").getFloat(mVPathRenderer));
+ json.put("rootAlpha", getAccessibleField(VPathRendererClass, "mRootAlpha").getInt(mVPathRenderer));
+ json.put("rootName", getAccessibleField(VPathRendererClass, "mRootName").get(mVPathRenderer));
+ json.put("rootGroup", getVGroup(getAccessibleField(mVPathRenderer.getClass(), "mRootGroup").get(mVPathRenderer)));
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ return json;
+ }
+
public JSONObject getDrawable(Object drawable, String filename, Rect padding)
{
+ if (drawable == null)
+ return null;
+
DrawableCache dc = m_drawableCache.get(filename);
if (dc != null)
{
@@ -819,10 +1000,39 @@ public class ExtractStyle {
bmp = (Bitmap) drawable;
else
{
- if (drawable instanceof BitmapDrawable)
- bmp = ((BitmapDrawable)drawable).getBitmap();
+ if (drawable instanceof BitmapDrawable) {
+ BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable;
+ bmp = bitmapDrawable.getBitmap();
+ try {
+ json.put("gravity", bitmapDrawable.getGravity());
+ json.put("tileModeX", bitmapDrawable.getTileModeX());
+ json.put("tileModeY", bitmapDrawable.getTileModeY());
+ if (Build.VERSION.SDK_INT >= 18) {
+ json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable));
+ json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable));
+ }
+ if (Build.VERSION.SDK_INT >= 21) {
+ json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable));
+ ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable);
+ if (tintList != null)
+ json.put("tintList", getColorStateList(tintList));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
else
{
+
+ if (rippleDrawableClass != null && rippleDrawableClass.isInstance(drawable))
+ return getRippleDrawable(drawable, filename, padding);
+
+ if (animatedStateListDrawableClass != null && animatedStateListDrawableClass.isInstance(drawable))
+ return getAnimatedStateListDrawable(drawable, filename);
+
+ if (vectorDrawableClass != null && vectorDrawableClass.isInstance(drawable))
+ return getVectorDrawable(drawable, filename, padding);
+
if (drawable instanceof ScaleDrawable)
{
return getDrawable(((ScaleDrawable)drawable).getDrawable(), filename, null);
@@ -852,9 +1062,7 @@ public class ExtractStyle {
try {
json.put("type", "clipDrawable");
Drawable.ConstantState dcs = ((ClipDrawable)drawable).getConstantState();
- Field f = dcs.getClass().getDeclaredField("mDrawable");
- f.setAccessible(true);
- json.put("drawable", getDrawable(f.get(dcs), filename, null));
+ json.put("drawable", getDrawable(getAccessibleField(dcs.getClass(), "mDrawable").get(dcs), filename, null));
if (null != padding)
json.put("padding", getJsonRect(padding));
else {
@@ -892,14 +1100,10 @@ public class ExtractStyle {
{
try {
InsetDrawable d = (InsetDrawable)drawable;
- Field mInsetState = d.getClass().getDeclaredField("mInsetState");
- mInsetState.setAccessible(true);
- Object mInsetStateObject = mInsetState.get(drawable);
- Field mDrawable = mInsetStateObject.getClass().getDeclaredField("mDrawable");
- mDrawable.setAccessible(true);
+ Object mInsetStateObject = getAccessibleField(InsetDrawable.class, "mInsetState").get(d);
Rect _padding = new Rect();
boolean hasPadding = d.getPadding(_padding);
- return getDrawable(mDrawable.get(mInsetStateObject), filename, hasPadding ? _padding : null);
+ return getDrawable(getAccessibleField(mInsetStateObject.getClass(), "mDrawable").get(mInsetStateObject), filename, hasPadding ? _padding : null);
} catch (Exception e) {
e.printStackTrace();
}
@@ -1210,9 +1414,17 @@ public class ExtractStyle {
json.put("TextView_drawableEnd", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableEnd", null));
else if (attr == TextView_drawablePadding)
json.put("TextView_drawablePadding", a.getDimensionPixelSize(attr, 0));
- else if (attr == TextView_textCursorDrawable)
- json.put("TextView_textCursorDrawable", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textCursorDrawable", null));
- else if (attr == TextView_maxLines)
+ else if (attr == TextView_textCursorDrawable) {
+ try {
+ json.put("TextView_textCursorDrawable", getDrawable(a.getDrawable(attr), styleName + "_TextView_textCursorDrawable", null));
+ } catch (Exception e_) {
+ try {
+ json.put("TextView_textCursorDrawable", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textCursorDrawable", null));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }else if (attr == TextView_maxLines)
json.put("TextView_maxLines", a.getInt(attr, -1));
else if (attr == TextView_maxHeight)
json.put("TextView_maxHeight", a.getDimensionPixelSize(attr, -1));
@@ -1300,13 +1512,37 @@ public class ExtractStyle {
json.put("TextView_imeActionId", a.getInt(attr,0));
else if (attr == TextView_privateImeOptions)
json.put("TextView_privateImeOptions", a.getString(attr));
- else if (attr == TextView_textSelectHandleLeft && styleName.equals("textViewStyle"))
- json.put("TextView_textSelectHandleLeft", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleLeft", null));
- else if (attr == TextView_textSelectHandleRight && styleName.equals("textViewStyle"))
- json.put("TextView_textSelectHandleRight", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleRight", null));
- else if (attr == TextView_textSelectHandle && styleName.equals("textViewStyle"))
- json.put("TextView_textSelectHandle", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandle", null));
- else if (attr == TextView_textIsSelectable)
+ else if (attr == TextView_textSelectHandleLeft && styleName.equals("textViewStyle")) {
+ try {
+ json.put("TextView_textSelectHandleLeft", getDrawable(a.getDrawable(attr), styleName + "_TextView_textSelectHandleLeft", null));
+ } catch (Exception _e) {
+ try {
+ json.put("TextView_textSelectHandleLeft", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleLeft", null));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } else if (attr == TextView_textSelectHandleRight && styleName.equals("textViewStyle")) {
+ try {
+ json.put("TextView_textSelectHandleRight", getDrawable(a.getDrawable(attr), styleName + "_TextView_textSelectHandleRight", null));
+ } catch (Exception _e) {
+ try {
+ json.put("TextView_textSelectHandleRight", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandleRight", null));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } else if (attr == TextView_textSelectHandle && styleName.equals("textViewStyle")) {
+ try {
+ json.put("TextView_textSelectHandle", getDrawable(a.getDrawable(attr), styleName + "_TextView_textSelectHandle", null));
+ } catch (Exception _e) {
+ try {
+ json.put("TextView_textSelectHandle", getDrawable(m_context.getResources().getDrawable(a.getResourceId(attr, 0)), styleName + "_TextView_textSelectHandle", null));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } else if (attr == TextView_textIsSelectable)
json.put("TextView_textIsSelectable", a.getBoolean(attr, false));
else if (attr == TextView_textAllCaps)
allCaps = a.getBoolean(attr, false);
@@ -1511,6 +1747,11 @@ public class ExtractStyle {
json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0));
json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0));
+ if (Build.VERSION.SDK_INT >= 21) {
+ json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true));
+ json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false));
+ }
+
a.recycle();
jsonWriter.name(styleName).value(json);
} catch (Exception e) {
@@ -1729,6 +1970,23 @@ public class ExtractStyle {
}
}
+ private JSONObject extractDefaultPalette()
+ {
+ TypedArray array = m_theme.obtainStyledAttributes(new int[]{
+ android.R.attr.textAppearance
+ });
+ int pos = 0;
+ JSONObject json = extractTextAppearance(array.getResourceId(pos++, -1));
+ try {
+ json.put("defaultBackgroundColor", defaultBackgroundColor);
+ json.put("defaultTextColorPrimary", defaultTextColor);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ array.recycle();
+ return json;
+ }
+
public ExtractStyle(Context context, String extractPath)
{
// Log.i(MinistroService.TAG, "Extract " + extractPath);
@@ -1740,9 +1998,13 @@ public class ExtractStyle {
TypedArray array = m_theme.obtainStyledAttributes(new int[]{
android.R.attr.colorBackground,
android.R.attr.textColorPrimary,
+ android.R.attr.textColor
});
defaultBackgroundColor = array.getColor(0, 0);
- defaultTextColor = array.getColor(1, 0xFFFFFF);
+ int textColor = array.getColor(1, 0xFFFFFF);
+ if (textColor == 0xFFFFFF)
+ textColor = array.getColor(2, 0xFFFFFF);
+ defaultTextColor = textColor;
array.recycle();
try
@@ -1750,6 +2012,7 @@ public class ExtractStyle {
SimpleJsonWriter jsonWriter = new SimpleJsonWriter(m_extractPath+"style.json");
jsonWriter.beginObject();
try {
+ jsonWriter.name("defaultStyle").value(extractDefaultPalette());
extractWindow(jsonWriter, "windowStyle");
jsonWriter.name("buttonStyle").value(extractTextAppearanceInformations("buttonStyle", "QPushButton", null, -1));
jsonWriter.name("spinnerStyle").value(extractTextAppearanceInformations("spinnerStyle", "QComboBox", null, -1));
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 7642bc38b5..f44465b4c5 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -50,6 +50,8 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable;
+import android.net.LocalServerSocket;
+import android.net.LocalSocket;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -72,8 +74,11 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
+import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -265,30 +270,31 @@ public class QtActivityDelegate
}
if (Build.VERSION.SDK_INT > 10 && (inputHints & ImhHiddenText) != 0)
- inputType |= 0x10;
+ inputType |= 0x10 /* TYPE_NUMBER_VARIATION_PASSWORD */;
} else if ((inputHints & ImhDialableCharactersOnly) != 0) {
inputType = android.text.InputType.TYPE_CLASS_PHONE;
} else if ((inputHints & (ImhDate | ImhTime)) != 0) {
inputType = android.text.InputType.TYPE_CLASS_DATETIME;
- if ((inputHints & ImhDate) != 0)
- inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE;
- if ((inputHints & ImhTime) != 0)
- inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME;
+ if ((inputHints & (ImhDate | ImhTime)) != (ImhDate | ImhTime)) {
+ if ((inputHints & ImhDate) != 0)
+ inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE;
+ if ((inputHints & ImhTime) != 0)
+ inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME;
+ } // else { TYPE_DATETIME_VARIATION_NORMAL(0) }
} else { // CLASS_TEXT
- if ((inputHints & ImhHiddenText) != 0) {
+ if ((inputHints & (ImhEmailCharactersOnly | ImhUrlCharactersOnly)) != 0) {
+ if ((inputHints & ImhUrlCharactersOnly) != 0) {
+ inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
+ } else if ((inputHints & ImhEmailCharactersOnly) != 0) {
+ inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+ }
+ } else if ((inputHints & ImhHiddenText) != 0) {
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
- } else if ((inputHints & (ImhNoAutoUppercase | ImhNoPredictiveText | ImhSensitiveData)) != 0) {
+ } else if ((inputHints & ImhSensitiveData) != 0) {
inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
}
- if ((inputHints & ImhEmailCharactersOnly) != 0)
- inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-
- if ((inputHints & ImhUrlCharactersOnly) != 0) {
- inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
- imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
- }
-
if ((inputHints & ImhMultiLine) != 0)
inputType |= android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
@@ -300,8 +306,10 @@ public class QtActivityDelegate
inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
}
- if ((inputHints & ImhNoPredictiveText) != 0 || (inputHints & ImhSensitiveData) != 0)
+ if ((inputHints & ImhNoPredictiveText) != 0 || (inputHints & ImhSensitiveData) != 0
+ || (inputHints & ImhHiddenText) != 0) {
inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
+ }
}
if ((inputHints & ImhMultiLine) != 0)
@@ -485,6 +493,59 @@ public class QtActivityDelegate
Log.i(QtNative.QtTAG, "DEBUGGER: " + msg);
}
+ private class DebugWaitRunnable implements Runnable {
+
+ public DebugWaitRunnable(String pingPongSocket) throws IOException {
+ socket = new LocalServerSocket(pingPongSocket);
+ }
+
+ public boolean wasFailure;
+ private LocalServerSocket socket;
+
+ public void run() {
+ final int napTime = 200; // milliseconds between file accesses
+ final int timeOut = 30000; // ms until we give up on ping and pong
+ final int maxAttempts = timeOut / napTime;
+
+ try {
+ LocalSocket connectionFromClient = socket.accept();
+ debugLog("Debug socket accepted");
+ BufferedReader inFromClient =
+ new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream()));
+ DataOutputStream outToClient = new DataOutputStream(connectionFromClient.getOutputStream());
+ outToClient.writeBytes("" + android.os.Process.myPid());
+
+ for (int i = 0; i < maxAttempts; i++) {
+ String clientData = inFromClient.readLine();
+ debugLog("Incoming socket " + clientData);
+ if (!clientData.isEmpty())
+ break;
+
+ if (connectionFromClient.isClosed()) {
+ wasFailure = true;
+ break;
+ }
+ Thread.sleep(napTime);
+ }
+ } catch (IOException ioEx) {
+ ioEx.printStackTrace();
+ wasFailure = true;
+ Log.e(QtNative.QtTAG,"Can't start debugger" + ioEx.getMessage());
+ } catch (InterruptedException interruptEx) {
+ wasFailure = true;
+ Log.e(QtNative.QtTAG,"Can't start debugger" + interruptEx.getMessage());
+ }
+ }
+
+ public void shutdown() throws IOException
+ {
+ wasFailure = true;
+ try {
+ socket.close();
+ } catch (IOException ignored) { }
+ }
+ };
+
public boolean startApplication()
{
// start application
@@ -492,190 +553,218 @@ public class QtActivityDelegate
// FIXME turn on debuggable check
// if the applications is debuggable and it has a native debug request
Bundle extras = m_activity.getIntent().getExtras();
- if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
- &&*/ extras != null
- && extras.containsKey("native_debug")
- && extras.getString("native_debug").equals("true")) {
- try {
- String packagePath =
- m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
- PackageManager.GET_CONFIGURATIONS).dataDir + "/";
- String gdbserverPath =
- extras.containsKey("gdbserver_path")
- ? extras.getString("gdbserver_path")
- : packagePath+"lib/gdbserver ";
-
- String socket =
- extras.containsKey("gdbserver_socket")
- ? extras.getString("gdbserver_socket")
- : "+debug-socket";
-
- if (!(new File(gdbserverPath)).exists())
- gdbserverPath += ".so";
-
- // start debugger
- m_debuggerProcess = Runtime.getRuntime().exec(gdbserverPath
- + socket
- + " --attach "
- + android.os.Process.myPid(),
- null,
- new File(packagePath));
- } catch (IOException ioe) {
- Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage());
- } catch (SecurityException se) {
- Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage());
- } catch (NameNotFoundException e) {
- Log.e(QtNative.QtTAG,"Can't start debugger" + e.getMessage());
+ if (extras != null) {
+
+ if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
+ &&*/ extras.containsKey("native_debug")
+ && extras.getString("native_debug").equals("true")) {
+ try {
+ String packagePath =
+ m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
+ PackageManager.GET_CONFIGURATIONS).dataDir + "/";
+ String gdbserverPath =
+ extras.containsKey("gdbserver_path")
+ ? extras.getString("gdbserver_path")
+ : packagePath+"lib/gdbserver ";
+
+ String socket =
+ extras.containsKey("gdbserver_socket")
+ ? extras.getString("gdbserver_socket")
+ : "+debug-socket";
+
+ if (!(new File(gdbserverPath)).exists())
+ gdbserverPath += ".so";
+
+ // start debugger
+ m_debuggerProcess = Runtime.getRuntime().exec(gdbserverPath
+ + socket
+ + " --attach "
+ + android.os.Process.myPid(),
+ null,
+ new File(packagePath));
+ } catch (IOException ioe) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage());
+ } catch (SecurityException se) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage());
+ } catch (NameNotFoundException e) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + e.getMessage());
+ }
}
- }
- if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
- &&*/ extras != null
- && extras.containsKey("debug_ping")
- && extras.getString("debug_ping").equals("true")) {
- try {
- debugLog("extra parameters: " + extras);
- String packageName = m_activity.getPackageName();
- String pingFile = extras.getString("ping_file");
- String pongFile = extras.getString("pong_file");
- String gdbserverSocket = extras.getString("gdbserver_socket");
- String gdbserverCommand = extras.getString("gdbserver_command");
- boolean usePing = pingFile != null;
- boolean usePong = pongFile != null;
- boolean useSocket = gdbserverSocket != null;
- int napTime = 200; // milliseconds between file accesses
- int timeOut = 30000; // ms until we give up on ping and pong
- int maxAttempts = timeOut / napTime;
-
- if (gdbserverSocket != null) {
- debugLog("removing gdb socket " + gdbserverSocket);
- new File(gdbserverSocket).delete();
- }
-
- if (usePing) {
- debugLog("removing ping file " + pingFile);
- File ping = new File(pingFile);
- if (ping.exists()) {
- if (!ping.delete())
- debugLog("ping file cannot be deleted");
+ if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
+ &&*/ extras.containsKey("debug_ping")
+ && extras.getString("debug_ping").equals("true")) {
+ try {
+ debugLog("extra parameters: " + extras);
+ String packageName = m_activity.getPackageName();
+ String pingFile = extras.getString("ping_file");
+ String pongFile = extras.getString("pong_file");
+ String gdbserverSocket = extras.getString("gdbserver_socket");
+ String gdbserverCommand = extras.getString("gdbserver_command");
+ String pingSocket = extras.getString("ping_socket");
+ boolean usePing = pingFile != null;
+ boolean usePong = pongFile != null;
+ boolean useSocket = gdbserverSocket != null;
+ boolean usePingSocket = pingSocket != null;
+ int napTime = 200; // milliseconds between file accesses
+ int timeOut = 30000; // ms until we give up on ping and pong
+ int maxAttempts = timeOut / napTime;
+
+ if (gdbserverSocket != null) {
+ debugLog("removing gdb socket " + gdbserverSocket);
+ new File(gdbserverSocket).delete();
}
- }
- if (usePong) {
- debugLog("removing pong file " + pongFile);
- File pong = new File(pongFile);
- if (pong.exists()) {
- if (!pong.delete())
- debugLog("pong file cannot be deleted");
+ if (usePing) {
+ debugLog("removing ping file " + pingFile);
+ File ping = new File(pingFile);
+ if (ping.exists()) {
+ if (!ping.delete())
+ debugLog("ping file cannot be deleted");
+ }
}
- }
- debugLog("starting " + gdbserverCommand);
- m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
- debugLog("gdbserver started");
-
- if (useSocket) {
- int i;
- for (i = 0; i < maxAttempts; ++i) {
- debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
- File file = new File(gdbserverSocket);
- if (file.exists()) {
- file.setReadable(true, false);
- file.setWritable(true, false);
- file.setExecutable(true, false);
- break;
+ if (usePong) {
+ debugLog("removing pong file " + pongFile);
+ File pong = new File(pongFile);
+ if (pong.exists()) {
+ if (!pong.delete())
+ debugLog("pong file cannot be deleted");
}
- Thread.sleep(napTime);
}
- if (i == maxAttempts) {
- debugLog("time out when waiting for socket");
- return false;
+ debugLog("starting " + gdbserverCommand);
+ m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
+ debugLog("gdbserver started");
+
+ if (useSocket) {
+ int i;
+ for (i = 0; i < maxAttempts; ++i) {
+ debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
+ File file = new File(gdbserverSocket);
+ if (file.exists()) {
+ file.setReadable(true, false);
+ file.setWritable(true, false);
+ file.setExecutable(true, false);
+ break;
+ }
+ Thread.sleep(napTime);
+ }
+
+ if (i == maxAttempts) {
+ debugLog("time out when waiting for debug socket");
+ return false;
+ }
+
+ debugLog("socket ok");
+ } else {
+ debugLog("socket not used");
}
- debugLog("socket ok");
- } else {
- debugLog("socket not used");
- }
+ if (usePingSocket) {
+ DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
+ Thread waitThread = new Thread(runnable);
+ waitThread.start();
- if (usePing) {
- // Tell we are ready.
- debugLog("writing ping at " + pingFile);
- FileWriter writer = new FileWriter(pingFile);
- writer.write("" + android.os.Process.myPid());
- writer.close();
- File file = new File(pingFile);
- file.setReadable(true, false);
- file.setWritable(true, false);
- file.setExecutable(true, false);
- debugLog("wrote ping");
- } else {
- debugLog("ping not requested");
- }
+ int i;
+ for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
+ debugLog("Waiting for debug socket connect");
+ debugLog("go to sleep");
+ Thread.sleep(napTime);
+ }
- // Wait until other side is ready.
- if (usePong) {
- int i;
- for (i = 0; i < maxAttempts; ++i) {
- debugLog("waiting for pong at " + pongFile + ", attempt " + i);
- File file = new File(pongFile);
- if (file.exists()) {
- file.delete();
- break;
+ if (i == maxAttempts) {
+ debugLog("time out when waiting for ping socket");
+ runnable.shutdown();
+ return false;
+ }
+
+ if (runnable.wasFailure) {
+ debugLog("Could not connect to debug client");
+ return false;
+ } else {
+ debugLog("Got pid acknowledgment");
}
- debugLog("go to sleep");
- Thread.sleep(napTime);
}
- debugLog("Removing pingFile " + pingFile);
- new File(pingFile).delete();
- if (i == maxAttempts) {
- debugLog("time out when waiting for pong file");
- return false;
+ if (usePing) {
+ // Tell we are ready.
+ debugLog("writing ping at " + pingFile);
+ FileWriter writer = new FileWriter(pingFile);
+ writer.write("" + android.os.Process.myPid());
+ writer.close();
+ File file = new File(pingFile);
+ file.setReadable(true, false);
+ file.setWritable(true, false);
+ file.setExecutable(true, false);
+ debugLog("wrote ping");
+ } else {
+ debugLog("ping not requested");
}
- debugLog("got pong " + pongFile);
- } else {
- debugLog("pong not requested");
- }
+ // Wait until other side is ready.
+ if (usePong) {
+ int i;
+ for (i = 0; i < maxAttempts; ++i) {
+ debugLog("waiting for pong at " + pongFile + ", attempt " + i);
+ File file = new File(pongFile);
+ if (file.exists()) {
+ file.delete();
+ break;
+ }
+ debugLog("go to sleep");
+ Thread.sleep(napTime);
+ }
+ debugLog("Removing pingFile " + pingFile);
+ new File(pingFile).delete();
+
+ if (i == maxAttempts) {
+ debugLog("time out when waiting for pong file");
+ return false;
+ }
- } catch (IOException ioe) {
- Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage());
- } catch (SecurityException se) {
- Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage());
+ debugLog("got pong " + pongFile);
+ } else {
+ debugLog("pong not requested");
+ }
+
+ } catch (IOException ioe) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage());
+ } catch (SecurityException se) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage());
+ }
}
- }
- if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
- &&*/ extras != null
- && extras.containsKey("qml_debug")
- && extras.getString("qml_debug").equals("true")) {
- String qmljsdebugger;
- if (extras.containsKey("qmljsdebugger")) {
- qmljsdebugger = extras.getString("qmljsdebugger");
- qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
- } else {
- qmljsdebugger = "port:3768";
+ if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
+ &&*/ extras.containsKey("qml_debug")
+ && extras.getString("qml_debug").equals("true")) {
+ String qmljsdebugger;
+ if (extras.containsKey("qmljsdebugger")) {
+ qmljsdebugger = extras.getString("qmljsdebugger");
+ qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
+ } else {
+ qmljsdebugger = "port:3768";
+ }
+ m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
}
- m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
- }
- if (extras.containsKey("extraenvvars")) {
- try {
- m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
- } catch (Exception e) {
- e.printStackTrace();
+ if (extras.containsKey("extraenvvars")) {
+ try {
+ m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- }
- if (extras.containsKey("extraappparams")) {
- try {
- m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8");
- } catch (Exception e) {
- e.printStackTrace();
+ if (extras.containsKey("extraappparams")) {
+ try {
+ m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- }
+ } // extras != null
if (null == m_surfaces)
onCreate(null);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 51688441e0..0e0072d234 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -191,6 +191,16 @@ public class QtNative
}
}
+ private static void runQtOnUiThread(final long id)
+ {
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ QtNative.onAndroidUiThread(id);
+ }
+ });
+ }
+
public static boolean startApplication(String params,
String environment,
String mainLibrary,
@@ -618,4 +628,6 @@ public class QtNative
// activity methods
public static native void onActivityResult(int requestCode, int resultCode, Intent data);
+
+ public static native void onAndroidUiThread(long id);
}
diff --git a/src/android/templates/templates.pro b/src/android/templates/templates.pro
index 684a556c5b..55387f3af7 100644
--- a/src/android/templates/templates.pro
+++ b/src/android/templates/templates.pro
@@ -2,6 +2,7 @@ CONFIG -= qt android_install
templates.files = \
$$PWD/AndroidManifest.xml \
+ $$PWD/build.gradle \
$$PWD/res
templates.path = $$[QT_INSTALL_PREFIX]/src/android/templates
@@ -17,5 +18,6 @@ INSTALLS += templates
QMAKE_POST_LINK += \
$${QMAKE_COPY} $$shell_path($$PWD/AndroidManifest.xml) $$OUT_PATH $$RETURN \
+ $${QMAKE_COPY} $$shell_path($$PWD/build.gradle) $$OUT_PATH $$RETURN \
$${QMAKE_COPY_DIR} $$shell_path($$PWD/res) $$OUT_PATH
}
diff --git a/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch b/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch
index d5e3697c4f..ad3187ec7c 100644
--- a/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch
+++ b/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch
@@ -1,178 +1,49 @@
-From f409f6837ce80d722eb6d2ff178b61b713d3e8c7 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Thu, 25 Sep 2014 13:23:19 +0300
+From bd27c33a4a7c48bd14b9b6c18c8cdce1c3aae155 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Fri, 14 Nov 2014 10:53:40 +0200
Subject: [PATCH] General fixes for ANGLE 2.1
- Fix commit.h include (use hard-coded version)
-- Fix undefined intptr_t in egl.h and eglext.h
- Fix export mismatch in libEGL.cpp and libGLESv2.cpp
-- Remove D3D9 d3dcompiler.h include requirement in the translator
- Normalize all precompiled shader names and includes
- Remove third-party event tracing; it was hardly used in ANGLE
and not enabled in Qt builds anyway.
Change-Id: I22254aed62e89a26756ca0784bae95909189c0f9
---
- src/3rdparty/angle/include/EGL/egl.h | 2 +-
- src/3rdparty/angle/include/EGL/eglext.h | 2 +-
- src/3rdparty/angle/src/common/event_tracer.cpp | 49 --
- src/3rdparty/angle/src/common/event_tracer.h | 43 --
- src/3rdparty/angle/src/common/version.h | 2 +-
- src/3rdparty/angle/src/libEGL/libEGL.cpp | 3 +
- src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 5 +
- src/3rdparty/angle/src/libGLESv2/libGLESv2.def | 3 -
- .../angle/src/libGLESv2/libGLESv2_mingw32.def | 3 -
- src/3rdparty/angle/src/libGLESv2/libGLESv2d.def | 3 -
- .../angle/src/libGLESv2/libGLESv2d_mingw32.def | 3 -
- .../angle/src/libGLESv2/renderer/Renderer.cpp | 1 -
- .../angle/src/libGLESv2/renderer/SwapChain.h | 4 -
- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 6 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 66 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 12 +-
- .../renderer/d3d/d3d11/PixelTransfer11.cpp | 10 +-
- .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 4 +-
- .../renderer/d3d/d3d11/shaders/Clear11.hlsl | 4 +
- .../src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp | 20 +-
- .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 12 -
- .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps | 6 +-
- .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs | 4 +-
- .../src/third_party/trace_event/trace_event.h | 826 ---------------------
- src/angle/src/common/common.pri | 2 -
- 25 files changed, 80 insertions(+), 1015 deletions(-)
- delete mode 100644 src/3rdparty/angle/src/common/event_tracer.cpp
- delete mode 100644 src/3rdparty/angle/src/common/event_tracer.h
- delete mode 100644 src/3rdparty/angle/src/third_party/trace_event/trace_event.h
+ src/3rdparty/angle/src/commit.h | 6 +-
+ src/3rdparty/angle/src/common/version.h | 2 +-
+ .../src/common/winrt/CoreWindowNativeWindow.cpp | 2 +-
+ src/3rdparty/angle/src/libEGL/libEGL.cpp | 3 +
+ src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 4 ++
+ src/3rdparty/angle/src/libGLESv2/libGLESv2.def | 3 -
+ .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 3 -
+ .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 66 +++++++++++-----------
+ .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 12 ++--
+ .../renderer/d3d/d3d11/PixelTransfer11.cpp | 10 ++--
+ .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 4 +-
+ .../renderer/d3d/d3d11/shaders/Clear11.hlsl | 4 ++
+ .../src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp | 20 +++----
+ .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 12 ----
+ .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps | 6 +-
+ .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs | 4 +-
+ 16 files changed, 76 insertions(+), 85 deletions(-)
-diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h
-index 12590a0..ab2f0cd 100644
---- a/src/3rdparty/angle/include/EGL/egl.h
-+++ b/src/3rdparty/angle/include/EGL/egl.h
-@@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
- #ifndef EGL_VERSION_1_5
- #define EGL_VERSION_1_5 1
- typedef void *EGLSync;
--typedef intptr_t EGLAttrib;
-+typedef khronos_intptr_t EGLAttrib;
- typedef khronos_utime_nanoseconds_t EGLTime;
- #define EGL_CONTEXT_MAJOR_VERSION 0x3098
- #define EGL_CONTEXT_MINOR_VERSION 0x30FB
-diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h
-index 9e29605..989359b 100644
---- a/src/3rdparty/angle/include/EGL/eglext.h
-+++ b/src/3rdparty/angle/include/EGL/eglext.h
-@@ -59,7 +59,7 @@ extern "C" {
- #ifndef EGL_KHR_cl_event2
- #define EGL_KHR_cl_event2 1
- typedef void *EGLSyncKHR;
--typedef intptr_t EGLAttribKHR;
-+typedef khronos_intptr_t EGLAttribKHR;
- typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
- #ifdef EGL_EGLEXT_PROTOTYPES
- EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
-diff --git a/src/3rdparty/angle/src/common/event_tracer.cpp b/src/3rdparty/angle/src/common/event_tracer.cpp
-deleted file mode 100644
-index 353c69d..0000000
---- a/src/3rdparty/angle/src/common/event_tracer.cpp
-+++ /dev/null
-@@ -1,49 +0,0 @@
--// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
--// Use of this source code is governed by a BSD-style license that can be
--// found in the LICENSE file.
--
--#include "common/event_tracer.h"
--
--namespace gl
--{
--
--GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag;
--AddTraceEventFunc g_addTraceEvent;
--
--} // namespace gl
--
--extern "C" {
--
--void TRACE_ENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc getCategoryEnabledFlag,
-- AddTraceEventFunc addTraceEvent)
--{
-- gl::g_getCategoryEnabledFlag = getCategoryEnabledFlag;
-- gl::g_addTraceEvent = addTraceEvent;
--}
--
--} // extern "C"
--
--namespace gl
--{
--
--const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name)
--{
-- if (g_getCategoryEnabledFlag)
-- {
-- return g_getCategoryEnabledFlag(name);
-- }
-- static unsigned char disabled = 0;
-- return &disabled;
--}
--
--void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
-- int numArgs, const char** argNames, const unsigned char* argTypes,
-- const unsigned long long* argValues, unsigned char flags)
--{
-- if (g_addTraceEvent)
-- {
-- g_addTraceEvent(phase, categoryGroupEnabled, name, id, numArgs, argNames, argTypes, argValues, flags);
-- }
--}
--
--} // namespace gl
-diff --git a/src/3rdparty/angle/src/common/event_tracer.h b/src/3rdparty/angle/src/common/event_tracer.h
-deleted file mode 100644
-index fa97435..0000000
---- a/src/3rdparty/angle/src/common/event_tracer.h
-+++ /dev/null
-@@ -1,43 +0,0 @@
--// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
--// Use of this source code is governed by a BSD-style license that can be
--// found in the LICENSE file.
--
--#ifndef COMMON_EVENT_TRACER_H_
--#define COMMON_EVENT_TRACER_H_
--
--#include "common/platform.h"
--
--#if !defined(TRACE_ENTRY)
--# ifdef ANGLE_PLATFORM_WINDOWS
--# define TRACE_ENTRY __stdcall
--# else
--# define TRACE_ENTRY
--# endif // ANGLE_PLATFORM_WINDOWS
--#endif //TRACE_ENTRY
--
--extern "C" {
--
--typedef const unsigned char* (*GetCategoryEnabledFlagFunc)(const char* name);
--typedef void (*AddTraceEventFunc)(char phase, const unsigned char* categoryGroupEnabled, const char* name,
-- unsigned long long id, int numArgs, const char** argNames,
-- const unsigned char* argTypes, const unsigned long long* argValues,
-- unsigned char flags);
--
--// extern "C" so that it has a reasonable name for GetProcAddress.
--void TRACE_ENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc get_category_enabled_flag,
-- AddTraceEventFunc add_trace_event_func);
--
--}
--
--namespace gl
--{
--
--const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name);
--
--void TraceAddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
-- int numArgs, const char** argNames, const unsigned char* argTypes,
-- const unsigned long long* argValues, unsigned char flags);
--
--}
--
--#endif // COMMON_EVENT_TRACER_H_
+diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h
+index 4c89a65..08fc893 100644
+--- a/src/3rdparty/angle/src/commit.h
++++ b/src/3rdparty/angle/src/commit.h
+@@ -7,8 +7,6 @@
+ // This is a default commit hash header, when git is not available.
+ //
+
+-#define ANGLE_COMMIT_HASH "unknown hash"
++#define ANGLE_COMMIT_HASH "30d6c255d238"
+ #define ANGLE_COMMIT_HASH_SIZE 12
+-#define ANGLE_COMMIT_DATE "unknown date"
+-
+-#define ANGLE_DISABLE_PROGRAM_BINARY_LOAD
++#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
diff --git a/src/3rdparty/angle/src/common/version.h b/src/3rdparty/angle/src/common/version.h
index d9148d1..f01e024 100644
--- a/src/3rdparty/angle/src/common/version.h
@@ -183,8 +54,19 @@ index d9148d1..f01e024 100644
#define ANGLE_MAJOR_VERSION 2
#define ANGLE_MINOR_VERSION 1
+diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
+index 0de16f4..0e63fa5 100644
+--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
++++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
+@@ -184,4 +184,4 @@ long ConvertDipsToPixels(float dips)
+ static const float dipsPerInch = 96.0f;
+ return lround((dips * GetLogicalDpi() / dipsPerInch));
+ }
+-}
+\ No newline at end of file
++}
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-index f9a4780..7ce2b93 100644
+index 851b723..6110698 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -6,6 +6,9 @@
@@ -198,7 +80,7 @@ index f9a4780..7ce2b93 100644
#include "common/debug.h"
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
-index 198c0ee..07f5d47 100644
+index 2306168..587950a 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
@@ -6,6 +6,10 @@
@@ -212,14 +94,6 @@ index 198c0ee..07f5d47 100644
#include "common/version.h"
#include "common/utilities.h"
-@@ -30,6 +34,7 @@
- #include "libGLESv2/validationES3.h"
- #include "libGLESv2/queryconversions.h"
-
-+
- extern "C"
- {
-
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
index 88dceb3..33557eb 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
@@ -231,93 +105,29 @@ index 88dceb3..33557eb 100644
-
- ; Setting up TRACE macro callbacks
- SetTraceFunctionPointers @284
-diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
-index d6272c4d..18ffcf6 100644
---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
-+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
-@@ -294,6 +294,3 @@ EXPORTS
- glBindTexImage@4 @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
--
-- ; Setting up TRACE macro callbacks
-- SetTraceFunctionPointers@8 @284
-diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
-index d301aa0..120371e 100644
---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
-+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
-@@ -294,6 +294,3 @@ EXPORTS
- glBindTexImage @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
--
-- ; Setting up TRACE macro callbacks
-- SetTraceFunctionPointers @284
-diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
-index a82d629..8c1306a 100644
---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
-+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
-@@ -294,6 +294,3 @@ EXPORTS
- glBindTexImage@4 @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
--
-- ; Setting up TRACE macro callbacks
-- SetTraceFunctionPointers@8 @284
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
-index df43012..910d028 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
-@@ -10,7 +10,6 @@
- #include "libGLESv2/Program.h"
- #include "libGLESv2/renderer/Renderer.h"
- #include "common/utilities.h"
--#include "third_party/trace_event/trace_event.h"
- #include "libGLESv2/Shader.h"
-
- #if defined (ANGLE_ENABLE_D3D9)
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
-index c53b2af..12be9b3 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
-@@ -16,10 +16,6 @@
- #include <GLES2/gl2.h>
- #include <EGL/egl.h>
-
--#if !defined(ANGLE_FORCE_VSYNC_OFF)
--#define ANGLE_FORCE_VSYNC_OFF 0
--#endif
--
- namespace rx
- {
-
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index df2e46c..acbd852 100644
+index 5c44fe0..bfeaf51 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -10,8 +10,6 @@
-
+@@ -11,8 +11,6 @@
+ #include "common/features.h"
#include "common/utilities.h"
-#include "third_party/trace_event/trace_event.h"
-
- namespace rx
+ // Definitions local to the translation unit
+ namespace
{
-
-@@ -28,7 +26,11 @@ HLSLCompiler::~HLSLCompiler()
+@@ -120,7 +118,6 @@ HLSLCompiler::~HLSLCompiler()
bool HLSLCompiler::initialize()
{
-+<<<<<<< HEAD
- TRACE_EVENT0("gpu", "initializeCompiler");
-+=======
-+#if !defined(ANGLE_PLATFORM_WINRT)
-+>>>>>>> 429814a... ANGLE: remove event tracing
+- TRACE_EVENT0("gpu", "initializeCompiler");
+ #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
// Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
- static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-index 3bdb9e7..72820a4 100644
+index 8ed1650..91e7552 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
@@ -13,39 +13,39 @@
@@ -394,7 +204,7 @@ index 3bdb9e7..72820a4 100644
#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-index c60b7a6..5caa427 100644
+index 12905d0..4630762 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -15,14 +15,14 @@
@@ -419,7 +229,7 @@ index c60b7a6..5caa427 100644
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-index f54bacc..edaafec 100644
+index 1bc2bd8..a4072d8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -22,11 +22,11 @@
@@ -440,7 +250,7 @@ index f54bacc..edaafec 100644
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-index 5ec132e..50dae4e 100644
+index 3fcacf6..834b7bd 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
@@ -12,8 +12,8 @@
@@ -452,8 +262,8 @@ index 5ec132e..50dae4e 100644
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
- namespace rx
- {
+ #include "common/features.h"
+ #include "common/NativeWindow.h"
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
index 6deef2b..b4cf380 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
@@ -485,7 +295,7 @@ index 6deef2b..b4cf380 100644
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
-index 80503d5..f061a32 100644
+index d4fcd17..2ca7a9c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
@@ -27,20 +27,20 @@ namespace
@@ -520,11 +330,11 @@ index 80503d5..f061a32 100644
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index 73c1abc..e8564bd 100644
+index 3bac4ba..82963ec 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -39,8 +39,6 @@
-
+@@ -42,8 +42,6 @@
+ #include "common/features.h"
#include "common/utilities.h"
-#include "third_party/trace_event/trace_event.h"
@@ -532,7 +342,7 @@ index 73c1abc..e8564bd 100644
#include <sstream>
// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
-@@ -190,7 +188,6 @@ EGLint Renderer9::initialize()
+@@ -185,7 +183,6 @@ EGLint Renderer9::initialize()
return EGL_NOT_INITIALIZED;
}
@@ -540,9 +350,9 @@ index 73c1abc..e8564bd 100644
mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
if (mD3d9Module == NULL)
-@@ -207,14 +204,12 @@ EGLint Renderer9::initialize()
+@@ -202,14 +199,12 @@ EGLint Renderer9::initialize()
// desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
- if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
+ if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
{
- TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface");
ASSERT(mD3d9Ex);
@@ -555,7 +365,7 @@ index 73c1abc..e8564bd 100644
mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
}
-@@ -233,7 +228,6 @@ EGLint Renderer9::initialize()
+@@ -228,7 +223,6 @@ EGLint Renderer9::initialize()
// Give up on getting device caps after about one second.
{
@@ -563,7 +373,7 @@ index 73c1abc..e8564bd 100644
for (int i = 0; i < 10; ++i)
{
result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
-@@ -268,7 +262,6 @@ EGLint Renderer9::initialize()
+@@ -263,7 +257,6 @@ EGLint Renderer9::initialize()
}
{
@@ -571,7 +381,7 @@ index 73c1abc..e8564bd 100644
mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
}
-@@ -305,7 +298,6 @@ EGLint Renderer9::initialize()
+@@ -300,7 +293,6 @@ EGLint Renderer9::initialize()
static const TCHAR className[] = TEXT("STATIC");
{
@@ -579,7 +389,7 @@ index 73c1abc..e8564bd 100644
mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
}
-@@ -313,7 +305,6 @@ EGLint Renderer9::initialize()
+@@ -308,7 +300,6 @@ EGLint Renderer9::initialize()
DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
{
@@ -587,7 +397,7 @@ index 73c1abc..e8564bd 100644
result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
-@@ -323,7 +314,6 @@ EGLint Renderer9::initialize()
+@@ -318,7 +309,6 @@ EGLint Renderer9::initialize()
if (FAILED(result))
{
@@ -595,7 +405,7 @@ index 73c1abc..e8564bd 100644
result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
if (FAILED(result))
-@@ -335,13 +325,11 @@ EGLint Renderer9::initialize()
+@@ -330,13 +320,11 @@ EGLint Renderer9::initialize()
if (mD3d9Ex)
{
@@ -662,858 +472,6 @@ index 3a36980..3bd611b 100644
{
VS_OUTPUT Out;
-diff --git a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h b/src/3rdparty/angle/src/third_party/trace_event/trace_event.h
-deleted file mode 100644
-index 1880056..0000000
---- a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h
-+++ /dev/null
-@@ -1,826 +0,0 @@
--// Copyright (c) 2013 The Chromium Authors. All rights reserved.
--// Use of this source code is governed by a BSD-style license that can be
--// found in the LICENSE file.
--
--// Trace events are for tracking application performance and resource usage.
--// Macros are provided to track:
--// Begin and end of function calls
--// Counters
--//
--// Events are issued against categories. Whereas LOG's
--// categories are statically defined, TRACE categories are created
--// implicitly with a string. For example:
--// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
--//
--// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
--// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
--// doSomethingCostly()
--// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
--// Note: our tools can't always determine the correct BEGIN/END pairs unless
--// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you need them
--// to be in separate scopes.
--//
--// A common use case is to trace entire function scopes. This
--// issues a trace BEGIN and END automatically:
--// void doSomethingCostly() {
--// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
--// ...
--// }
--//
--// Additional parameters can be associated with an event:
--// void doSomethingCostly2(int howMuch) {
--// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
--// "howMuch", howMuch);
--// ...
--// }
--//
--// The trace system will automatically add to this information the
--// current process id, thread id, and a timestamp in microseconds.
--//
--// To trace an asynchronous procedure such as an IPC send/receive, use ASYNC_BEGIN and
--// ASYNC_END:
--// [single threaded sender code]
--// static int send_count = 0;
--// ++send_count;
--// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
--// Send(new MyMessage(send_count));
--// [receive code]
--// void OnMyMessage(send_count) {
--// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
--// }
--// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
--// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. Pointers can
--// be used for the ID parameter, and they will be mangled internally so that
--// the same pointer on two different processes will not match. For example:
--// class MyTracedClass {
--// public:
--// MyTracedClass() {
--// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
--// }
--// ~MyTracedClass() {
--// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
--// }
--// }
--//
--// Trace event also supports counters, which is a way to track a quantity
--// as it varies over time. Counters are created with the following macro:
--// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
--//
--// Counters are process-specific. The macro itself can be issued from any
--// thread, however.
--//
--// Sometimes, you want to track two counters at once. You can do this with two
--// counter macros:
--// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
--// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
--// Or you can do it with a combined macro:
--// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
--// "bytesPinned", g_myCounterValue[0],
--// "bytesAllocated", g_myCounterValue[1]);
--// This indicates to the tracing UI that these counters should be displayed
--// in a single graph, as a summed area chart.
--//
--// Since counters are in a global namespace, you may want to disembiguate with a
--// unique ID, by using the TRACE_COUNTER_ID* variations.
--//
--// By default, trace collection is compiled in, but turned off at runtime.
--// Collecting trace data is the responsibility of the embedding
--// application. In Chrome's case, navigating to about:tracing will turn on
--// tracing and display data collected across all active processes.
--//
--//
--// Memory scoping note:
--// Tracing copies the pointers, not the string content, of the strings passed
--// in for category, name, and arg_names. Thus, the following code will
--// cause problems:
--// char* str = strdup("impprtantName");
--// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
--// free(str); // Trace system now has dangling pointer
--//
--// To avoid this issue with the |name| and |arg_name| parameters, use the
--// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
--// Notes: The category must always be in a long-lived char* (i.e. static const).
--// The |arg_values|, when used, are always deep copied with the _COPY
--// macros.
--//
--// When are string argument values copied:
--// const char* arg_values are only referenced by default:
--// TRACE_EVENT1("category", "name",
--// "arg1", "literal string is only referenced");
--// Use TRACE_STR_COPY to force copying of a const char*:
--// TRACE_EVENT1("category", "name",
--// "arg1", TRACE_STR_COPY("string will be copied"));
--// std::string arg_values are always copied:
--// TRACE_EVENT1("category", "name",
--// "arg1", std::string("string will be copied"));
--//
--//
--// Thread Safety:
--// A thread safe singleton and mutex are used for thread safety. Category
--// enabled flags are used to limit the performance impact when the system
--// is not enabled.
--//
--// TRACE_EVENT macros first cache a pointer to a category. The categories are
--// statically allocated and safe at all times, even after exit. Fetching a
--// category is protected by the TraceLog::lock_. Multiple threads initializing
--// the static variable is safe, as they will be serialized by the lock and
--// multiple calls will return the same pointer to the category.
--//
--// Then the category_enabled flag is checked. This is a unsigned char, and
--// not intended to be multithread safe. It optimizes access to addTraceEvent
--// which is threadsafe internally via TraceLog::lock_. The enabled flag may
--// cause some threads to incorrectly call or skip calling addTraceEvent near
--// the time of the system being enabled or disabled. This is acceptable as
--// we tolerate some data loss while the system is being enabled/disabled and
--// because addTraceEvent is threadsafe internally and checks the enabled state
--// again under lock.
--//
--// Without the use of these static category pointers and enabled flags all
--// trace points would carry a significant performance cost of aquiring a lock
--// and resolving the category.
--
--#ifndef COMMON_TRACE_EVENT_H_
--#define COMMON_TRACE_EVENT_H_
--
--#include <string>
--
--#include "common/event_tracer.h"
--
--// By default, const char* argument values are assumed to have long-lived scope
--// and will not be copied. Use this macro to force a const char* to be copied.
--#define TRACE_STR_COPY(str) \
-- WebCore::TraceEvent::TraceStringWithCopy(str)
--
--// Records a pair of begin and end events called "name" for the current
--// scope, with 0, 1 or 2 associated arguments. If the category is not
--// enabled, then this does nothing.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--#define TRACE_EVENT0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name)
--#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val)
--#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--
--// Records a single event called "name" immediately, with 0, 1 or 2
--// associated arguments. If the category is not enabled, then this
--// does nothing.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--#define TRACE_EVENT_INSTANT0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
-- category, name, TRACE_EVENT_FLAG_NONE)
--#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
-- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
--#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
-- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--#define TRACE_EVENT_COPY_INSTANT0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
-- category, name, TRACE_EVENT_FLAG_COPY)
--#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
-- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
--#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
-- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--
--// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
--// associated arguments. If the category is not enabled, then this
--// does nothing.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--#define TRACE_EVENT_BEGIN0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
-- category, name, TRACE_EVENT_FLAG_NONE)
--#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
-- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
--#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
-- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--#define TRACE_EVENT_COPY_BEGIN0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
-- category, name, TRACE_EVENT_FLAG_COPY)
--#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
-- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
--#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
-- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--
--// Records a single END event for "name" immediately. If the category
--// is not enabled, then this does nothing.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--#define TRACE_EVENT_END0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
-- category, name, TRACE_EVENT_FLAG_NONE)
--#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
-- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
--#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
-- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--#define TRACE_EVENT_COPY_END0(category, name) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
-- category, name, TRACE_EVENT_FLAG_COPY)
--#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
-- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
--#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
-- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
-- arg2_name, arg2_val)
--
--// Records the value of a counter called "name" immediately. Value
--// must be representable as a 32 bit integer.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--#define TRACE_COUNTER1(category, name, value) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, TRACE_EVENT_FLAG_NONE, \
-- "value", static_cast<int>(value))
--#define TRACE_COPY_COUNTER1(category, name, value) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, TRACE_EVENT_FLAG_COPY, \
-- "value", static_cast<int>(value))
--
--// Records the values of a multi-parted counter called "name" immediately.
--// The UI will treat value1 and value2 as parts of a whole, displaying their
--// values as a stacked-bar chart.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--#define TRACE_COUNTER2(category, name, value1_name, value1_val, \
-- value2_name, value2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, TRACE_EVENT_FLAG_NONE, \
-- value1_name, static_cast<int>(value1_val), \
-- value2_name, static_cast<int>(value2_val))
--#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \
-- value2_name, value2_val) \
-- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, TRACE_EVENT_FLAG_COPY, \
-- value1_name, static_cast<int>(value1_val), \
-- value2_name, static_cast<int>(value2_val))
--
--// Records the value of a counter called "name" immediately. Value
--// must be representable as a 32 bit integer.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--// - |id| is used to disambiguate counters with the same name. It must either
--// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
--// will be xored with a hash of the process ID so that the same pointer on
--// two different processes will not collide.
--#define TRACE_COUNTER_ID1(category, name, id, value) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, \
-- "value", static_cast<int>(value))
--#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, \
-- "value", static_cast<int>(value))
--
--// Records the values of a multi-parted counter called "name" immediately.
--// The UI will treat value1 and value2 as parts of a whole, displaying their
--// values as a stacked-bar chart.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--// - |id| is used to disambiguate counters with the same name. It must either
--// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
--// will be xored with a hash of the process ID so that the same pointer on
--// two different processes will not collide.
--#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \
-- value2_name, value2_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, \
-- value1_name, static_cast<int>(value1_val), \
-- value2_name, static_cast<int>(value2_val))
--#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \
-- value2_name, value2_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, \
-- value1_name, static_cast<int>(value1_val), \
-- value2_name, static_cast<int>(value2_val))
--
--// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
--// associated arguments. If the category is not enabled, then this
--// does nothing.
--// - category and name strings must have application lifetime (statics or
--// literals). They may not include " chars.
--// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
--// events are considered to match if their category, name and id values all
--// match. |id| must either be a pointer or an integer value up to 64 bits. If
--// it's a pointer, the bits will be xored with a hash of the process ID so
--// that the same pointer on two different processes will not collide.
--// An asynchronous operation can consist of multiple phases. The first phase is
--// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
--// ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END.
--// An async operation can span threads and processes, but all events in that
--// operation must use the same |name| and |id|. Each event can have its own
--// args.
--#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
-- category, name, id, TRACE_EVENT_FLAG_NONE)
--#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
--#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, \
-- arg1_name, arg1_val, arg2_name, arg2_val)
--#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
-- category, name, id, TRACE_EVENT_FLAG_COPY)
--#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, \
-- arg1_name, arg1_val)
--#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, \
-- arg1_name, arg1_val, arg2_name, arg2_val)
--
--// Records a single ASYNC_STEP event for |step| immediately. If the category
--// is not enabled, then this does nothing. The |name| and |id| must match the
--// ASYNC_BEGIN event above. The |step| param identifies this step within the
--// async event. This should be called at the beginning of the next phase of an
--// asynchronous operation.
--#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
--#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \
-- arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
-- arg1_name, arg1_val)
--#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
--#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \
-- arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
-- arg1_name, arg1_val)
--
--// Records a single ASYNC_END event for "name" immediately. If the category
--// is not enabled, then this does nothing.
--#define TRACE_EVENT_ASYNC_END0(category, name, id) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
-- category, name, id, TRACE_EVENT_FLAG_NONE)
--#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
--#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
-- category, name, id, TRACE_EVENT_FLAG_NONE, \
-- arg1_name, arg1_val, arg2_name, arg2_val)
--#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
-- category, name, id, TRACE_EVENT_FLAG_COPY)
--#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, \
-- arg1_name, arg1_val)
--#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
-- arg2_name, arg2_val) \
-- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
-- category, name, id, TRACE_EVENT_FLAG_COPY, \
-- arg1_name, arg1_val, arg2_name, arg2_val)
--
--// Creates a scope of a sampling state with the given category and name (both must
--// be constant strings). These states are intended for a sampling profiler.
--// Implementation note: we store category and name together because we don't
--// want the inconsistency/expense of storing two pointers.
--// |thread_bucket| is [0..2] and is used to statically isolate samples in one
--// thread from others.
--//
--// { // The sampling state is set within this scope.
--// TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
--// ...;
--// }
--#define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
-- TraceEvent::SamplingStateScope<bucket_number> traceEventSamplingScope(category "\0" name);
--
--// Returns a current sampling state of the given bucket.
--// The format of the returned string is "category\0name".
--#define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
-- TraceEvent::SamplingStateScope<bucket_number>::current()
--
--// Sets a current sampling state of the given bucket.
--// |category| and |name| have to be constant strings.
--#define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
-- TraceEvent::SamplingStateScope<bucket_number>::set(category "\0" name)
--
--// Sets a current sampling state of the given bucket.
--// |categoryAndName| doesn't need to be a constant string.
--// The format of the string is "category\0name".
--#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, categoryAndName) \
-- TraceEvent::SamplingStateScope<bucket_number>::set(categoryAndName)
--
--// Syntactic sugars for the sampling tracing in the main thread.
--#define TRACE_EVENT_SCOPED_SAMPLING_STATE(category, name) \
-- TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(0, category, name)
--#define TRACE_EVENT_GET_SAMPLING_STATE() \
-- TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(0)
--#define TRACE_EVENT_SET_SAMPLING_STATE(category, name) \
-- TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(0, category, name)
--#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(categoryAndName) \
-- TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(0, categoryAndName)
--
--////////////////////////////////////////////////////////////////////////////////
--// Implementation specific tracing API definitions.
--
--// Get a pointer to the enabled state of the given trace category. Only
--// long-lived literal strings should be given as the category name. The returned
--// pointer can be held permanently in a local static for example. If the
--// unsigned char is non-zero, tracing is enabled. If tracing is enabled,
--// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
--// between the load of the tracing state and the call to
--// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
--// for best performance when tracing is disabled.
--// const unsigned char*
--// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
--#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \
-- gl::TraceGetTraceCategoryEnabledFlag
--
--// Add a trace event to the platform tracing system.
--// void TRACE_EVENT_API_ADD_TRACE_EVENT(
--// char phase,
--// const unsigned char* category_enabled,
--// const char* name,
--// unsigned long long id,
--// int num_args,
--// const char** arg_names,
--// const unsigned char* arg_types,
--// const unsigned long long* arg_values,
--// unsigned char flags)
--#define TRACE_EVENT_API_ADD_TRACE_EVENT \
-- gl::TraceAddTraceEvent
--
--////////////////////////////////////////////////////////////////////////////////
--
--// Implementation detail: trace event macros create temporary variables
--// to keep instrumentation overhead low. These macros give each temporary
--// variable a unique name based on the line number to prevent name collissions.
--#define INTERNAL_TRACE_EVENT_UID3(a, b) \
-- trace_event_unique_##a##b
--#define INTERNAL_TRACE_EVENT_UID2(a, b) \
-- INTERNAL_TRACE_EVENT_UID3(a, b)
--#define INTERNALTRACEEVENTUID(name_prefix) \
-- INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
--
--// Implementation detail: internal macro to create static category.
--#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \
-- static const unsigned char* INTERNALTRACEEVENTUID(catstatic) = 0; \
-- if (!INTERNALTRACEEVENTUID(catstatic)) \
-- INTERNALTRACEEVENTUID(catstatic) = \
-- TRACE_EVENT_API_GET_CATEGORY_ENABLED(category);
--
--// Implementation detail: internal macro to create static category and add
--// event if the category is enabled.
--#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
-- do { \
-- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
-- if (*INTERNALTRACEEVENTUID(catstatic)) { \
-- gl::TraceEvent::addTraceEvent( \
-- phase, INTERNALTRACEEVENTUID(catstatic), name, \
-- gl::TraceEvent::noEventId, flags, ##__VA_ARGS__); \
-- } \
-- } while (0)
--
--// Implementation detail: internal macro to create static category and add begin
--// event if the category is enabled. Also adds the end event when the scope
--// ends.
--#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
-- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
-- gl::TraceEvent::TraceEndOnScopeClose \
-- INTERNALTRACEEVENTUID(profileScope); \
-- if (*INTERNALTRACEEVENTUID(catstatic)) { \
-- gl::TraceEvent::addTraceEvent( \
-- TRACE_EVENT_PHASE_BEGIN, \
-- INTERNALTRACEEVENTUID(catstatic), \
-- name, gl::TraceEvent::noEventId, \
-- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
-- INTERNALTRACEEVENTUID(profileScope).initialize( \
-- INTERNALTRACEEVENTUID(catstatic), name); \
-- }
--
--// Implementation detail: internal macro to create static category and add
--// event if the category is enabled.
--#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
-- ...) \
-- do { \
-- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
-- if (*INTERNALTRACEEVENTUID(catstatic)) { \
-- unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
-- gl::TraceEvent::TraceID traceEventTraceID( \
-- id, &traceEventFlags); \
-- gl::TraceEvent::addTraceEvent( \
-- phase, INTERNALTRACEEVENTUID(catstatic), \
-- name, traceEventTraceID.data(), traceEventFlags, \
-- ##__VA_ARGS__); \
-- } \
-- } while (0)
--
--// Notes regarding the following definitions:
--// New values can be added and propagated to third party libraries, but existing
--// definitions must never be changed, because third party libraries may use old
--// definitions.
--
--// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
--#define TRACE_EVENT_PHASE_BEGIN ('B')
--#define TRACE_EVENT_PHASE_END ('E')
--#define TRACE_EVENT_PHASE_INSTANT ('I')
--#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
--#define TRACE_EVENT_PHASE_ASYNC_STEP ('T')
--#define TRACE_EVENT_PHASE_ASYNC_END ('F')
--#define TRACE_EVENT_PHASE_METADATA ('M')
--#define TRACE_EVENT_PHASE_COUNTER ('C')
--#define TRACE_EVENT_PHASE_SAMPLE ('P')
--
--// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
--#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
--#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned char>(1 << 0))
--#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned char>(1 << 1))
--#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned char>(1 << 2))
--
--// Type values for identifying types in the TraceValue union.
--#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
--#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
--#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
--#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
--#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
--#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
--#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
--
--
--namespace gl {
--
--namespace TraceEvent {
--
--// Specify these values when the corresponding argument of addTraceEvent is not
--// used.
--const int zeroNumArgs = 0;
--const unsigned long long noEventId = 0;
--
--// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
--// are mangled with the Process ID so that they are unlikely to collide when the
--// same pointer is used on different processes.
--class TraceID {
--public:
-- explicit TraceID(const void* id, unsigned char* flags) :
-- m_data(static_cast<unsigned long long>(reinterpret_cast<unsigned long>(id)))
-- {
-- *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
-- }
-- explicit TraceID(unsigned long long id, unsigned char* flags) : m_data(id) { (void)flags; }
-- explicit TraceID(unsigned long id, unsigned char* flags) : m_data(id) { (void)flags; }
-- explicit TraceID(unsigned int id, unsigned char* flags) : m_data(id) { (void)flags; }
-- explicit TraceID(unsigned short id, unsigned char* flags) : m_data(id) { (void)flags; }
-- explicit TraceID(unsigned char id, unsigned char* flags) : m_data(id) { (void)flags; }
-- explicit TraceID(long long id, unsigned char* flags) :
-- m_data(static_cast<unsigned long long>(id)) { (void)flags; }
-- explicit TraceID(long id, unsigned char* flags) :
-- m_data(static_cast<unsigned long long>(id)) { (void)flags; }
-- explicit TraceID(int id, unsigned char* flags) :
-- m_data(static_cast<unsigned long long>(id)) { (void)flags; }
-- explicit TraceID(short id, unsigned char* flags) :
-- m_data(static_cast<unsigned long long>(id)) { (void)flags; }
-- explicit TraceID(signed char id, unsigned char* flags) :
-- m_data(static_cast<unsigned long long>(id)) { (void)flags; }
--
-- unsigned long long data() const { return m_data; }
--
--private:
-- unsigned long long m_data;
--};
--
--// Simple union to store various types as unsigned long long.
--union TraceValueUnion {
-- bool m_bool;
-- unsigned long long m_uint;
-- long long m_int;
-- double m_double;
-- const void* m_pointer;
-- const char* m_string;
--};
--
--// Simple container for const char* that should be copied instead of retained.
--class TraceStringWithCopy {
--public:
-- explicit TraceStringWithCopy(const char* str) : m_str(str) { }
-- operator const char* () const { return m_str; }
--private:
-- const char* m_str;
--};
--
--// Define setTraceValue for each allowed type. It stores the type and
--// value in the return arguments. This allows this API to avoid declaring any
--// structures so that it is portable to third_party libraries.
--#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
-- union_member, \
-- value_type_id) \
-- static inline void setTraceValue(actual_type arg, \
-- unsigned char* type, \
-- unsigned long long* value) { \
-- TraceValueUnion typeValue; \
-- typeValue.union_member = arg; \
-- *type = value_type_id; \
-- *value = typeValue.m_uint; \
-- }
--// Simpler form for int types that can be safely casted.
--#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
-- value_type_id) \
-- static inline void setTraceValue(actual_type arg, \
-- unsigned char* type, \
-- unsigned long long* value) { \
-- *type = value_type_id; \
-- *value = static_cast<unsigned long long>(arg); \
-- }
--
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
--INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
--INTERNAL_DECLARE_SET_TRACE_VALUE(bool, m_bool, TRACE_VALUE_TYPE_BOOL)
--INTERNAL_DECLARE_SET_TRACE_VALUE(double, m_double, TRACE_VALUE_TYPE_DOUBLE)
--INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, m_pointer,
-- TRACE_VALUE_TYPE_POINTER)
--INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, m_string,
-- TRACE_VALUE_TYPE_STRING)
--INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, m_string,
-- TRACE_VALUE_TYPE_COPY_STRING)
--
--#undef INTERNAL_DECLARE_SET_TRACE_VALUE
--#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
--
--static inline void setTraceValue(const std::string& arg,
-- unsigned char* type,
-- unsigned long long* value) {
-- TraceValueUnion typeValue;
-- typeValue.m_string = arg.data();
-- *type = TRACE_VALUE_TYPE_COPY_STRING;
-- *value = typeValue.m_uint;
--}
--
--// These addTraceEvent template functions are defined here instead of in the
--// macro, because the arg values could be temporary string objects. In order to
--// store pointers to the internal c_str and pass through to the tracing API, the
--// arg values must live throughout these procedures.
--
--static inline void addTraceEvent(char phase,
-- const unsigned char* categoryEnabled,
-- const char* name,
-- unsigned long long id,
-- unsigned char flags) {
-- TRACE_EVENT_API_ADD_TRACE_EVENT(
-- phase, categoryEnabled, name, id,
-- zeroNumArgs, 0, 0, 0,
-- flags);
--}
--
--template<class ARG1_TYPE>
--static inline void addTraceEvent(char phase,
-- const unsigned char* categoryEnabled,
-- const char* name,
-- unsigned long long id,
-- unsigned char flags,
-- const char* arg1Name,
-- const ARG1_TYPE& arg1Val) {
-- const int numArgs = 1;
-- unsigned char argTypes[1];
-- unsigned long long argValues[1];
-- setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
-- TRACE_EVENT_API_ADD_TRACE_EVENT(
-- phase, categoryEnabled, name, id,
-- numArgs, &arg1Name, argTypes, argValues,
-- flags);
--}
--
--template<class ARG1_TYPE, class ARG2_TYPE>
--static inline void addTraceEvent(char phase,
-- const unsigned char* categoryEnabled,
-- const char* name,
-- unsigned long long id,
-- unsigned char flags,
-- const char* arg1Name,
-- const ARG1_TYPE& arg1Val,
-- const char* arg2Name,
-- const ARG2_TYPE& arg2Val) {
-- const int numArgs = 2;
-- const char* argNames[2] = { arg1Name, arg2Name };
-- unsigned char argTypes[2];
-- unsigned long long argValues[2];
-- setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
-- setTraceValue(arg2Val, &argTypes[1], &argValues[1]);
-- return TRACE_EVENT_API_ADD_TRACE_EVENT(
-- phase, categoryEnabled, name, id,
-- numArgs, argNames, argTypes, argValues,
-- flags);
--}
--
--// Used by TRACE_EVENTx macro. Do not use directly.
--class TraceEndOnScopeClose {
--public:
-- // Note: members of m_data intentionally left uninitialized. See initialize.
-- TraceEndOnScopeClose() : m_pdata(0) { }
-- ~TraceEndOnScopeClose()
-- {
-- if (m_pdata)
-- addEventIfEnabled();
-- }
--
-- void initialize(const unsigned char* categoryEnabled,
-- const char* name)
-- {
-- m_data.categoryEnabled = categoryEnabled;
-- m_data.name = name;
-- m_pdata = &m_data;
-- }
--
--private:
-- // Add the end event if the category is still enabled.
-- void addEventIfEnabled()
-- {
-- // Only called when m_pdata is non-null.
-- if (*m_pdata->categoryEnabled) {
-- TRACE_EVENT_API_ADD_TRACE_EVENT(
-- TRACE_EVENT_PHASE_END,
-- m_pdata->categoryEnabled,
-- m_pdata->name, noEventId,
-- zeroNumArgs, 0, 0, 0,
-- TRACE_EVENT_FLAG_NONE);
-- }
-- }
--
-- // This Data struct workaround is to avoid initializing all the members
-- // in Data during construction of this object, since this object is always
-- // constructed, even when tracing is disabled. If the members of Data were
-- // members of this class instead, compiler warnings occur about potential
-- // uninitialized accesses.
-- struct Data {
-- const unsigned char* categoryEnabled;
-- const char* name;
-- };
-- Data* m_pdata;
-- Data m_data;
--};
--
--// TraceEventSamplingStateScope records the current sampling state
--// and sets a new sampling state. When the scope exists, it restores
--// the sampling state having recorded.
--template<size_t BucketNumber>
--class SamplingStateScope {
--public:
-- SamplingStateScope(const char* categoryAndName)
-- {
-- m_previousState = SamplingStateScope<BucketNumber>::current();
-- SamplingStateScope<BucketNumber>::set(categoryAndName);
-- }
--
-- ~SamplingStateScope()
-- {
-- SamplingStateScope<BucketNumber>::set(m_previousState);
-- }
--
-- // FIXME: Make load/store to traceSamplingState[] thread-safe and atomic.
-- static inline const char* current()
-- {
-- return reinterpret_cast<const char*>(*gl::traceSamplingState[BucketNumber]);
-- }
-- static inline void set(const char* categoryAndName)
-- {
-- *gl::traceSamplingState[BucketNumber] = reinterpret_cast<long>(const_cast<char*>(categoryAndName));
-- }
--
--private:
-- const char* m_previousState;
--};
--
--} // namespace TraceEvent
--
--} // namespace gl
--
--#endif
-diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
-index fd1c31c..8baedc5 100644
---- a/src/angle/src/common/common.pri
-+++ b/src/angle/src/common/common.pri
-@@ -51,7 +51,6 @@ static: DEFINES *= QT_OPENGL_ES_2_ANGLE_STATIC
- HEADERS += \
- $$ANGLE_DIR/src/common/angleutils.h \
- $$ANGLE_DIR/src/common/debug.h \
-- $$ANGLE_DIR/src/common/event_tracer.h \
- $$ANGLE_DIR/src/common/mathutil.h \
- $$ANGLE_DIR/src/common/platform.h \
- $$ANGLE_DIR/src/common/RefCountObject.h \
-@@ -61,7 +60,6 @@ HEADERS += \
- SOURCES += \
- $$ANGLE_DIR/src/common/angleutils.cpp \
- $$ANGLE_DIR/src/common/debug.cpp \
-- $$ANGLE_DIR/src/common/event_tracer.cpp \
- $$ANGLE_DIR/src/common/RefCountObject.cpp \
- $$ANGLE_DIR/src/common/tls.cpp
-
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
deleted file mode 100644
index f2252540eb..0000000000
--- a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 3ea314039783d2e6e558cb10aa86dbf278631eef Mon Sep 17 00:00:00 2001
-From: Thomas Hartmann <Thomas.Hartmann@digia.com>
-Date: Tue, 16 Sep 2014 23:24:24 +0300
-Subject: [PATCH 01/16] Fix compilation for MSVC 2008 and std::tuple
-
-For MSVC 2008 make_tuple is in the tr1 namespace.
-
-Change-Id: I4a51f6cabdf068993869b404b12ed1484a21a9d4
----
- src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
-index d472e14..f68ac38 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
-@@ -111,7 +111,11 @@ IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
-
- bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
- {
-+#if defined(_MSC_VER) && _MSC_VER < 1600
-+ return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
-+#else
- return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
-+#endif
- }
-
- IndexRangeCache::IndexBounds::IndexBounds()
---
-1.9.0.msysgit.0
-
diff --git a/src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch b/src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch
deleted file mode 100644
index 322d121149..0000000000
--- a/src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 9f1217589c029d2f91e863c54f7f9d52ef496f71 Mon Sep 17 00:00:00 2001
-From: Kai Koehne <kai.koehne@digia.com>
-Date: Tue, 16 Sep 2014 23:33:42 +0300
-Subject: [PATCH 02/16] Fix compilation of ANGLE with mingw-tdm64 gcc 4.8.1
-
-Do not rely on sprintf_s being declared/defined. This also fixes
-deployment to Windows XP.
-
-See https://chromium-review.googlesource.com/#/c/182975/ for a similar
-commit proposed upstream.
-
-Task-number: QTBUG-36242
-Change-Id: I520e2f61aeab34963e7a57baafd413c7db93f110
----
- src/3rdparty/angle/src/libEGL/Display.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
-index ecf3395..aaebdb3 100644
---- a/src/3rdparty/angle/src/libEGL/Display.cpp
-+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
-@@ -597,7 +597,7 @@ void Display::initVendorString()
- if (mRenderer && mRenderer->getLUID(&adapterLuid))
- {
- char adapterLuidString[64];
-- sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
-+ snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
-
- mVendorString += adapterLuidString;
- }
---
-1.9.0.msysgit.0
-
diff --git a/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch b/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch
index 1dfe6154e7..45a3f17cca 100644
--- a/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch
+++ b/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch
@@ -1,6 +1,6 @@
-From cb00356bad800ca2397301cb8b79ad0b097bddd8 Mon Sep 17 00:00:00 2001
+From 3a39939b5eba9f788789961c4800ba62618f758c Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@digia.com>
-Date: Tue, 16 Sep 2014 23:43:00 +0300
+Date: Tue, 11 Nov 2014 10:26:32 +0200
Subject: [PATCH 04/16] Make it possible to link ANGLE statically for
single-thread use.
@@ -11,8 +11,8 @@ Change-Id: Ifab25a820adf5953bb3b09036de53dbf7f1a7fd5
---
src/3rdparty/angle/include/KHR/khrplatform.h | 2 +-
src/3rdparty/angle/src/libEGL/main.cpp | 10 ++++++++++
- src/3rdparty/angle/src/libGLESv2/main.cpp | 10 ++++++++++
- 3 files changed, 21 insertions(+), 1 deletion(-)
+ src/3rdparty/angle/src/libGLESv2/main.cpp | 10 ++++++++--
+ 3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/3rdparty/angle/include/KHR/khrplatform.h b/src/3rdparty/angle/include/KHR/khrplatform.h
index c9e6f17..1ac2d3f 100644
@@ -28,7 +28,7 @@ index c9e6f17..1ac2d3f 100644
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
-index 0f8439c..8a1baef 100644
+index d1489f2..e88cad7 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -49,6 +49,8 @@ void DeallocateCurrent()
@@ -40,7 +40,7 @@ index 0f8439c..8a1baef 100644
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
-@@ -100,16 +102,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+@@ -108,16 +110,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE;
}
@@ -64,26 +64,27 @@ index 0f8439c..8a1baef 100644
+#endif
}
- void setCurrentError(EGLint error)
+ void recordError(const Error &error)
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
-index 4444d1a..1c577bc 100644
+index 3ac00d5..00f63ae 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
-@@ -46,6 +46,8 @@ void DeallocateCurrent()
+@@ -74,7 +74,7 @@ void DeallocateCurrent()
}
-+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
-+
+-#ifdef ANGLE_PLATFORM_WINDOWS
++#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
-@@ -82,16 +84,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+@@ -117,18 +117,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+
return TRUE;
}
+-#endif
++#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC
-+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
-+
namespace gl
{
@@ -104,5 +105,5 @@ index 4444d1a..1c577bc 100644
void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch b/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch
deleted file mode 100644
index 78c3e0fbe8..0000000000
--- a/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From df225c023963f37737b7e2d020c8f89a5d5f878e Mon Sep 17 00:00:00 2001
-From: Andy Shaw <andy.shaw@digia.com>
-Date: Tue, 16 Sep 2014 23:49:50 +0300
-Subject: [PATCH 05/16] Fix build when SSE2 is not available.
-
-Although SSE2 support is detected at runtime it still may not be
-available at build time, so we have to ensure it only uses SSE2
-when it is available at build time too.
-
-Change-Id: I86c45a6466ab4cec79aa0f62b0d5230a78ad825a
----
- src/3rdparty/angle/src/common/mathutil.h | 2 ++
- src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp | 8 ++++++++
- 2 files changed, 10 insertions(+)
-
-diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h
-index ffcb908..52f2bc1 100644
---- a/src/3rdparty/angle/src/common/mathutil.h
-+++ b/src/3rdparty/angle/src/common/mathutil.h
-@@ -118,6 +118,7 @@ inline bool supportsSSE2()
- return supports;
- }
-
-+#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid()
- int info[4];
- __cpuid(info, 0);
-
-@@ -127,6 +128,7 @@ inline bool supportsSSE2()
-
- supports = (info[3] >> 26) & 1;
- }
-+#endif
-
- checked = true;
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
-index cc20d94..f777b30 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
-@@ -10,6 +10,10 @@
-
- #include "libGLESv2/renderer/loadimage.h"
-
-+#if !defined(__SSE2__) && (defined(_M_X64) || _M_IX86_FP == 2)
-+#define __SSE2__
-+#endif
-+
- namespace rx
- {
-
-@@ -17,6 +21,7 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
- const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
- uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
- {
-+#ifdef __SSE2__
- __m128i zeroWide = _mm_setzero_si128();
-
- for (size_t z = 0; z < depth; z++)
-@@ -54,12 +59,14 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
- }
- }
- }
-+#endif
- }
-
- void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
- const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
- uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
- {
-+#ifdef __SSE2__
- __m128i brMask = _mm_set1_epi32(0x00ff00ff);
-
- for (size_t z = 0; z < depth; z++)
-@@ -99,6 +106,7 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
- }
- }
- }
-+#endif
- }
-
- }
---
-1.9.0.msysgit.0
-
diff --git a/src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch b/src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch
deleted file mode 100644
index e60bebd233..0000000000
--- a/src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 2a8568e6f44731df96f6567ffcc59a65ad2b3f29 Mon Sep 17 00:00:00 2001
-From: Kai Koehne <kai.koehne@digia.com>
-Date: Tue, 16 Sep 2014 23:55:25 +0300
-Subject: [PATCH 06/16] Fix compilation of libGLESv2 with older MinGW-w64
- headers
-
-Fix compilation of libGLESv2 for mingw-headers predating MinGW-w64
-svn commit 5567 (like MinGW-builds gcc 4.7.2-rev8, the toolchain
-we officially support).
-
-Commit 5567 added the D3DCOMPILER_DLL define to d3dcompiler.h, but with
-a trailing semicolon that has then fixed in commit 5783. Any toolchain
-that ships MinGW-w64 headers from a version in between (like
-MinGW-builds gcc 4.7.2-rev11) will unfortunately remain broken.
-
-Change-Id: I31272a1a991c4fc0f1611f8fb7510be51d6bb925
----
- .../angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index acbd852..eb0dfa5 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -10,6 +10,21 @@
-
- #include "common/utilities.h"
-
-+#if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL)
-+
-+// Add define + typedefs for older MinGW-w64 headers (pre 5783)
-+
-+#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
-+
-+HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
-+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
-+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
-+typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const char *filename,
-+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
-+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
-+
-+#endif // __MINGW32__ && !D3DCOMPILER_DLL
-+
- namespace rx
- {
-
---
-1.9.0.msysgit.0
-
diff --git a/src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch b/src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch
deleted file mode 100644
index c796ebc95e..0000000000
--- a/src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 76152feea8265f40fec8c6e53f976dbd82fb6c80 Mon Sep 17 00:00:00 2001
-From: Thiago Macieira <thiago.macieira@intel.com>
-Date: Tue, 16 Sep 2014 23:56:43 +0300
-Subject: [PATCH 07/16] Fix ANGLE build with Microsoft Visual Studio "14" CTP
-
-This version has a few new C99 support added, including snprintf.
-
-Change-Id: I5776456fd94254a64f08791f59bc775cb24c9b7f
----
- src/3rdparty/angle/src/common/angleutils.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h
-index 50a4132..ddbbd5f 100644
---- a/src/3rdparty/angle/src/common/angleutils.h
-+++ b/src/3rdparty/angle/src/common/angleutils.h
-@@ -135,7 +135,7 @@ inline std::string Str(int i)
- std::string FormatString(const char *fmt, va_list vararg);
- std::string FormatString(const char *fmt, ...);
-
--#if defined(_MSC_VER)
-+#if defined(_MSC_VER) && _MSC_VER < 1900
- #define snprintf _snprintf
- #endif
-
---
-1.9.0.msysgit.0
-
diff --git a/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch b/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch
index 7c821580d0..801db67682 100644
--- a/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch
+++ b/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch
@@ -1,6 +1,6 @@
-From 4f6dd1f7cdce3340723cc23e0aea27b156fa3497 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Tue, 16 Sep 2014 23:59:40 +0300
+From 4a5960465d1632ab089320fcbba4af294d58fd9a Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Fri, 7 Nov 2014 14:05:36 +0200
Subject: [PATCH 08/16] ANGLE: Dynamically load D3D compiler from a list or the
environment
@@ -11,29 +11,28 @@ QT_D3DCOMPILER_DLL.
Change-Id: I0d7a8a8a36cc571836f8fa59ea14513b9b19c19b
---
- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 27 +++++++++++++++++++---
- 1 file changed, 24 insertions(+), 3 deletions(-)
+ .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 27 ++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index eb0dfa5..5715d5f 100644
+index bfeaf51..9d003b4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -25,6 +25,10 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const
-
- #endif // __MINGW32__ && !D3DCOMPILER_DLL
+@@ -11,6 +11,10 @@
+ #include "common/features.h"
+ #include "common/utilities.h"
+#ifndef QT_D3DCOMPILER_DLL
+#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
+#endif
+
- namespace rx
+ // Definitions local to the translation unit
+ namespace
{
-
-@@ -59,10 +63,27 @@ bool HLSLCompiler::initialize()
+@@ -132,6 +136,29 @@ bool HLSLCompiler::initialize()
}
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
-- if (!mD3DCompilerModule)
+ // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL
+ const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL");
+ if (!defaultCompiler)
@@ -51,15 +50,15 @@ index eb0dfa5..5715d5f 100644
+
+ // Load the first available known compiler DLL
+ for (int i = 0; compilerDlls[i]; ++i)
- {
-- // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
-- mD3DCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
++ {
+ mD3DCompilerModule = LoadLibrary(compilerDlls[i]);
+ if (mD3DCompilerModule)
+ break;
- }
-
++ }
++
if (!mD3DCompilerModule)
+ {
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0009-ANGLE-Support-WinRT.patch b/src/angle/patches/0009-ANGLE-Support-WinRT.patch
index f4bae46b63..a38fb4ea13 100644
--- a/src/angle/patches/0009-ANGLE-Support-WinRT.patch
+++ b/src/angle/patches/0009-ANGLE-Support-WinRT.patch
@@ -1,1126 +1,673 @@
-From 7ff7dd46f54e23ae309887366bf477de9c33005b Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Wed, 17 Sep 2014 00:58:29 +0300
+From 4d150ba3814f824f1cadaedbdb83d0ac79d0e1a2 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Fri, 14 Nov 2014 09:28:11 +0200
Subject: [PATCH 09/16] ANGLE: Support WinRT
-This enables EGL for WinRT's native types, and adjusts some codepaths
-to accommodate differences between desktop Windows and WinRT.
+Tweak ANGLE's existing support for WinRT to allow for changing the
+window size on Windows Phone.
-- WinRT native handles added to eglplatform.h
-- References to native handles in libEGL/libGLESv2 follow eglplatform.h
-- D3D 11.1 structures and methods used when necessary
-- TLS replaced with thread attribute
-- LocalAlloc/Free replaced with Heap API
-
-Change-Id: Ia90377e700d335a1c569c2145008dd4b0dfd84d3
-Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
+Change-Id: Ia312b5318b977838a2953f1f530487cbf24974bc
---
- src/3rdparty/angle/include/EGL/eglplatform.h | 10 +-
- src/3rdparty/angle/src/common/platform.h | 3 +
- src/3rdparty/angle/src/common/tls.cpp | 37 ++++-
- src/3rdparty/angle/src/common/tls.h | 6 +-
- src/3rdparty/angle/src/common/utilities.cpp | 51 +++++-
- src/3rdparty/angle/src/libEGL/Display.cpp | 13 +-
- src/3rdparty/angle/src/libEGL/Display.h | 6 +-
- src/3rdparty/angle/src/libEGL/Surface.cpp | 185 ++++++++++++++++++++-
- src/3rdparty/angle/src/libEGL/Surface.h | 37 ++++-
- src/3rdparty/angle/src/libEGL/libEGL.cpp | 8 +-
- src/3rdparty/angle/src/libEGL/main.cpp | 21 +++
- src/3rdparty/angle/src/libGLESv2/main.cpp | 20 +++
- src/3rdparty/angle/src/libGLESv2/main.h | 4 +
- .../angle/src/libGLESv2/renderer/Renderer.h | 2 +-
- .../angle/src/libGLESv2/renderer/SwapChain.h | 15 +-
- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 11 +-
- .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 13 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 4 +-
- .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 73 ++++++--
- .../src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h | 6 +-
- .../src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp | 2 +-
- .../src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h | 2 +-
- 22 files changed, 481 insertions(+), 48 deletions(-)
+ src/3rdparty/angle/include/EGL/eglplatform.h | 5 +-
+ src/3rdparty/angle/src/common/NativeWindow.h | 7 +-
+ src/3rdparty/angle/src/common/platform.h | 4 +-
+ .../angle/src/common/win32/NativeWindow.cpp | 2 +-
+ .../src/common/winrt/CoreWindowNativeWindow.cpp | 87 +++++++++++++---------
+ .../src/common/winrt/CoreWindowNativeWindow.h | 48 ++----------
+ .../src/common/winrt/InspectableNativeWindow.cpp | 8 +-
+ .../src/common/winrt/InspectableNativeWindow.h | 7 +-
+ .../common/winrt/SwapChainPanelNativeWindow.cpp | 2 +-
+ .../src/common/winrt/SwapChainPanelNativeWindow.h | 2 +-
+ src/3rdparty/angle/src/libEGL/Display.h | 1 +
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 45 ++++++++---
+ src/3rdparty/angle/src/libEGL/Surface.h | 4 +
+ src/3rdparty/angle/src/libEGL/libEGL.cpp | 20 +++++
+ .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 2 +-
+ .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 74 +++++++++++-------
+ .../src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h | 2 +
+ 17 files changed, 189 insertions(+), 131 deletions(-)
diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
-index 3ab8844..ea9f577 100644
+index 3793e57..2eb3674 100644
--- a/src/3rdparty/angle/include/EGL/eglplatform.h
+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
-@@ -67,7 +67,15 @@
- * implementations.
- */
+@@ -73,13 +73,14 @@
+ #endif
+ #include <windows.h>
+
+-typedef HDC EGLNativeDisplayType;
+ typedef HBITMAP EGLNativePixmapType;
+
+-#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP /* Windows Store */
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
+ #include <inspectable.h>
++typedef IInspectable* EGLNativeDisplayType;
+ typedef IInspectable* EGLNativeWindowType;
+ #else
++typedef HDC EGLNativeDisplayType;
+ typedef HWND EGLNativeWindowType;
+ #endif
--#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
-+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
-+
-+struct IUnknown;
-+
-+typedef IUnknown *EGLNativeDisplayType;
-+typedef void *EGLNativePixmapType;
-+typedef IUnknown *EGLNativeWindowType;
+diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h
+index dc5fc8f..9e93aea 100644
+--- a/src/3rdparty/angle/src/common/NativeWindow.h
++++ b/src/3rdparty/angle/src/common/NativeWindow.h
+@@ -44,10 +44,11 @@ typedef IDXGIFactory DXGIFactory;
+
+ namespace rx
+ {
+
-+#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN 1
- #endif
+ class NativeWindow
+ {
+- public:
+- explicit NativeWindow(EGLNativeWindowType window);
++public:
++ explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
+
+ bool initialize();
+ bool getClientRect(LPRECT rect);
+@@ -58,9 +59,11 @@ class NativeWindow
+ DXGISwapChain** swapChain);
+
+ inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
++ inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; }
+
+ private:
+ EGLNativeWindowType mWindow;
++ EGLNativeDisplayType mDisplay;
+
+ #if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ std::shared_ptr<InspectableNativeWindow> mImpl;
diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index d07297d..387ba41 100644
+index cd12dba..0065ec7 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -11,6 +11,9 @@
-
- #if defined(_WIN32) || defined(_WIN64)
- # define ANGLE_PLATFORM_WINDOWS 1
-+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
-+# define ANGLE_PLATFORM_WINRT 1
-+# endif
- #elif defined(__APPLE__)
- # define ANGLE_PLATFORM_APPLE 1
- # define ANGLE_PLATFORM_POSIX 1
-diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp
-index 6b78219..c46fab5 100644
---- a/src/3rdparty/angle/src/common/tls.cpp
-+++ b/src/3rdparty/angle/src/common/tls.cpp
-@@ -10,11 +10,28 @@
-
- #include <assert.h>
-
-+#if defined(ANGLE_PLATFORM_WINRT)
-+#include <vector>
-+std::vector<void *> *tls = nullptr;
-+std::vector<TLSIndex> *freeIndices = nullptr;
-+#endif
-+
- TLSIndex CreateTLSIndex()
- {
- TLSIndex index;
-
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (!tls)
-+ tls = new std::vector<void *>;
-+ if (freeIndices && !freeIndices->empty()) {
-+ index = freeIndices->back();
-+ freeIndices->pop_back();
-+ return index;
-+ } else {
-+ tls->push_back(nullptr);
-+ return tls->size() - 1;
-+ }
-+#elif defined(ANGLE_PLATFORM_WINDOWS)
- index = TlsAlloc();
- #elif defined(ANGLE_PLATFORM_POSIX)
- // Create global pool key
-@@ -36,7 +53,12 @@ bool DestroyTLSIndex(TLSIndex index)
- return false;
- }
+@@ -34,7 +34,7 @@
+ #endif
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (!freeIndices)
-+ freeIndices = new std::vector<TLSIndex>;
-+ freeIndices->push_back(index);
-+ return true;
-+#elif ANGLE_PLATFORM_WINDOWS
- return (TlsFree(index) == TRUE);
- #elif defined(ANGLE_PLATFORM_POSIX)
- return (pthread_key_delete(index) == 0);
-@@ -51,7 +73,10 @@ bool SetTLSValue(TLSIndex index, void *value)
- return false;
- }
+ #ifdef ANGLE_PLATFORM_WINDOWS
+-# if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP
++# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ # define ANGLE_ENABLE_WINDOWS_STORE 1
+ # endif
+ # ifndef STRICT
+@@ -67,7 +67,9 @@
+ # if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ # include <dxgi1_3.h>
+ # if defined(_DEBUG)
++# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ # include <DXProgrammableCapture.h>
++# endif
+ # include <dxgidebug.h>
+ # endif
+ # endif
+diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
+index aa2bfa4..2440747 100644
+--- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
++++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
+@@ -16,7 +16,7 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
+ return (IsWindow(window) == TRUE);
+ }
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ tls->at(index) = value;
-+ return true;
-+#elif defined(ANGLE_PLATFORM_WINDOWS)
- return (TlsSetValue(index, value) == TRUE);
- #elif defined(ANGLE_PLATFORM_POSIX)
- return (pthread_setspecific(index, value) == 0);
-@@ -60,13 +85,17 @@ bool SetTLSValue(TLSIndex index, void *value)
-
- void *GetTLSValue(TLSIndex index)
+-NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window)
++NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display)
{
-+#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation
- assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
-+#endif
- if (index == TLS_INVALID_INDEX)
- {
- return NULL;
- }
+ }
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ return tls->at(index);
-+#elif defined(ANGLE_PLATFORM_WINDOWS)
- return TlsGetValue(index);
- #elif defined(ANGLE_PLATFORM_POSIX)
- return pthread_getspecific(index);
-diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h
-index 4b25fbc..c40ae1a 100644
---- a/src/3rdparty/angle/src/common/tls.h
-+++ b/src/3rdparty/angle/src/common/tls.h
-@@ -11,7 +11,11 @@
-
- #include "common/platform.h"
-
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ typedef size_t TLSIndex;
-+# define TLS_OUT_OF_INDEXES (static_cast<TLSIndex>(-1))
-+# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES
-+#elif defined(ANGLE_PLATFORM_WINDOWS)
- typedef DWORD TLSIndex;
- # define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
- #elif defined(ANGLE_PLATFORM_POSIX)
-diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp
-index 405f119..4b8e325 100644
---- a/src/3rdparty/angle/src/common/utilities.cpp
-+++ b/src/3rdparty/angle/src/common/utilities.cpp
-@@ -9,6 +9,14 @@
- #include "common/utilities.h"
- #include "common/mathutil.h"
- #include "common/platform.h"
-+#if defined(ANGLE_PLATFORM_WINRT)
-+# include <locale>
-+# include <codecvt>
-+# include <wrl.h>
-+# include <windows.storage.h>
-+ using namespace Microsoft::WRL;
-+ using namespace ABI::Windows::Storage;
-+#endif
+diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
+index 0e63fa5..9b65c15 100644
+--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
++++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
+@@ -6,21 +6,25 @@
- #include <set>
+ // CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
-@@ -441,7 +449,48 @@ int VariableSortOrder(GLenum type)
+-#include <windows.graphics.display.h>
++#include <algorithm>
+ #include "common/winrt/CoreWindowNativeWindow.h"
+ using namespace ABI::Windows::Foundation::Collections;
- std::string getTempPath()
+ namespace rx
{
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ static std::string path;
-+
-+ while (path.empty())
-+ {
-+ ComPtr<IApplicationDataStatics> factory;
-+ Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData);
-+ HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory));
-+ if (FAILED(result))
-+ break;
+
-+ ComPtr<IApplicationData> applicationData;
-+ result = factory->get_Current(&applicationData);
-+ if (FAILED(result))
-+ break;
++typedef ITypedEventHandler<ABI::Windows::UI::Core::CoreWindow *, ABI::Windows::UI::Core::WindowSizeChangedEventArgs *> SizeChangedHandler;
+
-+ ComPtr<IStorageFolder> storageFolder;
-+ result = applicationData->get_LocalFolder(&storageFolder);
-+ if (FAILED(result))
-+ break;
+ CoreWindowNativeWindow::~CoreWindowNativeWindow()
+ {
+ unregisterForSizeChangeEvents();
+ }
+
+-bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
++bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+ {
+ ComPtr<IPropertySet> props = propertySet;
+ ComPtr<IInspectable> win = window;
++ ComPtr<IInspectable> displayInformation = display;
+ SIZE swapChainSize = {};
+ bool swapChainSizeSpecified = false;
+ HRESULT result = S_OK;
+@@ -47,6 +51,29 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
+
+ if (SUCCEEDED(result))
+ {
++ result = displayInformation.As(&mDisplayInformation);
++ }
+
-+ ComPtr<IStorageItem> localFolder;
-+ result = storageFolder.As(&localFolder);
-+ if (FAILED(result))
-+ break;
++ if (SUCCEEDED(result))
++ {
++#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
++ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation2> displayInformation2;
++ result = mDisplayInformation.As(&displayInformation2);
++ ASSERT(SUCCEEDED(result));
+
-+ HSTRING localFolderPath;
-+ result = localFolder->get_Path(&localFolderPath);
-+ if (FAILED(result))
-+ break;
++ result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
++ ASSERT(SUCCEEDED(result));
++#else
++ ABI::Windows::Graphics::Display::ResolutionScale resolutionScale;
++ result = mDisplayInformation->get_ResolutionScale(&resolutionScale);
++ ASSERT(SUCCEEDED(result));
+
-+ std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
-+ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
-+ if (path.empty())
-+ {
-+ UNREACHABLE();
-+ break;
-+ }
++ mScaleFactor = DOUBLE(resolutionScale) / 100.0;
++#endif
+ }
+
-+ return path;
-+#elif defined(ANGLE_PLATFORM_WINDOWS)
- char path[MAX_PATH];
- DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
- if (pathLen == 0)
-diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
-index aaebdb3..ba09631 100644
---- a/src/3rdparty/angle/src/libEGL/Display.cpp
-+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
-@@ -56,6 +56,10 @@ Display::Display(EGLNativeDisplayType displayId, EGLint displayType)
- mRequestedDisplayType(displayType),
- mRenderer(NULL)
++ if (SUCCEEDED(result))
++ {
+ // If a swapchain size is specfied, then the automatic resize
+ // behaviors implemented by the host should be disabled. The swapchain
+ // will be still be scaled when being rendered to fit the bounds
+@@ -60,7 +87,14 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
+ }
+ else
+ {
+- result = GetCoreWindowSizeInPixels(mCoreWindow, &mClientRect);
++ ABI::Windows::Foundation::Rect rect;
++ HRESULT result = mCoreWindow->get_Bounds(&rect);
++ if (SUCCEEDED(result))
++ {
++ LONG width = std::floor(rect.Width * mScaleFactor + 0.5);
++ LONG height = std::floor(rect.Height * mScaleFactor + 0.5);
++ mClientRect = { 0, 0, width, height };
++ }
+ }
+ }
+
+@@ -76,12 +110,8 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
+
+ bool CoreWindowNativeWindow::registerForSizeChangeEvents()
{
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (mDisplayId)
-+ mDisplayId->AddRef();
-+#endif
+- ComPtr<IWindowSizeChangedEventHandler> sizeChangedHandler;
+- HRESULT result = Microsoft::WRL::MakeAndInitialize<CoreWindowSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
+- if (SUCCEEDED(result))
+- {
+- result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+- }
++ HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
++ &mSizeChangedEventToken);
+
+ if (SUCCEEDED(result))
+ {
+@@ -126,7 +156,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
+ if (SUCCEEDED(result))
+ {
+
+-#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected
+ // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
+ // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
+ // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
+@@ -152,36 +182,19 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
+ return result;
}
- Display::~Display()
-@@ -68,6 +72,11 @@ Display::~Display()
+-HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize)
++// Basically, this shouldn't be used on Phone
++HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
+ {
+- ABI::Windows::Foundation::Rect bounds;
+- HRESULT result = coreWindow->get_Bounds(&bounds);
+- if (SUCCEEDED(result))
++ ABI::Windows::Foundation::Size size;
++ if (SUCCEEDED(e->get_Size(&size)))
{
- displays->erase(iter);
+- *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
++ SIZE windowSizeInPixels = {
++ std::floor(size.Width * mScaleFactor + 0.5),
++ std::floor(size.Height * mScaleFactor + 0.5)
++ };
++ setNewClientSize(windowSizeInPixels);
}
-+
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (mDisplayId)
-+ mDisplayId->Release();
-+#endif
+
+- return result;
+-}
+-
+-static float GetLogicalDpi()
+-{
+- ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
+- float dpi = 96.0f;
+-
+- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
+- {
+- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
+- {
+- return dpi;
+- }
+- }
+- return dpi;
+-}
+-
+-long ConvertDipsToPixels(float dips)
+-{
+- static const float dipsPerInch = 96.0f;
+- return lround((dips * GetLogicalDpi() / dipsPerInch));
++ return S_OK;
}
+ }
+diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
+index 0c6222d..1c55124 100644
+--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
++++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
+@@ -11,67 +11,29 @@
+
+ #include "common/winrt/InspectableNativeWindow.h"
+ #include <memory>
+-
+-typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler;
++#include <windows.graphics.display.h>
+
+ namespace rx
+ {
+-long ConvertDipsToPixels(float dips);
- bool Display::initialize()
-@@ -192,7 +201,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
+ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
+ {
+ public:
+ ~CoreWindowNativeWindow();
+- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
++ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
+ bool registerForSizeChangeEvents();
+ void unregisterForSizeChangeEvents();
+ HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+ private:
++ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
++
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
++ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
+ ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
+ };
--EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
-+EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
- {
- const Config *configuration = mConfigSet.get(config);
- EGLint postSubBufferSupported = EGL_FALSE;
-@@ -493,7 +502,7 @@ bool Display::isValidSurface(egl::Surface *surface)
- return mSurfaceSet.find(surface) != mSurfaceSet.end();
+-[uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)]
+-class CoreWindowSizeChangedHandler :
+- public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler>
+-{
+- public:
+- CoreWindowSizeChangedHandler() { }
+- HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
+- {
+- if (!host)
+- {
+- return E_INVALIDARG;
+- }
+-
+- mHost = host;
+- return S_OK;
+- }
+-
+- // IWindowSizeChangedEventHandler
+- IFACEMETHOD(Invoke)(ABI::Windows::UI::Core::ICoreWindow *sender, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *sizeChangedEventArgs)
+- {
+- std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
+- if (host)
+- {
+- ABI::Windows::Foundation::Size windowSize;
+- if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
+- {
+- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
+- host->setNewClientSize(windowSizeInPixels);
+- }
+- }
+-
+- return S_OK;
+- }
+-
+- private:
+- std::weak_ptr<InspectableNativeWindow> mHost;
+-};
+-
+-HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize);
}
--bool Display::hasExistingWindowSurface(HWND window)
-+bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
+ #endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
+diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
+index c062a48..0589f6d 100644
+--- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
++++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
+@@ -11,9 +11,9 @@
+
+ namespace rx
+ {
+-NativeWindow::NativeWindow(EGLNativeWindowType window)
++NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
++ : mWindow(window), mDisplay(display)
{
- for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+- mWindow = window;
+ }
+
+ bool NativeWindow::initialize()
+@@ -40,7 +40,7 @@ bool NativeWindow::initialize()
+ mImpl = std::make_shared<CoreWindowNativeWindow>();
+ if (mImpl)
+ {
+- return mImpl->initialize(mWindow, propertySet.Get());
++ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ }
+ }
+ else if (IsSwapChainPanel(mWindow, &swapChainPanel))
+@@ -48,7 +48,7 @@ bool NativeWindow::initialize()
+ mImpl = std::make_shared<SwapChainPanelNativeWindow>();
+ if (mImpl)
+ {
+- return mImpl->initialize(mWindow, propertySet.Get());
++ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ }
+ }
+ else
+diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
+index c625348..402941a 100644
+--- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
++++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
+@@ -32,13 +32,14 @@ class InspectableNativeWindow
+ mRequiresSwapChainScaling(false),
+ mClientRectChanged(false),
+ mClientRect({0,0,0,0}),
+- mNewClientRect({0,0,0,0})
++ mNewClientRect({0,0,0,0}),
++ mScaleFactor(1.0)
{
-diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
-index 250878f..73ba767 100644
---- a/src/3rdparty/angle/src/libEGL/Display.h
-+++ b/src/3rdparty/angle/src/libEGL/Display.h
-@@ -43,7 +43,7 @@ class Display
- bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
- bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
+ mSizeChangedEventToken.value = 0;
+ }
+ virtual ~InspectableNativeWindow(){}
+
+- virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
++ virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0;
+ virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
+ virtual bool registerForSizeChangeEvents() = 0;
+ virtual void unregisterForSizeChangeEvents() = 0;
+@@ -49,6 +50,7 @@ class InspectableNativeWindow
+ if (mClientRectChanged && mSupportsSwapChainResize)
+ {
+ mClientRect = mNewClientRect;
++ mClientRectChanged = false;
+ }
+
+ *rect = mClientRect;
+@@ -76,6 +78,7 @@ protected:
+ RECT mClientRect;
+ RECT mNewClientRect;
+ bool mClientRectChanged;
++ DOUBLE mScaleFactor;
-- EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
-+ EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
- EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
- EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+ EventRegistrationToken mSizeChangedEventToken;
+ };
+diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
+index 4e4fb6d..268dfbd 100644
+--- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
++++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
+@@ -18,7 +18,7 @@ SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
+ unregisterForSizeChangeEvents();
+ }
-@@ -54,7 +54,7 @@ class Display
- bool isValidConfig(EGLConfig config);
- bool isValidContext(gl::Context *context);
- bool isValidSurface(egl::Surface *surface);
-- bool hasExistingWindowSurface(HWND window);
-+ bool hasExistingWindowSurface(EGLNativeWindowType window);
+-bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
++bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+ {
+ ComPtr<IPropertySet> props = propertySet;
+ ComPtr<IInspectable> win = window;
+diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
+index e88f554..5bbf274 100644
+--- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
++++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
+@@ -18,7 +18,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
+ public:
+ ~SwapChainPanelNativeWindow();
- rx::Renderer *getRenderer() { return mRenderer; };
+- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
++ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
+ bool registerForSizeChangeEvents();
+ void unregisterForSizeChangeEvents();
+ HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
+index 378323a..b3ffcc8 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.h
++++ b/src/3rdparty/angle/src/libEGL/Display.h
+@@ -67,6 +67,7 @@ class Display
-@@ -65,6 +65,8 @@ class Display
const char *getExtensionString() const;
const char *getVendorString() const;
-
+ EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
-+
+
private:
DISALLOW_COPY_AND_ASSIGN(Display);
-
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
-index 13b0f20..fa79961 100644
+index 3414656..b664a85 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
-@@ -22,10 +22,20 @@
- #include "libEGL/main.h"
- #include "libEGL/Display.h"
-
-+#if defined(ANGLE_PLATFORM_WINRT)
-+# include "wrl.h"
-+# include "windows.graphics.display.h"
-+# include "windows.ui.core.h"
-+using namespace ABI::Windows::Graphics::Display;
-+using namespace ABI::Windows::Foundation;
-+using namespace ABI::Windows::UI::Core;
-+using namespace Microsoft::WRL;
-+#endif
-+
- namespace egl
+@@ -31,7 +31,7 @@ namespace egl
{
--Surface::Surface(Display *display, const Config *config, HWND window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
-+Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
- : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
+ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
+- : mDisplay(display), mConfig(config), mNativeWindow(window), mPostSubBufferSupported(postSubBufferSupported)
++ : mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported)
{
- mRenderer = mDisplay->getRenderer();
-@@ -43,6 +53,17 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint fix
+ //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
+ mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
+@@ -47,6 +47,8 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
+ mSwapInterval = -1;
+ mWidth = width;
mHeight = height;
++ mFixedWidth = mWidth;
++ mFixedHeight = mHeight;
setSwapInterval(1);
mFixedSize = fixedSize;
-+ mSwapFlags = rx::SWAP_NORMAL;
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (mWindow)
-+ mWindow->AddRef();
-+ mScaleFactor = 1.0;
-+ mSizeToken.value = 0;
-+ mDpiToken.value = 0;
-+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ mOrientationToken.value = 0;
-+# endif
-+#endif
- subclassWindow();
+@@ -54,7 +56,7 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
}
-@@ -64,16 +85,86 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
+
+ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
+- : mDisplay(display), mNativeWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
++ : mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
+ {
+ //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
+ mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
+@@ -71,6 +73,8 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
setSwapInterval(1);
// This constructor is for offscreen surfaces, which are always fixed-size.
mFixedSize = EGL_TRUE;
-+ mSwapFlags = rx::SWAP_NORMAL;
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ mScaleFactor = 1.0;
-+ mSizeToken.value = 0;
-+ mDpiToken.value = 0;
-+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ mOrientationToken.value = 0;
-+# endif
-+#endif
++ mFixedWidth = mWidth;
++ mFixedHeight = mHeight;
}
Surface::~Surface()
- {
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (mSizeToken.value) {
-+ ComPtr<ICoreWindow> coreWindow;
-+ HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
-+ ASSERT(SUCCEEDED(hr));
-+
-+ hr = coreWindow->remove_SizeChanged(mSizeToken);
-+ ASSERT(SUCCEEDED(hr));
-+ }
-+ if (mDpiToken.value) {
-+ ComPtr<IDisplayInformation> displayInformation;
-+ HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
-+ ASSERT(SUCCEEDED(hr));
-+
-+ hr = displayInformation->remove_DpiChanged(mDpiToken);
-+ ASSERT(SUCCEEDED(hr));
-+ }
-+# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
-+ if (mOrientationToken.value) {
-+ ComPtr<IDisplayInformation> displayInformation;
-+ HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
-+ ASSERT(SUCCEEDED(hr));
-+
-+ hr = displayInformation->remove_OrientationChanged(mOrientationToken);
-+ ASSERT(SUCCEEDED(hr));
-+ }
-+# endif
-+#endif
- unsubclassWindow();
- release();
- }
+@@ -157,10 +161,13 @@ Error Surface::resetSwapChain()
- bool Surface::initialize()
+ Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
{
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (!mFixedSize) {
-+ HRESULT hr;
-+ ComPtr<IDisplayInformation> displayInformation;
-+ hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
-+ ASSERT(SUCCEEDED(hr));
-+ onDpiChanged(displayInformation.Get(), 0);
-+ hr = displayInformation->add_DpiChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onDpiChanged).Get(),
-+ &mDpiToken);
-+ ASSERT(SUCCEEDED(hr));
-+
-+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ onOrientationChanged(displayInformation.Get(), 0);
-+ hr = displayInformation->add_OrientationChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onOrientationChanged).Get(),
-+ &mOrientationToken);
-+ ASSERT(SUCCEEDED(hr));
-+# endif
-+
-+ ComPtr<ICoreWindow> coreWindow;
-+ hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
-+ ASSERT(SUCCEEDED(hr));
-+
-+ Rect rect;
-+ hr = coreWindow->get_Bounds(&rect);
-+ ASSERT(SUCCEEDED(hr));
-+ mWidth = rect.Width * mScaleFactor;
-+ mHeight = rect.Height * mScaleFactor;
-+ hr = coreWindow->add_SizeChanged(Callback<ITypedEventHandler<CoreWindow *, WindowSizeChangedEventArgs *>>(this, &Surface::onSizeChanged).Get(),
-+ &mSizeToken);
-+ ASSERT(SUCCEEDED(hr));
-+ }
-+#endif
-+
- if (!resetSwapChain())
- return false;
+- ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
-@@ -90,6 +181,11 @@ void Surface::release()
- mTexture->releaseTexImage();
- mTexture = NULL;
- }
-+
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (mWindow)
-+ mWindow->Release();
+- EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight));
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
++ backbufferWidth = std::max(1, backbufferWidth);
++ backbufferHeight = std::max(1, backbufferHeight);
+#endif
- }
-
- bool Surface::resetSwapChain()
-@@ -99,6 +195,7 @@ bool Surface::resetSwapChain()
- int width;
- int height;
++ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
-+#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mFixedSize)
+ if (status == EGL_CONTEXT_LOST)
{
- RECT windowRect;
-@@ -114,6 +211,7 @@ bool Surface::resetSwapChain()
- height = windowRect.bottom - windowRect.top;
+@@ -209,14 +216,14 @@ Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ return Error(EGL_SUCCESS);
}
- else
-+#endif
+
+- if (x + width > mWidth)
++ if (x + width > abs(mWidth))
{
- // non-window surface - size is determined at creation
- width = mWidth;
-@@ -207,7 +305,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
- return true;
+- width = mWidth - x;
++ width = abs(mWidth) - x;
}
-- EGLint status = mSwapChain->swapRect(x, y, width, height);
-+ EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags);
-
- if (status == EGL_CONTEXT_LOST)
+- if (y + height > mHeight)
++ if (y + height > abs(mHeight))
{
-@@ -224,7 +322,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
- return true;
- }
-
--HWND Surface::getWindowHandle()
-+EGLNativeWindowType Surface::getWindowHandle()
- {
- return mWindow;
- }
-@@ -233,6 +331,7 @@ HWND Surface::getWindowHandle()
- #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
- #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
-
-+#if !defined(ANGLE_PLATFORM_WINRT)
- static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
- {
- if (message == WM_SIZE)
-@@ -246,9 +345,11 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
- WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
- return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
- }
-+#endif
+- height = mHeight - y;
++ height = abs(mHeight) - y;
+ }
- void Surface::subclassWindow()
- {
-+#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mWindow)
- {
- return;
-@@ -272,10 +373,14 @@ void Surface::subclassWindow()
- SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
- SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
- mWindowSubclassed = true;
-+#else
-+ mWindowSubclassed = false;
-+#endif
- }
+ if (width == 0 || height == 0)
+@@ -224,6 +231,9 @@ Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ return Error(EGL_SUCCESS);
+ }
- void Surface::unsubclassWindow()
- {
-+#if !defined(ANGLE_PLATFORM_WINRT)
- if(!mWindowSubclassed)
- {
- return;
-@@ -299,16 +404,18 @@ void Surface::unsubclassWindow()
- RemoveProp(mWindow, kSurfaceProperty);
- RemoveProp(mWindow, kParentWndProc);
- mWindowSubclassed = false;
-+#endif
- }
++ ASSERT(width > 0);
++ ASSERT(height > 0);
++
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
- bool Surface::checkForOutOfDateSwapChain()
- {
-- RECT client;
- int clientWidth = getWidth();
- int clientHeight = getHeight();
- bool sizeDirty = false;
-+#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mFixedSize && !IsIconic(getWindowHandle()))
- {
-+ RECT client;
- // The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized
- // because that's not a useful size to render to.
- if (!GetClientRect(getWindowHandle(), &client))
-@@ -322,6 +429,7 @@ bool Surface::checkForOutOfDateSwapChain()
- clientHeight = client.bottom - client.top;
+ if (status == EGL_CONTEXT_LOST)
+@@ -352,6 +362,13 @@ bool Surface::checkForOutOfDateSwapChain()
sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
}
-+#endif
++ if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
++ {
++ clientWidth = mFixedWidth;
++ clientHeight = mFixedHeight;
++ sizeDirty = true;
++ }
++
bool wasDirty = (mSwapIntervalDirty || sizeDirty);
-@@ -446,4 +554,73 @@ EGLenum Surface::getFormat() const
+ if (mSwapIntervalDirty)
+@@ -378,7 +395,7 @@ bool Surface::checkForOutOfDateSwapChain()
+
+ Error Surface::swap()
{
- return mConfig->mRenderTargetFormat;
+- return swapRect(0, 0, mWidth, mHeight);
++ return swapRect(0, 0, abs(mWidth), abs(mHeight));
}
-+
-+#if defined(ANGLE_PLATFORM_WINRT)
-+
-+HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
+
+ Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+@@ -471,6 +488,16 @@ EGLint Surface::isFixedSize() const
+ return mFixedSize;
+ }
+
++void Surface::setFixedWidth(EGLint width)
+{
-+ HRESULT hr;
-+ Size size;
-+ hr = args->get_Size(&size);
-+ ASSERT(SUCCEEDED(hr));
-+
-+ resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5),
-+ std::floor(size.Height * mScaleFactor + 0.5));
-+
-+ if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
-+ {
-+ glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
-+ }
-+
-+ return S_OK;
++ mFixedWidth = width;
+}
+
-+HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *)
++void Surface::setFixedHeight(EGLint height)
+{
-+ HRESULT hr;
-+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ ComPtr<IDisplayInformation2> displayInformation2;
-+ hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf());
-+ ASSERT(SUCCEEDED(hr));
-+
-+ hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
-+ ASSERT(SUCCEEDED(hr));
-+# else
-+ ResolutionScale resolutionScale;
-+ hr = displayInformation->get_ResolutionScale(&resolutionScale);
-+ ASSERT(SUCCEEDED(hr));
-+
-+ mScaleFactor = double(resolutionScale) / 100.0;
-+# endif
-+ return S_OK;
++ mFixedHeight = height;
+}
+
-+# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
-+HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *)
-+{
-+ HRESULT hr;
-+ DisplayOrientations orientation;
-+ hr = displayInformation->get_CurrentOrientation(&orientation);
-+ ASSERT(SUCCEEDED(hr));
-+ switch (orientation) {
-+ default:
-+ case DisplayOrientations_Portrait:
-+ mSwapFlags = rx::SWAP_NORMAL;
-+ break;
-+ case DisplayOrientations_Landscape:
-+ mSwapFlags = rx::SWAP_ROTATE_90;
-+ break;
-+ case DisplayOrientations_LandscapeFlipped:
-+ mSwapFlags = rx::SWAP_ROTATE_270;
-+ break;
-+ case DisplayOrientations_PortraitFlipped:
-+ mSwapFlags = rx::SWAP_ROTATE_180;
-+ break;
-+ }
-+ return S_OK;
-+}
-+# endif
-+
-+#endif
-+
- }
+ EGLenum Surface::getFormat() const
+ {
+ return mConfig->mRenderTargetFormat;
diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
-index 24c66b7..ebffce8fe 100644
+index 662fe21..46382d0 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ b/src/3rdparty/angle/src/libEGL/Surface.h
-@@ -15,6 +15,20 @@
-
- #include "common/angleutils.h"
-
-+#if defined(ANGLE_PLATFORM_WINRT)
-+#include <EventToken.h>
-+namespace ABI { namespace Windows {
-+ namespace UI { namespace Core {
-+ struct ICoreWindow;
-+ struct IWindowSizeChangedEventArgs;
-+ } }
-+ namespace Graphics { namespace Display {
-+ struct IDisplayInformation;
-+ } }
-+} }
-+struct IInspectable;
-+#endif
-+
- namespace gl
- {
- class Texture2D;
-@@ -33,7 +47,7 @@ class Config;
- class Surface
- {
- public:
-- Surface(Display *display, const egl::Config *config, HWND window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported);
-+ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported);
- Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
-
- virtual ~Surface();
-@@ -42,7 +56,7 @@ class Surface
- void release();
- bool resetSwapChain();
-
-- HWND getWindowHandle();
-+ EGLNativeWindowType getWindowHandle();
- bool swap();
- bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
-
-@@ -71,6 +85,14 @@ class Surface
- private:
- DISALLOW_COPY_AND_ASSIGN(Surface);
+@@ -70,6 +70,8 @@ class Surface
+ virtual gl::Texture2D *getBoundTexture() const;
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
-+ HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-+# endif
-+#endif
-+
- Display *const mDisplay;
- rx::Renderer *mRenderer;
+ EGLint isFixedSize() const;
++ void setFixedWidth(EGLint width);
++ void setFixedHeight(EGLint height);
-@@ -83,7 +105,7 @@ private:
- bool resetSwapChain(int backbufferWidth, int backbufferHeight);
- bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
-
-- const HWND mWindow; // Window that the surface is created for.
-+ const EGLNativeWindowType mWindow; // Window that the surface is created for.
- bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Surface);
+@@ -91,6 +93,8 @@ class Surface
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
-@@ -104,9 +126,18 @@ private:
- EGLint mSwapInterval;
- EGLint mPostSubBufferSupported;
- EGLint mFixedSize;
-+ EGLint mSwapFlags;
-
- bool mSwapIntervalDirty;
- gl::Texture2D *mTexture;
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ double mScaleFactor;
-+ EventRegistrationToken mSizeToken;
-+ EventRegistrationToken mDpiToken;
-+# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ EventRegistrationToken mOrientationToken;
-+# endif
-+#endif
- };
- }
-
+ EGLint mWidth; // Width of surface
++ EGLint mFixedHeight; // Pending height of the surface
++ EGLint mFixedWidth; // Pending width of the surface
+ // EGLint horizontalResolution; // Horizontal dot pitch
+ // EGLint verticalResolution; // Vertical dot pitch
+ // EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-index 7ce2b93..7ea11c5 100644
+index 6110698..dc20d85 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-@@ -13,6 +13,7 @@
-
- #include "common/debug.h"
- #include "common/version.h"
-+#include "common/platform.h"
- #include "libGLESv2/Context.h"
- #include "libGLESv2/Texture.h"
- #include "libGLESv2/main.h"
-@@ -120,12 +121,13 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
- }
-
- EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
--
-+#if !defined(ANGLE_PLATFORM_WINRT)
- // Validate the display device context
- if (WindowFromDC(displayId) == NULL)
- {
- return egl::success(EGL_NO_DISPLAY);
+@@ -706,6 +706,26 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
+ return EGL_FALSE;
}
-+#endif
-
- EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
- if (attrib_list)
-@@ -327,14 +329,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
- return EGL_NO_SURFACE;
- }
-
-+#if !defined(ANGLE_PLATFORM_WINRT)
- HWND window = (HWND)win;
-
- if (!IsWindow(window))
- {
- return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
- }
-+#endif
-
-- return display->createWindowSurface(window, config, attrib_list);
-+ return display->createWindowSurface(win, config, attrib_list);
- }
-
- EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
-diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
-index 8a1baef..e74737e 100644
---- a/src/3rdparty/angle/src/libEGL/main.cpp
-+++ b/src/3rdparty/angle/src/libEGL/main.cpp
-@@ -11,6 +11,9 @@
- #include "common/debug.h"
- #include "common/tls.h"
-
-+#if defined(ANGLE_PLATFORM_WINRT)
-+__declspec(thread)
-+#endif
- static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
- namespace egl
-@@ -18,6 +21,12 @@ namespace egl
-
- Current *AllocateCurrent()
- {
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (currentTLS == TLS_OUT_OF_INDEXES)
-+ {
-+ currentTLS = CreateTLSIndex();
-+ }
-+#endif
- ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
-@@ -42,6 +51,12 @@ Current *AllocateCurrent()
-
- void DeallocateCurrent()
- {
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (currentTLS == TLS_OUT_OF_INDEXES)
-+ {
-+ return;
-+ }
-+#endif
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
- SafeDelete(current);
- SetTLSValue(currentTLS, NULL);
-@@ -72,6 +87,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
- }
- #endif
-
-+#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
-+ return DisableThreadLibraryCalls(instance);
-+#endif
-+
- currentTLS = CreateTLSIndex();
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
-@@ -86,7 +105,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
- break;
- case DLL_THREAD_DETACH:
- {
-+#if !defined(ANGLE_PLATFORM_WINRT)
- egl::DeallocateCurrent();
-+#endif
- }
- break;
- case DLL_PROCESS_DETACH:
-diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
-index 1c577bc..51447e2 100644
---- a/src/3rdparty/angle/src/libGLESv2/main.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
-@@ -11,6 +11,9 @@
-
- #include "common/tls.h"
-
-+#if defined(ANGLE_PLATFORM_WINRT)
-+__declspec(thread)
-+#endif
- static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
-
- namespace gl
-@@ -18,6 +21,12 @@ namespace gl
-
- Current *AllocateCurrent()
- {
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (currentTLS == TLS_OUT_OF_INDEXES)
-+ {
-+ currentTLS = CreateTLSIndex();
-+ }
-+#endif
- ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
-@@ -39,6 +48,12 @@ Current *AllocateCurrent()
-
- void DeallocateCurrent()
- {
-+#if defined(ANGLE_PLATFORM_WINRT)
-+ if (currentTLS == TLS_OUT_OF_INDEXES)
++ switch (attribute)
+ {
-+ return;
++ case EGL_WIDTH:
++ if (!eglSurface->isFixedSize() || !value) {
++ recordError(egl::Error(EGL_BAD_PARAMETER));
++ return EGL_FALSE;
++ }
++ eglSurface->setFixedWidth(value);
++ return EGL_TRUE;
++ case EGL_HEIGHT:
++ if (!eglSurface->isFixedSize() || !value) {
++ recordError(egl::Error(EGL_BAD_PARAMETER));
++ return EGL_FALSE;
++ }
++ eglSurface->setFixedHeight(value);
++ return EGL_TRUE;
++ default:
++ break;
+ }
-+#endif
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
- SafeDelete(current);
- SetTLSValue(currentTLS, NULL);
-@@ -54,6 +69,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
- {
- case DLL_PROCESS_ATTACH:
- {
-+#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
-+ return DisableThreadLibraryCalls(instance);
-+#endif
- currentTLS = CreateTLSIndex();
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
-@@ -73,8 +91,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
- break;
- case DLL_PROCESS_DETACH:
- {
-+#if !defined(ANGLE_PLATFORM_WINRT)
- gl::DeallocateCurrent();
- DestroyTLSIndex(currentTLS);
-+#endif
- }
- break;
- default:
-diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h
-index 684c302..c30ad33 100644
---- a/src/3rdparty/angle/src/libGLESv2/main.h
-+++ b/src/3rdparty/angle/src/libGLESv2/main.h
-@@ -14,6 +14,10 @@
- #include <GLES2/gl2.h>
- #include <EGL/egl.h>
-
-+#ifndef Sleep
-+#define Sleep(ms) WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE)
-+#endif
+
- namespace egl
- {
- class Display;
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
-index 7adbea2..b224974 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
-@@ -107,7 +107,7 @@ class Renderer
-
- virtual void sync(bool block) = 0;
-
-- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
-+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
-
- virtual gl::Error generateSwizzle(gl::Texture *texture) = 0;
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
-index 12be9b3..1ec702f 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
-@@ -15,14 +15,23 @@
-
- #include <GLES2/gl2.h>
- #include <EGL/egl.h>
-+#include <EGL/eglplatform.h>
+ UNIMPLEMENTED(); // FIXME
- namespace rx
- {
-
-+enum SwapFlags
-+{
-+ SWAP_NORMAL = 0,
-+ SWAP_ROTATE_90 = 1,
-+ SWAP_ROTATE_270 = 2,
-+ SWAP_ROTATE_180 = SWAP_ROTATE_90|SWAP_ROTATE_270,
-+};
-+
- class SwapChain
- {
- public:
-- SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
-+ SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
- : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
- {
- }
-@@ -31,13 +40,13 @@ class SwapChain
-
- virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
- virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
-- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
-+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) = 0;
- virtual void recreate() = 0;
-
- virtual HANDLE getShareHandle() {return mShareHandle;};
-
- protected:
-- const HWND mWindow; // Window that the surface is created for.
-+ const EGLNativeWindowType mWindow; // Window that the surface is created for.
- const GLenum mBackBufferFormat;
- const GLenum mDepthBufferFormat;
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index 5715d5f..d013197 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -9,6 +9,7 @@
- #include "libGLESv2/main.h"
-
- #include "common/utilities.h"
-+#include "common/platform.h"
-
- #if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL)
-
-@@ -45,11 +46,7 @@ HLSLCompiler::~HLSLCompiler()
-
- bool HLSLCompiler::initialize()
- {
--<<<<<<< HEAD
-- TRACE_EVENT0("gpu", "initializeCompiler");
--=======
- #if !defined(ANGLE_PLATFORM_WINRT)
-->>>>>>> 429814a... ANGLE: remove event tracing
- #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
- // Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
- static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
-@@ -94,7 +91,9 @@ bool HLSLCompiler::initialize()
-
- mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
- ASSERT(mD3DCompileFunc);
--
-+#else
-+ mD3DCompileFunc = reinterpret_cast<CompileFuncPtr>(&D3DCompile);
-+#endif
- return mD3DCompileFunc != NULL;
- }
-
-@@ -111,7 +110,9 @@ void HLSLCompiler::release()
- ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile,
- const UINT optimizationFlags[], const char *flagNames[], int attempts) const
- {
-+#if !defined(ANGLE_PLATFORM_WINRT)
- ASSERT(mD3DCompilerModule && mD3DCompileFunc);
-+#endif
-
- if (!hlsl)
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index ed880c3..0bb7489 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -6,6 +6,7 @@
-
- // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
-
-+#include "common/platform.h"
- #include "libGLESv2/main.h"
- #include "libGLESv2/Buffer.h"
- #include "libGLESv2/FramebufferAttachment.h"
-@@ -135,6 +136,7 @@ EGLint Renderer11::initialize()
- return EGL_NOT_INITIALIZED;
- }
-
-+#if !defined(ANGLE_PLATFORM_WINRT)
- mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
- mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
-
-@@ -153,6 +155,7 @@ EGLint Renderer11::initialize()
- ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
- return EGL_NOT_INITIALIZED;
- }
-+#endif
-
- D3D_FEATURE_LEVEL featureLevels[] =
- {
-@@ -207,7 +210,7 @@ EGLint Renderer11::initialize()
- }
- }
-
--#if !ANGLE_SKIP_DXGI_1_2_CHECK
-+#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT)
- // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
- // The easiest way to check is to query for a IDXGIDevice2.
- bool requireDXGI1_2 = false;
-@@ -237,8 +240,12 @@ EGLint Renderer11::initialize()
- }
- #endif
-
-+#if !defined(ANGLE_PLATFORM_WINRT)
- IDXGIDevice *dxgiDevice = NULL;
-- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
-+#else
-+ IDXGIDevice1 *dxgiDevice = NULL;
-+#endif
-+ result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
-
- if (FAILED(result))
- {
-@@ -408,7 +415,7 @@ void Renderer11::sync(bool block)
- }
- }
-
--SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
-+SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
- {
- return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
- }
+ recordError(egl::Error(EGL_SUCCESS));
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-index d309f14..b86f5e5 100644
+index 1655f1d..c789cae 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-@@ -57,7 +57,7 @@ class Renderer11 : public Renderer
-
- virtual void sync(bool block);
-
-- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
-+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
-
- virtual gl::Error generateSwizzle(gl::Texture *texture);
- virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
-@@ -222,7 +222,7 @@ class Renderer11 : public Renderer
+@@ -231,7 +231,7 @@ class Renderer11 : public RendererD3D
HMODULE mD3d11Module;
HMODULE mDxgiModule;
- HDC mDc;
+ EGLNativeDisplayType mDc;
- EGLint mRequestedDisplay;
+ std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
+ D3D_DRIVER_TYPE mDriverType;
- HLSLCompiler mCompiler;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-index 50dae4e..787c511 100644
+index 834b7bd..52c8a81 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-@@ -6,6 +6,7 @@
-
- // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
-
-+#include "common/platform.h"
- #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
- #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
- #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-@@ -18,7 +19,7 @@
- namespace rx
- {
-
--SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
-+SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
- GLenum backBufferFormat, GLenum depthBufferFormat)
- : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
- {
-@@ -38,6 +39,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+@@ -42,6 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE
mPassThroughPS = NULL;
mWidth = -1;
mHeight = -1;
-+ mViewportWidth = -1;
-+ mViewportHeight = -1;
++ mRotateL = false;
++ mRotateR = false;
mSwapInterval = 0;
mAppCreatedShareHandle = mShareHandle != NULL;
mPassThroughResourcesInit = false;
-@@ -92,6 +95,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- ASSERT(backbufferHeight >= 1);
+@@ -92,10 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ ASSERT(device != NULL);
+
+ // D3D11 does not allow zero size textures
+- ASSERT(backbufferWidth >= 1);
+- ASSERT(backbufferHeight >= 1);
++ ASSERT(backbufferWidth != 0);
++ ASSERT(backbufferHeight != 0);
// Preserve the render target content
-+#if !defined(ANGLE_PLATFORM_WINRT)
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
if (previousOffscreenTexture)
{
-@@ -99,6 +103,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+@@ -103,6 +106,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
}
const int previousWidth = mWidth;
const int previousHeight = mHeight;
@@ -1128,112 +675,107 @@ index 50dae4e..787c511 100644
releaseOffscreenTexture();
-@@ -281,7 +286,12 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
-
+@@ -136,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+ mOffscreenTexture->GetDesc(&offscreenTextureDesc);
+
+- if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
+- offscreenTextureDesc.Height != (UINT)backbufferHeight ||
++ if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) ||
++ offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) ||
+ offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
+ offscreenTextureDesc.MipLevels != 1 ||
+ offscreenTextureDesc.ArraySize != 1)
+@@ -152,8 +156,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
+
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+- offscreenTextureDesc.Width = backbufferWidth;
+- offscreenTextureDesc.Height = backbufferHeight;
++ offscreenTextureDesc.Width = abs(backbufferWidth);
++ offscreenTextureDesc.Height = abs(backbufferHeight);
+ offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
+ offscreenTextureDesc.MipLevels = 1;
+ offscreenTextureDesc.ArraySize = 1;
+@@ -233,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
+- depthStencilTextureDesc.Width = backbufferWidth;
+- depthStencilTextureDesc.Height = backbufferHeight;
++ depthStencilTextureDesc.Width = abs(backbufferWidth);
++ depthStencilTextureDesc.Height = abs(backbufferHeight);
+ depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
+ depthStencilTextureDesc.MipLevels = 1;
+ depthStencilTextureDesc.ArraySize = 1;
+@@ -286,6 +290,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
mWidth = backbufferWidth;
mHeight = backbufferHeight;
-+#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
-+ mViewportWidth = backbufferWidth;
-+ mViewportHeight = backbufferHeight;
-+#endif
-+#if !defined(ANGLE_PLATFORM_WINRT)
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
if (previousOffscreenTexture != NULL)
{
D3D11_BOX sourceBox = {0};
-@@ -300,9 +310,10 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
-
- if (mSwapChain)
- {
-- swapRect(0, 0, mWidth, mHeight);
-+ swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL);
+@@ -307,6 +312,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ swapRect(0, 0, mWidth, mHeight);
}
}
+#endif
return EGL_SUCCESS;
}
-@@ -329,8 +340,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
- SafeRelease(mBackBufferRTView);
+@@ -320,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ return EGL_BAD_ACCESS;
+ }
- // Resize swap chain
-+ HRESULT result;
-+#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is
-+#if !defined(ANGLE_PLATFORM_WINRT)
-+ const int bufferCount = 1;
-+#else
-+ const int bufferCount = 2;
++ // Windows Phone works around the rotation limitation by using negative values for the swap chain size
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape
++ mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape
++ backbufferWidth = abs(backbufferWidth);
++ backbufferHeight = abs(backbufferHeight);
+#endif
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
-- HRESULT result = mSwapChain->ResizeBuffers(1, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
-+ result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
-
- if (FAILED(result))
++
+ // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
+- if (backbufferWidth < 1 || backbufferHeight < 1)
++ if (backbufferWidth == 0 || backbufferHeight == 0)
{
-@@ -346,6 +364,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
- return EGL_BAD_ALLOC;
- }
+ return EGL_SUCCESS;
}
-+#endif
-
- result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
- ASSERT(SUCCEEDED(result));
-@@ -399,6 +418,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+@@ -329,6 +343,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ // Can only call resize if we have already created our swap buffer and resources
+ ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
- IDXGIFactory *factory = mRenderer->getDxgiFactory();
-
-+#if !defined(ANGLE_PLATFORM_WINRT)
- DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
- swapChainDesc.BufferDesc.Width = backbufferWidth;
- swapChainDesc.BufferDesc.Height = backbufferHeight;
-@@ -417,7 +437,37 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
- swapChainDesc.Flags = 0;
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone
+ SafeRelease(mBackBufferTexture);
+ SafeRelease(mBackBufferRTView);
- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
-+#else
-+ IDXGIFactory2 *factory2;
-+ HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2));
-+ ASSERT(SUCCEEDED(result));
-+
-+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
-+ swapChainDesc.Width = 0;
-+ swapChainDesc.Height = 0;
-+ swapChainDesc.Format = backbufferFormatInfo.texFormat;
-+ swapChainDesc.SampleDesc.Count = 1;
-+ swapChainDesc.SampleDesc.Quality = 0;
-+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-+ swapChainDesc.Stereo = FALSE;
-+ swapChainDesc.Flags = 0;
-+#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
-+ swapChainDesc.Scaling = DXGI_SCALING_NONE;
-+ swapChainDesc.BufferCount = 2;
-+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
-+#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ swapChainDesc.BufferCount = 1;
-+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+@@ -366,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ {
+ d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
+ }
+#endif
-+ IDXGISwapChain1 *swapChain;
-+ result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
-+ mSwapChain = swapChain;
-+ HRESULT hr = swapChain->GetDesc1(&swapChainDesc);
-+ ASSERT(SUCCEEDED(hr));
-+ mViewportWidth = swapChainDesc.Width;
-+ mViewportHeight = swapChainDesc.Height;
-+#endif
- if (FAILED(result))
- {
- ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
-@@ -513,7 +563,7 @@ void SwapChain11::initPassThroughResources()
+ return resetOffscreenTexture(backbufferWidth, backbufferHeight);
}
-
- // parameters should be validated/clamped by caller
--EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
-+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags)
- {
- if (!mSwapChain)
- {
-@@ -544,10 +594,13 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+@@ -512,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+- // Set vertices
+- D3D11_MAPPED_SUBRESOURCE mappedResource;
+- HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+- if (FAILED(result))
+- {
+- return EGL_BAD_ACCESS;
+- }
+-
+- d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+-
+ // Create a quad in homogeneous coordinates
+ float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
+ float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
+@@ -533,10 +539,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
float u2 = (x + width) / float(mWidth);
float v2 = (y + height) / float(mHeight);
@@ -1241,8 +783,18 @@ index 50dae4e..787c511 100644
- d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
- d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
- d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
-+ const int rotateL = flags & SWAP_ROTATE_90;
-+ const int rotateR = flags & SWAP_ROTATE_270;
++ const bool rotateL = mRotateL;
++ const bool rotateR = mRotateR;
++
++ // Set vertices
++ D3D11_MAPPED_SUBRESOURCE mappedResource;
++ HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
++ if (FAILED(result))
++ {
++ return EGL_BAD_ACCESS;
++ }
++
++ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+
+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
@@ -1251,72 +803,35 @@ index 50dae4e..787c511 100644
deviceContext->Unmap(mQuadVB, 0);
-@@ -577,8 +630,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+@@ -564,10 +583,11 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+
+ // Set the viewport
D3D11_VIEWPORT viewport;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
+- viewport.TopLeftX = 0;
+- viewport.TopLeftY = 0;
- viewport.Width = mWidth;
- viewport.Height = mHeight;
-+ viewport.Width = mViewportWidth;
-+ viewport.Height = mViewportHeight;
++ viewport.TopLeftX = 0.0f;
++ viewport.TopLeftY = 0.0f;
++ const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR);
++ viewport.Width = FLOAT(invertViewport ? mHeight : mWidth);
++ viewport.Height = FLOAT(invertViewport ? mWidth : mHeight);
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
-index fb0afd7..b30b785 100644
+index 22401d8..77509ed 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
-@@ -19,13 +19,13 @@ class Renderer11;
- class SwapChain11 : public SwapChain
- {
- public:
-- SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
-+ SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
- GLenum backBufferFormat, GLenum depthBufferFormat);
- virtual ~SwapChain11();
-
- EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
- virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
-- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
-+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags);
- virtual void recreate();
-
- virtual ID3D11Texture2D *getOffscreenTexture();
@@ -52,6 +52,8 @@ class SwapChain11 : public SwapChain
Renderer11 *mRenderer;
EGLint mHeight;
EGLint mWidth;
-+ EGLint mViewportWidth;
-+ EGLint mViewportHeight;
++ bool mRotateL;
++ bool mRotateR;
bool mAppCreatedShareHandle;
unsigned int mSwapInterval;
bool mPassThroughResourcesInit;
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
-index f702b79..0aeaabb 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
-@@ -238,7 +238,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
- }
-
- // parameters should be validated/clamped by caller
--EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
-+EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint)
- {
- if (!mSwapChain)
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
-index 16a62bd..4d756f8 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
-@@ -25,7 +25,7 @@ class SwapChain9 : public SwapChain
-
- EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
- virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
-- virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
-+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint);
- virtual void recreate();
-
- virtual IDirect3DSurface9 *getRenderTarget();
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch b/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
index 297d5adc84..dd2768cf3e 100644
--- a/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
+++ b/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
@@ -1,6 +1,6 @@
-From 0e8aa60332e17f284804dc1b89a9db5795a92ecb Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Wed, 17 Sep 2014 21:17:39 +0300
+From 829bf86c57357d3c8ec598b92fcfdb1849e84075 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Tue, 11 Nov 2014 17:11:54 +0200
Subject: [PATCH 10/16] ANGLE: Enable D3D11 for feature level 9 cards
Enable use of ANGLE on lower-end hardware, such as Surface RT and
@@ -8,23 +8,32 @@ Windows Phone 8.
Change-Id: Ice536802e4eedc1d264abd0dd65960638fce59e4
---
- src/3rdparty/angle/src/libGLESv2/angletypes.cpp | 4 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 73 +++----
+ src/3rdparty/angle/src/libGLESv2/angletypes.cpp | 6 +-
+ .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 69 ++++---
.../src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 4 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 8 +-
- .../renderer/d3d/d3d11/PixelTransfer11.cpp | 7 +-
- .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 209 +++++++++++++--------
+ .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 7 +-
+ .../renderer/d3d/d3d11/PixelTransfer11.cpp | 9 +-
+ .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 226 +++++++++++++--------
.../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 1 +
- .../renderer/d3d/d3d11/TextureStorage11.cpp | 2 +-
+ .../renderer/d3d/d3d11/TextureStorage11.cpp | 4 +-
.../libGLESv2/renderer/d3d/d3d11/formatutils11.cpp | 4 +-
.../renderer/d3d/d3d11/renderer11_utils.cpp | 2 +-
- 10 files changed, 190 insertions(+), 124 deletions(-)
+ 10 files changed, 208 insertions(+), 124 deletions(-)
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
-index 06618d5..bb6425d 100644
+index 6fd02e0..5a0cfc5 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
-@@ -22,8 +22,8 @@ SamplerState::SamplerState()
+@@ -12,6 +12,8 @@
+ #include "libGLESv2/State.h"
+ #include "libGLESv2/VertexArray.h"
+
++#include <float.h>
++
+ namespace gl
+ {
+
+@@ -24,8 +26,8 @@ SamplerState::SamplerState()
maxAnisotropy(1.0f),
baseLevel(0),
maxLevel(1000),
@@ -36,28 +45,28 @@ index 06618d5..bb6425d 100644
compareFunc(GL_LEQUAL),
swizzleRed(GL_RED),
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-index 72820a4..d43e65e 100644
+index 91e7552..06aea9b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-@@ -209,7 +209,7 @@ Blit11::Blit11(rx::Renderer11 *renderer)
+@@ -209,7 +209,7 @@ Blit11::Blit11(Renderer11 *renderer)
pointSamplerDesc.BorderColor[2] = 0.0f;
pointSamplerDesc.BorderColor[3] = 0.0f;
pointSamplerDesc.MinLOD = 0.0f;
- pointSamplerDesc.MaxLOD = 0.0f;
-+ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f;
++ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
ASSERT(SUCCEEDED(result));
-@@ -228,7 +228,7 @@ Blit11::Blit11(rx::Renderer11 *renderer)
+@@ -228,7 +228,7 @@ Blit11::Blit11(Renderer11 *renderer)
linearSamplerDesc.BorderColor[2] = 0.0f;
linearSamplerDesc.BorderColor[3] = 0.0f;
linearSamplerDesc.MinLOD = 0.0f;
- linearSamplerDesc.MaxLOD = 0.0f;
-+ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? FLT_MAX : 0.0f;
++ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
ASSERT(SUCCEEDED(result));
-@@ -290,28 +290,31 @@ Blit11::Blit11(rx::Renderer11 *renderer)
+@@ -290,28 +290,31 @@ Blit11::Blit11(Renderer11 *renderer)
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader");
@@ -76,14 +85,14 @@ index 72820a4..d43e65e 100644
- result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout");
+-
+- result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
+- ASSERT(SUCCEEDED(result));
+- d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
+ result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader");
-- result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
-- ASSERT(SUCCEEDED(result));
-- d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
--
- result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader");
@@ -109,7 +118,7 @@ index 72820a4..d43e65e 100644
buildShaderMap();
-@@ -972,40 +975,44 @@ void Blit11::buildShaderMap()
+@@ -970,22 +973,27 @@ void Blit11::buildShaderMap()
ID3D11Device *device = mRenderer->getDevice();
add2DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" ));
@@ -145,19 +154,7 @@ index 72820a4..d43e65e 100644
add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" ));
add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" ));
add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
- add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
-+ add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
- add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" ));
- add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" ));
-- add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
-+ add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
- add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" ));
- add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" ));
-- add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
- add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" ));
- add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" ));
- add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
+@@ -1003,7 +1011,6 @@ void Blit11::buildShaderMap()
add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" ));
add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
@@ -166,22 +163,22 @@ index 72820a4..d43e65e 100644
addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" ));
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
-index 43ce5ba..ecd4d46 100644
+index 2d5fa3c..5aab379 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
-@@ -747,7 +747,9 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
+@@ -753,7 +753,9 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
- bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
+ bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
-+ if (!static_cast<Renderer11 *>(renderer)->isLevel9())
++ if (!renderer->isLevel9())
+ bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
bufferDesc->CPUAccessFlags = 0;
break;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-index 5caa427..765d34f 100644
+index 4630762..7185a05 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
@@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer)
@@ -189,11 +186,11 @@ index 5caa427..765d34f 100644
rsDesc.DepthBiasClamp = 0.0f;
rsDesc.SlopeScaledDepthBias = 0.0f;
- rsDesc.DepthClipEnable = FALSE;
-+ rsDesc.DepthClipEnable = mRenderer->isLevel9();
++ rsDesc.DepthClipEnable = renderer->isLevel9();
rsDesc.ScissorEnable = FALSE;
rsDesc.MultisampleEnable = FALSE;
rsDesc.AntialiasedLineEnable = FALSE;
-@@ -114,6 +114,12 @@ Clear11::Clear11(Renderer11 *renderer)
+@@ -114,6 +114,11 @@ Clear11::Clear11(Renderer11 *renderer)
d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state");
mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat);
@@ -202,53 +199,63 @@ index 5caa427..765d34f 100644
+ memset(&mIntClearShader, 0, sizeof(ClearShader));
+ return;
+ }
-+
mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-index edaafec..a4e84f9 100644
+index a4072d8..6a3d347 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-@@ -88,13 +88,16 @@ PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer");
-
-+ StructZero(&mParamsData);
-+
- // init shaders
-+ if (mRenderer->isLevel9())
-+ return;
-+
- mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS");
- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+@@ -133,10 +133,13 @@ gl::Error PixelTransfer11::loadResources()
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader.");
+ }
- buildShaderMap();
--
-- StructZero(&mParamsData);
- }
+- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+- if (!mBufferToTextureGS)
++ if (!mRenderer->isLevel9())
+ {
+- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
++ mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
++ if (!mBufferToTextureGS)
++ {
++ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
++ }
+ }
- PixelTransfer11::~PixelTransfer11()
+ gl::Error error = buildShaderMap();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index 0bb7489..b4b26a8 100644
+index ffc6cc9..f6ba930 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -162,6 +162,11 @@ EGLint Renderer11::initialize()
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
+@@ -153,6 +153,24 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const eg
+ }
+ }
+
+#if !defined(ANGLE_ENABLE_D3D9)
-+ D3D_FEATURE_LEVEL_9_3,
-+ D3D_FEATURE_LEVEL_9_2,
-+ D3D_FEATURE_LEVEL_9_1,
++ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
++ {
++ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
++ {
++ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
++ }
++ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
++ {
++ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
++ }
++ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
++ {
++ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
++ }
++ }
+#endif
- };
-
- D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;
-@@ -1112,6 +1117,84 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
++
+ mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP
+ : D3D_DRIVER_TYPE_HARDWARE;
+ }
+@@ -1170,6 +1188,83 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
+ return gl::Error(GL_NO_ERROR);
}
}
-
+template<typename T>
+static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
+{
@@ -326,12 +333,11 @@ index 0bb7489..b4b26a8 100644
+ default: UNREACHABLE();
+ }
+}
-+
+
gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
{
- // Get the raw indices for an indexed draw
-@@ -1123,10 +1206,13 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+@@ -1189,10 +1284,13 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
+ indices = bufferData + offset;
}
+ // TODO: some level 9 hardware supports 32-bit indices; test and store support instead
@@ -345,7 +351,7 @@ index 0bb7489..b4b26a8 100644
if (error.isError())
{
SafeDelete(mLineLoopIB);
-@@ -1137,7 +1223,8 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
+@@ -1203,7 +1301,8 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
// Checked by Renderer11::applyPrimitiveType
ASSERT(count >= 0);
@@ -355,7 +361,7 @@ index 0bb7489..b4b26a8 100644
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
}
-@@ -1157,42 +1244,12 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
+@@ -1223,42 +1322,12 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
return error;
}
@@ -402,8 +408,8 @@ index 0bb7489..b4b26a8 100644
error = mLineLoopIB->unmapBuffer();
if (error.isError())
{
-@@ -1227,10 +1284,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
- indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+@@ -1300,10 +1369,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
+ indices = bufferData + offset;
}
+ const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
@@ -416,7 +422,7 @@ index 0bb7489..b4b26a8 100644
if (error.isError())
{
SafeDelete(mTriangleFanIB);
-@@ -1243,13 +1302,14 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
+@@ -1316,13 +1387,14 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
const unsigned int numTris = count - 2;
@@ -434,7 +440,7 @@ index 0bb7489..b4b26a8 100644
if (error.isError())
{
return error;
-@@ -1263,45 +1323,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
+@@ -1336,45 +1408,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return error;
}
@@ -485,7 +491,7 @@ index 0bb7489..b4b26a8 100644
error = mTriangleFanIB->unmapBuffer();
if (error.isError())
-@@ -1549,7 +1576,7 @@ gl::Error Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
+@@ -1634,7 +1673,7 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
}
// needed for the point sprite geometry shader
@@ -494,19 +500,7 @@ index 0bb7489..b4b26a8 100644
{
mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
-@@ -1711,6 +1738,11 @@ bool Renderer11::testDeviceResettable()
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
-+#if !defined(ANGLE_ENABLE_D3D9)
-+ D3D_FEATURE_LEVEL_9_3,
-+ D3D_FEATURE_LEVEL_9_2,
-+ D3D_FEATURE_LEVEL_9_1,
-+#endif
- };
-
- ID3D11Device* dummyDevice;
-@@ -1862,7 +1894,10 @@ int Renderer11::getMajorShaderModel() const
+@@ -1938,7 +1977,10 @@ int Renderer11::getMajorShaderModel() const
{
case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
@@ -518,7 +512,7 @@ index 0bb7489..b4b26a8 100644
default: UNREACHABLE(); return 0;
}
}
-@@ -1873,7 +1908,10 @@ int Renderer11::getMinorShaderModel() const
+@@ -1949,7 +1991,10 @@ int Renderer11::getMinorShaderModel() const
{
case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
@@ -530,49 +524,81 @@ index 0bb7489..b4b26a8 100644
default: UNREACHABLE(); return 0;
}
}
-@@ -2387,6 +2425,15 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
- case D3D_FEATURE_LEVEL_10_0:
- profileVersion = "4_0";
+@@ -2455,6 +2500,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
+
+ unsigned int profileMajorVersion = 0;
+ unsigned int profileMinorVersion = 0;
++ const char *profileSuffix = NULL;
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+@@ -2469,12 +2515,30 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
+ profileMajorVersion = 4;
+ profileMinorVersion = 0;
break;
+ case D3D_FEATURE_LEVEL_9_3:
-+ profileVersion = "4_0_level_9_3";
++ profileMajorVersion = 4;
++ profileMinorVersion = 0;
++ profileSuffix = "_level_9_3";
+ break;
+ case D3D_FEATURE_LEVEL_9_2:
-+ profileVersion = "4_0_level_9_2";
++ profileMajorVersion = 4;
++ profileMinorVersion = 0;
++ profileSuffix = "_level_9_2";
+ break;
+ case D3D_FEATURE_LEVEL_9_1:
-+ profileVersion = "4_0_level_9_1";
++ profileMajorVersion = 4;
++ profileMinorVersion = 0;
++ profileSuffix = "_level_9_1";
+ break;
++ break;
default:
UNREACHABLE();
- return NULL;
+ return gl::Error(GL_INVALID_OPERATION);
+ }
+
+ std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
++ if (profileSuffix)
++ profile += profileSuffix;
+
+ UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
+
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-index b86f5e5..2a53fa1 100644
+index c789cae..d44bd2f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-@@ -184,6 +184,7 @@ class Renderer11 : public Renderer
+@@ -188,6 +188,7 @@ class Renderer11 : public RendererD3D
ID3D11Device *getDevice() { return mDevice; }
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
- IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+ DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+ bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; }
Blit11 *getBlitter() { return mBlit; }
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
-index 3f0cd5b..91e7147 100644
+index 4287918..74af27e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
-@@ -472,7 +472,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalform
+@@ -744,7 +744,7 @@ gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
D3D11_TEXTURE2D_DESC desc;
- desc.Width = width; // Compressed texture size constraints?
- desc.Height = height;
-- desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
-+ desc.MipLevels = desc.MipLevels = mRenderer->isLevel9() ? 1 : ((levels > 0) ? (mTopLevel + levels) : 0);
+ desc.Width = mTextureWidth; // Compressed texture size constraints?
+ desc.Height = mTextureHeight;
+- desc.MipLevels = mMipLevels;
++ desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels;
desc.ArraySize = 1;
desc.Format = mTextureFormat;
desc.SampleDesc.Count = 1;
+@@ -863,7 +863,7 @@ gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORM
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
+- srvDesc.Texture2D.MipLevels = mipLevels;
++ srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels;
+
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
-index 1ea916d..c078287 100644
+index 1ea916d..90a879e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
@@ -557,7 +557,7 @@ D3D11LoadFunctionMap BuildD3D11LoadFunctionMap()
@@ -589,15 +615,15 @@ index 1ea916d..c078287 100644
// From GL_EXT_texture_storage
// | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN );
-+ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
++ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-index b1867fb..06a22eb 100644
+index 9ffc32e..cbfe557 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-@@ -283,7 +283,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
+@@ -284,7 +284,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
@@ -607,5 +633,5 @@ index b1867fb..06a22eb 100644
default: UNREACHABLE(); return false;
}
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch b/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch
index 35d525fb2d..afc9f256a1 100644
--- a/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch
+++ b/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch
@@ -1,6 +1,6 @@
-From 9e167b788cc9de1d963fd3fc2145848a6ccc0fa8 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Mon, 22 Sep 2014 23:13:16 +0300
+From bbfd3cfcf6e1195d86368b61ce39504ce6acda50 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Wed, 12 Nov 2014 17:09:23 +0200
Subject: [PATCH 12/16] ANGLE: fix semantic index lookup
The sorted semantic index table was returning a direct mapping to the
@@ -14,10 +14,10 @@ Change-Id: I75d05ed707f56c45210e3dcbc277f894e3dc5a48
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
-index 1085346..3f6d9e0 100644
+index 0619023..6d64b38 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
-@@ -2788,7 +2788,7 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
+@@ -1216,7 +1216,7 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
int oldIndex = mAttributesByLayout[i];
@@ -27,10 +27,10 @@ index 1085346..3f6d9e0 100644
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
-index b006c04..d835e4f 100644
+index e41f238..ff90a6a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
-@@ -112,10 +112,10 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
+@@ -113,10 +113,10 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
// Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout
GLint attributeSize;
@@ -44,5 +44,5 @@ index b006c04..d835e4f 100644
ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch b/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch
index 00e32186f0..b43dcc368b 100644
--- a/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch
+++ b/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch
@@ -1,6 +1,6 @@
-From 3499339ab768017458d3b5295af3742a0f6015db Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Mon, 22 Sep 2014 23:15:26 +0300
+From 5ef9348de2624c21be1c9fddd265fec5a0851d25 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Thu, 13 Nov 2014 15:34:26 +0200
Subject: [PATCH 13/16] ANGLE: Add support for querying platform device
The EGL_EXT_device_base extension allows for querying the platform
@@ -16,14 +16,14 @@ the IDXGIDevice3::Trim() calls required by the Windows Store.
Change-Id: Ibdf228d81d6604e56db9dd8597d7cd2983ebc428
---
- src/3rdparty/angle/src/libEGL/libEGL.cpp | 47 +++++++++++++++++++++++++-------
- 1 file changed, 37 insertions(+), 10 deletions(-)
+ src/3rdparty/angle/src/libEGL/libEGL.cpp | 50 +++++++++++++++++++++++++-------
+ 1 file changed, 39 insertions(+), 11 deletions(-)
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-index 7ea11c5..c2e0fd6 100644
+index dc20d85..68399d6 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-@@ -18,6 +18,9 @@
+@@ -17,6 +17,9 @@
#include "libGLESv2/Texture.h"
#include "libGLESv2/main.h"
#include "libGLESv2/renderer/SwapChain.h"
@@ -33,7 +33,7 @@ index 7ea11c5..c2e0fd6 100644
#include "libEGL/main.h"
#include "libEGL/Display.h"
-@@ -484,24 +487,48 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
+@@ -582,25 +585,50 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
egl::Display *display = static_cast<egl::Display*>(dpy);
egl::Surface *eglSurface = (egl::Surface*)surface;
@@ -44,7 +44,8 @@ index 7ea11c5..c2e0fd6 100644
-
- if (surface == EGL_NO_SURFACE)
- {
-- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+- recordError(egl::Error(EGL_BAD_SURFACE));
+- return EGL_FALSE;
- }
-
switch (attribute)
@@ -58,7 +59,8 @@ index 7ea11c5..c2e0fd6 100644
+
+ if (surface == EGL_NO_SURFACE)
+ {
-+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
++ recordError(egl::Error(EGL_BAD_SURFACE));
++ return EGL_FALSE;
+ }
+
rx::SwapChain *swapchain = eglSurface->getSwapChain();
@@ -82,7 +84,8 @@ index 7ea11c5..c2e0fd6 100644
+
+ if (renderer->getMajorShaderModel() < 4)
+ {
-+ return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
++ recordError(egl::Error(EGL_BAD_CONTEXT));
++ return EGL_FALSE;
+ }
+
+ *value = static_cast<rx::Renderer11*>(renderer)->getDevice();
@@ -90,8 +93,8 @@ index 7ea11c5..c2e0fd6 100644
+ break;
+#endif
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
- }
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch b/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch
index b884f7b549..9ceb34d964 100644
--- a/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch
+++ b/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch
@@ -1,6 +1,6 @@
-From a3046fef7f754f06937161e779ce0a651e77317b Mon Sep 17 00:00:00 2001
+From 5b3bc73210ed1847d9bd7a94f06cc0d5de8e0b89 Mon Sep 17 00:00:00 2001
From: Michael Bruning <michael.bruning@digia.com>
-Date: Mon, 22 Sep 2014 23:23:40 +0300
+Date: Thu, 13 Nov 2014 15:40:10 +0200
Subject: [PATCH 14/16] Let ANGLE use multithreaded devices if necessary.
This is needed to prevent lock-ups in application that use ANGLE from
@@ -11,13 +11,13 @@ communicate this from the QtWebEngine module.
Change-Id: Ibd5a5c75eb68af567d420d9a35efb3490c93b27c
---
- src/3rdparty/angle/src/common/platform.h | 1 +
- .../angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 13 +++++++++++++
- .../angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 ++++
- 3 files changed, 18 insertions(+)
+ src/3rdparty/angle/src/common/platform.h | 1 +
+ .../angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 10 ++++++++++
+ .../angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 ++++
+ 3 files changed, 15 insertions(+)
diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 387ba41..7d0d957 100644
+index 0065ec7..8b2190d 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
@@ -57,6 +57,7 @@
@@ -26,17 +26,16 @@ index 387ba41..7d0d957 100644
# include <d3d10_1.h>
+# include <d3d10.h>
# include <d3d11.h>
+ # include <d3d11_1.h>
# include <dxgi.h>
- # include <dxgi1_2.h>
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index b4b26a8..bd07ee1 100644
+index f6ba930..46b9984 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -301,6 +301,19 @@ EGLint Renderer11::initialize()
+@@ -258,6 +258,16 @@ EGLint Renderer11::initialize()
}
- #endif
-+#if !defined(ANGLE_PLATFORM_WINRT)
+ #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
+ if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
+ {
@@ -47,16 +46,14 @@ index b4b26a8..bd07ee1 100644
+ ASSERT(SUCCEEDED(result));
+ multithread->Release();
+ }
-+#endif
-+
- initializeDevice();
-
- return EGL_SUCCESS;
+ #if !ANGLE_SKIP_DXGI_1_2_CHECK
+ // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
+ // The easiest way to check is to query for a IDXGIDevice2.
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index e8564bd..1d52705 100644
+index 82963ec..4c552b2 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -304,6 +304,10 @@ EGLint Renderer9::initialize()
+@@ -299,6 +299,10 @@ EGLint Renderer9::initialize()
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
@@ -68,5 +65,5 @@ index e8564bd..1d52705 100644
result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
}
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch b/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch
index 7d914766a0..f78474f11a 100644
--- a/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch
+++ b/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch
@@ -1,23 +1,28 @@
-From 373b3f67352e9a6f599c6a9dd9aee3b4836e0a3f Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Mon, 22 Sep 2014 23:41:48 +0300
+From d9a9219ea2181dd4c1939d05747a21b67f16a906 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Thu, 13 Nov 2014 16:33:53 +0200
Subject: [PATCH 15/16] ANGLE: Fix -angle-d3d11 on MSVC2010
Allow the D3D11 renderer to build with the June 2010 DirectX SDK.
Change-Id: I2343acedab16845d6a0d4a53cf3145f583efc4a7
---
- src/3rdparty/angle/src/common/platform.h | 6 ++
- .../renderer/d3d/d3d11/renderer11_utils.cpp | 89 ++++++++++++++++++++++
- 2 files changed, 95 insertions(+)
+ src/3rdparty/angle/src/common/platform.h | 8 +-
+ src/3rdparty/angle/src/libGLESv2/Context.cpp | 8 +-
+ src/3rdparty/angle/src/libGLESv2/Data.h | 2 +-
+ src/3rdparty/angle/src/libGLESv2/State.cpp | 6 +-
+ .../src/libGLESv2/renderer/d3d/RendererD3D.cpp | 4 +-
+ .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 4 +-
+ .../renderer/d3d/d3d11/renderer11_utils.cpp | 137 +++++++++++++++++++++
+ 7 files changed, 156 insertions(+), 13 deletions(-)
diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 7d0d957..3c619f3 100644
+index 8b2190d..972eee2 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -52,7 +52,9 @@
+@@ -52,17 +52,23 @@
- # if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
+ # if defined(ANGLE_ENABLE_D3D9)
# include <d3d9.h>
+# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
@@ -25,11 +30,13 @@ index 7d0d957..3c619f3 100644
# endif
# if defined(ANGLE_ENABLE_D3D11)
-@@ -60,8 +62,12 @@
+ # include <d3d10_1.h>
# include <d3d10.h>
# include <d3d11.h>
+-# include <d3d11_1.h>
# include <dxgi.h>
-+# if _MSC_VER >= 1700
++# if defined(_MSC_VER) && (_MSC_VER >= 1700)
++# include <d3d11_1.h>
# include <dxgi1_2.h>
+# endif
+# if !defined(COMPILER_IMPLEMENTATION)
@@ -37,12 +44,118 @@ index 7d0d957..3c619f3 100644
+# endif
# endif
- # undef near
+ # if defined(ANGLE_ENABLE_WINDOWS_STORE)
+diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
+index fe9b1a2..b87689c 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
+@@ -168,9 +168,9 @@ Context::~Context()
+ }
+ mIncompleteTextures.clear();
+
+- for (auto &zeroTexture : mZeroTextures)
++ for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
+ {
+- zeroTexture.second.set(NULL);
++ i->second.set(NULL);
+ }
+ mZeroTextures.clear();
+
+@@ -354,7 +354,7 @@ void Context::deleteFenceSync(GLsync fenceSync)
+
+ void Context::deleteVertexArray(GLuint vertexArray)
+ {
+- auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
++ VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray);
+
+ if (vertexArrayObject != mVertexArrayMap.end())
+ {
+@@ -460,7 +460,7 @@ FenceSync *Context::getFenceSync(GLsync handle) const
+
+ VertexArray *Context::getVertexArray(GLuint handle) const
+ {
+- auto vertexArray = mVertexArrayMap.find(handle);
++ VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle);
+
+ if (vertexArray == mVertexArrayMap.end())
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h
+index cff872a..9234403 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Data.h
++++ b/src/3rdparty/angle/src/libGLESv2/Data.h
+@@ -14,7 +14,7 @@
+ namespace gl
+ {
+
+-struct Data final
++struct Data
+ {
+ public:
+ Data(GLint clientVersion, const State &state, const Caps &caps,
+diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp
+index e7acda2..b5b62f5 100644
+--- a/src/3rdparty/angle/src/libGLESv2/State.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/State.cpp
+@@ -665,13 +665,13 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
+
+ void State::initializeZeroTextures(const TextureMap &zeroTextures)
+ {
+- for (const auto &zeroTexture : zeroTextures)
++ for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++)
+ {
+- auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
++ TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first];
+
+ for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
+ {
+- samplerTextureArray[textureUnit].set(zeroTexture.second.get());
++ samplerTextureArray[textureUnit].set(i->second.get());
+ }
+ }
+ }
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+index 6f58243..97da6da 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+@@ -27,9 +27,9 @@ RendererD3D::RendererD3D(egl::Display *display)
+
+ RendererD3D::~RendererD3D()
+ {
+- for (auto &incompleteTexture : mIncompleteTextures)
++ for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
+ {
+- incompleteTexture.second.set(NULL);
++ i->second.set(NULL);
+ }
+ mIncompleteTextures.clear();
+ }
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+index 46b9984..a28fd78 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+@@ -873,7 +873,7 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
+
+ void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource)
+ {
+- auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
++ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
+ {
+@@ -3398,7 +3398,7 @@ Workarounds Renderer11::generateWorkarounds() const
+
+ void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
+ {
+- auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
++ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+
+ ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
+
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-index 06a22eb..345fd24 100644
+index cbfe557..5831c57 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-@@ -17,6 +17,37 @@
+@@ -18,6 +18,85 @@
#include <algorithm>
@@ -76,300 +189,348 @@ index 06a22eb..345fd24 100644
+#ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION
+# define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
+#endif
++#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION
++# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384
++#endif
++#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION
++# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048
++#endif
++#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
++# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048
++#endif
++#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP
++# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32
++#endif
++#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP
++# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32
++#endif
++#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT
++# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32
++#endif
++#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT
++# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32
++#endif
++#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT
++# define D3D10_1_SO_BUFFER_SLOT_COUNT 4
++#endif
++#ifndef D3D11_SO_BUFFER_SLOT_COUNT
++# define D3D11_SO_BUFFER_SLOT_COUNT 4
++#endif
++#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
++# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14
++#endif
++#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT
++# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16
++#endif
++#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
++# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8
++#endif
++#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
++# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7
++#endif
++#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT
++# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096
++#endif
++#ifndef D3D11_PS_INPUT_REGISTER_COUNT
++# define D3D11_PS_INPUT_REGISTER_COUNT 32
++#endif
++#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
++# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
++#endif
+
namespace rx
{
-@@ -275,7 +306,9 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
+@@ -276,7 +355,9 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
-@@ -293,7 +326,9 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
+@@ -294,7 +375,9 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
case D3D_FEATURE_LEVEL_10_1:
-@@ -313,7 +348,9 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+@@ -314,7 +397,9 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return true;
-@@ -333,7 +370,9 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+@@ -334,7 +419,9 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
-@@ -351,7 +390,9 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
+@@ -352,7 +439,9 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
-@@ -374,7 +415,9 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
+@@ -375,7 +464,9 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
-@@ -392,7 +435,9 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
+@@ -393,7 +484,9 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
case D3D_FEATURE_LEVEL_10_1:
-@@ -410,7 +455,9 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+@@ -411,7 +504,9 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
case D3D_FEATURE_LEVEL_10_1:
-@@ -428,7 +475,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
+@@ -429,7 +524,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
case D3D_FEATURE_LEVEL_10_1:
-@@ -446,7 +495,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
+@@ -447,7 +544,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
case D3D_FEATURE_LEVEL_10_1:
-@@ -464,7 +515,9 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+@@ -465,7 +564,9 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
case D3D_FEATURE_LEVEL_10_1:
-@@ -482,7 +535,9 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
+@@ -483,7 +584,9 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
case D3D_FEATURE_LEVEL_10_1:
-@@ -506,7 +561,9 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
+@@ -507,7 +610,9 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
-@@ -528,7 +585,9 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
+@@ -529,7 +634,9 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
-@@ -545,7 +604,9 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
+@@ -546,7 +653,9 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
-@@ -565,7 +626,9 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+@@ -566,7 +675,9 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
-@@ -590,7 +653,9 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+@@ -591,7 +702,9 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
case D3D_FEATURE_LEVEL_10_1:
-@@ -617,7 +682,9 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
+@@ -618,7 +731,9 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
-@@ -636,7 +703,9 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+@@ -637,7 +752,9 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
-@@ -658,7 +727,9 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+@@ -659,7 +776,9 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
-@@ -683,7 +754,9 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+@@ -684,7 +803,9 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
case D3D_FEATURE_LEVEL_10_1:
-@@ -702,7 +775,9 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
+@@ -703,7 +824,9 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
case D3D_FEATURE_LEVEL_10_1:
-@@ -721,7 +796,9 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+@@ -722,7 +845,9 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
case D3D_FEATURE_LEVEL_10_1:
-@@ -740,7 +817,9 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+@@ -741,7 +866,9 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
case D3D_FEATURE_LEVEL_10_1:
-@@ -759,7 +838,9 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+@@ -760,7 +887,9 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
-@@ -782,7 +863,9 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
+@@ -783,7 +912,9 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
case D3D_FEATURE_LEVEL_10_1:
-@@ -801,7 +884,9 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
+@@ -802,7 +933,9 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT;
-@@ -819,7 +904,9 @@ static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL fea
+@@ -820,7 +953,9 @@ static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL feat
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
-@@ -837,7 +924,9 @@ static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featur
+@@ -838,7 +973,9 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
{
switch (featureLevel)
{
-+#if _MSC_VER >= 1700
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
case D3D_FEATURE_LEVEL_11_1:
+#endif
- case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) /
+ case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
GetMaximumStreamOutputBuffers(featureLevel);
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch b/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch
index 2ea528018d..e3df95d8bf 100644
--- a/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch
+++ b/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch
@@ -1,35 +1,29 @@
-From 75c39e9020f062d155097f6b49aebbc12970b1e8 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@digia.com>
-Date: Tue, 23 Sep 2014 23:39:14 +0300
+From 43c8ceb17ccd6d5ae13a07c6d01b45eb40983917 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Tue, 11 Nov 2014 14:36:43 +0200
Subject: [PATCH 16/16] ANGLE: Fix compilation with MinGW + D3D11
-Provide workarounds for things GCC doesn't like, and define a number
-of macros not found in the MinGW headers.
+Provide workarounds for things GCC doesn't like, and define a few
+missing definitions not found in the MinGW headers.
Change-Id: I254c208209c0071fae5efb6727f2b3cfd5542da6
---
- src/3rdparty/angle/src/common/platform.h | 11 +++++
- src/3rdparty/angle/src/libEGL/Display.cpp | 1 +
- src/3rdparty/angle/src/libGLESv2/Context.cpp | 5 +-
- src/3rdparty/angle/src/libGLESv2/angletypes.h | 1 +
- .../angle/src/libGLESv2/renderer/copyimage.inl | 2 +-
- .../src/libGLESv2/renderer/d3d/TextureD3D.cpp | 4 +-
+ src/3rdparty/angle/src/common/platform.h | 73 ++++++++++++++++++++++
+ .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 6 ++
.../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 2 +-
- .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 2 +-
- .../renderer/d3d/d3d11/renderer11_utils.cpp | 53 +++++++++++++++++++++-
+ .../renderer/d3d/d3d11/renderer11_utils.cpp | 2 +-
.../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 +-
- src/3rdparty/angle/src/libGLESv2/validationES.cpp | 2 +-
- 11 files changed, 76 insertions(+), 11 deletions(-)
+ 5 files changed, 83 insertions(+), 4 deletions(-)
diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 3c619f3..b53394f 100644
+index 972eee2..0001e71 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -68,6 +68,17 @@
- # if !defined(COMPILER_IMPLEMENTATION)
- # include <d3dcompiler.h>
- # endif
-+# if defined(__MINGW32__)
+@@ -81,6 +81,79 @@
+ # endif
+ # endif
+
++# if defined(__MINGW32__) // Missing defines on MinGW
+typedef enum D3D11_MAP_FLAG
+{
+ D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
@@ -39,202 +33,121 @@ index 3c619f3..b53394f 100644
+ UINT64 NumPrimitivesWritten;
+ UINT64 PrimitivesStorageNeeded;
+} D3D11_QUERY_DATA_SO_STATISTICS;
-+# endif
- # endif
-
++typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)(
++ IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *,
++ UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
++#define D3D11_MESSAGE_CATEGORY UINT
++#define D3D11_MESSAGE_SEVERITY UINT
++#define D3D11_MESSAGE_ID UINT
++struct D3D11_MESSAGE;
++typedef struct D3D11_INFO_QUEUE_FILTER_DESC
++{
++ UINT NumCategories;
++ D3D11_MESSAGE_CATEGORY *pCategoryList;
++ UINT NumSeverities;
++ D3D11_MESSAGE_SEVERITY *pSeverityList;
++ UINT NumIDs;
++ D3D11_MESSAGE_ID *pIDList;
++} D3D11_INFO_QUEUE_FILTER_DESC;
++typedef struct D3D11_INFO_QUEUE_FILTER
++{
++ D3D11_INFO_QUEUE_FILTER_DESC AllowList;
++ D3D11_INFO_QUEUE_FILTER_DESC DenyList;
++} D3D11_INFO_QUEUE_FILTER;
++static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
++MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
++{
++public:
++ virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
++ virtual void __stdcall ClearStoredMessages() = 0;
++ virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
++ virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
++ virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
++ virtual UINT64 __stdcall GetNumStoredMessages() = 0;
++ virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
++ virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
++ virtual UINT64 __stdcall GetMessageCountLimit() = 0;
++ virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
++ virtual void __stdcall ClearStorageFilter() = 0;
++ virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
++ virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
++ virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual void __stdcall PopStorageFilter() = 0;
++ virtual UINT __stdcall GetStorageFilterStackSize() = 0;
++ virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
++ virtual void __stdcall ClearRetrievalFilter() = 0;
++ virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
++ virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
++ virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual void __stdcall PopRetrievalFilter() = 0;
++ virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
++ virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
++ virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
++ virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
++ virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
++ virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
++ virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
++ virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
++ virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
++ virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
++ virtual BOOL __stdcall GetMuteDebugOutput() = 0;
++};
++#endif // __MINGW32__
++
# undef near
-diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
-index ba09631..5a50e4b 100644
---- a/src/3rdparty/angle/src/libEGL/Display.cpp
-+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
-@@ -14,6 +14,7 @@
- #include <map>
- #include <vector>
- #include <sstream>
-+#include <iterator>
-
- #include "common/debug.h"
- #include "common/mathutil.h"
-diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
-index 04c7616..5342de1 100644
---- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
-@@ -33,6 +33,7 @@
- #include "libEGL/Surface.h"
-
- #include <sstream>
-+#include <iterator>
-
- namespace gl
- {
-@@ -354,7 +355,7 @@ void Context::deleteFenceSync(GLsync fenceSync)
- // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
- // and since our API is currently designed for being called from a single thread, we can delete
- // the fence immediately.
-- mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
-+ mResourceManager->deleteFenceSync(uintptr_t(fenceSync));
- }
-
- void Context::deleteVertexArray(GLuint vertexArray)
-@@ -460,7 +461,7 @@ Renderbuffer *Context::getRenderbuffer(GLuint handle)
-
- FenceSync *Context::getFenceSync(GLsync handle) const
- {
-- return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
-+ return mResourceManager->getFenceSync(uintptr_t(handle));
- }
-
- VertexArray *Context::getVertexArray(GLuint handle) const
-diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h
-index 922053e..642a6ec 100644
---- a/src/3rdparty/angle/src/libGLESv2/angletypes.h
-+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h
-@@ -11,6 +11,7 @@
-
- #include "libGLESv2/constants.h"
- #include "common/RefCountObject.h"
-+#include <float.h>
-
- namespace gl
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl
-index ea6970c..0498cf7 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl
-@@ -24,7 +24,7 @@ inline void WriteColor(const uint8_t *source, uint8_t *dest)
- template <typename sourceType, typename destType, typename colorDataType>
- inline void CopyPixel(const uint8_t *source, uint8_t *dest)
- {
-- colorType temp;
-+ colorDataType temp;
- ReadColor<sourceType, colorDataType>(source, &temp);
- WriteColor<destType, colorDataType>(&temp, dest);
- }
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
-index 2650913..96c8497 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
-@@ -129,7 +129,7 @@ bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei w
- if (unpack.pixelBuffer.id() != 0)
- {
- gl::Buffer *pixelBuffer = unpack.pixelBuffer.get();
-- unsigned int offset = reinterpret_cast<unsigned int>(pixels);
-+ ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
- // TODO: setImage/subImage is the only place outside of renderer that asks for a buffers raw data.
- // This functionality should be moved into renderer and the getData method of BufferImpl removed.
- const void *bufferData = pixelBuffer->getImplementation()->getData();
-@@ -186,7 +186,7 @@ bool TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void
- // to create a render target.
- ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
-
-- unsigned int offset = reinterpret_cast<unsigned int>(pixels);
-+ ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+ # undef far
+ #endif
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+index 9d003b4..776d92b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+@@ -14,6 +14,12 @@
+ #ifndef QT_D3DCOMPILER_DLL
+ #define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
+ #endif
++#ifndef D3DCOMPILE_RESERVED16
++#define D3DCOMPILE_RESERVED16 (1 << 16)
++#endif
++#ifndef D3DCOMPILE_RESERVED17
++#define D3DCOMPILE_RESERVED17 (1 << 17)
++#endif
- return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
- }
+ // Definitions local to the translation unit
+ namespace
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index bd07ee1..b29b2ef 100644
+index a28fd78..e6d7f30 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -281,7 +281,7 @@ EGLint Renderer11::initialize()
- }
-
+@@ -333,7 +333,7 @@ EGLint Renderer11::initialize()
// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
--#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
-+#if !defined(__MINGW32__) && defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+ #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
ID3D11InfoQueue *infoQueue;
- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
+- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
++ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-index 787c511..4b29be0 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-@@ -537,7 +537,7 @@ void SwapChain11::initPassThroughResources()
- samplerDesc.BorderColor[2] = 0.0f;
- samplerDesc.BorderColor[3] = 0.0f;
- samplerDesc.MinLOD = 0;
-- samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
-+ samplerDesc.MaxLOD = FLT_MAX;
-
- result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
- ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-index 345fd24..2af97e7 100644
+index 5831c57..121aa3b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-@@ -47,6 +47,57 @@
- #ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION
- # define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
- #endif
-+#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION
-+# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384
-+#endif
-+#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION
-+# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048
-+#endif
-+#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
-+# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048
-+#endif
-+#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP
-+# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32
-+#endif
-+#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP
-+# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32
-+#endif
-+#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT
-+# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32
-+#endif
-+#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT
-+# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32
-+#endif
-+#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT
-+# define D3D10_1_SO_BUFFER_SLOT_COUNT 4
-+#endif
-+#ifndef D3D11_SO_BUFFER_SLOT_COUNT
-+# define D3D11_SO_BUFFER_SLOT_COUNT 4
-+#endif
-+#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
-+# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14
-+#endif
-+#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT
-+# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16
-+#endif
-+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
-+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8
-+#endif
-+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
-+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7
-+#endif
-+#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT
-+# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096
-+#endif
-+#ifndef D3D11_PS_INPUT_REGISTER_COUNT
-+# define D3D11_PS_INPUT_REGISTER_COUNT 32
-+#endif
-+#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
-+# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
-+#endif
-+#ifndef D3D11_VS_OUTPUT_REGISTER_COUNT
-+# define D3D11_VS_OUTPUT_REGISTER_COUNT 32
-+#endif
-
- namespace rx
- {
-@@ -1147,7 +1198,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
+@@ -1196,7 +1196,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
{
-#if defined(_DEBUG)
-+#if !defined(__MINGW32__) && defined(_DEBUG)
++#if defined(_DEBUG) && !defined(__MINGW32__)
return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
#else
return S_OK;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index 1d52705..d63f9b8 100644
+index 4c552b2..601cd24 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -205,7 +205,7 @@ EGLint Renderer9::initialize()
- if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
+@@ -200,7 +200,7 @@ EGLint Renderer9::initialize()
+ if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
{
ASSERT(mD3d9Ex);
- mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void**>(&mD3d9));
@@ -242,7 +155,7 @@ index 1d52705..d63f9b8 100644
ASSERT(mD3d9);
}
else
-@@ -329,7 +329,7 @@ EGLint Renderer9::initialize()
+@@ -324,7 +324,7 @@ EGLint Renderer9::initialize()
if (mD3d9Ex)
{
@@ -251,19 +164,6 @@ index 1d52705..d63f9b8 100644
ASSERT(SUCCEEDED(result));
}
-diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.cpp b/src/3rdparty/angle/src/libGLESv2/validationES.cpp
-index 1b6180d..f79bc97 100644
---- a/src/3rdparty/angle/src/libGLESv2/validationES.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/validationES.cpp
-@@ -1667,7 +1667,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
- // TODO: also disable index checking on back-ends that are robust to out-of-range accesses.
- if (elementArrayBuffer)
- {
-- unsigned int offset = reinterpret_cast<unsigned int>(indices);
-+ GLint64 offset = reinterpret_cast<GLint64>(indices);
- if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL))
- {
- const void *dataPointer = elementArrayBuffer->getImplementation()->getData();
--
-1.9.0.msysgit.0
+1.9.4.msysgit.1
diff --git a/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch b/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch
new file mode 100644
index 0000000000..4ada6d41d2
--- /dev/null
+++ b/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch
@@ -0,0 +1,62 @@
+From d7839cc052de126cc3b457fe41963fd9c7e91846 Mon Sep 17 00:00:00 2001
+From: Kai Koehne <kai.koehne@theqtcompany.com>
+Date: Mon, 17 Nov 2014 15:10:10 +0100
+Subject: [PATCH] ANGLE: Fix compilation with D3D9
+
+Fixes a regression introduced in c6df5fe3ed0f2a722 that
+broke compilation with d3d9 (namely, -target xp).
+
+Task-number: QTBUG-42714
+Change-Id: I1a5e9682d5463bfa082a5d0c062399a131a7cf52
+---
+ src/3rdparty/angle/src/common/NativeWindow.h | 7 ++++++-
+ src/3rdparty/angle/src/common/platform.h | 1 +
+ src/3rdparty/angle/src/common/win32/NativeWindow.cpp | 2 +-
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h
+index 9e93aea..c4a0e42 100644
+--- a/src/3rdparty/angle/src/common/NativeWindow.h
++++ b/src/3rdparty/angle/src/common/NativeWindow.h
+@@ -54,7 +54,12 @@ public:
+ bool getClientRect(LPRECT rect);
+ bool isIconic();
+
+- HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
++# if defined(ANGLE_ENABLE_D3D11)
++ typedef ID3D11Device Device;
++#else
++ typedef IDirect3DDevice9 Device;
++#endif
++ HRESULT createSwapChain(Device* device, DXGIFactory* factory,
+ DXGI_FORMAT format, UINT width, UINT height,
+ DXGISwapChain** swapChain);
+
+diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
+index 0001e71..5bf97f9 100644
+--- a/src/3rdparty/angle/src/common/platform.h
++++ b/src/3rdparty/angle/src/common/platform.h
+@@ -52,6 +52,7 @@
+
+ # if defined(ANGLE_ENABLE_D3D9)
+ # include <d3d9.h>
++# include <dxgi.h>
+ # if !defined(COMPILER_IMPLEMENTATION)
+ # include <d3dcompiler.h>
+ # endif
+diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
+index 2440747..46082a2 100644
+--- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
++++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
+@@ -35,7 +35,7 @@ bool NativeWindow::isIconic()
+ return IsIconic(mWindow) == TRUE;
+ }
+
+-HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
++HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory,
+ DXGI_FORMAT format, unsigned int width, unsigned int height,
+ DXGISwapChain** swapChain)
+ {
+--
+1.9.4.msysgit.0
+
diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro
index 48ce7055fd..a16249309f 100644
--- a/src/angle/src/libEGL/libEGL.pro
+++ b/src/angle/src/libEGL/libEGL.pro
@@ -6,20 +6,40 @@ winrt: LIBS_PRIVATE += -ld3d11
LIBS_PRIVATE += -ldxguid -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget(libGLESv2)
HEADERS += \
+ $$ANGLE_DIR/src/common/NativeWindow.h \
+ $$ANGLE_DIR/src/libEGL/AttributeMap.h \
$$ANGLE_DIR/src/libEGL/Config.h \
$$ANGLE_DIR/src/libEGL/Display.h \
+ $$ANGLE_DIR/src/libEGL/Error.h \
$$ANGLE_DIR/src/libEGL/main.h \
$$ANGLE_DIR/src/libEGL/resource.h \
$$ANGLE_DIR/src/libEGL/ShaderCache.h \
$$ANGLE_DIR/src/libEGL/Surface.h
SOURCES += \
+ $$ANGLE_DIR/src/libEGL/AttributeMap.cpp \
$$ANGLE_DIR/src/libEGL/Config.cpp \
$$ANGLE_DIR/src/libEGL/Display.cpp \
+ $$ANGLE_DIR/src/libEGL/Error.cpp \
$$ANGLE_DIR/src/libEGL/libEGL.cpp \
$$ANGLE_DIR/src/libEGL/main.cpp \
$$ANGLE_DIR/src/libEGL/Surface.cpp
+!winrt {
+ SOURCES += \
+ $$ANGLE_DIR/src/common/win32/NativeWindow.cpp
+} else {
+ HEADERS += \
+ $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.h \
+ $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.h \
+ $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.h
+
+ SOURCES += \
+ $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.cpp \
+ $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.cpp \
+ $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.cpp
+}
+
!static {
DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}.def
mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}_mingw32.def
diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro
index c0f7982e6c..705768d17d 100644
--- a/src/angle/src/libGLESv2/libGLESv2.pro
+++ b/src/angle/src/libGLESv2/libGLESv2.pro
@@ -24,11 +24,13 @@ HEADERS += \
$$ANGLE_DIR/src/common/blocklayout.h \
$$ANGLE_DIR/src/common/shadervars.h \
$$ANGLE_DIR/src/common/utilities.h \
+ $$ANGLE_DIR/src/common/NativeWindow.h \
$$ANGLE_DIR/src/libGLESv2/angletypes.h \
$$ANGLE_DIR/src/libGLESv2/BinaryStream.h \
$$ANGLE_DIR/src/libGLESv2/Buffer.h \
$$ANGLE_DIR/src/libGLESv2/Caps.h \
$$ANGLE_DIR/src/libGLESv2/Context.h \
+ $$ANGLE_DIR/src/libGLESv2/Data.h \
$$ANGLE_DIR/src/libGLESv2/Error.h \
$$ANGLE_DIR/src/libGLESv2/Fence.h \
$$ANGLE_DIR/src/libGLESv2/formatutils.h \
@@ -53,6 +55,8 @@ HEADERS += \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexDataManager.h \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/MemoryBuffer.h \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/ProgramD3D.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RenderbufferD3D.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RendererD3D.h \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/ShaderD3D.h \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureD3D.h \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureStorage.h \
@@ -69,6 +73,7 @@ HEADERS += \
$$ANGLE_DIR/src/libGLESv2/renderer/loadimage.h \
$$ANGLE_DIR/src/libGLESv2/renderer/ProgramImpl.h \
$$ANGLE_DIR/src/libGLESv2/renderer/QueryImpl.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderbufferImpl.h \
$$ANGLE_DIR/src/libGLESv2/renderer/Renderer.h \
$$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.h \
$$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable.h \
@@ -77,6 +82,7 @@ HEADERS += \
$$ANGLE_DIR/src/libGLESv2/renderer/TextureImpl.h \
$$ANGLE_DIR/src/libGLESv2/renderer/TextureFeedbackImpl.h \
$$ANGLE_DIR/src/libGLESv2/renderer/VertexDeclarationCache.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Workarounds.h \
$$ANGLE_DIR/src/libGLESv2/resource.h \
$$ANGLE_DIR/src/libGLESv2/ResourceManager.h \
$$ANGLE_DIR/src/libGLESv2/Sampler.h \
@@ -102,6 +108,7 @@ SOURCES += \
$$ANGLE_DIR/src/libGLESv2/Buffer.cpp \
$$ANGLE_DIR/src/libGLESv2/Caps.cpp \
$$ANGLE_DIR/src/libGLESv2/Context.cpp \
+ $$ANGLE_DIR/src/libGLESv2/Data.cpp \
$$ANGLE_DIR/src/libGLESv2/Error.cpp \
$$ANGLE_DIR/src/libGLESv2/Fence.cpp \
$$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.cpp \
@@ -131,10 +138,12 @@ SOURCES += \
$$ANGLE_DIR/src/libGLESv2/VertexAttribute.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/copyimage.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/loadimage.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/loadimageSSE2.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/Image.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/IndexRangeCache.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/ProgramImpl.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderbufferImpl.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/Renderer.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/BufferD3D.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp \
@@ -143,6 +152,8 @@ SOURCES += \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexDataManager.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/ProgramD3D.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RendererD3D.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/ShaderD3D.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureD3D.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureStorage.cpp \
@@ -192,6 +203,8 @@ angle_d3d11 {
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
}
+SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/loadimageSSE2.cpp
+
!winrt {
HEADERS += \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Blit9.h \
@@ -211,6 +224,7 @@ angle_d3d11 {
$$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.h
SOURCES += \
+ $$ANGLE_DIR/src/common/win32/NativeWindow.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp \
@@ -227,6 +241,16 @@ angle_d3d11 {
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp \
$$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp \
$$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.cpp
+} else {
+ HEADERS += \
+ $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.h \
+ $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.h \
+ $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.h
+
+ SOURCES += \
+ $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.cpp \
+ $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.cpp \
+ $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.cpp
}
!static {
diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp
index 0f87d7263e..241501d60d 100644
--- a/src/corelib/animation/qanimationgroup.cpp
+++ b/src/corelib/animation/qanimationgroup.cpp
@@ -62,7 +62,7 @@
QAnimationGroup provides methods for adding and retrieving
animations. Besides that, you can remove animations by calling
- remove(), and clear the animation group by calling
+ \l removeAnimation(), and clear the animation group by calling
clear(). You may keep track of changes in the group's
animations by listening to QEvent::ChildAdded and
QEvent::ChildRemoved events.
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index dcbf55f28b..f47dec6ce0 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -79,7 +79,7 @@ QT_BEGIN_NAMESPACE
There are two ways to affect how QVariantAnimation interpolates
the values. You can set an easing curve by calling
setEasingCurve(), and configure the duration by calling
- setDuration(). You can change how the QVariants are interpolated
+ setDuration(). You can change how the \l{QVariant}s are interpolated
by creating a subclass of QVariantAnimation, and reimplementing
the virtual interpolated() function.
@@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE
If you need to interpolate other variant types, including custom
types, you have to implement interpolation for these yourself.
To do this, you can register an interpolator function for a given
- type. This function takes 3 parameters: the start value, the end value
+ type. This function takes 3 parameters: the start value, the end value,
and the current progress.
Example:
@@ -378,8 +378,8 @@ QVariantAnimation::~QVariantAnimation()
keyValues are referring to this effective progress.
The easing curve is used with the interpolator, the interpolated()
- virtual function, the animation's duration, and iterationCount, to
- control how the current value changes as the animation progresses.
+ virtual function, and the animation's duration to control how the
+ current value changes as the animation progresses.
*/
QEasingCurve QVariantAnimation::easingCurve() const
{
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 9d13e1b892..d2857c03b6 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -253,9 +253,10 @@ static QTextCodec *setupLocaleMapper()
// textCodecsMutex need to be locked to enter this function
static void setup()
{
- QCoreGlobalData *globalData = QCoreGlobalData::instance();
- if (!globalData->allCodecs.isEmpty())
+ static bool initialized = false;
+ if (initialized)
return;
+ initialized = true;
#if !defined(QT_NO_CODECS) && !defined(QT_BOOTSTRAPPED)
(void)new QTsciiCodec;
@@ -441,7 +442,7 @@ QTextCodec::ConverterState::~ConverterState()
an empty list. For example, "ISO-8859-1" has "latin1",
"CP819", "IBM819", and "iso-ir-100" as aliases.
- \row \li mibEnum()
+ \row \li \l{QTextCodec::mibEnum()}{mibEnum()}
\li Return the MIB enum for the encoding if it is listed in
the \l{IANA character-sets encoding file}.
@@ -465,7 +466,11 @@ QTextCodec::QTextCodec()
{
QMutexLocker locker(textCodecsMutex());
- QCoreGlobalData::instance()->allCodecs.prepend(this);
+ QCoreGlobalData *globalInstance = QCoreGlobalData::instance();
+ if (globalInstance->allCodecs.isEmpty())
+ setup();
+
+ globalInstance->allCodecs.prepend(this);
}
@@ -503,7 +508,7 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
QCoreGlobalData *globalData = QCoreGlobalData::instance();
if (!globalData)
return 0;
- setup();
+ setup();
#ifndef QT_USE_ICU
QTextCodecCache *cache = &globalData->codecCache;
@@ -704,7 +709,7 @@ QTextCodec* QTextCodec::codecForLocale()
\fn int QTextCodec::mibEnum() const
Subclasses of QTextCodec must reimplement this function. It
- returns the MIBenum (see \l{IANA character-sets encoding file}
+ returns the \l{QTextCodec::mibEnum()}{MIBenum} (see \l{IANA character-sets encoding file}
for more information). It is important that each QTextCodec
subclass returns the correct unique value for this function.
*/
@@ -733,7 +738,7 @@ QList<QByteArray> QTextCodec::aliases() const
\a state can be 0, in which case the conversion is stateless and
default conversion rules should be used. If state is not 0, the
codec should save the state after the conversion in \a state, and
- adjust the remainingChars and invalidChars members of the struct.
+ adjust the \c remainingChars and \c invalidChars members of the struct.
*/
/*!
@@ -749,7 +754,7 @@ QList<QByteArray> QTextCodec::aliases() const
\a state can be 0 in which case the conversion is stateless and
default conversion rules should be used. If state is not 0, the
codec should save the state after the conversion in \a state, and
- adjust the remainingChars and invalidChars members of the struct.
+ adjust the \c remainingChars and \c invalidChars members of the struct.
*/
/*!
@@ -1049,7 +1054,10 @@ QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba, QTextCodec *defaultCo
while (++pos2 < header.size()) {
char ch = header.at(pos2);
if (ch == '\"' || ch == '\'' || ch == '>') {
- c = QTextCodec::codecForName(header.mid(pos, pos2 - pos));
+ QByteArray name = header.mid(pos, pos2 - pos);
+ if (name == "unicode") // QTBUG-41998, ICU will return UTF-16.
+ name = QByteArrayLiteral("UTF-8");
+ c = QTextCodec::codecForName(name);
return c ? c : defaultCodec;
}
}
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
index 9210d2737f..97be131203 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
@@ -354,10 +354,10 @@ text.toBase64(); // returns "UXQgaXMgZ3JlYXQh"
//! [39bis]
QByteArray text("<p>Hello?</p>");
-text.toBase64(QByteArray::Base64 | QByteArray::OmitTrailingEquals); // returns "PHA+SGVsbG8/PC9wPg"
-text.toBase64(QByteArray::Base64); // returns "PHA+SGVsbG8/PC9wPg=="
-text.toBase64(QByteArray::Base64Url); // returns "PHA-SGVsbG8_PC9wPg=="
-text.toBase64(QByteArray::Base64Url | QByteArray::OmitTrailingEquals); // returns "PHA-SGVsbG8_PC9wPg"
+text.toBase64(QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals); // returns "PHA+SGVsbG8/PC9wPg"
+text.toBase64(QByteArray::Base64Encoding); // returns "PHA+SGVsbG8/PC9wPg=="
+text.toBase64(QByteArray::Base64UrlEncoding); // returns "PHA-SGVsbG8_PC9wPg=="
+text.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); // returns "PHA-SGVsbG8_PC9wPg"
//! [39bis]
diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp
index f5c6b69695..17d0adf097 100644
--- a/src/corelib/doc/snippets/qstring/main.cpp
+++ b/src/corelib/doc/snippets/qstring/main.cpp
@@ -774,14 +774,6 @@ void Widget::splitCaseSensitiveFunction()
void Widget::sprintfFunction()
{
- //! [63]
- size_t BufSize;
- char buf[BufSize];
-
- ::snprintf(buf, BufSize, "%lld", 123456789LL);
- QString str = QString::fromUtf8(buf);
- //! [63]
-
//! [64]
QString result;
QTextStream(&result) << "pi = " << 3.14;
diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc
index 6910b18937..9385c08995 100644
--- a/src/corelib/doc/src/animation.qdoc
+++ b/src/corelib/doc/src/animation.qdoc
@@ -27,6 +27,7 @@
/*!
\group animation
+ \brief Provides an easy way for creating animated GUIs.
\title Animation Framework
This page lists classes belonging to \l{Qt Core}'s
@@ -46,8 +47,8 @@
\keyword Animation
The animation framework aims to provide an easy way for creating animated
- and smooth GUI's. By animating Qt properties, the framework provides great
- freedom for animating widgets and other \l{QObject}s. The framework can
+ and smooth GUIs. By animating Qt properties, the framework provides great
+ freedom for animating widgets and other {QObject}s. The framework can
also be used with the Graphics View framework. Many of the concepts
available in the animation framework are also available in \l{Qt Quick},
where it offers a declarative way of defining animations. Much of the
@@ -56,7 +57,7 @@
In this overview, we explain the basics of its architecture. We
also show examples of the most common techniques that the
- framework allows for animating QObjects and graphics items.
+ framework allows for animating {QObject}s and graphics items.
\tableofcontents
@@ -84,7 +85,7 @@
over the property using an easing curve. So when you want to
animate a value, you can declare it as a property and make your
class a QObject. Note that this gives us great freedom in
- animating already existing widgets and other \l{QObject}s.
+ animating already existing widgets and other {QObject}s.
Complex animations can be constructed by building a tree structure
of \l{QAbstractAnimation}s. The tree is built by using
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index 6017269272..a517ca32d3 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -386,7 +386,7 @@
\l{QMapIterator::hasPrevious()}{hasPrevious()},
\l{QMapIterator::previous()}{previous()}, and
\l{QMapIterator::peekPrevious()}{peekPrevious()}. The key and
- value components are extracted by calling key() and value() on
+ value components are extracted by calling \l{QMapIterator::key()}{key()} and \l{QMapIterator::value()}{value()} on
the object returned by next(), peekNext(), previous(), or
peekPrevious().
@@ -395,7 +395,7 @@
\snippet code/doc_src_containers.cpp 7
- QMapIterator also provides a key() and a value() function that
+ QMapIterator also provides a \l{QMapIterator::key()}{key()} and a \l{QMapIterator::value()}{value()} function that
operate directly on the iterator and that return the key and
value of the last item that the iterator jumped above. For
example, the following code copies the contents of a QMap into a
@@ -459,13 +459,13 @@
\snippet code/doc_src_containers.cpp 10
Unlike \l{Java-style iterators}, STL-style iterators point
- directly at items. The begin() function of a container returns an
+ directly at items. The \l{QList::begin()}{begin()} function of a container returns an
iterator that points to the first item in the container. The
- end() function of a container returns an iterator to the
+ \l{QList::end()}{end()} function of a container returns an iterator to the
imaginary item one position past the last item in the container.
- end() marks an invalid position; it must never be dereferenced.
+ \l {QList::end()}{end()} marks an invalid position; it must never be dereferenced.
It is typically used in a loop's break condition. If the list is
- empty, begin() equals end(), so we never execute the loop.
+ empty, \l{QList::begin}{begin()} equals \l{QList:end()}{end()}, so we never execute the loop.
The diagram below shows the valid iterator positions as red
arrows for a vector containing four items:
@@ -484,8 +484,8 @@
compilers also allow us to write \c{i->toLower()}, but some
don't.
- For read-only access, you can use const_iterator, constBegin(),
- and constEnd(). For example:
+ For read-only access, you can use const_iterator, \l{QList::constBegin}{constBegin()},
+ and \l{QList::constEnd()}{constEnd()}. For example:
\snippet code/doc_src_containers.cpp 12
@@ -759,7 +759,7 @@
QString.
QVector<T> also uses that algorithm for data types that can be
- moved around in memory using memcpy() (including the basic C++
+ moved around in memory using \c memcpy() (including the basic C++
types, the pointer types, and Qt's \l{shared classes}) but uses a
different algorithm for data types that can only be moved by
calling the copy constructor and a destructor. Since the cost of
@@ -790,7 +790,7 @@
\endlist
If you know approximately how many items you will store in a
- container, you can start by calling reserve(), and when you are
- done populating the container, you can call squeeze() to release
+ container, you can start by calling \l{QString::reserve()}{reserve()}, and when you are
+ done populating the container, you can call \l{QString::squeeze()}{squeeze()} to release
the extra preallocated memory.
*/
diff --git a/src/corelib/doc/src/datastreamformat.qdoc b/src/corelib/doc/src/datastreamformat.qdoc
index b6efe6aa33..56a6d0aafa 100644
--- a/src/corelib/doc/src/datastreamformat.qdoc
+++ b/src/corelib/doc/src/datastreamformat.qdoc
@@ -173,7 +173,7 @@
\li If the image is null a "null image" marker is saved;
otherwise the image is saved in PNG or BMP format (depending
on the stream version). If you want control of the format,
- stream the image into a QBuffer (using QImageIO) and stream
+ stream the image into a QBuffer (using QImageIOHandler/QImageIOPlugin) and stream
that.
\endlist
\row \li QKeySequence
diff --git a/src/corelib/doc/src/filestorage.qdoc b/src/corelib/doc/src/filestorage.qdoc
index 394d920923..a60c5846ff 100644
--- a/src/corelib/doc/src/filestorage.qdoc
+++ b/src/corelib/doc/src/filestorage.qdoc
@@ -86,8 +86,8 @@ read console input and write console output.
There are three general ways to use QTextStream when reading text files:
\list
- \li Chunk by chunk, by calling readLine() or readAll().
- \li Word by word. QTextStream supports streaming into QStrings, QByteArrays
+ \li Chunk by chunk, by calling \l{QBuffer::readLine()}{readLine()} or \l{QBuffer::readAll()}{readAll()}.
+ \li Word by word. QTextStream supports streaming into {QString}s, {QByteArray}s
and char* buffers. Words are delimited by space, and leading white space
is automatically skipped.
\li Character by character, by streaming into QChar or char types. This
diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc
index 1185fe8348..ec8edb4b6b 100644
--- a/src/corelib/doc/src/implicit-sharing.qdoc
+++ b/src/corelib/doc/src/implicit-sharing.qdoc
@@ -30,6 +30,7 @@
/*!
\group shared
+ \brief How to maximize resource usage by implicit data sharing.
\title Implicitly Shared Classes
These \l{Qt Core} classes provides a safe and efficient way of sharing and
diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
index f79e8a7dca..b9b1874d0f 100644
--- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
+++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
@@ -242,7 +242,7 @@
By default, for every connection you make, a signal is emitted;
two signals are emitted for duplicate connections. You can break
- all of these connections with a single disconnect() call.
+ all of these connections with a single \l{QObject::disconnect()}{disconnect()} call.
If you pass the Qt::UniqueConnection \a type, the connection will only
be made if it is not a duplicate. If there is already a duplicate
(exact same signal to the exact same slot on the same objects),
@@ -251,9 +251,7 @@
This example illustrates that objects can work together without needing to
know any information about each other. To enable this, the objects only
need to be connected together, and this can be achieved with some simple
- QObject::connect() function calls, or with \c{uic}'s
- \l{Using a Designer UI File in Your Application#Automatic Connections}
- {automatic connections} feature.
+ QObject::connect() function calls, or with \c{uic}'s {automatic connections} feature.
\section1 A Real Example
@@ -354,7 +352,7 @@
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
\endcode
- There are several advantages to using connect() with function pointers.
+ There are several advantages to using QObject::connect() with function pointers.
First, it allows the compiler to check that the signal's arguments are
compatible with the slot's arguments. Arguments can also be implicitly
converted by the compiler, if needed.
@@ -407,7 +405,7 @@
will open: "Tax File", "Accounts File", or "Report File".
In order to open the correct file, you use QSignalMapper::setMapping() to
- map all the clicked() signals to a QSignalMapper object. Then you connect
+ map all the QPushButton::clicked() signals to a QSignalMapper object. Then you connect
the file's QPushButton::clicked() signal to the QSignalMapper::map() slot.
\snippet signalmapper/filereader.cpp 0
diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc
index b281eb177b..846eb7d1f0 100644
--- a/src/corelib/doc/src/statemachine.qdoc
+++ b/src/corelib/doc/src/statemachine.qdoc
@@ -27,6 +27,7 @@
/*!
\group statemachine
+ \brief How to create and execute state graphs.
\title State Machine Classes
These \l{Qt Core} classes are part of the \l{The State Machine Framework}{
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 8ac84599f2..ee396409d8 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -78,7 +78,7 @@
# define Q_NO_USING_KEYWORD
#elif defined(_MSC_VER)
-# define Q_CC_MSVC
+# define Q_CC_MSVC (_MSC_VER)
# define Q_CC_MSVC_NET
# define Q_OUTOFLINE_TEMPLATE inline
# if _MSC_VER < 1600
@@ -137,14 +137,14 @@
# endif
#elif defined(__GNUC__)
-# define Q_CC_GNU
+# define Q_CC_GNU (__GNUC__ * 100 + __GNUC_MINOR__)
# define Q_C_CALLBACKS
# if defined(__MINGW32__)
# define Q_CC_MINGW
# endif
# if defined(__INTEL_COMPILER)
/* Intel C++ also masquerades as GCC */
-# define Q_CC_INTEL
+# define Q_CC_INTEL (__INTEL_COMPILER)
# define Q_ASSUME_IMPL(expr) __assume(expr)
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# if __INTEL_COMPILER >= 1300 && !defined(__APPLE__)
@@ -152,7 +152,26 @@
# endif
# elif defined(__clang__)
/* Clang also masquerades as GCC */
-# define Q_CC_CLANG
+# if defined(__apple_build_version__)
+# /* http://en.wikipedia.org/wiki/Xcode#Toolchain_Versions */
+# if __apple_build_version__ >= 600051
+# define Q_CC_CLANG 305
+# elif __apple_build_version__ >= 503038
+# define Q_CC_CLANG 304
+# elif __apple_build_version__ >= 500275
+# define Q_CC_CLANG 303
+# elif __apple_build_version__ >= 425024
+# define Q_CC_CLANG 302
+# elif __apple_build_version__ >= 318045
+# define Q_CC_CLANG 301
+# elif __apple_build_version__ >= 211101
+# define Q_CC_CLANG 300
+# else
+# error "Unknown Apple Clang version"
+# endif
+# else
+# define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__)
+# endif
# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# if !defined(__has_extension)
@@ -168,7 +187,7 @@
# endif
# else
/* Plain GCC */
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
+# if Q_CC_GNU >= 405
# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
@@ -202,7 +221,7 @@
# define QT_NO_ARM_EABI
# endif
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 && !defined(Q_CC_CLANG)
+# if Q_CC_GNU >= 403 && !defined(Q_CC_CLANG)
# define Q_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
# endif
@@ -308,7 +327,7 @@
/* Using the `using' keyword avoids Intel C++ for Linux warnings */
# elif defined(__INTEL_COMPILER)
-# define Q_CC_INTEL
+# define Q_CC_INTEL (__INTEL_COMPILER)
/* Uses CFront, make sure to read the manual how to tweak templates. */
# elif defined(__ghs)
@@ -566,7 +585,7 @@
# endif
// Variadic macros are supported for gnu++98, c++11, c99 ... since 2.9
-# if ((__clang_major__ * 100) + __clang_minor__) >= 209
+# if Q_CC_CLANG >= 209
# if !defined(__STRICT_ANSI__) || defined(__GXX_EXPERIMENTAL_CXX0X__) \
|| (defined(__cplusplus) && (__cplusplus >= 201103L)) \
|| (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
@@ -581,7 +600,7 @@
# define Q_COMPILER_ALIGNAS
# define Q_COMPILER_ALIGNOF
# endif
-# if 0 /* not implemented in clang yet */
+# if __has_feature(cxx_atomic) && __has_include(<atomic>)
# define Q_COMPILER_ATOMICS
# endif
# if __has_feature(cxx_attributes)
@@ -668,7 +687,7 @@
# define Q_COMPILER_VARIADIC_TEMPLATES
# endif
/* Features that have no __has_feature() check */
-# if ((__clang_major__ * 100) + __clang_minor__) >= 209 /* since clang 2.9 */
+# if Q_CC_CLANG >= 209 /* since clang 2.9 */
# define Q_COMPILER_EXTERN_TEMPLATES
# endif
# endif
@@ -709,7 +728,7 @@
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
# define Q_COMPILER_RESTRICTED_VLA
# define Q_COMPILER_THREADSAFE_STATICS
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+# if Q_CC_GNU >= 403
// GCC supports binary literals in C, C++98 and C++11 modes
# define Q_COMPILER_BINARY_LITERALS
# endif
@@ -720,13 +739,13 @@
# define Q_COMPILER_VARIADIC_MACROS
# endif
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+# if Q_CC_GNU >= 403
/* C++11 features supported in GCC 4.3: */
# define Q_COMPILER_DECLTYPE
# define Q_COMPILER_RVALUE_REFS
# define Q_COMPILER_STATIC_ASSERT
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404
+# if Q_CC_GNU >= 404
/* C++11 features supported in GCC 4.4: */
# define Q_COMPILER_AUTO_FUNCTION
# define Q_COMPILER_AUTO_TYPE
@@ -735,7 +754,7 @@
# define Q_COMPILER_UNICODE_STRINGS
# define Q_COMPILER_VARIADIC_TEMPLATES
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
+# if Q_CC_GNU >= 405
/* C++11 features supported in GCC 4.5: */
# define Q_COMPILER_EXPLICIT_CONVERSIONS
/* GCC 4.4 implements initializer_list but does not define typedefs required
@@ -745,7 +764,7 @@
# define Q_COMPILER_RAW_STRINGS
# define Q_COMPILER_CLASS_ENUM
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
+# if Q_CC_GNU >= 406
/* Pre-4.6 compilers implement a non-final snapshot of N2346, hence default and delete
* functions are supported only if they are public. Starting from 4.6, GCC handles
* final version - the access modifier is not relevant. */
@@ -757,7 +776,7 @@
# define Q_COMPILER_UNRESTRICTED_UNIONS
# define Q_COMPILER_RANGE_FOR
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
+# if Q_CC_GNU >= 407
/* GCC 4.4 implemented <atomic> and std::atomic using its old intrinsics.
* However, the implementation is incomplete for most platforms until GCC 4.7:
* instead, std::atomic would use an external lock. Since we need an std::atomic
@@ -773,20 +792,20 @@
# define Q_COMPILER_TEMPLATE_ALIAS
# define Q_COMPILER_UDL
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
+# if Q_CC_GNU >= 408
# define Q_COMPILER_ATTRIBUTES
# define Q_COMPILER_ALIGNAS
# define Q_COMPILER_ALIGNOF
# define Q_COMPILER_INHERITING_CONSTRUCTORS
# define Q_COMPILER_THREAD_LOCAL
-# if (__GNUC__ * 100 + __GNUC_MINOR__) > 408 || __GNUC_PATCHLEVEL__ >= 1
+# if Q_CC_GNU > 408 || __GNUC_PATCHLEVEL__ >= 1
# define Q_COMPILER_REF_QUALIFIERS
# endif
# endif
/* C++11 features are complete as of GCC 4.8.1 */
# endif
# if __cplusplus > 201103L
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409
+# if Q_CC_GNU >= 409
/* C++1y features in GCC 4.9 - deprecated, do not update this list */
//# define Q_COMPILER_BINARY_LITERALS // already supported since GCC 4.3 as an extension
# define Q_COMPILER_LAMBDA_CAPTURES
@@ -880,6 +899,15 @@
# undef Q_COMPILER_INITIALIZER_LISTS
# undef Q_COMPILER_RVALUE_REFS
# undef Q_COMPILER_REF_QUALIFIERS
+// Also disable <atomic>, since it's clearly not there
+# undef Q_COMPILER_ATOMICS
+# endif
+# if defined(_LIBCPP_VERSION)
+// libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler
+// doesn't support it. That's required for the Intel compiler on OS X, for example.
+# if !__has_feature(cxx_atomic)
+# undef Q_COMPILER_ATOMICS
+# endif
# endif
# if defined(Q_COMPILER_THREADSAFE_STATICS) && defined(Q_OS_MAC)
// Mac OS X: Apple's low-level implementation of the C++ support library
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 4a21ab88d8..4e8721f7d7 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -877,7 +877,7 @@ public:
// (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#382).
// GCC 4.3 and 4.4 have support for decltype, but are affected by DR 382.
# if defined(Q_COMPILER_DECLTYPE) && \
- (defined(Q_CC_CLANG) || defined(Q_CC_INTEL) || !defined(Q_CC_GNU) || (__GNUC__ * 100 + __GNUC_MINOR__) >= 405)
+ (defined(Q_CC_CLANG) || defined(Q_CC_INTEL) || !defined(Q_CC_GNU) || Q_CC_GNU >= 405)
# define QT_FOREACH_DECLTYPE(x) typename QtPrivate::remove_reference<decltype(x)>::type
# else
# define QT_FOREACH_DECLTYPE(x) __typeof__((x))
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index c3ec2bc7f6..7ca0aa7f0b 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -84,14 +84,7 @@ class QLibraryInfoPrivate
{
public:
static QSettings *findConfiguration();
-#ifndef QT_BOOTSTRAPPED
- static void cleanup()
- {
- QLibrarySettings *ls = qt_library_settings();
- if (ls)
- ls->settings.reset(0);
- }
-#else
+#ifdef QT_BOOTSTRAPPED
static bool haveGroup(QLibraryInfo::PathGroup group)
{
QLibrarySettings *ls = qt_library_settings();
@@ -114,7 +107,6 @@ QLibrarySettings::QLibrarySettings()
: settings(QLibraryInfoPrivate::findConfiguration())
{
#ifndef QT_BOOTSTRAPPED
- qAddPostRoutine(QLibraryInfoPrivate::cleanup);
bool haveEffectivePaths;
bool havePaths;
#endif
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index f356bab42d..39c5ac602e 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1101,14 +1101,9 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
if (!pattern) {
// after destruction of static QMessagePattern instance
message.append(str);
- message.append(QLatin1Char('\n'));
return message;
}
- // don't print anything if pattern was empty
- if (pattern->tokens[0] == 0)
- return message;
-
bool skip = false;
// we do not convert file, function, line literals to local encoding due to overhead
@@ -1227,7 +1222,6 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
message.append(QLatin1String(token));
}
}
- message.append(QLatin1Char('\n'));
return message;
}
@@ -1289,7 +1283,7 @@ static void android_default_message_handler(QtMsgType type,
case QtFatalMsg: priority = ANDROID_LOG_FATAL; break;
};
- __android_log_print(priority, "Qt", "%s:%d (%s): %s",
+ __android_log_print(priority, "Qt", "%s:%d (%s): %s\n",
context.file, context.line,
context.function, qPrintable(message));
}
@@ -1303,16 +1297,21 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
{
QString logMessage = qFormatLogMessage(type, context, buf);
+ // print nothing if message pattern didn't apply / was empty.
+ // (still print empty lines, e.g. because message itself was empty)
+ if (logMessage.isNull())
+ return;
+
if (!qt_logging_to_console()) {
#if defined(Q_OS_WIN)
+ logMessage.append(QLatin1Char('\n'));
OutputDebugString(reinterpret_cast<const wchar_t *>(logMessage.utf16()));
return;
#elif defined(QT_USE_SLOG2)
+ logMessage.append(QLatin1Char('\n'));
slog2_default_handler(type, logMessage.toLocal8Bit().constData());
return;
#elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
- // remove trailing \n, systemd appears to want them newline-less
- logMessage.chop(1);
systemd_default_message_handler(type, context, logMessage);
return;
#elif defined(Q_OS_ANDROID)
@@ -1320,7 +1319,7 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
return;
#endif
}
- fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
+ fprintf(stderr, "%s\n", logMessage.toLocal8Bit().constData());
fflush(stderr);
}
@@ -1380,7 +1379,7 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
}
ungrabMessageHandler();
} else {
- fprintf(stderr, "%s", message.toLocal8Bit().constData());
+ fprintf(stderr, "%s\n", message.toLocal8Bit().constData());
}
}
@@ -1579,7 +1578,7 @@ void qErrnoWarning(int code, const char *msg, ...)
The default \a pattern is "%{if-category}%{category}: %{endif}%{message}".
The \a pattern can also be changed at runtime by setting the QT_MESSAGE_PATTERN
- environment variable; if both qSetMessagePattern() is called and QT_MESSAGE_PATTERN is
+ environment variable; if both \l qSetMessagePattern() is called and QT_MESSAGE_PATTERN is
set, the environment variable takes precedence.
Custom message handlers can use qFormatLogMessage() to take \a pattern into account.
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 4e074bcdb5..53d2b7b58b 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -134,7 +134,7 @@
\value AA_MacDontSwapCtrlAndMeta On Mac OS X by default, Qt swaps the
Control and Meta (Command) keys (i.e., whenever Control is pressed, Qt
sends Meta, and whenever Meta is pressed Control is sent). When this
- attribute is true, Qt will not do the flip. QKeySequence::StandardShortcuts
+ attribute is true, Qt will not do the flip. \l QKeySequence::StandardKey
will also flip accordingly (i.e., QKeySequence::Copy will be
Command+C on the keyboard regardless of the value set, though what is output for
QKeySequence::toString(QKeySequence::PortableText) will be different).
@@ -144,7 +144,7 @@
to be consistent in pixels-per-point across devices rather than
defining 1 point as 1/72 inch.
- \value AA_X11InitThreads Calls XInitThreads() as part of the QApplication
+ \value AA_X11InitThreads Calls \c XInitThreads() as part of the QApplication
construction in order to make Xlib calls thread-safe. This
attribute must be set before QApplication is constructed.
@@ -159,10 +159,11 @@
\value AA_UseHighDpiPixmaps Make QIcon::pixmap() generate high-dpi pixmaps
that can be larger than the requested size. Such pixmaps will have
- devicePixelRatio set to a value higher than 1. After setting this
- attribute application code that uses pixmap sizes in layout geometry
- calculations should typically divide by QPixmap::devicePixelRatio()
- to get device-independent layout geometry.
+ \l {QPixmap::devicePixelRatio}{devicePixelRatio()} set to a value higher than 1.
+
+ After setting this attribute, application code that uses pixmap
+ sizes in layout geometry calculations should typically divide by
+ \l {QPixmap::devicePixelRatio}{devicePixelRatio()} to get device-independent layout geometry.
\value AA_ForceRasterWidgets Make top-level widgets use pure raster surfaces,
and do not support non-native GL-based child widgets.
@@ -182,7 +183,7 @@
\l{http://www.mesa3d.org/llvmpipe.html}{Mesa llvmpipe}, providing
OpenGL 2.1. The value may have no effect if no such OpenGL
implementation is available. The default name of this library is
- opengl32sw.dll and can be overridden by setting the environment
+ \c opengl32sw.dll and can be overridden by setting the environment
variable \e QT_OPENGL_DLL. See the platform-specific pages, for
instance \l{Qt for Windows}, for more information. This value has
been added in Qt 5.4.
@@ -221,7 +222,7 @@
\value AllButtons This value corresponds to a mask of all
possible mouse buttons. Use to set the 'acceptedButtons'
- property of a mouseArea to accept ALL mouse buttons.
+ property of a MouseArea to accept ALL mouse buttons.
\value LeftButton The left button is pressed, or an event refers
to the left button. (The left button may be the right button on
@@ -2443,7 +2444,7 @@
\value ImhExclusiveInputMask This mask yields nonzero if any of the exclusive flags are used.
- \note If several exclusive flags are ORed together, the resulting character set will
+ \note If several exclusive flags are OR-ed together, the resulting character set will
consist of the union of the specified sets. For instance specifying \c ImhNumbersOnly and
\c ImhUppercaseOnly would yield a set consisting of numbers and uppercase letters.
@@ -2803,11 +2804,11 @@
This enum type describes the state of a gesture.
+ \value NoGesture No gesture has been detected.
\value GestureStarted A continuous gesture has started.
\value GestureUpdated A gesture continues.
\value GestureFinished A gesture has finished.
\value GestureCanceled A gesture was canceled.
- \omitvalue NoGesture
\sa QGesture
*/
@@ -2969,8 +2970,8 @@
This enum provides additional information concerning a QMouseEvent.
\value MouseEventCreatedDoubleClick Indicates that Qt has created a
- MouseButtonDblClick event from this event. The flag is set in the causing
- MouseButtonPress, and not in the resulting MouseButtonDblCLick.
+ \l {QEvent::MouseButtonDblClick}{MouseButtonDblClick} event from this event. The flag is set in the causing
+ \l {QEvent::MouseButtonPress}{MouseButtonPress}, and not in the resulting \l {QEvent::MouseButtonDblClick}{MouseButtonDblClick}.
\omitvalue MouseEventFlagMask
*/
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 26ac56396b..55cb31c62b 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -87,9 +87,9 @@
ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to
auto-detection implemented below.
*/
-#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__arm64__)
+#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__)
# define Q_PROCESSOR_ARM
-# if defined(__arm64__)
+# if defined(__aarch64__)
# define Q_PROCESSOR_ARM_64
# else
# define Q_PROCESSOR_ARM_32
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index bdc362ef22..77788e3cca 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -148,9 +148,8 @@ win32 {
HEADERS += io/qfilesystemwatcher_fsevents_p.h
}
macx {
- SOURCES += \
- io/qstorageinfo_mac.cpp \
- io/qstandardpaths_mac.cpp
+ SOURCES += io/qstorageinfo_mac.cpp
+ OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
LIBS += -framework DiskArbitration -framework IOKit
} else:ios {
OBJECTIVE_SOURCES += io/qstandardpaths_ios.mm
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 8d757a7773..60f04ce4f1 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -261,12 +261,6 @@ QDataStream::QDataStream()
/*!
Constructs a data stream that uses the I/O device \a d.
- \warning If you use QSocket or QSocketDevice as the I/O device \a d
- for reading data, you must make sure that enough data is available
- on the socket for the operation to successfully proceed;
- QDataStream does not have any means to handle or recover from
- short-reads.
-
\sa setDevice(), device()
*/
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 42250b629d..a126690240 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -73,6 +73,17 @@ QT_BEGIN_NAMESPACE
# endif
#endif
+#ifdef Q_OS_WIN
+// on Windows, read() and write() use int and unsigned int
+typedef int SignedIOType;
+typedef unsigned int UnsignedIOType;
+#else
+typedef ssize_t SignedIOType;
+typedef size_t UnsignedIOType;
+Q_STATIC_ASSERT_X(sizeof(SignedIOType) == sizeof(UnsignedIOType),
+ "Unsupported: read/write return a type with different size as the len parameter");
+#endif
+
/*! \class QFSFileEngine
\inmodule QtCore
\brief The QFSFileEngine class implements Qt's default file engine.
@@ -605,13 +616,16 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len)
} else if (fd != -1) {
// Unbuffered stdio mode.
-#ifdef Q_OS_WIN
- int result;
-#else
- ssize_t result;
-#endif
+ SignedIOType result;
do {
- result = QT_READ(fd, data + readBytes, size_t(len - readBytes));
+ // calculate the chunk size
+ // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
+ // we limit to the size of the signed type, otherwise we could get a negative number as a result
+ quint64 wantedBytes = quint64(len) - quint64(readBytes);
+ UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
+ if (chunkSize > wantedBytes)
+ chunkSize = wantedBytes;
+ result = QT_READ(fd, data + readBytes, chunkSize);
} while (result > 0 && (readBytes += result) < len);
eof = !(result == -1);
@@ -722,13 +736,16 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len)
} else if (fd != -1) {
// Unbuffered stdio mode.
-#ifdef Q_OS_WIN
- int result;
-#else
- ssize_t result;
-#endif
+ SignedIOType result;
do {
- result = QT_WRITE(fd, data + writtenBytes, size_t(len - writtenBytes));
+ // calculate the chunk size
+ // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
+ // we limit to the size of the signed type, otherwise we could get a negative number as a result
+ quint64 wantedBytes = quint64(len) - quint64(writtenBytes);
+ UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
+ if (chunkSize > wantedBytes)
+ chunkSize = wantedBytes;
+ result = QT_WRITE(fd, data + writtenBytes, chunkSize);
} while (result > 0 && (writtenBytes += result) < len);
}
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 0896432837..36f88f2774 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -788,7 +788,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
char *readPtr = data;
forever {
// Try reading from the buffer.
- int bufferReadChunkSize = d->buffer.read(data, maxSize);
+ qint64 bufferReadChunkSize = d->buffer.read(data, maxSize);
if (bufferReadChunkSize > 0) {
*d->pPos += bufferReadChunkSize;
readSoFar += bufferReadChunkSize;
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index 10d92a896d..d764cb0fbb 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -98,19 +98,19 @@ public:
first++;
return ch;
}
- int read(char* target, qint64 size) {
- int r = qMin(size, len);
+ qint64 read(char* target, qint64 size) {
+ qint64 r = qMin(size, len);
memcpy(target, first, r);
len -= r;
first += r;
return r;
}
- int peek(char* target, qint64 size) {
- int r = qMin(size, len);
+ qint64 peek(char* target, qint64 size) {
+ qint64 r = qMin(size, len);
memcpy(target, first, r);
return r;
}
- char* reserve(int size) {
+ char* reserve(qint64 size) {
makeSpace(size + len, freeSpaceAtEnd);
char* writePtr = first + len;
len += size;
@@ -128,16 +128,16 @@ public:
clear();
return retVal;
}
- int readLine(char* target, qint64 size) {
- int r = qMin(size, len);
+ qint64 readLine(char* target, qint64 size) {
+ qint64 r = qMin(size, len);
char* eol = static_cast<char*>(memchr(first, '\n', r));
if (eol)
r = 1+(eol-first);
memcpy(target, first, r);
len -= r;
first += r;
- return int(r);
- }
+ return r;
+ }
bool canReadLine() const {
return memchr(first, '\n', len);
}
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index 18a782a8f3..c256507430 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -287,7 +287,7 @@ bool QLockFilePrivate::getLockInfo(qint64 *pid, QString *hostname, QString *appn
appNameLine.chop(1);
QByteArray hostNameLine = reader.readLine();
hostNameLine.chop(1);
- if (pidLine.isEmpty() || appNameLine.isEmpty())
+ if (pidLine.isEmpty())
return false;
qint64 thePid = pidLine.toLongLong();
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 2fe93f0af6..3ed973494b 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -183,7 +183,7 @@ bool QLockFilePrivate::isApparentlyStale() const
QString hostname, appname;
if (!getLockInfo(&pid, &hostname, &appname))
return false;
- if (hostname == QString::fromLocal8Bit(localHostName())) {
+ if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
if (::kill(pid, 0) == -1 && errno == ESRCH)
return true; // PID doesn't exist anymore
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index d896da176a..ebca7d57ff 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1637,6 +1637,15 @@ bool QConfFileSettingsPrivate::readIniFile(const QByteArray &data,
int sectionPosition = 0;
bool ok = true;
+#ifndef QT_NO_TEXTCODEC
+ // detect utf8 BOM
+ const uchar *dd = (const uchar *)data.constData();
+ if (data.size() >= 3 && dd[0] == 0xef && dd[1] == 0xbb && dd[2] == 0xbf) {
+ iniCodec = QTextCodec::codecForName("UTF-8");
+ dataPos = 3;
+ }
+#endif
+
while (readIniLine(data, dataPos, lineStart, lineLen, equalsPos)) {
char ch = data.at(lineStart);
if (ch == '[') {
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index 4752077f87..344bec0309 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -235,8 +235,10 @@ static QVariant qtValue(CFPropertyListRef cfvalue)
int i;
qint64 ll;
- if (CFNumberGetValue(cfnumber, kCFNumberIntType, &i))
+ if (CFNumberGetType(cfnumber) == kCFNumberIntType) {
+ CFNumberGetValue(cfnumber, kCFNumberIntType, &i);
return i;
+ }
CFNumberGetValue(cfnumber, kCFNumberLongLongType, &ll);
return ll;
}
diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h
index cb29b4c83a..715f13530a 100644
--- a/src/corelib/io/qsettings_p.h
+++ b/src/corelib/io/qsettings_p.h
@@ -282,7 +282,7 @@ public:
bool isWritable() const;
QString fileName() const;
- static bool readIniFile(const QByteArray &data, UnparsedSettingsMap *unparsedIniSections);
+ bool readIniFile(const QByteArray &data, UnparsedSettingsMap *unparsedIniSections);
static bool readIniSection(const QSettingsKey &section, const QByteArray &data,
ParsedSettingsMap *settingsMap, QTextCodec *codec);
static bool readIniLine(const QByteArray &data, int &dataPos, int &lineStart, int &lineLen,
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 2583e46ad8..6950d58fda 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -195,7 +195,7 @@ QT_BEGIN_NAMESPACE
\li "~/Library/Preferences"
\li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
\row \li DownloadLocation
- \li "~/Documents"
+ \li "~/Downloads"
\li "C:/Users/<USER>/Documents"
\row \li GenericCacheLocation
\li "~/Library/Caches", "/Library/Caches"
@@ -526,7 +526,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
an empty QString if no relevant location can be found.
*/
-#if !defined(Q_OS_MAC) && !defined(QT_BOOTSTRAPPED)
+#if !defined(Q_OS_OSX) && !defined(QT_BOOTSTRAPPED)
QString QStandardPaths::displayName(StandardLocation type)
{
switch (type) {
diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm
index cdca28b8b5..9b500f4623 100644
--- a/src/corelib/io/qstandardpaths_ios.mm
+++ b/src/corelib/io/qstandardpaths_ios.mm
@@ -92,6 +92,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
break;
case AppDataLocation:
case AppLocalDataLocation:
+ location = pathForDirectory(NSApplicationSupportDirectory);
+ break;
case GenericDataLocation:
location = pathForDirectory(NSDocumentDirectory);
break;
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.mm
index 673b734d40..01d1c01f78 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.mm
@@ -33,6 +33,7 @@
#include "qstandardpaths.h"
#include <qdir.h>
+#include <qurl.h>
#include <private/qcore_mac_p.h>
#ifndef QT_BOOTSTRAPPED
@@ -55,8 +56,6 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
return kPreferencesFolderType;
case QStandardPaths::DesktopLocation:
return kDesktopFolderType;
- case QStandardPaths::DownloadLocation: // needs NSSearchPathForDirectoriesInDomains with NSDownloadsDirectory
- // which needs an objective-C *.mm file...
case QStandardPaths::DocumentsLocation:
return kDocumentsFolderType;
case QStandardPaths::FontsLocation:
@@ -113,6 +112,15 @@ static void appendOrganizationAndApp(QString &path)
static QString macLocation(QStandardPaths::StandardLocation type, short domain)
{
+ // https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html
+ if (type == QStandardPaths::DownloadLocation) {
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSURL *url = [fileManager URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
+ if (!url)
+ return QString();
+ return QString::fromNSString([url path]);
+ }
+
// http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
FSRef ref;
OSErr err = FSFindFolder(domain, translateLocation(type), false, &ref);
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 469c223b00..2ad6dfa121 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -131,10 +131,13 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return QString();
}
// "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700."
+ // since the current user is the owner, set both xxxUser and xxxOwner
QFile file(xdgRuntimeDir);
- const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser;
+ const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
+ | QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner;
if (file.permissions() != wantedPerms && !file.setPermissions(wantedPerms)) {
- qWarning("QStandardPaths: wrong permissions on runtime directory %s", qPrintable(xdgRuntimeDir));
+ qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s",
+ qPrintable(xdgRuntimeDir), qPrintable(file.errorString()));
return QString();
}
return xdgRuntimeDir;
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index ca5903ae36..bec7420dc7 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -90,17 +90,16 @@ static bool isPseudoFs(const QString &mountDir, const QByteArray &type)
{
if (mountDir.startsWith(QLatin1String("/dev"))
|| mountDir.startsWith(QLatin1String("/proc"))
- || mountDir.startsWith(QLatin1String("/run"))
|| mountDir.startsWith(QLatin1String("/sys"))
|| mountDir.startsWith(QLatin1String("/var/run"))
|| mountDir.startsWith(QLatin1String("/var/lock"))) {
return true;
}
+ if (type == "tmpfs")
+ return true;
#if defined(Q_OS_LINUX)
- if (type == "rootfs")
+ if (type == "rootfs" || type == "rpc_pipefs")
return true;
-#else
- Q_UNUSED(type);
#endif
return false;
diff --git a/src/corelib/io/qstorageinfo_win.cpp b/src/corelib/io/qstorageinfo_win.cpp
index 1ab34e56d4..51a268f58c 100644
--- a/src/corelib/io/qstorageinfo_win.cpp
+++ b/src/corelib/io/qstorageinfo_win.cpp
@@ -45,7 +45,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qvarlengtharray.h>
-#include <Windows.h>
+#include <qt_windows.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index d4c5e03058..b21e9b51e1 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -403,6 +403,7 @@
#include "qdebug.h"
#include "qhash.h"
#include "qdir.h" // for QDir::fromNativeSeparators
+#include "qdatastream.h"
#include "qtldurl_p.h"
#include "private/qipaddress_p.h"
#include "qurlquery.h"
@@ -429,6 +430,16 @@ static inline QString fileScheme()
return QStringLiteral("file");
}
+static inline QString webDavScheme()
+{
+ return QStringLiteral("webdavs");
+}
+
+static inline QString webDavSslTag()
+{
+ return QStringLiteral("@SSL");
+}
+
#ifdef Q_COMPILER_CLASS_ENUM
# define colon_uchar : uchar
#else
@@ -992,10 +1003,15 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro
}
// did we set to the file protocol?
- if (scheme == fileScheme())
+ if (scheme == fileScheme()
+#ifdef Q_OS_WIN
+ || scheme == webDavScheme()
+#endif
+ ) {
flags |= IsLocalFile;
- else
+ } else {
flags &= ~IsLocalFile;
+ }
return true;
}
@@ -3738,7 +3754,7 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
QUrl url;
if (localFile.isEmpty())
return url;
- url.setScheme(fileScheme());
+ QString scheme = fileScheme();
QString deslashified = QDir::fromNativeSeparators(localFile);
// magic for drives on windows
@@ -3747,13 +3763,21 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
} else if (deslashified.startsWith(QLatin1String("//"))) {
// magic for shared drive on windows
int indexOfPath = deslashified.indexOf(QLatin1Char('/'), 2);
- url.setHost(deslashified.mid(2, indexOfPath - 2));
+ QString hostSpec = deslashified.mid(2, indexOfPath - 2);
+ // Check for Windows-specific WebDAV specification: "//host@SSL/path".
+ if (hostSpec.endsWith(webDavSslTag(), Qt::CaseInsensitive)) {
+ hostSpec.chop(4);
+ scheme = webDavScheme();
+ }
+ url.setHost(hostSpec);
+
if (indexOfPath > 2)
deslashified = deslashified.right(deslashified.length() - indexOfPath);
else
deslashified.clear();
}
+ url.setScheme(scheme);
url.setPath(deslashified, DecodedMode);
return url;
}
@@ -3783,8 +3807,14 @@ QString QUrl::toLocalFile() const
// magic for shared drive on windows
if (!d->host.isEmpty()) {
- tmp = QStringLiteral("//") + host() + (ourPath.length() > 0 && ourPath.at(0) != QLatin1Char('/')
- ? QLatin1Char('/') + ourPath : ourPath);
+ tmp = QStringLiteral("//") + host();
+#ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only.
+ if (scheme() == webDavScheme())
+ tmp += webDavSslTag();
+#endif
+ if (!ourPath.isEmpty() && !ourPath.startsWith(QLatin1Char('/')))
+ tmp += QLatin1Char('/');
+ tmp += ourPath;
} else {
tmp = ourPath;
#ifdef Q_OS_WIN
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 74a7ea1988..a9cfa3e7ca 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1552,13 +1552,13 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
- \fn void QAbstractItemModel::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+ \fn void QAbstractItemModel::rowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row)
\since 4.6
This signal is emitted after rows have been moved within the
- model. The items between \a sourceStart and \a sourceEnd
- inclusive, under the given \a sourceParent item have been moved to \a destinationParent
- starting at the row \a destinationRow.
+ model. The items between \a start and \a end
+ inclusive, under the given \a parent item have been moved to \a destination
+ starting at the row \a row.
\b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
@@ -1584,13 +1584,13 @@ QAbstractItemModel::~QAbstractItemModel()
*/
/*!
- \fn void QAbstractItemModel::columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
+ \fn void QAbstractItemModel::columnsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column)
\since 4.6
This signal is emitted after columns have been moved within the
- model. The items between \a sourceStart and \a sourceEnd
- inclusive, under the given \a sourceParent item have been moved to \a destinationParent
- starting at the column \a destinationColumn.
+ model. The items between \a start and \a end
+ inclusive, under the given \a parent item have been moved to \a destination
+ starting at the column \a column.
\b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
@@ -1842,7 +1842,9 @@ QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
/*!
Returns \c{true} if a model can accept a drop of the \a data. This
- default implementation always returns \c{true}.
+ default implementation only checks if \a data has at least one format
+ in the list of mimeTypes() and if \a action is among the
+ model's supportedDropActions().
Reimplement this function in your custom model, if you want to
test whether the \a data can be dropped at \a row, \a column,
@@ -1855,12 +1857,19 @@ bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction a
int row, int column,
const QModelIndex &parent) const
{
- Q_UNUSED(data)
- Q_UNUSED(action)
Q_UNUSED(row)
Q_UNUSED(column)
Q_UNUSED(parent)
- return true;
+
+ if (!(action & supportedDropActions()))
+ return false;
+
+ const QStringList modelTypes = mimeTypes();
+ for (int i = 0; i < modelTypes.count(); ++i) {
+ if (data->hasFormat(modelTypes.at(i)))
+ return true;
+ }
+ return false;
}
/*!
@@ -2711,7 +2720,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
persistent indexes in the model, which you would otherwise be
required to do yourself. Using beginMoveRows and endMoveRows
is an alternative to emitting layoutAboutToBeChanged and
- layoutChanged directly along with changePersistentIndexes.
+ layoutChanged directly along with changePersistentIndex.
The \a sourceParent index corresponds to the parent from which the
rows are moved; \a sourceFirst and \a sourceLast are the first and last
@@ -2978,7 +2987,7 @@ void QAbstractItemModel::endRemoveColumns()
persistent indexes in the model, which you would otherwise be
required to do yourself. Using beginMoveRows and endMoveRows
is an alternative to emitting layoutAboutToBeChanged and
- layoutChanged directly along with changePersistentIndexes.
+ layoutChanged directly along with changePersistentIndex.
The \a sourceParent index corresponds to the parent from which the
columns are moved; \a sourceFirst and \a sourceLast are the first and last
@@ -3165,11 +3174,11 @@ void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QM
/*!
\since 4.1
- Changes the QPersistentModelIndexes that is equal to the indexes in the
+ Changes the {QPersistentModelIndex}es that are equal to the indexes in the
given \a from model index list to the given \a to model index list.
If no persistent model indexes equal to the indexes in the given \a from
- model index list was found, nothing is changed.
+ model index list are found, nothing is changed.
\sa persistentIndexList(), changePersistentIndex()
*/
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index ce26293183..b7f988ef7c 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -384,6 +384,26 @@ QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const
return d->model->mimeData(list);
}
+void QAbstractProxyModelPrivate::mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
+ int *sourceRow, int *sourceColumn, QModelIndex *sourceParent) const
+{
+ Q_Q(const QAbstractProxyModel);
+ *sourceRow = -1;
+ *sourceColumn = -1;
+ if (row == -1 && column == -1) {
+ *sourceParent = q->mapToSource(parent);
+ } else if (row == q->rowCount(parent)) {
+ *sourceParent = q->mapToSource(parent);
+ *sourceRow = model->rowCount(*sourceParent);
+ } else {
+ QModelIndex proxyIndex = q->index(row, column, parent);
+ QModelIndex sourceIndex = q->mapToSource(proxyIndex);
+ *sourceRow = sourceIndex.row();
+ *sourceColumn = sourceIndex.column();
+ *sourceParent = sourceIndex.parent();
+ }
+}
+
/*!
\reimp
\since 5.4
@@ -392,8 +412,11 @@ bool QAbstractProxyModel::canDropMimeData(const QMimeData *data, Qt::DropAction
int row, int column, const QModelIndex &parent) const
{
Q_D(const QAbstractProxyModel);
- const QModelIndex source = mapToSource(index(row, column, parent));
- return d->model->canDropMimeData(data, action, source.row(), source.column(), source.parent());
+ int sourceDestinationRow;
+ int sourceDestinationColumn;
+ QModelIndex sourceParent;
+ d->mapDropCoordinatesToSource(row, column, parent, &sourceDestinationRow, &sourceDestinationColumn, &sourceParent);
+ return d->model->canDropMimeData(data, action, sourceDestinationRow, sourceDestinationColumn, sourceParent);
}
/*!
@@ -404,8 +427,11 @@ bool QAbstractProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction act
int row, int column, const QModelIndex &parent)
{
Q_D(QAbstractProxyModel);
- const QModelIndex source = mapToSource(index(row, column, parent));
- return d->model->dropMimeData(data, action, source.row(), source.column(), source.parent());
+ int sourceDestinationRow;
+ int sourceDestinationColumn;
+ QModelIndex sourceParent;
+ d->mapDropCoordinatesToSource(row, column, parent, &sourceDestinationRow, &sourceDestinationColumn, &sourceParent);
+ return d->model->dropMimeData(data, action, sourceDestinationRow, sourceDestinationColumn, sourceParent);
}
/*!
diff --git a/src/corelib/itemmodels/qabstractproxymodel_p.h b/src/corelib/itemmodels/qabstractproxymodel_p.h
index 9402092fa8..24af5afc64 100644
--- a/src/corelib/itemmodels/qabstractproxymodel_p.h
+++ b/src/corelib/itemmodels/qabstractproxymodel_p.h
@@ -59,6 +59,8 @@ public:
QAbstractProxyModelPrivate() : QAbstractItemModelPrivate(), model(0) {}
QAbstractItemModel *model;
virtual void _q_sourceModelDestroyed();
+ void mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
+ int *source_row, int *source_column, QModelIndex *source_parent) const;
};
QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index db78af8cf8..5395fd5d09 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -1076,7 +1076,7 @@ void QItemSelectionModelPrivate::_q_layoutChanged(const QList<QPersistentModelIn
If you omit the QItemSelectionModel::Current command, a new current
selection will be created, and the previous one added to the whole
selection. All functions operate on both layers; for example,
- selectedItems() will return items from both layers.
+ \l {QTableWidget::selectedItems()}{selecteditems()} will return items from both layers.
\sa {Model/View Programming}, QAbstractItemModel, {Chart Example}
*/
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index a95c7dc8b3..0b2b0e4188 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -1196,11 +1196,7 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
parents << q->mapFromSource(source_parent);
emit q->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint);
QModelIndexPairList source_indexes = store_persistent_indexes();
- remove_source_items(m->proxy_rows, m->source_rows, source_rows_resort,
- source_parent, Qt::Vertical, false);
- sort_source_rows(source_rows_resort, source_parent);
- insert_source_items(m->proxy_rows, m->source_rows, source_rows_resort,
- source_parent, Qt::Vertical, false);
+ sort_source_rows(m->source_rows, source_parent);
update_persistent_indexes(source_indexes);
emit q->layoutChanged(parents, QAbstractItemModel::VerticalSortHint);
// Make sure we also emit dataChanged for the rows
@@ -2034,30 +2030,14 @@ Qt::DropActions QSortFilterProxyModel::supportedDropActions() const
return d->model->supportedDropActions();
}
+// Qt6: remove unnecessary reimplementation
/*!
\reimp
*/
bool QSortFilterProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent)
{
- Q_D(QSortFilterProxyModel);
- if ((row == -1) && (column == -1))
- return d->model->dropMimeData(data, action, -1, -1, mapToSource(parent));
- int source_destination_row = -1;
- int source_destination_column = -1;
- QModelIndex source_parent;
- if (row == rowCount(parent)) {
- source_parent = mapToSource(parent);
- source_destination_row = d->model->rowCount(source_parent);
- } else {
- QModelIndex proxy_index = index(row, column, parent);
- QModelIndex source_index = mapToSource(proxy_index);
- source_destination_row = source_index.row();
- source_destination_column = source_index.column();
- source_parent = source_index.parent();
- }
- return d->model->dropMimeData(data, action, source_destination_row,
- source_destination_column, source_parent);
+ return QAbstractProxyModel::dropMimeData(data, action, row, column, parent);
}
/*!
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index fd407af2cd..73c53ea649 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
removing QJsonValue's from the array.
A QJsonArray can be converted to and from a QVariantList. You can query the
- number of entries with size(), insert(), and remove() entries from it
+ number of entries with size(), insert(), and removeAt() entries from it
and iterate over its content using the standard C++ iterator pattern.
QJsonArray is an implicitly shared class and shares the data with the document
diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h
index 87d14a7703..a8307ae5aa 100644
--- a/src/corelib/json/qjsonarray.h
+++ b/src/corelib/json/qjsonarray.h
@@ -105,6 +105,7 @@ public:
typedef int difference_type;
typedef QJsonValue value_type;
typedef QJsonValueRef reference;
+ typedef QJsonValueRefPtr pointer;
inline iterator() : a(0), i(0) { }
explicit inline iterator(QJsonArray *array, int index) : a(array), i(index) { }
@@ -149,6 +150,7 @@ public:
typedef qptrdiff difference_type;
typedef QJsonValue value_type;
typedef QJsonValue reference;
+ typedef QJsonValuePtr pointer;
inline const_iterator() : a(0), i(0) { }
explicit inline const_iterator(const QJsonArray *array, int index) : a(array), i(index) { }
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 45647f2056..77900ba906 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -714,9 +714,7 @@ void QCoreApplication::init()
Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = this;
-#ifndef QT_BOOTSTRAPPED
QLoggingRegistry::instance()->init();
-#endif
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index a3d00faf31..1a8bb381aa 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -307,8 +307,9 @@ static void resolveTimerAPI()
}
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
- : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
- serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0)
+ : threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
+ getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
+ wakeUps(0)
{
resolveTimerAPI();
}
@@ -434,9 +435,10 @@ static inline UINT inputTimerMask()
LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
{
+ QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
+ Q_ASSERT(q != 0);
+
if (wp == PM_REMOVE) {
- QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
- Q_ASSERT(q != 0);
if (q) {
MSG *msg = (MSG *) lp;
QEventDispatcherWin32Private *d = q->d_func();
@@ -472,7 +474,7 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
#ifdef Q_OS_WINCE
return 0;
#else
- return CallNextHookEx(0, code, wp, lp);
+ return q->d_func()->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0;
#endif
}
@@ -643,15 +645,7 @@ void QEventDispatcherWin32::createInternalHwnd()
return;
d->internalHwnd = qt_create_internal_window(this);
-#ifndef Q_OS_WINCE
- // setup GetMessage hook needed to drive our posted events
- d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
- if (!d->getMessageHook) {
- int errorCode = GetLastError();
- qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
- errorCode, qPrintable(qt_error_string(errorCode)));
- }
-#endif
+ installMessageHook();
// register all socket notifiers
QList<int> sockets = (d->sn_read.keys().toSet()
@@ -665,6 +659,35 @@ void QEventDispatcherWin32::createInternalHwnd()
d->registerTimer(d->timerVec.at(i));
}
+void QEventDispatcherWin32::installMessageHook()
+{
+ Q_D(QEventDispatcherWin32);
+
+ if (d->getMessageHook)
+ return;
+
+#ifndef Q_OS_WINCE
+ // setup GetMessage hook needed to drive our posted events
+ d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
+ if (!d->getMessageHook) {
+ int errorCode = GetLastError();
+ qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
+ errorCode, qPrintable(qt_error_string(errorCode)));
+ }
+#endif
+}
+
+void QEventDispatcherWin32::uninstallMessageHook()
+{
+ Q_D(QEventDispatcherWin32);
+
+#ifndef Q_OS_WINCE
+ if (d->getMessageHook)
+ UnhookWindowsHookEx(d->getMessageHook);
+#endif
+ d->getMessageHook = 0;
+}
+
QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWin32Private, parent)
{
@@ -750,10 +773,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
}
}
if (haveMessage) {
-#ifdef Q_OS_WINCE
// WinCE doesn't support hooks at all, so we have to call this by hand :(
- (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
-#endif
+ if (!d->getMessageHook)
+ (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
if (seenWM_QT_SENDPOSTEDEVENTS) {
@@ -910,6 +932,11 @@ void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerTy
Q_D(QEventDispatcherWin32);
+ // exiting ... do not register new timers
+ // (QCoreApplication::closingDown() is set too late to be used here)
+ if (d->closingDown)
+ return;
+
WinTimerInfo *t = new WinTimerInfo;
t->dispatcher = this;
t->timerId = timerId;
@@ -1134,11 +1161,9 @@ void QEventDispatcherWin32::closingDown()
d->timerVec.clear();
d->timerDict.clear();
-#ifndef Q_OS_WINCE
- if (d->getMessageHook)
- UnhookWindowsHookEx(d->getMessageHook);
- d->getMessageHook = 0;
-#endif
+ d->closingDown = true;
+
+ uninstallMessageHook();
}
bool QEventDispatcherWin32::event(QEvent *e)
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 369c276615..8022299a76 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -67,6 +67,8 @@ class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
protected:
void createInternalHwnd();
+ void installMessageHook();
+ void uninstallMessageHook();
public:
explicit QEventDispatcherWin32(QObject *parent = 0);
@@ -145,6 +147,7 @@ public:
DWORD threadId;
bool interrupt;
+ bool closingDown;
// internal window handle used for socketnotifiers/timers/etc
HWND internalHwnd;
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 452e3464d6..b179323fdc 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -311,7 +311,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, ...
}
}
-QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, va_list args)
+QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, const QVaListPrivate &args)
: d(new QJNIObjectData())
{
QJNIEnvironmentPrivate env;
@@ -369,7 +369,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, ...)
}
}
-QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, va_list args)
+QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, const QVaListPrivate &args)
: d(new QJNIObjectData())
{
QJNIEnvironmentPrivate env;
@@ -402,7 +402,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj)
}
template <>
-void QJNIObjectPrivate::callMethod<void>(const char *methodName, const char *sig, va_list args) const
+void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig);
@@ -416,12 +416,12 @@ void QJNIObjectPrivate::callMethod<void>(const char *methodName, const char *sig
{
va_list args;
va_start(args, sig);
- callMethod<void>(methodName, sig, args);
+ callMethodV<void>(methodName, sig, args);
va_end(args);
}
template <>
-jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName, const char *sig, va_list args) const
+jboolean QJNIObjectPrivate::callMethodV<jboolean>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jboolean res = 0;
@@ -437,13 +437,13 @@ jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName, const c
{
va_list args;
va_start(args, sig);
- jboolean res = callMethod<jboolean>(methodName, sig, args);
+ jboolean res = callMethodV<jboolean>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName, const char *sig, va_list args) const
+jbyte QJNIObjectPrivate::callMethodV<jbyte>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jbyte res = 0;
@@ -459,13 +459,13 @@ jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName, const char *s
{
va_list args;
va_start(args, sig);
- jbyte res = callMethod<jbyte>(methodName, sig, args);
+ jbyte res = callMethodV<jbyte>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName, const char *sig, va_list args) const
+jchar QJNIObjectPrivate::callMethodV<jchar>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jchar res = 0;
@@ -481,13 +481,13 @@ jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName, const char *s
{
va_list args;
va_start(args, sig);
- jchar res = callMethod<jchar>(methodName, sig, args);
+ jchar res = callMethodV<jchar>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName, const char *sig, va_list args) const
+jshort QJNIObjectPrivate::callMethodV<jshort>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jshort res = 0;
@@ -503,13 +503,13 @@ jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName, const char
{
va_list args;
va_start(args, sig);
- jshort res = callMethod<jshort>(methodName, sig, args);
+ jshort res = callMethodV<jshort>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jint QJNIObjectPrivate::callMethod<jint>(const char *methodName, const char *sig, va_list args) const
+jint QJNIObjectPrivate::callMethodV<jint>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jint res = 0;
@@ -525,13 +525,13 @@ jint QJNIObjectPrivate::callMethod<jint>(const char *methodName, const char *sig
{
va_list args;
va_start(args, sig);
- jint res = callMethod<jint>(methodName, sig, args);
+ jint res = callMethodV<jint>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName, const char *sig, va_list args) const
+jlong QJNIObjectPrivate::callMethodV<jlong>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jlong res = 0;
@@ -547,13 +547,13 @@ jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName, const char *s
{
va_list args;
va_start(args, sig);
- jlong res = callMethod<jlong>(methodName, sig, args);
+ jlong res = callMethodV<jlong>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName, const char *sig, va_list args) const
+jfloat QJNIObjectPrivate::callMethodV<jfloat>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jfloat res = 0.f;
@@ -569,13 +569,13 @@ jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName, const char
{
va_list args;
va_start(args, sig);
- jfloat res = callMethod<jfloat>(methodName, sig, args);
+ jfloat res = callMethodV<jfloat>(methodName, sig, args);
va_end(args);
return res;
}
template <>
-jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName, const char *sig, va_list args) const
+jdouble QJNIObjectPrivate::callMethodV<jdouble>(const char *methodName, const char *sig, va_list args) const
{
QJNIEnvironmentPrivate env;
jdouble res = 0.;
@@ -591,7 +591,7 @@ jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName, const cha
{
va_list args;
va_start(args, sig);
- jdouble res = callMethod<jdouble>(methodName, sig, args);
+ jdouble res = callMethodV<jdouble>(methodName, sig, args);
va_end(args);
return res;
}
@@ -651,10 +651,10 @@ jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName) const
}
template <>
-void QJNIObjectPrivate::callStaticMethod<void>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+void QJNIObjectPrivate::callStaticMethodV<void>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jclass clazz = loadClass(className, env);
@@ -674,15 +674,15 @@ void QJNIObjectPrivate::callStaticMethod<void>(const char *className,
{
va_list args;
va_start(args, sig);
- callStaticMethod<void>(className, methodName, sig, args);
+ callStaticMethodV<void>(className, methodName, sig, args);
va_end(args);
}
template <>
-void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+void QJNIObjectPrivate::callStaticMethodV<void>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true);
@@ -699,15 +699,15 @@ void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz,
{
va_list args;
va_start(args, sig);
- callStaticMethod<void>(clazz, methodName, sig, args);
+ callStaticMethodV<void>(clazz, methodName, sig, args);
va_end(args);
}
template <>
-jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jboolean res = 0;
@@ -730,16 +730,16 @@ jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className,
{
va_list args;
va_start(args, sig);
- jboolean res = callStaticMethod<jboolean>(className, methodName, sig, args);
+ jboolean res = callStaticMethodV<jboolean>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jboolean res = 0;
@@ -759,16 +759,16 @@ jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jboolean res = callStaticMethod<jboolean>(clazz, methodName, sig, args);
+ jboolean res = callStaticMethodV<jboolean>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jbyte res = 0;
@@ -791,16 +791,16 @@ jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className,
{
va_list args;
va_start(args, sig);
- jbyte res = callStaticMethod<jbyte>(className, methodName, sig, args);
+ jbyte res = callStaticMethodV<jbyte>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jbyte res = 0;
@@ -820,16 +820,16 @@ jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jbyte res = callStaticMethod<jbyte>(clazz, methodName, sig, args);
+ jbyte res = callStaticMethodV<jbyte>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jchar QJNIObjectPrivate::callStaticMethodV<jchar>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jchar res = 0;
@@ -852,16 +852,16 @@ jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className,
{
va_list args;
va_start(args, sig);
- jchar res = callStaticMethod<jchar>(className, methodName, sig, args);
+ jchar res = callStaticMethodV<jchar>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jchar QJNIObjectPrivate::callStaticMethodV<jchar>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jchar res = 0;
@@ -881,16 +881,16 @@ jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jchar res = callStaticMethod<jchar>(clazz, methodName, sig, args);
+ jchar res = callStaticMethodV<jchar>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jshort QJNIObjectPrivate::callStaticMethodV<jshort>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jshort res = 0;
@@ -913,16 +913,16 @@ jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className,
{
va_list args;
va_start(args, sig);
- jshort res = callStaticMethod<jshort>(className, methodName, sig, args);
+ jshort res = callStaticMethodV<jshort>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jshort QJNIObjectPrivate::callStaticMethodV<jshort>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jshort res = 0;
@@ -942,16 +942,16 @@ jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jshort res = callStaticMethod<jshort>(clazz, methodName, sig, args);
+ jshort res = callStaticMethodV<jshort>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jint QJNIObjectPrivate::callStaticMethodV<jint>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jint res = 0;
@@ -974,16 +974,16 @@ jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className,
{
va_list args;
va_start(args, sig);
- jint res = callStaticMethod<jint>(className, methodName, sig, args);
+ jint res = callStaticMethodV<jint>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jint QJNIObjectPrivate::callStaticMethodV<jint>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jint res = 0;
@@ -1003,16 +1003,16 @@ jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jint res = callStaticMethod<jint>(clazz, methodName, sig, args);
+ jint res = callStaticMethodV<jint>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jlong QJNIObjectPrivate::callStaticMethodV<jlong>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jlong res = 0;
@@ -1035,16 +1035,16 @@ jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className,
{
va_list args;
va_start(args, sig);
- jlong res = callStaticMethod<jlong>(className, methodName, sig, args);
+ jlong res = callStaticMethodV<jlong>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jlong QJNIObjectPrivate::callStaticMethodV<jlong>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jlong res = 0;
@@ -1064,16 +1064,16 @@ jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jlong res = callStaticMethod<jlong>(clazz, methodName, sig, args);
+ jlong res = callStaticMethodV<jlong>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jfloat res = 0.f;
@@ -1096,16 +1096,16 @@ jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className,
{
va_list args;
va_start(args, sig);
- jfloat res = callStaticMethod<jfloat>(className, methodName, sig, args);
+ jfloat res = callStaticMethodV<jfloat>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jfloat res = 0.f;
@@ -1125,16 +1125,16 @@ jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jfloat res = callStaticMethod<jfloat>(clazz, methodName, sig, args);
+ jfloat res = callStaticMethodV<jfloat>(clazz, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jdouble res = 0.;
@@ -1157,16 +1157,16 @@ jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className,
{
va_list args;
va_start(args, sig);
- jdouble res = callStaticMethod<jdouble>(className, methodName, sig, args);
+ jdouble res = callStaticMethodV<jdouble>(className, methodName, sig, args);
va_end(args);
return res;
}
template <>
-jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jdouble res = 0.;
@@ -1186,7 +1186,7 @@ jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz,
{
va_list args;
va_start(args, sig);
- jdouble res = callStaticMethod<jdouble>(clazz, methodName, sig, args);
+ jdouble res = callStaticMethodV<jdouble>(clazz, methodName, sig, args);
va_end(args);
return res;
}
@@ -1299,9 +1299,9 @@ jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, const char *m
return callStaticMethod<jdouble>(clazz, methodName, "()D");
}
-QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
- const char *sig,
- va_list args) const
+QJNIObjectPrivate QJNIObjectPrivate::callObjectMethodV(const char *methodName,
+ const char *sig,
+ va_list args) const
{
QJNIEnvironmentPrivate env;
jobject res = 0;
@@ -1323,7 +1323,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
{
va_list args;
va_start(args, sig);
- QJNIObjectPrivate res = callObjectMethod(methodName, sig, args);
+ QJNIObjectPrivate res = callObjectMethodV(methodName, sig, args);
va_end(args);
return res;
}
@@ -1376,10 +1376,10 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jdoubleArray>(const char *
return callObjectMethod(methodName, "()[D");
}
-QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *className,
- const char *methodName,
- const char *sig,
- va_list args)
+QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jobject res = 0;
@@ -1405,15 +1405,15 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *classNam
{
va_list args;
va_start(args, sig);
- QJNIObjectPrivate res = callStaticObjectMethod(className, methodName, sig, args);
+ QJNIObjectPrivate res = callStaticObjectMethodV(className, methodName, sig, args);
va_end(args);
return res;
}
-QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
- const char *methodName,
- const char *sig,
- va_list args)
+QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args)
{
QJNIEnvironmentPrivate env;
jobject res = 0;
@@ -1436,7 +1436,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
{
va_list args;
va_start(args, sig);
- QJNIObjectPrivate res = callStaticObjectMethod(clazz, methodName, sig, args);
+ QJNIObjectPrivate res = callStaticObjectMethodV(clazz, methodName, sig, args);
va_end(args);
return res;
}
diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h
index 19f2cf7601..5f573624c6 100644
--- a/src/corelib/kernel/qjni_p.h
+++ b/src/corelib/kernel/qjni_p.h
@@ -186,31 +186,37 @@ public:
private:
friend class QAndroidJniObject;
- QJNIObjectPrivate(const char *className, const char *sig, va_list args);
- QJNIObjectPrivate(jclass clazz, const char *sig, va_list args);
+ struct QVaListPrivate { operator va_list &() const { return m_args; } va_list &m_args; };
+
+ QJNIObjectPrivate(const char *className, const char *sig, const QVaListPrivate &args);
+ QJNIObjectPrivate(jclass clazz, const char *sig, const QVaListPrivate &args);
template <typename T>
- T callMethod(const char *methodName,
- const char *sig,
- va_list args) const;
- QJNIObjectPrivate callObjectMethod(const char *methodName,
- const char *sig,
- va_list args) const;
+ T callMethodV(const char *methodName,
+ const char *sig,
+ va_list args) const;
+ QJNIObjectPrivate callObjectMethodV(const char *methodName,
+ const char *sig,
+ va_list args) const;
template <typename T>
- static T callStaticMethod(const char *className,
- const char *methodName,
- const char *sig, va_list args);
+ static T callStaticMethodV(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args);
template <typename T>
- static T callStaticMethod(jclass clazz,
- const char *methodName,
- const char *sig, va_list args);
- static QJNIObjectPrivate callStaticObjectMethod(const char *className,
- const char *methodName,
- const char *sig, va_list args);
-
- static QJNIObjectPrivate callStaticObjectMethod(jclass clazz,
- const char *methodName,
- const char *sig, va_list args);
+ static T callStaticMethodV(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args);
+ static QJNIObjectPrivate callStaticObjectMethodV(const char *className,
+ const char *methodName,
+ const char *sig,
+ va_list args);
+
+ static QJNIObjectPrivate callStaticObjectMethodV(jclass clazz,
+ const char *methodName,
+ const char *sig,
+ va_list args);
bool isSameObject(jobject obj) const;
bool isSameObject(const QJNIObjectPrivate &other) const;
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index c82b5ca033..d3bbce305a 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -34,6 +34,7 @@
#include "qjnihelpers_p.h"
#include "qmutex.h"
#include "qlist.h"
+#include <QtCore/qrunnable.h>
QT_BEGIN_NAMESPACE
@@ -41,6 +42,19 @@ static JavaVM *g_javaVM = Q_NULLPTR;
static jobject g_jActivity = Q_NULLPTR;
static jobject g_jClassLoader = Q_NULLPTR;
static jint g_androidSdkVersion = 0;
+static jclass g_jNativeClass = Q_NULLPTR;
+static jmethodID g_runQtOnUiThreadMethodID = Q_NULLPTR;
+
+static void onAndroidUiThread(JNIEnv *, jclass, jlong thiz)
+{
+ QRunnable *runnable = reinterpret_cast<QRunnable *>(thiz);
+ if (runnable == 0)
+ return;
+
+ runnable->run();
+ if (runnable->autoDelete())
+ delete runnable;
+}
namespace {
class ActivityResultListeners
@@ -140,6 +154,22 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
env->DeleteLocalRef(activity);
g_javaVM = vm;
+ static const JNINativeMethod methods[] = {
+ {"onAndroidUiThread", "(J)V", reinterpret_cast<void *>(onAndroidUiThread)}
+ };
+
+ const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
+
+ if (!regOk && exceptionCheck(env))
+ return JNI_ERR;
+
+ g_runQtOnUiThreadMethodID = env->GetStaticMethodID(jQtNative,
+ "runQtOnUiThread",
+ "(J)V");
+
+ g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative));
+ env->DeleteLocalRef(jQtNative);
+
return JNI_OK;
}
@@ -164,4 +194,12 @@ jint QtAndroidPrivate::androidSdkVersion()
return g_androidSdkVersion;
}
+void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env)
+{
+ Q_ASSERT(runnable != 0);
+ env->CallStaticVoidMethod(g_jNativeClass, g_runQtOnUiThreadMethodID, reinterpret_cast<jlong>(runnable));
+ if (exceptionCheck(env) && runnable != 0 && runnable->autoDelete())
+ delete runnable;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h
index 80c50ba611..6456dce4c4 100644
--- a/src/corelib/kernel/qjnihelpers_p.h
+++ b/src/corelib/kernel/qjnihelpers_p.h
@@ -50,6 +50,8 @@
QT_BEGIN_NAMESPACE
+class QRunnable;
+
namespace QtAndroidPrivate
{
class Q_CORE_EXPORT ActivityResultListener
@@ -64,6 +66,7 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
jobject classLoader();
Q_CORE_EXPORT jint androidSdkVersion();
+ Q_CORE_EXPORT void runOnUiThread(QRunnable *runnable, JNIEnv *env);
Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data);
Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener);
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index e68b899280..1faead8495 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -48,7 +48,7 @@ template <typename T> class QList;
class Q_CORE_EXPORT QMetaMethod
{
public:
- inline QMetaMethod() : mobj(0),handle(0) {}
+ Q_DECL_CONSTEXPR inline QMetaMethod() : mobj(0),handle(0) {}
QByteArray methodSignature() const;
QByteArray name() const;
@@ -204,7 +204,7 @@ inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
class Q_CORE_EXPORT QMetaEnum
{
public:
- inline QMetaEnum() : mobj(0),handle(0) {}
+ Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(0),handle(0) {}
const char *name() const;
bool isFlag() const;
@@ -286,7 +286,7 @@ private:
class Q_CORE_EXPORT QMetaClassInfo
{
public:
- inline QMetaClassInfo() : mobj(0),handle(0) {}
+ Q_DECL_CONSTEXPR inline QMetaClassInfo() : mobj(0),handle(0) {}
const char *name() const;
const char *value() const;
inline const QMetaObject *enclosingMetaObject() const { return mobj; }
diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp
index 5c185e1d62..3b1d808520 100644
--- a/src/corelib/kernel/qsystemerror.cpp
+++ b/src/corelib/kernel/qsystemerror.cpp
@@ -61,11 +61,11 @@ namespace {
// version in portable code. However, it's impossible to do that if
// _GNU_SOURCE is defined so we use C++ overloading to decide what to do
// depending on the return type
- static inline QString fromstrerror_helper(int, const QByteArray &buf)
+ static inline Q_DECL_UNUSED QString fromstrerror_helper(int, const QByteArray &buf)
{
return QString::fromLocal8Bit(buf);
}
- static inline QString fromstrerror_helper(const char *str, const QByteArray &)
+ static inline Q_DECL_UNUSED QString fromstrerror_helper(const char *str, const QByteArray &)
{
return QString::fromLocal8Bit(str);
}
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 5687a6c3a3..a2cf4a7813 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -427,9 +427,8 @@ QTranslator::~QTranslator()
directory. Returns \c true if the translation is successfully loaded;
otherwise returns \c false.
- If \a directory is not specified, the directory of the
- application's executable is used (i.e., as
- \l{QCoreApplication::}{applicationDirPath()}).
+ If \a directory is not specified, the current directory is used
+ (i.e., as \l{QDir::}{currentPath()}).
The previous contents of this translator object are discarded.
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 57e0523f7c..7dce813bb5 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -703,14 +703,15 @@ namespace QtPrivate {
{
static QSequentialIterable invoke(const QVariant &v)
{
- if (v.userType() == qMetaTypeId<QVariantList>()) {
+ const int typeId = v.userType();
+ if (typeId == qMetaTypeId<QVariantList>()) {
return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QVariantList*>(v.constData())));
}
- if (v.userType() == qMetaTypeId<QStringList>()) {
+ if (typeId == qMetaTypeId<QStringList>()) {
return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QStringList*>(v.constData())));
}
#ifndef QT_BOOTSTRAPPED
- if (v.userType() == qMetaTypeId<QByteArrayList>()) {
+ if (typeId == qMetaTypeId<QByteArrayList>()) {
return QSequentialIterable(QtMetaTypePrivate::QSequentialIterableImpl(reinterpret_cast<const QByteArrayList*>(v.constData())));
}
#endif
@@ -722,10 +723,11 @@ namespace QtPrivate {
{
static QAssociativeIterable invoke(const QVariant &v)
{
- if (v.userType() == qMetaTypeId<QVariantMap>()) {
+ const int typeId = v.userType();
+ if (typeId == qMetaTypeId<QVariantMap>()) {
return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantMap*>(v.constData())));
}
- if (v.userType() == qMetaTypeId<QVariantHash>()) {
+ if (typeId == qMetaTypeId<QVariantHash>()) {
return QAssociativeIterable(QtMetaTypePrivate::QAssociativeIterableImpl(reinterpret_cast<const QVariantHash*>(v.constData())));
}
return QAssociativeIterable(v.value<QtMetaTypePrivate::QAssociativeIterableImpl>());
@@ -736,7 +738,8 @@ namespace QtPrivate {
{
static QVariantList invoke(const QVariant &v)
{
- if (QtMetaTypePrivate::isBuiltinSequentialType(v.userType()) || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
+ const int typeId = v.userType();
+ if (QtMetaTypePrivate::isBuiltinSequentialType(typeId) || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) {
QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
QVariantList l;
l.reserve(iter.size());
@@ -752,7 +755,8 @@ namespace QtPrivate {
{
static QVariantHash invoke(const QVariant &v)
{
- if (QtMetaTypePrivate::isBuiltinAssociativeType(v.userType()) || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ const int typeId = v.userType();
+ if (QtMetaTypePrivate::isBuiltinAssociativeType(typeId) || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantHash l;
l.reserve(iter.size());
@@ -768,7 +772,8 @@ namespace QtPrivate {
{
static QVariantMap invoke(const QVariant &v)
{
- if (QtMetaTypePrivate::isBuiltinAssociativeType(v.userType()) || QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
+ const int typeId = v.userType();
+ if (QtMetaTypePrivate::isBuiltinAssociativeType(typeId) || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantMap l;
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
@@ -783,10 +788,11 @@ namespace QtPrivate {
{
static QPair<QVariant, QVariant> invoke(const QVariant &v)
{
- if (v.userType() == qMetaTypeId<QPair<QVariant, QVariant> >())
+ const int typeId = v.userType();
+ if (typeId == qMetaTypeId<QPair<QVariant, QVariant> >())
return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
- if (QMetaType::hasRegisteredConverterFunction(v.userType(), qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
+ if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
const QtMetaTypePrivate::VariantData d1 = pi.first();
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 9d14e5f90b..c5103ebe59 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -248,7 +248,7 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent)
\endcode
On a typical Unix system, this will be /usr/share/mime/packages/, but it is also
possible to extend the list of directories by setting the environment variable
- XDG_DATA_DIRS. For instance adding /opt/myapp/share to XDG_DATA_DIRS will result
+ \c XDG_DATA_DIRS. For instance adding /opt/myapp/share to \c XDG_DATA_DIRS will result
in /opt/myapp/share/mime/packages/ being searched for MIME definitions.
Here is an example of MIME XML:
@@ -575,7 +575,7 @@ QMimeType QMimeDatabase::mimeTypeForFileNameAndData(const QString &fileName, con
This can be useful for showing all MIME types to the user, for instance
in a MIME type editor. Do not use unless really necessary in other cases
- though, prefer using the mimeTypeFor* methods for performance reasons.
+ though, prefer using the \l {mimeTypeForData()}{mimeTypeForXxx()} methods for performance reasons.
*/
QList<QMimeType> QMimeDatabase::allMimeTypes() const
{
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index d1bf27eae0..1ad2a449c1 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -89,8 +89,8 @@ void QMimeTypePrivate::addGlobPattern(const QString &pattern)
Determining the MIME type of a file can be useful to make sure your
application supports it. It is also useful in file-manager-like applications
- or widgets, in order to display an appropriate icon() for the file, or even
- the descriptive comment() in detailed views.
+ or widgets, in order to display an appropriate \l {QMimeType::iconName}{icon} for the file, or even
+ the descriptive \l {QMimeType::comment()}{comment} in detailed views.
To check if a file has the expected MIME type, you should use inherits()
rather than a simple string comparison based on the name(). This is because
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index 4e9a60504a..c424344c3a 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -71,7 +71,7 @@ Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
-#if defined (Q_OF_ELF) && (defined (Q_CC_GNU) || defined(Q_CC_CLANG))
+#if (defined(Q_OF_ELF) || defined(Q_OS_WIN)) && (defined (Q_CC_GNU) || defined(Q_CC_CLANG))
# define QT_PLUGIN_METADATA_SECTION \
__attribute__ ((section (".qtmetadata"))) __attribute__((used))
#elif defined(Q_OS_MAC)
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 09500e92d7..be293f58e3 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -84,13 +84,9 @@ QT_END_NAMESPACE
// New atomics
#if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_DEFAULT_MEMBERS) && defined(Q_COMPILER_DELETE_MEMBERS)
-# if defined(Q_CC_CLANG) && ((((__clang_major__ * 100) + __clang_minor__) < 303) \
- || defined(__apple_build_version__) \
- )
- /* Do not define QT_BASIC_ATOMIC_HAS_CONSTRUCTORS for "stock" clang before version 3.3.
- Apple's version has different (higher!) version numbers, so disable it for all of them for now.
- (The only way to distinguish between them seems to be a check for __apple_build_version__ .)
-
+# if defined(Q_CC_CLANG) && Q_CC_CLANG < 303
+ /*
+ Do not define QT_BASIC_ATOMIC_HAS_CONSTRUCTORS for Clang before version 3.3.
For details about the bug: see http://llvm.org/bugs/show_bug.cgi?id=12670
*/
# else
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 625b78d001..36acfc4c09 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -785,7 +785,7 @@ static inline char qToLower(char c)
occurrences of a particular value with another, use one of the
two-parameter replace() overloads.
- QByteArrays can be compared using overloaded operators such as
+ {QByteArray}s can be compared using overloaded operators such as
operator<(), operator<=(), operator==(), operator>=(), and so on.
The comparison is based exclusively on the numeric values
of the characters and is very fast, but is not what a human would
@@ -830,7 +830,7 @@ static inline char qToLower(char c)
lastIndexOf(), operator<(), operator<=(), operator>(),
operator>=(), toLower() and toUpper().
- This issue does not apply to QStrings since they represent
+ This issue does not apply to {QString}s since they represent
characters using Unicode.
\sa QString, QBitArray
@@ -3203,6 +3203,7 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
replaced with a single space.
Whitespace means any character for which the standard C++
+ \c isspace() function returns \c true in the C locale. This includes the ASCII
isspace() function returns \c true in the C locale. This includes the ASCII
characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '.
@@ -3228,13 +3229,13 @@ QByteArray QByteArray::simplified_helper(QByteArray &a)
and the end.
Whitespace means any character for which the standard C++
- isspace() function returns \c true in the C locale. This includes the ASCII
+ \c isspace() function returns \c true in the C locale. This includes the ASCII
characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '.
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 33
- Unlike simplified(), trimmed() leaves internal whitespace alone.
+ Unlike simplified(), \l {QByteArray::trimmed()}{trimmed()} leaves internal whitespace alone.
\sa simplified()
*/
diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h
index 9d7e776028..dd84ec642c 100644
--- a/src/corelib/tools/qbytearraylist.h
+++ b/src/corelib/tools/qbytearraylist.h
@@ -63,6 +63,7 @@ class QByteArrayList : public QList<QByteArray>
template <> struct QListSpecialMethods<QByteArray>
#endif
{
+public:
inline QByteArray join() const
{ return QtPrivate::QByteArrayList_join(self(), 0, 0); }
inline QByteArray join(const QByteArray &sep) const
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
index ec1e78c358..5bcd01a587 100644
--- a/src/corelib/tools/qdatetime.h
+++ b/src/corelib/tools/qdatetime.h
@@ -118,7 +118,8 @@ QT_DEPRECATED inline bool setYMD(int y, int m, int d)
inline qint64 toJulianDay() const { return jd; }
private:
- static inline qint64 nullJd() { return std::numeric_limits<qint64>::min(); }
+ // using extra parentheses around min to avoid expanding it if it is a macro
+ static inline qint64 nullJd() { return (std::numeric_limits<qint64>::min)(); }
static inline qint64 minJd() { return Q_INT64_C(-784350574879); }
static inline qint64 maxJd() { return Q_INT64_C( 784354017364); }
diff --git a/src/corelib/tools/qelapsedtimer.h b/src/corelib/tools/qelapsedtimer.h
index d72a50f127..d21081f815 100644
--- a/src/corelib/tools/qelapsedtimer.h
+++ b/src/corelib/tools/qelapsedtimer.h
@@ -51,8 +51,8 @@ public:
};
Q_DECL_CONSTEXPR QElapsedTimer()
- : t1(Q_INT64_C(0x8000000000000000))
- , t2(Q_INT64_C(0x8000000000000000))
+ : t1(Q_INT64_C(0x8000000000000000)),
+ t2(Q_INT64_C(0x8000000000000000))
{
}
diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp
index 02d60cc60c..61bd7f1f21 100644
--- a/src/corelib/tools/qelapsedtimer_unix.cpp
+++ b/src/corelib/tools/qelapsedtimer_unix.cpp
@@ -35,8 +35,12 @@
#define _POSIX_C_SOURCE 200809L
#include "qelapsedtimer.h"
-#ifdef Q_OS_VXWORKS
+#if defined(Q_OS_VXWORKS)
#include "qfunctions_vxworks.h"
+#elif defined(Q_OS_QNX)
+#include <sys/neutrino.h>
+#include <sys/syspage.h>
+#include <inttypes.h>
#else
#include <sys/time.h>
#include <time.h>
@@ -84,7 +88,18 @@ QT_BEGIN_NAMESPACE
* see http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html
*/
-#ifndef CLOCK_REALTIME
+#if defined(Q_OS_QNX)
+static inline void qt_clock_gettime(clockid_t clock, struct timespec *ts)
+{
+ // The standard POSIX clock calls only have 1ms accuracy on QNX. To get
+ // higher accuracy, this platform-specific function must be used instead
+ quint64 cycles_per_sec = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
+ quint64 cycles = ClockCycles();
+ ts->tv_sec = cycles / cycles_per_sec;
+ quint64 mod = cycles % cycles_per_sec;
+ ts->tv_nsec = mod * Q_INT64_C(1000000000) / cycles_per_sec;
+}
+#elif !defined(CLOCK_REALTIME)
# define CLOCK_REALTIME 0
static inline void qt_clock_gettime(int, struct timespec *ts)
{
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index f32cd78801..b91fd38a5f 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -1365,7 +1365,7 @@ void **QListData::erase(void **xi)
\sa operator*()
*/
-/*! \fn T &QList::iterator::operator[](int j) const
+/*! \fn T &QList::iterator::operator[](difference_type j) const
Returns a modifiable reference to the item at position *this +
\a{j}.
@@ -1466,7 +1466,7 @@ void **QListData::erase(void **xi)
current and returns an iterator to the previously current item.
*/
-/*! \fn QList::iterator &QList::iterator::operator+=(int j)
+/*! \fn QList::iterator &QList::iterator::operator+=(difference_type j)
Advances the iterator by \a j items. (If \a j is negative, the
iterator goes backward.)
@@ -1474,7 +1474,7 @@ void **QListData::erase(void **xi)
\sa operator-=(), operator+()
*/
-/*! \fn QList::iterator &QList::iterator::operator-=(int j)
+/*! \fn QList::iterator &QList::iterator::operator-=(difference_type j)
Makes the iterator go back by \a j items. (If \a j is negative,
the iterator goes forward.)
@@ -1482,7 +1482,7 @@ void **QListData::erase(void **xi)
\sa operator+=(), operator-()
*/
-/*! \fn QList::iterator QList::iterator::operator+(int j) const
+/*! \fn QList::iterator QList::iterator::operator+(difference_type j) const
Returns an iterator to the item at \a j positions forward from
this iterator. (If \a j is negative, the iterator goes backward.)
@@ -1490,7 +1490,7 @@ void **QListData::erase(void **xi)
\sa operator-(), operator+=()
*/
-/*! \fn QList::iterator QList::iterator::operator-(int j) const
+/*! \fn QList::iterator QList::iterator::operator-(difference_type j) const
Returns an iterator to the item at \a j positions backward from
this iterator. (If \a j is negative, the iterator goes forward.)
@@ -1620,7 +1620,7 @@ void **QListData::erase(void **xi)
\sa operator*()
*/
-/*! \fn const T &QList::const_iterator::operator[](int j) const
+/*! \fn const T &QList::const_iterator::operator[](difference_type j) const
Returns the item at position *this + \a{j}.
@@ -1712,7 +1712,7 @@ void **QListData::erase(void **xi)
current and returns an iterator to the previously current item.
*/
-/*! \fn QList::const_iterator &QList::const_iterator::operator+=(int j)
+/*! \fn QList::const_iterator &QList::const_iterator::operator+=(difference_type j)
Advances the iterator by \a j items. (If \a j is negative, the
iterator goes backward.)
@@ -1720,7 +1720,7 @@ void **QListData::erase(void **xi)
\sa operator-=(), operator+()
*/
-/*! \fn QList::const_iterator &QList::const_iterator::operator-=(int j)
+/*! \fn QList::const_iterator &QList::const_iterator::operator-=(difference_type j)
Makes the iterator go back by \a j items. (If \a j is negative,
the iterator goes forward.)
@@ -1728,7 +1728,7 @@ void **QListData::erase(void **xi)
\sa operator+=(), operator-()
*/
-/*! \fn QList::const_iterator QList::const_iterator::operator+(int j) const
+/*! \fn QList::const_iterator QList::const_iterator::operator+(difference_type j) const
Returns an iterator to the item at \a j positions forward from
this iterator. (If \a j is negative, the iterator goes backward.)
@@ -1736,7 +1736,7 @@ void **QListData::erase(void **xi)
\sa operator-(), operator+=()
*/
-/*! \fn QList::const_iterator QList::const_iterator::operator-(int j) const
+/*! \fn QList::const_iterator QList::const_iterator::operator-(difference_type j) const
Returns an iterator to the item at \a j positions backward from
this iterator. (If \a j is negative, the iterator goes forward.)
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 9704c7b953..5b459269c1 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -188,6 +188,7 @@ public:
public:
Node *i;
typedef std::random_access_iterator_tag iterator_category;
+ // ### Qt6: use int
typedef qptrdiff difference_type;
typedef T value_type;
typedef T *pointer;
@@ -198,7 +199,7 @@ public:
inline iterator(const iterator &o): i(o.i){}
inline T &operator*() const { return i->t(); }
inline T *operator->() const { return &i->t(); }
- inline T &operator[](int j) const { return i[j].t(); }
+ inline T &operator[](difference_type j) const { return i[j].t(); }
inline bool operator==(const iterator &o) const { return i == o.i; }
inline bool operator!=(const iterator &o) const { return i != o.i; }
inline bool operator<(const iterator& other) const { return i < other.i; }
@@ -223,10 +224,10 @@ public:
inline iterator operator++(int) { Node *n = i; ++i; return n; }
inline iterator &operator--() { i--; return *this; }
inline iterator operator--(int) { Node *n = i; i--; return n; }
- inline iterator &operator+=(int j) { i+=j; return *this; }
- inline iterator &operator-=(int j) { i-=j; return *this; }
- inline iterator operator+(int j) const { return iterator(i+j); }
- inline iterator operator-(int j) const { return iterator(i-j); }
+ inline iterator &operator+=(difference_type j) { i+=j; return *this; }
+ inline iterator &operator-=(difference_type j) { i-=j; return *this; }
+ inline iterator operator+(difference_type j) const { return iterator(i+j); }
+ inline iterator operator-(difference_type j) const { return iterator(i-j); }
inline int operator-(iterator j) const { return int(i - j.i); }
};
friend class iterator;
@@ -235,6 +236,7 @@ public:
public:
Node *i;
typedef std::random_access_iterator_tag iterator_category;
+ // ### Qt6: use int
typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
@@ -250,7 +252,7 @@ public:
#endif
inline const T &operator*() const { return i->t(); }
inline const T *operator->() const { return &i->t(); }
- inline const T &operator[](int j) const { return i[j].t(); }
+ inline const T &operator[](difference_type j) const { return i[j].t(); }
inline bool operator==(const const_iterator &o) const { return i == o.i; }
inline bool operator!=(const const_iterator &o) const { return i != o.i; }
inline bool operator<(const const_iterator& other) const { return i < other.i; }
@@ -261,10 +263,10 @@ public:
inline const_iterator operator++(int) { Node *n = i; ++i; return n; }
inline const_iterator &operator--() { i--; return *this; }
inline const_iterator operator--(int) { Node *n = i; i--; return n; }
- inline const_iterator &operator+=(int j) { i+=j; return *this; }
- inline const_iterator &operator-=(int j) { i-=j; return *this; }
- inline const_iterator operator+(int j) const { return const_iterator(i+j); }
- inline const_iterator operator-(int j) const { return const_iterator(i-j); }
+ inline const_iterator &operator+=(difference_type j) { i+=j; return *this; }
+ inline const_iterator &operator-=(difference_type j) { i-=j; return *this; }
+ inline const_iterator operator+(difference_type j) const { return const_iterator(i+j); }
+ inline const_iterator operator-(difference_type j) const { return const_iterator(i-j); }
inline int operator-(const_iterator j) const { return int(i - j.i); }
};
friend class const_iterator;
@@ -316,6 +318,7 @@ public:
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
+ // ### Qt6: use int
typedef qptrdiff difference_type;
// comfort
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index a253057435..a923be50c0 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -3144,7 +3144,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len,
}
bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
- int decDigits) const
+ int decDigits, bool rejectGroupSeparators) const
{
buff->clear();
buff->reserve(str.length());
@@ -3205,7 +3205,7 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr
case ',':
//it can only be placed after a digit which is before the decimal point
- if (!lastWasDigit || decPointCnt > 0)
+ if (rejectGroupSeparators || !lastWasDigit || decPointCnt > 0)
return false;
break;
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index c33ced35d5..c5e62027c4 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -251,7 +251,9 @@ public:
inline char digitToCLocale(QChar c) const;
// this function is used in QIntValidator (QtGui)
- Q_CORE_EXPORT bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
+ Q_CORE_EXPORT bool validateChars(const QString &str, NumberMode numMode,
+ QByteArray *buff, int decDigits = -1,
+ bool rejectGroupSeparators = false) const;
public:
quint16 m_language_id, m_script_id, m_country_id;
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 0b3bbc0ad0..5281723c5d 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -519,7 +519,7 @@ QBasicAtomicInt qt_cpu_features = Q_BASIC_ATOMIC_INITIALIZER(0);
void qDetectCpuFeatures()
{
#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
-# if (__GNUC__ * 100 + __GNUC_MINOR__) < 403
+# if Q_CC_GNU < 403
// GCC 4.2 (at least the one that comes with Apple's XCode, on Mac) is
// known to be broken beyond repair in dealing with the inline assembly
// above. It will generate bad code that could corrupt important registers
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index ee2ff99a80..891a3ff053 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -218,8 +218,8 @@
#endif
// other x86 intrinsics
-#if defined(Q_PROCESSOR_X86) && ((defined(Q_CC_GNU) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) \
- || (defined(Q_CC_CLANG) && (__clang_major__ * 100 + __clang_minor__ >= 208)) \
+#if defined(Q_PROCESSOR_X86) && ((defined(Q_CC_GNU) && (Q_CC_GNU >= 404)) \
+ || (defined(Q_CC_CLANG) && (Q_CC_CLANG >= 208)) \
|| defined(Q_CC_INTEL))
# define QT_COMPILER_SUPPORTS_X86INTRIN
# ifdef Q_CC_INTEL
@@ -318,7 +318,7 @@ static inline uint qCpuFeatures()
#ifdef Q_PROCESSOR_X86
// Bit scan functions for x86
-# ifdef Q_CC_MSVC
+# if defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need
static __forceinline unsigned long _bit_scan_reverse(uint val)
{
@@ -332,7 +332,7 @@ static __forceinline unsigned long _bit_scan_forward(uint val)
_BitScanForward(&result, val);
return result;
}
-# elif (defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && __GNUC__ * 100 + __GNUC_MINOR__ < 405)) \
+# elif (defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && Q_CC_GNU < 405)) \
&& !defined(Q_CC_INTEL)
// Clang is missing the intrinsic for _bit_scan_reverse
// GCC only added it in version 4.5
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 0d13cccbec..76069225eb 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -3938,28 +3938,31 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl
{
QStringList sections = split(sep, KeepEmptyParts,
(flags & SectionCaseInsensitiveSeps) ? Qt::CaseInsensitive : Qt::CaseSensitive);
- if (sections.isEmpty())
- return QString();
+ const int sectionsSize = sections.size();
+
if (!(flags & SectionSkipEmpty)) {
if (start < 0)
- start += sections.count();
+ start += sectionsSize;
if (end < 0)
- end += sections.count();
+ end += sectionsSize;
} else {
int skip = 0;
- for (int k=0; k<sections.size(); ++k) {
+ for (int k = 0; k < sectionsSize; ++k) {
if (sections.at(k).isEmpty())
skip++;
}
if (start < 0)
- start += sections.count() - skip;
+ start += sectionsSize - skip;
if (end < 0)
- end += sections.count() - skip;
+ end += sectionsSize - skip;
}
+ if (start >= sectionsSize || end < 0 || start > end)
+ return QString();
+
int x = 0;
QString ret;
int first_i = start, last_i = end;
- for (int i = 0; x <= end && i < sections.size(); ++i) {
+ for (int i = 0; x <= end && i < sectionsSize; ++i) {
QString section = sections.at(i);
const bool empty = section.isEmpty();
if (x >= start) {
@@ -3967,16 +3970,16 @@ QString QString::section(const QString &sep, int start, int end, SectionFlags fl
first_i = i;
if(x == end)
last_i = i;
- if(x > start)
+ if (x > start && i > 0)
ret += sep;
ret += section;
}
if (!empty || !(flags & SectionSkipEmpty))
x++;
}
- if((flags & SectionIncludeLeadingSep) && first_i)
+ if ((flags & SectionIncludeLeadingSep) && first_i > 0)
ret.prepend(sep);
- if((flags & SectionIncludeTrailingSep) && last_i < sections.size()-1)
+ if ((flags & SectionIncludeTrailingSep) && last_i < sectionsSize - 1)
ret += sep;
return ret;
}
@@ -3996,15 +3999,32 @@ static QString extractSections(const QVector<qt_section_chunk> &sections,
int end,
QString::SectionFlags flags)
{
- if (start < 0)
- start += sections.count();
- if (end < 0)
- end += sections.count();
+ const int sectionsSize = sections.size();
+
+ if (!(flags & QString::SectionSkipEmpty)) {
+ if (start < 0)
+ start += sectionsSize;
+ if (end < 0)
+ end += sectionsSize;
+ } else {
+ int skip = 0;
+ for (int k = 0; k < sectionsSize; ++k) {
+ const qt_section_chunk &section = sections.at(k);
+ if (section.length == section.string.length())
+ skip++;
+ }
+ if (start < 0)
+ start += sectionsSize - skip;
+ if (end < 0)
+ end += sectionsSize - skip;
+ }
+ if (start >= sectionsSize || end < 0 || start > end)
+ return QString();
QString ret;
int x = 0;
int first_i = start, last_i = end;
- for (int i = 0; x <= end && i < sections.size(); ++i) {
+ for (int i = 0; x <= end && i < sectionsSize; ++i) {
const qt_section_chunk &section = sections.at(i);
const bool empty = (section.length == section.string.length());
if (x >= start) {
@@ -4021,12 +4041,13 @@ static QString extractSections(const QVector<qt_section_chunk> &sections,
x++;
}
- if ((flags & QString::SectionIncludeLeadingSep) && first_i < sections.size()) {
+ if ((flags & QString::SectionIncludeLeadingSep) && first_i >= 0) {
const qt_section_chunk &section = sections.at(first_i);
ret.prepend(section.string.left(section.length));
}
- if ((flags & QString::SectionIncludeTrailingSep) && last_i+1 <= sections.size()-1) {
+ if ((flags & QString::SectionIncludeTrailingSep)
+ && last_i < sectionsSize - 1) {
const qt_section_chunk &section = sections.at(last_i+1);
ret += section.string.left(section.length);
}
@@ -5650,21 +5671,18 @@ QString QString::toUpper_helper(QString &str)
Safely builds a formatted string from the format string \a cformat
and an arbitrary list of arguments.
- The %lc escape sequence expects a unicode character of type ushort
- (as returned by QChar::unicode()). The %ls escape sequence expects
- a pointer to a zero-terminated array of unicode characters of type
- ushort (as returned by QString::utf16()).
-
- \note This function expects a UTF-8 string for %s and Latin-1 for
- the format string.
+ The format string supports the conversion specifiers, length modifiers,
+ and flags provided by printf() in the standard C++ library. The \a cformat
+ string and \c{%s} arguments must be UTF-8 encoded.
- The format string supports most of the conversion specifiers
- provided by printf() in the standard C++ library. It doesn't
- honor the length modifiers (e.g. \c h for \c short, \c ll for
- \c{long long}). If you need those, use the standard snprintf()
- function instead:
-
- \snippet qstring/main.cpp 63
+ \note The \c{%lc} escape sequence expects a unicode character of type
+ \c char16_t, or \c ushort (as returned by QChar::unicode()).
+ The \c{%ls} escape sequence expects a pointer to a zero-terminated array
+ of unicode characters of type \c char16_t, or ushort (as returned by
+ QString::utf16()). This is at odds with the printf() in the standard C++
+ library, which defines \c {%lc} to print a wchar_t and \c{%ls} to print
+ a \c{wchar_t*}, and might also produce compiler warnings on platforms
+ where the size of \c {wchar_t} is not 16 bits.
\warning We do not recommend using QString::sprintf() in new Qt
code. Instead, consider using QTextStream or arg(), both of
@@ -6284,8 +6302,7 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 66
- Various string formats for floating point numbers can be converted
- to double values:
+ \warning The QString content may only contain valid numerical characters which includes the plus/minus sign, the characters g and e used in scientific notation, and the decimal point. Including the unit or additional characters leads to a conversion error.
\snippet qstring/main.cpp 67
@@ -6294,7 +6311,7 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 68
- For historic reasons, this function does not handle
+ For historical reasons, this function does not handle
thousands group separators. If you need to convert such numbers,
use QLocale::toDouble().
diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp
index 4d148249c0..3c8a9db086 100644
--- a/src/corelib/tools/qversionnumber.cpp
+++ b/src/corelib/tools/qversionnumber.cpp
@@ -40,7 +40,7 @@
**
****************************************************************************/
-#include <QtCore/qversionnumber.h>
+#include <QtCore/private/qversionnumber_p.h>
#include <QtCore/qhash.h>
#include <QtCore/private/qlocale_tools_p.h>
#include <QtCore/qcollator.h>
@@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QVersionNumber
\inmodule QtCore
+ \internal
\since 5.4
\brief The QVersionNumber class contains a version number with an arbitrary
number of segments.
diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber_p.h
index a951b2f1a0..a951b2f1a0 100644
--- a/src/corelib/tools/qversionnumber.h
+++ b/src/corelib/tools/qversionnumber_p.h
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 2e77f683a4..6f6404f83c 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -72,7 +72,7 @@ HEADERS += \
tools/qunicodetools_p.h \
tools/qvarlengtharray.h \
tools/qvector.h \
- tools/qversionnumber.h
+ tools/qversionnumber_p.h
SOURCES += \
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index b1ec11dc71..00c3aced0e 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -282,24 +282,18 @@ public:
QStringList serverConnectionNames;
ConnectionMode mode;
+ QDBusConnectionInterface *busService;
- // members accessed in unlocked mode (except for deletion)
- // connection and server provide their own locking mechanisms
- // busService doesn't have state to be changed
+ // the dispatch lock protects everything related to the DBusConnection or DBusServer
+ // including the timeouts and watches
+ QMutex dispatchLock;
DBusConnection *connection;
DBusServer *server;
- QDBusConnectionInterface *busService;
-
- // watchers and timeouts are accessed from any thread
- // but the corresponding timer and QSocketNotifier must be handled
- // only in the object's thread
- QMutex watchAndTimeoutLock;
WatcherHash watchers;
TimeoutHash timeouts;
PendingTimeoutList timeoutsPendingAdd;
- // members accessed through a lock
- QMutex dispatchLock;
+ // the master lock protects our own internal state
QReadWriteLock lock;
QDBusError lastError;
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 8586bdd83c..6fcdd5030a 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -154,7 +154,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
if (!q_dbus_timeout_get_enabled(timeout))
return true;
- QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d);
+ QDBusDispatchLocker locker(AddTimeoutAction, d);
if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) {
// correct thread
return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout));
@@ -189,7 +189,7 @@ static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data)
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
- QDBusWatchAndTimeoutLocker locker(RemoveTimeoutAction, d);
+ QDBusDispatchLocker locker(RemoveTimeoutAction, d);
// is it pending addition?
QDBusConnectionPrivate::PendingTimeoutList::iterator pit = d->timeoutsPendingAdd.begin();
@@ -262,7 +262,7 @@ static bool qDBusRealAddWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int f
{
QDBusConnectionPrivate::Watcher watcher;
- QDBusWatchAndTimeoutLocker locker(AddWatchAction, d);
+ QDBusDispatchLocker locker(AddWatchAction, d);
if (flags & DBUS_WATCH_READABLE) {
//qDebug("addReadWatch %d", fd);
watcher.watch = watch;
@@ -296,7 +296,7 @@ static void qDBusRemoveWatch(DBusWatch *watch, void *data)
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
int fd = q_dbus_watch_get_unix_fd(watch);
- QDBusWatchAndTimeoutLocker locker(RemoveWatchAction, d);
+ QDBusDispatchLocker locker(RemoveWatchAction, d);
QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
while (i != d->watchers.end() && i.key() == fd) {
if (i.value().watch == watch) {
@@ -340,7 +340,7 @@ static void qDBusToggleWatch(DBusWatch *watch, void *data)
static void qDBusRealToggleWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int fd)
{
- QDBusWatchAndTimeoutLocker locker(ToggleWatchAction, d);
+ QDBusDispatchLocker locker(ToggleWatchAction, d);
QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
while (i != d->watchers.end() && i.key() == fd) {
@@ -1015,8 +1015,8 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
extern bool qDBusInitThreads();
QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
- : QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0),
- watchAndTimeoutLock(QMutex::Recursive),
+ : QObject(p), ref(1), capabilities(0), mode(InvalidMode), busService(0),
+ dispatchLock(QMutex::Recursive), connection(0), server(0),
rootNode(QString(QLatin1Char('/'))),
anonymousAuthenticationAllowed(false)
{
@@ -1126,7 +1126,7 @@ bool QDBusConnectionPrivate::handleError(const QDBusErrorInternal &error)
void QDBusConnectionPrivate::timerEvent(QTimerEvent *e)
{
{
- QDBusWatchAndTimeoutLocker locker(TimerEventAction, this);
+ QDBusDispatchLocker locker(TimerEventAction, this);
DBusTimeout *timeout = timeouts.value(e->timerId(), 0);
if (timeout)
q_dbus_timeout_handle(timeout);
@@ -1145,7 +1145,7 @@ void QDBusConnectionPrivate::customEvent(QEvent *e)
switch (ev->subtype)
{
case QDBusConnectionCallbackEvent::AddTimeout: {
- QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this);
+ QDBusDispatchLocker locker(RealAddTimeoutAction, this);
while (!timeoutsPendingAdd.isEmpty()) {
QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst();
qDBusRealAddTimeout(this, entry.first, entry.second);
@@ -1178,41 +1178,29 @@ void QDBusConnectionPrivate::doDispatch()
void QDBusConnectionPrivate::socketRead(int fd)
{
- QVarLengthArray<DBusWatch *, 2> pendingWatches;
-
- {
- QDBusWatchAndTimeoutLocker locker(SocketReadAction, this);
- WatcherHash::ConstIterator it = watchers.constFind(fd);
- while (it != watchers.constEnd() && it.key() == fd) {
- if (it->watch && it->read && it->read->isEnabled())
- pendingWatches.append(it.value().watch);
- ++it;
+ QDBusDispatchLocker locker(SocketReadAction, this);
+ WatcherHash::ConstIterator it = watchers.constFind(fd);
+ while (it != watchers.constEnd() && it.key() == fd) {
+ if (it->watch && it->read && it->read->isEnabled()) {
+ if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE))
+ qDebug("OUT OF MEM");
}
+ ++it;
}
-
- for (int i = 0; i < pendingWatches.size(); ++i)
- if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_READABLE))
- qDebug("OUT OF MEM");
doDispatch();
}
void QDBusConnectionPrivate::socketWrite(int fd)
{
- QVarLengthArray<DBusWatch *, 2> pendingWatches;
-
- {
- QDBusWatchAndTimeoutLocker locker(SocketWriteAction, this);
- WatcherHash::ConstIterator it = watchers.constFind(fd);
- while (it != watchers.constEnd() && it.key() == fd) {
- if (it->watch && it->write && it->write->isEnabled())
- pendingWatches.append(it.value().watch);
- ++it;
+ QDBusDispatchLocker locker(SocketWriteAction, this);
+ WatcherHash::ConstIterator it = watchers.constFind(fd);
+ while (it != watchers.constEnd() && it.key() == fd) {
+ if (it->watch && it->write && it->write->isEnabled()) {
+ if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE))
+ qDebug("OUT OF MEM");
}
+ ++it;
}
-
- for (int i = 0; i < pendingWatches.size(); ++i)
- if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_WRITABLE))
- qDebug("OUT OF MEM");
}
void QDBusConnectionPrivate::objectDestroyed(QObject *obj)
@@ -1265,7 +1253,10 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in
//qDBusDebug() << "Emitting signal" << message;
//qDBusDebug() << "for paths:";
q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything
- huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
+ {
+ QDBusDispatchLocker locker(HuntAndEmitAction, this);
+ huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
+ }
q_dbus_message_unref(msg);
}
@@ -1922,7 +1913,11 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message)
qDBusDebug() << this << "sending message (no reply):" << message;
checkThread();
- bool isOk = q_dbus_connection_send(connection, msg, 0);
+ bool isOk;
+ {
+ QDBusDispatchLocker locker(SendMessageAction, this);
+ isOk = q_dbus_connection_send(connection, msg, 0);
+ }
int serial = 0;
if (isOk)
serial = q_dbus_message_get_serial(msg);
@@ -2040,7 +2035,11 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
qDBusDebug() << this << "sending message (blocking):" << message;
QDBusErrorInternal error;
- DBusMessage *reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error);
+ DBusMessage *reply;
+ {
+ QDBusDispatchLocker locker(SendWithReplyAndBlockAction, this);
+ reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error);
+ }
q_dbus_message_unref(msg);
diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp
index 8025636668..25206b4bb7 100644
--- a/src/dbus/qdbusmessage.cpp
+++ b/src/dbus/qdbusmessage.cpp
@@ -605,6 +605,10 @@ QString QDBusMessage::signature() const
*/
bool QDBusMessage::isReplyRequired() const
{
+ // Only method calls can have replies
+ if (d_ptr->type != DBUS_MESSAGE_TYPE_METHOD_CALL)
+ return false;
+
if (!d_ptr->msg)
return d_ptr->localMessage; // if it's a local message, reply is required
return !q_dbus_message_get_no_reply(d_ptr->msg);
diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h
index 78db18f5c7..8041068134 100644
--- a/src/dbus/qdbusthreaddebug_p.h
+++ b/src/dbus/qdbusthreaddebug_p.h
@@ -86,6 +86,9 @@ enum ThreadAction {
MessageResultReceivedAction = 26,
ActivateSignalAction = 27,
PendingCallBlockAction = 28,
+ SendMessageAction = 29,
+ SendWithReplyAndBlockAction = 30,
+ HuntAndEmitAction = 31,
AddTimeoutAction = 50,
RealAddTimeoutAction = 51,
@@ -196,13 +199,6 @@ struct QDBusDispatchLocker: QDBusMutexLocker
{ }
};
-struct QDBusWatchAndTimeoutLocker: QDBusMutexLocker
-{
- inline QDBusWatchAndTimeoutLocker(ThreadAction a, QDBusConnectionPrivate *s)
- : QDBusMutexLocker(a, s, &s->watchAndTimeoutLock)
- { }
-};
-
#if QDBUS_THREAD_DEBUG
# define SEM_ACQUIRE(action, sem) \
do { \
diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc
index 90248298d6..460018a52e 100644
--- a/src/gui/doc/src/richtext.qdoc
+++ b/src/gui/doc/src/richtext.qdoc
@@ -27,6 +27,7 @@
/*!
\group richtext-processing
+ \brief How to use Rich Text Processing APIs.
\title Rich Text Processing APIs
*/
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index f1a384af3a..d885729cbd 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1173,8 +1173,8 @@ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
QIconEngine * const engine = platformTheme ? platformTheme->createIconEngine(name)
: new QIconLoaderEngine(name);
QIcon *cachedIcon = new QIcon(engine);
- qtIconCache()->insert(name, cachedIcon);
icon = *cachedIcon;
+ qtIconCache()->insert(name, cachedIcon);
}
// Note the qapp check is to allow lazy loading of static icons
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 6009918521..2e8fc1963d 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -2945,7 +2945,7 @@ void qInitImageConversions()
}
#endif
-#ifdef __ARM_NEON__
+#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
index e3930bbb4d..88d1c87ee7 100644
--- a/src/gui/image/qimage_neon.cpp
+++ b/src/gui/image/qimage_neon.cpp
@@ -35,7 +35,7 @@
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#ifdef __ARM_NEON__
+#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
QT_BEGIN_NAMESPACE
@@ -103,4 +103,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
QT_END_NAMESPACE
-#endif // __ARM_NEON__
+#endif // defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index fbcc0608e2..ae30de634a 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -729,7 +729,7 @@ public:
};
QJpegHandlerPrivate(QJpegHandler *qq)
- : quality(75), iod_src(0), state(Ready), q(qq)
+ : quality(75), exifOrientation(1), iod_src(0), state(Ready), q(qq)
{}
~QJpegHandlerPrivate()
@@ -744,8 +744,10 @@ public:
bool readJpegHeader(QIODevice*);
bool read(QImage *image);
+ void applyExifOrientation(QImage *image);
int quality;
+ int exifOrientation;
QVariant size;
QImage::Format format;
QSize scaledSize;
@@ -763,6 +765,97 @@ public:
QJpegHandler *q;
};
+static bool readExifHeader(QDataStream &stream)
+{
+ char prefix[6];
+ if (stream.readRawData(prefix, sizeof(prefix)) != sizeof(prefix))
+ return false;
+ if (prefix[0] != 'E' || prefix[1] != 'x' || prefix[2] != 'i' || prefix[3] != 'f' || prefix[4] != 0 || prefix[5] != 0)
+ return false;
+ return true;
+}
+
+/*
+ * Returns -1 on error
+ * Returns 0 if no Exif orientation was found
+ * Returns 1 orientation is horizontal (normal)
+ * Returns 2 mirror horizontal
+ * Returns 3 rotate 180
+ * Returns 4 mirror vertical
+ * Returns 5 mirror horizontal and rotate 270 CCW
+ * Returns 6 rotate 90 CW
+ * Returns 7 mirror horizontal and rotate 90 CW
+ * Returns 8 rotate 270 CW
+ */
+static int getExifOrientation(QByteArray &exifData)
+{
+ QDataStream stream(&exifData, QIODevice::ReadOnly);
+
+ if (!readExifHeader(stream))
+ return -1;
+
+ quint16 val;
+ quint32 offset;
+
+ // read byte order marker
+ stream >> val;
+ if (val == 0x4949) // 'II' == Intel
+ stream.setByteOrder(QDataStream::LittleEndian);
+ else if (val == 0x4d4d) // 'MM' == Motorola
+ stream.setByteOrder(QDataStream::BigEndian);
+ else
+ return -1; // unknown byte order
+
+ // read size
+ stream >> val;
+ if (val != 0x2a)
+ return -1;
+
+ stream >> offset;
+ // we have already used 8 bytes of TIFF header
+ offset -= 8;
+
+ // read IFD
+ while (!stream.atEnd()) {
+ quint16 numEntries;
+
+ // skip offset bytes to get the next IFD
+ if (stream.skipRawData(offset) != (qint32)offset)
+ return -1;
+
+ stream >> numEntries;
+
+ for (;numEntries > 0; --numEntries) {
+ quint16 tag;
+ quint16 type;
+ quint32 components;
+ quint32 value;
+
+ stream >> tag >> type >> components >> value;
+
+ if (tag == 0x0112) { // Tag Exif.Image.Orientation
+ if (components !=1)
+ return -1;
+ if (type != 3) // we are expecting it to be an unsigned short
+ return -1;
+ if (value < 1 || value > 8) // check for valid range
+ return -1;
+
+ // It is possible to include the orientation multiple times.
+ // Right now the first value is returned.
+ return value;
+ }
+ }
+
+ // read offset to next IFD
+ stream >> offset;
+ if (offset == 0) // this is the last IFD
+ break;
+ }
+
+ // No Exif orientation was found
+ return 0;
+}
/*!
\internal
*/
@@ -782,6 +875,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
if (!setjmp(err.setjmp_buffer)) {
jpeg_save_markers(&info, JPEG_COM, 0xFFFF);
+ jpeg_save_markers(&info, JPEG_APP0+1, 0xFFFF); // Exif uses APP1 marker
(void) jpeg_read_header(&info, TRUE);
@@ -793,6 +887,8 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
format = QImage::Format_Invalid;
read_jpeg_format(format, &info);
+ QByteArray exifData;
+
for (jpeg_saved_marker_ptr marker = info.marker_list; marker != NULL; marker = marker->next) {
if (marker->marker == JPEG_COM) {
QString key, value;
@@ -810,9 +906,18 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
description += key + QLatin1String(": ") + value.simplified();
readTexts.append(key);
readTexts.append(value);
+ } else if (marker->marker == JPEG_APP0+1) {
+ exifData.append((const char*)marker->data, marker->data_length);
}
}
+ if (exifData.size()) {
+ // Exif data present
+ int orientation = getExifOrientation(exifData);
+ if (orientation > 0)
+ exifOrientation = orientation;
+ }
+
state = ReadHeader;
return true;
}
@@ -826,6 +931,48 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
return true;
}
+void QJpegHandlerPrivate::applyExifOrientation(QImage *image)
+{
+ // This is not an optimized implementation, but easiest to maintain
+ QTransform transform;
+
+ switch (exifOrientation) {
+ case 1: // normal
+ break;
+ case 2: // mirror horizontal
+ *image = image->mirrored(true, false);
+ break;
+ case 3: // rotate 180
+ transform.rotate(180);
+ *image = image->transformed(transform);
+ break;
+ case 4: // mirror vertical
+ *image = image->mirrored(false, true);
+ break;
+ case 5: // mirror horizontal and rotate 270 CCW
+ *image = image->mirrored(true, false);
+ transform.rotate(270);
+ *image = image->transformed(transform);
+ break;
+ case 6: // rotate 90 CW
+ transform.rotate(90);
+ *image = image->transformed(transform);
+ break;
+ case 7: // mirror horizontal and rotate 90 CW
+ *image = image->mirrored(true, false);
+ transform.rotate(90);
+ *image = image->transformed(transform);
+ break;
+ case 8: // rotate 270 CW
+ transform.rotate(-90);
+ *image = image->transformed(transform);
+ break;
+ default:
+ qWarning("This should never happen");
+ }
+ exifOrientation = 1;
+}
+
bool QJpegHandlerPrivate::read(QImage *image)
{
if(state == Ready)
@@ -837,6 +984,7 @@ bool QJpegHandlerPrivate::read(QImage *image)
if (success) {
for (int i = 0; i < readTexts.size()-1; i+=2)
image->setText(readTexts.at(i), readTexts.at(i+1));
+ applyExifOrientation(image);
state = Ready;
return true;
@@ -856,12 +1004,13 @@ extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uc
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(__ARM_NEON__)
+#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
// from qimage_neon.cpp
if (qCpuHasFeature(NEON))
rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
-#endif // __ARM_NEON__
+#endif
+
#if defined(QT_COMPILER_SUPPORTS_SSSE3)
// from qimage_ssse3.cpp
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c5e7fb523d..e421f79e91 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -163,7 +163,6 @@ QWindow *QGuiApplicationPrivate::focus_window = 0;
static QBasicMutex applicationFontMutex;
QFont *QGuiApplicationPrivate::app_font = 0;
bool QGuiApplicationPrivate::obey_desktop_settings = true;
-bool QGuiApplicationPrivate::noGrab = false;
static qreal fontSmoothingGamma = 1.7;
@@ -1191,20 +1190,10 @@ void QGuiApplicationPrivate::eventDispatcherReady()
platform_integration->initialize();
}
-#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
-// Find out if our parent process is gdb by looking at the 'exe' symlink under /proc.
-static bool runningUnderDebugger()
-{
- const QFileInfo parentProcExe(QStringLiteral("/proc/") + QString::number(getppid()) + QStringLiteral("/exe"));
- return parentProcExe.isSymLink() && parentProcExe.symLinkTarget().endsWith(QLatin1String("/gdb"));
-}
-#endif
-
void QGuiApplicationPrivate::init()
{
QCoreApplicationPrivate::is_app_running = false; // Starting up.
- bool doGrabUnderDebugger = false;
bool loadTestability = false;
QList<QByteArray> pluginList;
// Get command line params
@@ -1239,10 +1228,6 @@ void QGuiApplicationPrivate::init()
QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
}
#endif
- } else if (arg == "-nograb") {
- QGuiApplicationPrivate::noGrab = true;
- } else if (arg == "-dograb") {
- doGrabUnderDebugger = true;
#ifndef QT_NO_SESSIONMANAGER
} else if (arg == "-session" && i < argc-1) {
++i;
@@ -1268,16 +1253,6 @@ void QGuiApplicationPrivate::init()
argc = j;
}
-#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
- if (!doGrabUnderDebugger && !QGuiApplicationPrivate::noGrab && runningUnderDebugger()) {
- QGuiApplicationPrivate::noGrab = true;
- qDebug("Qt: gdb: -nograb added to command-line options.\n"
- "\t Use the -dograb option to enforce grabbing.");
- }
-#else
- Q_UNUSED(doGrabUnderDebugger)
-#endif
-
// Load environment exported generic plugins
foreach (const QByteArray &plugin, qgetenv("QT_QPA_GENERIC_PLUGINS").split(','))
pluginList << plugin;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 8988bd461d..eed3d5c10e 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -221,7 +221,6 @@ public:
QStyleHints *styleHints;
static bool obey_desktop_settings;
- static bool noGrab;
QInputMethod *inputMethod;
QString firstWindowTitle;
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index d5a3126176..975553e7cd 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -203,6 +203,7 @@ public:
, workaround_brokenTexSubImage(false)
, workaround_missingPrecisionQualifiers(false)
, active_engine(0)
+ , qgl_current_fbo_invalid(false)
{
requestedFormat = QSurfaceFormat::defaultFormat();
}
@@ -237,6 +238,8 @@ public:
QPaintEngineEx *active_engine;
+ bool qgl_current_fbo_invalid;
+
QVariant nativeHandle;
static QOpenGLContext *setCurrentContext(QOpenGLContext *context);
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
index 55a8aae33c..af60b36647 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow.cpp
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -52,6 +52,12 @@ QShapedPixmapWindow::QShapedPixmapWindow()
m_backingStore = new QBackingStore(this);
}
+QShapedPixmapWindow::~QShapedPixmapWindow()
+{
+ delete m_backingStore;
+ m_backingStore = 0;
+}
+
void QShapedPixmapWindow::render()
{
QRect rect(QPoint(), geometry().size());
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
index b59305f055..04198c83cb 100644
--- a/src/gui/kernel/qshapedpixmapdndwindow_p.h
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -56,6 +56,7 @@ class QShapedPixmapWindow : public QWindow
Q_OBJECT
public:
QShapedPixmapWindow();
+ ~QShapedPixmapWindow();
void render();
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index a3b7f38c80..fa99390af0 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1127,6 +1127,10 @@ Qt::WindowState QWindow::windowState() const
This is a hint to the window manager that this window is a dialog or pop-up
on behalf of the given window.
+ In order to cause the window to be centered above its transient parent by
+ default, depending on the window manager, it may also be necessary to call
+ setFlags() with a suitable \l Qt::WindowType (such as \c Qt::Dialog).
+
\sa transientParent(), parent()
*/
void QWindow::setTransientParent(QWindow *parent)
@@ -1644,8 +1648,6 @@ QPlatformSurface *QWindow::surfaceHandle() const
bool QWindow::setKeyboardGrabEnabled(bool grab)
{
Q_D(QWindow);
- if (grab && QGuiApplicationPrivate::noGrab)
- return false;
if (d->platformWindow)
return d->platformWindow->setKeyboardGrabEnabled(grab);
return false;
@@ -1663,8 +1665,6 @@ bool QWindow::setKeyboardGrabEnabled(bool grab)
bool QWindow::setMouseGrabEnabled(bool grab)
{
Q_D(QWindow);
- if (grab && QGuiApplicationPrivate::noGrab)
- return false;
if (d->platformWindow)
return d->platformWindow->setMouseGrabEnabled(grab);
return false;
@@ -2352,7 +2352,7 @@ QWindow *QWindow::fromWinId(WId id)
/*!
Causes an alert to be shown for \a msec miliseconds. If \a msec is \c 0 (the
default), then the alert is shown indefinitely until the window becomes
- active again.
+ active again. This function has no effect on an active window.
In alert state, the window indicates that it demands attention, for example by
flashing or bouncing the taskbar entry.
@@ -2363,7 +2363,7 @@ QWindow *QWindow::fromWinId(WId id)
void QWindow::alert(int msec)
{
Q_D(QWindow);
- if (!d->platformWindow || d->platformWindow->isAlertState())
+ if (!d->platformWindow || d->platformWindow->isAlertState() || isActive())
return;
d->platformWindow->setAlertState(true);
if (d->platformWindow->isAlertState() && msec)
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
index 6d9793ae3f..2230ed8801 100644
--- a/src/gui/kernel/qwindow.h
+++ b/src/gui/kernel/qwindow.h
@@ -358,6 +358,19 @@ private:
friend Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window);
};
+#ifndef Q_QDOC
+template <> inline QWindow *qobject_cast<QWindow*>(QObject *o)
+{
+ if (!o || !o->isWindowType()) return 0;
+ return static_cast<QWindow*>(o);
+}
+template <> inline const QWindow *qobject_cast<const QWindow*>(const QObject *o)
+{
+ if (!o || !o->isWindowType()) return 0;
+ return static_cast<const QWindow*>(o);
+}
+#endif // !Q_QDOC
+
QT_END_NAMESPACE
#endif // QWINDOW_H
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index b185e332e6..124d9d53f6 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -469,6 +469,8 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
funcs.glGenFramebuffers(1, &fbo);
funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true;
+
GLuint color_buffer = 0;
QT_CHECK_GLERROR();
@@ -997,7 +999,11 @@ bool QOpenGLFramebufferObject::bind()
if (current->shareGroup() != d->fbo_guard->group())
qWarning("QOpenGLFramebufferObject::bind() called from incompatible context");
#endif
+
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
+
+ QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
+
if (d->texture_guard || d->format.samples() != 0)
d->valid = d->checkFramebufferStatus(current);
else
@@ -1029,9 +1035,12 @@ bool QOpenGLFramebufferObject::release()
qWarning("QOpenGLFramebufferObject::release() called from incompatible context");
#endif
- if (current)
+ if (current) {
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->defaultFramebufferObject());
+ QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
+ }
+
return true;
}
@@ -1194,9 +1203,23 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
If used together with QOpenGLPaintDevice, \a flipped should be the opposite of the value
of QOpenGLPaintDevice::paintFlipped().
- Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
- a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported. Since 5.4 an
- A2BGR30 image is returned if the internal format is RGB10_A2.
+ The returned image has a format of premultiplied ARGB32 or RGB32. The latter is used
+ only when internalTextureFormat() is set to \c GL_RGB.
+
+ If the rendering in the framebuffer was not done with premultiplied alpha in mind,
+ create a wrapper QImage with a non-premultiplied format. This is necessary before
+ performing operations like QImage::save() because otherwise the image data would get
+ unpremultiplied, even though it was not premultiplied in the first place. To create
+ such a wrapper without performing a copy of the pixel data, do the following:
+
+ \code
+ QImage fboImage(fbo.toImage());
+ QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32);
+ \endcode
+
+ Since Qt 5.2 the function will fall back to premultiplied RGBA8888 or RGBx8888 when
+ reading to (A)RGB32 is not supported. Since 5.4 an A2BGR30 image is returned if the
+ internal format is RGB10_A2.
For multisampled framebuffer objects the samples are resolved using the
\c{GL_EXT_framebuffer_blit} extension. If the extension is not available, the contents
@@ -1272,8 +1295,10 @@ bool QOpenGLFramebufferObject::bindDefault()
{
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
- if (ctx)
+ if (ctx) {
ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
+ QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true;
+ }
#ifdef QT_DEBUG
else
qWarning("QOpenGLFramebufferObject::bindDefault() called without current context.");
@@ -1342,6 +1367,7 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen
qWarning("QOpenGLFramebufferObject::setAttachment() called from incompatible context");
#endif
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
+ QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
d->initAttachments(current, attachment);
}
diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp
index e908fd8e91..a08d26f708 100644
--- a/src/gui/opengl/qopenglpaintdevice.cpp
+++ b/src/gui/opengl/qopenglpaintdevice.cpp
@@ -138,8 +138,8 @@ QOpenGLPaintDevice::QOpenGLPaintDevice(int width, int height)
/*!
\internal
*/
-QOpenGLPaintDevice::QOpenGLPaintDevice(QOpenGLPaintDevicePrivate *dd)
- : d_ptr(dd)
+QOpenGLPaintDevice::QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd)
+ : d_ptr(&dd)
{
}
diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h
index dda3bfe43f..10cee842ab 100644
--- a/src/gui/opengl/qopenglpaintdevice.h
+++ b/src/gui/opengl/qopenglpaintdevice.h
@@ -53,7 +53,6 @@ public:
QOpenGLPaintDevice();
explicit QOpenGLPaintDevice(const QSize &size);
QOpenGLPaintDevice(int width, int height);
- QOpenGLPaintDevice(QOpenGLPaintDevicePrivate *dd);
virtual ~QOpenGLPaintDevice();
int devType() const { return QInternal::OpenGL; }
@@ -76,6 +75,7 @@ public:
virtual void ensureActiveTarget();
protected:
+ QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd);
int metric(QPaintDevice::PaintDeviceMetric metric) const;
Q_DISABLE_COPY(QOpenGLPaintDevice)
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
index 0f70a01014..cd268cd685 100644
--- a/src/gui/opengl/qopengltextureglyphcache.cpp
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -82,10 +82,12 @@ QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache()
clear();
}
+#if !defined(QT_OPENGL_ES_2)
static inline bool isCoreProfile()
{
return QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile;
}
+#endif
void QOpenGLTextureGlyphCache::createTextureData(int width, int height)
{
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index d120175108..d136f3a903 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -708,6 +708,9 @@ void QBrush::setStyle(Qt::BrushStyle style)
void QBrush::setColor(const QColor &c)
{
+ if (d->color == c)
+ return;
+
detach(d->style);
d->color = c;
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 4c6dc958b2..a991b89f48 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6928,7 +6928,7 @@ void qInitDrawhelperAsm()
qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
#endif
-#ifdef Q_PROCESSOR_MIPS_32
+#if defined(Q_PROCESSOR_MIPS_32) && defined(QT_COMPILER_SUPPORTS_MIPS_DSP)
qt_memfill32 = qt_memfill32_asm_mips_dsp;
#endif // Q_PROCESSOR_MIPS_32
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 30421ea2fa..8cf45863b8 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -2506,7 +2506,8 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
QFontEngine::FaceId face_id = fe->faceId();
bool noEmbed = false;
- if (face_id.filename.isEmpty()
+ if (!embedFonts
+ || face_id.filename.isEmpty()
|| fe->fsType & 0x200 /* bitmap embedding only */
|| fe->fsType == 2 /* no embedding allowed */) {
*currentPage << "Q\n";
@@ -2529,10 +2530,6 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
qreal size = ti.fontEngine->fontDef.pixelSize;
-#if defined(Q_OS_WIN)
- size = (ti.fontEngine->ascent() + ti.fontEngine->descent()).toReal();
-#endif
-
QVarLengthArray<glyph_t> glyphs;
QVarLengthArray<QFixedPoint> positions;
QTransform m = QTransform::fromTranslate(p.x(), p.y());
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index decf2fe121..8fe6aff79f 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -620,7 +620,7 @@ struct QtFontDesc
static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
- QtFontDesc *desc, const QList<int> &blacklisted, bool fallback);
+ QtFontDesc *desc, const QList<int> &blacklisted);
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi)
{
@@ -1110,7 +1110,7 @@ static bool matchFamilyName(const QString &familyName, QtFontFamily *f)
*/
static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
- QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool fallback = false)
+ QtFontDesc *desc, const QList<int> &blacklistedFamilies)
{
Q_UNUSED(force_encoding_id);
int result = -1;
@@ -1163,7 +1163,7 @@ static int match(int script, const QFontDef &request,
load(test.family->name, script);
// Check if family is supported in the script we want
- if (!fallback && script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported))
+ if (script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported))
continue;
// as we know the script is supported, we can be sure
@@ -2490,7 +2490,7 @@ bool QFontDatabase::supportsThreadedFontRendering()
*/
QFontEngine *
QFontDatabase::findFont(int script, const QFontPrivate *fp,
- const QFontDef &request, bool multi, bool fallback)
+ const QFontDef &request, bool multi)
{
QMutexLocker locker(fontDatabaseMutex());
@@ -2518,7 +2518,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
QtFontDesc desc;
QList<int> blackListed;
- int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed, fallback);
+ int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed);
if (index >= 0) {
engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
if (!engine)
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index f1c479d0bb..d7d8745f12 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -152,7 +152,7 @@ private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
static QString resolveFontFamilyAlias(const QString &family);
- static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false, bool fallback = false);
+ static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false);
static void load(const QFontPrivate *d, int script);
friend struct QFontDef;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index fe0f9fa943..4c6fc7c1a6 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -373,8 +373,6 @@ bool QFontEngine::supportsScript(QChar::Script script) const
if (!ret && script_tag_2 != HB_OT_TAG_DEFAULT_SCRIPT)
ret = hb_ot_layout_table_find_script(face, HB_OT_TAG_GSUB, HB_OT_TAG_DEFAULT_SCRIPT, &script_index);
}
-
- hb_face_destroy(face);
}
return ret;
}
@@ -2028,7 +2026,7 @@ void QFontEngineMultiBasicImpl::loadEngine(int at)
request.family = fallbackFamilies.at(at-1);
engines[at] = QFontDatabase::findFont(script,
/*fontprivate = */0,
- request, /*multi = */false, true);
+ request, /*multi = */false);
Q_ASSERT(engines[at]);
engines[at]->ref.ref();
engines[at]->fontDef = request;
@@ -2098,4 +2096,8 @@ QFontEngine* QFontEngineMultiBasicImpl::createMultiFontEngine(QFontEngine *fe, i
return engine;
}
+QTestFontEngine::QTestFontEngine(int size)
+ : QFontEngineBox(TestFontEngine, size)
+{}
+
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index b44eb43be5..4c5bab77d6 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -1459,10 +1459,7 @@ void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_me
bool QFontEngineFT::supportsTransformation(const QTransform &transform) const
{
- // The freetype engine falls back to QFontEngine for tranformed glyphs,
- // which uses fast-tranform and produces very ugly results, so we claim
- // to support just translations.
- return transform.type() <= QTransform::TxTranslate;
+ return transform.type() <= QTransform::TxRotate;
}
void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
@@ -1943,17 +1940,75 @@ void QFontEngineFT::unlockAlphaMapForGlyph()
currentlyLockedAlphaMap = QImage();
}
-QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format)
+QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
+ QFixed subPixelPosition,
+ GlyphFormat format,
+ const QTransform &t)
{
- return defaultGlyphSet.outline_drawing ? 0 :
- loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, g, subPixelPosition, format);
+ FT_Face face = 0;
+ QGlyphSet *glyphSet = 0;
+ FT_Matrix ftMatrix = QTransformToFTMatrix(t);
+ if (cacheEnabled) {
+ if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) {
+ for (int i = 0; i < transformedGlyphSets.count(); ++i) {
+ const QGlyphSet &g = transformedGlyphSets.at(i);
+ if (g.transformationMatrix.xx == ftMatrix.xx
+ && g.transformationMatrix.xy == ftMatrix.xy
+ && g.transformationMatrix.yx == ftMatrix.yx
+ && g.transformationMatrix.yy == ftMatrix.yy) {
+
+ // found a match, move it to the front
+ transformedGlyphSets.move(i, 0);
+ glyphSet = &transformedGlyphSets[0];
+ break;
+ }
+ }
+
+ if (!glyphSet) {
+ // don't cache more than 10 transformations
+ if (transformedGlyphSets.count() >= 10) {
+ transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0);
+ } else {
+ transformedGlyphSets.prepend(QGlyphSet());
+ }
+ glyphSet = &transformedGlyphSets[0];
+ glyphSet->clear();
+ glyphSet->transformationMatrix = ftMatrix;
+ }
+ } else {
+ glyphSet = &defaultGlyphSet;
+ }
+ Q_ASSERT(glyphSet != 0);
+ }
+
+ if (glyphSet != 0 && glyphSet->outline_drawing)
+ return 0;
+
+ Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0;
+ if (!glyph || glyph->format != format) {
+ face = lockFace();
+ FT_Matrix m = this->matrix;
+ FT_Matrix_Multiply(&ftMatrix, &m);
+ freetype->matrix = m;
+ glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false);
+ }
+
+ if (face)
+ unlockFace();
+
+ return glyph;
}
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
{
+ return alphaMapForGlyph(g, subPixelPosition, QTransform());
+}
+
+QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
+{
lockFace();
- QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono));
+ QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono, t));
if (!glyph || !glyph->data) {
unlockFace();
return QFontEngine::alphaMapForGlyph(g);
@@ -1982,12 +2037,12 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
{
- if (t.type() > QTransform::TxTranslate)
+ if (t.type() > QTransform::TxRotate)
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
lockFace();
- QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32));
+ QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32, t));
if (!glyph || !glyph->data) {
unlockFace();
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index a73c281f1d..1894d25d70 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -233,6 +233,7 @@ private:
virtual void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const;
virtual QImage alphaMapForGlyph(glyph_t g) { return alphaMapForGlyph(g, 0); }
virtual QImage alphaMapForGlyph(glyph_t, QFixed);
+ QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
QFixed subPixelPosition,
@@ -265,7 +266,7 @@ private:
inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false) const
{ return loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, subPixelPosition, format, fetchMetricsOnly); }
Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const;
- Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format);
+ Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t);
QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix);
bool loadGlyphs(QGlyphSet *gs, const glyph_t *glyphs, int num_glyphs,
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 50b1bb9e9d..9364b82bed 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -463,7 +463,7 @@ private:
class QTestFontEngine : public QFontEngineBox
{
public:
- inline QTestFontEngine(int size) : QFontEngineBox(TestFontEngine, size) {}
+ QTestFontEngine(int size);
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index eb7bca1974..16c45e642b 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -632,7 +632,7 @@ hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe)
fe->face_destroy_func = _hb_qt_face_release;
}
- return hb_face_reference((hb_face_t *)fe->face_);
+ return (hb_face_t *)fe->face_;
}
@@ -645,8 +645,6 @@ _hb_qt_font_create(QFontEngine *fe)
hb_font_t *font = hb_font_create(face);
- hb_face_destroy(face); // ref-ed in hb_qt_face_get_for_engine()
-
if (Q_UNLIKELY(hb_font_is_immutable(font))) {
hb_font_destroy(font);
return NULL;
@@ -684,7 +682,7 @@ hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe)
fe->font_destroy_func = _hb_qt_font_release;
}
- return hb_font_reference((hb_font_t *)fe->font_);
+ return (hb_font_t *)fe->font_;
}
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 9fe1fd26e9..d156124b98 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1168,8 +1168,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
};
const int num_features = 1;
shapedOk = hb_shape_full(hb_font, buffer, features, num_features, 0);
-
- hb_font_destroy(hb_font);
}
if (!shapedOk) {
hb_buffer_destroy(buffer);
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index f6525448de..37c18e3624 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -44,31 +44,49 @@
QT_BEGIN_NAMESPACE
-static QString resolve2xFile(const QString &fileName, qreal targetDevicePixelRatio)
+static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio)
{
+ // We might use the fileName for loading if url loading fails
+ // try to make sure it is a valid file path.
+ // Also, QFile{Info}::exists works only on filepaths (not urls)
+
+ if (url->isValid()) {
+ if (url->scheme() == QLatin1Literal("qrc")) {
+ fileName = fileName.right(fileName.length() - 3);
+ }
+ else if (url->scheme() == QLatin1Literal("file")) {
+ fileName = url->toLocalFile();
+ }
+ }
+
if (targetDevicePixelRatio <= 1.0)
return fileName;
- int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
+ // try to find a 2x version
+
+ const int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
if (dotIndex != -1) {
QString at2xfileName = fileName;
at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
- if (QFile::exists(at2xfileName))
- return at2xfileName;
+ if (QFile::exists(at2xfileName)) {
+ fileName = at2xfileName;
+ *url = QUrl(fileName);
+ }
}
+
return fileName;
}
-static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
+
+static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
{
QPixmap pm;
QString name = format.name();
- if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
+ if (name.startsWith(QLatin1String(":/"))) // auto-detect resources and convert them to url
name.prepend(QLatin1String("qrc"));
- QPaintDevice *pdev = doc->documentLayout()->paintDevice();
- name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio());
QUrl url = QUrl(name);
+ name = resolveFileName(name, &url, devicePixelRatio);
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Pixmap || data.type() == QVariant::Image) {
pm = qvariant_cast<QPixmap>(data);
@@ -77,19 +95,18 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
}
if (pm.isNull()) {
- QString context;
#if 0
+ QString context;
// ### Qt5
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
if (browser)
context = browser->source().toString();
#endif
+ // try direct loading
QImage img;
- if (img.isNull()) { // try direct loading
- name = format.name(); // remove qrc:/ prefix again
- if (name.isEmpty() || !img.load(name))
- return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
- }
+ if (name.isEmpty() || !img.load(name))
+ return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
+
pm = QPixmap::fromImage(img);
doc->addResource(QTextDocument::ImageResource, url, pm);
}
@@ -142,16 +159,15 @@ static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format)
return size;
}
-static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
+static QImage getImage(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
{
QImage image;
QString name = format.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
- QPaintDevice *pdev = doc->documentLayout()->paintDevice();
- name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio());
QUrl url = QUrl(name);
+ name = resolveFileName(name, &url, devicePixelRatio);
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Image) {
image = qvariant_cast<QImage>(data);
@@ -160,19 +176,18 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
}
if (image.isNull()) {
- QString context;
-
#if 0
+ QString context;
// ### Qt5
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
if (browser)
context = browser->source().toString();
#endif
- if (image.isNull()) { // try direct loading
- name = format.name(); // remove qrc:/ prefix again
- if (name.isEmpty() || !image.load(name))
- return QImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
- }
+ // try direct loading
+
+ if (name.isEmpty() || !image.load(name))
+ return QImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
+
doc->addResource(QTextDocument::ImageResource, url, image);
}
@@ -241,10 +256,10 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen
const QTextImageFormat imageFormat = format.toImageFormat();
if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
- const QImage image = getImage(doc, imageFormat);
+ const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio());
p->drawImage(rect, image, image.rect());
} else {
- const QPixmap pixmap = getPixmap(doc, imageFormat);
+ const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatio());
p->drawPixmap(rect, pixmap, pixmap.rect());
}
}
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index adc5663299..1ac50d3e5c 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -2256,8 +2256,10 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
logClusters,
iterator.itemStart,
iterator.itemLength));
- for (int i = 0; i < subLayout.numGlyphs; ++i)
- pos.rx() += subLayout.advances[i].toReal();
+ for (int i = 0; i < subLayout.numGlyphs; ++i) {
+ QFixed justification = QFixed::fromFixed(subLayout.justifications[i].space_18d6);
+ pos.rx() += (subLayout.advances[i] + justification).toReal();
+ }
if (rtl)
end = start;
@@ -2559,6 +2561,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
}
else
itm = eng->findItem(pos);
+ if (itm < 0) {
+ *cursorPos = 0;
+ return x.toReal();
+ }
eng->shapeLine(line);
const QScriptItem *si = &eng->layoutData->items[itm];
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index 1b5a10f733..f879847935 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -316,7 +316,12 @@ void QValidator::fixup(QString &) const
QIntValidator uses its locale() to interpret the number. For example,
in Arabic locales, QIntValidator will accept Arabic digits.
- \sa QDoubleValidator, QRegExpValidator, {Line Edits Example}
+ \note The QLocale::NumberOptions set on the locale() also affect the
+ way the number is interpreted. For example, since QLocale::RejectGroupSeparator
+ is not set by default, the validator will accept group separators. It is thus
+ recommended to use QLocale::toInt() to obtain the numeric value.
+
+ \sa QDoubleValidator, QRegExpValidator, QLocale::toInt(), {Line Edits Example}
*/
/*!
@@ -393,7 +398,8 @@ static qlonglong pow10(int exp)
QValidator::State QIntValidator::validate(QString & input, int&) const
{
QByteArray buff;
- if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff,
+ -1, locale().numberOptions() & QLocale::RejectGroupSeparator)) {
return Invalid;
}
@@ -432,7 +438,8 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
void QIntValidator::fixup(QString &input) const
{
QByteArray buff;
- if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff,
+ -1, locale().numberOptions() & QLocale::RejectGroupSeparator)) {
return;
}
bool ok, overflow;
@@ -548,7 +555,12 @@ public:
in the German locale, "1,234" will be accepted as the fractional number
1.234. In Arabic locales, QDoubleValidator will accept Arabic digits.
- \sa QIntValidator, QRegExpValidator, {Line Edits Example}
+ \note The QLocale::NumberOptions set on the locale() also affect the
+ way the number is interpreted. For example, since QLocale::RejectGroupSeparator
+ is not set by default, the validator will accept group separators. It is thus
+ recommended to use QLocale::toDouble() to obtain the numeric value.
+
+ \sa QIntValidator, QRegExpValidator, QLocale::toDouble(), {Line Edits Example}
*/
/*!
@@ -648,8 +660,10 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
{
Q_Q(const QDoubleValidator);
QByteArray buff;
- if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec))
+ if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec,
+ locale.numberOptions() & QLocale::RejectGroupSeparator)) {
return QValidator::Invalid;
+ }
if (buff.isEmpty())
return QValidator::Intermediate;
@@ -1003,7 +1017,7 @@ QValidator::State QRegularExpressionValidator::validate(QString &input, int &pos
const QRegularExpressionMatch m = d->usedRe.match(input, 0, QRegularExpression::PartialPreferCompleteMatch);
if (m.hasMatch()) {
return Acceptable;
- } else if (m.hasPartialMatch()) {
+ } else if (input.isEmpty() || m.hasPartialMatch()) {
return Intermediate;
} else {
pos = input.size();
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index f50a79b061..66f093e490 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -151,7 +151,7 @@ QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request
}
if (request.d->operation == QHttpNetworkRequest::Post) {
// add content type, if not set in the request
- if (request.headerField("content-type").isEmpty()) {
+ if (request.headerField("content-type").isEmpty() && ((request.d->uploadByteDevice && request.d->uploadByteDevice->size() > 0) || request.d->url.hasQuery())) {
//Content-Type is mandatory. We can't say anything about the encoding, but x-www-form-urlencoded is the most likely to work.
//This warning indicates a bug in application code not setting a required header.
//Note that if using QHttpMultipart, the content-type is set in QNetworkAccessManagerPrivate::prepareMultipart already
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index b13c21d624..522f8d9891 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -654,6 +654,7 @@ void QHttpThreadDelegate::encryptedSlot()
if (!httpReply)
return;
+ emit sslConfigurationChanged(httpReply->sslConfiguration());
emit encrypted();
}
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index f00b58a8ce..52d56fb071 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -1135,7 +1135,12 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) {
QNetworkConfigurationManager manager;
if (!d->networkConfiguration.identifier().isEmpty()) {
- d->createSession(d->networkConfiguration);
+ if ((d->networkConfiguration.state() & QNetworkConfiguration::Defined)
+ && d->networkConfiguration != manager.defaultConfiguration())
+ d->createSession(manager.defaultConfiguration());
+ else
+ d->createSession(d->networkConfiguration);
+
} else {
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
d->createSession(manager.defaultConfiguration());
@@ -1590,6 +1595,11 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
if (customNetworkConfiguration) {
online = (networkConfiguration.state() & QNetworkConfiguration::Active);
} else {
+ if (isOnline && online != isOnline) {
+ networkSessionStrongRef.clear();
+ networkSessionWeakRef.clear();
+ }
+
online = isOnline;
}
}
diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp
index 149d89c000..a615dcc7b6 100644
--- a/src/network/socket/qlocalserver_unix.cpp
+++ b/src/network/socket/qlocalserver_unix.cpp
@@ -90,13 +90,14 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
// Check any of the flags
if (socketOptions & QLocalServer::WorldAccessOption) {
- tempDir.reset(new QTemporaryDir(fullServerName));
+ QFileInfo serverNameFileInfo(fullServerName);
+ tempDir.reset(new QTemporaryDir(serverNameFileInfo.absolutePath() + QLatin1Char('/')));
if (!tempDir->isValid()) {
setError(QLatin1String("QLocalServer::listen"));
return false;
}
tempPath = tempDir->path();
- tempPath += QLatin1Char('/') + requestedServerName;
+ tempPath += QLatin1String("/s");
}
// create the unix socket
@@ -124,13 +125,6 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
}
::memcpy(addr.sun_path, tempPath.toLatin1().data(),
tempPath.toLatin1().size() + 1);
-
- if (-1 == ::fchmod(listenSocket, 0)) {
- setError(QLatin1String("QLocalServer::listen"));
- closeServer();
- return false;
- }
-
} else {
::memcpy(addr.sun_path, fullServerName.toLatin1().data(),
fullServerName.toLatin1().size() + 1);
@@ -160,30 +154,28 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
}
if (socketOptions & QLocalServer::WorldAccessOption) {
- mode_t mode = 000;
+ mode_t mode = 000;
- if (socketOptions & QLocalServer::UserAccessOption) {
- mode |= S_IRWXU;
- }
- if (socketOptions & QLocalServer::GroupAccessOption) {
- mode |= S_IRWXG;
- }
- if (socketOptions & QLocalServer::OtherAccessOption) {
- mode |= S_IRWXO;
- }
+ if (socketOptions & QLocalServer::UserAccessOption)
+ mode |= S_IRWXU;
- if (mode) {
- if (-1 == ::chmod(tempPath.toLatin1(), mode)) {
- setError(QLatin1String("QLocalServer::listen"));
- closeServer();
- return false;
- }
- }
- if (-1 == ::rename(tempPath.toLatin1(), fullServerName.toLatin1())){
- setError(QLatin1String("QLocalServer::listen"));
- closeServer();
- return false;
- }
+ if (socketOptions & QLocalServer::GroupAccessOption)
+ mode |= S_IRWXG;
+
+ if (socketOptions & QLocalServer::OtherAccessOption)
+ mode |= S_IRWXO;
+
+ if (::chmod(tempPath.toLatin1(), mode) == -1) {
+ setError(QLatin1String("QLocalServer::listen"));
+ closeServer();
+ return false;
+ }
+
+ if (::rename(tempPath.toLatin1(), fullServerName.toLatin1()) == -1) {
+ setError(QLatin1String("QLocalServer::listen"));
+ closeServer();
+ return false;
+ }
}
Q_ASSERT(!socketNotifier);
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index c3be3eb408..cacfe11fea 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -529,41 +529,27 @@ qint64 QNativeSocketEngine::write(const char *data, qint64 len)
qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr, quint16 *port)
{
Q_D(QNativeSocketEngine);
- if (d->socketType != QAbstractSocket::UdpSocket)
+ if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty())
return -1;
- QHostAddress returnAddress;
- quint16 returnPort;
-
- for (int i = 0; i < d->pendingDatagrams.size(); ++i) {
- IDatagramSocketMessageReceivedEventArgs *arg = d->pendingDatagrams.at(i);
- ComPtr<IHostName> remoteHost;
- HString remoteHostString;
- HString remotePort;
- arg->get_RemoteAddress(&remoteHost);
- arg->get_RemotePort(remotePort.GetAddressOf());
- remoteHost->get_CanonicalName(remoteHostString.GetAddressOf());
- returnAddress.setAddress(qt_QStringFromHString(remoteHostString));
- returnPort = qt_QStringFromHString(remotePort).toInt();
- ComPtr<IDataReader> reader;
- arg->GetDataReader(&reader);
- if (!reader)
- continue;
-
- BYTE buffer[1024];
- reader->ReadBytes(maxlen, buffer);
- *addr = returnAddress;
- *port = returnPort;
- arg = d->pendingDatagrams.takeFirst();
- arg->Release();
-
- // TODO: fill data
- Q_UNUSED(data);
- --i;
- return maxlen;
+ WinRtDatagram datagram = d->pendingDatagrams.takeFirst();
+ if (addr)
+ *addr = datagram.address;
+
+ if (port)
+ *port = datagram.port;
+
+ QByteArray readOrigin;
+ // Do not read the whole datagram. Put the rest of it back into the "queue"
+ if (maxlen < datagram.data.length()) {
+ QByteArray readOrigin = datagram.data.left(maxlen);
+ datagram.data = datagram.data.remove(0, maxlen);
+ d->pendingDatagrams.prepend(datagram);
+ } else {
+ readOrigin = datagram.data;
}
-
- return -1;
+ strcpy(data, readOrigin);
+ return readOrigin.length();
}
qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QHostAddress &addr, quint16 port)
@@ -609,17 +595,10 @@ bool QNativeSocketEngine::hasPendingDatagrams() const
qint64 QNativeSocketEngine::pendingDatagramSize() const
{
Q_D(const QNativeSocketEngine);
- qint64 ret = 0;
- foreach (IDatagramSocketMessageReceivedEventArgs *arg, d->pendingDatagrams) {
- ComPtr<IDataReader> reader;
- UINT32 unconsumedBufferLength;
- arg->GetDataReader(&reader);
- if (!reader)
- return -1;
- reader->get_UnconsumedBufferLength(&unconsumedBufferLength);
- ret += unconsumedBufferLength;
- }
- return ret;
+ if (d->pendingDatagrams.isEmpty())
+ return -1;
+
+ return d->pendingDatagrams.at(0).data.length();
}
qint64 QNativeSocketEngine::bytesToWrite() const
@@ -1236,7 +1215,32 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I
{
Q_Q(QNativeSocketEngine);
Q_UNUSED(socket);
- pendingDatagrams.append(args);
+
+ WinRtDatagram datagram;
+ QHostAddress returnAddress;
+ ComPtr<IHostName> remoteHost;
+ HRESULT hr = args->get_RemoteAddress(&remoteHost);
+ RETURN_OK_IF_FAILED("Could not obtain remote host");
+ HString remoteHostString;
+ remoteHost->get_CanonicalName(remoteHostString.GetAddressOf());
+ RETURN_OK_IF_FAILED("Could not obtain remote host's canonical name");
+ returnAddress.setAddress(qt_QStringFromHString(remoteHostString));
+ datagram.address = returnAddress;
+ HString remotePort;
+ hr = args->get_RemotePort(remotePort.GetAddressOf());
+ RETURN_OK_IF_FAILED("Could not obtain remote port");
+ datagram.port = qt_QStringFromHString(remotePort).toInt();
+
+ ComPtr<IDataReader> reader;
+ hr = args->GetDataReader(&reader);
+ RETURN_OK_IF_FAILED("Could not obtain data reader");
+ quint32 length;
+ hr = reader->get_UnconsumedBufferLength(&length);
+ RETURN_OK_IF_FAILED("Could not obtain unconsumed buffer length");
+ datagram.data.resize(length);
+ hr = reader->ReadBytes(length, reinterpret_cast<BYTE *>(datagram.data.data()));
+ RETURN_OK_IF_FAILED("Could not read datagram");
+ pendingDatagrams.append(datagram);
emit q->readReady();
return S_OK;
diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h
index 7652a09b17..716403097d 100644
--- a/src/network/socket/qnativesocketengine_winrt_p.h
+++ b/src/network/socket/qnativesocketengine_winrt_p.h
@@ -55,6 +55,12 @@ QT_BEGIN_NAMESPACE
class QNativeSocketEnginePrivate;
+struct WinRtDatagram {
+ QByteArray data;
+ int port;
+ QHostAddress address;
+};
+
class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine
{
Q_OBJECT
@@ -197,7 +203,8 @@ private:
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> connectOp;
QBuffer readBytes;
QMutex readMutex;
- QList<ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *> pendingDatagrams;
+
+ QList<WinRtDatagram> pendingDatagrams;
QList<ABI::Windows::Networking::Sockets::IStreamSocket *> pendingConnections;
QList<ABI::Windows::Networking::Sockets::IStreamSocket *> currentConnections;
QEventLoop eventLoop;
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 6b0fa954eb..e4d30ff229 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -95,7 +95,7 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
type = QSsl::PrivateKey;
dsa = q_DSA_new();
- memcpy(rsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA));
+ memcpy(dsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA));
return true;
}
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index d919d8e934..71b8237e03 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -63,6 +63,9 @@
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
#include <link.h>
#endif
+#ifdef Q_OS_DARWIN
+#include "private/qcore_mac_p.h"
+#endif
#include <algorithm>
@@ -107,6 +110,8 @@ QT_BEGIN_NAMESPACE
possibly with a different version of OpenSSL.
*/
+#ifndef QT_LINKED_OPENSSL
+
namespace {
void qsslSocketUnresolvedSymbolWarning(const char *functionName)
{
@@ -119,6 +124,8 @@ void qsslSocketCannotResolveSymbolWarning(const char *functionName)
}
}
+#endif // QT_LINKED_OPENSSL
+
#ifdef SSLEAY_MACROS
DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
#endif
@@ -448,6 +455,15 @@ static QStringList libraryPathList()
# ifdef Q_OS_DARWIN
paths = QString::fromLatin1(qgetenv("DYLD_LIBRARY_PATH"))
.split(QLatin1Char(':'), QString::SkipEmptyParts);
+
+ // search in .app/Contents/Frameworks
+ UInt32 packageType;
+ CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, NULL);
+ if (packageType == FOUR_CHAR_CODE('APPL')) {
+ QUrl bundleUrl = QUrl::fromCFURL(QCFType<CFURLRef>(CFBundleCopyBundleURL(CFBundleGetMainBundle())));
+ QUrl frameworksUrl = QUrl::fromCFURL(QCFType<CFURLRef>(CFBundleCopyPrivateFrameworksURL(CFBundleGetMainBundle())));
+ paths << bundleUrl.resolved(frameworksUrl).path();
+ }
# else
paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
.split(QLatin1Char(':'), QString::SkipEmptyParts);
@@ -597,7 +613,13 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
}
#endif
+#ifndef Q_OS_DARWIN
// second attempt: find the development files libssl.so and libcrypto.so
+ //
+ // disabled on OS X/iOS:
+ // OS X's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
+ // attempt, _after_ <bundle>/Contents/Frameworks has been searched.
+ // iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place.
libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
if (libcrypto->load() && libssl->load()) {
@@ -607,6 +629,7 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
libssl->unload();
libcrypto->unload();
}
+#endif
// third attempt: loop on the most common library paths and find libssl
QStringList sslList = findAllLibSsl();
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 43df311636..1fa5723d85 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -612,6 +612,21 @@ void QGL2PaintEngineExPrivate::resetGLState()
#endif
}
+bool QGL2PaintEngineExPrivate::resetOpenGLContextActiveEngine()
+{
+ QOpenGLContext *guiGlContext = ctx->contextHandle();
+ QOpenGLContextPrivate *guiGlContextPrivate =
+ guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0;
+
+ if (guiGlContextPrivate && guiGlContextPrivate->active_engine) {
+ ctx->d_func()->refreshCurrentFbo();
+ guiGlContextPrivate->active_engine = 0;
+ return true;
+ }
+
+ return false;
+}
+
void QGL2PaintEngineEx::endNativePainting()
{
Q_D(QGL2PaintEngineEx);
@@ -2015,6 +2030,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->ctx = d->device->context();
d->ctx->d_ptr->active_engine = this;
+ d->resetOpenGLContextActiveEngine();
+
const QSize sz = d->device->size();
d->width = sz.width();
d->height = sz.height();
@@ -2080,6 +2097,8 @@ bool QGL2PaintEngineEx::end()
ctx->d_ptr->active_engine = 0;
+ d->resetOpenGLContextActiveEngine();
+
d->resetGLState();
delete d->shaderManager;
@@ -2105,7 +2124,7 @@ void QGL2PaintEngineEx::ensureActive()
Q_D(QGL2PaintEngineEx);
QGLContext *ctx = d->ctx;
- if (isActive() && ctx->d_ptr->active_engine != this) {
+ if (isActive() && (ctx->d_ptr->active_engine != this || d->resetOpenGLContextActiveEngine())) {
ctx->d_ptr->active_engine = this;
d->needsSync = true;
}
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 528bfdeeb9..ac1d63df17 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -191,6 +191,7 @@ public:
void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
void resetGLState();
+ bool resetOpenGLContextActiveEngine();
// fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points,
// however writeClip can also be thought of as en entry point as it does similar things.
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 211fad267f..8cd26f1ea4 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -167,6 +167,8 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
// ### the QTextureGlyphCache API needs to be reworked to allow
// ### resizeTextureData to fail
+ ctx->d_ptr->refreshCurrentFbo();
+
funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo);
GLuint tmp_texture;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 1e49d95087..35f08e0092 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -510,6 +510,35 @@ void QGLContextPrivate::setupSharing() {
}
}
+void QGLContextPrivate::refreshCurrentFbo()
+{
+ QOpenGLContextPrivate *guiGlContextPrivate =
+ guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0;
+
+ // if QOpenGLFramebufferObjects have been used in the mean-time, we've lost our cached value
+ if (guiGlContextPrivate && guiGlContextPrivate->qgl_current_fbo_invalid) {
+ GLint current;
+ QOpenGLFunctions *funcs = qgl_functions();
+ funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &current);
+
+ current_fbo = current;
+
+ guiGlContextPrivate->qgl_current_fbo_invalid = false;
+ }
+}
+
+void QGLContextPrivate::setCurrentFbo(GLuint fbo)
+{
+ current_fbo = fbo;
+
+ QOpenGLContextPrivate *guiGlContextPrivate =
+ guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0;
+
+ if (guiGlContextPrivate)
+ guiGlContextPrivate->qgl_current_fbo_invalid = false;
+}
+
+
/*!
\fn bool QGLFormat::doubleBuffer() const
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index c4151a3d34..4cf656fd86 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -238,6 +238,8 @@ public:
bool ownContext;
void setupSharing();
+ void refreshCurrentFbo();
+ void setCurrentFbo(GLuint fbo);
QGLFormat glFormat;
QGLFormat reqFormat;
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 4ef50e9334..4537f5bfae 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -472,6 +472,8 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
return;
+ ctx->d_ptr->refreshCurrentFbo();
+
size = sz;
target = texture_target;
// texture dimensions
@@ -1027,7 +1029,7 @@ bool QGLFramebufferObject::bind()
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
d->valid = d->checkFramebufferStatus();
if (d->valid && current)
- current->d_ptr->current_fbo = d->fbo();
+ current->d_ptr->setCurrentFbo(d->fbo());
return d->valid;
}
@@ -1060,7 +1062,7 @@ bool QGLFramebufferObject::release()
#endif
if (current) {
- current->d_ptr->current_fbo = current->d_ptr->default_fbo;
+ current->d_ptr->setCurrentFbo(current->d_ptr->default_fbo);
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo);
}
@@ -1109,6 +1111,20 @@ QGLFramebufferObjectFormat QGLFramebufferObject::format() const
Returns the contents of this framebuffer object as a QImage.
+ The returned image has a format of premultiplied ARGB32 or RGB32. The latter is used
+ only when internalTextureFormat() is set to \c GL_RGB.
+
+ If the rendering in the framebuffer was not done with premultiplied alpha in mind,
+ create a wrapper QImage with a non-premultiplied format. This is necessary before
+ performing operations like QImage::save() because otherwise the image data would get
+ unpremultiplied, even though it was not premultiplied in the first place. To create
+ such a wrapper without performing a copy of the pixel data, do the following:
+
+ \code
+ QImage fboImage(fbo.toImage());
+ QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32);
+ \endcode
+
On QNX the back buffer is not preserved when a buffer swap occures. So this function
might return old content.
*/
@@ -1173,7 +1189,7 @@ bool QGLFramebufferObject::bindDefault()
if (!functions.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
return false;
- ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo;
+ ctx->d_ptr->setCurrentFbo(ctx->d_ptr->default_fbo);
functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo);
#ifdef QT_DEBUG
} else {
@@ -1320,7 +1336,12 @@ bool QGLFramebufferObject::isBound() const
{
Q_D(const QGLFramebufferObject);
const QGLContext *current = QGLContext::currentContext();
- return current ? current->d_ptr->current_fbo == d->fbo() : false;
+ if (current) {
+ current->d_ptr->refreshCurrentFbo();
+ return current->d_ptr->current_fbo == d->fbo();
+ }
+
+ return false;
}
/*!
@@ -1400,6 +1421,8 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q
const int ty0 = th - (targetRect.top() + targetRect.height());
const int ty1 = th - targetRect.top();
+ ctx->d_ptr->refreshCurrentFbo();
+
functions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0);
functions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0);
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index 40cc7bb71d..c07d0a761b 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -74,6 +74,8 @@ void QGLPaintDevice::beginPaint()
QGLContext *ctx = context();
ctx->makeCurrent();
+ ctx->d_func()->refreshCurrentFbo();
+
// Record the currently bound FBO so we can restore it again
// in endPaint() and bind this device's FBO
//
@@ -85,7 +87,7 @@ void QGLPaintDevice::beginPaint()
m_previousFBO = ctx->d_func()->current_fbo;
if (m_previousFBO != m_thisFBO) {
- ctx->d_ptr->current_fbo = m_thisFBO;
+ ctx->d_func()->setCurrentFbo(m_thisFBO);
ctx->contextHandle()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_thisFBO);
}
@@ -102,8 +104,10 @@ void QGLPaintDevice::ensureActiveTarget()
if (ctx != QGLContext::currentContext())
ctx->makeCurrent();
+ ctx->d_func()->refreshCurrentFbo();
+
if (ctx->d_ptr->current_fbo != m_thisFBO) {
- ctx->d_ptr->current_fbo = m_thisFBO;
+ ctx->d_func()->setCurrentFbo(m_thisFBO);
ctx->contextHandle()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_thisFBO);
}
@@ -114,8 +118,11 @@ void QGLPaintDevice::endPaint()
{
// Make sure the FBO bound at beginPaint is re-bound again here:
QGLContext *ctx = context();
+
+ ctx->d_func()->refreshCurrentFbo();
+
if (m_previousFBO != ctx->d_func()->current_fbo) {
- ctx->d_ptr->current_fbo = m_previousFBO;
+ ctx->d_func()->setCurrentFbo(m_previousFBO);
ctx->contextHandle()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_previousFBO);
}
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 56bfaebe4f..63b624aea2 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -344,6 +344,8 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
QOpenGLExtensions extensions(ctx->contextHandle());
+ ctx->d_ptr->refreshCurrentFbo();
+
if (d->blit_fbo) {
QOpenGLFramebufferObject::blitFramebuffer(d->blit_fbo, d->fbo);
extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle());
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm
index 27a490335b..6fcd19e07b 100644
--- a/src/platformsupport/clipboard/qmacmime.mm
+++ b/src/platformsupport/clipboard/qmacmime.mm
@@ -48,6 +48,7 @@
#include "qmacmime_p.h"
#include "qguiapplication.h"
+#include "private/qcore_mac_p.h"
QT_BEGIN_NAMESPACE
@@ -335,9 +336,9 @@ QVariant QMacPasteboardMimePlainTextFallback::convertToMime(const QString &mimet
// Note that public.text is documented by Apple to have an undefined encoding. From
// testing it seems that utf8 is normally used, at least by Safari on iOS.
const QByteArray &firstData = data.first();
- return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
+ return QString(QCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *>(firstData.constData()),
- firstData.size(), kCFStringEncodingUTF8, false));
+ firstData.size(), kCFStringEncodingUTF8, false)));
} else {
qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
}
@@ -410,9 +411,9 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q
// I can only handle two types (system and unicode) so deal with them that way
QVariant ret;
if (flavor == QLatin1String("public.utf8-plain-text")) {
- ret = QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
+ ret = QString(QCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *>(firstData.constData()),
- firstData.size(), CFStringGetSystemEncoding(), false));
+ firstData.size(), CFStringGetSystemEncoding(), false)));
} else if (flavor == QLatin1String("public.utf16-plain-text")) {
ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
firstData.size() / sizeof(QChar));
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
index 80153cd18f..f3a135a499 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience.cpp
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -37,8 +37,8 @@
#ifdef Q_OS_LINUX
#include <sys/ioctl.h>
#include <linux/fb.h>
-#include <private/qmath_p.h>
#endif
+#include <private/qmath_p.h>
#include "qeglconvenience_p.h"
@@ -448,10 +448,13 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config)
}
}
-#ifdef Q_OS_LINUX
+#ifdef Q_OS_UNIX
QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize)
{
+#ifndef Q_OS_LINUX
+ Q_UNUSED(framebufferDevice)
+#endif
const int defaultPhysicalDpi = 100;
static QSizeF size;
@@ -466,10 +469,11 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize
return size;
}
- struct fb_var_screeninfo vinfo;
int w = -1;
int h = -1;
QSize screenResolution;
+#ifdef Q_OS_LINUX
+ struct fb_var_screeninfo vinfo;
if (framebufferDevice != -1) {
if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
@@ -479,7 +483,9 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize
h = vinfo.height;
screenResolution = QSize(vinfo.xres, vinfo.yres);
}
- } else {
+ } else
+#endif
+ {
// Use the provided screen size, when available, since some platforms may have their own
// specific way to query it. Otherwise try querying it from the framebuffer.
screenResolution = screenSize.isEmpty() ? q_screenSizeFromFb(framebufferDevice) : screenSize;
@@ -499,6 +505,9 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize
QSize q_screenSizeFromFb(int framebufferDevice)
{
+#ifndef Q_OS_LINUX
+ Q_UNUSED(framebufferDevice)
+#endif
const int defaultWidth = 800;
const int defaultHeight = 600;
static QSize size;
@@ -513,6 +522,7 @@ QSize q_screenSizeFromFb(int framebufferDevice)
return size;
}
+#ifdef Q_OS_LINUX
struct fb_var_screeninfo vinfo;
int xres = -1;
int yres = -1;
@@ -528,6 +538,10 @@ QSize q_screenSizeFromFb(int framebufferDevice)
size.setWidth(xres <= 0 ? defaultWidth : xres);
size.setHeight(yres <= 0 ? defaultHeight : yres);
+#else
+ size.setWidth(defaultWidth);
+ size.setHeight(defaultHeight);
+#endif
}
return size;
@@ -535,10 +549,14 @@ QSize q_screenSizeFromFb(int framebufferDevice)
int q_screenDepthFromFb(int framebufferDevice)
{
+#ifndef Q_OS_LINUX
+ Q_UNUSED(framebufferDevice)
+#endif
const int defaultDepth = 32;
static int depth = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEPTH");
if (depth == 0) {
+#ifdef Q_OS_LINUX
struct fb_var_screeninfo vinfo;
if (framebufferDevice != -1) {
@@ -550,11 +568,14 @@ int q_screenDepthFromFb(int framebufferDevice)
if (depth <= 0)
depth = defaultDepth;
+#else
+ depth = defaultDepth;
+#endif
}
return depth;
}
-#endif // Q_OS_LINUX
+#endif // Q_OS_UNIX
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/basic/basic.pri b/src/platformsupport/fontdatabases/basic/basic.pri
index 88be809cd8..c2b882ed5a 100644
--- a/src/platformsupport/fontdatabases/basic/basic.pri
+++ b/src/platformsupport/fontdatabases/basic/basic.pri
@@ -17,6 +17,7 @@ contains(QT_CONFIG, freetype) {
$$QT_FREETYPE_DIR/src/base/ftbbox.c \
$$QT_FREETYPE_DIR/src/base/ftdebug.c \
$$QT_FREETYPE_DIR/src/base/ftglyph.c \
+ $$QT_FREETYPE_DIR/src/base/ftlcdfil.c \
$$QT_FREETYPE_DIR/src/base/ftinit.c \
$$QT_FREETYPE_DIR/src/base/ftmm.c \
$$QT_FREETYPE_DIR/src/base/fttype1.c \
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 2b9883eb36..5dec1d0915 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -409,7 +409,7 @@ static void populateFromPattern(FcPattern *pattern)
#endif
FontFile *fontFile = new FontFile;
- fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->fileName = QString::fromLocal8Bit((const char *)file_value);
fontFile->indexValue = indexValue;
QFont::Style style = (slant_value == FC_SLANT_ITALIC)
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 207b525664..44f6be21c7 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -353,7 +353,10 @@ QFixed QCoreTextFontEngine::averageCharWidth() const
qreal QCoreTextFontEngine::maxCharWidth() const
{
- return 0;
+ // ### FIXME: 'W' might not be the widest character, but this is better than nothing
+ const glyph_t glyph = glyphIndex('W');
+ glyph_metrics_t bb = const_cast<QCoreTextFontEngine *>(this)->boundingBox(glyph);
+ return bb.xoff.toReal();
}
qreal QCoreTextFontEngine::minLeftBearing() const
diff --git a/src/plugins/bearer/connman/connman.pro b/src/plugins/bearer/connman/connman.pro
index bc4efe8b62..efa13a6ebd 100644
--- a/src/plugins/bearer/connman/connman.pro
+++ b/src/plugins/bearer/connman/connman.pro
@@ -8,14 +8,14 @@ QT = core network-private dbus
CONFIG += link_pkgconfig
HEADERS += qconnmanservice_linux_p.h \
- qofonoservice_linux_p.h \
+ ../linux_common/qofonoservice_linux_p.h \
qconnmanengine.h \
../qnetworksession_impl.h \
../qbearerengine_impl.h
SOURCES += main.cpp \
qconnmanservice_linux.cpp \
- qofonoservice_linux.cpp \
+ ../linux_common/qofonoservice_linux.cpp \
qconnmanengine.cpp \
../qnetworksession_impl.cpp
diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h
index 52e8b384a0..a995d8ed25 100644
--- a/src/plugins/bearer/connman/qconnmanengine.h
+++ b/src/plugins/bearer/connman/qconnmanengine.h
@@ -48,7 +48,7 @@
#include "../qbearerengine_impl.h"
#include "qconnmanservice_linux_p.h"
-#include "qofonoservice_linux_p.h"
+#include "../linux_common/qofonoservice_linux_p.h"
#include <QMap>
#include <QVariant>
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index 6f9ea91799..55847a04a4 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -288,8 +288,6 @@ void QScanThread::getUserConfigurations()
for (NSString *ifName in wifiInterfaces) {
CWInterface *wifiInterface = [CWInterface interfaceWithName: ifName];
- if (!wifiInterface.powerOn)
- continue;
NSString *nsInterfaceName = wifiInterface.ssid;
// add user configured system networks
@@ -311,6 +309,21 @@ void QScanThread::getUserConfigurations()
CFRelease(airportPlist);
}
+ // remembered networks
+ CWConfiguration *userConfig = [wifiInterface configuration];
+ NSOrderedSet *networkProfiles = [userConfig networkProfiles];
+ NSEnumerator *enumerator = [networkProfiles objectEnumerator];
+ CWNetworkProfile *wProfile;
+ while ((wProfile = [enumerator nextObject])) {
+ QString networkName = QCFString::toQString([wProfile ssid]);
+
+ if (!userProfiles.contains(networkName)) {
+ QMap<QString,QString> map;
+ map.insert(networkName, QCFString::toQString(nsInterfaceName));
+ userProfiles.insert(networkName, map);
+ }
+ }
+
// 802.1X user profiles
QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile: QCFString::toNSString(userProfilePath)] autorelease];
@@ -330,14 +343,14 @@ void QScanThread::getUserConfigurations()
[itemKey getObjects:objects andKeys:keys];
QString networkName;
QString ssid;
- for(int i = 0; i < dictSize; i++) {
+ for (int i = 0; i < dictSize; i++) {
if([nameStr isEqualToString:keys[i]]) {
networkName = QCFString::toQString(objects[i]);
}
- if([networkSsidStr isEqualToString:keys[i]]) {
+ if ([networkSsidStr isEqualToString:keys[i]]) {
ssid = QCFString::toQString(objects[i]);
}
- if(!userProfiles.contains(networkName)
+ if (!userProfiles.contains(networkName)
&& !ssid.isEmpty()) {
QMap<QString,QString> map;
map.insert(ssid, QCFString::toQString(nsInterfaceName));
diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp
index acc82bda04..f4460c1be0 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux.cpp
+++ b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp
@@ -95,14 +95,12 @@ QStringList QOfonoManagerInterface::getModems()
{
if (modemList.isEmpty()) {
QList<QVariant> argumentList;
- QDBusPendingReply<PathPropertiesList> reply = asyncCallWithArgumentList(QLatin1String("GetModems"), argumentList);
+ QDBusPendingReply<PathPropertiesList> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetModems"), argumentList);
reply.waitForFinished();
if (!reply.isError()) {
foreach (ObjectPathProperties modem, reply.value()) {
modemList << modem.path.path();
}
- } else {
- qDebug() << reply.error().message();
}
}
@@ -114,7 +112,8 @@ QString QOfonoManagerInterface::currentModem()
QStringList modems = getModems();
foreach (const QString &modem, modems) {
QOfonoModemInterface device(modem);
- if (device.isPowered() && device.isOnline())
+ if (device.isPowered() && device.isOnline()
+ && device.interfaces().contains(QStringLiteral("org.ofono.NetworkRegistration")))
return modem;
}
return QString();
@@ -171,11 +170,17 @@ bool QOfonoModemInterface::isOnline()
return qdbus_cast<bool>(var);
}
+QStringList QOfonoModemInterface::interfaces()
+{
+ const QVariant var = getProperty(QStringLiteral("Interfaces"));
+ return var.toStringList();
+}
+
QVariantMap QOfonoModemInterface::getProperties()
{
if (propertiesMap.isEmpty()) {
QList<QVariant> argumentList;
- QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList);
if (!reply.isError()) {
propertiesMap = reply.value();
}
@@ -187,7 +192,8 @@ QVariant QOfonoModemInterface::getProperty(const QString &property)
{
QVariant var;
QVariantMap map = getProperties();
- var = map.value(property);
+ if (map.contains(property))
+ var = map.value(property);
return var;
}
@@ -214,7 +220,8 @@ QVariant QOfonoNetworkRegistrationInterface::getProperty(const QString &property
{
QVariant var;
QVariantMap map = getProperties();
- var = map.value(property);
+ if (map.contains(property))
+ var = map.value(property);
return var;
}
@@ -222,12 +229,10 @@ QVariantMap QOfonoNetworkRegistrationInterface::getProperties()
{
if (propertiesMap.isEmpty()) {
QList<QVariant> argumentList;
- QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList);
reply.waitForFinished();
if (!reply.isError()) {
propertiesMap = reply.value();
- } else {
- qDebug() << reply.error().message();
}
}
return propertiesMap;
@@ -264,12 +269,30 @@ QStringList QOfonoDataConnectionManagerInterface::contexts()
return contextList;
}
+PathPropertiesList QOfonoDataConnectionManagerInterface::contextsWithProperties()
+{
+ if (contextListProperties.isEmpty()) {
+ QDBusPendingReply<PathPropertiesList > reply = call(QLatin1String("GetContexts"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ contextListProperties = reply.value();
+ }
+ }
+ return contextListProperties;
+}
+
bool QOfonoDataConnectionManagerInterface::roamingAllowed()
{
QVariant var = getProperty(QStringLiteral("RoamingAllowed"));
return qdbus_cast<bool>(var);
}
+QString QOfonoDataConnectionManagerInterface::bearer()
+{
+ QVariant var = getProperty(QStringLiteral("Bearer"));
+ return qdbus_cast<QString>(var);
+}
+
QVariant QOfonoDataConnectionManagerInterface::getProperty(const QString &property)
{
return getProperties().value(property);
@@ -279,7 +302,7 @@ QVariantMap &QOfonoDataConnectionManagerInterface::getProperties()
{
if (propertiesMap.isEmpty()) {
QList<QVariant> argumentList;
- QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList);
if (!reply.isError()) {
propertiesMap = reply.value();
}
@@ -294,6 +317,68 @@ void QOfonoDataConnectionManagerInterface::propertyChanged(const QString &name,
Q_EMIT roamingAllowedChanged(value.variant().toBool());
}
+
+QOfonoConnectionContextInterface::QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent)
+ : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ dbusPathName,
+ OFONO_CONNECTION_CONTEXT_INTERFACE,
+ QDBusConnection::systemBus(), parent)
+{
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ path(),
+ QLatin1String(OFONO_MODEM_INTERFACE),
+ QLatin1String("PropertyChanged"),
+ this,SLOT(propertyChanged(QString,QDBusVariant)));
+}
+
+QOfonoConnectionContextInterface::~QOfonoConnectionContextInterface()
+{
+}
+
+QVariantMap QOfonoConnectionContextInterface::getProperties()
+{
+ if (propertiesMap.isEmpty()) {
+ QList<QVariant> argumentList;
+ QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList);
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
+ }
+ }
+ return propertiesMap;
+}
+
+void QOfonoConnectionContextInterface::propertyChanged(const QString &name, const QDBusVariant &value)
+{
+ propertiesMap[name] = value.variant();
+}
+
+QVariant QOfonoConnectionContextInterface::getProperty(const QString &property)
+{
+ QVariant var;
+ QVariantMap map = getProperties();
+ if (map.contains(property))
+ var = map.value(property);
+ return var;
+}
+
+bool QOfonoConnectionContextInterface::active()
+{
+ QVariant var = getProperty(QStringLiteral("Active"));
+ return qdbus_cast<bool>(var);
+}
+
+QString QOfonoConnectionContextInterface::accessPointName()
+{
+ QVariant var = getProperty(QStringLiteral("AccessPointName"));
+ return qdbus_cast<QString>(var);
+}
+
+QString QOfonoConnectionContextInterface::name()
+{
+ QVariant var = getProperty(QStringLiteral("Name"));
+ return qdbus_cast<QString>(var);
+}
+
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/connman/qofonoservice_linux_p.h b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h
index 302d7543d4..8adb8db19c 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux_p.h
+++ b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h
@@ -67,6 +67,7 @@
#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
#define OFONO_NETWORK_REGISTRATION_INTERFACE "org.ofono.NetworkRegistration"
#define OFONO_DATA_CONNECTION_MANAGER_INTERFACE "org.ofono.ConnectionManager"
+#define OFONO_CONNECTION_CONTEXT_INTERFACE "org.ofono.ConnectionContext"
QT_BEGIN_NAMESPACE
@@ -114,6 +115,7 @@ public:
bool isPowered();
bool isOnline();
+ QStringList interfaces();
private:
QVariantMap getProperties();
QVariantMap propertiesMap;
@@ -151,18 +153,42 @@ public:
~QOfonoDataConnectionManagerInterface();
QStringList contexts();
+ PathPropertiesList contextsWithProperties();
bool roamingAllowed();
+ QVariant getProperty(const QString &);
+ QString bearer();
Q_SIGNALS:
void roamingAllowedChanged(bool);
private:
QVariantMap &getProperties();
QVariantMap propertiesMap;
- QVariant getProperty(const QString &);
QStringList contextList;
+ PathPropertiesList contextListProperties;
private Q_SLOTS:
void propertyChanged(const QString &, const QDBusVariant &value);
};
+class QOfonoConnectionContextInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+
+public:
+
+ explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = 0);
+ ~QOfonoConnectionContextInterface();
+
+ QVariant getProperty(const QString &);
+ bool active();
+ QString accessPointName();
+ QString name();
+
+Q_SIGNALS:
+private:
+ QVariantMap getProperties();
+ QVariantMap propertiesMap;
+private slots:
+ void propertyChanged(const QString &, const QDBusVariant &value);
+};
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/networkmanager/main.cpp b/src/plugins/bearer/networkmanager/main.cpp
index f416bb42a6..3576ddc37c 100644
--- a/src/plugins/bearer/networkmanager/main.cpp
+++ b/src/plugins/bearer/networkmanager/main.cpp
@@ -66,10 +66,7 @@ QBearerEngine *QNetworkManagerEnginePlugin::create(const QString &key) const
{
if (key == QLatin1String("networkmanager")) {
QNetworkManagerEngine *engine = new QNetworkManagerEngine;
- if (engine->networkManagerAvailable())
- return engine;
- else
- delete engine;
+ return engine;
}
return 0;
diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro
index 1ed9bfaa1b..b3a270615c 100644
--- a/src/plugins/bearer/networkmanager/networkmanager.pro
+++ b/src/plugins/bearer/networkmanager/networkmanager.pro
@@ -6,16 +6,16 @@ load(qt_plugin)
QT = core network-private dbus
-HEADERS += qnmdbushelper.h \
- qnetworkmanagerservice.h \
+HEADERS += qnetworkmanagerservice.h \
qnetworkmanagerengine.h \
+ ../linux_common/qofonoservice_linux_p.h \
../qnetworksession_impl.h \
../qbearerengine_impl.h
SOURCES += main.cpp \
- qnmdbushelper.cpp \
qnetworkmanagerservice.cpp \
qnetworkmanagerengine.cpp \
+ ../linux_common/qofonoservice_linux.cpp \
../qnetworksession_impl.cpp
OTHER_FILES += networkmanager.json
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index 5f49ea0b6d..f0977b4735 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -47,6 +47,7 @@
#include <QDBusInterface>
#include <QDBusMessage>
#include <QDBusReply>
+#include "../linux_common/qofonoservice_linux_p.h"
#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
@@ -55,47 +56,85 @@ QT_BEGIN_NAMESPACE
QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent)
: QBearerEngineImpl(parent),
- managerInterface(new QNetworkManagerInterface(this)),
- systemSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this)),
- userSettings(new QNetworkManagerSettings(NM_DBUS_SERVICE, this))
+ managerInterface(NULL),
+ systemSettings(NULL),
+ ofonoManager(NULL),
+ nmAvailable(false)
{
- if (!managerInterface->isValid())
- return;
-
- managerInterface->setConnections();
- connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)),
- this, SLOT(deviceAdded(QDBusObjectPath)));
- connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)),
- this, SLOT(deviceRemoved(QDBusObjectPath)));
- connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)),
- this, SLOT(activationFinished(QDBusPendingCallWatcher*)));
- connect(managerInterface, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
- this, SLOT(interfacePropertiesChanged(QString,QMap<QString,QVariant>)));
-
qDBusRegisterMetaType<QNmSettingsMap>();
- systemSettings->setConnections();
- connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)),
- this, SLOT(newConnection(QDBusObjectPath)));
-
- userSettings->setConnections();
- connect(userSettings, SIGNAL(newConnection(QDBusObjectPath)),
- this, SLOT(newConnection(QDBusObjectPath)));
+ nmWatcher = new QDBusServiceWatcher(NM_DBUS_SERVICE,QDBusConnection::systemBus(),
+ QDBusServiceWatcher::WatchForRegistration |
+ QDBusServiceWatcher::WatchForUnregistration, this);
+ connect(nmWatcher, SIGNAL(serviceRegistered(QString)),
+ this, SLOT(nmRegistered(QString)));
+ connect(nmWatcher, SIGNAL(serviceUnregistered(QString)),
+ this, SLOT(nmUnRegistered(QString)));
+
+ ofonoWatcher = new QDBusServiceWatcher("org.ofono",QDBusConnection::systemBus(),
+ QDBusServiceWatcher::WatchForRegistration |
+ QDBusServiceWatcher::WatchForUnregistration, this);
+ connect(ofonoWatcher, SIGNAL(serviceRegistered(QString)),
+ this, SLOT(ofonoRegistered(QString)));
+ connect(ofonoWatcher, SIGNAL(serviceUnregistered(QString)),
+ this, SLOT(ofonoUnRegistered(QString)));
+
+ if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.ofono"))
+ ofonoRegistered();
+
+ if (QDBusConnection::systemBus().interface()->isServiceRegistered(NM_DBUS_SERVICE))
+ nmRegistered();
}
QNetworkManagerEngine::~QNetworkManagerEngine()
{
qDeleteAll(connections);
+ connections.clear();
qDeleteAll(accessPoints);
+ accessPoints.clear();
qDeleteAll(wirelessDevices);
- qDeleteAll(activeConnections);
+ wirelessDevices.clear();
+ qDeleteAll(activeConnectionsList);
+ activeConnectionsList.clear();
+ qDeleteAll(interfaceDevices);
+ interfaceDevices.clear();
+
+ connectionInterfaces.clear();
+
+ qDeleteAll(ofonoContextManagers);
+ ofonoContextManagers.clear();
+
+ qDeleteAll(wiredDevices);
+ wiredDevices.clear();
}
void QNetworkManagerEngine::initialize()
{
+ if (nmAvailable)
+ setupConfigurations();
+}
+
+void QNetworkManagerEngine::setupConfigurations()
+{
QMutexLocker locker(&mutex);
+ // Get active connections.
+ foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) {
- // Get current list of access points.
+ QNetworkManagerConnectionActive *activeConnection =
+ new QNetworkManagerConnectionActive(acPath.path(),this);
+ activeConnectionsList.insert(acPath.path(), activeConnection);
+ connect(activeConnection, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
+ this, SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>)));
+ activeConnection->setConnections();
+
+ QStringList devices = activeConnection->devices();
+ if (!devices.isEmpty()) {
+ QNetworkManagerInterfaceDevice device(devices.at(0),this);
+ connectionInterfaces.insert(activeConnection->connection().path(),device.networkInterface());
+ }
+ }
+
+ // Get current list of access points.
foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) {
locker.unlock();
deviceAdded(devicePath); //add all accesspoints
@@ -103,7 +142,6 @@ void QNetworkManagerEngine::initialize()
}
// Get connections.
-
foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) {
locker.unlock();
if (!hasIdentifier(settingsPath.path()))
@@ -111,57 +149,19 @@ void QNetworkManagerEngine::initialize()
locker.relock();
}
- foreach (const QDBusObjectPath &settingsPath, userSettings->listConnections()) {
- locker.unlock();
- if (!hasIdentifier(settingsPath.path()))
- newConnection(settingsPath, userSettings);
- locker.relock();
- }
-
- // Get active connections.
- foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) {
- QNetworkManagerConnectionActive *activeConnection =
- new QNetworkManagerConnectionActive(acPath.path(),this);
- activeConnections.insert(acPath.path(), activeConnection);
-
- activeConnection->setConnections();
- connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
- this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>)));
- }
Q_EMIT updateCompleted();
}
bool QNetworkManagerEngine::networkManagerAvailable() const
{
- QMutexLocker locker(&mutex);
-
- return managerInterface->isValid();
+ return nmAvailable;
}
-QString QNetworkManagerEngine::getInterfaceFromId(const QString &id)
+QString QNetworkManagerEngine::getInterfaceFromId(const QString &settingsPath)
{
- QMutexLocker locker(&mutex);
-
- foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) {
- QNetworkManagerConnectionActive activeConnection(acPath.path());
-
- const QString identifier = activeConnection.connection().path();
-
- if (id == identifier) {
- QList<QDBusObjectPath> devices = activeConnection.devices();
-
- if (devices.isEmpty())
- continue;
-
- QNetworkManagerInterfaceDevice device(devices.at(0).path());
- return device.networkInterface();
- }
- }
-
- return QString();
+ return connectionInterfaces.value(settingsPath);
}
-
bool QNetworkManagerEngine::hasIdentifier(const QString &id)
{
QMutexLocker locker(&mutex);
@@ -177,35 +177,37 @@ void QNetworkManagerEngine::connectToId(const QString &id)
if (!connection)
return;
- QNmSettingsMap map = connection->getSettings();
- const QString connectionType = map.value("connection").value("type").toString();
+ NMDeviceType connectionType = connection->getType();
QString dbusDevicePath;
- foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) {
- QNetworkManagerInterfaceDevice device(devicePath.path());
- if (device.deviceType() == DEVICE_TYPE_ETHERNET &&
- connectionType == QLatin1String("802-3-ethernet")) {
- dbusDevicePath = devicePath.path();
+ const QString settingsPath = connection->connectionInterface()->path();
+ QString specificPath = configuredAccessPoints.key(settingsPath);
+
+ if (isConnectionActive(settingsPath))
+ return;
+
+ QHashIterator<QString, QNetworkManagerInterfaceDevice*> i(interfaceDevices);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value()->deviceType() == DEVICE_TYPE_ETHERNET &&
+ connectionType == DEVICE_TYPE_ETHERNET) {
+ dbusDevicePath = i.key();
break;
- } else if (device.deviceType() == DEVICE_TYPE_WIFI &&
- connectionType == QLatin1String("802-11-wireless")) {
- dbusDevicePath = devicePath.path();
+ } else if (i.value()->deviceType() == DEVICE_TYPE_WIFI &&
+ connectionType == DEVICE_TYPE_WIFI) {
+ dbusDevicePath = i.key();
break;
- } else if (device.deviceType() == DEVICE_TYPE_MODEM &&
- connectionType == QLatin1String("gsm")) {
- dbusDevicePath = devicePath.path();
+ } else if (i.value()->deviceType() == DEVICE_TYPE_MODEM &&
+ connectionType == DEVICE_TYPE_MODEM) {
+ dbusDevicePath = i.key();
break;
}
}
- const QString service = connection->connectionInterface()->service();
- const QString settingsPath = connection->connectionInterface()->path();
- QString specificPath = configuredAccessPoints.key(settingsPath);
-
if (specificPath.isEmpty())
specificPath = "/";
- managerInterface->activateConnection(service, QDBusObjectPath(settingsPath),
+ managerInterface->activateConnection(QDBusObjectPath(settingsPath),
QDBusObjectPath(dbusDevicePath), QDBusObjectPath(specificPath));
}
@@ -221,13 +223,11 @@ void QNetworkManagerEngine::disconnectFromId(const QString &id)
return;
}
- foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) {
- QNetworkManagerConnectionActive activeConnection(acPath.path());
-
- const QString identifier = activeConnection.connection().path();
-
- if (id == identifier && accessPointConfigurations.contains(id)) {
- managerInterface->deactivateConnection(acPath);
+ QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList);
+ while (i.hasNext()) {
+ i.next();
+ if (id == i.value()->connection().path() && accessPointConfigurations.contains(id)) {
+ managerInterface->deactivateConnection(QDBusObjectPath(i.key()));
break;
}
}
@@ -235,7 +235,7 @@ void QNetworkManagerEngine::disconnectFromId(const QString &id)
void QNetworkManagerEngine::requestUpdate()
{
- if (managerInterface->wirelessEnabled()) {
+ if (managerInterface && managerInterface->wirelessEnabled()) {
QHashIterator<QString, QNetworkManagerInterfaceDeviceWireless *> i(wirelessDevices);
while (i.hasNext()) {
i.next();
@@ -250,12 +250,9 @@ void QNetworkManagerEngine::scanFinished()
QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection);
}
-void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
- const QMap<QString, QVariant> &properties)
+void QNetworkManagerEngine::interfacePropertiesChanged(const QMap<QString, QVariant> &properties)
{
- Q_UNUSED(path)
QMutexLocker locker(&mutex);
-
QMapIterator<QString, QVariant> i(properties);
while (i.hasNext()) {
i.next();
@@ -267,22 +264,20 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
qdbus_cast<QList<QDBusObjectPath> >(i.value().value<QDBusArgument>());
QStringList identifiers = accessPointConfigurations.keys();
- foreach (const QString &id, identifiers)
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
-
- QStringList priorActiveConnections = this->activeConnections.keys();
+ QStringList priorActiveConnections = activeConnectionsList.keys();
foreach (const QDBusObjectPath &acPath, activeConnections) {
priorActiveConnections.removeOne(acPath.path());
QNetworkManagerConnectionActive *activeConnection =
- this->activeConnections.value(acPath.path());
+ activeConnectionsList.value(acPath.path());
+
if (!activeConnection) {
activeConnection = new QNetworkManagerConnectionActive(acPath.path(),this);
- this->activeConnections.insert(acPath.path(), activeConnection);
+ activeConnectionsList.insert(acPath.path(), activeConnection);
+ connect(activeConnection, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
+ this, SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>)));
activeConnection->setConnections();
- connect(activeConnection, SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)),
- this, SLOT(activeConnectionPropertiesChanged(QString,QMap<QString,QVariant>)));
}
const QString id = activeConnection->connection().path();
@@ -293,8 +288,14 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
if (ptr) {
ptr->mutex.lock();
if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
- ptr->state != QNetworkConfiguration::Active) {
- ptr->state = QNetworkConfiguration::Active;
+ (ptr->state & QNetworkConfiguration::Active) != QNetworkConfiguration::Active) {
+
+ ptr->state |= QNetworkConfiguration::Active;
+
+ if (activeConnectionsList.value(id) && activeConnectionsList.value(id)->defaultRoute()
+ && managerInterface->state() < QNetworkManagerInterface::NM_STATE_CONNECTED_GLOBAL) {
+ ptr->purpose = QNetworkConfiguration::PrivatePurpose;
+ }
ptr->mutex.unlock();
locker.unlock();
@@ -307,7 +308,7 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
}
while (!priorActiveConnections.isEmpty())
- delete this->activeConnections.take(priorActiveConnections.takeFirst());
+ delete activeConnectionsList.take(priorActiveConnections.takeFirst());
while (!identifiers.isEmpty()) {
QNetworkConfigurationPrivatePointer ptr =
@@ -330,14 +331,13 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
}
}
-void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &path,
- const QMap<QString, QVariant> &properties)
+void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QMap<QString, QVariant> &properties)
{
QMutexLocker locker(&mutex);
Q_UNUSED(properties)
- QNetworkManagerConnectionActive *activeConnection = activeConnections.value(path);
+ QNetworkManagerConnectionActive *activeConnection = qobject_cast<QNetworkManagerConnectionActive *>(sender());
if (!activeConnection)
return;
@@ -346,32 +346,34 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (ptr) {
- ptr->mutex.lock();
- if (activeConnection->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
- ptr->state != QNetworkConfiguration::Active) {
- ptr->state |= QNetworkConfiguration::Active;
- ptr->mutex.unlock();
-
- locker.unlock();
- emit configurationChanged(ptr);
- locker.relock();
- } else {
- ptr->mutex.unlock();
+ if (properties.contains(QStringLiteral("State"))) {
+ ptr->mutex.lock();
+ if (properties.value("State").toUInt() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
+ QStringList devices = activeConnection->devices();
+ if (!devices.isEmpty()) {
+ QNetworkManagerInterfaceDevice device(devices.at(0),this);
+ connectionInterfaces.insert(id,device.networkInterface());
+ }
+
+ ptr->state |= QNetworkConfiguration::Active;
+ ptr->mutex.unlock();
+
+ locker.unlock();
+ emit configurationChanged(ptr);
+ locker.relock();
+ } else {
+ connectionInterfaces.remove(id);
+ ptr->mutex.unlock();
+ }
}
}
}
-void QNetworkManagerEngine::devicePropertiesChanged(const QString &/*path*/,quint32 /*state*/)
-{
-// Q_UNUSED(path);
-// Q_UNUSED(state)
-}
-
-void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &activeConnectionsList)
+void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &connectionsList)
{
QMutexLocker locker(&mutex);
for (int i = 0; i < connections.count(); ++i) {
- if (activeConnectionsList.contains(connections.at(i)->connectionInterface()->path()))
+ if (connectionsList.contains(connections.at(i)->connectionInterface()->path()))
continue;
const QString settingsPath = connections.at(i)->connectionInterface()->path();
@@ -392,33 +394,33 @@ void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &activeCo
void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path)
{
- QMutexLocker locker(&mutex);
QNetworkManagerInterfaceDevice *iDevice;
iDevice = new QNetworkManagerInterfaceDevice(path.path(),this);
connect(iDevice,SIGNAL(connectionsChanged(QStringList)),
this,SLOT(deviceConnectionsChanged(QStringList)));
- connect(iDevice,SIGNAL(stateChanged(QString,quint32)),
- this,SLOT(devicePropertiesChanged(QString,quint32)));
iDevice->setConnections();
interfaceDevices.insert(path.path(),iDevice);
-
if (iDevice->deviceType() == DEVICE_TYPE_WIFI) {
QNetworkManagerInterfaceDeviceWireless *wirelessDevice =
new QNetworkManagerInterfaceDeviceWireless(iDevice->connectionInterface()->path(),this);
- wirelessDevice->setConnections();
connect(wirelessDevice, SIGNAL(accessPointAdded(QString)),
this, SLOT(newAccessPoint(QString)));
connect(wirelessDevice, SIGNAL(accessPointRemoved(QString)),
this, SLOT(removeAccessPoint(QString)));
connect(wirelessDevice,SIGNAL(scanDone()),this,SLOT(scanFinished()));
-
- foreach (const QDBusObjectPath &apPath, wirelessDevice->getAccessPoints())
- newAccessPoint(apPath.path());
+ wirelessDevice->setConnections();
wirelessDevices.insert(path.path(), wirelessDevice);
}
+
+ if (iDevice->deviceType() == DEVICE_TYPE_ETHERNET) {
+ QNetworkManagerInterfaceDeviceWired *wiredDevice =
+ new QNetworkManagerInterfaceDeviceWired(iDevice->connectionInterface()->path(),this);
+ connect(wiredDevice,SIGNAL(carrierChanged(bool)),this,SLOT(wiredCarrierChanged(bool)));
+ wiredDevices.insert(iDevice->connectionInterface()->path(), wiredDevice);
+ }
}
void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path)
@@ -435,6 +437,41 @@ void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path)
delete wirelessDevices.take(path.path());
locker.relock();
}
+ if (wiredDevices.contains(path.path())) {
+ locker.unlock();
+ delete wiredDevices.take(path.path());
+ locker.relock();
+ }
+}
+
+void QNetworkManagerEngine::wiredCarrierChanged(bool carrier)
+{
+ QNetworkManagerInterfaceDeviceWired *deviceWired = qobject_cast<QNetworkManagerInterfaceDeviceWired *>(sender());
+ if (!deviceWired)
+ return;
+ QMutexLocker locker(&mutex);
+ foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) {
+ for (int i = 0; i < connections.count(); ++i) {
+ QNetworkManagerSettingsConnection *connection = connections.at(i);
+ if (connection->getType() == DEVICE_TYPE_ETHERNET
+ && settingsPath.path() == connection->connectionInterface()->path()) {
+ QNetworkConfigurationPrivatePointer ptr =
+ accessPointConfigurations.value(settingsPath.path());
+
+ if (ptr) {
+ ptr->mutex.lock();
+ if (carrier)
+ ptr->state |= QNetworkConfiguration::Discovered;
+ else
+ ptr->state = QNetworkConfiguration::Defined;
+ ptr->mutex.unlock();
+ locker.unlock();
+ emit configurationChanged(ptr);
+ return;
+ }
+ }
+ }
+ }
}
void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path,
@@ -444,67 +481,102 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path,
if (!settings)
settings = qobject_cast<QNetworkManagerSettings *>(sender());
- if (!settings)
+ if (!settings) {
return;
+ }
- settings->deleteLater();
QNetworkManagerSettingsConnection *connection =
new QNetworkManagerSettingsConnection(settings->connectionInterface()->service(),
path.path(),this);
- QString apPath;
- for (int i = 0; i < accessPoints.count(); ++i) {
- if (connection->getSsid() == accessPoints.at(i)->ssid()) {
- // remove the corresponding accesspoint from configurations
- apPath = accessPoints.at(i)->connectionInterface()->path();
-
- QNetworkConfigurationPrivatePointer ptr
- = accessPointConfigurations.take(apPath);
- if (ptr) {
- locker.unlock();
- emit configurationRemoved(ptr);
- locker.relock();
- }
- }
+ const QString settingsPath = connection->connectionInterface()->path();
+ if (accessPointConfigurations.contains(settingsPath)) {
+ return;
}
+
connections.append(connection);
connect(connection,SIGNAL(removed(QString)),this,SLOT(removeConnection(QString)));
connect(connection,SIGNAL(updated()),this,SLOT(updateConnection()));
connection->setConnections();
- const QString settingsPath = connection->connectionInterface()->path();
+ NMDeviceType deviceType = connection->getType();
- if (connection->getType() == DEVICE_TYPE_WIFI
- && !configuredAccessPoints.contains(settingsPath))
- configuredAccessPoints.insert(apPath,settingsPath);
+ if (deviceType == DEVICE_TYPE_WIFI) {
+ QString apPath;
+ for (int i = 0; i < accessPoints.count(); ++i) {
+ if (connection->getSsid() == accessPoints.at(i)->ssid()) {
+ // remove the corresponding accesspoint from configurations
+ apPath = accessPoints.at(i)->connectionInterface()->path();
+ QNetworkConfigurationPrivatePointer ptr
+ = accessPointConfigurations.take(apPath);
+ if (ptr) {
+ locker.unlock();
+ emit configurationRemoved(ptr);
+ locker.relock();
+ }
+ }
+ }
+ if (!configuredAccessPoints.contains(settingsPath))
+ configuredAccessPoints.insert(apPath,settingsPath);
+ }
QNetworkConfigurationPrivate *cpPriv =
parseConnection(settingsPath, connection->getSettings());
// Check if connection is active.
- foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) {
- QNetworkManagerConnectionActive activeConnection(acPath.path());
+ if (isConnectionActive(settingsPath))
+ cpPriv->state |= QNetworkConfiguration::Active;
+
+ if (deviceType == DEVICE_TYPE_ETHERNET) {
+ QHashIterator<QString, QNetworkManagerInterfaceDevice*> i(interfaceDevices);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value()->deviceType() == deviceType) {
+ QNetworkManagerInterfaceDeviceWired *wiredDevice
+ = wiredDevices.value(i.value()->connectionInterface()->path());
+ if (wiredDevice->carrier()) {
+ cpPriv->state |= QNetworkConfiguration::Discovered;
+ }
+ }
+ }
+ }
- if (activeConnection.defaultRoute() &&
- activeConnection.connection().path() == settingsPath &&
- activeConnection.state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
- cpPriv->state |= QNetworkConfiguration::Active;
- break;
- }
- }
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
-
locker.unlock();
emit configurationAdded(ptr);
}
+bool QNetworkManagerEngine::isConnectionActive(const QString &settingsPath)
+{
+ QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value()->connection().path() == settingsPath) {
+ if (i.value()->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATING
+ || i.value()->state() == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
+ return true;
+ } else {
+ break;
+ }
+ }
+ }
+
+ QNetworkManagerSettingsConnection *settingsConnection = connectionFromId(settingsPath);
+ if (settingsConnection->getType() == DEVICE_TYPE_MODEM) {
+ return isActiveContext(settingsConnection->connectionInterface()->path());
+ }
+
+ return false;
+}
+
void QNetworkManagerEngine::removeConnection(const QString &path)
{
QMutexLocker locker(&mutex);
QNetworkManagerSettingsConnection *connection =
qobject_cast<QNetworkManagerSettingsConnection *>(sender());
+
if (!connection)
return;
@@ -525,6 +597,7 @@ void QNetworkManagerEngine::removeConnection(const QString &path)
while (i.hasNext()) {
i.next();
if (i.value() == path) {
+ configuredAccessPoints.remove(i.key());
newAccessPoint(i.key());
}
}
@@ -538,8 +611,6 @@ void QNetworkManagerEngine::updateConnection()
qobject_cast<QNetworkManagerSettingsConnection *>(sender());
if (!connection)
return;
-
- connection->deleteLater();
const QString settingsPath = connection->connectionInterface()->path();
QNetworkConfigurationPrivate *cpPriv = parseConnection(settingsPath, connection->getSettings());
@@ -575,10 +646,9 @@ void QNetworkManagerEngine::updateConnection()
void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher)
{
QMutexLocker locker(&mutex);
-
+ QDBusPendingReply<QDBusObjectPath> reply(*watcher);
watcher->deleteLater();
- QDBusPendingReply<QDBusObjectPath> reply(*watcher);
if (!reply.isError()) {
QDBusObjectPath result = reply.value();
@@ -607,7 +677,6 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher)
void QNetworkManagerEngine::newAccessPoint(const QString &path)
{
QMutexLocker locker(&mutex);
-
QNetworkManagerInterfaceAccessPoint *accessPoint =
new QNetworkManagerInterfaceAccessPoint(path,this);
@@ -620,15 +689,14 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path)
if (okToAdd) {
accessPoints.append(accessPoint);
accessPoint->setConnections();
- connect(accessPoint, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
- this, SLOT(updateAccessPoint(QMap<QString,QVariant>)));
}
-
// Check if configuration exists for connection.
if (!accessPoint->ssid().isEmpty()) {
+
for (int i = 0; i < connections.count(); ++i) {
QNetworkManagerSettingsConnection *connection = connections.at(i);
const QString settingsPath = connection->connectionInterface()->path();
+
if (accessPoint->ssid() == connection->getSsid()) {
if (!configuredAccessPoints.contains(path)) {
configuredAccessPoints.insert(path,settingsPath);
@@ -639,6 +707,9 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path)
ptr->mutex.lock();
QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined;
ptr->state = (flag | QNetworkConfiguration::Discovered);
+
+ if (isConnectionActive(settingsPath))
+ ptr->state = (flag | QNetworkConfiguration::Active);
ptr->mutex.unlock();
locker.unlock();
@@ -655,11 +726,7 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path)
ptr->isValid = true;
ptr->id = path;
ptr->type = QNetworkConfiguration::InternetAccessPoint;
- if (accessPoint->flags() == NM_802_11_AP_FLAGS_PRIVACY) {
- ptr->purpose = QNetworkConfiguration::PrivatePurpose;
- } else {
- ptr->purpose = QNetworkConfiguration::PublicPurpose;
- }
+ ptr->purpose = QNetworkConfiguration::PublicPurpose;
ptr->state = QNetworkConfiguration::Undefined;
ptr->bearerType = QNetworkConfiguration::BearerWLAN;
@@ -674,13 +741,13 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path)
QMutexLocker locker(&mutex);
for (int i = 0; i < accessPoints.count(); ++i) {
QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i);
-
if (accessPoint->connectionInterface()->path() == path) {
accessPoints.removeOne(accessPoint);
if (configuredAccessPoints.contains(accessPoint->connectionInterface()->path())) {
// find connection and change state to Defined
configuredAccessPoints.remove(accessPoint->connectionInterface()->path());
+
for (int i = 0; i < connections.count(); ++i) {
QNetworkManagerSettingsConnection *connection = connections.at(i);
@@ -706,8 +773,6 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path)
if (ptr) {
locker.unlock();
-
- locker.unlock();
emit configurationRemoved(ptr);
locker.relock();
}
@@ -718,46 +783,12 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path)
}
}
-void QNetworkManagerEngine::updateAccessPoint(const QMap<QString, QVariant> &map)
-{
- QMutexLocker locker(&mutex);
-
- Q_UNUSED(map)
-
- QNetworkManagerInterfaceAccessPoint *accessPoint =
- qobject_cast<QNetworkManagerInterfaceAccessPoint *>(sender());
- if (!accessPoint)
- return;
- accessPoint->deleteLater();
- for (int i = 0; i < connections.count(); ++i) {
- QNetworkManagerSettingsConnection *connection = connections.at(i);
-
- if (accessPoint->ssid() == connection->getSsid()) {
- const QString settingsPath = connection->connectionInterface()->path();
- const QString connectionId = settingsPath;
-
- QNetworkConfigurationPrivatePointer ptr =
- accessPointConfigurations.value(connectionId);
- ptr->mutex.lock();
- QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined;
- ptr->state = (flag | QNetworkConfiguration::Discovered);
- ptr->mutex.unlock();
-
- locker.unlock();
- emit configurationChanged(ptr);
- return;
- }
- }
-}
-
QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &settingsPath,
const QNmSettingsMap &map)
{
- // Q_UNUSED(service);
QMutexLocker locker(&mutex);
QNetworkConfigurationPrivate *cpPriv = new QNetworkConfigurationPrivate;
cpPriv->name = map.value("connection").value("id").toString();
-
cpPriv->isValid = true;
cpPriv->id = settingsPath;
cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
@@ -765,18 +796,16 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri
cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
cpPriv->state = QNetworkConfiguration::Defined;
-
const QString connectionType = map.value("connection").value("type").toString();
if (connectionType == QLatin1String("802-3-ethernet")) {
cpPriv->bearerType = QNetworkConfiguration::BearerEthernet;
- cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) {
- QNetworkManagerInterfaceDevice device(devicePath.path());
+ QNetworkManagerInterfaceDevice device(devicePath.path(),this);
if (device.deviceType() == DEVICE_TYPE_ETHERNET) {
- QNetworkManagerInterfaceDeviceWired wiredDevice(device.connectionInterface()->path());
- if (wiredDevice.carrier()) {
+ QNetworkManagerInterfaceDeviceWired *wiredDevice = wiredDevices.value(device.connectionInterface()->path());
+ if (wiredDevice->carrier()) {
cpPriv->state |= QNetworkConfiguration::Discovered;
break;
}
@@ -786,12 +815,6 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri
cpPriv->bearerType = QNetworkConfiguration::BearerWLAN;
const QString connectionSsid = map.value("802-11-wireless").value("ssid").toString();
- const QString connectionSecurity = map.value("802-11-wireless").value("security").toString();
- if (!connectionSecurity.isEmpty()) {
- cpPriv->purpose = QNetworkConfiguration::PrivatePurpose;
- } else {
- cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
- }
for (int i = 0; i < accessPoints.count(); ++i) {
if (connectionSsid == accessPoints.at(i)->ssid()
&& map.value("802-11-wireless").value("seen-bssids").toStringList().contains(accessPoints.at(i)->hwAddress())) {
@@ -814,35 +837,46 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri
}
} else if (connectionType == QLatin1String("gsm")) {
- foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) {
- QNetworkManagerInterfaceDevice device(devicePath.path());
-
- if (device.deviceType() == DEVICE_TYPE_MODEM) {
- QNetworkManagerInterfaceDeviceModem deviceModem(device.connectionInterface()->path(),this);
- switch (deviceModem.currentCapabilities()) {
- case 2:
- cpPriv->bearerType = QNetworkConfiguration::Bearer2G;
+ const QString connectionPath = map.value("connection").value("id").toString();
+ cpPriv->name = contextName(connectionPath);
+ cpPriv->bearerType = currentBearerType(connectionPath);
+
+ if (ofonoManager && ofonoManager->isValid()) {
+ const QString contextPart = connectionPath.section('/', -1);
+ QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers);
+ while (i.hasNext()) {
+ i.next();
+ const QString path = i.key() +"/"+contextPart;
+ if (isActiveContext(path)) {
+ cpPriv->state |= QNetworkConfiguration::Active;
break;
- case 4:
- cpPriv->bearerType = QNetworkConfiguration::Bearer3G;
- break;
- case 8:
- cpPriv->bearerType = QNetworkConfiguration::Bearer4G;
- break;
- default:
- cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
- break;
- };
+ }
}
}
-
- cpPriv->purpose = QNetworkConfiguration::PrivatePurpose;
- cpPriv->state |= QNetworkConfiguration::Discovered;
}
return cpPriv;
}
+bool QNetworkManagerEngine::isActiveContext(const QString &contextPath)
+{
+ if (ofonoManager && ofonoManager->isValid()) {
+ const QString contextPart = contextPath.section('/', -1);
+ QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers);
+ while (i.hasNext()) {
+ i.next();
+ PathPropertiesList list = i.value()->contextsWithProperties();
+ for (int i = 0; i < list.size(); ++i) {
+ if (list.at(i).path.path().contains(contextPart)) {
+ return list.at(i).properties.value(QStringLiteral("Active")).toBool();
+
+ }
+ }
+ }
+ }
+ return false;
+}
+
QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const QString &id) const
{
for (int i = 0; i < connections.count(); ++i) {
@@ -857,7 +891,6 @@ QNetworkManagerSettingsConnection *QNetworkManagerEngine::connectionFromId(const
QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &id)
{
QMutexLocker locker(&mutex);
-
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (!ptr)
@@ -866,8 +899,8 @@ QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &i
if (!ptr->isValid)
return QNetworkSession::Invalid;
- foreach (const QString &acPath, activeConnections.keys()) {
- QNetworkManagerConnectionActive *activeConnection = activeConnections.value(acPath);
+ foreach (const QString &acPath, activeConnectionsList.keys()) {
+ QNetworkManagerConnectionActive *activeConnection = activeConnectionsList.value(acPath);
const QString identifier = activeConnection->connection().path();
@@ -899,7 +932,7 @@ quint64 QNetworkManagerEngine::bytesWritten(const QString &id)
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
- const QString networkInterface = getInterfaceFromId(id);
+ const QString networkInterface = connectionInterfaces.value(id);
if (!networkInterface.isEmpty()) {
const QString devFile = QLatin1String("/sys/class/net/") +
networkInterface +
@@ -927,7 +960,7 @@ quint64 QNetworkManagerEngine::bytesReceived(const QString &id)
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (ptr && (ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
- const QString networkInterface = getInterfaceFromId(id);
+ const QString networkInterface = connectionInterfaces.value(id);
if (!networkInterface.isEmpty()) {
const QString devFile = QLatin1String("/sys/class/net/") +
networkInterface +
@@ -974,9 +1007,125 @@ QNetworkSessionPrivate *QNetworkManagerEngine::createSessionBackend()
QNetworkConfigurationPrivatePointer QNetworkManagerEngine::defaultConfiguration()
{
+ QHashIterator<QString, QNetworkManagerConnectionActive*> i(activeConnectionsList);
+ while (i.hasNext()) {
+ i.next();
+ QNetworkManagerConnectionActive *activeConnection = i.value();
+ if ((activeConnection->defaultRoute() || activeConnection->default6Route())) {
+ return accessPointConfigurations.value(activeConnection->connection().path());
+ }
+ }
+
return QNetworkConfigurationPrivatePointer();
}
+QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const QString &id)
+{
+ QString contextPart = id.section('/', -1);
+ QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers);
+ while (i.hasNext()) {
+ i.next();
+ QString contextPath = i.key() +"/"+contextPart;
+
+ if (i.value()->contexts().contains(contextPath)) {
+
+ QString bearer = i.value()->bearer();
+
+ if (bearer == QStringLiteral("gsm")) {
+ return QNetworkConfiguration::Bearer2G;
+ } else if (bearer == QStringLiteral("edge")) {
+ return QNetworkConfiguration::Bearer2G;
+ } else if (bearer == QStringLiteral("umts")) {
+ return QNetworkConfiguration::BearerWCDMA;
+ } else if (bearer == QStringLiteral("hspa")
+ || bearer == QStringLiteral("hsdpa")
+ || bearer == QStringLiteral("hsupa")) {
+ return QNetworkConfiguration::BearerHSPA;
+ } else if (bearer == QStringLiteral("lte")) {
+ return QNetworkConfiguration::BearerLTE;
+ }
+ }
+ }
+
+ return QNetworkConfiguration::BearerUnknown;
+}
+
+QString QNetworkManagerEngine::contextName(const QString &path)
+{
+ QString contextPart = path.section('/', -1);
+ QHashIterator<QString, QOfonoDataConnectionManagerInterface*> i(ofonoContextManagers);
+ while (i.hasNext()) {
+ i.next();
+ PathPropertiesList list = i.value()->contextsWithProperties();
+ for (int i = 0; i < list.size(); ++i) {
+ if (list.at(i).path.path().contains(contextPart)) {
+ return list.at(i).properties.value(QStringLiteral("Name")).toString();
+ }
+ }
+ }
+ return path;
+}
+
+void QNetworkManagerEngine::nmRegistered(const QString &)
+{
+ if (ofonoManager) {
+ delete ofonoManager;
+ ofonoManager = NULL;
+ }
+ managerInterface = new QNetworkManagerInterface(this);
+ systemSettings = new QNetworkManagerSettings(NM_DBUS_SERVICE, this);
+
+ connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)),
+ this, SLOT(deviceAdded(QDBusObjectPath)));
+ connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)),
+ this, SLOT(deviceRemoved(QDBusObjectPath)));
+ connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)),
+ this, SLOT(activationFinished(QDBusPendingCallWatcher*)));
+ connect(managerInterface, SIGNAL(propertiesChanged(QMap<QString,QVariant>)),
+ this, SLOT(interfacePropertiesChanged(QMap<QString,QVariant>)));
+ managerInterface->setConnections();
+
+ connect(systemSettings, SIGNAL(newConnection(QDBusObjectPath)),
+ this, SLOT(newConnection(QDBusObjectPath)));
+ systemSettings->setConnections();
+ nmAvailable = true;
+
+ setupConfigurations();
+}
+
+void QNetworkManagerEngine::nmUnRegistered(const QString &)
+{
+ if (systemSettings) {
+ delete systemSettings;
+ systemSettings = NULL;
+ }
+ if (managerInterface) {
+ delete managerInterface;
+ managerInterface = NULL;
+ }
+}
+
+void QNetworkManagerEngine::ofonoRegistered(const QString &)
+{
+ if (ofonoManager) {
+ delete ofonoManager;
+ ofonoManager = NULL;
+ }
+ ofonoManager = new QOfonoManagerInterface(this);
+ if (ofonoManager && ofonoManager->isValid()) {
+ Q_FOREACH (const QString &modem, ofonoManager->getModems()) {
+ QOfonoDataConnectionManagerInterface *ofonoContextManager
+ = new QOfonoDataConnectionManagerInterface(modem,this);
+ ofonoContextManagers.insert(modem, ofonoContextManager);
+ }
+ }
+}
+
+void QNetworkManagerEngine::ofonoUnRegistered(const QString &)
+{
+ ofonoContextManagers.clear();
+}
+
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
index ab1cfea71e..da6af14c00 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
@@ -49,6 +49,8 @@
#include "qnetworkmanagerservice.h"
+#include "../linux_common/qofonoservice_linux_p.h"
+
#include <QMap>
#include <QVariant>
@@ -89,11 +91,8 @@ public:
QNetworkConfigurationPrivatePointer defaultConfiguration();
private Q_SLOTS:
- void interfacePropertiesChanged(const QString &path,
- const QMap<QString, QVariant> &properties);
- void activeConnectionPropertiesChanged(const QString &path,
- const QMap<QString, QVariant> &properties);
- void devicePropertiesChanged(const QString &path, quint32);
+ void interfacePropertiesChanged(const QMap<QString, QVariant> &properties);
+ void activeConnectionPropertiesChanged(const QMap<QString, QVariant> &properties);
void deviceAdded(const QDBusObjectPath &path);
void deviceRemoved(const QDBusObjectPath &path);
@@ -106,9 +105,16 @@ private Q_SLOTS:
void newAccessPoint(const QString &path);
void removeAccessPoint(const QString &path);
- void updateAccessPoint(const QMap<QString, QVariant> &map);
void scanFinished();
+ void wiredCarrierChanged(bool);
+
+ void nmRegistered(const QString &serviceName = QString());
+ void nmUnRegistered(const QString &serviceName = QString());
+
+ void ofonoRegistered(const QString &serviceName = QString());
+ void ofonoUnRegistered(const QString &serviceName = QString());
+
private:
QNetworkConfigurationPrivate *parseConnection(const QString &settingsPath,
const QNmSettingsMap &map);
@@ -116,14 +122,29 @@ private:
QNetworkManagerInterface *managerInterface;
QNetworkManagerSettings *systemSettings;
- QNetworkManagerSettings *userSettings;
+ QHash<QString, QNetworkManagerInterfaceDeviceWired *> wiredDevices;
QHash<QString, QNetworkManagerInterfaceDeviceWireless *> wirelessDevices;
- QHash<QString, QNetworkManagerConnectionActive *> activeConnections;
+
+ QHash<QString, QNetworkManagerConnectionActive *> activeConnectionsList;
QList<QNetworkManagerSettingsConnection *> connections;
QList<QNetworkManagerInterfaceAccessPoint *> accessPoints;
QHash<QString, QNetworkManagerInterfaceDevice *> interfaceDevices;
QMap<QString,QString> configuredAccessPoints; //ap, settings path
+ QHash<QString,QString> connectionInterfaces; // ac, interface
+
+ QOfonoManagerInterface *ofonoManager;
+ QHash <QString, QOfonoDataConnectionManagerInterface *> ofonoContextManagers;
+ QNetworkConfiguration::BearerType currentBearerType(const QString &id);
+ QString contextName(const QString &path);
+
+ bool isConnectionActive(const QString &settingsPath);
+ QDBusServiceWatcher *ofonoWatcher;
+ QDBusServiceWatcher *nmWatcher;
+
+ bool isActiveContext(const QString &contextPath);
+ bool nmAvailable;
+ void setupConfigurations();
};
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
index f249ac6100..fad94f069d 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp
@@ -44,7 +44,6 @@
#include <QtDBus/QDBusPendingCall>
#include "qnetworkmanagerservice.h"
-#include "qnmdbushelper.h"
#ifndef QT_NO_DBUS
@@ -64,18 +63,38 @@ QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent)
d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE),
QLatin1String(NM_DBUS_PATH),
QLatin1String(NM_DBUS_INTERFACE),
- QDBusConnection::systemBus());
+ QDBusConnection::systemBus(),parent);
if (!d->connectionInterface->isValid()) {
d->valid = false;
return;
}
d->valid = true;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)),
- this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)));
- connect(nmDBusHelper,SIGNAL(pathForStateChanged(QString,quint32)),
- this, SIGNAL(stateChanged(QString,quint32)));
+ QDBusInterface managerPropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ QLatin1String(NM_DBUS_PATH),
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus());
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE);
+ QDBusPendingReply<QVariantMap> propsReply
+ = managerPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ }
+
+ QDBusPendingReply<QList <QDBusObjectPath> > nmReply
+ = d->connectionInterface->call(QLatin1String("GetDevices"));
+ nmReply.waitForFinished();
+ if (!nmReply.isError()) {
+ devicesPathList = nmReply.value();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ QLatin1String(NM_DBUS_PATH),
+ QLatin1String(NM_DBUS_INTERFACE),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
}
QNetworkManagerInterface::~QNetworkManagerInterface()
@@ -91,27 +110,24 @@ bool QNetworkManagerInterface::isValid()
bool QNetworkManagerInterface::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
- QDBusConnection dbusConnection = QDBusConnection::systemBus();
-
- bool allOk = false;
- if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
QLatin1String(NM_DBUS_PATH),
QLatin1String(NM_DBUS_INTERFACE),
QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>)))) {
- allOk = true;
- }
- if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
+
+ bool allOk = false;
+ if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
QLatin1String(NM_DBUS_PATH),
QLatin1String(NM_DBUS_INTERFACE),
QLatin1String("DeviceAdded"),
this,SIGNAL(deviceAdded(QDBusObjectPath)))) {
allOk = true;
}
- if (dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE),
+ if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
QLatin1String(NM_DBUS_PATH),
QLatin1String(NM_DBUS_INTERFACE),
QLatin1String("DeviceRemoved"),
@@ -127,14 +143,17 @@ QDBusInterface *QNetworkManagerInterface::connectionInterface() const
return d->connectionInterface;
}
-QList <QDBusObjectPath> QNetworkManagerInterface::getDevices() const
+QList <QDBusObjectPath> QNetworkManagerInterface::getDevices()
{
- QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("GetDevices"));
- return reply.value();
+ if (devicesPathList.isEmpty()) {
+ qWarning() << "using blocking call!";
+ QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("GetDevices"));
+ devicesPathList = reply.value();
+ }
+ return devicesPathList;
}
-void QNetworkManagerInterface::activateConnection( const QString &,
- QDBusObjectPath connectionPath,
+void QNetworkManagerInterface::activateConnection(QDBusObjectPath connectionPath,
QDBusObjectPath devicePath,
QDBusObjectPath specificObject)
{
@@ -150,28 +169,80 @@ void QNetworkManagerInterface::activateConnection( const QString &,
void QNetworkManagerInterface::deactivateConnection(QDBusObjectPath connectionPath) const
{
- d->connectionInterface->call(QLatin1String("DeactivateConnection"), QVariant::fromValue(connectionPath));
+ d->connectionInterface->asyncCall(QLatin1String("DeactivateConnection"), QVariant::fromValue(connectionPath));
}
bool QNetworkManagerInterface::wirelessEnabled() const
{
- return d->connectionInterface->property("WirelessEnabled").toBool();
+ if (propertyMap.contains("WirelessEnabled"))
+ return propertyMap.value("WirelessEnabled").toBool();
+ return false;
}
bool QNetworkManagerInterface::wirelessHardwareEnabled() const
{
- return d->connectionInterface->property("WirelessHardwareEnabled").toBool();
+ if (propertyMap.contains("WirelessHardwareEnabled"))
+ return propertyMap.value("WirelessHardwareEnabled").toBool();
+ return false;
}
QList <QDBusObjectPath> QNetworkManagerInterface::activeConnections() const
{
- QVariant prop = d->connectionInterface->property("ActiveConnections");
- return prop.value<QList<QDBusObjectPath> >();
+ if (propertyMap.contains("ActiveConnections")) {
+
+ const QDBusArgument &dbusArgs = propertyMap.value("ActiveConnections").value<QDBusArgument>();
+ QDBusObjectPath path;
+ QList <QDBusObjectPath> list;
+
+ dbusArgs.beginArray();
+ while (!dbusArgs.atEnd()) {
+ dbusArgs >> path;
+ list.append(path);
+ }
+ dbusArgs.endArray();
+
+ return list;
+ }
+
+ QList <QDBusObjectPath> list;
+ list << QDBusObjectPath();
+ return list;
}
-quint32 QNetworkManagerInterface::state()
+QNetworkManagerInterface::NMState QNetworkManagerInterface::state()
{
- return d->connectionInterface->property("State").toUInt();
+ if (propertyMap.contains("State"))
+ return static_cast<QNetworkManagerInterface::NMState>(propertyMap.value("State").toUInt());
+ return QNetworkManagerInterface::NM_STATE_UNKNOWN;
+}
+
+QString QNetworkManagerInterface::version() const
+{
+ if (propertyMap.contains("Version"))
+ return propertyMap.value("Version").toString();
+ return QString();
+}
+
+void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map)
+{
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ propertyMap.insert(i.key(),i.value());
+
+ if (i.key() == QStringLiteral("State")) {
+ quint32 state = i.value().toUInt();
+ if (state == NM_DEVICE_STATE_ACTIVATED
+ || state == NM_DEVICE_STATE_DISCONNECTED
+ || state == NM_DEVICE_STATE_UNAVAILABLE
+ || state == NM_DEVICE_STATE_FAILED) {
+ Q_EMIT propertiesChanged(map);
+ Q_EMIT stateChanged(state);
+ }
+ } else if (i.key() == QStringLiteral("ActiveConnections")) {
+ Q_EMIT propertiesChanged(map);
+ }
+ }
}
class QNetworkManagerInterfaceAccessPointPrivate
@@ -183,18 +254,38 @@ public:
};
QNetworkManagerInterfaceAccessPoint::QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
d = new QNetworkManagerInterfaceAccessPointPrivate();
d->path = dbusPathName;
d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE),
d->path,
QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT),
- QDBusConnection::systemBus());
+ QDBusConnection::systemBus(),parent);
if (!d->connectionInterface->isValid()) {
d->valid = false;
return;
}
+ QDBusInterface accessPointPropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus());
+
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT);
+ QDBusPendingReply<QVariantMap> propsReply
+ = accessPointPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
+
d->valid = true;
}
@@ -212,24 +303,10 @@ bool QNetworkManagerInterfaceAccessPoint::isValid()
bool QNetworkManagerInterfaceAccessPoint::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
- bool allOk = false;
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)),
- this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)));
-
- if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT),
- QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>))) ) {
- allOk = true;
-
- }
- return allOk;
+ return true;
}
QDBusInterface *QNetworkManagerInterfaceAccessPoint::connectionInterface() const
@@ -239,47 +316,74 @@ QDBusInterface *QNetworkManagerInterfaceAccessPoint::connectionInterface() const
quint32 QNetworkManagerInterfaceAccessPoint::flags() const
{
- return d->connectionInterface->property("Flags").toUInt();
+ if (propertyMap.contains("Flags"))
+ return propertyMap.value("Flags").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceAccessPoint::wpaFlags() const
{
- return d->connectionInterface->property("WpaFlags").toUInt();
+ if (propertyMap.contains("WpaFlags"))
+ return propertyMap.value("WpaFlags").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceAccessPoint::rsnFlags() const
{
- return d->connectionInterface->property("RsnFlags").toUInt();
+ if (propertyMap.contains("RsnFlags"))
+ return propertyMap.value("RsnFlags").toUInt();
+ return 0;
}
QString QNetworkManagerInterfaceAccessPoint::ssid() const
{
- return d->connectionInterface->property("Ssid").toString();
+ if (propertyMap.contains("Ssid"))
+ return propertyMap.value("Ssid").toString();
+ return QString();
}
quint32 QNetworkManagerInterfaceAccessPoint::frequency() const
{
- return d->connectionInterface->property("Frequency").toUInt();
+ if (propertyMap.contains("Frequency"))
+ return propertyMap.value("Frequency").toUInt();
+ return 0;
}
QString QNetworkManagerInterfaceAccessPoint::hwAddress() const
{
- return d->connectionInterface->property("HwAddress").toString();
+ if (propertyMap.contains("HwAddress"))
+ return propertyMap.value("HwAddress").toString();
+ return QString();
}
quint32 QNetworkManagerInterfaceAccessPoint::mode() const
{
- return d->connectionInterface->property("Mode").toUInt();
+ if (propertyMap.contains("Mode"))
+ return propertyMap.value("Mode").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceAccessPoint::maxBitrate() const
{
- return d->connectionInterface->property("MaxBitrate").toUInt();
+ if (propertyMap.contains("MaxBitrate"))
+ return propertyMap.value("MaxBitrate").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceAccessPoint::strength() const
{
- return d->connectionInterface->property("Strength").toUInt();
+ if (propertyMap.contains("Strength"))
+ return propertyMap.value("Strength").toUInt();
+ return 0;
+}
+
+void QNetworkManagerInterfaceAccessPoint::propertiesSwap(QMap<QString,QVariant> map)
+{
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ propertyMap.insert(i.key(),i.value());
+ }
}
class QNetworkManagerInterfaceDevicePrivate
@@ -291,18 +395,39 @@ public:
};
QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
+
d = new QNetworkManagerInterfaceDevicePrivate();
d->path = deviceObjectPath;
d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE),
d->path,
QLatin1String(NM_DBUS_INTERFACE_DEVICE),
- QDBusConnection::systemBus());
+ QDBusConnection::systemBus(),parent);
if (!d->connectionInterface->isValid()) {
d->valid = false;
return;
}
+ QDBusInterface devicePropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus(),parent);
+
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE);
+ QDBusPendingReply<QVariantMap> propsReply
+ = devicePropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String(NM_DBUS_INTERFACE_DEVICE),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
d->valid = true;
}
@@ -319,35 +444,10 @@ bool QNetworkManagerInterfaceDevice::isValid()
bool QNetworkManagerInterfaceDevice::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
- bool allOk = true;
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper,SIGNAL(pathForStateChanged(QString,quint32)),
- this, SIGNAL(stateChanged(QString,quint32)));
-
- if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_DEVICE),
- QLatin1String("StateChanged"),
- nmDBusHelper,SLOT(deviceStateChanged(quint32)))) {
- allOk = false;
- }
-
- connect(nmDBusHelper, SIGNAL(pathForConnectionsChanged(QStringList)),
- this,SIGNAL(connectionsChanged(QStringList)));
-
- if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT),
- QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>))) ) {
- allOk = false;
- }
-
- return allOk;
+ return true;
}
QDBusInterface *QNetworkManagerInterfaceDevice::connectionInterface() const
@@ -357,33 +457,66 @@ QDBusInterface *QNetworkManagerInterfaceDevice::connectionInterface() const
QString QNetworkManagerInterfaceDevice::udi() const
{
- return d->connectionInterface->property("Udi").toString();
+ if (propertyMap.contains("Udi"))
+ return propertyMap.value("Udi").toString();
+ return QString();
}
QString QNetworkManagerInterfaceDevice::networkInterface() const
{
- return d->connectionInterface->property("Interface").toString();
+ if (propertyMap.contains("Interface"))
+ return propertyMap.value("Interface").toString();
+ return QString();
}
quint32 QNetworkManagerInterfaceDevice::ip4Address() const
{
- return d->connectionInterface->property("Ip4Address").toUInt();
+ if (propertyMap.contains("Ip4Address"))
+ return propertyMap.value("Ip4Address").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceDevice::state() const
{
- return d->connectionInterface->property("State").toUInt();
+ if (propertyMap.contains("State"))
+ return propertyMap.value("State").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceDevice::deviceType() const
{
- return d->connectionInterface->property("DeviceType").toUInt();
+ if (propertyMap.contains("DeviceType"))
+ return propertyMap.value("DeviceType").toUInt();
+ return 0;
}
QDBusObjectPath QNetworkManagerInterfaceDevice::ip4config() const
{
- QVariant prop = d->connectionInterface->property("Ip4Config");
- return prop.value<QDBusObjectPath>();
+ if (propertyMap.contains("Ip4Config"))
+ return propertyMap.value("Ip4Config").value<QDBusObjectPath>();
+ return QDBusObjectPath();
+}
+
+void QNetworkManagerInterfaceDevice::propertiesSwap(QMap<QString,QVariant> map)
+{
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ if (i.key() == QStringLiteral("AvailableConnections")) { //Device
+ const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>();
+ QDBusObjectPath path;
+ QStringList paths;
+ dbusArgs.beginArray();
+ while (!dbusArgs.atEnd()) {
+ dbusArgs >> path;
+ paths << path.path();
+ }
+ dbusArgs.endArray();
+ Q_EMIT connectionsChanged(paths);
+ }
+ propertyMap.insert(i.key(),i.value());
+ }
+ Q_EMIT propertiesChanged(map);
}
class QNetworkManagerInterfaceDeviceWiredPrivate
@@ -395,7 +528,7 @@ public:
};
QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
d = new QNetworkManagerInterfaceDeviceWiredPrivate();
d->path = ifaceDevicePath;
@@ -407,6 +540,27 @@ QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const Q
d->valid = false;
return;
}
+ QDBusInterface deviceWiredPropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus(),parent);
+
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED);
+ QDBusPendingReply<QVariantMap> propsReply
+ = deviceWiredPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
+
d->valid = true;
}
@@ -424,23 +578,9 @@ bool QNetworkManagerInterfaceDeviceWired::isValid()
bool QNetworkManagerInterfaceDeviceWired::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
-
- bool allOk = true;
-
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)),
- this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)));
- if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED),
- QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>))) ) {
- allOk = false;
- }
- return allOk;
+ return true;
}
QDBusInterface *QNetworkManagerInterfaceDeviceWired::connectionInterface() const
@@ -450,17 +590,53 @@ QDBusInterface *QNetworkManagerInterfaceDeviceWired::connectionInterface() const
QString QNetworkManagerInterfaceDeviceWired::hwAddress() const
{
- return d->connectionInterface->property("HwAddress").toString();
+ if (propertyMap.contains("HwAddress"))
+ return propertyMap.value("HwAddress").toString();
+ return QString();
}
quint32 QNetworkManagerInterfaceDeviceWired::speed() const
{
- return d->connectionInterface->property("Speed").toUInt();
+ if (propertyMap.contains("Speed"))
+ return propertyMap.value("Speed").toUInt();
+ return 0;
}
bool QNetworkManagerInterfaceDeviceWired::carrier() const
{
- return d->connectionInterface->property("Carrier").toBool();
+ if (propertyMap.contains("Carrier"))
+ return propertyMap.value("Carrier").toBool();
+ return false;
+}
+
+QStringList QNetworkManagerInterfaceDeviceWired::availableConnections()
+{
+ QStringList list;
+ if (propertyMap.contains("AvailableConnections")) {
+ const QDBusArgument &dbusArgs = propertyMap.value("Carrier").value<QDBusArgument>();
+ QDBusObjectPath path;
+ dbusArgs.beginArray();
+ while (!dbusArgs.atEnd()) {
+ dbusArgs >> path;
+ list << path.path();
+ }
+ dbusArgs.endArray();
+ }
+
+ return list;
+}
+
+void QNetworkManagerInterfaceDeviceWired::propertiesSwap(QMap<QString,QVariant> map)
+{
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ propertyMap.insert(i.key(),i.value());
+ if (i.key() == QStringLiteral("Carrier")) {
+ Q_EMIT carrierChanged(i.value().toBool());
+ }
+ }
+ Q_EMIT propertiesChanged(map);
}
class QNetworkManagerInterfaceDeviceWirelessPrivate
@@ -472,7 +648,7 @@ public:
};
QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
d = new QNetworkManagerInterfaceDeviceWirelessPrivate();
d->path = ifaceDevicePath;
@@ -484,6 +660,43 @@ QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(c
d->valid = false;
return;
}
+
+
+ QDBusPendingReply<QList <QDBusObjectPath> > nmReply
+ = d->connectionInterface->call(QLatin1String("GetAccessPoints"));
+
+ if (!nmReply.isError()) {
+ accessPointsList = nmReply.value();
+ }
+
+ QDBusInterface deviceWirelessPropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus(),parent);
+
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS);
+ QDBusPendingReply<QVariantMap> propsReply
+ = deviceWirelessPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
+
+ QDBusPendingReply<QList<QDBusObjectPath> > reply
+ = d->connectionInterface->asyncCall(QLatin1String("GetAccessPoints"));
+
+ QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(reply);
+ connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(accessPointsFinished(QDBusPendingCallWatcher*)));
+
+
d->valid = true;
}
@@ -498,29 +711,31 @@ bool QNetworkManagerInterfaceDeviceWireless::isValid()
return d->valid;
}
+void QNetworkManagerInterfaceDeviceWireless::slotAccessPointAdded(QDBusObjectPath path)
+{
+ if (path.path().length() > 2)
+ Q_EMIT accessPointAdded(path.path());
+}
+
+void QNetworkManagerInterfaceDeviceWireless::slotAccessPointRemoved(QDBusObjectPath path)
+{
+ if (path.path().length() > 2)
+ Q_EMIT accessPointRemoved(path.path());
+}
+
bool QNetworkManagerInterfaceDeviceWireless::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
QDBusConnection dbusConnection = QDBusConnection::systemBus();
bool allOk = true;
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)),
- this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)));
-
- connect(nmDBusHelper, SIGNAL(pathForAccessPointAdded(QString)),
- this,SIGNAL(accessPointAdded(QString)));
-
- connect(nmDBusHelper, SIGNAL(pathForAccessPointRemoved(QString)),
- this,SIGNAL(accessPointRemoved(QString)));
if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
+ d->path,
QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS),
QLatin1String("AccessPointAdded"),
- nmDBusHelper, SLOT(slotAccessPointAdded(QDBusObjectPath)))) {
+ this, SLOT(slotAccessPointAdded(QDBusObjectPath)))) {
allOk = false;
}
@@ -529,18 +744,10 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections()
d->path,
QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS),
QLatin1String("AccessPointRemoved"),
- nmDBusHelper, SLOT(slotAccessPointRemoved(QDBusObjectPath)))) {
+ this, SLOT(slotAccessPointRemoved(QDBusObjectPath)))) {
allOk = false;
}
-
- if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS),
- QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(slotPropertiesChanged(QMap<QString,QVariant>)))) {
- allOk = false;
- }
if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE),
d->path,
QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS),
@@ -551,6 +758,19 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections()
return allOk;
}
+void QNetworkManagerInterfaceDeviceWireless::accessPointsFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<QList<QDBusObjectPath> > reply(*watcher);
+ watcher->deleteLater();
+ if (!reply.isError()) {
+ accessPointsList = reply.value();
+ }
+
+ for (int i = 0; i < accessPointsList.size(); i++) {
+ Q_EMIT accessPointAdded(accessPointsList.at(i).path());
+ }
+}
+
QDBusInterface *QNetworkManagerInterfaceDeviceWireless::connectionInterface() const
{
return d->connectionInterface;
@@ -558,33 +778,48 @@ QDBusInterface *QNetworkManagerInterfaceDeviceWireless::connectionInterface() co
QList <QDBusObjectPath> QNetworkManagerInterfaceDeviceWireless::getAccessPoints()
{
- QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("GetAccessPoints"));
- return reply.value();
+ if (accessPointsList.isEmpty()) {
+ qWarning() << "Using blocking call!";
+ QDBusReply<QList<QDBusObjectPath> > reply
+ = d->connectionInterface->call(QLatin1String("GetAccessPoints"));
+ accessPointsList = reply.value();
+ }
+ return accessPointsList;
}
QString QNetworkManagerInterfaceDeviceWireless::hwAddress() const
{
- return d->connectionInterface->property("HwAddress").toString();
+ if (propertyMap.contains("HwAddress"))
+ return propertyMap.value("HwAddress").toString();
+ return QString();
}
quint32 QNetworkManagerInterfaceDeviceWireless::mode() const
{
- return d->connectionInterface->property("Mode").toUInt();
+ if (propertyMap.contains("Mode"))
+ return propertyMap.value("Mode").toUInt();
+ return 0;
}
quint32 QNetworkManagerInterfaceDeviceWireless::bitrate() const
{
- return d->connectionInterface->property("Bitrate").toUInt();
+ if (propertyMap.contains("Bitrate"))
+ return propertyMap.value("Bitrate").toUInt();
+ return 0;
}
QDBusObjectPath QNetworkManagerInterfaceDeviceWireless::activeAccessPoint() const
{
- return d->connectionInterface->property("ActiveAccessPoint").value<QDBusObjectPath>();
+ if (propertyMap.contains("ActiveAccessPoint"))
+ return propertyMap.value("ActiveAccessPoint").value<QDBusObjectPath>();
+ return QDBusObjectPath();
}
quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const
{
- return d->connectionInterface->property("WirelelessCapabilities").toUInt();
+ if (propertyMap.contains("WirelelessCapabilities"))
+ return propertyMap.value("WirelelessCapabilities").toUInt();
+ return 0;
}
void QNetworkManagerInterfaceDeviceWireless::scanIsDone()
@@ -597,6 +832,17 @@ void QNetworkManagerInterfaceDeviceWireless::requestScan()
d->connectionInterface->asyncCall(QLatin1String("RequestScan"));
}
+void QNetworkManagerInterfaceDeviceWireless::propertiesSwap(QMap<QString,QVariant> map)
+{
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ propertyMap.insert(i.key(),i.value());
+ if (i.key() == QStringLiteral("ActiveAccessPoint")) { //DeviceWireless
+ Q_EMIT propertiesChanged(map);
+ }
+ }
+}
class QNetworkManagerInterfaceDeviceModemPrivate
{
@@ -607,7 +853,7 @@ public:
};
QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
d = new QNetworkManagerInterfaceDeviceModemPrivate();
d->path = ifaceDevicePath;
@@ -619,6 +865,25 @@ QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const Q
d->valid = false;
return;
}
+ QDBusInterface deviceModemPropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus(),parent);
+
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM);
+ QDBusPendingReply<QVariantMap> propsReply
+ = deviceModemPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
d->valid = true;
}
@@ -639,20 +904,7 @@ bool QNetworkManagerInterfaceDeviceModem::setConnections()
if (!isValid() )
return false;
- bool allOk = true;
-
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)),
- this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)));
- if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM),
- QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(slotDevicePropertiesChanged(QMap<QString,QVariant>))) ) {
- allOk = false;
- }
- return allOk;
+ return true;
}
QDBusInterface *QNetworkManagerInterfaceDeviceModem::connectionInterface() const
@@ -660,14 +912,28 @@ QDBusInterface *QNetworkManagerInterfaceDeviceModem::connectionInterface() const
return d->connectionInterface;
}
-quint32 QNetworkManagerInterfaceDeviceModem::modemCapabilities() const
+QNetworkManagerInterfaceDeviceModem::ModemCapabilities QNetworkManagerInterfaceDeviceModem::modemCapabilities() const
+{
+ if (propertyMap.contains("ModemCapabilities"))
+ return static_cast<QNetworkManagerInterfaceDeviceModem::ModemCapabilities>(propertyMap.value("ModemCapabilities").toUInt());
+ return QNetworkManagerInterfaceDeviceModem::None;
+}
+
+QNetworkManagerInterfaceDeviceModem::ModemCapabilities QNetworkManagerInterfaceDeviceModem::currentCapabilities() const
{
- return d->connectionInterface->property("ModemCapabilities").toUInt();
+ if (propertyMap.contains("CurrentCapabilities"))
+ return static_cast<QNetworkManagerInterfaceDeviceModem::ModemCapabilities>(propertyMap.value("CurrentCapabilities").toUInt());
+ return QNetworkManagerInterfaceDeviceModem::None;
}
-quint32 QNetworkManagerInterfaceDeviceModem::currentCapabilities() const
+void QNetworkManagerInterfaceDeviceModem::propertiesSwap(QMap<QString,QVariant> map)
{
- return d->connectionInterface->property("CurrentCapabilities").toUInt();
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ propertyMap.insert(i.key(),i.value());
+ }
+ Q_EMIT propertiesChanged(map);
}
class QNetworkManagerSettingsPrivate
@@ -691,6 +957,14 @@ QNetworkManagerSettings::QNetworkManagerSettings(const QString &settingsService,
d->valid = false;
return;
}
+
+ QDBusPendingReply<QList <QDBusObjectPath> > nmReply
+ = d->connectionInterface->call(QLatin1String("ListConnections"));
+
+ if (!nmReply.isError()) {
+ connectionsList = nmReply.value();
+ }
+
d->valid = true;
}
@@ -722,10 +996,16 @@ bool QNetworkManagerSettings::setConnections()
QList <QDBusObjectPath> QNetworkManagerSettings::listConnections()
{
- QDBusReply<QList<QDBusObjectPath> > reply = d->connectionInterface->call(QLatin1String("ListConnections"));
- return reply.value();
+ if (connectionsList.isEmpty()) {
+ qWarning() << "Using blocking call!";
+ QDBusReply<QList<QDBusObjectPath> > reply
+ = d->connectionInterface->call(QLatin1String("ListConnections"));
+ connectionsList = reply.value();
+ }
+ return connectionsList;
}
+
QString QNetworkManagerSettings::getConnectionByUuid(const QString &uuid)
{
QList<QVariant> argumentList;
@@ -751,7 +1031,7 @@ public:
};
QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
qDBusRegisterMetaType<QNmSettingsMap>();
d = new QNetworkManagerSettingsConnectionPrivate();
@@ -766,8 +1046,12 @@ QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QStri
return;
}
d->valid = true;
- QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call(QLatin1String("GetSettings"));
- d->settingsMap = rep.value();
+
+ QDBusPendingReply<QNmSettingsMap> nmReply
+ = d->connectionInterface->call(QLatin1String("GetSettings"));
+ if (!nmReply.isError()) {
+ d->settingsMap = nmReply.value();
+ }
}
QNetworkManagerSettingsConnection::~QNetworkManagerSettingsConnection()
@@ -783,7 +1067,7 @@ bool QNetworkManagerSettingsConnection::isValid()
bool QNetworkManagerSettingsConnection::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
QDBusConnection dbusConnection = QDBusConnection::systemBus();
@@ -796,21 +1080,21 @@ bool QNetworkManagerSettingsConnection::setConnections()
allOk = false;
}
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForSettingsRemoved(QString)),
- this,SIGNAL(removed(QString)));
-
if (!dbusConnection.connect(d->service,
d->path,
QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION),
QLatin1String("Removed"),
- nmDBusHelper, SIGNAL(slotSettingsRemoved()))) {
+ this, SIGNAL(slotSettingsRemoved()))) {
allOk = false;
}
return allOk;
}
+void QNetworkManagerSettingsConnection::slotSettingsRemoved()
+{
+ Q_EMIT removed(d->path);
+}
+
QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const
{
return d->connectionInterface;
@@ -818,8 +1102,11 @@ QDBusInterface *QNetworkManagerSettingsConnection::connectionInterface() const
QNmSettingsMap QNetworkManagerSettingsConnection::getSettings()
{
- QDBusReply< QNmSettingsMap > rep = d->connectionInterface->call(QLatin1String("GetSettings"));
- d->settingsMap = rep.value();
+ if (d->settingsMap.isEmpty()) {
+ qWarning() << "Using blocking call!";
+ QDBusReply<QNmSettingsMap> reply = d->connectionInterface->call(QLatin1String("GetSettings"));
+ d->settingsMap = reply.value();
+ }
return d->settingsMap;
}
@@ -832,6 +1119,8 @@ NMDeviceType QNetworkManagerSettingsConnection::getType()
return DEVICE_TYPE_ETHERNET;
else if (devType == QLatin1String("802-11-wireless"))
return DEVICE_TYPE_WIFI;
+ else if (devType == QLatin1String("gsm"))
+ return DEVICE_TYPE_MODEM;
else
return DEVICE_TYPE_UNKNOWN;
}
@@ -908,7 +1197,7 @@ public:
};
QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString &activeConnectionObjectPath, QObject *parent)
- : QObject(parent), nmDBusHelper(0)
+ : QObject(parent)
{
d = new QNetworkManagerConnectionActivePrivate();
d->path = activeConnectionObjectPath;
@@ -920,6 +1209,29 @@ QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString &
d->valid = false;
return;
}
+ QDBusInterface connectionActivePropertiesInterface(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String("org.freedesktop.DBus.Properties"),
+ QDBusConnection::systemBus());
+
+
+ QList<QVariant> argumentList;
+ argumentList << QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION);
+ QDBusPendingReply<QVariantMap> propsReply
+ = connectionActivePropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"),
+ argumentList);
+
+ if (!propsReply.isError()) {
+ propertyMap = propsReply.value();
+ } else {
+ qWarning() << propsReply.error().message();
+ }
+
+ QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
+ d->path,
+ QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION),
+ QLatin1String("PropertiesChanged"),
+ this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
d->valid = true;
}
@@ -936,24 +1248,10 @@ bool QNetworkManagerConnectionActive::isValid()
bool QNetworkManagerConnectionActive::setConnections()
{
- if(!isValid() )
+ if (!isValid())
return false;
- bool allOk = true;
- delete nmDBusHelper;
- nmDBusHelper = new QNmDBusHelper(this);
- connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap<QString,QVariant>)),
- this,SIGNAL(propertiesChanged(QString,QMap<QString,QVariant>)));
-
- if (!QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE),
- d->path,
- QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION),
- QLatin1String("PropertiesChanged"),
- nmDBusHelper,SLOT(activeConnectionPropertiesChanged(QMap<QString,QVariant>))) ) {
- allOk = false;
- }
-
- return allOk;
+ return true;
}
QDBusInterface *QNetworkManagerConnectionActive::connectionInterface() const
@@ -963,30 +1261,70 @@ QDBusInterface *QNetworkManagerConnectionActive::connectionInterface() const
QDBusObjectPath QNetworkManagerConnectionActive::connection() const
{
- QVariant prop = d->connectionInterface->property("Connection");
- return prop.value<QDBusObjectPath>();
+ if (propertyMap.contains("Connection"))
+ return propertyMap.value("Connection").value<QDBusObjectPath>();
+ return QDBusObjectPath();
}
QDBusObjectPath QNetworkManagerConnectionActive::specificObject() const
{
- QVariant prop = d->connectionInterface->property("SpecificObject");
- return prop.value<QDBusObjectPath>();
+ if (propertyMap.contains("SpecificObject"))
+ return propertyMap.value("SpecificObject").value<QDBusObjectPath>();
+ return QDBusObjectPath();
}
-QList<QDBusObjectPath> QNetworkManagerConnectionActive::devices() const
+QStringList QNetworkManagerConnectionActive::devices() const
{
- QVariant prop = d->connectionInterface->property("Devices");
- return prop.value<QList<QDBusObjectPath> >();
+ QStringList list;
+ if (propertyMap.contains("Devices")) {
+ const QDBusArgument &dbusArgs = propertyMap.value("Devices").value<QDBusArgument>();
+ QDBusObjectPath path;
+
+ dbusArgs.beginArray();
+ while (!dbusArgs.atEnd()) {
+ dbusArgs >> path;
+ list.append(path.path());
+ }
+ dbusArgs.endArray();
+ }
+ return list;
}
quint32 QNetworkManagerConnectionActive::state() const
{
- return d->connectionInterface->property("State").toUInt();
+ if (propertyMap.contains("State"))
+ return propertyMap.value("State").toUInt();
+ return 0;
}
bool QNetworkManagerConnectionActive::defaultRoute() const
{
- return d->connectionInterface->property("Default").toBool();
+ if (propertyMap.contains("Default"))
+ return propertyMap.value("Default").toBool();
+ return false;
+}
+
+bool QNetworkManagerConnectionActive::default6Route() const
+{
+ if (propertyMap.contains("Default6"))
+ return propertyMap.value("Default6").toBool();
+ return false;
+}
+
+void QNetworkManagerConnectionActive::propertiesSwap(QMap<QString,QVariant> map)
+{
+ QMapIterator<QString, QVariant> i(map);
+ while (i.hasNext()) {
+ i.next();
+ propertyMap.insert(i.key(),i.value());
+ if (i.key() == QStringLiteral("State")) {
+ quint32 state = i.value().toUInt();
+ if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
+ || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
+ Q_EMIT propertiesChanged(map);
+ }
+ }
+ }
}
class QNetworkManagerIp4ConfigPrivate
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
index 11ddaf7088..e645159d71 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
@@ -56,7 +56,6 @@
#include <QtDBus/QDBusObjectPath>
#include <QtDBus/QDBusContext>
#include <QMap>
-#include "qnmdbushelper.h"
#ifndef QT_NO_DBUS
@@ -89,7 +88,7 @@ typedef enum
NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0,
NM_ACTIVE_CONNECTION_STATE_ACTIVATING,
NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
- NM_ACTIVE_CONNECTION_STATE_DEACTIVATED
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4
} NMActiveConnectionState;
#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
@@ -135,12 +134,23 @@ class QNetworkManagerInterface : public QObject
Q_OBJECT
public:
+ typedef enum
+ {
+ NM_STATE_UNKNOWN = 0,
+ NM_STATE_ASLEEP = 10,
+ NM_STATE_DISCONNECTED = 20,
+ NM_STATE_DISCONNECTING = 30,
+ NM_STATE_CONNECTING = 40,
+ NM_STATE_CONNECTED_LOCAL = 50,
+ NM_STATE_CONNECTED_SITE = 60,
+ NM_STATE_CONNECTED_GLOBAL = 70
+ } NMState;
QNetworkManagerInterface(QObject *parent = 0);
~QNetworkManagerInterface();
- QList <QDBusObjectPath> getDevices() const;
- void activateConnection(const QString &serviceName, QDBusObjectPath connection, QDBusObjectPath device, QDBusObjectPath specificObject);
+ QList <QDBusObjectPath> getDevices();
+ void activateConnection(QDBusObjectPath connection,QDBusObjectPath device, QDBusObjectPath specificObject);
void deactivateConnection(QDBusObjectPath connectionPath) const;
QDBusObjectPath path() const;
@@ -149,21 +159,28 @@ public:
bool wirelessEnabled() const;
bool wirelessHardwareEnabled() const;
QList <QDBusObjectPath> activeConnections() const;
- quint32 state();
+ NMState state();
+ QString version() const;
bool setConnections();
bool isValid();
Q_SIGNALS:
void deviceAdded(QDBusObjectPath);
void deviceRemoved(QDBusObjectPath);
- void propertiesChanged( const QString &, QMap<QString,QVariant>);
- void stateChanged(const QString&, quint32);
+ void propertiesChanged(QMap<QString,QVariant>);
+ void stateChanged(quint32);
void activationFinished(QDBusPendingCallWatcher*);
+ void propertiesReady();
+ void devicesListReady();
private Q_SLOTS:
+ void propertiesSwap(QMap<QString,QVariant>);
+
private:
QNetworkManagerInterfacePrivate *d;
- QNmDBusHelper *nmDBusHelper;
+ QVariantMap propertyMap;
+ QList<QDBusObjectPath> devicesPathList;
+
};
class QNetworkManagerInterfaceAccessPointPrivate;
@@ -228,11 +245,14 @@ public:
Q_SIGNALS:
void propertiesChanged(QMap <QString,QVariant>);
- void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void propertiesReady();
+
+private Q_SLOTS:
+ void propertiesSwap(QMap<QString,QVariant>);
+
private:
QNetworkManagerInterfaceAccessPointPrivate *d;
- QNmDBusHelper *nmDBusHelper;
-
+ QVariantMap propertyMap;
};
class QNetworkManagerInterfaceDevicePrivate;
@@ -258,11 +278,14 @@ public:
Q_SIGNALS:
void stateChanged(const QString &, quint32);
- void propertiesChanged(const QString &, QMap<QString,QVariant>);
+ void propertiesChanged(QMap<QString,QVariant>);
void connectionsChanged(QStringList);
+ void propertiesReady();
+private Q_SLOTS:
+ void propertiesSwap(QMap<QString,QVariant>);
private:
QNetworkManagerInterfaceDevicePrivate *d;
- QNmDBusHelper *nmDBusHelper;
+ QVariantMap propertyMap;
};
class QNetworkManagerInterfaceDeviceWiredPrivate;
@@ -282,12 +305,19 @@ public:
bool carrier() const;
bool setConnections();
bool isValid();
+ QStringList availableConnections();
Q_SIGNALS:
- void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void propertiesChanged(QMap<QString,QVariant>);
+ void propertiesReady();
+ void carrierChanged(bool);
+
+private Q_SLOTS:
+ void propertiesSwap(QMap<QString,QVariant>);
+
private:
QNetworkManagerInterfaceDeviceWiredPrivate *d;
- QNmDBusHelper *nmDBusHelper;
+ QVariantMap propertyMap;
};
class QNetworkManagerInterfaceDeviceWirelessPrivate;
@@ -325,15 +355,26 @@ public:
void requestScan();
Q_SIGNALS:
- void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void propertiesChanged(QMap<QString,QVariant>);
void accessPointAdded(const QString &);
void accessPointRemoved(const QString &);
void scanDone();
+ void propertiesReady();
+ void accessPointsReady();
+
private Q_SLOTS:
void scanIsDone();
+ void propertiesSwap(QMap<QString,QVariant>);
+
+ void slotAccessPointAdded(QDBusObjectPath);
+ void slotAccessPointRemoved(QDBusObjectPath);
+
+ void accessPointsFinished(QDBusPendingCallWatcher *watcher);
+
private:
QNetworkManagerInterfaceDeviceWirelessPrivate *d;
- QNmDBusHelper *nmDBusHelper;
+ QVariantMap propertyMap;
+ QList <QDBusObjectPath> accessPointsList;
};
class QNetworkManagerInterfaceDeviceModemPrivate;
@@ -350,6 +391,7 @@ public:
Gsm_Umts = 0x4,
Lte = 0x08
};
+ Q_DECLARE_FLAGS(ModemCapabilities, ModemCapability)
explicit QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath,
QObject *parent = 0);
@@ -361,16 +403,22 @@ public:
bool setConnections();
bool isValid();
- quint32 modemCapabilities() const;
- quint32 currentCapabilities() const;
+ ModemCapabilities modemCapabilities() const;
+ ModemCapabilities currentCapabilities() const;
Q_SIGNALS:
- void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void propertiesChanged(QMap<QString,QVariant>);
+ void propertiesReady();
+
+private Q_SLOTS:
+ void propertiesSwap(QMap<QString,QVariant>);
+
private:
QNetworkManagerInterfaceDeviceModemPrivate *d;
- QNmDBusHelper *nmDBusHelper;
+ QVariantMap propertyMap;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkManagerInterfaceDeviceModem::ModemCapabilities)
class QNetworkManagerSettingsPrivate;
class QNetworkManagerSettings : public QObject
@@ -390,8 +438,10 @@ public:
Q_SIGNALS:
void newConnection(QDBusObjectPath);
+ void connectionsListReady();
private:
QNetworkManagerSettingsPrivate *d;
+ QList <QDBusObjectPath> connectionsList;
};
class QNetworkManagerSettingsConnectionPrivate;
@@ -418,12 +468,14 @@ public:
bool isValid();
Q_SIGNALS:
-
void updated();
void removed(const QString &path);
+ void settingsReady();
+
+private Q_SLOTS:
+ void slotSettingsRemoved();
private:
- QNmDBusHelper *nmDBusHelper;
QNetworkManagerSettingsConnectionPrivate *d;
};
@@ -444,22 +496,26 @@ public:
~ QNetworkManagerConnectionActive();
QDBusInterface *connectionInterface() const;
- QString serviceName() const;
QDBusObjectPath connection() const;
QDBusObjectPath specificObject() const;
- QList<QDBusObjectPath> devices() const;
+ QStringList devices() const;
quint32 state() const;
bool defaultRoute() const;
+ bool default6Route() const;
bool setConnections();
bool isValid();
Q_SIGNALS:
- void propertiesChanged(QList<QDBusObjectPath>);
- void propertiesChanged( const QString &, QMap<QString,QVariant>);
+ void propertiesChanged(QMap<QString,QVariant>);
+ void propertiesReady();
+
+private Q_SLOTS:
+ void propertiesSwap(QMap<QString,QVariant>);
+
private:
QNetworkManagerConnectionActivePrivate *d;
- QNmDBusHelper *nmDBusHelper;
+ QVariantMap propertyMap;
};
class QNetworkManagerIp4ConfigPrivate;
diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp b/src/plugins/bearer/networkmanager/qnmdbushelper.cpp
deleted file mode 100644
index 0decfd78b9..0000000000
--- a/src/plugins/bearer/networkmanager/qnmdbushelper.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// this class is for helping qdbus get stuff
-
-#include "qnmdbushelper.h"
-
-#include "qnetworkmanagerservice.h"
-
-#include <QDBusError>
-#include <QDBusInterface>
-#include <QDBusMessage>
-#include <QDBusReply>
-
-#include <QDebug>
-
-#ifndef QT_NO_DBUS
-
-QT_BEGIN_NAMESPACE
-
-QNmDBusHelper::QNmDBusHelper(QObject * parent)
- : QObject(parent)
-{
-}
-
-QNmDBusHelper::~QNmDBusHelper()
-{
-}
-
-void QNmDBusHelper::deviceStateChanged(quint32 state)
- {
- QDBusMessage msg = this->message();
- if (state == NM_DEVICE_STATE_ACTIVATED
- || state == NM_DEVICE_STATE_DISCONNECTED
- || state == NM_DEVICE_STATE_UNAVAILABLE
- || state == NM_DEVICE_STATE_FAILED) {
- emit pathForStateChanged(msg.path(), state);
- }
- }
-
-void QNmDBusHelper::slotAccessPointAdded(QDBusObjectPath path)
-{
- if (path.path().length() > 2)
- emit pathForAccessPointAdded(path.path());
-}
-
-void QNmDBusHelper::slotAccessPointRemoved(QDBusObjectPath path)
-{
- if (path.path().length() > 2)
- emit pathForAccessPointRemoved(path.path());
-}
-
-void QNmDBusHelper::slotPropertiesChanged(QMap<QString,QVariant> map)
-{
- QDBusMessage msg = this->message();
- QMapIterator<QString, QVariant> i(map);
- while (i.hasNext()) {
- i.next();
- if (i.key() == QStringLiteral("State")) {
- quint32 state = i.value().toUInt();
- if (state == NM_DEVICE_STATE_ACTIVATED
- || state == NM_DEVICE_STATE_DISCONNECTED
- || state == NM_DEVICE_STATE_UNAVAILABLE
- || state == NM_DEVICE_STATE_FAILED) {
- emit pathForPropertiesChanged(msg.path(), map);
- }
- } else if (i.key() == QStringLiteral("ActiveAccessPoint")) {
- emit pathForPropertiesChanged(msg.path(), map);
- } else if (i.key() == QStringLiteral("ActiveConnections")) {
- emit pathForPropertiesChanged(msg.path(), map);
- } else if (i.key() == QStringLiteral("AvailableConnections")) {
- const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>();
- QDBusObjectPath path;
- QStringList paths;
- dbusArgs.beginArray();
- while (!dbusArgs.atEnd()) {
- dbusArgs >> path;
- paths << path.path();
- }
- dbusArgs.endArray();
- emit pathForConnectionsChanged(paths);
- }
- }
-}
-
-void QNmDBusHelper::slotSettingsRemoved()
-{
- QDBusMessage msg = this->message();
- emit pathForSettingsRemoved(msg.path());
-}
-
-void QNmDBusHelper::activeConnectionPropertiesChanged(QMap<QString,QVariant> map)
-{
- QDBusMessage msg = this->message();
- QMapIterator<QString, QVariant> i(map);
- while (i.hasNext()) {
- i.next();
- if (i.key() == QStringLiteral("State")) {
- quint32 state = i.value().toUInt();
- if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
- || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
- emit pathForPropertiesChanged(msg.path(), map);
- }
- }
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp
index 1db59fec94..c5adc98af7 100644
--- a/src/plugins/bearer/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/qnetworksession_impl.cpp
@@ -366,7 +366,8 @@ void QNetworkSessionPrivateImpl::networkConfigurationsChanged()
else
updateStateFromActiveConfig();
- startTime = engine->startTime(activeConfig.identifier());
+ if (engine)
+ startTime = engine->startTime(activeConfig.identifier());
}
void QNetworkSessionPrivateImpl::configurationChanged(QNetworkConfigurationPrivatePointer config)
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
index 9bc53ed5c0..ec8c746b2d 100644
--- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qibustypes.h"
-#include <qtextformat.h>
#include <QtDBus>
#include <QHash>
@@ -134,7 +133,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusAttribute &a
return argument;
}
-QTextFormat QIBusAttribute::format() const
+QTextCharFormat QIBusAttribute::format() const
{
QTextCharFormat fmt;
switch (type) {
@@ -225,11 +224,32 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at
QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
{
+ QHash<QPair<int, int>, QTextCharFormat> rangeAttrs;
+
+ // Merge text fomats for identical ranges into a single QTextFormat.
+ for (int i = 0; i < attributes.size(); ++i) {
+ const QIBusAttribute &attr = attributes.at(i);
+ const QTextCharFormat &format = attr.format();
+
+ if (format.isValid()) {
+ const QPair<int, int> range(attr.start, attr.end);
+ rangeAttrs[range].merge(format);
+ }
+ }
+
+ // Assemble list in original attribute order.
QList<QInputMethodEvent::Attribute> imAttrs;
+
for (int i = 0; i < attributes.size(); ++i) {
const QIBusAttribute &attr = attributes.at(i);
- imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format());
+ const QTextFormat &format = attr.format();
+
+ imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ attr.start,
+ attr.end - attr.start,
+ format.isValid() ? rangeAttrs[QPair<int, int>(attr.start, attr.end)] : format);
}
+
return imAttrs;
}
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h
index 2ec3b019ff..96791b17a1 100644
--- a/src/plugins/platforminputcontexts/ibus/qibustypes.h
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h
@@ -36,6 +36,7 @@
#include <qvector.h>
#include <qevent.h>
#include <QDBusArgument>
+#include <QTextCharFormat>
QT_BEGIN_NAMESPACE
@@ -70,7 +71,7 @@ public:
QIBusAttribute();
~QIBusAttribute();
- QTextFormat format() const;
+ QTextCharFormat format() const;
Type type;
quint32 value;
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 536415339f..62da60ab92 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -48,10 +48,6 @@ using namespace QtAndroid;
namespace QtAndroidInput
{
- static jmethodID m_showSoftwareKeyboardMethodID = 0;
- static jmethodID m_resetSoftwareKeyboardMethodID = 0;
- static jmethodID m_hideSoftwareKeyboardMethodID = 0;
- static jmethodID m_updateSelectionMethodID = 0;
static bool m_ignoreMouseEvents = false;
static bool m_softwareKeyboardVisible = false;
@@ -62,30 +58,28 @@ namespace QtAndroidInput
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
#endif
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
- selStart, selEnd, candidatesStart, candidatesEnd);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
+ "updateSelection",
+ "(IIII)V",
+ selStart,
+ selEnd,
+ candidatesStart,
+ candidatesEnd);
}
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints)
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(),
- m_showSoftwareKeyboardMethodID,
- left,
- top,
- width,
- height,
- inputHints);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
+ "showSoftwareKeyboard",
+ "(IIIII)V",
+ left,
+ top,
+ width,
+ height,
+ inputHints);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints;
#endif
@@ -93,11 +87,7 @@ namespace QtAndroidInput
void resetSoftwareKeyboard()
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_resetSoftwareKeyboardMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetSoftwareKeyboard");
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ RESETSOFTWAREKEYBOARD";
#endif
@@ -105,11 +95,7 @@ namespace QtAndroidInput
void hideSoftwareKeyboard()
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_hideSoftwareKeyboardMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "hideSoftwareKeyboard");
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ HIDESOFTWAREKEYBOARD";
#endif
@@ -722,13 +708,6 @@ namespace QtAndroidInput
{"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged}
};
-#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
- VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
- if (!VAR) { \
- __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
- return false; \
- }
-
bool registerNatives(JNIEnv *env)
{
jclass appClass = QtAndroid::applicationClass();
@@ -738,10 +717,6 @@ namespace QtAndroidInput
return false;
}
- GET_AND_CHECK_STATIC_METHOD(m_showSoftwareKeyboardMethodID, appClass, "showSoftwareKeyboard", "(IIIII)V");
- GET_AND_CHECK_STATIC_METHOD(m_resetSoftwareKeyboardMethodID, appClass, "resetSoftwareKeyboard", "()V");
- GET_AND_CHECK_STATIC_METHOD(m_hideSoftwareKeyboardMethodID, appClass, "hideSoftwareKeyboard", "()V");
- GET_AND_CHECK_STATIC_METHOD(m_updateSelectionMethodID, appClass, "updateSelection", "(IIII)V");
return true;
}
}
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 235e004904..df0a8c56cb 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -80,7 +80,6 @@ static jmethodID m_createBitmapMethodID = Q_NULLPTR;
static jobject m_ARGB_8888_BitmapConfigValue = Q_NULLPTR;
static jobject m_RGB_565_BitmapConfigValue = Q_NULLPTR;
-jmethodID m_setFullScreenMethodID = Q_NULLPTR;
static bool m_statusBarShowing = true;
static jclass m_bitmapDrawableClass = Q_NULLPTR;
@@ -182,13 +181,7 @@ namespace QtAndroid
if (m_statusBarShowing)
return;
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv) {
- qWarning("Failed to get JNI Environment.");
- return;
- }
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, false);
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "setFullScreen", "(Z)V", false);
m_statusBarShowing = true;
}
@@ -197,13 +190,7 @@ namespace QtAndroid
if (!m_statusBarShowing)
return;
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv) {
- qWarning("Failed to get JNI Environment.");
- return;
- }
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, true);
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "setFullScreen", "(Z)V", true);
m_statusBarShowing = false;
}
@@ -453,16 +440,9 @@ static void *startMainMethod(void */*data*/)
if (res < 0)
qWarning() << "dlclose failed:" << dlerror();
}
- m_mainLibraryHnd = Q_NULLPTR;
- m_main = Q_NULLPTR;
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv)
- return 0;
- if (m_applicationClass) {
- jmethodID quitApp = env.jniEnv->GetStaticMethodID(m_applicationClass, "quitApp", "()V");
- env.jniEnv->CallStaticVoidMethod(m_applicationClass, quitApp);
- }
+ if (m_applicationClass)
+ QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "quitApp", "()V");
return 0;
}
@@ -723,7 +703,6 @@ static int registerNatives(JNIEnv *env)
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
m_applicationClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V");
if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 01330ce283..8cf9274857 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -85,29 +85,6 @@ namespace QtAndroid
jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
- struct AttachedJNIEnv
- {
- AttachedJNIEnv()
- {
- attached = false;
- if (QtAndroid::javaVM()->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
- if (QtAndroid::javaVM()->AttachCurrentThread(&jniEnv, NULL) < 0) {
- __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
- jniEnv = Q_NULLPTR;
- return;
- }
- attached = true;
- }
- }
-
- ~AttachedJNIEnv()
- {
- if (attached)
- QtAndroid::javaVM()->DetachCurrentThread();
- }
- bool attached;
- JNIEnv *jniEnv;
- };
const char *classErrorMsgFmt();
const char *methodErrorMsgFmt();
const char *qtTagText();
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index 1251bbf193..36c349f6b4 100644
--- a/src/plugins/platforms/android/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -44,6 +44,7 @@
#include <QSet>
#include <QWindow>
#include <QtCore/private/qjnihelpers_p.h>
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
@@ -61,9 +62,6 @@ namespace QtAndroidMenu
static QMutex menuBarMutex(QMutex::Recursive);
static jmethodID openContextMenuMethodID = 0;
- static jmethodID closeContextMenuMethodID = 0;
- static jmethodID resetOptionsMenuMethodID = 0;
- static jmethodID openOptionsMenuMethodID = 0;
static jmethodID clearMenuMethodID = 0;
static jmethodID addMenuItemMethodID = 0;
@@ -78,16 +76,12 @@ namespace QtAndroidMenu
void resetMenuBar()
{
- AttachedJNIEnv env;
- if (env.jniEnv)
- env.jniEnv->CallStaticVoidMethod(applicationClass(), resetOptionsMenuMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
}
void openOptionsMenu()
{
- AttachedJNIEnv env;
- if (env.jniEnv)
- env.jniEnv->CallStaticVoidMethod(applicationClass(), openOptionsMenuMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
}
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
@@ -103,22 +97,14 @@ namespace QtAndroidMenu
visibleMenu = menu;
menu->aboutToShow();
- if (env) {
- env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
- } else {
- AttachedJNIEnv aenv;
- if (aenv.jniEnv)
- aenv.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
- }
+ env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
}
void hideContextMenu(QAndroidPlatformMenu *menu)
{
QMutexLocker lock(&visibleMenuMutex);
if (visibleMenu == menu) {
- AttachedJNIEnv env;
- if (env.jniEnv)
- env.jniEnv->CallStaticVoidMethod(applicationClass(), closeContextMenuMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "closeContextMenu");
pendingContextMenus.clear();
} else {
pendingContextMenus.removeOne(menu);
@@ -430,9 +416,6 @@ namespace QtAndroidMenu
}
GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "(IIII)V");
- GET_AND_CHECK_STATIC_METHOD(closeContextMenuMethodID, appClass, "closeContextMenu", "()V");
- GET_AND_CHECK_STATIC_METHOD(resetOptionsMenuMethodID, appClass, "resetOptionsMenu", "()V");
- GET_AND_CHECK_STATIC_METHOD(openOptionsMenuMethodID, appClass, "openOptionsMenu", "()V");
jclass clazz;
FIND_AND_CHECK_CLASS("android/view/Menu");
diff --git a/src/plugins/platforms/android/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h
index c54eb37f37..f85db9ff86 100644
--- a/src/plugins/platforms/android/androidjnimenu.h
+++ b/src/plugins/platforms/android/androidjnimenu.h
@@ -50,7 +50,7 @@ namespace QtAndroidMenu
{
// Menu support
void openOptionsMenu();
- void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env = 0);
+ void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env);
void hideContextMenu(QAndroidPlatformMenu *menu);
void syncMenu(QAndroidPlatformMenu *menu);
void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu);
diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
index fb73db8455..2605ec9901 100644
--- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp
+++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
@@ -44,6 +44,7 @@ QAndroidPlatformClipboard::QAndroidPlatformClipboard()
QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode)
{
+ Q_UNUSED(mode);
Q_ASSERT(supportsMode(mode));
m_mimeData.setText(QtAndroidClipboard::hasClipboardText()
? QtAndroidClipboard::clipboardText()
@@ -53,8 +54,8 @@ QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode)
void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
- Q_ASSERT(supportsMode(mode));
- QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString());
+ if (supportsMode(mode))
+ QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString());
if (data != 0)
data->deleteLater();
}
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 8a3a958d3b..07bdf95bf4 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -78,10 +78,24 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
return QtAndroid::javaVM();
if (resource == "QtActivity")
return QtAndroid::activity();
- if (resource == "AndroidStylePalettes")
- return &m_palettes;
- if (resource == "AndroidStyleFonts")
- return &m_fonts;
+ if (resource == "AndroidStyleData") {
+ if (m_androidStyle)
+ return &m_androidStyle->m_styleData;
+ else
+ return Q_NULLPTR;
+ }
+ if (resource == "AndroidStandardPalette") {
+ if (m_androidStyle)
+ return &m_androidStyle->m_standardPalette;
+ else
+ return Q_NULLPTR;
+ }
+ if (resource == "AndroidQWidgetFonts") {
+ if (m_androidStyle)
+ return &m_androidStyle->m_QWidgetsFonts;
+ else
+ return Q_NULLPTR;
+ }
if (resource == "AndroidDeviceName") {
static QString deviceName = QtAndroid::deviceName();
return &deviceName;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 13c98442e9..7b4ab08847 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -44,6 +44,8 @@
#include "qandroidplatformscreen.h"
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QDesktopWidget;
@@ -51,12 +53,12 @@ class QAndroidPlatformServices;
class QAndroidSystemLocale;
class QPlatformAccessibility;
+struct AndroidStyle;
class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
{
public:
void *nativeResourceForIntegration(const QByteArray &resource);
- QHash<int, QPalette> m_palettes;
- QHash<int, QFont> m_fonts;
+ std::shared_ptr<AndroidStyle> m_androidStyle;
};
class QAndroidPlatformIntegration : public QPlatformIntegration
diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp
index f3505fac3c..8f992f6bea 100644
--- a/src/plugins/platforms/android/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp
@@ -34,6 +34,7 @@
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
#include "androidjnimenu.h"
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
@@ -140,7 +141,7 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
Q_UNUSED(parentWindow);
Q_UNUSED(item);
setVisible(true);
- QtAndroidMenu::showContextMenu(this, targetRect);
+ QtAndroidMenu::showContextMenu(this, targetRect, QJNIEnvironmentPrivate());
}
QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 914de9d270..b955cff44d 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -37,17 +37,281 @@
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
#include "qandroidplatformdialoghelpers.h"
-#include <QVariant>
-#include <QFileInfo>
+
#include <QCoreApplication>
+#include <QDebug>
+#include <QFileInfo>
+#include <QJsonDocument>
+#include <QVariant>
+
#include <private/qguiapplication_p.h>
#include <qandroidplatformintegration.h>
QT_BEGIN_NAMESPACE
+namespace {
+ const int textStyle_bold = 1;
+ const int textStyle_italic = 2;
+
+ const int typeface_sans = 1;
+ const int typeface_serif = 2;
+ const int typeface_monospace = 3;
+}
+
+static int fontType(const QString &androidControl)
+{
+ if (androidControl == QLatin1String("defaultStyle"))
+ return QPlatformTheme::SystemFont;
+ if (androidControl == QLatin1String("textViewStyle"))
+ return QPlatformTheme::LabelFont;
+ else if (androidControl == QLatin1String("buttonStyle"))
+ return QPlatformTheme::PushButtonFont;
+ else if (androidControl == QLatin1String("checkboxStyle"))
+ return QPlatformTheme::CheckBoxFont;
+ else if (androidControl == QLatin1String("radioButtonStyle"))
+ return QPlatformTheme::RadioButtonFont;
+ else if (androidControl == QLatin1String("simple_list_item_single_choice"))
+ return QPlatformTheme::ItemViewFont;
+ else if (androidControl == QLatin1String("simple_spinner_dropdown_item"))
+ return QPlatformTheme::ComboMenuItemFont;
+ else if (androidControl == QLatin1String("spinnerStyle"))
+ return QPlatformTheme::ComboLineEditFont;
+ else if (androidControl == QLatin1String("simple_list_item"))
+ return QPlatformTheme::ListViewFont;
+ return -1;
+}
+
+static int paletteType(const QString &androidControl)
+{
+ if (androidControl == QLatin1String("defaultStyle"))
+ return QPlatformTheme::SystemPalette;
+ if (androidControl == QLatin1String("textViewStyle"))
+ return QPlatformTheme::LabelPalette;
+ else if (androidControl == QLatin1String("buttonStyle"))
+ return QPlatformTheme::ButtonPalette;
+ else if (androidControl == QLatin1String("checkboxStyle"))
+ return QPlatformTheme::CheckBoxPalette;
+ else if (androidControl == QLatin1String("radioButtonStyle"))
+ return QPlatformTheme::RadioButtonPalette;
+ else if (androidControl == QLatin1String("simple_list_item_single_choice"))
+ return QPlatformTheme::ItemViewPalette;
+ else if (androidControl == QLatin1String("editTextStyle"))
+ return QPlatformTheme::TextLineEditPalette;
+ else if (androidControl == QLatin1String("spinnerStyle"))
+ return QPlatformTheme::ComboBoxPalette;
+ return -1;
+}
+
+static void setPaletteColor(const QVariantMap &object,
+ QPalette &palette,
+ QPalette::ColorRole role)
+{
+ // QPalette::Active -> ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
+ palette.setColor(QPalette::Active,
+ role,
+ QRgb(object.value(QLatin1String("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt()));
+
+ // QPalette::Inactive -> ENABLED_STATE_SET
+ palette.setColor(QPalette::Inactive,
+ role,
+ QRgb(object.value(QLatin1String("ENABLED_STATE_SET")).toInt()));
+
+ // QPalette::Disabled -> EMPTY_STATE_SET
+ palette.setColor(QPalette::Disabled,
+ role,
+ QRgb(object.value(QLatin1String("EMPTY_STATE_SET")).toInt()));
+
+ palette.setColor(QPalette::Current, role, palette.color(QPalette::Active, role));
+
+ if (role == QPalette::WindowText) {
+ // QPalette::BrightText -> PRESSED
+ // QPalette::Active -> PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
+ palette.setColor(QPalette::Active,
+ QPalette::BrightText,
+ QRgb(object.value(QLatin1String("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt()));
+
+ // QPalette::Inactive -> PRESSED_ENABLED_STATE_SET
+ palette.setColor(QPalette::Inactive,
+ QPalette::BrightText,
+ QRgb(object.value(QLatin1String("PRESSED_ENABLED_STATE_SET")).toInt()));
+
+ // QPalette::Disabled -> PRESSED_STATE_SET
+ palette.setColor(QPalette::Disabled,
+ QPalette::BrightText,
+ QRgb(object.value(QLatin1String("PRESSED_STATE_SET")).toInt()));
+
+ palette.setColor(QPalette::Current, QPalette::BrightText, palette.color(QPalette::Active, QPalette::BrightText));
+
+ // QPalette::HighlightedText -> SELECTED
+ // QPalette::Active -> ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET
+ palette.setColor(QPalette::Active,
+ QPalette::HighlightedText,
+ QRgb(object.value(QLatin1String("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET")).toInt()));
+
+ // QPalette::Inactive -> ENABLED_SELECTED_STATE_SET
+ palette.setColor(QPalette::Inactive,
+ QPalette::HighlightedText,
+ QRgb(object.value(QLatin1String("ENABLED_SELECTED_STATE_SET")).toInt()));
+
+ // QPalette::Disabled -> SELECTED_STATE_SET
+ palette.setColor(QPalette::Disabled,
+ QPalette::HighlightedText,
+ QRgb(object.value(QLatin1String("SELECTED_STATE_SET")).toInt()));
+
+ palette.setColor(QPalette::Current,
+ QPalette::HighlightedText,
+ palette.color(QPalette::Active, QPalette::HighlightedText));
+
+ // Same colors for Text
+ palette.setColor(QPalette::Active, QPalette::Text, palette.color(QPalette::Active, role));
+ palette.setColor(QPalette::Inactive, QPalette::Text, palette.color(QPalette::Inactive, role));
+ palette.setColor(QPalette::Disabled, QPalette::Text, palette.color(QPalette::Disabled, role));
+ palette.setColor(QPalette::Current, QPalette::Text, palette.color(QPalette::Current, role));
+
+ // And for ButtonText
+ palette.setColor(QPalette::Active, QPalette::ButtonText, palette.color(QPalette::Active, role));
+ palette.setColor(QPalette::Inactive, QPalette::ButtonText, palette.color(QPalette::Inactive, role));
+ palette.setColor(QPalette::Disabled, QPalette::ButtonText, palette.color(QPalette::Disabled, role));
+ palette.setColor(QPalette::Current, QPalette::ButtonText, palette.color(QPalette::Current, role));
+ }
+}
+
+static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
+{
+ QString stylePath(QLatin1String(qgetenv("MINISTRO_ANDROID_STYLE_PATH")));
+ const QLatin1Char slashChar('/');
+ if (!stylePath.isEmpty() && !stylePath.endsWith(slashChar))
+ stylePath += slashChar;
+
+ QString androidTheme = QLatin1String(qgetenv("QT_ANDROID_THEME"));
+ if (!androidTheme.isEmpty() && !androidTheme.endsWith(slashChar))
+ androidTheme += slashChar;
+
+ if (stylePath.isEmpty()) {
+ stylePath = QLatin1String("/data/data/org.kde.necessitas.ministro/files/dl/style/")
+ + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI")) + slashChar;
+ }
+ Q_ASSERT(!stylePath.isEmpty());
+
+ if (!androidTheme.isEmpty() && QFileInfo(stylePath + androidTheme + QLatin1String("style.json")).exists())
+ stylePath += androidTheme;
+
+ QFile f(stylePath + QLatin1String("style.json"));
+ if (!f.open(QIODevice::ReadOnly))
+ return std::shared_ptr<AndroidStyle>();
+
+ QJsonParseError error;
+ QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error);
+ if (document.isNull()) {
+ qCritical() << error.errorString();
+ return std::shared_ptr<AndroidStyle>();
+ }
+
+ if (!document.isObject()) {
+ qCritical() << "Style.json does not contain a valid style.";
+ return std::shared_ptr<AndroidStyle>();
+ }
+ std::shared_ptr<AndroidStyle> style(new AndroidStyle);
+ style->m_styleData = document.object();
+ for (QJsonObject::const_iterator objectIterator = style->m_styleData.constBegin();
+ objectIterator != style->m_styleData.constEnd();
+ ++objectIterator) {
+ QString key = objectIterator.key();
+ QJsonValue value = objectIterator.value();
+ if (!value.isObject()) {
+ qWarning("Style.json structure is unrecognized.");
+ continue;
+ }
+ QJsonObject item = value.toObject();
+ QJsonObject::const_iterator attributeIterator = item.find(QLatin1String("qtClass"));
+ QByteArray qtClassName;
+ if (attributeIterator != item.constEnd()) {
+ // The item has palette and font information for a specific Qt Class (e.g. QWidget, QPushButton, etc.)
+ qtClassName = attributeIterator.value().toString().toLatin1();
+ }
+ const int ft = fontType(key);
+ if (ft > -1 || !qtClassName.isEmpty()) {
+ // Extract font information
+ QFont font;
+
+ // Font size (in pixels)
+ attributeIterator = item.find(QLatin1String("TextAppearance_textSize"));
+ if (attributeIterator != item.constEnd())
+ font.setPixelSize(int(attributeIterator.value().toDouble()));
+
+ // Font style
+ attributeIterator = item.find(QLatin1String("TextAppearance_textStyle"));
+ if (attributeIterator != item.constEnd()) {
+ const int style = int(attributeIterator.value().toDouble());
+ font.setBold(style & textStyle_bold);
+ font.setItalic(style & textStyle_italic);
+ }
+
+ // Font typeface
+ attributeIterator = item.find(QLatin1String("TextAppearance_typeface"));
+ if (attributeIterator != item.constEnd()) {
+ QFont::StyleHint styleHint = QFont::AnyStyle;
+ switch (int(attributeIterator.value().toDouble())) {
+ case typeface_sans:
+ styleHint = QFont::SansSerif;
+ break;
+ case typeface_serif:
+ styleHint = QFont::Serif;
+ break;
+ case typeface_monospace:
+ styleHint = QFont::Monospace;
+ break;
+ }
+ font.setStyleHint(styleHint, QFont::PreferMatch);
+ }
+ if (!qtClassName.isEmpty())
+ style->m_QWidgetsFonts.insert(qtClassName, font);
+
+ if (ft > -1) {
+ style->m_fonts.insert(ft, font);
+ if (ft == QPlatformTheme::SystemFont)
+ QGuiApplication::setFont(font);
+ }
+ // Extract font information
+ }
+
+ const int pt = paletteType(key);
+ if (pt > -1 || !qtClassName.isEmpty()) {
+ // Extract palette information
+ QPalette palette;
+ attributeIterator = item.find(QLatin1String("defaultTextColorPrimary"));
+ if (attributeIterator != item.constEnd())
+ palette.setColor(QPalette::WindowText, QRgb(int(attributeIterator.value().toDouble())));
+
+ attributeIterator = item.find(QLatin1String("defaultBackgroundColor"));
+ if (attributeIterator != item.constEnd())
+ palette.setColor(QPalette::Background, QRgb(int(attributeIterator.value().toDouble())));
+
+ attributeIterator = item.find(QLatin1String("TextAppearance_textColor"));
+ if (attributeIterator != item.constEnd())
+ setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::WindowText);
+
+ attributeIterator = item.find(QLatin1String("TextAppearance_textColorLink"));
+ if (attributeIterator != item.constEnd())
+ setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::Link);
+
+ attributeIterator = item.find(QLatin1String("TextAppearance_textColorHighlight"));
+ if (attributeIterator != item.constEnd())
+ palette.setColor(QPalette::Highlight, QRgb(int(attributeIterator.value().toDouble())));
+
+ if (pt == QPlatformTheme::SystemPalette)
+ *defaultPalette = style->m_standardPalette = palette;
+
+ if (pt > -1)
+ style->m_palettes.insert(pt, palette);
+ // Extract palette information
+ }
+ }
+ return style;
+}
+
QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface)
{
- m_androidPlatformNativeInterface = androidPlatformNativeInterface;
QColor background(229, 229, 229);
QColor light = background.lighter(150);
QColor mid(background.darker(130));
@@ -80,6 +344,9 @@ QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *an
m_defaultPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight);
m_defaultPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight);
m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Highlight, highlight.lighter(150));
+ m_androidStyleData = loadAndroidStyle(&m_defaultPalette);
+ QGuiApplication::setPalette(m_defaultPalette);
+ androidPlatformNativeInterface->m_androidStyle = m_androidStyleData;
}
QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const
@@ -132,9 +399,11 @@ static inline int paletteType(QPlatformTheme::Palette type)
const QPalette *QAndroidPlatformTheme::palette(Palette type) const
{
- QHash<int, QPalette>::const_iterator it = m_androidPlatformNativeInterface->m_palettes.find(paletteType(type));
- if (it != m_androidPlatformNativeInterface->m_palettes.end())
- return &(it.value());
+ if (m_androidStyleData) {
+ auto it = m_androidStyleData->m_palettes.find(paletteType(type));
+ if (it != m_androidStyleData->m_palettes.end())
+ return &(it.value());
+ }
return &m_defaultPalette;
}
@@ -154,9 +423,11 @@ static inline int fontType(QPlatformTheme::Font type)
const QFont *QAndroidPlatformTheme::font(Font type) const
{
- QHash<int, QFont>::const_iterator it = m_androidPlatformNativeInterface->m_fonts.find(fontType(type));
- if (it != m_androidPlatformNativeInterface->m_fonts.end())
- return &(it.value());
+ if (m_androidStyleData) {
+ auto it = m_androidStyleData->m_fonts.find(fontType(type));
+ if (it != m_androidStyleData->m_fonts.end())
+ return &(it.value());
+ }
// default in case the style has not set a font
static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi
@@ -165,18 +436,12 @@ const QFont *QAndroidPlatformTheme::font(Font type) const
return 0;
}
-static const QLatin1String STYLES_PATH("/data/data/org.kde.necessitas.ministro/files/dl/style/");
-static const QLatin1String STYLE_FILE("/style.json");
-
QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
{
switch (hint) {
case StyleNames:
if (qEnvironmentVariableIntValue("QT_USE_ANDROID_NATIVE_STYLE")
- && (!qgetenv("MINISTRO_ANDROID_STYLE_PATH").isEmpty()
- || QFileInfo(STYLES_PATH
- + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI"))
- + STYLE_FILE).exists())) {
+ && m_androidStyleData) {
return QStringList("android");
}
return QStringList("fusion");
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h
index 01611bf9d4..334e86ad7a 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/qandroidplatformtheme.h
@@ -37,8 +37,22 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/qpalette.h>
+#include <QJsonObject>
+
+#include <memory>
+
QT_BEGIN_NAMESPACE
+struct AndroidStyle
+{
+ QJsonObject m_styleData;
+ QPalette m_standardPalette;
+ QHash<int, QPalette> m_palettes;
+ QHash<int, QFont> m_fonts;
+ QHash<QByteArray, QFont> m_QWidgetsFonts;
+ QHash<QByteArray, QFont> m_QWidgetsPalettes;
+};
+
class QAndroidPlatformNativeInterface;
class QAndroidPlatformTheme: public QPlatformTheme
{
@@ -57,7 +71,7 @@ public:
private:
- QAndroidPlatformNativeInterface * m_androidPlatformNativeInterface;
+ std::shared_ptr<AndroidStyle> m_androidStyleData;
QPalette m_defaultPalette;
};
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index bfff5c3266..917f020132 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -51,12 +51,9 @@ public:
QPaintDevice *paintDevice();
void flush(QWindow *widget, const QRegion &region, const QPoint &offset);
-#ifndef QT_NO_OPENGL
- QImage toImage() const Q_DECL_OVERRIDE;
-#endif
+ QImage toImage() const;
void resize (const QSize &size, const QRegion &);
bool scroll(const QRegion &area, int dx, int dy);
- CGImageRef getBackingStoreCGImage();
qreal getBackingStoreDevicePixelRatio();
private:
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index e13e295511..ba1198c19c 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -96,12 +96,10 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion &region, const QPoint
}
}
-#ifndef QT_NO_OPENGL
QImage QCocoaBackingStore::toImage() const
{
return m_qImage;
}
-#endif
void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
{
@@ -121,17 +119,6 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
return true;
}
-CGImageRef QCocoaBackingStore::getBackingStoreCGImage()
-{
- if (!m_cgImage)
- m_cgImage = qt_mac_toCGImage(m_qImage);
-
- // Warning: do not retain/release/cache the returned image from
- // outside the backingstore since it shares data with a QImage and
- // needs special memory considerations.
- return m_cgImage;
-}
-
qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio()
{
return m_qImage.devicePixelRatio();
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index 8158c244ab..7d99f566bf 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -106,10 +106,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
mResultSet = false;
mClosingDueToKnownButton = false;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7)
- [mColorPanel setRestorable:NO];
-#endif
+ [mColorPanel setRestorable:NO];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(colorChanged:)
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index c37bb63916..f5e22d1125 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -149,11 +149,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
mDialogIsExecuting = false;
mResultSet = false;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7)
- [mFontPanel setRestorable:NO];
-#endif
-
+ [mFontPanel setRestorable:NO];
[mFontPanel setDelegate:self];
[[NSFontManager sharedFontManager] setDelegate:self];
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index e0838cb342..72bd09625a 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -144,15 +144,8 @@ void QCocoaScreen::updateGeometry()
qreal QCocoaScreen::devicePixelRatio() const
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- NSScreen * screen = osScreen();
- return qreal(screen ? [screen backingScaleFactor] : 1.0);
- } else
-#endif
- {
- return 1.0;
- }
+ NSScreen * screen = osScreen();
+ return qreal(screen ? [screen backingScaleFactor] : 1.0);
}
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
diff --git a/src/plugins/platforms/cocoa/qcocoaintrospection.mm b/src/plugins/platforms/cocoa/qcocoaintrospection.mm
index 806effc929..84b16813dc 100644
--- a/src/plugins/platforms/cocoa/qcocoaintrospection.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintrospection.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -79,43 +79,33 @@ QT_BEGIN_NAMESPACE
void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel, SEL backupSel)
{
-#ifndef QT_MAC_USE_COCOA
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
-#endif
- {
- // The following code replaces the _implementation_ for the selector we want to hack
- // (originalSel) with the implementation found in proxyClass. Then it creates
- // a new 'backup' method inside baseClass containing the old, original,
- // implementation (fakeSel). You can let the proxy implementation of originalSel
- // call fakeSel if needed (similar approach to calling a super class implementation).
- // fakeSel must also be implemented in proxyClass, as the signature is used
- // as template for the method one we add into baseClass.
- // NB: You will typically never create any instances of proxyClass; we use it
- // only for stealing its contents and put it into baseClass.
- if (!replacementSel)
- replacementSel = originalSel;
+ // The following code replaces the _implementation_ for the selector we want to hack
+ // (originalSel) with the implementation found in proxyClass. Then it creates
+ // a new 'backup' method inside baseClass containing the old, original,
+ // implementation (fakeSel). You can let the proxy implementation of originalSel
+ // call fakeSel if needed (similar approach to calling a super class implementation).
+ // fakeSel must also be implemented in proxyClass, as the signature is used
+ // as template for the method one we add into baseClass.
+ // NB: You will typically never create any instances of proxyClass; we use it
+ // only for stealing its contents and put it into baseClass.
+ if (!replacementSel)
+ replacementSel = originalSel;
- Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
- Method replacementMethod = class_getInstanceMethod(proxyClass, replacementSel);
- IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(replacementMethod));
+ Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
+ Method replacementMethod = class_getInstanceMethod(proxyClass, replacementSel);
+ IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(replacementMethod));
- if (backupSel) {
- Method backupMethod = class_getInstanceMethod(proxyClass, backupSel);
- class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod));
- }
+ if (backupSel) {
+ Method backupMethod = class_getInstanceMethod(proxyClass, backupSel);
+ class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod));
}
}
void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel)
{
-#ifndef QT_MAC_USE_COCOA
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
-#endif
- {
- Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
- Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel);
- method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass));
- }
+ Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
+ Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel);
+ method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 791b0805d0..251fe9485c 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -323,17 +323,22 @@ NSMenuItem *QCocoaMenuItem::sync()
text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
QString finalString = qt_mac_removeMnemonics(text);
+ bool useAttributedTitle = false;
// Cocoa Font and title
if (m_font.resolve()) {
NSFont *customMenuFont = [NSFont fontWithName:QCFString::toNSString(m_font.family())
size:m_font.pointSize()];
- NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
- NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
- NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
- NSAttributedString *str = [[[NSAttributedString alloc] initWithString:QCFString::toNSString(finalString)
- attributes:attributes] autorelease];
- [m_native setAttributedTitle: str];
- } else {
+ if (customMenuFont) {
+ NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
+ NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
+ NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
+ NSAttributedString *str = [[[NSAttributedString alloc] initWithString:QCFString::toNSString(finalString)
+ attributes:attributes] autorelease];
+ [m_native setAttributedTitle: str];
+ useAttributedTitle = true;
+ }
+ }
+ if (!useAttributedTitle) {
[m_native setTitle: QCFString::toNSString(finalString)];
}
diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
index 421d934fa7..b657ef9a82 100644
--- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm
+++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
@@ -88,9 +88,9 @@ QVariant QMacPasteboardMimeTraditionalMacPlainText::convertToMime(const QString
const QByteArray &firstData = data.first();
QVariant ret;
if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) {
- return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
+ return QString(QCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
reinterpret_cast<const UInt8 *>(firstData.constData()),
- firstData.size(), CFStringGetSystemEncoding(), false));
+ firstData.size(), CFStringGetSystemEncoding(), false)));
} else {
qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
}
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
index 2101b68769..c26a2b22fd 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -466,17 +466,13 @@ bool QCocoaPrintDevice::openPpdFile()
ppdClose(m_ppd);
m_ppd = 0;
CFURLRef ppdURL = NULL;
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
- char ppdPath[PATH_MAX];
-#else
char ppdPath[MAXPATHLEN];
-#endif
if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr
- && ppdURL != NULL
- && CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath))) {
- m_ppd = ppdOpenFile(ppdPath);
+ && ppdURL != NULL) {
+ if (CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath)))
+ m_ppd = ppdOpenFile(ppdPath);
+ CFRelease(ppdURL);
}
- CFRelease(ppdURL);
return m_ppd ? true : false;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index a43cf73d34..b232c7a4d3 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -268,6 +268,7 @@ public: // for QNSView
bool m_inConstructor;
bool m_inSetVisible;
+ bool m_inSetGeometry;
#ifndef QT_NO_OPENGL
QCocoaGLContext *m_glContext;
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 3366e5bc3c..6656212457 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -107,26 +107,6 @@ static void selectNextKeyWindow(NSWindow *currentKeyWindow)
}
}
-
-@interface NSWindow (CocoaWindowCategory)
-- (NSRect) legacyConvertRectFromScreen:(NSRect) rect;
-@end
-
-@implementation NSWindow (CocoaWindowCategory)
-- (NSRect) legacyConvertRectFromScreen:(NSRect) rect
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- return [self convertRectFromScreen: rect];
- }
-#endif
- NSRect r = rect;
- r.origin = [self convertScreenToBase:rect.origin];
- return r;
-}
-@end
-
-
@implementation QNSWindowHelper
@synthesize window = _window;
@@ -197,7 +177,7 @@ static void selectNextKeyWindow(NSWindow *currentKeyWindow)
if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
NSPoint loc = [theEvent locationInWindow];
- NSRect windowFrame = [self.window legacyConvertRectFromScreen:[self.window frame]];
+ NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
NSRect contentFrame = [[self.window contentView] frame];
if (NSMouseInRect(loc, windowFrame, NO) &&
!NSMouseInRect(loc, contentFrame, NO))
@@ -401,6 +381,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_windowUnderMouse(false)
, m_inConstructor(true)
, m_inSetVisible(false)
+ , m_inSetGeometry(false)
#ifndef QT_NO_OPENGL
, m_glContext(0)
#endif
@@ -432,19 +413,16 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
} else {
m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
m_contentView = m_qtView;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
// Enable high-dpi OpenGL for retina displays. Enabling has the side
// effect that Cocoa will start calling glViewport(0, 0, width, height),
// overriding any glViewport calls in application code. This is usually not a
// problem, except if the appilcation wants to have a "custom" viewport.
// (like the hellogl example)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7
- && tlw->supportsOpenGL()) {
+ if (tlw->supportsOpenGL()) {
BOOL enable = qt_mac_resolveOption(YES, tlw, "_q_mac_wantsBestResolutionOpenGLSurface",
"QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE");
[m_contentView setWantsBestResolutionOpenGLSurface:enable];
}
-#endif
BOOL enable = qt_mac_resolveOption(NO, tlw, "_q_mac_wantsLayer",
"QT_MAC_WANTS_LAYER");
[m_contentView setWantsLayer:enable];
@@ -493,6 +471,8 @@ QSurfaceFormat QCocoaWindow::format() const
void QCocoaWindow::setGeometry(const QRect &rectIn)
{
+ QBoolBlocker inSetGeometry(m_inSetGeometry, true);
+
QRect rect = rectIn;
// This means it is a call from QWindow::setFramePosition() and
// the coordinates include the frame (size is still the contents rectangle).
@@ -516,7 +496,8 @@ QRect QCocoaWindow::geometry() const
// of view. Embedded QWindows get global (screen) geometry.
if (m_contentViewIsEmbedded) {
NSPoint windowPoint = [m_contentView convertPoint:NSMakePoint(0, 0) toView:nil];
- NSPoint screenPoint = [[m_contentView window] convertBaseToScreen:windowPoint]; // ### use convertRectToScreen after 10.6 removal
+ NSRect screenRect = [[m_contentView window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
+ NSPoint screenPoint = screenRect.origin;
QPoint position = qt_mac_flipPoint(screenPoint).toPoint();
QSize size = qt_mac_toQRect([m_contentView bounds]).size();
return QRect(position, size);
@@ -681,11 +662,7 @@ void QCocoaWindow::setVisible(bool visible)
// Since this isn't a native popup, the window manager doesn't close the popup when you click outside
NSUInteger parentStyleMask = [parentCocoaWindow->m_nsWindow styleMask];
if ((m_resizableTransientParent = (parentStyleMask & NSResizableWindowMask))
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7
- && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask)
-#endif
- )
+ && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask))
[parentCocoaWindow->m_nsWindow setStyleMask:parentStyleMask & ~NSResizableWindowMask];
}
@@ -784,11 +761,7 @@ void QCocoaWindow::setVisible(bool visible)
if (parentCocoaWindow && window()->type() == Qt::Popup) {
parentCocoaWindow->m_activePopupWindow = 0;
if (m_resizableTransientParent
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7
- && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask)
-#endif
- )
+ && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask))
// QTBUG-30266: a window should not be resizable while a transient popup is open
[parentCocoaWindow->m_nsWindow setStyleMask:[parentCocoaWindow->m_nsWindow styleMask] | NSResizableWindowMask];
}
@@ -903,19 +876,15 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
setWindowTitle(window()->title());
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- Qt::WindowType type = window()->type();
- if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
- NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior];
- if (flags & Qt::WindowFullscreenButtonHint)
- behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
- else
- behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
- [m_nsWindow setCollectionBehavior:behavior];
- }
+ Qt::WindowType type = window()->type();
+ if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
+ NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior];
+ if (flags & Qt::WindowFullscreenButtonHint)
+ behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
+ else
+ behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
+ [m_nsWindow setCollectionBehavior:behavior];
}
-#endif
setWindowZoomButton(flags);
}
@@ -1340,13 +1309,9 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindow.hasShadow = NO;
m_nsWindow.level = NSNormalWindowLevel;
NSWindowCollectionBehavior collectionBehavior =
- NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
- m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
- }
-#endif
+ NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle
+ | NSWindowCollectionBehaviorFullScreenAuxiliary;
+ m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
m_nsWindow.collectionBehavior = collectionBehavior;
setCocoaGeometry(window()->geometry());
@@ -1438,17 +1403,17 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
if ((type & Qt::Popup) == Qt::Popup)
[window setHasShadow:YES];
- [window setHidesOnDeactivate:(type & Qt::Tool) == Qt::Tool];
+ // Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set.
+ QVariant showWithoutActivating = QPlatformWindow::window()->property("_q_macAlwaysShowToolWindow");
+ bool shouldHideOnDeactivate = ((type & Qt::Tool) == Qt::Tool) &&
+ !(showWithoutActivating.isValid() && showWithoutActivating.toBool());
+ [window setHidesOnDeactivate: shouldHideOnDeactivate];
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- // Make popup winows show on the same desktop as the parent full-screen window.
- [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
+ // Make popup windows show on the same desktop as the parent full-screen window.
+ [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
+ if ((type & Qt::Popup) == Qt::Popup)
+ [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
- if ((type & Qt::Popup) == Qt::Popup)
- [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
- }
-#endif
createdWindow = window;
} else {
QNSWindow *window;
@@ -1458,10 +1423,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
createdWindow = window;
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if ([createdWindow respondsToSelector:@selector(setRestorable:)])
[createdWindow setRestorable: NO];
-#endif
NSInteger level = windowLevel(flags);
[createdWindow setLevel:level];
@@ -1562,18 +1525,11 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
}
if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) {
- bool fakeFullScreen = true;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- if (window()->flags() & Qt::WindowFullscreenButtonHint) {
- fakeFullScreen = false;
- if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen)
- predictedState = Qt::WindowMaximized;
- [m_nsWindow toggleFullScreen : m_nsWindow];
- }
- }
-#endif
- if (fakeFullScreen) {
+ if (window()->flags() & Qt::WindowFullscreenButtonHint) {
+ if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen)
+ predictedState = Qt::WindowMaximized;
+ [m_nsWindow toggleFullScreen : m_nsWindow];
+ } else {
if (newState & Qt::WindowFullScreen) {
QScreen *screen = window()->screen();
if (screen) {
@@ -1747,20 +1703,13 @@ bool QCocoaWindow::testContentBorderAreaPosition(int position) const
qreal QCocoaWindow::devicePixelRatio() const
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- // The documented way to observe the relationship between device-independent
- // and device pixels is to use one for the convertToBacking functions. Other
- // methods such as [NSWindow backingScaleFacor] might not give the correct
- // result, for example if setWantsBestResolutionOpenGLSurface is not set or
- // or ignored by the OpenGL driver.
- NSSize backingSize = [m_contentView convertSizeToBacking:NSMakeSize(1.0, 1.0)];
- return backingSize.height;
- } else
-#endif
- {
- return 1.0;
- }
+ // The documented way to observe the relationship between device-independent
+ // and device pixels is to use one for the convertToBacking functions. Other
+ // methods such as [NSWindow backingScaleFacor] might not give the correct
+ // result, for example if setWantsBestResolutionOpenGLSurface is not set or
+ // or ignored by the OpenGL driver.
+ NSSize backingSize = [m_contentView convertSizeToBacking:NSMakeSize(1.0, 1.0)];
+ return backingSize.height;
}
// Returns whether the window can be expose, which it can
@@ -1808,10 +1757,15 @@ void QCocoaWindow::updateExposedGeometry()
if (!m_geometryUpdateExposeAllowed)
return;
+ // Do not send incorrect exposes in case the window is not even visible yet.
+ // We might get here as a result of a resize() from QWidget's show(), for instance.
+ if (!window()->isVisible())
+ return;
+
if (!isWindowExposable())
return;
- if (m_exposedGeometry == geometry() && m_exposedDevicePixelRatio == devicePixelRatio())
+ if (m_exposedGeometry.size() == geometry().size() && m_exposedDevicePixelRatio == devicePixelRatio())
return;
m_isExposed = true;
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 8b23f84a25..8d8df13dc3 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -51,7 +51,8 @@ QT_END_NAMESPACE
Q_FORWARD_DECLARE_OBJC_CLASS(QNSViewMouseMoveHelper);
@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> {
- QCocoaBackingStore* m_backingStore;
+ QImage m_backingStore;
+ qreal m_pixelRatio;
QPoint m_backingStoreOffset;
CGImageRef m_maskImage;
uchar *m_maskData;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 1f58a0457f..0ce5b3b332 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -143,7 +143,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
{
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
if (self) {
- m_backingStore = 0;
+ m_pixelRatio = 1.;
m_maskImage = 0;
m_shouldInvalidateWindowShadow = false;
m_window = 0;
@@ -361,12 +361,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
// Send a geometry change event to Qt, if it's ready to handle events
if (!m_platformWindow->m_inConstructor) {
QWindowSystemInterface::handleGeometryChange(m_window, geometry);
- // Do not send incorrect exposes in case the window is not even visible yet.
- // We might get here as a result of a resize() from QWidget's show(), for instance.
- if (m_platformWindow->window()->isVisible()) {
- m_platformWindow->updateExposedGeometry();
+ m_platformWindow->updateExposedGeometry();
+ // Guard against processing window system events during QWindow::setGeometry
+ // calles, which Qt and Qt applications do not excpect.
+ if (!m_platformWindow->m_inSetGeometry)
QWindowSystemInterface::flushWindowSystemEvents();
- }
}
}
@@ -408,10 +407,6 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ?
Qt::WindowMinimized : Qt::WindowNoState;
[self notifyWindowStateChanged:newState];
- // NSWindowDidOrderOnScreenAndFinishAnimatingNotification is private API, and not
- // emitted in 10.6, so we bring back the old behavior for that case alone.
- if (newState == Qt::WindowNoState && QSysInfo::QSysInfo::MacintoshVersion == QSysInfo::MV_10_6)
- m_platformWindow->exposeWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
m_platformWindow->obscureWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
@@ -424,12 +419,17 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
#pragma clang diagnostic ignored "-Wobjc-method-access"
enum { NSWindowOcclusionStateVisible = 1UL << 1 };
#endif
- // Older versions managed in -[QNSView viewDidMoveToWindow].
- // Support QWidgetAction in NSMenu. Mavericks only sends this notification.
- // Ideally we should support this in Qt as well, in order to disable animations
- // when the window is occluded.
- if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible)
+ if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) {
m_platformWindow->exposeWindow();
+ } else {
+ // Send Obscure events on window occlusion to stop animations. Several
+ // unit tests expect paint and/or expose events for windows that are
+ // sometimes (unpredictably) occlouded: Don't send Obscure events when
+ // running under QTestLib.
+ static bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
+ if (!onTestLib)
+ m_platformWindow->obscureWindow();
+ }
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
#pragma clang diagnostic pop
#endif
@@ -437,24 +437,16 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_window) {
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
if (screenIndex != NSNotFound) {
- m_platformWindow->updateExposedGeometry();
QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen());
+ m_platformWindow->updateExposedGeometry();
}
}
- } else {
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- if (notificationName == NSWindowDidEnterFullScreenNotification
- || notificationName == NSWindowDidExitFullScreenNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidEnterFullScreenNotification ?
- Qt::WindowFullScreen : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- }
- }
-#endif
-
+ } else if (notificationName == NSWindowDidEnterFullScreenNotification
+ || notificationName == NSWindowDidExitFullScreenNotification) {
+ Qt::WindowState newState = notificationName == NSWindowDidEnterFullScreenNotification ?
+ Qt::WindowFullScreen : Qt::WindowNoState;
+ [self notifyWindowStateChanged:newState];
}
}
@@ -478,8 +470,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
- m_backingStore = backingStore;
- m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
+ m_backingStore = backingStore->toImage();
+ m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio();
+ m_backingStoreOffset = offset * m_pixelRatio;
foreach (QRect rect, region.rects()) {
[self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
}
@@ -543,7 +536,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_platformWindow->m_drawContentBorderGradient)
NSDrawWindowBackground(dirtyRect);
- if (!m_backingStore)
+ if (m_backingStore.isNull())
return;
// Calculate source and target rects. The target rect is the dirtyRect:
@@ -551,11 +544,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
// The backing store source rect will be larger on retina displays.
// Scale dirtyRect by the device pixel ratio:
- const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio();
- CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio,
- dirtyRect.origin.y * devicePixelRatio,
- dirtyRect.size.width * devicePixelRatio,
- dirtyRect.size.height * devicePixelRatio);
+ CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * m_pixelRatio,
+ dirtyRect.origin.y * m_pixelRatio,
+ dirtyRect.size.width * m_pixelRatio,
+ dirtyRect.size.height * m_pixelRatio);
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort];
@@ -581,7 +573,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
dirtyBackingRect.size.width,
dirtyBackingRect.size.height
);
- CGImageRef bsCGImage = m_backingStore->getBackingStoreCGImage();
+ CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore);
CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect);
// Optimization: Copy frame buffer content instead of blending for
@@ -596,10 +588,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
CGContextRestoreGState(cgContext);
CGImageRelease(cleanImg);
CGImageRelease(subMask);
+ CGImageRelease(bsCGImage);
[self invalidateWindowShadowIfNeeded];
-
- m_backingStore = 0;
}
- (BOOL) isFlipped
@@ -611,7 +602,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
{
if (m_window->flags() & Qt::WindowTransparentForInput)
return NO;
- QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
+ if (!m_platformWindow->windowIsPopupType())
+ QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
return YES;
}
@@ -656,16 +648,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
NSWindow *window = [self window];
NSPoint nsWindowPoint;
- // Use convertRectToScreen if available (added in 10.7).
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if ([window respondsToSelector:@selector(convertRectFromScreen:)]) {
- NSRect windowRect = [window convertRectFromScreen:NSMakeRect(mouseLocation.x, mouseLocation.y, 1, 1)];
- nsWindowPoint = windowRect.origin; // NSWindow coordinates
- } else
-#endif
- {
- nsWindowPoint = [window convertScreenToBase:mouseLocation]; // NSWindow coordinates
- }
+ NSRect windowRect = [window convertRectFromScreen:NSMakeRect(mouseLocation.x, mouseLocation.y, 1, 1)];
+ nsWindowPoint = windowRect.origin; // NSWindow coordinates
NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates
*qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates
@@ -678,6 +662,19 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_frameStrutButtons = Qt::NoButton;
}
+- (NSPoint) screenMousePoint:(NSEvent *)theEvent
+{
+ NSPoint screenPoint;
+ if (theEvent) {
+ NSPoint windowPoint = [theEvent locationInWindow];
+ NSRect screenRect = [[theEvent window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
+ screenPoint = screenRect.origin;
+ } else {
+ screenPoint = [NSEvent mouseLocation];
+ }
+ return screenPoint;
+}
+
- (void)handleMouseEvent:(NSEvent *)theEvent
{
[self handleTabletEvent: theEvent];
@@ -692,23 +689,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_platformWindow->m_forwardWindow = 0;
}
- NSPoint globalPos = [NSEvent mouseLocation];
-
- if ([self.window parentWindow]
- && (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)) {
- // QToolBar can be implemented as a child window on top of its main window
- // (with a borderless NSWindow). If an option "unified toolbar" set on the main window,
- // it's possible to drag such a window using this toolbar.
- // While handling mouse drag events, QToolBar moves the window (QWidget::move).
- // In such a combination [NSEvent mouseLocation] is very different from the
- // real event location and as a result a window will move chaotically.
- NSPoint winPoint = [theEvent locationInWindow];
- NSRect tmpRect = NSMakeRect(winPoint.x, winPoint.y, 1., 1.);
- tmpRect = [[theEvent window] convertRectToScreen:tmpRect];
- globalPos = tmpRect.origin;
- }
-
- [targetView convertFromScreen:globalPos toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
+ [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
ulong timestamp = [theEvent timestamp] * 1000;
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
@@ -881,7 +862,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
QPointF windowPoint;
QPointF screenPoint;
- [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
// Top-level windows generate enter-leave events for sub-windows.
@@ -1296,18 +1277,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
// It looks like 1/4 degrees per pixel behaves most native.
// (NB: Qt expects the unit for delta to be 8 per degree):
const int pixelsToDegrees = 2; // 8 * 1/4
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) {
- angleDelta.setX([theEvent scrollingDeltaX] * pixelsToDegrees);
- angleDelta.setY([theEvent scrollingDeltaY] * pixelsToDegrees);
- } else
-#endif
- {
- angleDelta.setX([theEvent deviceDeltaX] * pixelsToDegrees);
- angleDelta.setY([theEvent deviceDeltaY] * pixelsToDegrees);
- }
-
+ angleDelta.setX([theEvent scrollingDeltaX] * pixelsToDegrees);
+ angleDelta.setY([theEvent scrollingDeltaY] * pixelsToDegrees);
} else {
// carbonEventKind == kEventMouseWheelMoved
// Remove acceleration, and use either -120 or 120 as delta:
@@ -1316,20 +1287,16 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
}
QPoint pixelDelta;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) {
- if ([theEvent hasPreciseScrollingDeltas]) {
- pixelDelta.setX([theEvent scrollingDeltaX]);
- pixelDelta.setY([theEvent scrollingDeltaY]);
- } else {
- // docs: "In the case of !hasPreciseScrollingDeltas, multiply the delta with the line width."
- // scrollingDeltaX seems to return a minimum value of 0.1 in this case, map that to two pixels.
- const CGFloat lineWithEstimate = 20.0;
- pixelDelta.setX([theEvent scrollingDeltaX] * lineWithEstimate);
- pixelDelta.setY([theEvent scrollingDeltaY] * lineWithEstimate);
- }
+ if ([theEvent hasPreciseScrollingDeltas]) {
+ pixelDelta.setX([theEvent scrollingDeltaX]);
+ pixelDelta.setY([theEvent scrollingDeltaY]);
+ } else {
+ // docs: "In the case of !hasPreciseScrollingDeltas, multiply the delta with the line width."
+ // scrollingDeltaX seems to return a minimum value of 0.1 in this case, map that to two pixels.
+ const CGFloat lineWithEstimate = 20.0;
+ pixelDelta.setX([theEvent scrollingDeltaX] * lineWithEstimate);
+ pixelDelta.setY([theEvent scrollingDeltaY] * lineWithEstimate);
}
-#endif
QPointF qt_windowPoint;
QPointF qt_screenPoint;
@@ -1337,44 +1304,36 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
NSTimeInterval timestamp = [theEvent timestamp];
ulong qt_timestamp = timestamp * 1000;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) {
- // Prevent keyboard modifier state from changing during scroll event streams.
- // A two-finger trackpad flick generates a stream of scroll events. We want
- // the keyboard modifier state to be the state at the beginning of the
- // flick in order to avoid changing the interpretation of the events
- // mid-stream. One example of this happening would be when pressing cmd
- // after scrolling in Qt Creator: not taking the phase into account causes
- // the end of the event stream to be interpreted as font size changes.
- NSEventPhase momentumPhase = [theEvent momentumPhase];
- if (momentumPhase == NSEventPhaseNone) {
- currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- }
+ // Prevent keyboard modifier state from changing during scroll event streams.
+ // A two-finger trackpad flick generates a stream of scroll events. We want
+ // the keyboard modifier state to be the state at the beginning of the
+ // flick in order to avoid changing the interpretation of the events
+ // mid-stream. One example of this happening would be when pressing cmd
+ // after scrolling in Qt Creator: not taking the phase into account causes
+ // the end of the event stream to be interpreted as font size changes.
+ NSEventPhase momentumPhase = [theEvent momentumPhase];
+ if (momentumPhase == NSEventPhaseNone) {
+ currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
+ }
- NSEventPhase phase = [theEvent phase];
- Qt::ScrollPhase ph = Qt::ScrollUpdate;
+ NSEventPhase phase = [theEvent phase];
+ Qt::ScrollPhase ph = Qt::ScrollUpdate;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- // On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
- if (phase == NSEventPhaseMayBegin)
- ph = Qt::ScrollBegin;
- } else
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ // On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
+ if (phase == NSEventPhaseMayBegin)
+ ph = Qt::ScrollBegin;
+ } else
#endif
if (phase == NSEventPhaseBegan) {
// On 10.7, MayBegin will not happen, so Began is the actual beginning.
ph = Qt::ScrollBegin;
}
- if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
- ph = Qt::ScrollEnd;
- }
-
- QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph);
- } else
-#endif
- {
- QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta,
- [QNSView convertKeyModifiers:[theEvent modifierFlags]]);
+ if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
+ ph = Qt::ScrollEnd;
}
+
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph);
}
#endif //QT_NO_WHEELEVENT
@@ -1432,7 +1391,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QString text;
// ignore text for the U+F700-U+F8FF range. This is used by Cocoa when
// delivering function keys (e.g. arrow keys, backspace, F1-F35, etc.)
- if (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff)
+ if (!(modifiers & (Qt::ControlModifier | Qt::MetaModifier)) && (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff))
text = QCFString::toQString(characters);
QWindow *focusWindow = [self topLevelWindow];
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index d48cbdfac8..7b77c9f1a8 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -90,20 +90,13 @@ static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransfor
if (rgn.isEmpty()) {
CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
} else {
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- QCFType<HIMutableShapeRef> shape = qt_mac_QRegionToHIMutableShape(rgn);
- Q_ASSERT(!HIShapeIsEmpty(shape));
- HIShapeReplacePathInCGContext(shape, hd);
- } else {
- QVector<QRect> rects = rgn.rects();
- const int count = rects.size();
- for (int i = 0; i < count; i++) {
- const QRect &r = rects[i];
- CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
- CGContextAddRect(hd, mac_r);
- }
+ QVector<QRect> rects = rgn.rects();
+ const int count = rects.size();
+ for (int i = 0; i < count; i++) {
+ const QRect &r = rects[i];
+ CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ CGContextAddRect(hd, mac_r);
}
-
}
CGContextClip(hd);
@@ -1137,184 +1130,85 @@ extern "C" {
void
QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode)
{
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- int cg_mode = kCGBlendModeNormal;
- switch (mode) {
- case QPainter::CompositionMode_Multiply:
- cg_mode = kCGBlendModeMultiply;
- break;
- case QPainter::CompositionMode_Screen:
- cg_mode = kCGBlendModeScreen;
- break;
- case QPainter::CompositionMode_Overlay:
- cg_mode = kCGBlendModeOverlay;
- break;
- case QPainter::CompositionMode_Darken:
- cg_mode = kCGBlendModeDarken;
- break;
- case QPainter::CompositionMode_Lighten:
- cg_mode = kCGBlendModeLighten;
- break;
- case QPainter::CompositionMode_ColorDodge:
- cg_mode = kCGBlendModeColorDodge;
- break;
- case QPainter::CompositionMode_ColorBurn:
- cg_mode = kCGBlendModeColorBurn;
- break;
- case QPainter::CompositionMode_HardLight:
- cg_mode = kCGBlendModeHardLight;
- break;
- case QPainter::CompositionMode_SoftLight:
- cg_mode = kCGBlendModeSoftLight;
- break;
- case QPainter::CompositionMode_Difference:
- cg_mode = kCGBlendModeDifference;
- break;
- case QPainter::CompositionMode_Exclusion:
- cg_mode = kCGBlendModeExclusion;
- break;
- case QPainter::CompositionMode_Plus:
- cg_mode = kCGBlendModePlusLighter;
- break;
- case QPainter::CompositionMode_SourceOver:
- cg_mode = kCGBlendModeNormal;
- break;
- case QPainter::CompositionMode_DestinationOver:
- cg_mode = kCGBlendModeDestinationOver;
- break;
- case QPainter::CompositionMode_Clear:
- cg_mode = kCGBlendModeClear;
- break;
- case QPainter::CompositionMode_Source:
- cg_mode = kCGBlendModeCopy;
- break;
- case QPainter::CompositionMode_Destination:
- cg_mode = -1;
- break;
- case QPainter::CompositionMode_SourceIn:
- cg_mode = kCGBlendModeSourceIn;
- break;
- case QPainter::CompositionMode_DestinationIn:
- cg_mode = kCGCompositeModeDestinationIn;
- break;
- case QPainter::CompositionMode_SourceOut:
- cg_mode = kCGBlendModeSourceOut;
- break;
- case QPainter::CompositionMode_DestinationOut:
- cg_mode = kCGBlendModeDestinationOver;
- break;
- case QPainter::CompositionMode_SourceAtop:
- cg_mode = kCGBlendModeSourceAtop;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- cg_mode = kCGBlendModeDestinationAtop;
- break;
- case QPainter::CompositionMode_Xor:
- cg_mode = kCGBlendModeXOR;
- break;
- default:
- break;
- }
- if (cg_mode > -1) {
- CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
- }
- } else if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3
- && mode <= QPainter::CompositionMode_Xor) {
- // The standard porter duff ops.
- int cg_mode = kCGCompositeModeCopy;
- switch (mode) {
- case QPainter::CompositionMode_SourceOver:
- cg_mode = kCGCompositeModeSourceOver;
- break;
- case QPainter::CompositionMode_DestinationOver:
- cg_mode = kCGCompositeModeDestinationOver;
- break;
- case QPainter::CompositionMode_Clear:
- cg_mode = kCGCompositeModeClear;
- break;
- default:
- qWarning("QCoreGraphicsPaintEngine: Unhandled composition mode %d", (int)mode);
- break;
- case QPainter::CompositionMode_Source:
- cg_mode = kCGCompositeModeCopy;
- break;
- case QPainter::CompositionMode_Destination:
- cg_mode = CGCompositeMode(-1);
- break;
- case QPainter::CompositionMode_SourceIn:
- cg_mode = kCGCompositeModeSourceIn;
- break;
- case QPainter::CompositionMode_DestinationIn:
- cg_mode = kCGCompositeModeDestinationIn;
- break;
- case QPainter::CompositionMode_SourceOut:
- cg_mode = kCGCompositeModeSourceOut;
- break;
- case QPainter::CompositionMode_DestinationOut:
- cg_mode = kCGCompositeModeDestinationOut;
- break;
- case QPainter::CompositionMode_SourceAtop:
- cg_mode = kCGCompositeModeSourceAtop;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- cg_mode = kCGCompositeModeDestinationAtop;
- break;
- case QPainter::CompositionMode_Xor:
- cg_mode = kCGCompositeModeXOR;
- break;
- }
- if (cg_mode > -1)
- CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
- } else {
- bool needPrivateAPI = false;
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
- int cg_mode = kCGBlendModeNormal;
- switch (mode) {
- case QPainter::CompositionMode_Multiply:
- cg_mode = kCGBlendModeMultiply;
- break;
- case QPainter::CompositionMode_Screen:
- cg_mode = kCGBlendModeScreen;
- break;
- case QPainter::CompositionMode_Overlay:
- cg_mode = kCGBlendModeOverlay;
- break;
- case QPainter::CompositionMode_Darken:
- cg_mode = kCGBlendModeDarken;
- break;
- case QPainter::CompositionMode_Lighten:
- cg_mode = kCGBlendModeLighten;
- break;
- case QPainter::CompositionMode_ColorDodge:
- cg_mode = kCGBlendModeColorDodge;
- break;
- case QPainter::CompositionMode_ColorBurn:
- cg_mode = kCGBlendModeColorBurn;
- break;
- case QPainter::CompositionMode_HardLight:
- cg_mode = kCGBlendModeHardLight;
- break;
- case QPainter::CompositionMode_SoftLight:
- cg_mode = kCGBlendModeSoftLight;
- break;
- case QPainter::CompositionMode_Difference:
- cg_mode = kCGBlendModeDifference;
- break;
- case QPainter::CompositionMode_Exclusion:
- cg_mode = kCGBlendModeExclusion;
- break;
- case QPainter::CompositionMode_Plus:
- needPrivateAPI = true;
- cg_mode = kCGCompositeModePlusLighter;
- break;
- default:
- break;
- }
- if (!needPrivateAPI)
- CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
- else
- CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
- }
+ int cg_mode = kCGBlendModeNormal;
+ switch (mode) {
+ case QPainter::CompositionMode_Multiply:
+ cg_mode = kCGBlendModeMultiply;
+ break;
+ case QPainter::CompositionMode_Screen:
+ cg_mode = kCGBlendModeScreen;
+ break;
+ case QPainter::CompositionMode_Overlay:
+ cg_mode = kCGBlendModeOverlay;
+ break;
+ case QPainter::CompositionMode_Darken:
+ cg_mode = kCGBlendModeDarken;
+ break;
+ case QPainter::CompositionMode_Lighten:
+ cg_mode = kCGBlendModeLighten;
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ cg_mode = kCGBlendModeColorDodge;
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ cg_mode = kCGBlendModeColorBurn;
+ break;
+ case QPainter::CompositionMode_HardLight:
+ cg_mode = kCGBlendModeHardLight;
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ cg_mode = kCGBlendModeSoftLight;
+ break;
+ case QPainter::CompositionMode_Difference:
+ cg_mode = kCGBlendModeDifference;
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ cg_mode = kCGBlendModeExclusion;
+ break;
+ case QPainter::CompositionMode_Plus:
+ cg_mode = kCGBlendModePlusLighter;
+ break;
+ case QPainter::CompositionMode_SourceOver:
+ cg_mode = kCGBlendModeNormal;
+ break;
+ case QPainter::CompositionMode_DestinationOver:
+ cg_mode = kCGBlendModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cg_mode = kCGBlendModeClear;
+ break;
+ case QPainter::CompositionMode_Source:
+ cg_mode = kCGBlendModeCopy;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cg_mode = -1;
+ break;
+ case QPainter::CompositionMode_SourceIn:
+ cg_mode = kCGBlendModeSourceIn;
+ break;
+ case QPainter::CompositionMode_DestinationIn:
+ cg_mode = kCGCompositeModeDestinationIn;
+ break;
+ case QPainter::CompositionMode_SourceOut:
+ cg_mode = kCGBlendModeSourceOut;
+ break;
+ case QPainter::CompositionMode_DestinationOut:
+ cg_mode = kCGBlendModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_SourceAtop:
+ cg_mode = kCGBlendModeSourceAtop;
+ break;
+ case QPainter::CompositionMode_DestinationAtop:
+ cg_mode = kCGBlendModeDestinationAtop;
+ break;
+ case QPainter::CompositionMode_Xor:
+ cg_mode = kCGBlendModeXOR;
+ break;
+ default:
+ break;
+ }
+ if (cg_mode > -1) {
+ CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
}
}
@@ -1645,8 +1539,6 @@ void QCoreGraphicsPaintEnginePrivate::drawPath(uchar ops, CGMutablePathRef path)
if (!(q->state->renderHints() & QPainter::Antialiasing)) {
if (current.pen.style() == Qt::SolidLine || current.pen.width() >= 3)
CGContextTranslateCTM(hd, double(pixelSize.x()) * 0.25, double(pixelSize.y()) * 0.25);
- else if (current.pen.style() == Qt::DotLine && QSysInfo::MacintoshVersion == QSysInfo::MV_10_3)
- ; // Do nothing.
else
CGContextTranslateCTM(hd, 0, double(pixelSize.y()) * 0.1);
}
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index f684fef233..a58514614b 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -412,7 +412,10 @@ void QMacPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti)
{
Q_D(QMacPrintEngine);
Q_ASSERT(d->state == QPrinter::Active);
- d->paintEngine->drawTextItem(p, ti);
+ if (!d->embedFonts)
+ QPaintEngine::drawTextItem(p, ti);
+ else
+ d->paintEngine->drawTextItem(p, ti);
}
void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr)
@@ -457,8 +460,6 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
break;
case PPK_CustomBase:
break;
- case PPK_FontEmbedding:
- break;
case PPK_PageOrder:
// TODO Check if can be supported via Cups Options
break;
@@ -471,6 +472,9 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
break;
// The following keys are properties and settings that are supported by the Mac PrintEngine
+ case PPK_FontEmbedding:
+ d->embedFonts = value.toBool();
+ break;
case PPK_Resolution: {
// TODO It appears the old code didn't actually set the resolution??? Can we delete all this???
int bestResolution = 0;
@@ -622,9 +626,6 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_CustomBase:
// Special case, leave null
break;
- case PPK_FontEmbedding:
- ret = false;
- break;
case PPK_PageOrder:
// TODO Check if can be supported via Cups Options
ret = QPrinter::FirstPageFirst;
@@ -648,6 +649,9 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
break;
// The following keys are properties and settings that are supported by the Mac PrintEngine
+ case PPK_FontEmbedding:
+ ret = d->embedFonts;
+ break;
case PPK_CollateCopies: {
Boolean status;
PMGetCollate(d->settings(), &status);
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
index c7307688ae..c99069b7f7 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h
+++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -124,10 +124,11 @@ public:
QString m_creator;
QPaintEngine *paintEngine;
QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant> valueCache;
+ uint embedFonts;
QMacPrintEnginePrivate() : mode(QPrinter::ScreenResolution), state(QPrinter::Idle),
m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))),
- printInfo(0), paintEngine(0) {}
+ printInfo(0), paintEngine(0), embedFonts(true) {}
~QMacPrintEnginePrivate();
void initialize();
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index 142362a065..351f94be2b 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -39,6 +39,7 @@
#include "qwindowsdirect2dwindow.h"
#include "qwindowscontext.h"
+#include "qwindowsguieventdispatcher.h"
#include <qplatformdefs.h>
#include <QtCore/QCoreApplication>
@@ -47,6 +48,16 @@
QT_BEGIN_NAMESPACE
+class QWindowsDirect2DEventDispatcher : public QWindowsGuiEventDispatcher
+{
+public:
+ QWindowsDirect2DEventDispatcher(QObject *parent = 0)
+ : QWindowsGuiEventDispatcher(parent)
+ {
+ uninstallMessageHook(); // ### Workaround for QTBUG-42428
+ }
+};
+
class QWindowsDirect2DIntegrationPrivate
{
public:
@@ -237,6 +248,11 @@ QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(Q
return new QWindowsDirect2DBackingStore(window);
}
+QAbstractEventDispatcher *QWindowsDirect2DIntegration::createEventDispatcher() const
+{
+ return new QWindowsDirect2DEventDispatcher;
+}
+
QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const
{
return &d->m_d2dContext;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
index b410464372..c72b22a6e8 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
@@ -56,6 +56,7 @@ public:
QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
QWindowsDirect2DContext *direct2DContext() const;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index c13f0f333a..a86bb0ee04 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -1471,7 +1471,8 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
r.x(), r.y() + r.height()
};
const QVectorPath vp(points, 4, 0, QVectorPath::RectangleHint);
- const QBrush brush(sr.isValid() ? pm.copy(sr.toRect()) : pm);
+ QBrush brush(sr.isValid() ? pm.copy(sr.toRect()) : pm);
+ brush.setTransform(QTransform::fromTranslate(r.x(), r.y()));
rasterFill(vp, brush);
return;
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
index ef02d77375..c89d293d1d 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -199,12 +199,13 @@ void QWindowsDirect2DWindow::setupSwapChain()
void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
{
- if (!m_swapChain)
- return;
-
m_pixmap.reset();
m_bitmap.reset();
m_deviceContext->SetTarget(Q_NULLPTR);
+ m_needsFullFlush = true;
+
+ if (!m_swapChain)
+ return;
HRESULT hr = m_swapChain->ResizeBuffers(0,
size.width(), size.height(),
@@ -212,8 +213,6 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
0);
if (FAILED(hr))
qWarning("%s: Could not resize swap chain: %#x", __FUNCTION__, hr);
-
- m_needsFullFlush = true;
}
QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const
diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro
index 89d8d42cea..13481f6198 100644
--- a/src/plugins/platforms/directfb/directfb.pro
+++ b/src/plugins/platforms/directfb/directfb.pro
@@ -29,6 +29,8 @@ HEADERS = qdirectfbintegration.h \
qdirectfbscreen.h \
qdirectfbeglhooks.h
+contains(QT_CONFIG, libudev): DEFINES += QDEVICEDISCOVERY_UDEV
+
# ### port the GL context
contains(QT_CONFIG, directfb_egl) {
HEADERS += qdirectfb_egl.h
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index ddf19face6..1b042a0743 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -67,11 +67,13 @@ QByteArray QEglFSHooks::fbDeviceName() const
int QEglFSHooks::framebufferIndex() const
{
int fbIndex = 0;
+#ifndef QT_NO_REGULAREXPRESSION
QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)"));
QRegularExpressionMatch match = fbIndexRx.match(fbDeviceName());
if (match.hasMatch())
fbIndex = match.captured(1).toInt();
+#endif
return fbIndex;
}
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index c7d8b55b19..c5ab3b52f5 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -76,7 +76,6 @@ protected:
private:
friend class QEglFSWindow;
- EGLDisplay m_dpy;
EGLSurface m_surface;
QPlatformCursor *m_cursor;
QEGLPlatformWindow *m_rootWindow;
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index ef1f496b29..59c2014d66 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -103,7 +103,7 @@ void QEglFSWindow::create()
if (isRaster()) {
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
- context->setFormat(window()->requestedFormat());
+ context->setFormat(m_format);
context->setScreen(window()->screen());
if (!context->create())
qFatal("EGLFS: Failed to create compositing context");
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index ce7dfe2606..ffffc4cbc4 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -241,11 +241,11 @@ enum SetJumpResult
kJumpedFromUserMainTrampoline,
};
-// We define qt_main so that user_main_trampoline() will not cause
+// We define qtmn so that user_main_trampoline() will not cause
// missing symbols in the case of hybrid applications that don't
-// user our main wrapper. Since the symbol is weak, it will not
+// use our main wrapper. Since the symbol is weak, it will not
// get used or cause a clash in the normal Qt application usecase,
-// where we rename main to qt_main.
+// where we rename main to qtmn before linking.
extern "C" int __attribute__((weak)) qtmn(int argc, char *argv[])
{
Q_UNUSED(argc);
@@ -317,11 +317,16 @@ static bool rootLevelRunLoopIntegration()
}
#if defined(Q_PROCESSOR_X86)
-# define SET_STACK_POINTER "mov %0, %%esp"
# define FUNCTION_CALL_ALIGNMENT 16
+# if defined(Q_PROCESSOR_X86_32)
+# define SET_STACK_POINTER "mov %0, %%esp"
+# elif defined(Q_PROCESSOR_X86_64)
+# define SET_STACK_POINTER "movq %0, %%rsp"
+# endif
#elif defined(Q_PROCESSOR_ARM)
-# define SET_STACK_POINTER "mov sp, %0"
+# // Valid for both 32 and 64-bit ARM
# define FUNCTION_CALL_ALIGNMENT 4
+# define SET_STACK_POINTER "mov sp, %0"
#else
# error "Unknown processor family"
#endif
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h
index c09987f9dc..f7b9cd7015 100644
--- a/src/plugins/platforms/ios/qiosglobal.h
+++ b/src/plugins/platforms/ios/qiosglobal.h
@@ -41,6 +41,16 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods);
+
+#if !defined(QT_NO_DEBUG)
+#define qImDebug(...) \
+ for (bool qt_category_enabled = lcQpaInputMethods().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
+ QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, lcQpaInputMethods().categoryName()).debug(__VA_ARGS__)
+#else
+#define qImDebug() QT_NO_QDEBUG_MACRO()
+#endif
+
class QPlatformScreen;
bool isQtApplication();
@@ -52,7 +62,7 @@ QPointF fromCGPoint(const CGPoint &point);
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation);
UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation);
-QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen);
+
int infoPlistValue(NSString* key, int defaultValue);
QT_END_NAMESPACE
@@ -61,4 +71,14 @@ QT_END_NAMESPACE
+(id)currentFirstResponder;
@end
+class FirstResponderCandidate : public QScopedValueRollback<UIResponder *>
+{
+public:
+ FirstResponderCandidate(UIResponder *);
+ static UIResponder *currentCandidate() { return s_firstResponderCandidate; }
+
+private:
+ static UIResponder *s_firstResponderCandidate;
+};
+
#endif // QIOSGLOBAL_H
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index 7ff4950599..3ecd0ca61f 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -46,6 +46,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
+
bool isQtApplication()
{
// Returns \c true if the plugin is in full control of the whole application. This means
@@ -125,15 +127,6 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation)
return uiOrientation;
}
-QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen)
-{
- // UIScreen is always in portrait. Use this function to convert CGRects
- // aligned with UIScreen into whatever is the current orientation of QScreen.
- QRect geometry = screen->geometry();
- return geometry.width() < geometry.height() ? rect
- : QRect(rect.y(), geometry.height() - rect.width() - rect.x(), rect.height(), rect.width());
-}
-
int infoPlistValue(NSString* key, int defaultValue)
{
static NSBundle *bundle = [NSBundle mainBundle];
@@ -148,6 +141,27 @@ int infoPlistValue(NSString* key, int defaultValue)
@end
@implementation QtFirstResponderEvent
+- (void) dealloc
+{
+ self.firstResponder = 0;
+ [super dealloc];
+}
+@end
+
+
+@implementation UIView (QtFirstResponder)
+- (UIView*)qt_findFirstResponder
+{
+ if ([self isFirstResponder])
+ return self;
+
+ for (UIView *subview in self.subviews) {
+ if (UIView *firstResponder = [subview qt_findFirstResponder])
+ return firstResponder;
+ }
+
+ return nil;
+}
@end
@implementation UIResponder (QtFirstResponder)
@@ -162,9 +176,20 @@ int infoPlistValue(NSString* key, int defaultValue)
- (void)qt_findFirstResponder:(id)sender event:(QtFirstResponderEvent *)event
{
Q_UNUSED(sender);
- event.firstResponder = self;
+
+ if ([self isKindOfClass:[UIView class]])
+ event.firstResponder = [static_cast<UIView *>(self) qt_findFirstResponder];
+ else
+ event.firstResponder = [self isFirstResponder] ? self : nil;
}
@end
+FirstResponderCandidate::FirstResponderCandidate(UIResponder *responder)
+ : QScopedValueRollback<UIResponder *>(s_firstResponderCandidate, responder)
+{
+}
+
+UIResponder *FirstResponderCandidate::s_firstResponderCandidate = 0;
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h
index 8850bbf80e..d2a9c261ba 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.h
+++ b/src/plugins/platforms/ios/qiosinputcontext.h
@@ -42,6 +42,7 @@
const char kImePlatformDataInputView[] = "inputView";
const char kImePlatformDataInputAccessoryView[] = "inputAccessoryView";
+const char kImePlatformDataReturnKeyType[] = "returnKeyType";
QT_BEGIN_NAMESPACE
@@ -50,9 +51,10 @@ QT_BEGIN_NAMESPACE
struct ImeState
{
- ImeState() : currentState(0) {}
+ ImeState() : currentState(0), focusObject(0) {}
Qt::InputMethodQueries update(Qt::InputMethodQueries properties);
QInputMethodQueryEvent currentState;
+ QObject *focusObject;
};
class QIOSInputContext : public QPlatformInputContext
@@ -65,7 +67,8 @@ public:
void showInputPanel();
void hideInputPanel();
- void hideVirtualKeyboard();
+
+ void clearCurrentFocusObject();
bool isInputPanelVisible() const;
void setFocusObject(QObject *object);
@@ -80,6 +83,9 @@ public:
void commit();
const ImeState &imeState() { return m_imeState; };
+ bool inputMethodAccepted() const;
+
+ static QIOSInputContext *instance();
private:
QIOSKeyboardListener *m_keyboardListener;
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index b403154321..e417e9a1fb 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -44,26 +44,30 @@
#import <UIKit/UIGestureRecognizerSubclass.h>
#include "qiosglobal.h"
+#include "qiosintegration.h"
#include "qiostextresponder.h"
+#include "qiosviewcontroller.h"
#include "qioswindow.h"
#include "quiview.h"
#include <QGuiApplication>
#include <QtGui/private/qwindow_p.h>
+// -------------------------------------------------------------------------
+
static QUIView *focusView()
{
return qApp->focusWindow() ?
reinterpret_cast<QUIView *>(qApp->focusWindow()->winId()) : 0;
}
-@interface QIOSKeyboardListener : UIGestureRecognizer {
+// -------------------------------------------------------------------------
+
+@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> {
@public
QIOSInputContext *m_context;
BOOL m_keyboardVisible;
BOOL m_keyboardVisibleAndDocked;
- BOOL m_touchPressWhileKeyboardVisible;
- BOOL m_keyboardHiddenByGesture;
QRectF m_keyboardRect;
CGRect m_keyboardEndRect;
NSTimeInterval m_duration;
@@ -76,13 +80,11 @@ static QUIView *focusView()
- (id)initWithQIOSInputContext:(QIOSInputContext *)context
{
- self = [super initWithTarget:self action:@selector(gestureTriggered)];
+ self = [super initWithTarget:self action:@selector(gestureStateChanged:)];
if (self) {
m_context = context;
m_keyboardVisible = NO;
m_keyboardVisibleAndDocked = NO;
- m_touchPressWhileKeyboardVisible = NO;
- m_keyboardHiddenByGesture = NO;
m_duration = 0;
m_curve = UIViewAnimationCurveEaseOut;
m_viewController = 0;
@@ -98,10 +100,9 @@ static QUIView *focusView()
Q_ASSERT(m_viewController);
// Attach 'hide keyboard' gesture to the window, but keep it disabled when the
- // keyboard is not visible. Note that we never trigger the gesture the way it is intended
- // since we don't want to cancel touch events and interrupt flicking etc. Instead we use
- // the gesture framework more as an event filter and hide the keyboard silently.
+ // keyboard is not visible.
self.enabled = NO;
+ self.cancelsTouchesInView = NO;
self.delaysTouchesEnded = NO;
[m_viewController.view.window addGestureRecognizer:self];
}
@@ -155,11 +156,19 @@ static QUIView *focusView()
// Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
m_keyboardVisibleAndDocked = YES;
m_keyboardEndRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
- self.enabled = YES;
+
if (!m_duration) {
m_duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
m_curve = UIViewAnimationCurve([[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]);
}
+
+ UIResponder *firstResponder = [UIResponder currentFirstResponder];
+ if (![firstResponder isKindOfClass:[QIOSTextInputResponder class]])
+ return;
+
+ // Enable hide-keyboard gesture
+ self.enabled = YES;
+
m_context->scrollToCursor();
}
@@ -168,7 +177,7 @@ static QUIView *focusView()
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
m_keyboardVisibleAndDocked = NO;
m_keyboardEndRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
- if (!m_keyboardHiddenByGesture) {
+ if (self.state != UIGestureRecognizerStateBegan) {
// Only disable the gesture if the hiding of the keyboard was not caused by it.
// Otherwise we need to await the final touchEnd callback for doing some clean-up.
self.enabled = NO;
@@ -201,51 +210,81 @@ static QUIView *focusView()
}
}
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+// -------------------------------------------------------------------------
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
- CGPoint p = [[touches anyObject] locationInView:m_viewController.view.window];
- if (CGRectContainsPoint(m_keyboardEndRect, p)) {
- m_keyboardHiddenByGesture = YES;
- m_context->hideVirtualKeyboard();
- }
+ [super touchesBegan:touches withEvent:event];
- [super touchesMoved:touches withEvent:event];
+ Q_ASSERT(m_keyboardVisibleAndDocked);
+
+ if ([touches count] != 1)
+ self.state = UIGestureRecognizerStateFailed;
}
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
- Q_ASSERT(m_keyboardVisibleAndDocked);
- m_touchPressWhileKeyboardVisible = YES;
- [super touchesBegan:touches withEvent:event];
+ [super touchesMoved:touches withEvent:event];
+
+ if (self.state != UIGestureRecognizerStatePossible)
+ return;
+
+ CGPoint touchPoint = [[touches anyObject] locationInView:m_viewController.view.window];
+ if (CGRectContainsPoint(m_keyboardEndRect, touchPoint))
+ self.state = UIGestureRecognizerStateBegan;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
- m_touchPressWhileKeyboardVisible = NO;
- [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO];
[super touchesEnded:touches withEvent:event];
+
+ [self touchesEndedOrCancelled];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
- m_touchPressWhileKeyboardVisible = NO;
- [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO];
[super touchesCancelled:touches withEvent:event];
+
+ [self touchesEndedOrCancelled];
+}
+
+- (void)touchesEndedOrCancelled
+{
+ // Defer final state change until next runloop iteration, so that Qt
+ // has a chance to process the final touch events first, before we eg.
+ // scroll the view.
+ dispatch_async(dispatch_get_main_queue (), ^{
+ // iOS will transition from began to changed by itself
+ Q_ASSERT(self.state != UIGestureRecognizerStateBegan);
+
+ if (self.state == UIGestureRecognizerStateChanged)
+ self.state = UIGestureRecognizerStateEnded;
+ else
+ self.state = UIGestureRecognizerStateFailed;
+ });
+}
+
+- (void)gestureStateChanged:(id)sender
+{
+ Q_UNUSED(sender);
+
+ if (self.state == UIGestureRecognizerStateBegan) {
+ qImDebug() << "hide keyboard gesture was triggered";
+ UIResponder *firstResponder = [UIResponder currentFirstResponder];
+ Q_ASSERT([firstResponder isKindOfClass:[QIOSTextInputResponder class]]);
+ [firstResponder resignFirstResponder];
+ }
}
-- (void)touchesEndedPostDelivery
+- (void)reset
{
- // Do some clean-up _after_ touchEnd has been delivered to QUIView
- m_keyboardHiddenByGesture = NO;
+ [super reset];
+
if (!m_keyboardVisibleAndDocked) {
+ qImDebug() << "keyboard was hidden, disabling hide-keyboard gesture";
self.enabled = NO;
- if (qApp->focusObject()) {
- // UI Controls are told to gain focus on touch release. So when the 'hide keyboard' gesture
- // finishes, the final touch end can trigger a control to gain focus. This is in conflict with
- // the gesture, so we clear focus once more as a work-around.
- static_cast<QWindowPrivate *>(QObjectPrivate::get(qApp->focusWindow()))->clearFocusObject();
- }
} else {
+ qImDebug() << "gesture completed without triggering, scrolling view to cursor";
m_context->scrollToCursor();
}
}
@@ -261,8 +300,11 @@ Qt::InputMethodQueries ImeState::update(Qt::InputMethodQueries properties)
QInputMethodQueryEvent newState(properties);
- if (qApp && qApp->focusObject())
- QCoreApplication::sendEvent(qApp->focusObject(), &newState);
+ // Update the focus object that the new state is based on
+ focusObject = qApp ? qApp->focusObject() : 0;
+
+ if (focusObject)
+ QCoreApplication::sendEvent(focusObject, &newState);
Qt::InputMethodQueries updatedProperties;
for (uint i = 0; i < (sizeof(Qt::ImQueryAll) * CHAR_BIT); ++i) {
@@ -279,6 +321,11 @@ Qt::InputMethodQueries ImeState::update(Qt::InputMethodQueries properties)
// -------------------------------------------------------------------------
+QIOSInputContext *QIOSInputContext::instance()
+{
+ return static_cast<QIOSInputContext *>(QIOSIntegration::instance()->inputContext());
+}
+
QIOSInputContext::QIOSInputContext()
: QPlatformInputContext()
, m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
@@ -303,16 +350,29 @@ QRectF QIOSInputContext::keyboardRect() const
void QIOSInputContext::showInputPanel()
{
// No-op, keyboard controlled fully by platform based on focus
+ qImDebug() << "can't show virtual keyboard without a focus object, ignoring";
}
void QIOSInputContext::hideInputPanel()
{
- // No-op, keyboard controlled fully by platform based on focus
+ if (![m_textResponder isFirstResponder]) {
+ qImDebug() << "QIOSTextInputResponder is not first responder, ignoring";
+ return;
+ }
+
+ if (qGuiApp->focusObject() != m_imeState.focusObject) {
+ qImDebug() << "current focus object does not match IM state, likely hiding from focusOut event, so ignoring";
+ return;
+ }
+
+ qImDebug() << "hiding VKB as requested by QInputMethod::hide()";
+ [m_textResponder resignFirstResponder];
}
-void QIOSInputContext::hideVirtualKeyboard()
+void QIOSInputContext::clearCurrentFocusObject()
{
- static_cast<QWindowPrivate *>(QObjectPrivate::get(qApp->focusWindow()))->clearFocusObject();
+ if (QWindow *focusWindow = qApp->focusWindow())
+ static_cast<QWindowPrivate *>(QObjectPrivate::get(focusWindow))->clearFocusObject();
}
bool QIOSInputContext::isInputPanelVisible() const
@@ -342,10 +402,10 @@ void QIOSInputContext::scrollToCursor()
if (!isQtApplication())
return;
- if (m_keyboardListener->m_touchPressWhileKeyboardVisible) {
- // Don't scroll to the cursor if the user is touching the screen. This
- // interferes with selection and the 'hide keyboard' gesture. Instead
- // we update scrolling upon touchEnd.
+ if (m_keyboardListener.state == UIGestureRecognizerStatePossible && m_keyboardListener.numberOfTouches == 1) {
+ // Don't scroll to the cursor if the user is touching the screen and possibly
+ // trying to trigger the hide-keyboard gesture.
+ qImDebug() << "preventing scrolling to cursor as we're still waiting for a possible gesture";
return;
}
@@ -415,6 +475,18 @@ void QIOSInputContext::setFocusObject(QObject *focusObject)
{
Q_UNUSED(focusObject);
+ qImDebug() << "new focus object =" << focusObject;
+
+ if (m_keyboardListener.state == UIGestureRecognizerStateChanged) {
+ // A new focus object may be set as part of delivering touch events to
+ // application during the hide-keyboard gesture, but we don't want that
+ // to result in a new object getting focus and bringing the keyboard up
+ // again.
+ qImDebug() << "clearing focus object" << focusObject << "as hide-keyboard gesture is active";
+ clearCurrentFocusObject();
+ return;
+ }
+
reset();
if (m_keyboardListener->m_keyboardVisibleAndDocked)
@@ -425,6 +497,8 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
{
Q_UNUSED(focusWindow);
+ qImDebug() << "new focus window =" << focusWindow;
+
reset();
[m_keyboardListener handleKeyboardRectChanged];
@@ -443,17 +517,59 @@ void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties)
// Mask for properties that we are interested in and see if any of them changed
updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImPlatformData);
+ if (updatedProperties & Qt::ImEnabled) {
+ // Switching on and off input-methods needs a re-fresh of hints and platform
+ // data when we turn them on again, as the IM state we have may have been
+ // invalidated when IM was switched off. We could defer this until we know
+ // if IM was turned on, to limit the extra query parameters, but for simplicity
+ // we always do the update.
+ updatedProperties |= (Qt::ImHints | Qt::ImPlatformData);
+ }
+
+ qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject();
+
Qt::InputMethodQueries changedProperties = m_imeState.update(updatedProperties);
if (changedProperties & (Qt::ImEnabled | Qt::ImHints | Qt::ImPlatformData)) {
// Changes to enablement or hints require virtual keyboard reconfigure
- [m_textResponder release];
- m_textResponder = [[QIOSTextInputResponder alloc] initWithInputContext:this];
- [m_textResponder reloadInputViews];
+
+ qImDebug() << "changed IM properties" << changedProperties << "require keyboard reconfigure";
+
+ if (inputMethodAccepted()) {
+ qImDebug() << "replacing text responder with new text responder";
+ [m_textResponder autorelease];
+ m_textResponder = [[QIOSTextInputResponder alloc] initWithInputContext:this];
+ [m_textResponder becomeFirstResponder];
+ } else if ([UIResponder currentFirstResponder] == m_textResponder) {
+ qImDebug() << "IM not enabled, resigning text responder as first responder";
+ [m_textResponder resignFirstResponder];
+ } else {
+ qImDebug() << "IM not enabled. Text responder not first responder. Nothing to do";
+ }
} else {
[m_textResponder notifyInputDelegate:changedProperties];
}
}
+bool QIOSInputContext::inputMethodAccepted() const
+{
+ // The IM enablement state is based on the last call to update()
+ bool lastKnownImEnablementState = m_imeState.currentState.value(Qt::ImEnabled).toBool();
+
+#if !defined(QT_NO_DEBUG)
+ // QPlatformInputContext keeps a cached value of the current IM enablement state that is
+ // updated by QGuiApplication when the current focus object changes, or by QInputMethod's
+ // update() function. If the focus object changes, but the change is not propagated as
+ // a signal to QGuiApplication due to bugs in the widget/graphicsview/qml stack, we'll
+ // end up with a stale value for QPlatformInputContext::inputMethodAccepted(). To be on
+ // the safe side we always use our own cached value to decide if IM is enabled, and try
+ // to detect the case where the two values are out of sync.
+ if (lastKnownImEnablementState != QPlatformInputContext::inputMethodAccepted())
+ qWarning("QPlatformInputContext::inputMethodAccepted() does not match actual focus object IM enablement!");
+#endif
+
+ return lastKnownImEnablementState;
+}
+
/*!
Called by the input item to reset the input method state.
*/
@@ -478,16 +594,3 @@ void QIOSInputContext::commit()
[m_textResponder unmarkText];
[m_textResponder notifyInputDelegate:Qt::ImSurroundingText];
}
-
-// -------------------------------------------------------------------------
-
-@interface QUIView (InputMethods)
-- (void)reloadInputViews;
-@end
-
-@implementation QUIView (InputMethods)
-- (void)reloadInputViews
-{
- qApp->inputMethod()->reset();
-}
-@end
diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm
index 005b06547e..0f351f785b 100644
--- a/src/plugins/platforms/ios/qiosmenu.mm
+++ b/src/plugins/platforms/ios/qiosmenu.mm
@@ -153,13 +153,29 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
[self setDelegate:self];
[self setDataSource:self];
[self selectRow:m_selectedRow inComponent:0 animated:false];
+ [self listenForKeyboardWillHideNotification:YES];
}
return self;
}
+-(void)listenForKeyboardWillHideNotification:(BOOL)listen
+{
+ if (listen) {
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(cancelMenu)
+ name:@"UIKeyboardWillHideNotification" object:nil];
+ } else {
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:@"UIKeyboardWillHideNotification" object:nil];
+ }
+}
+
-(void)dealloc
{
+ [self listenForKeyboardWillHideNotification:NO];
self.toolbar = 0;
[super dealloc];
}
@@ -193,6 +209,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
- (void)closeMenu
{
+ [self listenForKeyboardWillHideNotification:NO];
if (!m_visibleMenuItems.isEmpty())
QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(m_selectedRow));
else
@@ -201,6 +218,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
- (void)cancelMenu
{
+ [self listenForKeyboardWillHideNotification:NO];
QIOSMenu::currentMenu()->dismiss();
}
@@ -452,11 +470,11 @@ void QIOSMenu::toggleShowUsingUIPickerView(bool show)
Q_ASSERT(!focusObjectWithPickerView);
focusObjectWithPickerView = qApp->focusWindow()->focusObject();
focusObjectWithPickerView->installEventFilter(this);
- qApp->inputMethod()->update(Qt::ImPlatformData);
+ qApp->inputMethod()->update(Qt::ImEnabled | Qt::ImPlatformData);
} else {
Q_ASSERT(focusObjectWithPickerView);
focusObjectWithPickerView->removeEventFilter(this);
- qApp->inputMethod()->update(Qt::ImPlatformData);
+ qApp->inputMethod()->update(Qt::ImEnabled | Qt::ImPlatformData);
focusObjectWithPickerView = 0;
Q_ASSERT(m_pickerView);
@@ -477,6 +495,7 @@ bool QIOSMenu::eventFilter(QObject *obj, QEvent *event)
imPlatformData.insert(kImePlatformDataInputView, QVariant::fromValue(static_cast<void *>(m_pickerView)));
imPlatformData.insert(kImePlatformDataInputAccessoryView, QVariant::fromValue(static_cast<void *>(m_pickerView.toolbar)));
queryEvent->setValue(Qt::ImPlatformData, imPlatformData);
+ queryEvent->setValue(Qt::ImEnabled, true);
return true;
}
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.mm b/src/plugins/platforms/ios/qiosplatformaccessibility.mm
index ad8bd9bdf4..705c626272 100644
--- a/src/plugins/platforms/ios/qiosplatformaccessibility.mm
+++ b/src/plugins/platforms/ios/qiosplatformaccessibility.mm
@@ -58,16 +58,16 @@ void invalidateCache(QAccessibleInterface *iface)
return;
}
- QWindow *win = 0;
- QAccessibleInterface *parent = iface;
- do {
- win = parent->window();
- parent = parent->parent();
- } while (!win && parent);
-
- if (win && win->handle()) {
- QIOSWindow *window = static_cast<QIOSWindow*>(win->handle());
- window->clearAccessibleCache();
+ // This will invalidate everything regardless of what window the
+ // interface belonged to. We might want to revisit this strategy later.
+ // (Therefore this function still takes the interface as argument)
+ // It is also responsible for the bug that focus gets temporary lost
+ // when items get added or removed from the screen
+ foreach (QWindow *win, QGuiApplication::topLevelWindows()) {
+ if (win && win->handle()) {
+ QIOSWindow *window = static_cast<QIOSWindow*>(win->handle());
+ window->clearAccessibleCache();
+ }
}
}
diff --git a/src/plugins/platforms/ios/qiostextresponder.h b/src/plugins/platforms/ios/qiostextresponder.h
index 2923feba3b..118ab8958a 100644
--- a/src/plugins/platforms/ios/qiostextresponder.h
+++ b/src/plugins/platforms/ios/qiostextresponder.h
@@ -47,12 +47,10 @@ class QIOSInputContext;
@interface QIOSTextInputResponder : UIResponder <UITextInputTraits, UIKeyInput, UITextInput>
{
- @public
- QString m_markedText;
- BOOL m_inSendEventToFocusObject;
-
@private
QIOSInputContext *m_inputContext;
+ QString m_markedText;
+ BOOL m_inSendEventToFocusObject;
}
- (id)initWithInputContext:(QIOSInputContext *)context;
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 54362cde7a..2fcc7258f7 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -173,9 +173,13 @@
m_inSendEventToFocusObject = NO;
m_inputContext = inputContext;
+ QVariantMap platformData = [self imValue:Qt::ImPlatformData].toMap();
Qt::InputMethodHints hints = Qt::InputMethodHints([self imValue:Qt::ImHints].toUInt());
- self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+ self.returnKeyType = platformData.value(kImePlatformDataReturnKeyType).isValid() ?
+ UIReturnKeyType(platformData.value(kImePlatformDataReturnKeyType).toInt()) :
+ (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+
self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText);
self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ?
UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault;
@@ -202,7 +206,6 @@
else
self.keyboardType = UIKeyboardTypeDefault;
- QVariantMap platformData = [self imValue:Qt::ImPlatformData].toMap();
if (UIView *inputView = static_cast<UIView *>(platformData.value(kImePlatformDataInputView).value<void *>()))
self.inputView = [[[WrapperView alloc] initWithView:inputView] autorelease];
if (UIView *accessoryView = static_cast<UIView *>(platformData.value(kImePlatformDataInputAccessoryView).value<void *>()))
@@ -218,30 +221,68 @@
[super dealloc];
}
-- (BOOL)isFirstResponder
+- (BOOL)canBecomeFirstResponder
{
return YES;
}
-- (UIResponder*)nextResponder
+- (BOOL)becomeFirstResponder
{
- return qApp->focusWindow() ?
- reinterpret_cast<QUIView *>(qApp->focusWindow()->handle()->winId()) : 0;
+ FirstResponderCandidate firstResponderCandidate(self);
+
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
+
+ if (![super becomeFirstResponder]) {
+ qImDebug() << self << "was not allowed to become first responder";
+ return NO;
+ }
+
+ qImDebug() << self << "became first responder";
+
+ return YES;
}
-/*!
- iOS uses [UIResponder(Internal) _requiresKeyboardWhenFirstResponder] to check if the
- current responder should bring up the keyboard, which in turn checks if the responder
- supports the UIKeyInput protocol. By dynamically reporting our protocol conformance
- we can control the keyboard visibility depending on whether or not we have a focus
- object with IME enabled.
-*/
-- (BOOL)conformsToProtocol:(Protocol *)protocol
+- (BOOL)resignFirstResponder
{
- if (protocol == @protocol(UIKeyInput))
- return m_inputContext->inputMethodAccepted();
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
- return [super conformsToProtocol:protocol];
+ // Don't allow activation events of the window that we're doing text on behalf on
+ // to steal responder.
+ if (FirstResponderCandidate::currentCandidate() == [self nextResponder]) {
+ qImDebug() << "not allowing parent window to steal responder";
+ return NO;
+ }
+
+ if (![super resignFirstResponder])
+ return NO;
+
+ qImDebug() << self << "resigned first responder";
+
+ // Dismissing the keyboard will trigger resignFirstResponder, but so will
+ // a regular responder transfer to another window. In the former case, iOS
+ // will set the new first-responder to our next-responder, and in the latter
+ // case we'll have an active responder candidate.
+ if ([UIResponder currentFirstResponder] == [self nextResponder]) {
+ // We have resigned the keyboard, and transferred back to the parent view, so unset focus object
+ Q_ASSERT(!FirstResponderCandidate::currentCandidate());
+ qImDebug() << "keyboard was closed, clearing focus object";
+ m_inputContext->clearCurrentFocusObject();
+ } else {
+ // We've lost responder status because another Qt window was made active,
+ // another QIOSTextResponder was made first-responder, another UIView was
+ // made first-responder, or the first-responder was cleared globally. In
+ // either of these cases we don't have to do anything.
+ qImDebug() << "lost first responder, but not clearing focus object";
+ }
+
+ return YES;
+}
+
+
+- (UIResponder*)nextResponder
+{
+ return qApp->focusWindow() ?
+ reinterpret_cast<QUIView *>(qApp->focusWindow()->handle()->winId()) : 0;
}
// -------------------------------------------------------------------------
@@ -575,9 +616,8 @@
[self sendEventToFocusObject:press];
[self sendEventToFocusObject:release];
- Qt::InputMethodHints imeHints = static_cast<Qt::InputMethodHints>([self imValue:Qt::ImHints].toUInt());
- if (!(imeHints & Qt::ImhMultiLine))
- m_inputContext->hideVirtualKeyboard();
+ if (self.returnKeyType == UIReturnKeyDone)
+ [self resignFirstResponder];
return;
}
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index c46ed4c0b1..c4b92618b1 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -44,6 +44,7 @@
#include "qiosglobal.h"
#include "qiosintegration.h"
#include "qiosviewcontroller.h"
+#include "qiostextresponder.h"
#include "qioswindow.h"
#include "qiosmenu.h"
@@ -191,33 +192,66 @@
- (BOOL)becomeFirstResponder
{
- if ([super becomeFirstResponder]) {
+ FirstResponderCandidate firstResponderCandidate(self);
+
+ qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
+ << "first:" << [UIResponder currentFirstResponder];
+
+ if (![super becomeFirstResponder]) {
+ qImDebug() << m_qioswindow->window()
+ << "was not allowed to become first responder";
+ return NO;
+ }
+
+ qImDebug() << m_qioswindow->window() << "became first responder";
+
+ if (qGuiApp->focusWindow() != m_qioswindow->window()) {
QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
QWindowSystemInterface::flushWindowSystemEvents();
+ } else {
+ qImDebug() << m_qioswindow->window()
+ << "already active, not sending window activation";
+ }
+
+ return YES;
+}
- return YES;
+- (BOOL)responderShouldTriggerWindowDeactivation:(UIResponder *)responder
+{
+ // We don't want to send window deactivation in case the resign
+ // was a result of another Qt window becoming first responder.
+ if ([responder isKindOfClass:[QUIView class]])
+ return NO;
+
+ // Nor do we want to deactivate the Qt window if the new responder
+ // is temporarily handling text input on behalf of a Qt window.
+ if ([responder isKindOfClass:[QIOSTextInputResponder class]]) {
+ while ((responder = [responder nextResponder])) {
+ if ([responder isKindOfClass:[QUIView class]])
+ return NO;
+ }
}
- return NO;
+ return YES;
}
- (BOOL)resignFirstResponder
{
- if ([super resignFirstResponder]) {
- // We don't want to send window deactivation in case we're in the process
- // of activating another window. The handleWindowActivated of the activation
- // will take care of both.
- dispatch_async(dispatch_get_main_queue (), ^{
- if (![[UIResponder currentFirstResponder] isKindOfClass:[QUIView class]]) {
- QWindowSystemInterface::handleWindowActivated(0);
- QWindowSystemInterface::flushWindowSystemEvents();
- }
- });
-
- return YES;
+ qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
+ << "first:" << [UIResponder currentFirstResponder];
+
+ if (![super resignFirstResponder])
+ return NO;
+
+ qImDebug() << m_qioswindow->window() << "resigned first responder";
+
+ UIResponder *newResponder = FirstResponderCandidate::currentCandidate();
+ if ([self responderShouldTriggerWindowDeactivation:newResponder]) {
+ QWindowSystemInterface::handleWindowActivated(0);
+ QWindowSystemInterface::flushWindowSystemEvents();
}
- return NO;
+ return YES;
}
// -------------------------------------------------------------------------
diff --git a/src/plugins/platforms/ios/quiview_accessibility.mm b/src/plugins/platforms/ios/quiview_accessibility.mm
index 6565e08302..7e1cb9a4fd 100644
--- a/src/plugins/platforms/ios/quiview_accessibility.mm
+++ b/src/plugins/platforms/ios/quiview_accessibility.mm
@@ -48,7 +48,7 @@
- (void)createAccessibleElement:(QAccessibleInterface *)iface
{
- if (!iface || iface->state().invisible)
+ if (!iface || iface->state().invisible || (iface->text(QAccessible::Name).isEmpty() && iface->text(QAccessible::Value).isEmpty() && iface->text(QAccessible::Description).isEmpty()))
return;
QAccessible::Id accessibleId = QAccessible::uniqueId(iface);
UIAccessibilityElement *elem = [[QMacAccessibilityElement alloc] initWithId: accessibleId withAccessibilityContainer: self];
@@ -60,12 +60,9 @@
if (!iface)
return;
- if (iface->childCount() == 0) {
- [self createAccessibleElement: iface];
- } else {
- for (int i = 0; i < iface->childCount(); ++i)
- [self createAccessibleContainer: iface->child(i)];
- }
+ [self createAccessibleElement: iface];
+ for (int i = 0; i < iface->childCount(); ++i)
+ [self createAccessibleContainer: iface->child(i)];
}
- (void)initAccessibility
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
index baa8778153..948d986fc5 100644
--- a/src/plugins/platforms/kms/kms.pro
+++ b/src/plugins/platforms/kms/kms.pro
@@ -9,6 +9,7 @@ QT += core-private gui-private platformsupport-private
qtHaveModule(opengl):QT += opengl-private
DEFINES += MESA_EGL_NO_X11_HEADERS __GBM__
+contains(QT_CONFIG, libudev): DEFINES += QDEVICEDISCOVERY_UDEV
CONFIG += link_pkgconfig egl qpa/genericunixfontdatabase
diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro
index 389d45c29c..5e185e357f 100644
--- a/src/plugins/platforms/linuxfb/linuxfb.pro
+++ b/src/plugins/platforms/linuxfb/linuxfb.pro
@@ -9,6 +9,7 @@ QT += core-private gui-private platformsupport-private
SOURCES = main.cpp qlinuxfbintegration.cpp qlinuxfbscreen.cpp
HEADERS = qlinuxfbintegration.h qlinuxfbscreen.h
+contains(QT_CONFIG, libudev): DEFINES += QDEVICEDISCOVERY_UDEV
CONFIG += qpa/genericunixfontdatabase
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index db48e0ed93..22a4dbb09f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -102,15 +102,6 @@ static inline int componentVerbose(const char *v, const char *keyWord)
return 0;
}
-static inline bool hasTouchSupport(QSysInfo::WinVersion wv)
-{
- enum { QT_SM_DIGITIZER = 94, QT_NID_INTEGRATED_TOUCH = 0x1,
- QT_NID_EXTERNAL_TOUCH = 0x02, QT_NID_MULTI_INPUT = 0x40 };
-
- return wv < QSysInfo::WV_WINDOWS7 ? false :
- (GetSystemMetrics(QT_SM_DIGITIZER) & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT)) != 0;
-}
-
#if !defined(LANG_SYRIAC)
# define LANG_SYRIAC 0x5a
#endif
@@ -318,7 +309,7 @@ QWindowsContextPrivate::QWindowsContextPrivate()
QWindowsContext::shell32dll.init();
QWindowsContext::shcoredll.init();
- if (hasTouchSupport(ver) && QWindowsContext::user32dll.initTouch())
+ if (m_mouseHandler.touchDevice() && QWindowsContext::user32dll.initTouch())
m_systemInfo |= QWindowsContext::SI_SupportsTouch;
#endif // !Q_OS_WINCE
m_displayContext = GetDC(0);
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 4cbead44c5..f1f472b3e2 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -1224,16 +1224,21 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters)
QScopedArrayPointer<WCHAR> buffer(new WCHAR[totalStringLength + 2 * size]);
QScopedArrayPointer<COMDLG_FILTERSPEC> comFilterSpec(new COMDLG_FILTERSPEC[size]);
- const QString matchesAll = QStringLiteral(" (*)");
WCHAR *ptr = buffer.data();
// Split filter specification as 'Texts (*.txt[;] *.doc)'
// into description and filters specification as '*.txt;*.doc'
for (int i = 0; i < size; ++i) {
- // Display glitch (CLSID only): 'All files (*)' shows up as 'All files (*) (*)'
+ // Display glitch (CLSID only): Any filter not filtering on suffix (such as
+ // '*', 'a.*') will be duplicated in combo: 'All files (*) (*)',
+ // 'AAA files (a.*) (a.*)'
QString description = specs[i].description;
- if (!m_hideFiltersDetails && description.endsWith(matchesAll))
- description.truncate(description.size() - matchesAll.size());
+ const QString &filter = specs[i].filter;
+ if (!m_hideFiltersDetails && !filter.startsWith(QLatin1String("*."))) {
+ const int pos = description.lastIndexOf(QLatin1Char('('));
+ if (pos > 0)
+ description.truncate(pos);
+ }
// Add to buffer.
comFilterSpec[i].pszName = ptr;
ptr += description.toWCharArray(ptr);
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index 3b277c0b5a..c0d0c1f77c 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -360,10 +360,10 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
EGLDisplay display = EGL_NO_DISPLAY;
#ifdef EGL_ANGLE_platform_angle_opengl
if (libEGL.eglGetPlatformDisplayEXT && qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) {
- const EGLint anglePlatformAttributes[][3] = {
+ const EGLint anglePlatformAttributes[][5] = {
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE },
- { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE, EGL_NONE }
+ { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, EGL_NONE }
};
const EGLint *attributes = 0;
const QByteArray anglePlatform = qgetenv("QT_ANGLE_PLATFORM");
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
index efef6f4ded..4abf2d703e 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h
@@ -38,13 +38,13 @@
#include <QtCore/QSharedPointer>
#include "qtwindows_additional.h"
-QT_BEGIN_NAMESPACE
-
#if !defined(QT_NO_DIRECTWRITE)
struct IDWriteFactory;
struct IDWriteGdiInterop;
#endif
+QT_BEGIN_NAMESPACE
+
class QWindowsFontEngineData
{
Q_DISABLE_COPY(QWindowsFontEngineData)
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index fd585ee683..e6f30f2c35 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -804,10 +804,8 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
uint format = GGO_METRICS;
if (ttf)
format |= GGO_GLYPH_INDEX;
- int res = GetGlyphOutline(hdc, glyph, format, &gMetric, 0, 0, &mat);
- if (res == GDI_ERROR) {
+ if (GetGlyphOutline(hdc, glyph, format, &gMetric, 0, 0, &mat) == GDI_ERROR)
return false;
- }
// #### obey scale
*metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
(int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 76c5790554..2addb90de3 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -41,16 +41,16 @@
#include <QtGui/private/qfontengine_p.h>
#include <QtCore/QSharedPointer>
-class QWindowsFontEngineData;
-
-struct IDWriteFont ;
-struct IDWriteFontFace ;
-struct IDWriteFactory ;
-struct IDWriteBitmapRenderTarget ;
-struct IDWriteGdiInterop ;
+struct IDWriteFont;
+struct IDWriteFontFace;
+struct IDWriteFactory;
+struct IDWriteBitmapRenderTarget;
+struct IDWriteGdiInterop;
QT_BEGIN_NAMESPACE
+class QWindowsFontEngineData;
+
class QWindowsFontEngineDirectWrite : public QFontEngine
{
public:
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 990dbaeba2..ff9ad1874a 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -39,6 +39,7 @@
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qguiapplication_p.h>
#include <QtGui/QKeyEvent>
QT_BEGIN_NAMESPACE
@@ -1104,9 +1105,17 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
else {
const QString text = uch.isNull() ? QString() : QString(uch);
const char a = uch.row() ? 0 : uch.cell();
+ const Qt::KeyboardModifiers modifiers(state);
+#ifndef QT_NO_SHORTCUT
+ // Is Qt interested in the context menu key?
+ if (modifiers == Qt::SHIFT && code == Qt::Key_F10
+ && !QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(QKeySequence(Qt::SHIFT + Qt::Key_F10))) {
+ return false;
+ }
+#endif // !QT_NO_SHORTCUT
key_recorder.storeKey(msg.wParam, a, state, text);
QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code,
- Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, text, false);
+ modifiers, scancode, msg.wParam, nModifiers, text, false);
result =true;
bool store = true;
#ifndef Q_OS_WINCE
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 39321c3460..acb692579b 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -109,6 +109,30 @@ static inline void compressMouseMove(MSG *msg)
}
}
+static inline QTouchDevice *createTouchDevice()
+{
+ enum { QT_SM_TABLETPC = 86, QT_SM_DIGITIZER = 94, QT_SM_MAXIMUMTOUCHES = 95,
+ QT_NID_INTEGRATED_TOUCH = 0x1, QT_NID_EXTERNAL_TOUCH = 0x02,
+ QT_NID_MULTI_INPUT = 0x40, QT_NID_READY = 0x80 };
+
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7)
+ return 0;
+ const int digitizers = GetSystemMetrics(QT_SM_DIGITIZER);
+ if (!(digitizers & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH)))
+ return 0;
+ const int tabletPc = GetSystemMetrics(QT_SM_TABLETPC);
+ const int maxTouchPoints = GetSystemMetrics(QT_SM_MAXIMUMTOUCHES);
+ qCDebug(lcQpaEvents) << "Digitizers:" << hex << showbase << (digitizers & ~QT_NID_READY)
+ << "Ready:" << (digitizers & QT_NID_READY) << dec << noshowbase
+ << "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints;
+ QTouchDevice *result = new QTouchDevice;
+ result->setType(digitizers & QT_NID_INTEGRATED_TOUCH
+ ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad);
+ result->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
+ result->setMaximumTouchPoints(maxTouchPoints);
+ return result;
+}
+
/*!
\class QWindowsMouseHandler
\brief Windows mouse handler
@@ -122,10 +146,12 @@ static inline void compressMouseMove(MSG *msg)
QWindowsMouseHandler::QWindowsMouseHandler() :
m_windowUnderMouse(0),
m_trackedWindow(0),
- m_touchDevice(0),
+ m_touchDevice(createTouchDevice()),
m_leftButtonDown(false),
m_previousCaptureWindow(0)
{
+ if (m_touchDevice)
+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
}
Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
@@ -404,6 +430,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
typedef QWindowSystemInterface::TouchPoint QTouchPoint;
typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList;
+ Q_ASSERT(m_touchDevice);
const QRect screenGeometry = window->screen()->geometry();
const int winTouchPointCount = msg.wParam;
@@ -464,14 +491,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
if (allStates == Qt::TouchPointReleased)
m_touchInputIDToTouchPointID.clear();
- if (!m_touchDevice) {
- m_touchDevice = new QTouchDevice;
- // TODO: Device used to be hardcoded to screen in previous code.
- m_touchDevice->setType(QTouchDevice::TouchScreen);
- m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
- QWindowSystemInterface::registerTouchDevice(m_touchDevice);
- }
-
QWindowSystemInterface::handleTouchEvent(window,
m_touchDevice,
touchPoints);
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index 967c64e597..6491de93b5 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -51,6 +51,8 @@ class QWindowsMouseHandler
public:
QWindowsMouseHandler();
+ QTouchDevice *touchDevice() const { return m_touchDevice; }
+
bool translateMouseEvent(QWindow *widget, HWND hwnd,
QtWindows::WindowsEventType t, MSG msg,
LRESULT *result);
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
index 5daeee69c0..64aedb1b33 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -35,8 +35,8 @@
QT_BEGIN_NAMESPACE
-QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface)
- : QEGLPlatformContext(format, share, display), m_eglSurface(surface)
+QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config)
+ : QEGLPlatformContext(format, share, display, &config), m_eglSurface(surface)
{
}
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
index fb1199a79e..142e204fc8 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.h
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE
class QWinRTEGLContext : public QEGLPlatformContext
{
public:
- explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface);
+ explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config);
QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index b8ca9fdc66..4fa90b4b68 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -110,7 +110,7 @@ QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *wi
QPlatformOpenGLContext *QWinRTIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
QWinRTScreen *screen = static_cast<QWinRTScreen *>(context->screen()->handle());
- return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface());
+ return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface(), screen->eglConfig());
}
QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 3933902ae3..fadcd01b06 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -33,6 +33,11 @@
#include "qwinrtscreen.h"
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+#include <d3d11.h>
+#include <dxgi1_2.h>
+
#include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h"
#include "qwinrtcursor.h"
@@ -452,6 +457,7 @@ public:
EGLDisplay eglDisplay;
EGLSurface eglSurface;
+ EGLConfig eglConfig;
QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens;
@@ -467,6 +473,7 @@ QWinRTScreen::QWinRTScreen()
Q_D(QWinRTScreen);
d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR;
+ d->eglDisplay = EGL_NO_DISPLAY;
// Obtain the WinRT Application, view, and window
HRESULT hr;
@@ -525,8 +532,10 @@ QWinRTScreen::QWinRTScreen()
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]);
Q_ASSERT_SUCCEEDED(hr);
+#ifndef Q_OS_WINPHONE
hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]);
Q_ASSERT_SUCCEEDED(hr);
+#endif
hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]);
Q_ASSERT_SUCCEEDED(hr);
hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]);
@@ -575,7 +584,43 @@ QWinRTScreen::QWinRTScreen()
if (!eglInitialize(d->eglDisplay, NULL, NULL))
qCritical("Failed to initialize EGL: 0x%x", eglGetError());
- d->eglSurface = eglCreateWindowSurface(d->eglDisplay, q_configFromGLFormat(d->eglDisplay, d->surfaceFormat), d->coreWindow.Get(), NULL);
+ // Check that the device properly supports depth/stencil rendering, and disable them if not
+ ComPtr<ID3D11Device> d3dDevice;
+ const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
+ if (ok && d3dDevice) {
+ ComPtr<IDXGIDevice> dxgiDevice;
+ hr = d3dDevice.As(&dxgiDevice);
+ if (SUCCEEDED(hr)) {
+ ComPtr<IDXGIAdapter> dxgiAdapter;
+ hr = dxgiDevice->GetAdapter(&dxgiAdapter);
+ if (SUCCEEDED(hr)) {
+ ComPtr<IDXGIAdapter2> dxgiAdapter2;
+ hr = dxgiAdapter.As(&dxgiAdapter2);
+ if (SUCCEEDED(hr)) {
+ DXGI_ADAPTER_DESC2 desc;
+ hr = dxgiAdapter2->GetDesc2(&desc);
+ if (SUCCEEDED(hr)) {
+ // The following GPUs do not render properly with depth/stencil
+ if ((desc.VendorId == 0x4d4f4351 && desc.DeviceId == 0x32303032)) { // Qualcomm Adreno 225
+ d->surfaceFormat.setDepthBufferSize(-1);
+ d->surfaceFormat.setStencilBufferSize(-1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->surfaceFormat);
+ d->surfaceFormat = q_glFormatFromConfig(d->eglDisplay, d->eglConfig, d->surfaceFormat);
+ const QRect bounds = geometry();
+ EGLint windowAttributes[] = {
+ EGL_FIXED_SIZE_ANGLE, EGL_TRUE,
+ EGL_WIDTH, bounds.width(),
+ EGL_HEIGHT, bounds.height(),
+ EGL_NONE
+ };
+ d->eglSurface = eglCreateWindowSurface(d->eglDisplay, d->eglConfig, d->coreWindow.Get(), windowAttributes);
if (d->eglSurface == EGL_NO_SURFACE)
qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
}
@@ -706,6 +751,12 @@ EGLSurface QWinRTScreen::eglSurface() const
return d->eglSurface;
}
+EGLConfig QWinRTScreen::eglConfig() const
+{
+ Q_D(const QWinRTScreen);
+ return d->eglConfig;
+}
+
QWindow *QWinRTScreen::topWindow() const
{
Q_D(const QWinRTScreen);
@@ -1010,26 +1061,33 @@ HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationPr
return S_OK;
}
-HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
+HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *)
{
Q_D(QWinRTScreen);
- Size size;
- HRESULT hr = args->get_Size(&size);
- RETURN_OK_IF_FAILED("Failed to get window size.");
-
+ Rect size;
+ HRESULT hr;
+ hr = d->coreWindow->get_Bounds(&size);
+ RETURN_OK_IF_FAILED("Failed to get window bounds");
QSizeF logicalSize = QSizeF(size.Width, size.Height);
+#ifndef Q_OS_WINPHONE // This handler is called from orientation changed, in which case we should always update the size
if (d->logicalSize == logicalSize)
return S_OK;
+#endif
- // Regardless of state, all top-level windows are viewport-sized - this might change if
- // a more advanced compositor is written.
d->logicalSize = logicalSize;
- const QRect newGeometry = geometry();
- QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
- QPlatformScreen::resizeMaximizedWindows();
- handleExpose();
-
+ if (d->eglDisplay) {
+ const QRect newGeometry = geometry();
+#ifdef Q_OS_WINPHONE // Resize the EGL window
+ const int width = newGeometry.width() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::LandscapeOrientation ? -1 : 1);
+ const int height = newGeometry.height() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::InvertedLandscapeOrientation ? -1 : 1);
+ eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_WIDTH, width);
+ eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_HEIGHT, height);
+#endif
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
+ QPlatformScreen::resizeMaximizedWindows();
+ handleExpose();
+ }
return S_OK;
}
@@ -1099,6 +1157,9 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
}
+#ifdef Q_OS_WINPHONE // The size changed handler is ignored in favor of this callback
+ onSizeChanged(Q_NULLPTR, Q_NULLPTR);
+#endif
return S_OK;
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index e70a998216..c95a2073ed 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -109,6 +109,7 @@ public:
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
EGLDisplay eglDisplay() const; // To opengl context
EGLSurface eglSurface() const; // To window
+ EGLConfig eglConfig() const;
private:
void handleExpose();
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 35d6b64008..8800db60d3 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -40,6 +40,14 @@
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
+#include <qfunctions_winrt.h>
+#include <windows.ui.viewmanagement.h>
+#include <wrl.h>
+
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
QT_BEGIN_NAMESPACE
QWinRTWindow::QWinRTWindow(QWindow *window)
@@ -48,6 +56,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
{
setWindowFlags(window->flags());
setWindowState(window->windowState());
+ setWindowTitle(window->title());
handleContentOrientationChange(window->contentOrientation());
setGeometry(window->geometry());
}
@@ -94,6 +103,24 @@ void QWinRTWindow::setVisible(bool visible)
m_screen->removeWindow(window());
}
+void QWinRTWindow::setWindowTitle(const QString &title)
+{
+ ComPtr<IApplicationViewStatics2> statics;
+ HRESULT hr;
+
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
+ IID_PPV_ARGS(&statics));
+ RETURN_VOID_IF_FAILED("Could not get ApplicationViewStatics");
+
+ ComPtr<IApplicationView> view;
+ hr = statics->GetForCurrentView(&view);
+ RETURN_VOID_IF_FAILED("Could not access currentView");
+
+ HStringReference str(reinterpret_cast<LPCWSTR>(title.utf16()), title.length());
+ hr = view->put_Title(str.Get());
+ RETURN_VOID_IF_FAILED("Unable to set window title");
+}
+
void QWinRTWindow::raise()
{
if (!window()->isTopLevel())
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 85f3efab5d..7e01efa818 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -52,6 +52,7 @@ public:
bool isExposed() const;
void setGeometry(const QRect &rect);
void setVisible(bool visible);
+ void setWindowTitle(const QString &title);
void raise();
void lower();
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index 84910c4172..5777980093 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -75,7 +75,6 @@ private:
void init(QXcbScreen *screen, QPlatformOpenGLContext *share);
void init(QXcbScreen *screen, QPlatformOpenGLContext *share, const QVariant &nativeHandle);
- QXcbScreen *m_screen;
Display *m_display;
GLXFBConfig m_config;
GLXContext m_context;
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index 45856f3e6c..8b3893ec2f 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -276,7 +276,7 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
- m_screen = connection()->screens().at(connection()->primaryScreen());
+ m_screen = connection()->primaryScreen();
int x = 0, y = 0, w = 3, h = 3;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 835c414d85..5510c3b1b4 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -244,7 +244,7 @@ void QXcbConnection::updateScreens()
// the first or an exact match. An exact match isn't
// always available if primary->output is XCB_NONE
// or currently disconnected output.
- if (m_primaryScreen == xcbScreenNumber) {
+ if (m_primaryScreenNumber == xcbScreenNumber) {
if (!primaryScreen || (primary && outputs[i] == primary->output)) {
primaryScreen = screen;
siblings.prepend(siblings.takeLast());
@@ -306,7 +306,7 @@ void QXcbConnection::updateScreens()
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName)
: m_connection(0)
, m_canGrabServer(canGrabServer)
- , m_primaryScreen(0)
+ , m_primaryScreenNumber(0)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
, xfixes_first_event(0)
@@ -331,7 +331,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
#ifdef XCB_USE_XLIB
dpy = XOpenDisplay(m_displayName.constData());
if (dpy) {
- m_primaryScreen = DefaultScreen(dpy);
+ m_primaryScreenNumber = DefaultScreen(dpy);
m_connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
XSetErrorHandler(nullErrorHandler);
@@ -339,7 +339,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_xlib_display = dpy;
}
#else
- m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen);
+ m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
#endif //XCB_USE_XLIB
if (!m_connection || xcb_connection_has_error(m_connection))
@@ -449,6 +449,16 @@ QXcbConnection::~QXcbConnection()
delete m_keyboard;
}
+QXcbScreen *QXcbConnection::primaryScreen() const
+{
+ if (!m_screens.isEmpty()) {
+ Q_ASSERT(m_screens.first()->screenNumber() == primaryScreenNumber());
+ return m_screens.first();
+ }
+
+ return Q_NULLPTR;
+}
+
void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener)
{
m_mapper.insert(id, eventListener);
@@ -1219,7 +1229,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
xcb_window_t QXcbConnection::rootWindow()
{
- return screens().at(primaryScreen())->root();
+ return primaryScreen()->root();
}
void QXcbConnection::processXcbEvents()
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 4a16e116c6..7286b6b89b 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -324,6 +324,7 @@ private:
class QXcbWindowEventListener
{
public:
+ virtual ~QXcbWindowEventListener() {}
virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; }
virtual void handleExposeEvent(const xcb_expose_event_t *) {}
@@ -369,7 +370,8 @@ public:
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
const QList<QXcbScreen *> &screens() const { return m_screens; }
- int primaryScreen() const { return m_primaryScreen; }
+ int primaryScreenNumber() const { return m_primaryScreenNumber; }
+ QXcbScreen *primaryScreen() const;
inline xcb_atom_t atom(QXcbAtom::Atom atom) const { return m_allAtoms[atom]; }
QXcbAtom::Atom qatom(xcb_atom_t atom) const;
@@ -469,6 +471,7 @@ public:
QXcbEventReader *eventReader() const { return m_reader; }
+ bool canGrab() const { return m_canGrabServer; }
protected:
bool event(QEvent *e) Q_DECL_OVERRIDE;
@@ -550,7 +553,7 @@ private:
bool m_canGrabServer;
QList<QXcbScreen *> m_screens;
- int m_primaryScreen;
+ int m_primaryScreenNumber;
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 53437f24ae..7037e102e2 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -311,7 +311,7 @@ void QXcbDrag::move(const QMouseEvent *me)
return;
const QList<QXcbScreen *> &screens = connection()->screens();
- QXcbScreen *screen = screens.at(connection()->primaryScreen());
+ QXcbScreen *screen = connection()->primaryScreen();
for (int i = 0; i < screens.size(); ++i) {
if (screens.at(i)->geometry().contains(globalPos)) {
screen = screens.at(i);
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index d3533b8e44..3818494d99 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -92,11 +92,11 @@
QT_BEGIN_NAMESPACE
-#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
// Find out if our parent process is gdb by looking at the 'exe' symlink under /proc,.
// or, for older Linuxes, read out 'cmdline'.
static bool runningUnderDebugger()
{
+#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
const QString parentProc = QLatin1String("/proc/") + QString::number(getppid());
const QFileInfo parentProcExe(parentProc + QLatin1String("/exe"));
if (parentProcExe.isSymLink())
@@ -113,12 +113,15 @@ static bool runningUnderDebugger()
s += c;
}
return s == "gdb";
-}
+#else
+ return false;
#endif
+}
QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char **argv)
: m_services(new QGenericUnixServices)
, m_instanceName(0)
+ , m_canGrab(true)
{
qRegisterMetaType<QXcbWindow*>();
#ifdef XCB_USE_XLIB
@@ -126,16 +129,10 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
#endif
m_nativeInterface.reset(new QXcbNativeInterface);
- bool canGrab = true;
- #if defined(QT_DEBUG) && defined(Q_OS_LINUX)
- canGrab = !runningUnderDebugger();
- #endif
- static bool canNotGrabEnv = qgetenv("QT_XCB_NO_GRAB_SERVER").length();
- if (canNotGrabEnv)
- canGrab = false;
-
// Parse arguments
const char *displayName = 0;
+ bool noGrabArg = false;
+ bool doGrabArg = false;
if (argc) {
int j = 1;
for (int i = 1; i < argc; i++) {
@@ -146,13 +143,35 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
displayName = argv[++i];
else if (arg == "-name" && i < argc - 1)
m_instanceName = argv[++i];
+ else if (arg == "-nograb")
+ noGrabArg = true;
+ else if (arg == "-dograb")
+ doGrabArg = true;
else
argv[j++] = argv[i];
}
argc = j;
} // argc
- m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab, displayName);
+ bool underDebugger = runningUnderDebugger();
+ if (noGrabArg && doGrabArg && underDebugger) {
+ qWarning() << "Both -nograb and -dograb command line arguments specified. Please pick one. -nograb takes prcedence";
+ doGrabArg = false;
+ }
+
+#if defined(QT_DEBUG)
+ if (!noGrabArg && !doGrabArg && underDebugger) {
+ qDebug("Qt: gdb: -nograb added to command-line options.\n"
+ "\t Use the -dograb option to enforce grabbing.");
+ }
+#endif
+ m_canGrab = (!underDebugger && noGrabArg) || (underDebugger && doGrabArg);
+
+ static bool canNotGrabEnv = qEnvironmentVariableIsSet("QT_XCB_NO_GRAB_SERVER");
+ if (canNotGrabEnv)
+ m_canGrab = false;
+
+ m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, displayName);
for (int i = 0; i < parameters.size() - 1; i += 2) {
#ifdef Q_XCB_DEBUG
@@ -408,19 +427,19 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
case QPlatformIntegration::StartDragTime:
case QPlatformIntegration::KeyboardAutoRepeatRate:
case QPlatformIntegration::PasswordMaskDelay:
- case QPlatformIntegration::FontSmoothingGamma:
case QPlatformIntegration::StartDragVelocity:
case QPlatformIntegration::UseRtlExtensions:
case QPlatformIntegration::PasswordMaskCharacter:
// TODO using various xcb, gnome or KDE settings
break; // Not implemented, use defaults
+ case QPlatformIntegration::FontSmoothingGamma:
+ // Match Qt 4.8 text rendering, and rendering of other X11 toolkits.
+ return qreal(1.0);
case QPlatformIntegration::StartDragDistance: {
// The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but
// on a high-resolution screen it makes sense to increase it.
- const QList<QXcbScreen *> &screens = defaultConnection()->screens();
qreal dpi = 100.0;
- if (screens.length() > 0) {
- const QXcbScreen *screen = screens.at(defaultConnection()->primaryScreen());
+ if (const QXcbScreen *screen = defaultConnection()->primaryScreen()) {
if (screen->logicalDpi().first > dpi)
dpi = screen->logicalDpi().first;
if (screen->logicalDpi().second > dpi)
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index ffb068ecb3..db6ad541ea 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -117,6 +117,7 @@ private:
mutable QByteArray m_wmClass;
const char *m_instanceName;
+ bool m_canGrab;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index dae3a79628..260fb46309 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -721,7 +721,7 @@ void QXcbKeyboard::updateKeymap()
if (xkb_keymap) {
new_state = xkb_state_new(xkb_keymap);
} else {
- printKeymapError("Failed to compile a keymap!");
+ printKeymapError("Qt: Failed to compile a keymap!");
m_config = false;
return;
}
@@ -737,6 +737,8 @@ void QXcbKeyboard::updateKeymap()
xkb_state = new_state;
if (!connection()->hasXKB())
updateXKBMods();
+
+ checkForLatinLayout();
}
#ifndef QT_NO_XKB
@@ -824,37 +826,137 @@ void QXcbKeyboard::updateXKBMods()
xkb_mods.mod5 = xkb_keymap_mod_get_index(xkb_keymap, "Mod5");
}
+static bool isLatin(xkb_keysym_t sym)
+{
+ return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
+}
+
+void QXcbKeyboard::checkForLatinLayout()
+{
+ m_hasLatinLayout = false;
+ const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(xkb_keymap);
+ const xcb_keycode_t minKeycode = connection()->setup()->min_keycode;
+ const xcb_keycode_t maxKeycode = connection()->setup()->max_keycode;
+ struct xkb_state *kb_state = xkb_state_new(xkb_keymap);
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
+ xkb_state_update_mask(kb_state, 0, 0, 0, 0, 0, layout);
+ for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code);
+ // if layout can produce any of these latin letters (chosen
+ // arbitrarily) then it must be a latin key based layout
+ if (sym == XK_q || sym == XK_a || sym == XK_e) {
+ m_hasLatinLayout = true;
+ xkb_state_unref(kb_state);
+ return;
+ }
+ }
+ }
+ xkb_state_unref(kb_state);
+}
+
+xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const
+{
+ xkb_layout_index_t layout;
+ xkb_keysym_t sym = XKB_KEY_NoSymbol;
+ const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(xkb_keymap, keycode);
+ const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(xkb_state, keycode);
+ // Look at user layouts in the order in which they are defined in system
+ // settings to find a latin keysym.
+ for (layout = 0; layout < layoutCount; ++layout) {
+ if (layout == currentLayout)
+ continue;
+ const xkb_keysym_t *syms;
+ xkb_level_index_t level = xkb_state_key_get_level(xkb_state, keycode, layout);
+ if (xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, layout, level, &syms) != 1)
+ continue;
+ if (isLatin(syms[0])) {
+ sym = syms[0];
+ break;
+ }
+ }
+ // If user layouts don't contain any layout that results in a latin key, we query a
+ // key from "US" layout, this allows for latin-key-based shorcuts to work even when
+ // users have only one (non-latin) layout set.
+ xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
+ xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
+ if (sym == XKB_KEY_NoSymbol && !m_hasLatinLayout) {
+ if (!latin_keymap) {
+ const struct xkb_rule_names names = { xkb_names.rules, xkb_names.model, "us", 0, 0 };
+ latin_keymap = xkb_keymap_new_from_names(xkb_context, &names, (xkb_keymap_compile_flags)0);
+ static bool printFailure = true;
+ if (!latin_keymap && printFailure) {
+ // print message about failure to compile US keymap only once,
+ // no need to do this on every key press.
+ printFailure = false;
+ printKeymapError("Qt: Failed to compile US keymap, shortcut handling with "
+ "non-Latin keyboard layouts may not be fully functional!");
+ }
+ }
+ if (latin_keymap) {
+ struct xkb_state *latin_state = xkb_state_new(latin_keymap);
+ if (latin_state) {
+ xkb_state_update_mask(latin_state, 0, latchedMods, lockedMods, 0, 0, 0);
+ sym = xkb_state_key_get_one_sym(latin_state, keycode);
+ xkb_state_unref(latin_state);
+ } else {
+ qWarning("QXcbKeyboard: failed to create a state for US keymap!");
+ }
+ }
+ }
+ if (sym == XKB_KEY_NoSymbol)
+ return sym;
+ // Check for uniqueness, consider the following setup:
+ // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active).
+ // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+<physical x key>,
+ // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained
+ // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired
+ // then the obtained key is not unique. This prevents ctrl+<physical q key> from generating a ctrl+q
+ // shortcut in the above described setup. We don't want ctrl+<physical x key> and ctrl+<physical q key> to
+ // generate the same shortcut event in this case.
+ const xcb_keycode_t minKeycode = connection()->setup()->min_keycode;
+ const xcb_keycode_t maxKeycode = connection()->setup()->max_keycode;
+ struct xkb_state *kb_state = xkb_state_new(xkb_keymap);
+ for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) {
+ xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, prevLayout);
+ for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
+ xkb_keysym_t prevSym = xkb_state_key_get_one_sym(kb_state, code);
+ if (prevSym == sym) {
+ sym = XKB_KEY_NoSymbol;
+ break;
+ }
+ }
+ }
+ xkb_state_unref(kb_state);
+ return sym;
+}
+
QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
{
// turn off the modifier bits which doesn't participate in shortcuts
Qt::KeyboardModifiers notNeeded = Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier;
Qt::KeyboardModifiers modifiers = event->modifiers() &= ~notNeeded;
// create a fresh kb state and test against the relevant modifier combinations
- // NOTE: it should be possible to query the keymap directly, once it gets
- // supported by libxkbcommon
- struct xkb_state * kb_state = xkb_state_new(xkb_keymap);
+ struct xkb_state *kb_state = xkb_state_new(xkb_keymap);
if (!kb_state) {
- qWarning("QXcbKeyboard: failed to compile xkb keymap");
+ qWarning("QXcbKeyboard: failed to compile xkb keymap!");
return QList<int>();
}
// get kb state from the master xkb_state and update the temporary kb_state
- xkb_layout_index_t baseLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_DEPRESSED);
- xkb_layout_index_t latchedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LATCHED);
xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LOCKED);
xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
- xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods,
- baseLayout, latchedLayout, lockedLayout);
+ xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout);
- xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, event->nativeScanCode());
+ quint32 keycode = event->nativeScanCode();
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, keycode);
if (sym == XKB_KEY_NoSymbol) {
xkb_state_unref(kb_state);
return QList<int>();
}
QList<int> result;
- int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode()));
+ int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, keycode));
result += (baseQtKey + modifiers); // The base key is _always_ valid, of course
xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift");
@@ -866,48 +968,33 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
Q_ASSERT(controlMod < 32);
xkb_mod_mask_t depressed;
- struct xkb_keymap *fallback_keymap = 0;
int qtKey = 0;
- //obtain a list of possible shortcuts for the given key event
+ // obtain a list of possible shortcuts for the given key event
for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) {
Qt::KeyboardModifiers neededMods = ModsTbl[i];
if ((modifiers & neededMods) == neededMods) {
-
- depressed = 0;
- if (neededMods & Qt::AltModifier)
- depressed |= (1 << altMod);
- if (neededMods & Qt::ShiftModifier)
- depressed |= (1 << shiftMod);
- if (neededMods & Qt::ControlModifier)
- depressed |= (1 << controlMod);
-
- // update a keyboard state from a set of explicit masks
if (i == 8) {
- // Add a fall back key for layouts with non Latin-1 characters
- if (baseQtKey > 255) {
- struct xkb_rule_names names = { xkb_names.rules, xkb_names.model, "us", 0, 0 };
- fallback_keymap = xkb_keymap_new_from_names(xkb_context, &names, (xkb_keymap_compile_flags)0);
- if (!fallback_keymap)
- continue;
- xkb_state_unref(kb_state);
- kb_state = xkb_state_new(fallback_keymap);
- if (!kb_state)
- continue;
- } else
+ if (isLatin(baseQtKey))
continue;
+ // add a latin key as a fall back key
+ sym = lookupLatinKeysym(keycode);
} else {
- xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods,
- baseLayout, latchedLayout, lockedLayout);
+ depressed = 0;
+ if (neededMods & Qt::AltModifier)
+ depressed |= (1 << altMod);
+ if (neededMods & Qt::ShiftModifier)
+ depressed |= (1 << shiftMod);
+ if (neededMods & Qt::ControlModifier)
+ depressed |= (1 << controlMod);
+ xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout);
+ sym = xkb_state_key_get_one_sym(kb_state, keycode);
}
- sym = xkb_state_key_get_one_sym(kb_state, event->nativeScanCode());
-
if (sym == XKB_KEY_NoSymbol)
continue;
Qt::KeyboardModifiers mods = modifiers & ~neededMods;
- qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode()));
-
- if (qtKey == baseQtKey || qtKey == 0)
+ qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, keycode));
+ if (!qtKey || qtKey == baseQtKey)
continue;
// catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
@@ -926,8 +1013,6 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
}
}
xkb_state_unref(kb_state);
- xkb_keymap_unref(fallback_keymap);
-
return result;
}
@@ -1002,6 +1087,8 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
, xkb_context(0)
, xkb_keymap(0)
, xkb_state(0)
+ , latin_keymap(0)
+ , m_hasLatinLayout(false)
{
memset(&xkb_names, 0, sizeof(xkb_names));
#ifndef QT_NO_XKB
@@ -1029,6 +1116,7 @@ QXcbKeyboard::~QXcbKeyboard()
xkb_state_unref(xkb_state);
xkb_keymap_unref(xkb_keymap);
xkb_context_unref(xkb_context);
+ xkb_keymap_unref(latin_keymap);
if (!connection()->hasXKB())
xcb_key_symbols_free(m_key_symbols);
clearXKBConfig();
@@ -1324,7 +1412,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
if (type == QEvent::KeyPress)
targetWindow->updateNetWmUserTime(time);
- // It is crucial the order of xkb_state_key_get_one_sym & xkb_state_update_key operations is not reversed!
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code);
QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
@@ -1348,15 +1435,22 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
return;
}
- Qt::KeyboardModifiers modifiers = translateModifiers(state);
-
QString string = lookupString(xkb_state, code);
int count = string.size();
string.truncate(count);
- int qtcode = keysymToQtKey(sym, modifiers, string);
- bool isAutoRepeat = false;
+ // Ιf control modifier is set we should prefer latin character, this is
+ // used for standard shortcuts in checks like "key == QKeySequence::Copy",
+ // users can still see the actual X11 keysym with QKeyEvent::nativeVirtualKey
+ Qt::KeyboardModifiers modifiers = translateModifiers(state);
+ xcb_keysym_t translatedSym = XKB_KEY_NoSymbol;
+ if (modifiers & Qt::ControlModifier && !isLatin(sym))
+ translatedSym = lookupLatinKeysym(code);
+ if (translatedSym == XKB_KEY_NoSymbol)
+ translatedSym = sym;
+ int qtcode = keysymToQtKey(translatedSym, modifiers, string);
+ bool isAutoRepeat = false;
if (type == QEvent::KeyPress) {
if (m_autorepeat_code == code) {
isAutoRepeat = true;
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index e71165d824..9f1cf165cb 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -91,6 +91,9 @@ protected:
void updateVModMapping();
void updateVModToRModMapping();
+ xkb_keysym_t lookupLatinKeysym(xkb_keycode_t keycode) const;
+ void checkForLatinLayout();
+
private:
bool m_config;
xcb_keycode_t m_autorepeat_code;
@@ -99,6 +102,7 @@ private:
struct xkb_keymap *xkb_keymap;
struct xkb_state *xkb_state;
struct xkb_rule_names xkb_names;
+ mutable struct xkb_keymap *latin_keymap;
struct _mod_masks {
uint alt;
@@ -128,6 +132,7 @@ private:
_mod_masks vmod_masks;
int core_device_id;
#endif
+ bool m_hasLatinLayout;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 0d75a7f032..3058b29f2d 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -367,7 +367,7 @@ void *QXcbNativeInterface::x11Screen()
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
- return reinterpret_cast<void *>(defaultConnection->primaryScreen());
+ return reinterpret_cast<void *>(defaultConnection->primaryScreenNumber());
return 0;
}
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index 9ec4ea80ec..40a50f61ab 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -59,7 +59,7 @@ QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection)
const xcb_atom_t trayAtom = connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_OPCODE);
if (!trayAtom)
return 0;
- const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreen());
+ const QByteArray netSysTray = QByteArrayLiteral("_NET_SYSTEM_TRAY_S") + QByteArray::number(connection->primaryScreenNumber());
const xcb_atom_t selection = connection->internAtom(netSysTray.constData());
if (!selection)
return 0;
@@ -145,11 +145,8 @@ QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window)
inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged()
{
- const int screen = m_connection->primaryScreen();
- if (screen >= 0 && screen < m_connection->screens().size()) {
- const QPlatformScreen *ps = m_connection->screens().at(screen);
+ if (const QPlatformScreen *ps = m_connection->primaryScreen())
emit systemTrayWindowChanged(ps->screen());
- }
}
// Client messages with the "MANAGER" atom on the root window indicate creation of a new tray.
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 0c2e9d047c..85af8ee1d2 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2170,6 +2170,9 @@ void QXcbWindow::updateSyncRequestCounter()
bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
{
+ if (grab && !connection()->canGrab())
+ return false;
+
if (!grab) {
xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME);
return true;
@@ -2185,6 +2188,9 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
bool QXcbWindow::setMouseGrabEnabled(bool grab)
{
+ if (grab && !connection()->canGrab())
+ return false;
+
if (!grab) {
xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
return true;
@@ -2380,13 +2386,10 @@ void QXcbWindow::setAlertState(bool enabled)
{
if (m_alertState == enabled)
return;
- const NetWmStates oldState = netWmStates();
+
m_alertState = enabled;
- if (enabled) {
- setNetWmStates(oldState | NetWmStateDemandsAttention);
- } else {
- setNetWmStates(oldState & ~NetWmStateDemandsAttention);
- }
+
+ changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
}
bool QXcbWindow::needsSync() const
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
index 0458be32f6..1be9ab3e05 100644
--- a/src/plugins/platforms/xcb/qxcbwmsupport.cpp
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
@@ -56,7 +56,7 @@ void QXcbWMSupport::updateNetWMAtoms()
{
net_wm_atoms.clear();
- xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root();
+ xcb_window_t root = connection()->primaryScreen()->root();
int offset = 0;
int remaining = 0;
do {
@@ -90,7 +90,7 @@ void QXcbWMSupport::updateVirtualRoots()
if (!isSupportedByWM(atom(QXcbAtom::_NET_VIRTUAL_ROOTS)))
return;
- xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root();
+ xcb_window_t root = connection()->primaryScreen()->root();
int offset = 0;
int remaining = 0;
do {
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index 6f2e60c9be..13d42832db 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -262,6 +262,12 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
d_ptr->initialized = true;
}
+QXcbXSettings::~QXcbXSettings()
+{
+ delete d_ptr;
+ d_ptr = 0;
+}
+
bool QXcbXSettings::initialized() const
{
Q_D(const QXcbXSettings);
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.h b/src/plugins/platforms/xcb/qxcbxsettings.h
index 717fe559c9..3496cedf36 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.h
+++ b/src/plugins/platforms/xcb/qxcbxsettings.h
@@ -45,6 +45,7 @@ class QXcbXSettings : public QXcbWindowEventListener
Q_DECLARE_PRIVATE(QXcbXSettings)
public:
QXcbXSettings(QXcbScreen *screen);
+ ~QXcbXSettings();
bool initialized() const;
QVariant setting(const QByteArray &property) const;
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 9aaafadcad..f14fcde73f 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -60,7 +60,7 @@ contains(QT_CONFIG, xcb-xlib) {
# to support custom cursors with depth > 1
contains(QT_CONFIG, xcb-render) {
DEFINES += XCB_USE_RENDER
- LIBS += -lxcb-render -lxcb-render-util -lXrender
+ LIBS += -lxcb-render -lxcb-render-util
}
# build with session management support
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
index c5f8338dab..d7e73c873d 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
+++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
@@ -82,6 +82,7 @@ QGtk2Dialog::QGtk2Dialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget)
QGtk2Dialog::~QGtk2Dialog()
{
+ gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
gtk_widget_destroy(gtkWidget);
}
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
index 7a6acf8b78..d20fbb558b 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.cpp
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -470,9 +470,10 @@ void QPpdPrintDevice::loadPrinter()
m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance);
if (m_cupsDest) {
const char *ppdFile = cupsGetPPD(m_cupsName);
- if (ppdFile)
+ if (ppdFile) {
m_ppd = ppdOpenFile(ppdFile);
- unlink(ppdFile);
+ unlink(ppdFile);
+ }
if (m_ppd) {
ppdMarkDefaults(m_ppd);
} else {
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index 90b204eb0c..4e0a3e0795 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -269,7 +269,8 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem
bool fallBack = state->pen().brush().style() != Qt::SolidPattern
|| qAlpha(brushColor) != 0xff
|| d->txop >= QTransform::TxProject
- || ti.fontEngine->type() != QFontEngine::Win;
+ || ti.fontEngine->type() != QFontEngine::Win
+ || !d->embed_fonts;
if (!fallBack) {
const QVariantMap userData = ti.fontEngine->userData().toMap();
@@ -716,8 +717,6 @@ void QWin32PrintEnginePrivate::fillPath_dev(const QPainterPath &path, const QCol
void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QColor &color, qreal penWidth)
{
- Q_Q(QWin32PrintEngine);
-
composeGdiPath(path);
LOGBRUSH brush;
brush.lbStyle = BS_SOLID;
@@ -1003,8 +1002,6 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
// The following keys are settings that are unsupported by the Windows PrintEngine
case PPK_CustomBase:
break;
- case PPK_FontEmbedding:
- break;
case PPK_PageOrder:
break;
case PPK_PrinterProgram:
@@ -1013,6 +1010,10 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
break;
// The following keys are properties and settings that are supported by the Windows PrintEngine
+ case PPK_FontEmbedding:
+ d->embed_fonts = value.toBool();
+ break;
+
case PPK_CollateCopies:
{
if (!d->devMode)
@@ -1284,9 +1285,6 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
// The following keys are settings that are unsupported by the Windows PrintEngine
// Return sensible default values to ensure consistent behavior across platforms
- case PPK_FontEmbedding:
- value = false;
- break;
case PPK_PageOrder:
value = QPrinter::FirstPageFirst;
break;
@@ -1298,6 +1296,10 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
break;
// The following keys are properties and settings that are supported by the Windows PrintEngine
+ case PPK_FontEmbedding:
+ value = d->embed_fonts;
+ break;
+
case PPK_CollateCopies:
value = d->devMode->dmCollate == DMCOLLATE_TRUE;
break;
diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/kernel/qprintengine_win_p.h
index b84bde8a92..0a87795bb8 100644
--- a/src/printsupport/kernel/qprintengine_win_p.h
+++ b/src/printsupport/kernel/qprintengine_win_p.h
@@ -125,7 +125,8 @@ public:
m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))),
num_copies(1),
printToFile(false),
- reinit(false)
+ reinit(false),
+ embed_fonts(true)
{
}
@@ -216,6 +217,7 @@ public:
uint has_pen : 1;
uint has_brush : 1;
uint has_custom_paper_size : 1;
+ uint embed_fonts : 1;
uint txop;
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index c13b1574d0..437a68e609 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -1632,8 +1632,6 @@ QPrinter::PaperSource QPrinter::paperSource() const
Enabled or disables font embedding depending on \a enable.
- Currently this option is only supported on X11.
-
\sa fontEmbeddingEnabled()
*/
void QPrinter::setFontEmbeddingEnabled(bool enable)
@@ -1647,8 +1645,6 @@ void QPrinter::setFontEmbeddingEnabled(bool enable)
Returns \c true if font embedding is enabled.
- Currently this option is only supported on X11.
-
\sa setFontEmbeddingEnabled()
*/
bool QPrinter::fontEmbeddingEnabled() const
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index d3443e7390..6298262958 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -46,7 +46,6 @@
#include <QtCore/qobject.h>
#include <QtCore/qvariant.h>
#include <QtCore/qurl.h>
-#include <QtCore/qversionnumber.h>
#include <QtCore/qpoint.h>
#include <QtCore/qsize.h>
@@ -164,11 +163,6 @@ template<> inline char *toString(const QVariant &v)
return qstrdup(vstring.constData());
}
-template<> inline char *toString(const QVersionNumber &version)
-{
- return toString(version.toString());
-}
-
template<>
inline bool qCompare(QString const &t1, QLatin1String const &t2, const char *actual,
const char *expected, const char *file, int line)
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 2d92b3f6bd..24d563045b 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -1027,13 +1027,6 @@ QT_BEGIN_NAMESPACE
Returns a textual representation of the given \a variant.
*/
-/*!
- \fn char *QTest::toString(const QVersionNumber &version)
- \overload
-
- Returns a textual representation of the given \a version.
-*/
-
/*! \fn void QTest::qWait(int ms)
Waits for \a ms milliseconds. While waiting, events will be processed and
@@ -1735,7 +1728,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
} else if (strcmp(argv[i], "-vb") == 0) {
QBenchmarkGlobalData::current->verboseOutput = true;
#ifdef Q_OS_WINRT
- } else if (strncmp(argv[i], "-ServerName:", 12) == 0) {
+ } else if (strncmp(argv[i], "-ServerName:", 12) == 0 ||
+ strncmp(argv[i], "-qdevel", 7) == 0) {
continue;
#endif
} else if (argv[i][0] == '-') {
@@ -2159,7 +2153,7 @@ char *toPrettyUnicode(const ushort *p, int length)
break;
}
- if (*p < 0x7f && *p >= 0x20 && *p != '\\') {
+ if (*p < 0x7f && *p >= 0x20 && *p != '\\' && *p != '"') {
*dst++ = *p;
continue;
}
diff --git a/src/testlib/qtesteventloop.h b/src/testlib/qtesteventloop.h
index 9e738d2c47..034655cc50 100644
--- a/src/testlib/qtesteventloop.h
+++ b/src/testlib/qtesteventloop.h
@@ -40,6 +40,7 @@
#include <QtCore/qeventloop.h>
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
+#include <QtCore/qthread.h>
QT_BEGIN_NAMESPACE
@@ -101,6 +102,12 @@ inline void QTestEventLoop::enterLoopMSecs(int ms)
inline void QTestEventLoop::exitLoop()
{
+ if (thread() != QThread::currentThread())
+ {
+ QMetaObject::invokeMethod(this, "exitLoop", Qt::QueuedConnection);
+ return;
+ }
+
if (timerId != -1)
killTimer(timerId);
timerId = -1;
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 7ea953232f..e48fdc1ad0 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -279,7 +279,6 @@ namespace QTest {
return;
QString msg = qFormatLogMessage(type, context, message);
- msg.chop(1); // remove trailing newline
if (type != QtFatalMsg) {
if (counter.load() <= 0)
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index 3924ecfa7f..e0f5546966 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -142,8 +142,9 @@ mac {
}
macx {
- SOURCES += \
- ../../corelib/io/qstandardpaths_mac.cpp
+ OBJECTIVE_SOURCES += \
+ ../../corelib/tools/qstring_mac.mm \
+ ../../corelib/io/qstandardpaths_mac.mm
} else:unix {
SOURCES += \
../../corelib/io/qstandardpaths_unix.cpp
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index acc635c5ca..912fa995fa 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -501,7 +501,7 @@ void Generator::generateCode()
for (int i = 0; i < extraList.count(); ++i) {
fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData());
}
- fprintf(out, " 0\n};\n\n");
+ fprintf(out, " Q_NULLPTR\n};\n\n");
}
//
@@ -513,24 +513,24 @@ void Generator::generateCode()
fprintf(out, "const QMetaObject %s::staticMetaObject = {\n", cdef->qualified.constData());
if (isQObject)
- fprintf(out, " { 0, ");
+ fprintf(out, " { Q_NULLPTR, ");
else if (cdef->superclassList.size())
fprintf(out, " { &%s::staticMetaObject, ", purestSuperClass.constData());
else
- fprintf(out, " { 0, ");
+ fprintf(out, " { Q_NULLPTR, ");
fprintf(out, "qt_meta_stringdata_%s.data,\n"
" qt_meta_data_%s, ", qualifiedClassNameIdentifier.constData(),
qualifiedClassNameIdentifier.constData());
if (hasStaticMetaCall)
fprintf(out, " qt_static_metacall, ");
else
- fprintf(out, " 0, ");
+ fprintf(out, " Q_NULLPTR, ");
if (extraList.isEmpty())
- fprintf(out, "0, ");
+ fprintf(out, "Q_NULLPTR, ");
else
fprintf(out, "qt_meta_extradata_%s, ", qualifiedClassNameIdentifier.constData());
- fprintf(out, "0}\n};\n\n");
+ fprintf(out, "Q_NULLPTR}\n};\n\n");
if(isQt)
return;
@@ -545,7 +545,7 @@ void Generator::generateCode()
// Generate smart cast function
//
fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
- fprintf(out, " if (!_clname) return 0;\n");
+ fprintf(out, " if (!_clname) return Q_NULLPTR;\n");
fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata))\n"
" return static_cast<void*>(const_cast< %s*>(this));\n",
qualifiedClassNameIdentifier.constData(), cdef->classname.constData());
@@ -570,7 +570,7 @@ void Generator::generateCode()
QByteArray superClass = purestSuperClass;
fprintf(out, " return %s::qt_metacast(_clname);\n", superClass.constData());
} else {
- fprintf(out, " return 0;\n");
+ fprintf(out, " return Q_NULLPTR;\n");
}
fprintf(out, "}\n");
@@ -1450,7 +1450,7 @@ void Generator::generateSignal(FunctionDef *def,int index)
fprintf(out, "QPrivateSignal");
fprintf(out, ")%s\n{\n"
- " QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n"
+ " QMetaObject::activate(%s, &staticMetaObject, %d, Q_NULLPTR);\n"
"}\n", constQualifier, thisPtr.constData(), index);
return;
}
@@ -1480,7 +1480,7 @@ void Generator::generateSignal(FunctionDef *def,int index)
fprintf(out, " void *_a[] = { ");
if (def->normalizedType == "void") {
- fprintf(out, "0");
+ fprintf(out, "Q_NULLPTR");
} else {
if (def->returnTypeIsVolatile)
fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))");
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
index 0336981649..687c4f8474 100644
--- a/src/tools/moc/preprocessor.cpp
+++ b/src/tools/moc/preprocessor.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.org>
+** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -1133,10 +1133,6 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
macro.symbols.last().token == PP_HASHHASH) {
error("'##' cannot appear at either end of a macro expansion");
}
- if (macro.symbols.last().token == HASH ||
- macro.symbols.last().token == PP_HASH) {
- error("'#' is not followed by a macro parameter");
- }
}
macros.insert(name, macro);
continue;
diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
index ea24c35a07..dc735df297 100644
--- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -243,6 +243,8 @@ static QString generateInterfaceXml(const ClassDef *mo)
foreach (const FunctionDef &mm, mo->signalList) {
if (mm.wasCloned)
continue;
+ if (!mm.isScriptable && !(flags & QDBusConnection::ExportNonScriptableSignals))
+ continue;
retval += addFunction(mm, true);
}
@@ -250,10 +252,14 @@ static QString generateInterfaceXml(const ClassDef *mo)
if (flags & (QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportNonScriptableSlots)) {
foreach (const FunctionDef &slot, mo->slotList) {
+ if (!slot.isScriptable && !(flags & QDBusConnection::ExportNonScriptableSlots))
+ continue;
if (slot.access == FunctionDef::Public)
retval += addFunction(slot);
}
foreach (const FunctionDef &method, mo->methodList) {
+ if (!method.isScriptable && !(flags & QDBusConnection::ExportNonScriptableSlots))
+ continue;
if (method.access == FunctionDef::Public)
retval += addFunction(method);
}
diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp
index 48218da513..92b6ccca6a 100644
--- a/src/tools/qdoc/cppcodemarker.cpp
+++ b/src/tools/qdoc/cppcodemarker.cpp
@@ -136,7 +136,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
if ((style == Detailed) && !node->parent()->name().isEmpty() &&
(node->type() != Node::Property) && !node->isQmlNode())
- name.prepend(taggedNode(node->parent()) + "::");
+ name.prepend(taggedNode(node->parent()) + "::&#8203;");
switch (node->type()) {
case Node::Namespace:
@@ -212,7 +212,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
bracketed += "slot";
}
if (!bracketed.isEmpty())
- extra += " [" + bracketed.join(' ') + QLatin1Char(']');
+ extra += QLatin1Char('[') + bracketed.join(' ') + QStringLiteral("] ");
}
break;
case Node::Enum:
@@ -283,13 +283,13 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
if (style == Summary) {
if (node->status() == Node::Preliminary) {
- extra += " (preliminary)";
+ extra += "(preliminary) ";
}
else if (node->status() == Node::Deprecated) {
- extra += " (deprecated)";
+ extra += "(deprecated) ";
}
else if (node->status() == Node::Obsolete) {
- extra += " (obsolete)";
+ extra += "(obsolete) ";
}
}
@@ -297,7 +297,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node,
extra.prepend("<@extra>");
extra.append("</@extra>");
}
- return synopsis + extra;
+ return extra + synopsis;
}
/*!
diff --git a/src/tools/qdoc/doc/images/qt-logo.png b/src/tools/qdoc/doc/images/qt-logo.png
index 14ddf2a028..6b72d5fb72 100644
--- a/src/tools/qdoc/doc/images/qt-logo.png
+++ b/src/tools/qdoc/doc/images/qt-logo.png
Binary files differ
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index e158a8dff6..bc79d5ce7f 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -123,7 +123,7 @@ void HtmlGenerator::initializeGenerator(const Config &config)
{ ATOM_FORMATTING_PARAMETER, "<i>", "</i>" },
{ ATOM_FORMATTING_SUBSCRIPT, "<sub>", "</sub>" },
{ ATOM_FORMATTING_SUPERSCRIPT, "<sup>", "</sup>" },
- { ATOM_FORMATTING_TELETYPE, "<tt>", "</tt>" },
+ { ATOM_FORMATTING_TELETYPE, "<code>", "</code>" }, // <tt> tag is not supported in HTML5
{ ATOM_FORMATTING_UICONTROL, "<b>", "</b>" },
{ ATOM_FORMATTING_UNDERLINE, "<u>", "</u>" },
{ 0, 0, 0 }
@@ -156,6 +156,10 @@ void HtmlGenerator::initializeGenerator(const Config &config)
postPostHeader = config.getString(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_POSTPOSTHEADER);
+ prologue = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_PROLOGUE);
+
footer = config.getString(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_FOOTER);
@@ -1035,7 +1039,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
out() << "<dl>\n";
}
else if (atom->string() == ATOM_LIST_VALUE) {
- out() << "<table class=\"valuelist\">";
+ out() << "<div class=\"table\"><table class=\"valuelist\">";
threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable_) {
if (++numTableRows_ % 2 == 1)
@@ -1087,7 +1091,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
// ### Trenton
QString t= protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),relative)));
- out() << "<tr><td class=\"topAlign\"><tt>" << t << "</tt>";
+ out() << "<tr><td class=\"topAlign\"><code>" << t << "</code>";
if (relative->type() == Node::Enum) {
out() << "</td><td class=\"topAlign\">";
@@ -1097,7 +1101,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
if (itemValue.isEmpty())
out() << '?';
else
- out() << "<tt>" << protectEnc(itemValue) << "</tt>";
+ out() << "<code>" << protectEnc(itemValue) << "</code>";
}
skipAhead = 1;
}
@@ -1142,7 +1146,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
out() << "</dl>\n";
}
else if (atom->string() == ATOM_LIST_VALUE) {
- out() << "</table>\n";
+ out() << "</table></div>\n";
}
else {
out() << "</ol>\n";
@@ -1230,7 +1234,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
else if (p2.contains("%"))
width = p2;
}
- out() << "<table class=\"" << attr << "\"";
+ out() << "<div class=\"table\"><table class=\"" << attr << "\"";
if (!width.isEmpty())
out() << " width=\"" << width << "\"";
out() << ">\n ";
@@ -1238,7 +1242,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark
}
break;
case Atom::TableRight:
- out() << "</table>\n";
+ out() << "</table></div>\n";
break;
case Atom::TableHeaderLeft:
out() << "<thead><tr class=\"qt-style\">";
@@ -1652,8 +1656,7 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker)
Generate the TOC for the new doc format.
Don't generate a TOC for the home page.
*/
- if ((dn->name() != QString("index.html")) &&
- (dn->name() != QString("qtexamplesandtutorials.html")))
+ if ((dn->name() != QStringLiteral("index.html")))
generateTableOfContents(dn,marker,0);
generateKeywordAnchors(dn);
@@ -1905,8 +1908,8 @@ void HtmlGenerator::generateHeader(const QString& title,
#else
out() << QString("<?xml version=\"1.0\"?>\n");
#endif
- out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
- out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage);
+ out() << "<!DOCTYPE html>\n";
+ out() << QString("<html lang=\"%1\">\n").arg(naturalLanguage);
out() << "<head>\n";
out() << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
if (node && !node->doc().location().isEmpty())
@@ -1973,7 +1976,8 @@ void HtmlGenerator::generateHeader(const QString& title,
out() << QString(postHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
generateNavigationBar(title,node,marker);
- out() << "<li id=\"buildversion\">\n" << buildversion << "</li>\n";
+ if (!buildversion.isEmpty())
+ out() << "<li id=\"buildversion\">" << buildversion << "</li>\n";
out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
navigationLinks.clear();
@@ -2047,6 +2051,7 @@ void HtmlGenerator::generateTitle(const QString& title,
const Node *relative,
CodeMarker *marker)
{
+ out() << QString(prologue).replace("\\" + COMMAND_VERSION, qdb_->version());
if (!title.isEmpty())
out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n";
if (!subTitle.isEmpty()) {
@@ -2091,12 +2096,9 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
//add the includes to the map
if (!inner->includes().isEmpty()) {
text.clear();
- text << formattingRightMap()[ATOM_FORMATTING_BOLD]
- << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
- << highlightedCode(indent(codeIndent,
+ text << highlightedCode(indent(codeIndent,
marker->markedUpIncludes(inner->includes())),
- inner)
- << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ inner);
requisites.insert(headerText, text);
}
@@ -2131,9 +2133,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
ModuleNode* moduleNode = qdb_->findModule(inner->moduleName());
if (moduleNode && !moduleNode->qtVariable().isEmpty()) {
text.clear();
- text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_TELETYPE)
- << "QT += " + moduleNode->qtVariable()
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_TELETYPE);
+ text << "QT += " + moduleNode->qtVariable();
requisites.insert(qtVariableText, text);
}
}
@@ -2191,7 +2191,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
if (!requisites.isEmpty()) {
//generate the table
- out() << "<table class=\"alignedsummary\">\n";
+ out() << "<div class=\"table\"><table class=\"alignedsummary\">\n";
QStringList::ConstIterator i;
for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
@@ -2209,7 +2209,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker)
out() << "</td></tr>";
}
}
- out() << "</table>";
+ out() << "</table></div>";
}
}
@@ -2246,10 +2246,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker)
else
qmlModuleVersion = qcn->qmlModuleVersion();
text.clear();
- text << formattingRightMap()[ATOM_FORMATTING_BOLD]
- << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]
- << "import " + qcn->qmlModuleName() + " " + qmlModuleVersion
- << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
+ text << "import " + qcn->qmlModuleName() + " " + qmlModuleVersion;
requisites.insert(importText, text);
//add the since and project into the map
@@ -2310,7 +2307,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker)
if (!requisites.isEmpty()) {
//generate the table
- out() << "<table class=\"alignedsummary\">\n";
+ out() << "<div class=\"table\"><table class=\"alignedsummary\">\n";
QStringList::ConstIterator i;
for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) {
@@ -2328,7 +2325,7 @@ void HtmlGenerator::generateQmlRequisites(QmlClassNode *qcn, CodeMarker *marker)
out() << "</td></tr>";
}
}
- out() << "</table>";
+ out() << "</table></div>";
}
}
@@ -2374,12 +2371,10 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
QList<Atom*> toc;
if (node->doc().hasTableOfContents())
toc = node->doc().tableOfContents();
- if (toc.isEmpty() && !sections && !node->isModule())
- return;
-
- //turn off table of contents if HTML.tocdepth is set to 0
- if (tocDepth == 0)
+ if (tocDepth == 0 || (toc.isEmpty() && !sections && !node->isModule())) {
+ generateSidebar();
return;
+ }
QStringList sectionNumber;
int detailsBase = 0;
@@ -2388,6 +2383,7 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
inContents_ = true;
inLink_ = true;
+ out() << "<div class=\"sidebar\">\n";
out() << "<div class=\"toc\">\n";
out() << "<h3><a name=\"toc\">Contents</a></h3>\n";
sectionNumber.append("1");
@@ -2485,10 +2481,21 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
}
out() << "</ul>\n";
out() << "</div>\n";
+ out() << "<div class=\"sidebar-content\" id=\"sidebar-content\"></div>";
+ out() << "</div>\n";
inContents_ = false;
inLink_ = false;
}
+/*!
+ Outputs a placeholder div where the style can add customized sidebar content.
+ */
+void HtmlGenerator::generateSidebar() {
+ out() << "<div class=\"sidebar\">";
+ out() << "<div class=\"sidebar-content\" id=\"sidebar-content\"></div>";
+ out() << "</div>\n";
+}
+
QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
CodeMarker *marker)
{
@@ -2505,6 +2512,7 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
beginSubPage(inner, fileName);
QString title = "List of All Members for " + inner->name();
generateHeader(title, inner, marker);
+ generateSidebar();
generateTitle(title, Text(), SmallSubTitle, inner, marker);
out() << "<p>This is the complete list of members for ";
generateFullName(inner, 0);
@@ -2536,6 +2544,7 @@ QString HtmlGenerator::generateAllQmlMembersFile(QmlClassNode* qml_cn, CodeMarke
beginSubPage(qml_cn, fileName);
QString title = "List of All Members for " + qml_cn->name();
generateHeader(title, qml_cn, marker);
+ generateSidebar();
generateTitle(title, Text(), SmallSubTitle, qml_cn, marker);
out() << "<p>This is the complete list of members for ";
generateFullName(qml_cn, 0);
@@ -2620,6 +2629,7 @@ QString HtmlGenerator::generateLowStatusMemberFile(InnerNode *inner,
beginSubPage(inner, fileName);
generateHeader(title, inner, marker);
+ generateSidebar();
generateTitle(title, Text(), SmallSubTitle, inner, marker);
if (status == CodeMarker::Compat) {
@@ -2696,6 +2706,7 @@ QString HtmlGenerator::generateQmlMemberFile(QmlClassNode* qcn,
beginSubPage(qcn, fileName);
generateHeader(title, qcn, marker);
+ generateSidebar();
generateTitle(title, Text(), SmallSubTitle, qcn, marker);
out() << "<p><b>The following members of QML type "
@@ -2813,7 +2824,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
}
if (allInternal)
return;
- out() << "<table class=\"annotated\">\n";
+ out() << "<div class=\"table\"><table class=\"annotated\">\n";
int row = 0;
NodeList nodes = nm.values();
foreach (const Node* node, nodes) {
@@ -2849,7 +2860,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
}
out() << "</tr>\n";
}
- out() << "</table>\n";
+ out() << "</table></div>\n";
}
/*!
@@ -3101,8 +3112,8 @@ void HtmlGenerator::generateQmlItem(const Node *node,
if (summary)
marked.replace("@name>", "b>");
- marked.replace("<@extra>", "<tt>");
- marked.replace("</@extra>", "</tt>");
+ marked.replace("<@extra>", "<code>");
+ marked.replace("</@extra>", "</code>");
if (summary) {
marked.remove("<@type>");
@@ -3226,11 +3237,11 @@ void HtmlGenerator::generateSection(const NodeList& nl,
alignNames = false;
}
if (alignNames) {
- out() << "<table class=\"alignedsummary\">\n";
+ out() << "<div class=\"table\"><table class=\"alignedsummary\">\n";
}
else {
if (twoColumn)
- out() << "<table class=\"propsummary\">\n"
+ out() << "<div class=\"table\"><table class=\"propsummary\">\n"
<< "<tr><td class=\"topAlign\">";
out() << "<ul>\n";
}
@@ -3261,11 +3272,11 @@ void HtmlGenerator::generateSection(const NodeList& nl,
++m;
}
if (alignNames)
- out() << "</table>\n";
+ out() << "</table></div>\n";
else {
out() << "</ul>\n";
if (twoColumn)
- out() << "</td></tr>\n</table>\n";
+ out() << "</td></tr>\n</table></div>\n";
}
}
}
@@ -3287,11 +3298,11 @@ void HtmlGenerator::generateSectionList(const Section& section,
alignNames = false;
}
if (alignNames) {
- out() << "<table class=\"alignedsummary\">\n";
+ out() << "<div class=\"table\"><table class=\"alignedsummary\">\n";
}
else {
if (twoColumn)
- out() << "<table class=\"propsummary\">\n"
+ out() << "<div class=\"table\"><table class=\"propsummary\">\n"
<< "<tr><td class=\"topAlign\">";
out() << "<ul>\n";
}
@@ -3327,11 +3338,11 @@ void HtmlGenerator::generateSectionList(const Section& section,
++m;
}
if (alignNames)
- out() << "</table>\n";
+ out() << "</table></div>\n";
else {
out() << "</ul>\n";
if (twoColumn)
- out() << "</td></tr>\n</table>\n";
+ out() << "</td></tr>\n</table></div>\n";
}
}
@@ -3395,8 +3406,8 @@ void HtmlGenerator::generateSynopsis(const Node *node,
extraRegExp.setMinimal(true);
marked.remove(extraRegExp);
} else {
- marked.replace("<@extra>", "<tt>");
- marked.replace("</@extra>", "</tt>");
+ marked.replace("<@extra>", "<code>");
+ marked.replace("</@extra>", "</code>");
}
if (style != CodeMarker::Detailed) {
@@ -4236,7 +4247,7 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
const QmlPropertyGroupNode* qpgn = static_cast<const QmlPropertyGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().constBegin();
out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
+ out() << "<div class=\"table\"><table class=\"qmlname\">";
QString heading = qpgn->name() + " group";
out() << "<tr valign=\"top\" class=\"even\" id=\"" << nodeRef << "\">";
@@ -4261,13 +4272,13 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
}
++p;
}
- out() << "</table>";
+ out() << "</table></div>";
out() << "</div>";
}
else if (node->type() == Node::QmlProperty) {
qpn = static_cast<QmlPropertyNode*>(node);
out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
+ out() << "<div class=\"table\"><table class=\"qmlname\">";
out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">";
out() << "<td class=\"tblQmlPropNode\"><p>";
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
@@ -4281,43 +4292,43 @@ void HtmlGenerator::generateDetailedQmlMember(Node *node,
out() << "<span class=\"qmldefault\">default</span>";
generateQmlItem(qpn, relative, marker, false);
out() << "</p></td></tr>";
- out() << "</table>";
+ out() << "</table></div>";
out() << "</div>";
}
else if (node->type() == Node::QmlSignal) {
const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
+ out() << "<div class=\"table\"><table class=\"qmlname\">";
out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">";
out() << "<td class=\"tblQmlFuncNode\"><p>";
out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
out() << "</p></td></tr>";
- out() << "</table>";
+ out() << "</table></div>";
out() << "</div>";
}
else if (node->type() == Node::QmlSignalHandler) {
const FunctionNode* qshn = static_cast<const FunctionNode*>(node);
out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
+ out() << "<div class=\"table\"><table class=\"qmlname\">";
out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">";
out() << "<td class=\"tblQmlFuncNode\"><p>";
out() << "<a name=\"" + refForNode(qshn) + "\"></a>";
generateSynopsis(qshn,relative,marker,CodeMarker::Detailed,false);
out() << "</p></td></tr>";
- out() << "</table>";
+ out() << "</table></div>";
out() << "</div>";
}
else if (node->type() == Node::QmlMethod) {
const FunctionNode* qmn = static_cast<const FunctionNode*>(node);
out() << "<div class=\"qmlproto\">";
- out() << "<table class=\"qmlname\">";
+ out() << "<div class=\"table\"><table class=\"qmlname\">";
out() << "<tr valign=\"top\" class=\"odd\" id=\"" << nodeRef << "\">";
out() << "<td class=\"tblQmlFuncNode\"><p>";
out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
out() << "</p></td></tr>";
- out() << "</table>";
+ out() << "</table></div>";
out() << "</div>";
}
out() << "<div class=\"qmldoc\">";
@@ -4479,8 +4490,6 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element)
return;
QString fileName = manifest +"-manifest.xml";
QFile file(outputDir() + QLatin1Char('/') + fileName);
- if (!file.open(QFile::WriteOnly | QFile::Text))
- return ;
bool demos = false;
if (manifest == "demos")
demos = true;
@@ -4501,7 +4510,7 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element)
}
++i;
}
- if (!proceed)
+ if (!proceed || !file.open(QFile::WriteOnly | QFile::Text))
return;
QXmlStreamWriter writer(&file);
diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h
index 3641e88a47..f7625113f0 100644
--- a/src/tools/qdoc/htmlgenerator.h
+++ b/src/tools/qdoc/htmlgenerator.h
@@ -148,6 +148,7 @@ private:
void generateTableOfContents(const Node *node,
CodeMarker *marker,
QList<Section>* sections = 0);
+ void generateSidebar();
QString generateListOfAllMemberFile(const InnerNode *inner,
CodeMarker *marker);
QString generateAllQmlMembersFile(QmlClassNode* qml_cn, CodeMarker* marker);
@@ -242,6 +243,7 @@ private:
QString endHeader;
QString postHeader;
QString postPostHeader;
+ QString prologue;
QString footer;
QString address;
bool pleaseGenerateMacRef;
@@ -276,6 +278,7 @@ public:
#define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
#define HTMLGENERATOR_POSTHEADER "postheader"
#define HTMLGENERATOR_POSTPOSTHEADER "postpostheader"
+#define HTMLGENERATOR_PROLOGUE "prologue"
#define HTMLGENERATOR_NONAVIGATIONBAR "nonavigationbar"
#define HTMLGENERATOR_NOSUBDIRS "nosubdirs"
#define HTMLGENERATOR_TOCDEPTH "tocdepth"
diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp
index 1e49dd08a0..e152b04ead 100644
--- a/src/tools/qdoc/qdocindexfiles.cpp
+++ b/src/tools/qdoc/qdocindexfiles.cpp
@@ -982,6 +982,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer,
if (!brief.isEmpty())
writer.writeAttribute("brief", brief);
}
+ break;
case Node::QmlModule:
{
const QmlModuleNode* qmn = static_cast<const QmlModuleNode*>(node);
diff --git a/src/tools/qdoc/qmlparser/qqmljs.g b/src/tools/qdoc/qmlparser/qqmljs.g
index de4fec4d56..616e3b3166 100644
--- a/src/tools/qdoc/qmlparser/qqmljs.g
+++ b/src/tools/qdoc/qmlparser/qqmljs.g
@@ -1,21 +1,31 @@
----------------------------------------------------------------------------
--
--- Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+-- Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-- Contact: http://www.qt-project.org/legal
--
-- This file is part of the QtQml module of the Qt Toolkit.
--
--- $QT_BEGIN_LICENSE:LGPL-ONLY$
+-- $QT_BEGIN_LICENSE:LGPL21$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and Digia. For licensing terms and
+-- conditions see http://qt.digia.com/licensing. For further information
+-- use the contact form at http://qt.digia.com/contact-us.
+--
-- GNU Lesser General Public License Usage
--- This file may be used under the terms of the GNU Lesser
--- General Public License version 2.1 as published by the Free Software
--- Foundation and appearing in the file LICENSE.LGPL included in the
--- packaging of this file. Please review the following information to
--- ensure the GNU Lesser General Public License version 2.1 requirements
--- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+-- Alternatively, this file may be used under the terms of the GNU Lesser
+-- General Public License version 2.1 or version 3 as published by the Free
+-- Software Foundation and appearing in the file LICENSE.LGPLv21 and
+-- LICENSE.LGPLv3 included in the packaging of this file. Please review the
+-- following information to ensure the GNU Lesser General Public License
+-- requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+-- http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
--
--- If you have questions regarding the use of this file, please contact
--- us via http://www.qt-project.org/.
+-- In addition, as a special exception, Digia gives you certain additional
+-- rights. These rights are described in the Digia Qt LGPL Exception
+-- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
--
-- $QT_END_LICENSE$
--
@@ -89,41 +99,33 @@
/./****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -142,41 +144,33 @@
/:/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -1090,6 +1084,31 @@ case $rule_number: {
} break;
./
+UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ;
+/.
+case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
+ node->isReadonlyMember = true;
+ node->readonlyToken = loc(1);
+ node->propertyToken = loc(2);
+ node->typeToken = loc(3);
+ node->identifierToken = loc(4);
+ node->semicolonToken = loc(5); // insert a fake ';' before ':'
+
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
+ propertyName->identifierToken = loc(4);
+ propertyName->next = 0;
+
+ AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
+ propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
+ binding->colonToken = loc(5);
+
+ node->binding = binding;
+
+ sym(1).Node = node;
+} break;
+./
+
UiObjectMember: FunctionDeclaration ;
/.
case $rule_number: {
diff --git a/src/tools/qdoc/qmlparser/qqmljsgrammar.cpp b/src/tools/qdoc/qmlparser/qqmljsgrammar.cpp
index d3fb3f8d1f..2600a5e14c 100644
--- a/src/tools/qdoc/qmlparser/qqmljsgrammar.cpp
+++ b/src/tools/qdoc/qmlparser/qqmljsgrammar.cpp
@@ -57,35 +57,35 @@ const short QQmlJSGrammar::lhs [] = {
130, 130, 130, 130, 130, 130, 130, 111, 138, 138,
138, 139, 139, 140, 140, 111, 111, 111, 111, 111,
111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 124, 124, 124, 124, 124, 124, 124, 143,
+ 111, 111, 111, 124, 124, 124, 124, 124, 124, 124,
143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
- 143, 143, 143, 143, 143, 143, 143, 129, 145, 145,
- 145, 145, 144, 144, 149, 149, 149, 147, 147, 150,
- 150, 150, 150, 153, 153, 153, 153, 153, 153, 153,
+ 143, 143, 143, 143, 143, 143, 143, 143, 129, 145,
+ 145, 145, 145, 144, 144, 149, 149, 149, 147, 147,
+ 150, 150, 150, 150, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
- 153, 153, 153, 153, 154, 154, 120, 120, 120, 120,
- 120, 157, 157, 158, 158, 158, 158, 156, 156, 159,
- 159, 160, 160, 161, 161, 161, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 163, 163, 163, 163,
- 164, 164, 164, 165, 165, 165, 165, 166, 166, 166,
- 166, 166, 166, 166, 167, 167, 167, 167, 167, 167,
- 168, 168, 168, 168, 168, 169, 169, 169, 169, 169,
- 170, 170, 171, 171, 172, 172, 173, 173, 174, 174,
- 175, 175, 176, 176, 177, 177, 178, 178, 179, 179,
- 180, 180, 181, 181, 148, 148, 182, 182, 183, 183,
+ 153, 153, 153, 153, 153, 154, 154, 120, 120, 120,
+ 120, 120, 157, 157, 158, 158, 158, 158, 156, 156,
+ 159, 159, 160, 160, 161, 161, 161, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 163, 163, 163,
+ 163, 164, 164, 164, 165, 165, 165, 165, 166, 166,
+ 166, 166, 166, 166, 166, 167, 167, 167, 167, 167,
+ 167, 168, 168, 168, 168, 168, 169, 169, 169, 169,
+ 169, 170, 170, 171, 171, 172, 172, 173, 173, 174,
+ 174, 175, 175, 176, 176, 177, 177, 178, 178, 179,
+ 179, 180, 180, 181, 181, 148, 148, 182, 182, 183,
183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
- 109, 109, 184, 184, 185, 185, 186, 186, 108, 108,
+ 183, 109, 109, 184, 184, 185, 185, 186, 186, 108,
108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 131, 195, 195, 194, 194, 142, 142,
- 196, 196, 197, 197, 199, 199, 198, 200, 203, 201,
- 201, 204, 202, 202, 132, 133, 133, 134, 134, 187,
- 187, 187, 187, 187, 187, 187, 187, 188, 188, 188,
- 188, 189, 189, 189, 189, 190, 190, 135, 136, 205,
- 205, 208, 208, 206, 206, 209, 207, 191, 192, 192,
- 137, 137, 137, 210, 211, 193, 193, 212, 141, 155,
- 155, 213, 213, 152, 152, 151, 151, 214, 112, 112,
- 215, 215, 110, 110, 146, 146, 216};
+ 108, 108, 108, 108, 131, 195, 195, 194, 194, 142,
+ 142, 196, 196, 197, 197, 199, 199, 198, 200, 203,
+ 201, 201, 204, 202, 202, 132, 133, 133, 134, 134,
+ 187, 187, 187, 187, 187, 187, 187, 187, 188, 188,
+ 188, 188, 189, 189, 189, 189, 190, 190, 135, 136,
+ 205, 205, 208, 208, 206, 206, 209, 207, 191, 192,
+ 192, 137, 137, 137, 210, 211, 193, 193, 212, 141,
+ 155, 155, 213, 213, 152, 152, 151, 151, 214, 112,
+ 112, 215, 215, 110, 110, 146, 146, 216};
const short QQmlJSGrammar::rhs [] = {
2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
@@ -95,110 +95,110 @@ const short QQmlJSGrammar::rhs [] = {
1, 1, 1, 1, 1, 1, 1, 3, 1, 1,
1, 0, 1, 2, 4, 6, 6, 3, 3, 7,
7, 4, 4, 5, 5, 5, 6, 6, 10, 6,
+ 7, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 3, 3, 4, 5, 3, 4, 3, 1, 1, 2,
- 3, 4, 1, 2, 3, 7, 8, 1, 3, 1,
+ 2, 3, 3, 4, 5, 3, 4, 3, 1, 1,
+ 2, 3, 4, 1, 2, 3, 7, 8, 1, 3,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 4, 3,
- 5, 1, 2, 4, 4, 4, 3, 0, 1, 1,
- 3, 1, 1, 1, 2, 2, 1, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 3, 3, 3,
- 1, 3, 3, 1, 3, 3, 3, 1, 3, 3,
- 3, 3, 3, 3, 1, 3, 3, 3, 3, 3,
- 1, 3, 3, 3, 3, 1, 3, 3, 3, 3,
- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
- 1, 5, 1, 5, 1, 3, 1, 3, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 3, 5, 1, 2, 4, 4, 4, 3, 0, 1,
+ 1, 3, 1, 1, 1, 2, 2, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 1, 3, 3,
+ 3, 1, 3, 3, 1, 3, 3, 3, 1, 3,
+ 3, 3, 3, 3, 3, 1, 3, 3, 3, 3,
+ 3, 1, 3, 3, 3, 3, 1, 3, 3, 3,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 1, 5, 1, 5, 1, 3, 1, 3, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 3, 0, 1, 1, 3, 0, 1, 1, 1,
+ 1, 1, 3, 0, 1, 1, 3, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 1, 2, 0, 1, 3, 3,
- 1, 1, 1, 3, 1, 3, 2, 2, 2, 0,
- 1, 2, 0, 1, 1, 2, 2, 7, 5, 7,
- 7, 7, 5, 9, 10, 7, 8, 2, 2, 3,
- 3, 2, 2, 3, 3, 3, 3, 5, 5, 3,
- 5, 1, 2, 0, 1, 4, 3, 3, 3, 3,
- 3, 3, 4, 5, 2, 2, 2, 1, 8, 8,
- 7, 1, 3, 0, 1, 0, 1, 1, 1, 1,
- 1, 2, 1, 1, 0, 1, 2};
+ 1, 1, 1, 1, 3, 1, 2, 0, 1, 3,
+ 3, 1, 1, 1, 3, 1, 3, 2, 2, 2,
+ 0, 1, 2, 0, 1, 1, 2, 2, 7, 5,
+ 7, 7, 7, 5, 9, 10, 7, 8, 2, 2,
+ 3, 3, 2, 2, 3, 3, 3, 3, 5, 5,
+ 3, 5, 1, 2, 0, 1, 4, 3, 3, 3,
+ 3, 3, 3, 4, 5, 2, 2, 2, 1, 8,
+ 8, 7, 1, 3, 0, 1, 0, 1, 1, 1,
+ 1, 1, 2, 1, 1, 0, 1, 2};
const short QQmlJSGrammar::action_default [] = {
- 0, 0, 28, 0, 0, 0, 28, 0, 184, 251,
- 215, 223, 219, 163, 235, 211, 3, 148, 81, 164,
- 227, 231, 152, 181, 162, 167, 147, 201, 188, 0,
- 88, 89, 84, 0, 78, 73, 355, 0, 0, 0,
- 0, 86, 0, 0, 82, 85, 77, 0, 0, 74,
- 76, 79, 75, 87, 80, 0, 83, 0, 0, 177,
- 0, 0, 164, 183, 166, 165, 0, 0, 0, 179,
- 180, 178, 182, 0, 212, 0, 0, 0, 0, 202,
- 0, 0, 0, 0, 0, 0, 192, 0, 0, 0,
- 186, 187, 185, 190, 194, 193, 191, 189, 204, 203,
- 205, 0, 220, 0, 216, 0, 0, 158, 145, 157,
- 146, 114, 115, 116, 141, 117, 142, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
- 143, 131, 132, 133, 134, 135, 136, 137, 138, 139,
- 140, 144, 0, 0, 156, 252, 159, 0, 160, 0,
- 161, 155, 0, 248, 241, 239, 246, 247, 245, 244,
- 250, 243, 242, 240, 249, 236, 0, 224, 0, 0,
- 228, 0, 0, 232, 0, 0, 158, 150, 0, 149,
- 0, 154, 168, 0, 344, 344, 345, 0, 342, 0,
- 343, 0, 346, 259, 266, 265, 273, 261, 0, 262,
- 0, 347, 0, 354, 263, 264, 81, 269, 267, 351,
- 348, 353, 270, 0, 281, 0, 0, 0, 0, 338,
- 0, 355, 253, 295, 0, 0, 0, 282, 0, 0,
- 271, 272, 0, 260, 268, 296, 297, 0, 344, 0,
- 0, 346, 0, 339, 340, 0, 328, 352, 0, 312,
- 313, 314, 315, 0, 308, 309, 310, 311, 336, 337,
- 0, 0, 0, 0, 0, 300, 301, 302, 257, 255,
- 217, 225, 221, 237, 213, 258, 0, 164, 229, 233,
- 206, 195, 0, 0, 214, 0, 0, 0, 0, 207,
- 0, 0, 0, 0, 0, 199, 197, 200, 198, 196,
- 209, 208, 210, 0, 222, 0, 218, 0, 256, 164,
- 0, 238, 253, 254, 0, 253, 0, 0, 304, 0,
- 0, 0, 306, 0, 226, 0, 0, 230, 0, 0,
- 234, 293, 0, 285, 294, 288, 0, 292, 0, 253,
- 286, 0, 253, 0, 0, 305, 0, 0, 0, 307,
- 0, 0, 0, 299, 0, 298, 81, 108, 356, 0,
- 0, 113, 275, 278, 0, 114, 281, 117, 142, 119,
- 120, 84, 124, 125, 78, 126, 129, 82, 85, 253,
- 79, 87, 132, 80, 134, 83, 136, 137, 282, 139,
- 140, 144, 0, 110, 109, 112, 96, 111, 95, 0,
- 105, 276, 274, 0, 0, 0, 346, 0, 106, 152,
- 153, 158, 0, 151, 0, 316, 317, 0, 344, 0,
- 0, 346, 0, 107, 0, 0, 0, 319, 324, 322,
- 325, 0, 0, 323, 324, 0, 320, 0, 321, 277,
- 327, 0, 277, 326, 0, 329, 330, 0, 277, 331,
- 332, 0, 0, 333, 0, 0, 0, 334, 335, 170,
- 169, 0, 0, 0, 303, 0, 0, 0, 318, 290,
- 283, 0, 291, 287, 0, 289, 279, 0, 280, 284,
- 0, 0, 346, 0, 341, 99, 0, 0, 103, 90,
- 0, 92, 101, 0, 93, 102, 104, 94, 100, 91,
- 0, 97, 174, 172, 176, 173, 171, 175, 349, 6,
- 350, 4, 2, 71, 98, 0, 0, 74, 76, 75,
- 37, 5, 0, 72, 0, 51, 50, 49, 0, 0,
+ 0, 0, 28, 0, 0, 0, 28, 0, 185, 252,
+ 216, 224, 220, 164, 236, 212, 3, 149, 82, 165,
+ 228, 232, 153, 182, 163, 168, 148, 202, 189, 0,
+ 89, 90, 85, 0, 79, 74, 356, 0, 0, 0,
+ 0, 87, 0, 0, 83, 86, 78, 0, 0, 75,
+ 77, 80, 76, 88, 81, 0, 84, 0, 0, 178,
+ 0, 0, 165, 184, 167, 166, 0, 0, 0, 180,
+ 181, 179, 183, 0, 213, 0, 0, 0, 0, 203,
+ 0, 0, 0, 0, 0, 0, 193, 0, 0, 0,
+ 187, 188, 186, 191, 195, 194, 192, 190, 205, 204,
+ 206, 0, 221, 0, 217, 0, 0, 159, 146, 158,
+ 147, 115, 116, 117, 142, 118, 143, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
+ 144, 132, 133, 134, 135, 136, 137, 138, 139, 140,
+ 141, 145, 0, 0, 157, 253, 160, 0, 161, 0,
+ 162, 156, 0, 249, 242, 240, 247, 248, 246, 245,
+ 251, 244, 243, 241, 250, 237, 0, 225, 0, 0,
+ 229, 0, 0, 233, 0, 0, 159, 151, 0, 150,
+ 0, 155, 169, 0, 345, 345, 346, 0, 343, 0,
+ 344, 0, 347, 260, 267, 266, 274, 262, 0, 263,
+ 0, 348, 0, 355, 264, 265, 82, 270, 268, 352,
+ 349, 354, 271, 0, 282, 0, 0, 0, 0, 339,
+ 0, 356, 254, 296, 0, 0, 0, 283, 0, 0,
+ 272, 273, 0, 261, 269, 297, 298, 0, 345, 0,
+ 0, 347, 0, 340, 341, 0, 329, 353, 0, 313,
+ 314, 315, 316, 0, 309, 310, 311, 312, 337, 338,
+ 0, 0, 0, 0, 0, 301, 302, 303, 258, 256,
+ 218, 226, 222, 238, 214, 259, 0, 165, 230, 234,
+ 207, 196, 0, 0, 215, 0, 0, 0, 0, 208,
+ 0, 0, 0, 0, 0, 200, 198, 201, 199, 197,
+ 210, 209, 211, 0, 223, 0, 219, 0, 257, 165,
+ 0, 239, 254, 255, 0, 254, 0, 0, 305, 0,
+ 0, 0, 307, 0, 227, 0, 0, 231, 0, 0,
+ 235, 294, 0, 286, 295, 289, 0, 293, 0, 254,
+ 287, 0, 254, 0, 0, 306, 0, 0, 0, 308,
+ 0, 0, 0, 300, 0, 299, 82, 109, 357, 0,
+ 0, 114, 276, 279, 0, 115, 282, 118, 143, 120,
+ 121, 85, 125, 126, 79, 127, 130, 83, 86, 254,
+ 80, 88, 133, 81, 135, 84, 137, 138, 283, 140,
+ 141, 145, 0, 111, 110, 113, 97, 112, 96, 0,
+ 106, 277, 275, 0, 0, 0, 347, 0, 107, 153,
+ 154, 159, 0, 152, 0, 317, 318, 0, 345, 0,
+ 0, 347, 0, 108, 0, 0, 0, 320, 325, 323,
+ 326, 0, 0, 324, 325, 0, 321, 0, 322, 278,
+ 328, 0, 278, 327, 0, 330, 331, 0, 278, 332,
+ 333, 0, 0, 334, 0, 0, 0, 335, 336, 171,
+ 170, 0, 0, 0, 304, 0, 0, 0, 319, 291,
+ 284, 0, 292, 288, 0, 290, 280, 0, 281, 285,
+ 0, 0, 347, 0, 342, 100, 0, 0, 104, 91,
+ 0, 93, 102, 0, 94, 103, 105, 95, 101, 92,
+ 0, 98, 175, 173, 177, 174, 172, 176, 350, 6,
+ 351, 4, 2, 72, 99, 0, 0, 75, 77, 76,
+ 37, 5, 0, 73, 0, 51, 50, 49, 0, 0,
64, 0, 65, 41, 42, 43, 44, 46, 47, 68,
45, 0, 51, 0, 0, 0, 0, 0, 60, 0,
61, 0, 0, 32, 0, 0, 69, 33, 0, 36,
- 34, 30, 0, 35, 31, 0, 62, 0, 63, 152,
- 0, 66, 70, 0, 0, 0, 0, 67, 0, 58,
+ 34, 30, 0, 35, 31, 0, 62, 0, 63, 153,
+ 0, 66, 70, 0, 0, 0, 0, 153, 278, 0,
+ 67, 82, 115, 282, 118, 143, 120, 121, 85, 125,
+ 126, 127, 130, 83, 86, 254, 88, 133, 81, 135,
+ 84, 137, 138, 283, 140, 141, 145, 71, 0, 58,
52, 59, 53, 0, 0, 0, 0, 55, 0, 56,
- 57, 54, 0, 0, 152, 277, 0, 0, 48, 81,
- 114, 281, 117, 142, 119, 120, 84, 124, 125, 126,
- 129, 82, 85, 253, 87, 132, 80, 134, 83, 136,
- 137, 282, 139, 140, 144, 0, 38, 39, 0, 40,
- 8, 0, 0, 9, 0, 11, 0, 10, 0, 1,
- 27, 15, 14, 26, 13, 12, 29, 7, 0, 18,
- 0, 19, 0, 24, 25, 0, 20, 21, 0, 22,
- 23, 16, 17, 357};
+ 57, 54, 0, 0, 0, 0, 48, 0, 38, 39,
+ 0, 40, 8, 0, 0, 9, 0, 11, 0, 10,
+ 0, 1, 27, 15, 14, 26, 13, 12, 29, 7,
+ 0, 18, 0, 19, 0, 24, 25, 0, 20, 21,
+ 0, 22, 23, 16, 17, 358};
const short QQmlJSGrammar::goto_default [] = {
- 7, 639, 211, 198, 209, 521, 509, 634, 647, 508,
- 633, 637, 635, 643, 22, 640, 638, 636, 18, 520,
+ 7, 641, 211, 198, 209, 521, 509, 636, 649, 508,
+ 635, 639, 637, 645, 22, 642, 640, 638, 18, 520,
562, 552, 559, 554, 539, 193, 197, 199, 204, 234,
- 212, 231, 543, 583, 582, 203, 233, 26, 487, 486,
+ 212, 231, 543, 613, 612, 203, 233, 26, 487, 486,
359, 358, 9, 357, 360, 202, 480, 361, 109, 17,
147, 24, 13, 146, 19, 25, 59, 23, 8, 28,
27, 280, 15, 274, 10, 270, 12, 272, 11, 271,
@@ -209,295 +209,267 @@ const short QQmlJSGrammar::goto_default [] = {
0};
const short QQmlJSGrammar::action_index [] = {
- 239, 1406, 2692, 2692, 2794, 1119, 115, 29, 168, -106,
- 26, -23, -60, 225, -106, 306, 33, -106, -106, 732,
- -2, 145, 243, 223, -106, -106, -106, 379, 227, 1406,
- -106, -106, -106, 539, -106, -106, 2488, 1698, 1406, 1406,
- 1406, -106, 1023, 1406, -106, -106, -106, 1406, 1406, -106,
- -106, -106, -106, -106, -106, 1406, -106, 1406, 1406, -106,
- 1406, 1406, 114, 206, -106, -106, 1406, 1406, 1406, -106,
- -106, -106, 211, 1406, 302, 1406, 1406, 1406, 1406, 369,
- 1406, 1406, 1406, 1406, 1406, 1406, 226, 1406, 1406, 1406,
- 135, 151, 110, 257, 279, 276, 256, 222, 475, 475,
- 475, 1406, 7, 1406, 57, 2284, 1406, 1406, -106, -106,
+ 264, 1225, 2708, 2708, 2606, 938, 94, 104, 119, -106,
+ 92, 79, 81, 262, -106, 263, 78, -106, -106, 654,
+ 89, 125, 259, 229, -106, -106, -106, 322, 314, 1225,
+ -106, -106, -106, 412, -106, -106, 2300, 1713, 1225, 1225,
+ 1225, -106, 842, 1225, -106, -106, -106, 1225, 1225, -106,
+ -106, -106, -106, -106, -106, 1225, -106, 1225, 1225, -106,
+ 1225, 1225, 141, 216, -106, -106, 1225, 1225, 1225, -106,
+ -106, -106, 209, 1225, 281, 1225, 1225, 1225, 1225, 367,
+ 1225, 1225, 1225, 1225, 1225, 1225, 219, 1225, 1225, 1225,
+ 101, 102, 115, 314, 314, 314, 314, 314, 357, 347,
+ 337, 1225, 71, 1225, 70, 2198, 1225, 1225, -106, -106,
-106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
-106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
-106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, 136, 1406, -106, -106, 30, -24, -106, 1406,
- -106, -106, 1406, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, 1406, 2, 1406, 1406,
- 10, 97, 1406, -106, 2284, 1406, 1406, -106, 141, -106,
- -45, -106, -106, 4, 457, 386, 89, 79, -106, 448,
- -106, 74, 2692, -106, -106, -106, -106, -106, 164, -106,
- 460, -106, 85, -106, -106, -106, 96, -106, -106, -106,
- 2692, -106, -106, 547, -106, 629, 143, 2794, 62, 54,
- 43, 2998, 1406, -106, 51, 1406, 52, -106, 47, 45,
- -106, -106, 454, -106, -106, -106, -106, 64, 352, 31,
- 61, 2692, 27, -106, -106, 2794, -106, -106, 139, -106,
- -106, -106, -106, 126, -106, -106, -106, -106, -106, -106,
- -6, 25, 1406, 130, 159, -106, -106, -106, 1600, -106,
- 68, 65, 5, -106, 308, 60, 3, 835, 99, 105,
- 337, 207, 408, 1406, 317, 1406, 1406, 1406, 1406, 353,
- 1406, 1406, 1406, 1406, 1406, 186, 203, 204, 212, 219,
- 333, 343, 359, 1406, 20, 1406, 202, 1406, -106, 732,
- 1406, -106, 1406, 81, 72, 1406, 77, 2794, -106, 1406,
- 149, 2794, -106, 1406, 80, 1406, 1406, 94, 88, 1406,
- -106, -8, 128, -25, -106, -106, 1406, -106, 471, 1406,
- -106, -53, 1406, -56, 2794, -106, 1406, 134, 2794, -106,
- 1406, 138, 2794, -5, 2794, -106, -4, -106, 9, -9,
- 37, -106, -106, 2794, -12, 555, 32, 629, 123, 1406,
- 2794, 41, 18, 504, 2386, 21, 1023, 49, 46, 1505,
- 2386, 42, 16, 44, 1406, 24, -10, 1406, 17, 1406,
- -15, -18, 2590, -106, -106, -106, -106, -106, -106, 1406,
- -106, -106, -106, -1, -26, -3, 2692, -27, -106, 277,
- -106, 1406, -28, -106, 90, -106, -106, 1, 552, -40,
- -11, 2692, -29, -106, 1406, 117, 14, -106, 50, -106,
- 40, 119, 1406, -106, 11, 35, -106, -54, -106, 2794,
- -106, 116, 2794, -106, 267, -106, -106, 121, 2794, -7,
- -106, -31, -19, -106, 376, 6, 78, -106, -106, -106,
- -106, 1406, 98, 2794, -106, 1406, 106, 2794, -106, 76,
- -106, 254, -106, -106, 1406, -106, -106, 552, -106, -106,
- 71, 75, 2692, 67, -106, -106, 122, 1992, -106, -106,
- 1796, -106, -106, 1894, -106, -106, -106, -106, -106, -106,
- 113, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- 2692, -106, -106, -106, 111, 22, 929, 152, 39, 48,
- -106, -106, 301, -106, 147, -106, -106, -106, 468, 155,
- -106, 2182, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, 178, -30, 463, 181, -14, 400, 229, -106, -32,
- -106, 929, 104, -106, 0, 929, -106, -106, 1311, -106,
- -106, -106, 1215, -106, -106, 248, -106, 2182, -106, 392,
- 59, -106, -106, 244, 552, 73, 2182, -106, 236, -106,
- 237, -106, 70, 15, 368, 214, 355, -106, 103, -106,
- -106, -106, 2087, 721, 392, 2896, 1698, 34, -106, 56,
- 598, 55, 629, 107, 1406, 2794, 53, 23, 544, 36,
- 1023, 58, 66, 1505, 69, 38, 63, 1406, 95, 84,
- 1406, 102, 1406, 83, 82, 124, -106, -106, 87, -106,
- -106, 929, 813, 91, 929, -106, 271, -106, 86, -106,
- -106, 100, 101, -106, -106, -106, -106, -106, 552, -106,
- 209, -106, 109, -106, -106, 552, -106, -106, 92, -106,
- -106, -106, -106, -106,
+ -106, -106, 98, 1225, -106, -106, 66, 65, -106, 1225,
+ -106, -106, 1225, -106, -106, -106, -106, -106, -106, -106,
+ -106, -106, -106, -106, -106, -106, 1225, 44, 1225, 1225,
+ 64, 57, 1225, -106, 2198, 1225, 1225, -106, 137, -106,
+ 49, -106, -106, 93, 344, 474, 95, 86, -106, 390,
+ -106, 85, 2708, -106, -106, -106, -106, -106, 189, -106,
+ 474, -106, 80, -106, -106, -106, 83, -106, -106, -106,
+ 2708, -106, -106, 490, -106, 551, 130, 2606, 46, 51,
+ 52, 2912, 1225, -106, 63, 1225, 56, -106, 58, 60,
+ -106, -106, 474, -106, -106, -106, -106, 61, 474, 62,
+ 67, 2708, 68, -106, -106, 2606, -106, -106, 87, -106,
+ -106, -106, -106, 110, -106, -106, -106, -106, -106, -106,
+ -24, 69, 1225, 122, 143, -106, -106, -106, 1419, -106,
+ 74, 76, 77, -106, 269, 73, 72, 611, 75, 114,
+ 397, 314, 474, 1225, 287, 1225, 1225, 1225, 1225, 397,
+ 1225, 1225, 1225, 1225, 1225, 218, 215, 198, 192, 182,
+ 397, 397, 312, 1225, 55, 1225, 59, 1225, -106, 654,
+ 1225, -106, 1225, 54, 53, 1225, 50, 2606, -106, 1225,
+ 124, 2606, -106, 1225, 90, 1225, 1225, 105, 88, 1225,
+ -106, 84, 157, -27, -106, -106, 1225, -106, 474, 1225,
+ -106, 82, 1225, 91, 2606, -106, 1225, 120, 2606, -106,
+ 1225, 103, 2606, -9, 2606, -106, -2, -106, 11, -30,
+ 17, -106, -106, 2606, -37, 469, 15, 551, 138, 1225,
+ 2606, 14, -16, 433, 2402, -20, 842, 6, 5, 1324,
+ 2402, 4, -36, 2, 1225, 7, -18, 1225, 10, 1225,
+ -26, -13, 2504, -106, -106, -106, -106, -106, -106, 1225,
+ -106, -106, -106, -33, -59, -25, 2708, 23, -106, 197,
+ -106, 1225, -12, -106, 140, -106, -106, 22, 474, -4,
+ 26, 2708, 12, -106, 1225, 113, 30, -106, 142, -106,
+ 142, 121, 1225, -106, -3, 45, -106, -5, -106, 2606,
+ -106, 108, 2606, -106, 207, -106, -106, 106, 2606, 37,
+ -106, 25, 36, -106, 474, 38, 40, -106, -106, -106,
+ -106, 1225, 136, 2606, -106, 1225, 166, 2606, -106, 13,
+ -106, 200, -106, -106, 1225, -106, -106, 474, -106, -106,
+ -17, 16, 2708, -11, -106, -106, 131, 1811, -106, -106,
+ 1615, -106, -106, 1517, -106, -106, -106, -106, -106, -106,
+ 109, -106, -106, -106, -106, -106, -106, -106, -106, -106,
+ 2708, -106, -106, -106, 233, -19, 748, 152, -60, 41,
+ -106, -106, 191, -106, 177, -106, -106, -106, 387, 203,
+ -106, 1906, -106, -106, -106, -106, -106, -106, -106, -106,
+ -106, 180, 43, 376, 174, 48, 474, 240, -106, 8,
+ -106, 748, 111, -106, -1, 748, -106, -106, 1130, -106,
+ -106, -106, 1034, -106, -106, 228, -106, 1906, -106, 295,
+ 21, -106, -106, 184, 379, 39, 2001, 288, 2810, 18,
+ -106, 34, 482, 33, 551, 138, 1225, 2606, 31, 9,
+ 399, 3, 643, 19, 29, 1324, 28, 1, 27, 1225,
+ 24, 0, 1225, 20, 1225, -7, -8, -106, 193, -106,
+ 205, -106, 47, 42, 329, 208, 319, -106, 128, -106,
+ -106, -106, 2096, 748, 1713, 35, -106, 132, -106, -106,
+ 32, -106, -106, 748, 748, 94, 748, -106, 250, -106,
+ 116, -106, -106, 233, 233, -106, -106, -106, -106, -106,
+ 393, -106, 214, -106, 100, -106, -106, 474, -106, -106,
+ 96, -106, -106, -106, -106, -106,
- -111, 43, 59, 70, 71, 369, 40, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, 21,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, 79,
- -111, -111, -111, -16, -111, -111, 5, -26, 23, 73,
- 91, -111, 83, 61, -111, -111, -111, 88, 87, -111,
- -111, -111, -111, -111, -111, 29, -111, 66, 39, -111,
- 97, 193, -111, -111, -111, -111, 160, 180, 183, -111,
- -111, -111, -111, 176, -111, 167, 151, 155, 152, -111,
- 148, 187, 195, 197, 199, 201, -111, 186, 92, 194,
+ -111, 15, 71, 87, 80, 305, -6, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -42,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, 95,
+ -111, -111, -111, 3, -111, -111, -5, -11, 9, 109,
+ 91, -111, 62, 45, -111, -111, -111, 50, 63, -111,
+ -111, -111, -111, -111, -111, 32, -111, 203, 197, -111,
+ 189, 178, -111, -111, -111, -111, 182, 185, 188, -111,
+ -111, -111, -111, 193, -111, 198, 168, 113, 114, -111,
+ 133, 116, 123, 129, 130, 132, -111, 136, 139, 142,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, 103, -111, 108, -111, 181, -2, -42, -111, -111,
+ -111, 148, -111, 151, -111, 186, 6, -37, -111, -111,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, 34, -111, -111, -111, -111, -111, 3,
- -111, -111, 10, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, 127, -111, 109, 15,
- -111, -111, 16, -111, 225, 44, 128, -111, -111, -111,
- -111, -111, -111, -111, 25, 157, -111, -111, -111, 26,
- -111, -111, 24, -111, -111, -111, -111, -111, -111, -111,
- 22, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- 179, -111, -111, 45, -111, 46, -111, 107, -111, 48,
- -111, 106, 62, -111, -111, 163, -3, -111, -111, -111,
- -111, -111, -14, -111, -111, -111, -111, -111, 57, -111,
- -111, 224, -111, -111, -111, 227, -111, -111, -111, -111,
+ -111, -111, -111, 42, -111, -111, -111, -111, -111, 22,
+ -111, -111, 2, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, 96, -111, 66, 21,
+ -111, -111, 0, -111, 274, 35, 88, -111, -111, -111,
+ -111, -111, -111, -111, 41, 75, -111, -111, -111, 49,
+ -111, -111, 48, -111, -111, -111, -111, -111, -111, -111,
+ 57, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ 77, -111, -111, 54, -111, 27, -111, 243, -111, 25,
+ -111, 160, 36, -111, -111, 169, 40, -111, -111, -111,
+ -111, -111, 56, -111, -111, -111, -111, -111, 180, -111,
+ -111, 163, -111, -111, -111, 246, -111, -111, -111, -111,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, 35, -111, -111, -111, -111, -111, 72, -111,
+ -111, -111, 8, -111, -111, -111, -111, -111, 69, -111,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, 12, 264, -111, 258, 246, 254, 209, -111,
- 60, 51, 52, 27, 53, -111, -111, -111, -111, -111,
- -111, -111, -111, 244, -111, 255, -111, 203, -111, -111,
- 207, -111, 217, -111, -111, 198, -111, 208, -111, 8,
- -111, 215, -111, 232, -111, 233, 234, -111, -111, 223,
- -111, -111, -111, -111, -111, -111, 230, -111, 95, 113,
- -111, -111, 153, -111, 156, -111, 2, -111, 147, -111,
- 58, -111, 137, -111, 100, -111, -111, -111, -111, -111,
- -111, -111, -111, 135, -111, 41, -111, 54, -111, 117,
- 162, -111, -111, 50, 169, -111, 174, -111, -111, 32,
- 178, -111, -111, -111, 31, -111, 7, 144, -111, 130,
- -111, -111, 142, -111, -111, -111, -111, -111, -111, 11,
- -111, -111, -111, -111, -111, -111, 214, -111, -111, -111,
- -111, 140, -111, -111, -111, -111, -111, -111, 158, -111,
- -111, 149, -111, -111, 47, -111, -111, -111, -111, -111,
- -55, -111, 38, -111, -67, -111, -111, -111, -111, 263,
- -111, -111, 262, -111, -111, -111, -111, -111, 190, -76,
- -111, -111, 30, -111, 19, -111, 14, -111, -111, -111,
- -111, 33, -111, 272, -111, 64, -111, 175, -111, -111,
- -111, -111, -111, -111, 18, -111, -111, 69, -111, -111,
- -111, -111, 114, -111, -111, -111, -111, 20, -111, -111,
- 110, -111, -111, 28, -111, -111, -111, -111, -111, -111,
+ -111, -111, 61, 211, -111, 272, 257, 256, 236, -111,
+ 81, 83, 85, 68, 94, -111, -111, -111, -111, -111,
+ -111, -111, -111, 235, -111, 218, -111, 209, -111, -111,
+ 244, -111, 227, -111, -111, 228, -111, 238, -111, 33,
+ -111, 167, -111, 245, -111, 253, 254, -111, -111, 225,
+ -111, -111, -111, -111, -111, -111, 217, -111, 194, 213,
+ -111, -111, 208, -111, 207, -111, 52, -111, 205, -111,
+ 55, -111, 201, -111, 199, -111, -111, -111, -111, -111,
+ -111, -111, -111, 278, -111, 39, -111, 34, -111, 173,
+ 219, -111, -111, 53, 231, -111, 73, -111, -111, 44,
+ 59, -111, -111, -111, 47, -111, 24, 102, -111, 101,
+ -111, -111, 111, -111, -111, -111, -111, -111, -111, 26,
+ -111, -111, -111, -111, -111, -111, 65, -111, -111, -111,
+ -111, 76, -111, -111, -111, -111, -111, -111, 79, -111,
+ -111, 89, -111, -111, 51, -111, -111, -111, -111, -111,
+ -62, -111, 37, -111, -63, -111, -111, -111, -111, 387,
+ -111, -111, 264, -111, -111, -111, -111, -111, 158, -54,
+ -111, -111, 28, -111, 38, -111, 23, -111, -111, -111,
+ -111, 43, -111, 78, -111, 58, -111, 67, -111, -111,
+ -111, -111, -111, -111, 18, -111, -111, 195, -111, -111,
+ -111, -111, 161, -111, -111, -111, -111, 20, -111, -111,
+ 157, -111, -111, 31, -111, -111, -111, -111, -111, -111,
-111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- 86, -111, -111, -111, -111, -111, 55, -111, -111, -111,
- -111, -111, -111, -111, -7, -111, -111, -111, 1, -111,
- -111, 329, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, 0, -11, -111, -10, -111, -111, -111,
- -111, 204, -111, -111, -111, 205, -111, -111, 317, -111,
- -111, -111, 311, -111, -111, -111, -111, 370, -111, -111,
- -9, -111, -111, -4, -12, -111, 337, -111, -111, -111,
- -18, -111, -111, -111, -1, -17, -6, -111, -111, -111,
- -111, -111, 466, 78, -111, 82, 307, -13, -111, -111,
- -8, -111, 6, -111, 74, 76, -111, -111, 9, -111,
- 85, -111, -111, 17, -111, -111, -111, 4, -111, -22,
- 84, -111, 67, -111, -111, -111, -111, -111, 49, -111,
- -111, 37, 42, 68, 77, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, 13, -111,
- -111, -111, -111, -111, -111, 36, -111, -111, -111, -111,
- -111, -111, -111, -111};
+ 206, -111, -111, -111, -111, -111, -7, -111, -111, -111,
+ -111, -111, -111, -111, -24, -111, -111, -111, -12, -111,
+ -111, 342, -111, -111, -111, -111, -111, -111, -111, -111,
+ -111, -111, -111, -16, -32, -111, 5, -111, -111, -111,
+ -111, 152, -111, -111, -111, 248, -111, -111, 330, -111,
+ -111, -111, 324, -111, -111, -111, -111, 385, -111, -111,
+ -21, -111, -111, 1, 14, -111, 367, -111, 232, 12,
+ -111, -111, 11, -111, 10, -111, 164, 141, -111, -111,
+ 7, -111, 64, -111, -111, 19, -111, -111, -111, 17,
+ -111, -1, 60, -111, 46, -111, -111, -111, -111, -111,
+ -15, -111, -111, -111, -2, -17, -4, -111, -111, -111,
+ -111, -111, 484, 138, 313, -3, -111, -111, -111, -111,
+ 4, -111, -111, 13, 16, 97, 127, -111, -111, -111,
+ -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
+ -14, -111, -111, -111, -111, -111, -111, -8, -111, -111,
+ -111, -111, -111, -111, -111, -111};
const short QQmlJSGrammar::action_info [] = {
- 166, 438, 551, 245, 344, 454, 346, 544, 342, 336,
- 546, 354, 166, 452, 448, 181, 432, 392, 465, 103,
- 420, 461, 421, 448, -138, 101, 423, 73, 408, 663,
- 406, -135, 413, 558, 405, 404, 151, 418, 149, -141,
- 185, 143, 439, 402, 399, 432, 398, 428, -122, -111,
- 101, -133, 424, -112, 268, 432, -130, 350, 73, 268,
- -122, 262, -141, 245, 312, -130, 456, 558, 307, 283,
- -133, 261, 350, -112, 424, 588, -111, 578, 585, 350,
- 576, 465, 243, 461, 305, 448, 103, 424, 524, 143,
- 184, 240, 558, 474, 241, 329, 323, 189, 268, 305,
- 238, 323, -135, 245, 172, 573, 143, 192, 482, -138,
- 0, 448, 555, 303, 143, 174, 174, 448, 465, 461,
- 558, 143, 484, 442, 143, 143, 174, 451, 303, 435,
- 490, 481, 555, 315, 175, 175, 338, 317, 143, 191,
- 244, 452, 143, 0, 143, 175, 143, 662, 661, 143,
- 60, 416, 415, 660, 659, 325, 64, 143, 463, 326,
- 556, 61, 531, 0, 590, 589, 467, 65, 259, 258,
- 654, 653, 143, 501, 436, 60, 525, 426, 491, 0,
- 626, 542, 631, 632, 259, 258, 61, 257, 256, 339,
- 264, 60, 144, 174, 348, 168, 0, 179, 352, 169,
- 252, 251, 61, 283, 259, 258, 631, 632, 60, 321,
- 525, 87, 175, 88, 411, 0, 532, 530, 66, 61,
- 267, 265, 527, 66, 89, 236, 235, 527, 87, 87,
- 88, 88, 87, 526, 88, 66, 549, 87, 526, 88,
- 105, 89, 89, 525, 87, 89, 88, 87, 266, 88,
- 89, 87, 87, 88, 88, 567, 527, 89, 174, 106,
- 89, 107, 477, 67, 89, 89, 525, 526, 67, 68,
- 657, 656, 580, 525, 68, 143, 0, 175, 0, 176,
- 67, 87, 87, 88, 88, 0, 68, 0, 0, 527,
- 550, 548, 174, 0, 89, 89, 0, 581, 579, 0,
- 526, 87, 655, 88, 87, 0, 88, 0, 592, 568,
- 566, 175, 527, 411, 89, 478, 476, 89, 650, 527,
- 75, 76, 0, 526, 75, 76, 285, 286, 446, 445,
- 526, 0, 651, 649, 558, 285, 286, 6, 5, 4,
- 1, 3, 2, 0, 0, 0, 0, 77, 78, 0,
- 0, 77, 78, 287, 288, 0, 290, 291, 0, 0,
- 290, 291, 287, 288, 648, 292, 290, 291, 293, 292,
- 294, 0, 293, 0, 294, 292, 290, 291, 293, 0,
- 294, 35, 290, 291, 35, 292, 0, 0, 293, 0,
- 294, 292, 80, 81, 293, 593, 294, 35, 0, 0,
- 82, 83, 80, 81, 84, 35, 85, 174, 0, 0,
- 82, 83, 0, 0, 84, 35, 85, 0, 49, 52,
- 50, 49, 52, 50, 0, -98, 175, 0, 176, 35,
- 0, 0, 0, 0, 49, 52, 50, 35, 0, 0,
- 0, 0, 49, 52, 50, 0, 46, 34, 51, 46,
- 34, 51, 49, 52, 50, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 49, 52, 50, 0,
- 46, 34, 51, 0, 49, 52, 50, 35, 0, 0,
- 46, 34, 51, 35, 0, 0, 35, 0, 0, 35,
- 0, 0, 35, 0, 46, 34, 51, 35, 80, 81,
- 35, 0, 46, 34, 51, 0, 82, 83, 0, 0,
- 84, 0, 85, 0, 49, 52, 50, 0, 0, 0,
- 49, 52, 50, 49, 52, 50, 49, 52, 50, 49,
- 52, 50, 0, 35, 49, 52, 50, 49, 52, 50,
- 184, 0, 46, 34, 51, 0, 0, 0, 46, 34,
- 51, 46, 34, 51, 46, 34, 51, 46, 34, 51,
- 0, 0, 46, 34, 51, 46, 34, 51, 35, 0,
- 49, 52, 50, 35, 0, 184, 35, 0, 0, 0,
- 184, 35, 0, 0, 35, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 46, 34,
- 51, 0, 0, 0, 0, 49, 52, 50, 250, 249,
- 49, 52, 50, 49, 52, 50, 250, 249, 49, 52,
- 50, 49, 52, 50, 0, 0, 0, 35, 0, 0,
+ 424, 405, 432, 404, 346, 245, 573, 354, 406, -134,
+ 461, -112, -113, -131, -136, 448, 350, -139, 402, 392,
+ 268, -123, -142, 465, 399, 398, -131, -139, 465, 461,
+ 474, -136, 558, 448, -134, -112, -113, 424, -123, 350,
+ -142, 245, 551, 481, 484, 268, 576, 524, 413, 482,
+ 438, 558, 439, 261, 558, 615, 420, 452, 418, 421,
+ 283, 454, 143, 428, 172, 558, 166, 423, 558, 448,
+ 608, 73, 546, 448, 149, 283, 0, 323, 408, 0,
+ 544, 307, 268, 0, 0, 0, 143, 184, 350, 448,
+ 245, 166, 101, 73, 461, 329, 465, 238, 456, 424,
+ 241, 336, 618, 189, 665, 262, 143, 323, 0, 181,
+ 317, 143, 451, 0, 315, 442, 143, 143, 192, 555,
+ 0, 143, 240, 243, 303, 151, 452, 101, 143, 185,
+ 143, 435, 143, 312, 305, 244, 0, 0, 303, 490,
+ 555, 60, 60, 342, 143, 143, 191, 432, 252, 251,
+ 103, 344, 61, 61, 144, 60, 305, 662, 661, 60,
+ 103, 656, 655, 352, 325, 338, 61, 556, 326, 501,
+ 61, 257, 256, 426, 143, 168, 436, 664, 663, 169,
+ 348, 542, 264, 64, 321, 633, 634, 491, 628, 620,
+ 619, 259, 258, 179, 65, 174, 463, 143, 622, 259,
+ 258, 416, 415, 525, 267, 265, 525, 87, 477, 88,
+ 531, 0, 174, 525, 175, 143, 411, 87, 339, 88,
+ 89, 66, 0, 87, 558, 88, 467, 527, 66, 610,
+ 89, 175, 266, 411, 525, 567, 89, 525, 526, 0,
+ 87, 66, 88, 87, 87, 88, 88, 549, 174, 527,
+ 236, 235, 527, 89, 611, 609, 89, 89, 0, 527,
+ 526, 478, 476, 526, 532, 530, 67, 175, 446, 445,
+ 526, 0, 68, 67, 174, 659, 658, 105, 0, 68,
+ 527, 75, 76, 527, 0, 623, 67, 285, 286, 568,
+ 566, 526, 68, 175, 526, 176, 106, 652, 107, 75,
+ 76, 550, 548, 174, 0, 285, 286, 657, 77, 78,
+ 174, 653, 651, 0, 287, 288, 0, 0, 0, 0,
+ 0, -99, 175, 0, 176, 0, 77, 78, -99, 175,
+ 0, 176, 287, 288, 0, 290, 291, 0, 0, 87,
+ 0, 88, 0, 650, 292, 80, 81, 293, 35, 294,
+ 0, 0, 89, 82, 83, 0, 0, 84, 35, 85,
+ 80, 81, 6, 5, 4, 1, 3, 2, 82, 83,
+ 80, 81, 84, 35, 85, 0, 0, 0, 82, 83,
+ 80, 81, 84, 0, 85, 49, 52, 50, 82, 83,
+ 80, 81, 84, 0, 85, 49, 52, 50, 82, 83,
+ 0, 0, 84, 0, 85, 35, 0, 0, 35, 0,
+ 49, 52, 50, 46, 34, 51, 35, 0, 0, 35,
+ 290, 291, 35, 46, 34, 51, 0, 0, 35, 292,
+ 0, 0, 293, 0, 294, 184, 0, 0, 46, 34,
+ 51, 35, 49, 52, 50, 49, 52, 50, 184, 0,
+ 0, 0, 0, 49, 52, 50, 49, 52, 50, 49,
+ 52, 50, 35, 0, 0, 49, 52, 50, 0, 184,
+ 46, 34, 51, 46, 34, 51, 0, 0, 49, 52,
+ 50, 46, 34, 51, 46, 34, 51, 46, 34, 51,
+ 0, 0, 0, 46, 34, 51, 0, 0, 35, 49,
+ 52, 50, 0, 35, 0, 0, 46, 34, 51, 0,
+ 0, 35, 0, 0, 0, 0, 0, 0, 0, 35,
+ 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
+ 250, 249, 0, 0, 0, 49, 52, 50, 0, 0,
+ 49, 52, 50, 250, 249, 0, 0, 0, 49, 52,
+ 50, 250, 249, 0, 0, 0, 49, 52, 50, 0,
0, 0, 0, 46, 34, 51, 0, 0, 46, 34,
- 51, 46, 34, 51, 0, 0, 46, 34, 51, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 35, 250,
- 249, 0, 0, 0, 49, 52, 50, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 255, 254, 46, 34, 51, 49, 52, 50, 0, 0,
+ 51, 0, 0, 0, 0, 0, 46, 34, 51, 0,
+ 35, 0, 0, 0, 46, 34, 51, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 30, 31, 153, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 154, 0, 0, 0, 155,
- 35, 0, 0, 0, 36, 37, 0, 38, 156, 0,
- 157, 0, 0, 0, 516, 0, 0, 0, 45, 0,
- 0, 158, 0, 159, 64, 0, 0, 0, 0, 0,
- 0, 160, 0, 0, 161, 65, 53, 49, 52, 50,
- 162, 54, 0, 0, 0, 0, 163, 0, 0, 0,
- 0, 0, 44, 56, 32, 0, 0, 0, 41, 0,
- 0, 0, 164, 0, 0, 46, 34, 51, 0, 0,
- 0, 0, 0, 0, 0, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 33, 0, 0, 153, 0,
- 0, 0, 35, 0, 0, 0, 36, 37, 154, 38,
- 0, 0, 155, 0, 0, 0, 516, 0, 0, 0,
- 45, 156, 0, 157, 0, 0, 319, 0, 0, 0,
- 0, 0, 0, 0, 158, 0, 159, 64, 53, 49,
- 52, 50, 0, 54, 160, 0, 0, 161, 65, 0,
- 0, 0, 0, 162, 44, 56, 32, 0, 0, 163,
- 41, 0, 0, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 164, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 255, 254, 153, 0, 0, 49, 52, 50,
+ 0, 0, 0, 0, 154, 0, 0, 0, 155, 0,
+ 0, 0, 0, 0, 0, 0, 0, 156, 0, 157,
+ 0, 0, 319, 0, 0, 46, 34, 51, 0, 0,
+ 158, 0, 159, 64, 0, 30, 31, 153, 0, 0,
+ 160, 0, 0, 161, 65, 33, 0, 154, 0, 162,
+ 0, 155, 35, 0, 0, 163, 36, 37, 0, 38,
+ 156, 0, 157, 0, 0, 0, 42, 0, 0, 0,
+ 45, 164, 0, 158, 0, 159, 64, 0, 0, 0,
+ 0, 0, 0, 160, 0, 0, 161, 65, 53, 49,
+ 52, 50, 162, 54, 0, 0, 0, 0, 163, 0,
+ 0, 0, 0, 0, 44, 56, 32, 0, 0, 0,
+ 41, 0, 0, 0, 164, 0, 0, 46, 34, 51,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
- 0, 0, 36, 37, 0, 38, 0, 0, 0, 0,
- 0, 0, 516, 0, 0, 0, 45, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
+ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+ 0, 36, 37, 0, 38, 0, 0, 0, 0, 0,
+ 0, 516, 0, 0, 0, 45, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 44, 56, 32, 0, 0, 0, 41, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
- 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
- 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 53, 49,
- 52, 50, 0, 54, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 44, 56, 32, 0, 0, 0,
- 41, 0, 0, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 515,
- 0, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 219, 0, 0, 0, 0, 0, 0, 35, 0,
- 0, 0, 36, 37, 0, 38, 0, 0, 0, 0,
- 0, 0, 516, 0, 0, 0, 45, 0, 0, 0,
+ 0, 0, 0, 53, 49, 52, 50, 0, 54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,
+ 56, 32, 0, 0, 0, 41, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 30, 31, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
+ 0, 35, 0, 0, 0, 36, 37, 0, 38, 0,
+ 0, 0, 0, 0, 0, 42, 0, 0, 0, 45,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 53, 517, 519, 518, 0, 54,
- 0, 0, 0, 0, 227, 0, 0, 0, 0, 0,
- 44, 56, 32, 214, 0, 0, 41, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 515, 0, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 219, 0, 0,
- 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
- 0, 38, 0, 0, 0, 0, 0, 0, 516, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
- 563, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 517, 519, 518, 0, 54, 0, 0, 0, 0,
- 227, 0, 0, 0, 0, 0, 44, 56, 32, 214,
- 0, 0, 41, 0, 0, 0, 0, 0, 0, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 515, 0, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 219, 0, 0, 0, 0, 0, 0,
- 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
- 0, 0, 0, 0, 516, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 560, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 53, 517, 519, 518,
- 0, 54, 0, 0, 0, 0, 227, 0, 0, 0,
- 0, 0, 44, 56, 32, 214, 0, 0, 41, 0,
- 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 0, 0, 0, 0, 0, 53, 49, 52,
+ 50, 0, 54, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 44, 56, 32, 0, 0, 0, 41,
+ 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 515, 0,
+ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 219, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+ 0, 36, 37, 0, 38, 0, 0, 0, 0, 0,
+ 0, 516, 0, 0, 0, 45, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
- 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -131, 0, 0, 0, 29, 30, 31, 0,
+ 0, 0, 0, 53, 517, 519, 518, 0, 54, 0,
+ 0, 0, 0, 227, 0, 0, 0, 0, 0, 44,
+ 56, 32, 214, 0, 0, 41, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 515, 0, 30, 31, 0, 0,
+ 0, 0, 0, 0, 0, 0, 219, 0, 0, 0,
+ 0, 0, 0, 35, 0, 0, 0, 36, 37, 0,
+ 38, 0, 0, 0, 0, 0, 0, 516, 0, 0,
+ 0, 45, 0, 0, 0, 0, 0, 0, 0, 563,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 53,
+ 517, 519, 518, 0, 54, 0, 0, 0, 0, 227,
+ 0, 0, 0, 0, 0, 44, 56, 32, 214, 0,
+ 0, 41, 0, 0, 0, 0, 0, 0, 46, 34,
+ 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 515, 0, 30, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 219, 0, 0, 0, 0, 0, 0, 35,
+ 0, 0, 0, 36, 37, 0, 38, 0, 0, 0,
+ 0, 0, 0, 516, 0, 0, 0, 45, 0, 0,
+ 0, 0, 0, 0, 0, 560, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 517, 519, 518, 0,
+ 54, 0, 0, 0, 0, 227, 0, 0, 0, 0,
+ 0, 44, 56, 32, 214, 0, 0, 41, 0, 0,
+ 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29, 30, 31, 0,
0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
0, 38, 0, 0, 0, 39, 0, 40, 42, 43,
@@ -507,369 +479,362 @@ const short QQmlJSGrammar::action_info [] = {
0, 58, 0, 0, 0, 0, 44, 56, 32, 0,
0, 0, 41, 0, 0, 0, 0, 0, 0, 46,
34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 29, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 33, 0, 0, 0, 0, 0, 0, 35,
- 0, 0, 0, 36, 37, 0, 38, 0, 0, 0,
- 39, 0, 40, 42, 43, 0, 0, 45, 0, 0,
- 0, 47, 0, 48, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 53, 49, 52, 50, 0,
- 54, 0, 55, 0, 57, 282, 58, 0, 0, 0,
- 0, 44, 56, 32, 0, 0, 0, 41, 0, 0,
- 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 488, 0, 0, 29,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 35, 0, 0,
- 0, 36, 37, 0, 38, 0, 0, 0, 39, 0,
- 40, 42, 43, 0, 0, 45, 0, 0, 0, 47,
- 0, 48, 0, 0, 489, 0, 0, 0, 0, 0,
- 0, 0, 0, 53, 49, 52, 50, 0, 54, 0,
- 55, 0, 57, 0, 58, 0, 0, 0, 0, 44,
- 56, 32, 0, 0, 0, 41, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 488, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 494, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
- 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 496, 0, 0, 29, 30, 31, 0, 0,
+ 0, -132, 0, 0, 0, 29, 30, 31, 0, 0,
0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
0, 0, 0, 35, 0, 0, 0, 36, 37, 0,
38, 0, 0, 0, 39, 0, 40, 42, 43, 0,
0, 45, 0, 0, 0, 47, 0, 48, 0, 0,
- 497, 0, 0, 0, 0, 0, 0, 0, 0, 53,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 53,
49, 52, 50, 0, 54, 0, 55, 0, 57, 0,
58, 0, 0, 0, 0, 44, 56, 32, 0, 0,
0, 41, 0, 0, 0, 0, 0, 0, 46, 34,
51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 496, 0, 0, 29, 30, 31, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
- 0, 35, 0, 0, 0, 36, 37, 0, 38, 0,
- 0, 0, 39, 0, 40, 42, 43, 0, 0, 45,
- 0, 0, 0, 47, 0, 48, 0, 0, 499, 0,
- 0, 0, 0, 0, 0, 0, 0, 53, 49, 52,
- 50, 0, 54, 0, 55, 0, 57, 0, 58, 0,
- 0, 0, 0, 44, 56, 32, 0, 0, 0, 41,
- 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 29, 30,
+ 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
+ 0, 0, 36, 37, 0, 38, 0, 0, 0, 39,
+ 0, 40, 42, 43, 0, 0, 45, 0, 0, 0,
+ 47, 0, 48, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
+ 0, 55, 0, 57, 282, 58, 0, 0, 0, 0,
+ 44, 56, 32, 0, 0, 0, 41, 0, 0, 0,
+ 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 496, 0, 0, 29, 30,
31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
- 0, 0, 0, 0, 0, 0, 35, 220, 0, 0,
- 595, 596, 0, 38, 0, 0, 0, 39, 0, 40,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,
+ 36, 37, 0, 38, 0, 0, 0, 39, 0, 40,
42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
- 48, 0, 0, 0, 0, 0, 0, 0, 223, 0,
- 0, 0, 53, 49, 52, 50, 224, 54, 0, 55,
- 226, 57, 0, 58, 0, 229, 0, 0, 44, 56,
+ 48, 0, 0, 497, 0, 0, 0, 0, 0, 0,
+ 0, 0, 53, 49, 52, 50, 0, 54, 0, 55,
+ 0, 57, 0, 58, 0, 0, 0, 0, 44, 56,
32, 0, 0, 0, 41, 0, 0, 0, 0, 0,
0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 29, 30, 31, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
- 0, 35, 220, 0, 0, 221, 37, 0, 38, 0,
- 0, 0, 39, 0, 40, 42, 43, 0, 0, 45,
- 0, 0, 0, 47, 0, 48, 0, 0, 0, 0,
- 0, 0, 0, 223, 0, 0, 0, 53, 49, 52,
- 50, 224, 54, 0, 55, 226, 57, 0, 58, 0,
- 229, 0, 0, 44, 56, 32, 0, 0, 0, 41,
- 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 111, 112,
- 113, 0, 0, 115, 117, 118, 0, 0, 119, 0,
- 120, 0, 0, 0, 122, 123, 124, 0, 0, 0,
- 0, 0, 0, 35, 125, 126, 127, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 131, 0, 0, 0, 0, 0, 0,
- 49, 52, 50, 132, 133, 134, 0, 136, 137, 138,
- 139, 140, 141, 0, 0, 129, 135, 121, 114, 116,
- 130, 0, 0, 0, 0, 0, 0, 0, 46, 34,
- 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 111, 112, 113, 0, 0, 115, 117, 118, 0, 0,
- 119, 0, 120, 0, 0, 0, 122, 123, 124, 0,
- 0, 0, 0, 0, 0, 35, 125, 126, 127, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,
- 0, 0, 0, 395, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 131, 0, 0, 0, 0,
- 0, 397, 49, 52, 50, 132, 133, 134, 0, 136,
- 137, 138, 139, 140, 141, 0, 0, 129, 135, 121,
- 114, 116, 130, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 488, 0, 0, 29, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+ 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
+ 0, 38, 0, 0, 0, 39, 0, 40, 42, 43,
+ 0, 0, 45, 0, 0, 0, 47, 0, 48, 0,
+ 0, 494, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 49, 52, 50, 0, 54, 0, 55, 0, 57,
+ 0, 58, 0, 0, 0, 0, 44, 56, 32, 0,
+ 0, 0, 41, 0, 0, 0, 0, 0, 0, 46,
+ 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 488, 0, 0, 29, 30, 31, 0, 0, 0,
+ 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
+ 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
+ 0, 0, 0, 39, 0, 40, 42, 43, 0, 0,
+ 45, 0, 0, 0, 47, 0, 48, 0, 0, 489,
+ 0, 0, 0, 0, 0, 0, 0, 0, 53, 49,
+ 52, 50, 0, 54, 0, 55, 0, 57, 0, 58,
+ 0, 0, 0, 0, 44, 56, 32, 0, 0, 0,
+ 41, 0, 0, 0, 0, 0, 0, 46, 34, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 496,
+ 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+ 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
+ 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
+ 0, 0, 47, 0, 48, 0, 0, 499, 0, 0,
+ 0, 0, 0, 0, 0, 0, 53, 49, 52, 50,
+ 0, 54, 0, 55, 0, 57, 0, 58, 0, 0,
+ 0, 0, 44, 56, 32, 0, 0, 0, 41, 0,
+ 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 220, 0, 0, 221,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 0, 0, 0, 0, 0, 223, 0, 0,
+ 0, 53, 49, 52, 50, 224, 54, 0, 55, 226,
+ 57, 0, 58, 0, 229, 0, 0, 44, 56, 32,
+ 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
+ 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+ 35, 220, 0, 0, 578, 37, 0, 38, 0, 0,
+ 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
+ 0, 0, 47, 0, 48, 0, 0, 0, 0, 0,
+ 0, 0, 223, 0, 0, 0, 53, 49, 52, 50,
+ 224, 54, 0, 55, 226, 57, 0, 58, 0, 229,
+ 0, 0, 44, 56, 32, 0, 0, 0, 41, 0,
+ 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 220, 0, 0, 578,
+ 624, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 0, 0, 0, 0, 0, 223, 0, 0,
+ 0, 53, 49, 52, 50, 224, 54, 0, 55, 226,
+ 57, 0, 58, 0, 229, 0, 0, 44, 56, 32,
+ 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
0, 0, 111, 112, 113, 0, 0, 115, 117, 118,
0, 0, 119, 0, 120, 0, 0, 0, 122, 123,
124, 0, 0, 0, 0, 0, 0, 35, 125, 126,
127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 128, 0, 0, 0, 395, 0, 0, 0, 0,
+ 0, 128, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 131, 0, 0,
- 0, 0, 0, 397, 49, 52, 50, 132, 133, 134,
+ 0, 0, 0, 0, 49, 52, 50, 132, 133, 134,
0, 136, 137, 138, 139, 140, 141, 0, 0, 129,
135, 121, 114, 116, 130, 0, 0, 0, 0, 0,
- 0, 0, 46, 374, 380, 0, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
0, 0, 0, 0, 111, 112, 113, 0, 0, 115,
117, 118, 0, 0, 119, 0, 120, 0, 0, 0,
122, 123, 124, 0, 0, 0, 0, 0, 0, 35,
125, 126, 127, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 128, 0, 0, 0, 395, 0, 0,
- 0, 0, 0, 0, 0, 396, 0, 0, 0, 131,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 131,
0, 0, 0, 0, 0, 397, 49, 52, 50, 132,
133, 134, 0, 136, 137, 138, 139, 140, 141, 0,
0, 129, 135, 121, 114, 116, 130, 0, 0, 0,
0, 0, 0, 0, 46, 374, 380, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 213, 0, 0, 0,
- 0, 215, 0, 29, 30, 31, 217, 0, 0, 0,
- 0, 0, 0, 218, 219, 0, 0, 0, 0, 0,
- 0, 35, 220, 0, 0, 221, 37, 0, 38, 0,
- 0, 0, 39, 0, 40, 42, 43, 0, 0, 45,
- 0, 0, 0, 47, 0, 48, 0, 0, 0, 0,
- 0, 222, 0, 223, 0, 0, 0, 53, 49, 52,
- 50, 224, 54, 225, 55, 226, 57, 227, 58, 228,
- 229, 0, 0, 44, 56, 32, 214, 216, 0, 41,
+ 0, 0, 0, 0, 0, 0, 111, 112, 113, 0,
+ 0, 115, 117, 118, 0, 0, 119, 0, 120, 0,
+ 0, 0, 122, 123, 124, 0, 0, 0, 0, 0,
+ 0, 35, 125, 126, 127, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 128, 0, 0, 0, 395,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 131, 0, 0, 0, 0, 0, 397, 49, 52,
+ 50, 132, 133, 134, 0, 136, 137, 138, 139, 140,
+ 141, 0, 0, 129, 135, 121, 114, 116, 130, 0,
0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 213, 0,
- 0, 0, 0, 215, 0, 29, 30, 31, 217, 0,
- 0, 0, 0, 0, 0, 218, 33, 0, 0, 0,
- 0, 0, 0, 35, 220, 0, 0, 221, 37, 0,
- 38, 0, 0, 0, 39, 0, 40, 42, 43, 0,
- 0, 45, 0, 0, 0, 47, 0, 48, 0, 0,
- 0, 0, 0, 222, 0, 223, 0, 0, 0, 53,
- 49, 52, 50, 224, 54, 225, 55, 226, 57, 227,
- 58, 228, 229, 0, 0, 44, 56, 32, 214, 216,
- 0, 41, 0, 0, 0, 0, 0, 0, 46, 34,
- 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 600, 112, 113, 0, 0, 602, 117, 604, 30, 31,
- 605, 0, 120, 0, 0, 0, 122, 607, 608, 0,
- 0, 0, 0, 0, 0, 35, 609, 126, 127, 221,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 610,
- 43, 0, 0, 612, 0, 0, 0, 47, 0, 48,
- 0, 0, 0, 0, 0, 613, 0, 223, 0, 0,
- 0, 614, 49, 52, 50, 615, 616, 617, 55, 619,
- 620, 621, 622, 623, 624, 0, 0, 611, 618, 606,
- 601, 603, 130, 41, 0, 0, 0, 0, 0, 0,
- 46, 374, 380, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 365, 112, 113, 0, 0, 367, 117, 369,
- 30, 31, 370, 0, 120, 0, 0, 0, 122, 372,
- 373, 0, 0, 0, 0, 0, 0, 35, 375, 126,
- 127, 221, 37, 0, 38, 0, 0, 0, 39, 0,
- 40, 376, 43, 0, 0, 378, 0, 0, 0, 47,
- 0, 48, 0, -277, 0, 0, 0, 379, 0, 223,
- 0, 0, 0, 381, 49, 52, 50, 382, 383, 384,
- 55, 386, 387, 388, 389, 390, 391, 0, 0, 377,
- 385, 371, 366, 368, 130, 41, 0, 0, 0, 0,
- 0, 0, 46, 374, 380, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 111, 112,
+ 113, 0, 0, 115, 117, 118, 0, 0, 119, 0,
+ 120, 0, 0, 0, 122, 123, 124, 0, 0, 0,
+ 0, 0, 0, 35, 125, 126, 127, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 128, 0, 0,
+ 0, 395, 0, 0, 0, 0, 0, 0, 0, 396,
+ 0, 0, 0, 131, 0, 0, 0, 0, 0, 397,
+ 49, 52, 50, 132, 133, 134, 0, 136, 137, 138,
+ 139, 140, 141, 0, 0, 129, 135, 121, 114, 116,
+ 130, 0, 0, 0, 0, 0, 0, 0, 46, 374,
+ 380, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 213, 0, 0, 0, 0, 215, 0, 29, 30, 31,
+ 217, 0, 0, 0, 0, 0, 0, 218, 33, 0,
+ 0, 0, 0, 0, 0, 35, 220, 0, 0, 221,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 0, 0, 0, 222, 0, 223, 0, 0,
+ 0, 53, 49, 52, 50, 224, 54, 225, 55, 226,
+ 57, 227, 58, 228, 229, 0, 0, 44, 56, 32,
+ 214, 216, 0, 41, 0, 0, 0, 0, 0, 0,
+ 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 213, 0, 0, 0, 0, 215, 0, 29,
+ 30, 31, 217, 0, 0, 0, 0, 0, 0, 218,
+ 219, 0, 0, 0, 0, 0, 0, 35, 220, 0,
+ 0, 221, 37, 0, 38, 0, 0, 0, 39, 0,
+ 40, 42, 43, 0, 0, 45, 0, 0, 0, 47,
+ 0, 48, 0, 0, 0, 0, 0, 222, 0, 223,
+ 0, 0, 0, 53, 49, 52, 50, 224, 54, 225,
+ 55, 226, 57, 227, 58, 228, 229, 0, 0, 44,
+ 56, 32, 214, 216, 0, 41, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 582, 112, 113, 0, 0, 584,
+ 117, 586, 30, 31, 587, 0, 120, 0, 0, 0,
+ 122, 589, 590, 0, 0, 0, 0, 0, 0, 35,
+ 591, 126, 127, 221, 37, 0, 38, 0, 0, 0,
+ 39, 0, 40, 592, 43, 0, 0, 594, 0, 0,
+ 0, 47, 0, 48, 0, 0, 0, 0, 0, 595,
+ 0, 223, 0, 0, 0, 596, 49, 52, 50, 597,
+ 598, 599, 55, 601, 602, 603, 604, 605, 606, 0,
+ 0, 593, 600, 588, 583, 585, 130, 41, 0, 0,
+ 0, 0, 0, 0, 46, 374, 380, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 365, 112, 113, 0,
+ 0, 367, 117, 369, 30, 31, 370, 0, 120, 0,
+ 0, 0, 122, 372, 373, 0, 0, 0, 0, 0,
+ 0, 35, 375, 126, 127, 221, 37, 0, 38, 0,
+ 0, 0, 39, 0, 40, 376, 43, 0, 0, 378,
+ 0, 0, 0, 47, 0, 48, 0, -278, 0, 0,
+ 0, 379, 0, 223, 0, 0, 0, 381, 49, 52,
+ 50, 382, 383, 384, 55, 386, 387, 388, 389, 390,
+ 391, 0, 0, 377, 385, 371, 366, 368, 130, 41,
+ 0, 0, 0, 0, 0, 0, 46, 374, 380, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
- 148, 142, 183, 447, 469, 347, 575, 444, 547, 627,
- 248, 320, 587, 572, 584, 586, 485, 591, 565, 529,
- 313, 545, 447, 393, 253, 528, 500, 183, 574, 453,
- 331, 652, 447, 437, 444, 313, 462, 455, 263, 457,
- 237, 441, 206, 188, 190, 150, 16, 178, 433, 630,
- 425, 641, 165, 400, 658, 458, 642, 171, 173, 248,
- 475, 351, 498, 248, 253, 313, 183, 466, 183, 541,
- 495, 629, 253, 512, 511, 188, 145, 206, 260, 645,
- 644, 62, 0, 62, 362, 507, 298, 469, 206, 206,
- 247, 514, 514, 62, 206, 460, 646, 409, 152, 409,
- 599, 628, 355, 239, 206, 62, 62, 62, 362, 260,
- 296, 297, 299, 331, 62, 62, 313, 504, 206, 295,
- 62, 62, 459, 460, 356, 206, 277, 62, 62, 502,
- 182, 281, 206, 62, 410, 182, 410, 401, 62, 353,
- 459, 62, 62, 506, 505, 62, 62, 503, 493, 349,
- 91, 62, 492, 206, 63, 206, 313, 62, 345, 483,
- 393, 479, 62, 62, 260, 206, 444, 206, 510, 102,
- 148, 62, 104, 182, 206, 188, 188, 468, 180, 170,
- 206, 62, 148, 247, 62, 394, 460, 393, 409, 340,
- 412, 341, 362, 206, 422, 167, 393, 206, 62, 108,
- 459, 313, 62, 187, 419, 62, 62, 86, 206, 62,
- 318, 98, 100, 403, 62, 99, 69, 322, 514, 514,
- 313, 62, 417, 553, 557, 410, 206, 79, 110, 246,
- 62, 343, 206, 206, 62, 0, 70, 62, 74, 71,
- 62, 62, 206, 108, 90, 206, 93, 62, 62, 62,
- 72, 62, 92, 62, 94, 62, 95, 309, 96, 407,
- 97, 309, 281, 62, 362, 362, 281, 0, 281, 242,
- 302, 0, 110, 177, 464, 0, 316, 309, 0, 308,
- 206, 206, 281, 311, 309, 0, 62, 62, 309, 281,
- 206, 281, 281, 281, 0, 314, 0, 0, 62, 330,
- 62, 324, 0, 281, 327, 281, 337, 300, 62, 62,
- 328, 304, 62, 281, 281, 301, 564, 281, 62, 289,
- 306, 569, 561, 281, 0, 514, 553, 284, 625, 0,
- 0, 514, 0, 0, 522, 0, 0, 0, 0, 0,
- 522, 0, 0, 0, 0, 0, 513, 523, 0, 485,
- 443, 440, 513, 523, 533, 534, 535, 536, 540, 537,
- 538, 577, 533, 534, 535, 536, 540, 537, 538, 0,
+ 545, 572, 565, 632, 654, 148, 529, 541, 528, 142,
+ 660, 263, 500, 393, 617, 616, 621, 614, 16, 629,
+ 444, 183, 313, 547, 447, 183, 631, 643, 253, 248,
+ 644, 485, 575, 574, 607, 152, 320, 437, 178, 313,
+ 441, 433, 173, 183, 165, 253, 462, 313, 457, 447,
+ 444, 453, 253, 458, 425, 347, 455, 248, 351, 188,
+ 475, 466, 498, 171, 150, 447, 206, 190, 400, 468,
+ 0, 183, 248, 495, 469, 237, 409, 393, 409, 331,
+ 464, 247, 512, 206, 145, 206, 62, 409, 507, 206,
+ 0, 511, 0, 188, 0, 206, 206, 188, 206, 62,
+ 62, 504, 460, 417, 62, 206, 505, 206, 647, 646,
+ 407, 0, 0, 410, 62, 410, 459, 62, 148, 506,
+ 62, 187, 62, 277, 410, 419, 412, 298, 281, 393,
+ 148, 0, 0, 0, 422, 62, 170, 62, 180, 62,
+ 295, 514, 296, 260, 297, 62, 648, 503, 62, 62,
+ 62, 182, 514, 299, 394, 62, 62, 460, 459, 206,
+ 362, 630, 362, 62, 167, 502, 514, 62, 62, 322,
+ 62, 553, 444, 99, 100, 93, 206, 62, 356, 206,
+ 510, 206, 94, 62, 62, 206, 62, 62, 95, 96,
+ 62, 97, 86, 62, 90, 493, 62, 91, 188, 492,
+ 92, 355, 62, 353, 108, 62, 483, 349, 242, 345,
+ 247, 313, 331, 469, 102, 104, 313, 206, 62, 206,
+ 182, 260, 62, 206, 206, 206, 239, 62, 98, 182,
+ 313, 313, 62, 110, 362, 72, 62, 206, 69, 62,
+ 318, 70, 62, 62, 71, 260, 63, 62, 246, 393,
+ 581, 62, 62, 460, 0, 74, 206, 62, 79, 459,
+ 0, 206, 514, 309, 206, 62, 362, 557, 281, 0,
+ 281, 309, 62, 0, 284, 403, 281, 281, 0, 309,
+ 401, 0, 206, 306, 281, 308, 343, 479, 340, 62,
+ 62, 341, 108, 337, 281, 281, 206, 302, 309, 62,
+ 0, 330, 304, 281, 281, 314, 316, 62, 309, 0,
+ 62, 62, 281, 281, 324, 281, 281, 301, 300, 514,
+ 311, 110, 177, 0, 327, 0, 62, 569, 522, 564,
+ 328, 281, 553, 289, 627, 561, 0, 0, 514, 0,
+ 513, 523, 0, 0, 514, 0, 0, 522, 0, 0,
+ 0, 0, 443, 522, 0, 485, 0, 0, 0, 513,
+ 523, 0, 0, 0, 0, 513, 523, 533, 534, 535,
+ 536, 540, 537, 538, 0, 0, 0, 0, 0, 0,
+ 0, 577, 0, 0, 0, 0, 0, 0, 0, 362,
+ 579, 580, 533, 534, 535, 536, 540, 537, 538, 569,
+ 0, 0, 0, 0, 0, 206, 0, 0, 570, 571,
+ 533, 534, 535, 536, 540, 537, 538, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 514, 569, 0, 0, 0, 0, 0,
- 0, 0, 522, 570, 571, 533, 534, 535, 536, 540,
- 537, 538, 0, 0, 513, 523, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 440, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 577, 0,
+ 0, 0, 0, 0, 0, 0, 0, 625, 626, 533,
+ 534, 535, 536, 540, 537, 538, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 594, 0, 0, 0, 0, 0, 0, 0, 0, 597,
- 598, 533, 534, 535, 536, 540, 537, 538, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0};
+ 0, 0, 0, 0, 0};
const short QQmlJSGrammar::action_check [] = {
- 2, 55, 34, 7, 60, 36, 31, 37, 61, 17,
- 24, 16, 2, 20, 33, 60, 5, 8, 36, 79,
- 60, 36, 33, 33, 7, 48, 55, 1, 55, 0,
- 33, 7, 60, 33, 60, 36, 60, 36, 8, 7,
- 36, 8, 7, 55, 7, 5, 55, 33, 7, 7,
- 48, 7, 36, 7, 36, 5, 7, 36, 1, 36,
- 7, 36, 7, 7, 61, 7, 60, 33, 8, 1,
- 7, 77, 36, 7, 36, 60, 7, 29, 8, 36,
- 7, 36, 55, 36, 79, 33, 79, 36, 66, 8,
- 36, 60, 33, 17, 33, 7, 2, 8, 36, 79,
- 36, 2, 7, 7, 7, 66, 8, 33, 33, 7,
- -1, 33, 8, 48, 8, 15, 15, 33, 36, 36,
- 33, 8, 55, 7, 8, 8, 15, 6, 48, 10,
- 8, 60, 8, 61, 34, 34, 8, 60, 8, 60,
- 55, 20, 8, -1, 8, 34, 8, 61, 62, 8,
- 40, 61, 62, 61, 62, 50, 42, 8, 60, 54,
- 56, 51, 7, -1, 61, 62, 60, 53, 61, 62,
- 61, 62, 8, 60, 55, 40, 29, 60, 56, -1,
- 56, 29, 91, 92, 61, 62, 51, 61, 62, 61,
- 60, 40, 56, 15, 60, 50, -1, 56, 60, 54,
- 61, 62, 51, 1, 61, 62, 91, 92, 40, 60,
- 29, 25, 34, 27, 36, -1, 61, 62, 12, 51,
- 61, 62, 75, 12, 38, 61, 62, 75, 25, 25,
- 27, 27, 25, 86, 27, 12, 7, 25, 86, 27,
- 15, 38, 38, 29, 25, 38, 27, 25, 89, 27,
- 38, 25, 25, 27, 27, 7, 75, 38, 15, 34,
- 38, 36, 8, 57, 38, 38, 29, 86, 57, 63,
- 61, 62, 36, 29, 63, 8, -1, 34, -1, 36,
- 57, 25, 25, 27, 27, -1, 63, -1, -1, 75,
- 61, 62, 15, -1, 38, 38, -1, 61, 62, -1,
- 86, 25, 93, 27, 25, -1, 27, -1, 7, 61,
- 62, 34, 75, 36, 38, 61, 62, 38, 47, 75,
- 18, 19, -1, 86, 18, 19, 18, 19, 61, 62,
- 86, -1, 61, 62, 33, 18, 19, 98, 99, 100,
- 101, 102, 103, -1, -1, -1, -1, 45, 46, -1,
- -1, 45, 46, 45, 46, -1, 23, 24, -1, -1,
- 23, 24, 45, 46, 93, 32, 23, 24, 35, 32,
- 37, -1, 35, -1, 37, 32, 23, 24, 35, -1,
- 37, 29, 23, 24, 29, 32, -1, -1, 35, -1,
- 37, 32, 23, 24, 35, 94, 37, 29, -1, -1,
- 31, 32, 23, 24, 35, 29, 37, 15, -1, -1,
- 31, 32, -1, -1, 35, 29, 37, -1, 66, 67,
- 68, 66, 67, 68, -1, 33, 34, -1, 36, 29,
- -1, -1, -1, -1, 66, 67, 68, 29, -1, -1,
- -1, -1, 66, 67, 68, -1, 94, 95, 96, 94,
- 95, 96, 66, 67, 68, -1, -1, -1, -1, -1,
- -1, -1, 94, 95, 96, -1, 66, 67, 68, -1,
- 94, 95, 96, -1, 66, 67, 68, 29, -1, -1,
- 94, 95, 96, 29, -1, -1, 29, -1, -1, 29,
- -1, -1, 29, -1, 94, 95, 96, 29, 23, 24,
- 29, -1, 94, 95, 96, -1, 31, 32, -1, -1,
- 35, -1, 37, -1, 66, 67, 68, -1, -1, -1,
- 66, 67, 68, 66, 67, 68, 66, 67, 68, 66,
- 67, 68, -1, 29, 66, 67, 68, 66, 67, 68,
- 36, -1, 94, 95, 96, -1, -1, -1, 94, 95,
- 96, 94, 95, 96, 94, 95, 96, 94, 95, 96,
- -1, -1, 94, 95, 96, 94, 95, 96, 29, -1,
- 66, 67, 68, 29, -1, 36, 29, -1, -1, -1,
- 36, 29, -1, -1, 29, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 94, 95,
- 96, -1, -1, -1, -1, 66, 67, 68, 61, 62,
- 66, 67, 68, 66, 67, 68, 61, 62, 66, 67,
- 68, 66, 67, 68, -1, -1, -1, 29, -1, -1,
+ 36, 60, 5, 36, 31, 7, 66, 16, 33, 7,
+ 36, 7, 7, 7, 7, 33, 36, 7, 55, 8,
+ 36, 7, 7, 36, 7, 55, 7, 7, 36, 36,
+ 17, 7, 33, 33, 7, 7, 7, 36, 7, 36,
+ 7, 7, 34, 60, 55, 36, 7, 66, 60, 33,
+ 55, 33, 7, 77, 33, 8, 60, 20, 36, 33,
+ 1, 36, 8, 33, 7, 33, 2, 55, 33, 33,
+ 29, 1, 24, 33, 8, 1, -1, 2, 55, -1,
+ 37, 8, 36, -1, -1, -1, 8, 36, 36, 33,
+ 7, 2, 48, 1, 36, 7, 36, 36, 60, 36,
+ 33, 17, 60, 8, 0, 36, 8, 2, -1, 60,
+ 60, 8, 6, -1, 61, 7, 8, 8, 33, 8,
+ -1, 8, 60, 55, 48, 60, 20, 48, 8, 36,
+ 8, 10, 8, 61, 79, 55, -1, -1, 48, 8,
+ 8, 40, 40, 61, 8, 8, 60, 5, 61, 62,
+ 79, 60, 51, 51, 56, 40, 79, 61, 62, 40,
+ 79, 61, 62, 60, 50, 8, 51, 56, 54, 60,
+ 51, 61, 62, 60, 8, 50, 55, 61, 62, 54,
+ 60, 29, 60, 42, 60, 91, 92, 56, 56, 61,
+ 62, 61, 62, 56, 53, 15, 60, 8, 7, 61,
+ 62, 61, 62, 29, 61, 62, 29, 25, 8, 27,
+ 7, -1, 15, 29, 34, 8, 36, 25, 61, 27,
+ 38, 12, -1, 25, 33, 27, 60, 75, 12, 36,
+ 38, 34, 89, 36, 29, 7, 38, 29, 86, -1,
+ 25, 12, 27, 25, 25, 27, 27, 7, 15, 75,
+ 61, 62, 75, 38, 61, 62, 38, 38, -1, 75,
+ 86, 61, 62, 86, 61, 62, 57, 34, 61, 62,
+ 86, -1, 63, 57, 15, 61, 62, 15, -1, 63,
+ 75, 18, 19, 75, -1, 94, 57, 18, 19, 61,
+ 62, 86, 63, 34, 86, 36, 34, 47, 36, 18,
+ 19, 61, 62, 15, -1, 18, 19, 93, 45, 46,
+ 15, 61, 62, -1, 45, 46, -1, -1, -1, -1,
+ -1, 33, 34, -1, 36, -1, 45, 46, 33, 34,
+ -1, 36, 45, 46, -1, 23, 24, -1, -1, 25,
+ -1, 27, -1, 93, 32, 23, 24, 35, 29, 37,
+ -1, -1, 38, 31, 32, -1, -1, 35, 29, 37,
+ 23, 24, 98, 99, 100, 101, 102, 103, 31, 32,
+ 23, 24, 35, 29, 37, -1, -1, -1, 31, 32,
+ 23, 24, 35, -1, 37, 66, 67, 68, 31, 32,
+ 23, 24, 35, -1, 37, 66, 67, 68, 31, 32,
+ -1, -1, 35, -1, 37, 29, -1, -1, 29, -1,
+ 66, 67, 68, 94, 95, 96, 29, -1, -1, 29,
+ 23, 24, 29, 94, 95, 96, -1, -1, 29, 32,
+ -1, -1, 35, -1, 37, 36, -1, -1, 94, 95,
+ 96, 29, 66, 67, 68, 66, 67, 68, 36, -1,
+ -1, -1, -1, 66, 67, 68, 66, 67, 68, 66,
+ 67, 68, 29, -1, -1, 66, 67, 68, -1, 36,
+ 94, 95, 96, 94, 95, 96, -1, -1, 66, 67,
+ 68, 94, 95, 96, 94, 95, 96, 94, 95, 96,
+ -1, -1, -1, 94, 95, 96, -1, -1, 29, 66,
+ 67, 68, -1, 29, -1, -1, 94, 95, 96, -1,
+ -1, 29, -1, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, -1, -1, -1, -1, 94, 95, 96,
+ 61, 62, -1, -1, -1, 66, 67, 68, -1, -1,
+ 66, 67, 68, 61, 62, -1, -1, -1, 66, 67,
+ 68, 61, 62, -1, -1, -1, 66, 67, 68, -1,
-1, -1, -1, 94, 95, 96, -1, -1, 94, 95,
- 96, 94, 95, 96, -1, -1, 94, 95, 96, 94,
- 95, 96, -1, -1, -1, -1, -1, -1, 29, 61,
- 62, -1, -1, -1, 66, 67, 68, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 96, -1, -1, -1, -1, -1, 94, 95, 96, -1,
+ 29, -1, -1, -1, 94, 95, 96, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 61, 62, 94, 95, 96, 66, 67, 68, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 94, 95, 96, -1, -1, -1, -1,
- -1, -1, -1, 12, 13, 3, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, 13, -1, -1, -1, 17,
- 29, -1, -1, -1, 33, 34, -1, 36, 26, -1,
- 28, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, 39, -1, 41, 42, -1, -1, -1, -1, -1,
- -1, 49, -1, -1, 52, 53, 65, 66, 67, 68,
- 58, 70, -1, -1, -1, -1, 64, -1, -1, -1,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- -1, -1, 80, -1, -1, 94, 95, 96, -1, -1,
- -1, -1, -1, -1, -1, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, 3, -1,
- -1, -1, 29, -1, -1, -1, 33, 34, 13, 36,
- -1, -1, 17, -1, -1, -1, 43, -1, -1, -1,
- 47, 26, -1, 28, -1, -1, 31, -1, -1, -1,
- -1, -1, -1, -1, 39, -1, 41, 42, 65, 66,
- 67, 68, -1, 70, 49, -1, -1, 52, 53, -1,
- -1, -1, -1, 58, 81, 82, 83, -1, -1, 64,
- 87, -1, -1, -1, -1, -1, -1, 94, 95, 96,
- -1, -1, -1, -1, -1, 80, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 61, 62, 3, -1, -1, 66, 67, 68,
+ -1, -1, -1, -1, 13, -1, -1, -1, 17, -1,
+ -1, -1, -1, -1, -1, -1, -1, 26, -1, 28,
+ -1, -1, 31, -1, -1, 94, 95, 96, -1, -1,
+ 39, -1, 41, 42, -1, 12, 13, 3, -1, -1,
+ 49, -1, -1, 52, 53, 22, -1, 13, -1, 58,
+ -1, 17, 29, -1, -1, 64, 33, 34, -1, 36,
+ 26, -1, 28, -1, -1, -1, 43, -1, -1, -1,
+ 47, 80, -1, 39, -1, 41, 42, -1, -1, -1,
+ -1, -1, -1, 49, -1, -1, 52, 53, 65, 66,
+ 67, 68, 58, 70, -1, -1, -1, -1, 64, -1,
+ -1, -1, -1, -1, 81, 82, 83, -1, -1, -1,
+ 87, -1, -1, -1, 80, -1, -1, 94, 95, 96,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 12, 13, -1, -1, -1, -1, -1, -1, -1,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, -1,
- -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
+ -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
- -1, -1, -1, 94, 95, 96, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
- -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
- -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
- 47, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
- 67, 68, -1, 70, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 81, 82, 83, -1, -1, -1,
- 87, -1, -1, -1, -1, -1, -1, 94, 95, 96,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 10,
- -1, 12, 13, -1, -1, -1, -1, -1, -1, -1,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, -1,
- -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
+ -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 81,
+ 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
+ -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 12, 13, -1, -1, -1, -1,
+ -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
+ -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
+ -1, -1, -1, -1, -1, 43, -1, -1, -1, 47,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, -1, -1, -1, 75, -1, -1, -1, -1, -1,
- 81, 82, 83, 84, -1, -1, 87, -1, -1, -1,
- -1, -1, -1, 94, 95, 96, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 10, -1, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
- -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, -1, -1, -1, 43, -1,
- -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
- 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
- 75, -1, -1, -1, -1, -1, 81, 82, 83, 84,
- -1, -1, 87, -1, -1, -1, -1, -1, -1, 94,
- 95, 96, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 10, -1, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, -1, -1, -1, -1, -1, 55, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, -1, -1, -1, 75, -1, -1, -1,
- -1, -1, 81, 82, 83, 84, -1, -1, 87, -1,
- -1, -1, -1, -1, -1, 94, 95, 96, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
+ 68, -1, 70, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
+ -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 10, -1,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
+ -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, 87, -1, -1, -1, -1, -1, -1,
- 94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 7, -1, -1, -1, 11, 12, 13, -1,
+ -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
+ -1, -1, -1, 75, -1, -1, -1, -1, -1, 81,
+ 82, 83, 84, -1, -1, 87, -1, -1, -1, -1,
+ -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 10, -1, 12, 13, -1, -1,
+ -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
+ -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
+ 36, -1, -1, -1, -1, -1, -1, 43, -1, -1,
+ -1, 47, -1, -1, -1, -1, -1, -1, -1, 55,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 65,
+ 66, 67, 68, -1, 70, -1, -1, -1, -1, 75,
+ -1, -1, -1, -1, -1, 81, 82, 83, 84, -1,
+ -1, 87, -1, -1, -1, -1, -1, -1, 94, 95,
+ 96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 10, -1, 12, 13, -1, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
+ -1, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
+ 70, -1, -1, -1, -1, 75, -1, -1, -1, -1,
+ -1, 81, 82, 83, 84, -1, -1, 87, -1, -1,
+ -1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 11, 12, 13, -1,
-1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
-1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
-1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
@@ -879,101 +844,100 @@ const short QQmlJSGrammar::action_check [] = {
-1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
-1, -1, 87, -1, -1, -1, -1, -1, -1, 94,
95, 96, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 11, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
- -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
- 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
- -1, 51, -1, 53, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
- 70, -1, 72, -1, 74, 75, 76, -1, -1, -1,
- -1, 81, 82, 83, -1, -1, -1, 87, -1, -1,
- -1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 8, -1, -1, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, 56, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
- 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
- -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, 87, -1, -1, -1, -1, -1, -1,
- 94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 8, -1, -1, 11, 12, 13, -1, -1,
+ -1, 7, -1, -1, -1, 11, 12, 13, -1, -1,
-1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
-1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
-1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- 56, -1, -1, -1, -1, -1, -1, -1, -1, 65,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 65,
66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
-1, 87, -1, -1, -1, -1, -1, -1, 94, 95,
96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 8, -1, -1, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
- -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
- -1, -1, -1, 51, -1, 53, -1, -1, 56, -1,
- -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, -1, 70, -1, 72, -1, 74, -1, 76, -1,
- -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
- -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 11, 12,
+ 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
+ -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
+ -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
+ 51, -1, 53, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ -1, 72, -1, 74, 75, 76, -1, -1, -1, -1,
+ 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
+ -1, -1, -1, 94, 95, 96, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8, -1, -1, 11, 12,
13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
- -1, -1, -1, -1, -1, -1, 29, 30, -1, -1,
+ -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
- 53, -1, -1, -1, -1, -1, -1, -1, 61, -1,
- -1, -1, 65, 66, 67, 68, 69, 70, -1, 72,
- 73, 74, -1, 76, -1, 78, -1, -1, 81, 82,
+ 53, -1, -1, 56, -1, -1, -1, -1, -1, -1,
+ -1, -1, 65, 66, 67, 68, -1, 70, -1, 72,
+ -1, 74, -1, 76, -1, -1, -1, -1, 81, 82,
83, -1, -1, -1, 87, -1, -1, -1, -1, -1,
-1, 94, 95, 96, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
- -1, 29, 30, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
- -1, -1, -1, 51, -1, 53, -1, -1, -1, -1,
- -1, -1, -1, 61, -1, -1, -1, 65, 66, 67,
- 68, 69, 70, -1, 72, 73, 74, -1, 76, -1,
- 78, -1, -1, 81, 82, 83, -1, -1, -1, 87,
- -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
- 6, -1, -1, 9, 10, 11, -1, -1, 14, -1,
- 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
- -1, -1, -1, 29, 30, 31, 32, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 43, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 59, -1, -1, -1, -1, -1, -1,
- 66, 67, 68, 69, 70, 71, -1, 73, 74, 75,
- 76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
- 86, -1, -1, -1, -1, -1, -1, -1, 94, 95,
- 96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 4, 5, 6, -1, -1, 9, 10, 11, -1, -1,
- 14, -1, 16, -1, -1, -1, 20, 21, 22, -1,
- -1, -1, -1, -1, -1, 29, 30, 31, 32, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 43,
- -1, -1, -1, 47, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 59, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, 71, -1, 73,
- 74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
- 84, 85, 86, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8, -1, -1, 11, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
+ -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
+ -1, -1, 87, -1, -1, -1, -1, -1, -1, 94,
+ 95, 96, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8, -1, -1, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
+ -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
+ 47, -1, -1, -1, 51, -1, 53, -1, -1, 56,
+ -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
+ 67, 68, -1, 70, -1, 72, -1, 74, -1, 76,
+ -1, -1, -1, -1, 81, 82, 83, -1, -1, -1,
+ 87, -1, -1, -1, -1, -1, -1, 94, 95, 96,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 8,
+ -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, 56, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, 72, -1, 74, -1, 76, -1, -1,
+ -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
+ -1, -1, -1, -1, -1, 94, 95, 96, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, 30, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, -1, -1, -1, -1, -1, 61, -1, -1,
+ -1, 65, 66, 67, 68, 69, 70, -1, 72, 73,
+ 74, -1, 76, -1, 78, -1, -1, 81, 82, 83,
+ -1, -1, -1, 87, -1, -1, -1, -1, -1, -1,
+ 94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, 30, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
+ -1, -1, 61, -1, -1, -1, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, -1, 76, -1, 78,
+ -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
+ -1, -1, -1, -1, -1, 94, 95, 96, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, 30, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, -1, -1, -1, -1, -1, 61, -1, -1,
+ -1, 65, 66, 67, 68, 69, 70, -1, 72, 73,
+ 74, -1, 76, -1, 78, -1, -1, 81, 82, 83,
+ -1, -1, -1, 87, -1, -1, -1, -1, -1, -1,
94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
-1, -1, 14, -1, 16, -1, -1, -1, 20, 21,
22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
32, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
+ -1, 43, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 59, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, 69, 70, 71,
+ -1, -1, -1, -1, 66, 67, 68, 69, 70, 71,
-1, 73, 74, 75, 76, 77, 78, -1, -1, 81,
82, 83, 84, 85, 86, -1, -1, -1, -1, -1,
-1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
@@ -982,104 +946,126 @@ const short QQmlJSGrammar::action_check [] = {
20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
30, 31, 32, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
- -1, -1, -1, -1, -1, 55, -1, -1, -1, 59,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 59,
-1, -1, -1, -1, -1, 65, 66, 67, 68, 69,
70, 71, -1, 73, 74, 75, 76, 77, 78, -1,
-1, 81, 82, 83, 84, 85, 86, -1, -1, -1,
-1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 4, -1, -1, -1,
- -1, 9, -1, 11, 12, 13, 14, -1, -1, -1,
- -1, -1, -1, 21, 22, -1, -1, -1, -1, -1,
- -1, 29, 30, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
- -1, -1, -1, 51, -1, 53, -1, -1, -1, -1,
- -1, 59, -1, 61, -1, -1, -1, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
- 78, -1, -1, 81, 82, 83, 84, 85, -1, 87,
+ -1, -1, -1, -1, -1, -1, 4, 5, 6, -1,
+ -1, 9, 10, 11, -1, -1, 14, -1, 16, -1,
+ -1, -1, 20, 21, 22, -1, -1, -1, -1, -1,
+ -1, 29, 30, 31, 32, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 43, -1, -1, -1, 47,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 59, -1, -1, -1, -1, -1, 65, 66, 67,
+ 68, 69, 70, 71, -1, 73, 74, 75, 76, 77,
+ 78, -1, -1, 81, 82, 83, 84, 85, 86, -1,
-1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 4, -1,
- -1, -1, -1, 9, -1, 11, 12, 13, 14, -1,
- -1, -1, -1, -1, -1, 21, 22, -1, -1, -1,
- -1, -1, -1, 29, 30, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
- -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- -1, -1, -1, 59, -1, 61, -1, -1, -1, 65,
- 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
+ 6, -1, -1, 9, 10, 11, -1, -1, 14, -1,
+ 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
+ -1, -1, -1, 29, 30, 31, 32, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 43, -1, -1,
+ -1, 47, -1, -1, -1, -1, -1, -1, -1, 55,
+ -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
+ 66, 67, 68, 69, 70, 71, -1, 73, 74, 75,
76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
- -1, 87, -1, -1, -1, -1, -1, -1, 94, 95,
+ 86, -1, -1, -1, -1, -1, -1, -1, 94, 95,
96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 4, 5, 6, -1, -1, 9, 10, 11, 12, 13,
- 14, -1, 16, -1, -1, -1, 20, 21, 22, -1,
- -1, -1, -1, -1, -1, 29, 30, 31, 32, 33,
+ 4, -1, -1, -1, -1, 9, -1, 11, 12, 13,
+ 14, -1, -1, -1, -1, -1, -1, 21, 22, -1,
+ -1, -1, -1, -1, -1, 29, 30, -1, -1, 33,
34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
-1, -1, -1, -1, -1, 59, -1, 61, -1, -1,
-1, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
- 84, 85, 86, 87, -1, -1, -1, -1, -1, -1,
+ 84, 85, -1, 87, -1, -1, -1, -1, -1, -1,
94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
- 12, 13, 14, -1, 16, -1, -1, -1, 20, 21,
- 22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
- 32, 33, 34, -1, 36, -1, -1, -1, 40, -1,
+ -1, -1, 4, -1, -1, -1, -1, 9, -1, 11,
+ 12, 13, 14, -1, -1, -1, -1, -1, -1, 21,
+ 22, -1, -1, -1, -1, -1, -1, 29, 30, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, 55, -1, -1, -1, 59, -1, 61,
+ -1, 53, -1, -1, -1, -1, -1, 59, -1, 61,
-1, -1, -1, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, -1, -1, 81,
- 82, 83, 84, 85, 86, 87, -1, -1, -1, -1,
+ 82, 83, 84, 85, -1, 87, -1, -1, -1, -1,
-1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1,
+ -1, -1, -1, -1, 4, 5, 6, -1, -1, 9,
+ 10, 11, 12, 13, 14, -1, 16, -1, -1, -1,
+ 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, 31, 32, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, -1, -1, -1, 59,
+ -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, -1,
+ -1, 81, 82, 83, 84, 85, 86, 87, -1, -1,
+ -1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 4, 5, 6, -1,
+ -1, 9, 10, 11, 12, 13, 14, -1, 16, -1,
+ -1, -1, 20, 21, 22, -1, -1, -1, -1, -1,
+ -1, 29, 30, 31, 32, 33, 34, -1, 36, -1,
+ -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
+ -1, -1, -1, 51, -1, 53, -1, 55, -1, -1,
+ -1, 59, -1, 61, -1, -1, -1, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
+ 78, -1, -1, 81, 82, 83, 84, 85, 86, 87,
+ -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
- 42, 3, 18, 25, 18, 3, 18, 3, 18, 22,
- 18, 3, 18, 22, 32, 32, 42, 18, 18, 18,
- 3, 32, 25, 18, 18, 32, 3, 18, 32, 105,
- 18, 18, 25, 100, 3, 3, 3, 18, 3, 25,
- 18, 3, 18, 18, 18, 42, 3, 3, 103, 9,
- 3, 14, 42, 42, 18, 25, 14, 42, 42, 18,
- 42, 3, 42, 18, 18, 3, 18, 3, 18, 14,
- 42, 22, 18, 2, 4, 18, 42, 18, 2, 11,
- 12, 54, -1, 54, 2, 56, 59, 18, 18, 18,
- 4, 14, 14, 54, 18, 56, 19, 14, 77, 14,
- 18, 23, 2, 46, 18, 54, 54, 54, 2, 2,
- 59, 59, 59, 18, 54, 54, 3, 56, 18, 59,
- 54, 54, 56, 56, 18, 18, 54, 54, 54, 56,
- 56, 59, 18, 54, 51, 56, 51, 2, 54, 2,
- 56, 54, 54, 56, 56, 54, 54, 56, 38, 2,
- 58, 54, 42, 18, 57, 18, 3, 54, 2, 45,
- 18, 92, 54, 54, 2, 18, 3, 18, 109, 66,
- 42, 54, 64, 56, 18, 18, 18, 2, 50, 70,
- 18, 54, 42, 4, 54, 43, 56, 18, 14, 94,
- 50, 78, 2, 18, 45, 68, 18, 18, 54, 18,
- 56, 3, 54, 46, 46, 54, 54, 59, 18, 54,
- 2, 60, 60, 44, 54, 60, 56, 2, 14, 14,
- 3, 54, 44, 19, 19, 51, 18, 60, 47, 2,
- 54, 78, 18, 18, 54, -1, 56, 54, 62, 56,
- 54, 54, 18, 18, 58, 18, 59, 54, 54, 54,
- 57, 54, 58, 54, 59, 54, 59, 54, 59, 45,
- 59, 54, 59, 54, 2, 2, 59, -1, 59, 45,
- 61, -1, 47, 48, 2, -1, 78, 54, -1, 76,
- 18, 18, 59, 76, 54, -1, 54, 54, 54, 59,
- 18, 59, 59, 59, -1, 78, -1, -1, 54, 76,
- 54, 69, -1, 59, 71, 59, 76, 61, 54, 54,
- 76, 67, 54, 59, 59, 61, 5, 59, 54, 61,
- 65, 14, 5, 59, -1, 14, 19, 63, 21, -1,
- -1, 14, -1, -1, 23, -1, -1, -1, -1, -1,
- 23, -1, -1, -1, -1, -1, 35, 36, -1, 42,
- 88, 88, 35, 36, 25, 26, 27, 28, 29, 30,
- 31, 24, 25, 26, 27, 28, 29, 30, 31, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 14, 14, -1, -1, -1, -1, -1,
- -1, -1, 23, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, -1, -1, 35, 36, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 32, 22, 18, 9, 18, 42, 18, 14, 32, 3,
+ 18, 3, 3, 18, 18, 32, 18, 32, 3, 22,
+ 3, 18, 3, 18, 25, 18, 22, 14, 18, 18,
+ 14, 42, 18, 32, 22, 77, 3, 100, 3, 3,
+ 3, 103, 42, 18, 42, 18, 3, 3, 25, 25,
+ 3, 105, 18, 25, 3, 3, 18, 18, 3, 18,
+ 42, 3, 42, 42, 42, 25, 18, 18, 42, 2,
+ -1, 18, 18, 42, 18, 18, 14, 18, 14, 18,
+ 2, 4, 2, 18, 42, 18, 54, 14, 56, 18,
+ -1, 4, -1, 18, -1, 18, 18, 18, 18, 54,
+ 54, 56, 56, 44, 54, 18, 56, 18, 11, 12,
+ 45, -1, -1, 51, 54, 51, 56, 54, 42, 56,
+ 54, 46, 54, 54, 51, 46, 50, 59, 59, 18,
+ 42, -1, -1, -1, 45, 54, 70, 54, 50, 54,
+ 59, 14, 59, 2, 59, 54, 19, 56, 54, 54,
+ 54, 56, 14, 59, 43, 54, 54, 56, 56, 18,
+ 2, 23, 2, 54, 68, 56, 14, 54, 54, 2,
+ 54, 19, 3, 60, 60, 59, 18, 54, 18, 18,
+ 109, 18, 59, 54, 54, 18, 54, 54, 59, 59,
+ 54, 59, 59, 54, 58, 38, 54, 58, 18, 42,
+ 58, 2, 54, 2, 18, 54, 45, 2, 45, 2,
+ 4, 3, 18, 18, 66, 64, 3, 18, 54, 18,
+ 56, 2, 54, 18, 18, 18, 46, 54, 60, 56,
+ 3, 3, 54, 47, 2, 57, 54, 18, 56, 54,
+ 2, 56, 54, 54, 56, 2, 57, 54, 2, 18,
+ 18, 54, 54, 56, -1, 62, 18, 54, 60, 56,
+ -1, 18, 14, 54, 18, 54, 2, 19, 59, -1,
+ 59, 54, 54, -1, 63, 44, 59, 59, -1, 54,
+ 2, -1, 18, 65, 59, 76, 78, 92, 94, 54,
+ 54, 78, 18, 76, 59, 59, 18, 61, 54, 54,
+ -1, 76, 67, 59, 59, 78, 78, 54, 54, -1,
+ 54, 54, 59, 59, 69, 59, 59, 61, 61, 14,
+ 76, 47, 48, -1, 71, -1, 54, 14, 23, 5,
+ 76, 59, 19, 61, 21, 5, -1, -1, 14, -1,
+ 35, 36, -1, -1, 14, -1, -1, 23, -1, -1,
+ -1, -1, 88, 23, -1, 42, -1, -1, -1, 35,
+ 36, -1, -1, -1, -1, 35, 36, 25, 26, 27,
+ 28, 29, 30, 31, -1, -1, -1, -1, -1, -1,
+ -1, 14, -1, -1, -1, -1, -1, -1, -1, 2,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 14,
+ -1, -1, -1, -1, -1, 18, -1, -1, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 88, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 14, -1, -1, -1, -1, -1, -1, -1, -1, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 14, -1,
+ -1, -1, -1, -1, -1, -1, -1, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -1087,6 +1073,6 @@ const short QQmlJSGrammar::action_check [] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1};
+ -1, -1, -1, -1, -1};
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/qmlparser/qqmljsgrammar_p.h b/src/tools/qdoc/qmlparser/qqmljsgrammar_p.h
index 6b3d1c8013..7a369be194 100644
--- a/src/tools/qdoc/qmlparser/qqmljsgrammar_p.h
+++ b/src/tools/qdoc/qmlparser/qqmljsgrammar_p.h
@@ -161,15 +161,15 @@ public:
T_XOR = 79,
T_XOR_EQ = 80,
- ACCEPT_STATE = 663,
- RULE_COUNT = 357,
- STATE_COUNT = 664,
+ ACCEPT_STATE = 665,
+ RULE_COUNT = 358,
+ STATE_COUNT = 666,
TERMINAL_COUNT = 106,
NON_TERMINAL_COUNT = 111,
- GOTO_INDEX_OFFSET = 664,
- GOTO_INFO_OFFSET = 3104,
- GOTO_CHECK_OFFSET = 3104
+ GOTO_INDEX_OFFSET = 666,
+ GOTO_INFO_OFFSET = 3018,
+ GOTO_CHECK_OFFSET = 3018
};
static const char *const spell [];
diff --git a/src/tools/qdoc/qmlparser/qqmljsparser.cpp b/src/tools/qdoc/qmlparser/qqmljsparser.cpp
index 262043b3b8..762e60c827 100644
--- a/src/tools/qdoc/qmlparser/qqmljsparser.cpp
+++ b/src/tools/qdoc/qmlparser/qqmljsparser.cpp
@@ -567,56 +567,78 @@ case 69: {
} break;
case 70: {
- sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
+ node->isReadonlyMember = true;
+ node->readonlyToken = loc(1);
+ node->propertyToken = loc(2);
+ node->typeToken = loc(3);
+ node->identifierToken = loc(4);
+ node->semicolonToken = loc(5); // insert a fake ';' before ':'
+
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
+ propertyName->identifierToken = loc(4);
+ propertyName->next = 0;
+
+ AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
+ propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
+ binding->colonToken = loc(5);
+
+ node->binding = binding;
+
+ sym(1).Node = node;
} break;
case 71: {
sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
-case 79: {
+case 72: {
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
+} break;
+
+case 80: {
AST::ThisExpression *node = new (pool) AST::ThisExpression();
node->thisToken = loc(1);
sym(1).Node = node;
} break;
-case 80: {
+case 81: {
AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 81: {
+case 82: {
AST::NullExpression *node = new (pool) AST::NullExpression();
node->nullToken = loc(1);
sym(1).Node = node;
} break;
-case 82: {
+case 83: {
AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
node->trueToken = loc(1);
sym(1).Node = node;
} break;
-case 83: {
+case 84: {
AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
node->falseToken = loc(1);
sym(1).Node = node;
} break;
-case 84: {
+case 85: {
AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 85:
-case 86: {
+case 86:
+case 87: {
AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 87: {
+case 88: {
bool rx = lexer->scanRegExp(Lexer::NoPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -632,7 +654,7 @@ case 87: {
sym(1).Node = node;
} break;
-case 88: {
+case 89: {
bool rx = lexer->scanRegExp(Lexer::EqualPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -648,28 +670,28 @@ case 88: {
sym(1).Node = node;
} break;
-case 89: {
+case 90: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
} break;
-case 90: {
+case 91: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 91: {
+case 92: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 92: {
+case 93: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
(AST::Elision *) 0);
node->lbracketToken = loc(1);
@@ -678,7 +700,7 @@ case 92: {
sym(1).Node = node;
} break;
-case 93: {
+case 94: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
sym(4).Elision->finish());
node->lbracketToken = loc(1);
@@ -687,7 +709,7 @@ case 93: {
sym(1).Node = node;
} break;
-case 94: {
+case 95: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
node = new (pool) AST::ObjectLiteral(
@@ -699,7 +721,7 @@ case 94: {
sym(1).Node = node;
} break;
-case 95: {
+case 96: {
AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
sym(2).PropertyAssignmentList->finish ());
node->lbraceToken = loc(1);
@@ -707,14 +729,14 @@ case 95: {
sym(1).Node = node;
} break;
-case 96: {
+case 97: {
AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
node->lparenToken = loc(1);
node->rparenToken = loc(3);
sym(1).Node = node;
} break;
-case 97: {
+case 98: {
if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
QLatin1String("Ignored annotation")));
@@ -734,48 +756,48 @@ case 97: {
}
} break;
-case 98: {
+case 99: {
sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
} break;
-case 99: {
+case 100: {
sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
} break;
-case 100: {
+case 101: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
(AST::Elision *) 0, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 101: {
+case 102: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
sym(4).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 102: {
+case 103: {
AST::Elision *node = new (pool) AST::Elision();
node->commaToken = loc(1);
sym(1).Node = node;
} break;
-case 103: {
+case 104: {
AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 104: {
+case 105: {
AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 105: {
+case 106: {
AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
sym(2).PropertyName, sym(6).FunctionBody);
node->getSetToken = loc(1);
@@ -786,7 +808,7 @@ case 105: {
sym(1).Node = node;
} break;
-case 106: {
+case 107: {
AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody);
node->getSetToken = loc(1);
@@ -797,56 +819,56 @@ case 106: {
sym(1).Node = node;
} break;
-case 107: {
+case 108: {
sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
} break;
-case 108: {
+case 109: {
AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 109: {
+case 110: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 110: {
+case 111: {
AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 111: {
+case 112: {
AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 112: {
+case 113: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 148: {
+case 149: {
AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 149: {
+case 150: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 150: {
+case 151: {
AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
node->newToken = loc(1);
node->lparenToken = loc(3);
@@ -854,384 +876,384 @@ case 150: {
sym(1).Node = node;
} break;
-case 152: {
+case 153: {
AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
} break;
-case 153: {
+case 154: {
AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 154: {
+case 155: {
AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 155: {
+case 156: {
AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 156: {
+case 157: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 157: {
+case 158: {
sym(1).Node = 0;
} break;
-case 158: {
+case 159: {
sym(1).Node = sym(1).ArgumentList->finish();
} break;
-case 159: {
+case 160: {
sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
} break;
-case 160: {
+case 161: {
AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 164: {
+case 165: {
AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
node->incrementToken = loc(2);
sym(1).Node = node;
} break;
-case 165: {
+case 166: {
AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
node->decrementToken = loc(2);
sym(1).Node = node;
} break;
-case 167: {
+case 168: {
AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
node->deleteToken = loc(1);
sym(1).Node = node;
} break;
-case 168: {
+case 169: {
AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
node->voidToken = loc(1);
sym(1).Node = node;
} break;
-case 169: {
+case 170: {
AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
node->typeofToken = loc(1);
sym(1).Node = node;
} break;
-case 170: {
+case 171: {
AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
node->incrementToken = loc(1);
sym(1).Node = node;
} break;
-case 171: {
+case 172: {
AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
node->decrementToken = loc(1);
sym(1).Node = node;
} break;
-case 172: {
+case 173: {
AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
node->plusToken = loc(1);
sym(1).Node = node;
} break;
-case 173: {
+case 174: {
AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
node->minusToken = loc(1);
sym(1).Node = node;
} break;
-case 174: {
+case 175: {
AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
node->tildeToken = loc(1);
sym(1).Node = node;
} break;
-case 175: {
+case 176: {
AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
node->notToken = loc(1);
sym(1).Node = node;
} break;
-case 177: {
+case 178: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mul, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 178: {
+case 179: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Div, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 179: {
+case 180: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mod, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 181: {
+case 182: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Add, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 182: {
+case 183: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Sub, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 184: {
+case 185: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::LShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 185: {
+case 186: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::RShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 186: {
+case 187: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::URShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 188: {
+case 189: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 189: {
+case 190: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 190: {
+case 191: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 191: {
+case 192: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 192: {
+case 193: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 193: {
+case 194: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::In, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 195: {
+case 196: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 196: {
+case 197: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 197: {
+case 198: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 198: {
+case 199: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 199: {
+case 200: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 201: {
+case 202: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 202: {
+case 203: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 203: {
+case 204: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 204: {
+case 205: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 206: {
+case 207: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 207: {
+case 208: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 208: {
+case 209: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 209: {
+case 210: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 211: {
+case 212: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 213: {
+case 214: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 215: {
+case 216: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 217: {
+case 218: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 219: {
+case 220: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 221: {
+case 222: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 223: {
+case 224: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 225: {
+case 226: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 227: {
+case 228: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 229: {
+case 230: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 231: {
+case 232: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1239,7 +1261,7 @@ case 231: {
sym(1).Node = node;
} break;
-case 233: {
+case 234: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1247,112 +1269,112 @@ case 233: {
sym(1).Node = node;
} break;
-case 235: {
+case 236: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 237: {
+case 238: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 238: {
+case 239: {
sym(1).ival = QSOperator::Assign;
} break;
-case 239: {
+case 240: {
sym(1).ival = QSOperator::InplaceMul;
} break;
-case 240: {
+case 241: {
sym(1).ival = QSOperator::InplaceDiv;
} break;
-case 241: {
+case 242: {
sym(1).ival = QSOperator::InplaceMod;
} break;
-case 242: {
+case 243: {
sym(1).ival = QSOperator::InplaceAdd;
} break;
-case 243: {
+case 244: {
sym(1).ival = QSOperator::InplaceSub;
} break;
-case 244: {
+case 245: {
sym(1).ival = QSOperator::InplaceLeftShift;
} break;
-case 245: {
+case 246: {
sym(1).ival = QSOperator::InplaceRightShift;
} break;
-case 246: {
+case 247: {
sym(1).ival = QSOperator::InplaceURightShift;
} break;
-case 247: {
+case 248: {
sym(1).ival = QSOperator::InplaceAnd;
} break;
-case 248: {
+case 249: {
sym(1).ival = QSOperator::InplaceXor;
} break;
-case 249: {
+case 250: {
sym(1).ival = QSOperator::InplaceOr;
} break;
-case 251: {
+case 252: {
AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 252: {
+case 253: {
sym(1).Node = 0;
} break;
-case 255: {
+case 256: {
AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 256: {
+case 257: {
sym(1).Node = 0;
} break;
-case 273: {
+case 274: {
AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 274: {
+case 275: {
sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
} break;
-case 275: {
+case 276: {
sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
} break;
-case 276: {
+case 277: {
sym(1).Node = 0;
} break;
-case 277: {
+case 278: {
sym(1).Node = sym(1).StatementList->finish ();
} break;
-case 279: {
+case 280: {
AST::VariableStatement *node = new (pool) AST::VariableStatement(
sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
node->declarationKindToken = loc(1);
@@ -1360,76 +1382,76 @@ case 279: {
sym(1).Node = node;
} break;
-case 280: {
+case 281: {
sym(1).ival = T_CONST;
} break;
-case 281: {
+case 282: {
sym(1).ival = T_VAR;
} break;
-case 282: {
+case 283: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
-case 283: {
+case 284: {
AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 284: {
+case 285: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
-case 285: {
+case 286: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
} break;
-case 286: {
+case 287: {
AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 287: {
+case 288: {
AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 288: {
+case 289: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 289: {
+case 290: {
sym(1).Node = 0;
} break;
-case 291: {
+case 292: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 292: {
+case 293: {
sym(1).Node = 0;
} break;
-case 294: {
+case 295: {
AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
node->semicolonToken = loc(1);
sym(1).Node = node;
} break;
-case 296: {
+case 297: {
AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 297: {
+case 298: {
AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1438,7 +1460,7 @@ case 297: {
sym(1).Node = node;
} break;
-case 298: {
+case 299: {
AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1446,7 +1468,7 @@ case 298: {
sym(1).Node = node;
} break;
-case 301: {
+case 302: {
AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
node->doToken = loc(1);
node->whileToken = loc(3);
@@ -1456,7 +1478,7 @@ case 301: {
sym(1).Node = node;
} break;
-case 302: {
+case 303: {
AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
node->whileToken = loc(1);
node->lparenToken = loc(2);
@@ -1464,7 +1486,7 @@ case 302: {
sym(1).Node = node;
} break;
-case 303: {
+case 304: {
AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
sym(5).Expression, sym(7).Expression, sym(9).Statement);
node->forToken = loc(1);
@@ -1475,7 +1497,7 @@ case 303: {
sym(1).Node = node;
} break;
-case 304: {
+case 305: {
AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
@@ -1488,7 +1510,7 @@ case 304: {
sym(1).Node = node;
} break;
-case 305: {
+case 306: {
AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
@@ -1498,7 +1520,7 @@ case 305: {
sym(1).Node = node;
} break;
-case 306: {
+case 307: {
AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
node->forToken = loc(1);
@@ -1509,14 +1531,14 @@ case 306: {
sym(1).Node = node;
} break;
-case 308: {
+case 309: {
AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
node->continueToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 310: {
+case 311: {
AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
node->continueToken = loc(1);
node->identifierToken = loc(2);
@@ -1524,14 +1546,14 @@ case 310: {
sym(1).Node = node;
} break;
-case 312: {
+case 313: {
AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
node->breakToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 314: {
+case 315: {
AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
node->breakToken = loc(1);
node->identifierToken = loc(2);
@@ -1539,14 +1561,14 @@ case 314: {
sym(1).Node = node;
} break;
-case 316: {
+case 317: {
AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
node->returnToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 317: {
+case 318: {
AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
node->withToken = loc(1);
node->lparenToken = loc(2);
@@ -1554,7 +1576,7 @@ case 317: {
sym(1).Node = node;
} break;
-case 318: {
+case 319: {
AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
node->switchToken = loc(1);
node->lparenToken = loc(2);
@@ -1562,83 +1584,83 @@ case 318: {
sym(1).Node = node;
} break;
-case 319: {
+case 320: {
AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 320: {
+case 321: {
AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(5);
sym(1).Node = node;
} break;
-case 321: {
+case 322: {
sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
} break;
-case 322: {
+case 323: {
sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
} break;
-case 323: {
+case 324: {
sym(1).Node = 0;
} break;
-case 324: {
+case 325: {
sym(1).Node = sym(1).CaseClauses->finish ();
} break;
-case 325: {
+case 326: {
AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
node->caseToken = loc(1);
node->colonToken = loc(3);
sym(1).Node = node;
} break;
-case 326: {
+case 327: {
AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
node->defaultToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 327: {
+case 328: {
AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 329: {
+case 330: {
AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
node->throwToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 330: {
+case 331: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 331: {
+case 332: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 332: {
+case 333: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 333: {
+case 334: {
AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
node->catchToken = loc(1);
node->lparenToken = loc(2);
@@ -1647,20 +1669,20 @@ case 333: {
sym(1).Node = node;
} break;
-case 334: {
+case 335: {
AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
node->finallyToken = loc(1);
sym(1).Node = node;
} break;
-case 336: {
+case 337: {
AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
node->debuggerToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 338: {
+case 339: {
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
node->identifierToken = loc(2);
@@ -1671,7 +1693,7 @@ case 338: {
sym(1).Node = node;
} break;
-case 339: {
+case 340: {
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
if (! stringRef(2).isNull())
@@ -1683,7 +1705,7 @@ case 339: {
sym(1).Node = node;
} break;
-case 340: {
+case 341: {
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody);
node->functionToken = loc(1);
node->lparenToken = loc(2);
@@ -1693,56 +1715,56 @@ case 340: {
sym(1).Node = node;
} break;
-case 341: {
+case 342: {
AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 342: {
+case 343: {
AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
node->commaToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 343: {
+case 344: {
sym(1).Node = 0;
} break;
-case 344: {
+case 345: {
sym(1).Node = sym(1).FormalParameterList->finish ();
} break;
-case 345: {
+case 346: {
sym(1).Node = 0;
} break;
-case 347: {
+case 348: {
sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
} break;
-case 349: {
+case 350: {
sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
} break;
-case 350: {
+case 351: {
sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
} break;
-case 351: {
+case 352: {
sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
} break;
-case 352: {
+case 353: {
sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
} break;
-case 353: {
+case 354: {
sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
} break;
-case 354: {
+case 355: {
sym(1).Node = 0;
} break;
diff --git a/src/tools/qdoc/qmlparser/qqmljsparser_p.h b/src/tools/qdoc/qmlparser/qqmljsparser_p.h
index b0abf06b25..cf9f641fbc 100644
--- a/src/tools/qdoc/qmlparser/qqmljsparser_p.h
+++ b/src/tools/qdoc/qmlparser/qqmljsparser_p.h
@@ -240,9 +240,9 @@ protected:
-#define J_SCRIPT_REGEXPLITERAL_RULE1 87
+#define J_SCRIPT_REGEXPLITERAL_RULE1 88
-#define J_SCRIPT_REGEXPLITERAL_RULE2 88
+#define J_SCRIPT_REGEXPLITERAL_RULE2 89
QT_QML_END_NAMESPACE
diff --git a/src/tools/qlalr/doc/src/images/qt-logo.png b/src/tools/qlalr/doc/src/images/qt-logo.png
index 2dc67161c1..6e7d000c04 100644
--- a/src/tools/qlalr/doc/src/images/qt-logo.png
+++ b/src/tools/qlalr/doc/src/images/qt-logo.png
Binary files differ
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 9d8a7b7051..5769ed552c 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -730,33 +730,37 @@ bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIO
{
m_errorDevice = &errorDevice;
- const char pattern[] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };
if (m_format == Pass2) {
- char c;
- for (int i = 0; i < 8; ) {
- if (!tempDevice.getChar(&c)) {
- m_errorDevice->write("No data signature found\n");
- return false;
- }
- if (c == pattern[i]) {
- ++i;
- } else {
- for (int k = 0; k < i; ++k)
- outDevice.putChar(pattern[k]);
- outDevice.putChar(c);
- i = 0;
+ const char pattern[] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };
+ bool foundSignature = false;
+
+ while (true) {
+ char c;
+ for (int i = 0; i < 8; ) {
+ if (!tempDevice.getChar(&c)) {
+ if (foundSignature)
+ return true;
+ m_errorDevice->write("No data signature found\n");
+ return false;
+ }
+ if (c == pattern[i]) {
+ ++i;
+ } else {
+ for (int k = 0; k < i; ++k)
+ outDevice.putChar(pattern[k]);
+ outDevice.putChar(c);
+ i = 0;
+ }
}
- }
- m_outDevice = &outDevice;
- quint64 start = outDevice.pos();
- writeDataBlobs();
- quint64 len = outDevice.pos() - start;
+ m_outDevice = &outDevice;
+ quint64 start = outDevice.pos();
+ writeDataBlobs();
+ quint64 len = outDevice.pos() - start;
- tempDevice.seek(tempDevice.pos() + len - 8);
- outDevice.write(tempDevice.readAll());
-
- return true;
+ tempDevice.seek(tempDevice.pos() + len - 8);
+ foundSignature = true;
+ }
}
//write out
@@ -889,6 +893,8 @@ bool RCCResourceLibrary::writeDataBlobs()
if (m_format == C_Code)
writeString("\n};\n\n");
else if (m_format == Pass1) {
+ if (offset < 8)
+ offset = 8;
writeString("\nstatic const unsigned char qt_resource_data[");
writeByteArray(QByteArray::number(offset));
writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp
index ade5cfe3dc..41692d11bd 100644
--- a/src/widgets/accessible/simplewidgets.cpp
+++ b/src/widgets/accessible/simplewidgets.cpp
@@ -414,12 +414,14 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const
if (qobject_cast<QLabel*>(object())) {
QLabel *label = qobject_cast<QLabel*>(object());
str = label->text();
+#ifndef QT_NO_TEXTHTMLPARSER
if (label->textFormat() == Qt::RichText
|| (label->textFormat() == Qt::AutoText && Qt::mightBeRichText(str))) {
QTextDocument doc;
doc.setHtml(str);
str = doc.toPlainText();
}
+#endif
if (label->buddy())
str = qt_accStripAmp(str);
#ifndef QT_NO_LCDNUMBER
diff --git a/src/widgets/dialogs/images/qtlogo-64.png b/src/widgets/dialogs/images/qtlogo-64.png
index 4f68e162de..af87e98cf5 100644
--- a/src/widgets/dialogs/images/qtlogo-64.png
+++ b/src/widgets/dialogs/images/qtlogo-64.png
Binary files differ
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 0ba3ea40e0..6065ad015e 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -510,7 +510,7 @@ bool QFileDialog::restoreState(const QByteArray &state)
if (!d->qFileDialogUi->splitter->restoreState(d->splitterState))
return false;
QList<int> list = d->qFileDialogUi->splitter->sizes();
- if (list.count() >= 2 && list.at(0) == 0 && list.at(1) == 0) {
+ if (list.count() >= 2 && (list.at(0) == 0 || list.at(1) == 0)) {
for (int i = 0; i < list.count(); ++i)
list[i] = d->qFileDialogUi->splitter->widget(i)->sizeHint().width();
d->qFileDialogUi->splitter->setSizes(list);
diff --git a/src/widgets/dialogs/qfiledialog.ui b/src/widgets/dialogs/qfiledialog.ui
index 89adaf530e..7f6e59c908 100644
--- a/src/widgets/dialogs/qfiledialog.ui
+++ b/src/widgets/dialogs/qfiledialog.ui
@@ -179,6 +179,9 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
+ <property name="childrenCollapsible">
+ <bool>false</bool>
+ </property>
<widget class="QSidebar" name="sidebar">
<property name="accessibleName">
<string>Sidebar</string>
diff --git a/src/widgets/dialogs/qfiledialog_embedded.ui b/src/widgets/dialogs/qfiledialog_embedded.ui
index 16128dc0a0..4cdc620437 100644
--- a/src/widgets/dialogs/qfiledialog_embedded.ui
+++ b/src/widgets/dialogs/qfiledialog_embedded.ui
@@ -1,4 +1,5 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<comment>*********************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
@@ -40,8 +41,8 @@
**
*********************************************************************</comment>
<class>QFileDialog</class>
- <widget class="QDialog" name="QFileDialog" >
- <property name="geometry" >
+ <widget class="QDialog" name="QFileDialog">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
@@ -49,14 +50,14 @@
<height>320</height>
</rect>
</property>
- <property name="sizeGripEnabled" >
+ <property name="sizeGripEnabled">
<bool>true</bool>
</property>
- <layout class="QVBoxLayout" >
+ <layout class="QVBoxLayout">
<item>
- <widget class="QFileDialogComboBox" name="lookInCombo" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <widget class="QFileDialogComboBox" name="lookInCombo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -64,45 +65,45 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" >
+ <layout class="QHBoxLayout">
<item>
- <widget class="QToolButton" name="backButton" >
- <property name="toolTip" >
+ <widget class="QToolButton" name="backButton">
+ <property name="toolTip">
<string>Back</string>
</property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="forwardButton" >
- <property name="toolTip" >
+ <widget class="QToolButton" name="forwardButton">
+ <property name="toolTip">
<string>Forward</string>
</property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="toParentButton" >
- <property name="toolTip" >
+ <widget class="QToolButton" name="toParentButton">
+ <property name="toolTip">
<string>Parent Directory</string>
</property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="newFolderButton" >
- <property name="toolTip" >
+ <widget class="QToolButton" name="newFolderButton">
+ <property name="toolTip">
<string>Create New Folder</string>
</property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="listModeButton" >
- <property name="toolTip" >
+ <widget class="QToolButton" name="listModeButton">
+ <property name="toolTip">
<string>List View</string>
</property>
</widget>
</item>
<item>
- <widget class="QToolButton" name="detailModeButton" >
- <property name="toolTip" >
+ <widget class="QToolButton" name="detailModeButton">
+ <property name="toolTip">
<string>Detail View</string>
</property>
</widget>
@@ -110,75 +111,89 @@
</layout>
</item>
<item>
- <widget class="QSplitter" name="splitter" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <widget class="QSplitter" name="splitter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <widget class="QSidebar" name="sidebar" />
- <widget class="QFrame" name="frame" >
- <property name="frameShape" >
+ <property name="childrenCollapsible">
+ <bool>false</bool>
+ </property>
+ <widget class="QSidebar" name="sidebar"/>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
- <property name="frameShadow" >
+ <property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QVBoxLayout" >
- <property name="spacing" >
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
<number>0</number>
</property>
- <property name="margin" >
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
- <widget class="QStackedWidget" name="stackedWidget" >
- <property name="currentIndex" >
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="currentIndex">
<number>0</number>
</property>
- <widget class="QWidget" name="page" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>108</width>
- <height>164</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" >
- <property name="spacing" >
+ <widget class="QWidget" name="page">
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
<number>0</number>
</property>
- <property name="margin" >
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
- <widget class="QFileDialogListView" name="listView" />
+ <widget class="QFileDialogListView" name="listView"/>
</item>
</layout>
</widget>
- <widget class="QWidget" name="page_2" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>100</width>
- <height>30</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" >
- <property name="spacing" >
+ <widget class="QWidget" name="page_2">
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
<number>0</number>
</property>
- <property name="margin" >
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
- <widget class="QFileDialogTreeView" name="treeView" />
+ <widget class="QFileDialogTreeView" name="treeView"/>
</item>
</layout>
</widget>
@@ -189,31 +204,31 @@
</widget>
</item>
<item>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QFileDialogLineEdit" name="fileNameEdit" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QFileDialogLineEdit" name="fileNameEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
- <item rowspan="2" row="0" column="1" >
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
+ <item row="0" column="1" rowspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="standardButtons" >
+ <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QComboBox" name="fileTypeCombo" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <item row="1" column="0">
+ <widget class="QComboBox" name="fileTypeCombo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -223,23 +238,23 @@
</layout>
</item>
<item>
- <widget class="QLabel" name="fileNameLabel" >
- <property name="enabled" >
+ <widget class="QLabel" name="fileNameLabel">
+ <property name="enabled">
<bool>false</bool>
</property>
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="minimumSize" >
+ <property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
- <property name="maximumSize" >
+ <property name="maximumSize">
<size>
<width>0</width>
<height>0</height>
@@ -248,45 +263,45 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="fileTypeLabel" >
- <property name="enabled" >
+ <widget class="QLabel" name="fileTypeLabel">
+ <property name="enabled">
<bool>false</bool>
</property>
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="maximumSize" >
+ <property name="maximumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
- <property name="text" >
+ <property name="text">
<string>Files of type:</string>
</property>
</widget>
</item>
<item>
- <widget class="QLabel" name="lookInLabel" >
- <property name="enabled" >
+ <widget class="QLabel" name="lookInLabel">
+ <property name="enabled">
<bool>false</bool>
</property>
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="maximumSize" >
+ <property name="maximumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
- <property name="text" >
+ <property name="text">
<string>Look in:</string>
</property>
</widget>
@@ -297,27 +312,27 @@
<customwidget>
<class>QFileDialogTreeView</class>
<extends>QTreeView</extends>
- <header>qfiledialog_p.h</header>
+ <header>private/qfiledialog_p.h</header>
</customwidget>
<customwidget>
<class>QFileDialogListView</class>
<extends>QListView</extends>
- <header>qfiledialog_p.h</header>
+ <header>private/qfiledialog_p.h</header>
</customwidget>
<customwidget>
<class>QSidebar</class>
<extends>QListWidget</extends>
- <header>qsidebar_p.h</header>
+ <header>private/qsidebar_p.h</header>
</customwidget>
<customwidget>
<class>QFileDialogLineEdit</class>
<extends>QLineEdit</extends>
- <header>qfiledialog_p.h</header>
+ <header>private/qfiledialog_p.h</header>
</customwidget>
<customwidget>
<class>QFileDialogComboBox</class>
<extends>QComboBox</extends>
- <header>qfiledialog_p.h</header>
+ <header>private/qfiledialog_p.h</header>
</customwidget>
</customwidgets>
<tabstops>
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 988d3ad3c7..baa55cb88f 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE
QFileSystemModel can be accessed using the standard interface provided by
QAbstractItemModel, but it also provides some convenience functions that are
specific to a directory model.
- The fileInfo(), isDir(), name(), and path() functions provide information
+ The fileInfo(), isDir(), fileName() and filePath() functions provide information
about the underlying files and directories related to items in the model.
Directories can be created and removed using mkdir(), rmdir().
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 1f7b18e824..a378daa3d3 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -2571,6 +2571,14 @@ void QWizard::setWizardStyle(WizardStyle style)
d->disableUpdates();
d->wizStyle = style;
d->updateButtonTexts();
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+ if (aeroStyleChange) {
+ //Send a resizeevent since the antiflicker widget probably needs a new size
+ //because of the backbutton in the window title
+ QResizeEvent ev(geometry().size(), geometry().size());
+ QApplication::sendEvent(this, &ev);
+ }
+#endif
d->updateLayout();
updateGeometry();
d->enableUpdates();
diff --git a/src/widgets/doc/snippets/code/doc_src_layout.cpp b/src/widgets/doc/snippets/code/doc_src_layout.cpp
index 5ea8ce5a5f..a10cd52e2e 100644
--- a/src/widgets/doc/snippets/code/doc_src_layout.cpp
+++ b/src/widgets/doc/snippets/code/doc_src_layout.cpp
@@ -42,7 +42,7 @@
#ifndef CARD_H
#define CARD_H
-#include <QtGui>
+#include <QtWidgets>
#include <QList>
class CardLayout : public QLayout
diff --git a/src/widgets/doc/snippets/qlistview-dnd/main.cpp b/src/widgets/doc/snippets/qlistview-dnd/main.cpp
index c4a8aebb01..422ce35c6b 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/main.cpp
+++ b/src/widgets/doc/snippets/qlistview-dnd/main.cpp
@@ -38,7 +38,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
diff --git a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp
index ed06819dd9..3b19295676 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp
+++ b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp
@@ -38,7 +38,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include "mainwindow.h"
#include "model.h"
diff --git a/src/widgets/doc/snippets/qlistview-dnd/model.cpp b/src/widgets/doc/snippets/qlistview-dnd/model.cpp
index 6ebeb2eb56..aa12cef3a2 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/model.cpp
+++ b/src/widgets/doc/snippets/qlistview-dnd/model.cpp
@@ -65,18 +65,31 @@ DragDropListModel::DragDropListModel(const QStringList &strings,
}
//! [0]
-bool DragDropListModel::dropMimeData(const QMimeData *data,
+bool DragDropListModel::canDropMimeData(const QMimeData *data,
Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
- if (action == Qt::IgnoreAction)
- return true;
+ Q_UNUSED(action);
+ Q_UNUSED(row);
+ Q_UNUSED(parent);
if (!data->hasFormat("application/vnd.text.list"))
return false;
if (column > 0)
-//! [0] //! [1]
return false;
+
+ return true;
+}
+//! [0]
+//! [1]
+bool DragDropListModel::dropMimeData(const QMimeData *data,
+ Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+ if (!canDropMimeData(data, action, row, column, parent))
+ return false;
+
+ if (action == Qt::IgnoreAction)
+ return true;
//! [1]
//! [2]
diff --git a/src/widgets/doc/snippets/qlistview-dnd/model.h b/src/widgets/doc/snippets/qlistview-dnd/model.h
index 9b667ad4a3..9217052971 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/model.h
+++ b/src/widgets/doc/snippets/qlistview-dnd/model.h
@@ -63,6 +63,8 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool canDropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent);
QMimeData *mimeData(const QModelIndexList &indexes) const;
diff --git a/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro b/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro
index 71fa273a69..bc2a1f0dce 100644
--- a/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro
+++ b/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro
@@ -3,3 +3,4 @@ SOURCES = main.cpp \
model.cpp
HEADERS = mainwindow.h \
model.h
+QT += widgets
diff --git a/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc
index 8978efa1e3..ada0460689 100644
--- a/src/widgets/doc/src/model-view-programming.qdoc
+++ b/src/widgets/doc/src/model-view-programming.qdoc
@@ -1769,6 +1769,9 @@
dropped onto existing items separately to data dropped into the top level
of the model (i.e., onto an invalid item).
+ Models can forbid dropping on certain items, or depending on the dropped data,
+ by reimplementing QAbstractItemModel::canDropMimeData().
+
The model first has to make sure that the operation should be acted on,
the data supplied is in a format that can be used, and that its destination
within the model is valid:
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 67d135271c..03f22a270f 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -1968,8 +1968,10 @@ QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
Caching can speed up rendering if your item spends a significant time
redrawing itself. In some cases the cache can also slow down rendering, in
particular when the item spends less time redrawing than QGraphicsItem
- spends redrawing from the cache. When enabled, the item's paint() function
- will be called only once for each call to update(); for any subsequent
+ spends redrawing from the cache.
+
+ When caching is enabled, an item's paint() function will generally draw into an
+ offscreen pixmap cache; for any subsequent
repaint requests, the Graphics View framework will redraw from the
cache. This approach works particularly well with QGLWidget, which stores
all the cache as OpenGL textures.
@@ -1980,6 +1982,12 @@ QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
You can read more about the different cache modes in the CacheMode
documentation.
+ \note Enabling caching does not imply that the item's paint() function will be
+ called only in response to an explicit update() call. For instance, under
+ memory pressure, Qt may decide to drop some of the cache information;
+ in such cases an item's paint() function will be called even if there
+ was no update() call (that is, exactly as if there were no caching enabled).
+
\sa CacheMode, QPixmapCache::setCacheLimit()
*/
void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
@@ -2439,7 +2447,12 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly,
Items are visible by default; it is unnecessary to call
setVisible() on a new item.
- \sa isVisible(), show(), hide()
+ \note An item with opacity set to 0 will still be considered visible,
+ although it will be treated like an invisible item: mouse events will pass
+ through it, it will not be included in the items returned by
+ QGraphicsView::items(), and so on. However, the item will retain the focus.
+
+ \sa isVisible(), show(), hide(), setOpacity()
*/
void QGraphicsItem::setVisible(bool visible)
{
@@ -2707,7 +2720,11 @@ qreal QGraphicsItem::effectiveOpacity() const
with the parent: ItemIgnoresParentOpacity and
ItemDoesntPropagateOpacityToChildren.
- \sa opacity(), effectiveOpacity()
+ \note Setting the opacity of an item to 0 will not make the item invisible
+ (according to isVisible()), but the item will be treated like an invisible
+ one. See the documentation of setVisible() for more information.
+
+ \sa opacity(), effectiveOpacity(), setVisible()
*/
void QGraphicsItem::setOpacity(qreal opacity)
{
@@ -4487,7 +4504,7 @@ void QGraphicsItem::resetTransform()
Use
\code
- setRotation(rotation() + angle);
+ item->setTransform(QTransform().rotate(angle), true);
\endcode
instead.
@@ -5337,6 +5354,16 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
All painting is done in local coordinates.
+ \note It is mandatory that an item will always redraw itself in the exact
+ same way, unless update() was called; otherwise visual artifacts may
+ occur. In other words, two subsequent calls to paint() must always produce
+ the same output, unless update() was called between them.
+
+ \note Enabling caching for an item does not guarantee that paint()
+ will be invoked only once by the Graphics View framework,
+ even without any explicit call to update(). See the documentation of
+ setCacheMode() for more details.
+
\sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
*/
@@ -9764,6 +9791,7 @@ QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
using textWidth().
\note In order to align HTML text in the center, the item's text width must be set.
+ Otherwise, you can call adjustSize() after setting the item's text.
\image graphicsview-textitem.png
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index a6361bd750..9d38a330c8 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1905,7 +1905,7 @@ void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
&& (event->source() != this|| !(event->possibleActions() & Qt::MoveAction)))
return;
- if (d_func()->canDecode(event)) {
+ if (d_func()->canDrop(event)) {
event->accept();
setState(DraggingState);
} else {
@@ -1934,7 +1934,7 @@ void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
QModelIndex index = indexAt(event->pos());
d->hover = index;
if (!d->droppingOnItself(event, index)
- && d->canDecode(event)) {
+ && d->canDrop(event)) {
if (index.isValid() && d->showDropIndicator) {
QRect rect = visualRect(index);
@@ -1979,7 +1979,7 @@ void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
}
}
d->viewport->update();
- } // can decode
+ } // can drop
if (d->shouldAutoScroll(event->pos()))
startAutoScroll();
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 047533b22c..c3bd1fb504 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -164,13 +164,15 @@ public:
#ifndef QT_NO_DRAGANDDROP
virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
- inline bool canDecode(QDropEvent *e) const {
- QStringList modelTypes = model->mimeTypes();
- const QMimeData *mime = e->mimeData();
- for (int i = 0; i < modelTypes.count(); ++i)
- if (mime->hasFormat(modelTypes.at(i))
- && (e->dropAction() & model->supportedDropActions()))
- return true;
+ inline bool canDrop(QDropEvent *event) {
+ QModelIndex index;
+ int col = -1;
+ int row = -1;
+ if (dropOn(event, &row, &col, &index)) {
+ return model->canDropMimeData(event->mimeData(),
+ dragDropMode == QAbstractItemView::InternalMove ? Qt::MoveAction : event->dropAction(),
+ row, col, index);
+ }
return false;
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index a097228846..e7d18092f1 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1977,7 +1977,7 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
? intersectVector.last() : QModelIndex();
dd->hover = index;
if (!dd->droppingOnItself(event, index)
- && dd->canDecode(event)) {
+ && dd->canDrop(event)) {
if (index.isValid() && dd->showDropIndicator) {
QRect rect = qq->visualRect(index);
@@ -2023,7 +2023,7 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
}
}
dd->viewport->update();
- } // can decode
+ } // can drop
if (dd->shouldAutoScroll(event->pos()))
qq->startAutoScroll();
@@ -2757,7 +2757,7 @@ bool QIconModeViewBase::filterDragLeaveEvent(QDragLeaveEvent *e)
bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e)
{
- if (e->source() != qq || !dd->canDecode(e))
+ if (e->source() != qq || !dd->canDrop(e))
return false;
// ignore by default
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 9abec13b5b..500e812e28 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -53,6 +53,7 @@
#include "qtranslator.h"
#include "qvariant.h"
#include "qwidget.h"
+#include "qgraphicssceneevent.h"
#include "private/qdnd_p.h"
#include "private/qguiapplication_p.h"
#include "qcolormap.h"
@@ -2291,6 +2292,31 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
return w;
}
+Qt::MouseEventSource QApplicationPrivate::mouseEventSource(const QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ return static_cast<const QMouseEvent *>(e)->source();
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseMove:
+ return static_cast<const QGraphicsSceneMouseEvent *>(e)->source();
+#endif // !QT_NO_GRAPHICSVIEW
+ default:
+ break;
+ }
+ return Qt::MouseEventNotSynthesized;
+}
+
/*!
\fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, const QPointF &globalPosF)
\internal
@@ -4211,8 +4237,9 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
return true;
}
-void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
+bool QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
{
+ bool containsPress = false;
for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
@@ -4225,7 +4252,11 @@ void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEven
touchPoint.d->rect = rect;
touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
+
+ if (touchPoint.state() == Qt::TouchPointPressed)
+ containsPress = true;
}
+ return containsPress;
}
void QApplicationPrivate::initializeMultitouch()
@@ -4372,11 +4403,14 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
QApplication::keyboardModifiers(),
it.value().first,
it.value().second);
- updateTouchPointsForWidget(widget, &touchEvent);
+ bool containsPress = updateTouchPointsForWidget(widget, &touchEvent);
touchEvent.setTimestamp(timestamp);
touchEvent.setWindow(window->windowHandle());
touchEvent.setTarget(widget);
+ if (containsPress)
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
+
switch (touchEvent.type()) {
case QEvent::TouchBegin:
{
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 156bf34194..b24b592fbe 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -168,6 +168,7 @@ public:
static void setFocusWidget(QWidget *focus, Qt::FocusReason reason);
static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next,
bool *wrappingOccurred = 0);
+ static Qt::MouseEventSource mouseEventSource(const QEvent *e);
#ifndef QT_NO_GRAPHICSVIEW
// Maintain a list of all scenes to ensure font and palette propagation to
@@ -275,7 +276,7 @@ public:
QPixmap *ignore_cursor;
#endif
- static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent);
+ static bool updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent);
void initializeMultitouch();
void initializeMultitouch_sys();
void cleanupMultitouch();
diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h
index 8668145d8a..26d9ede59d 100644
--- a/src/widgets/kernel/qgesture_p.h
+++ b/src/widgets/kernel/qgesture_p.h
@@ -80,7 +80,7 @@ class QPanGesturePrivate : public QGesturePrivate
public:
QPanGesturePrivate()
- : acceleration(0), xVelocity(0), yVelocity(0)
+ : acceleration(0), xVelocity(0), yVelocity(0), pointCount(2)
{
}
@@ -95,6 +95,7 @@ public:
qreal acceleration;
qreal xVelocity;
qreal yVelocity;
+ int pointCount; // ### fixme Qt 5.5: Add accessor to QPanGesture.
};
class QPinchGesturePrivate : public QGesturePrivate
@@ -134,11 +135,17 @@ class QSwipeGesturePrivate : public QGesturePrivate
Q_DECLARE_PUBLIC(QSwipeGesture)
public:
+ enum State {
+ NoGesture,
+ Started,
+ ThreePointsReached
+ };
+
QSwipeGesturePrivate()
: horizontalDirection(QSwipeGesture::NoDirection),
verticalDirection(QSwipeGesture::NoDirection),
swipeAngle(0),
- started(false), velocityValue(0)
+ state(NoGesture), velocityValue(0)
{
}
@@ -150,7 +157,7 @@ public:
qreal swipeAngle;
QPoint lastPositions[3];
- bool started;
+ State state;
qreal velocityValue;
QElapsedTimer time;
};
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index 739e6b1870..c9af3062d3 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -63,6 +63,24 @@
QT_BEGIN_NAMESPACE
+static inline int panTouchPoints()
+{
+ // Override by environment variable for testing.
+ static const char panTouchPointVariable[] = "QT_PAN_TOUCHPOINTS";
+ if (qEnvironmentVariableIsSet(panTouchPointVariable)) {
+ bool ok;
+ const int result = qgetenv(panTouchPointVariable).toInt(&ok);
+ if (ok && result >= 1)
+ return result;
+ qWarning() << "Ignoring invalid value of " << panTouchPointVariable;
+ }
+ // Pan should use 1 finger on a touch screen and 2 fingers on touch pads etc.
+ // where 1 finger movements are used for mouse event synthetization. For now,
+ // default to 2 until all classes inheriting QScrollArea are fixed to handle it
+ // correctly.
+ return 2;
+}
+
QGestureManager::QGestureManager(QObject *parent)
: QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture)
{
@@ -73,7 +91,7 @@ QGestureManager::QGestureManager(QObject *parent)
registerGestureRecognizer(new QMacPinchGestureRecognizer);
registerGestureRecognizer(new QMacPanGestureRecognizer);
#else
- registerGestureRecognizer(new QPanGestureRecognizer);
+ registerGestureRecognizer(new QPanGestureRecognizer(panTouchPoints()));
registerGestureRecognizer(new QPinchGestureRecognizer);
registerGestureRecognizer(new QSwipeGestureRecognizer);
registerGestureRecognizer(new QTapGestureRecognizer);
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 8a4e0c8ffd..db116b070c 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -471,7 +471,7 @@ class QOpenGLWidgetPaintDevice : public QOpenGLPaintDevice
{
public:
QOpenGLWidgetPaintDevice(QOpenGLWidget *widget)
- : QOpenGLPaintDevice(new QOpenGLWidgetPaintDevicePrivate(widget)) { }
+ : QOpenGLPaintDevice(*new QOpenGLWidgetPaintDevicePrivate(widget)) { }
void ensureActiveTarget() Q_DECL_OVERRIDE;
};
@@ -578,12 +578,22 @@ GLuint QOpenGLWidgetPrivate::textureId() const
void QOpenGLWidgetPrivate::reset()
{
+ Q_Q(QOpenGLWidget);
+
+ // Destroy the OpenGL resources first. These need the context to be current.
+ if (initialized)
+ q->makeCurrent();
+
delete paintDevice;
paintDevice = 0;
delete fbo;
fbo = 0;
delete resolvedFbo;
resolvedFbo = 0;
+
+ if (initialized)
+ q->doneCurrent();
+
// Delete the context first, then the surface. Slots connected to
// the context's aboutToBeDestroyed() may still call makeCurrent()
// to perform some cleanup.
diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp
index 0822c04033..53e5d091fa 100644
--- a/src/widgets/kernel/qstandardgestures.cpp
+++ b/src/widgets/kernel/qstandardgestures.cpp
@@ -38,16 +38,13 @@
#include "qwidget.h"
#include "qabstractscrollarea.h"
#include <qgraphicssceneevent.h>
+#include <QtGui/QTouchDevice>
#include "qdebug.h"
#ifndef QT_NO_GESTURES
QT_BEGIN_NAMESPACE
-QPanGestureRecognizer::QPanGestureRecognizer()
-{
-}
-
QGesture *QPanGestureRecognizer::create(QObject *target)
{
if (target && target->isWidgetType()) {
@@ -62,8 +59,35 @@ QGesture *QPanGestureRecognizer::create(QObject *target)
return new QPanGesture;
}
+static QPointF panOffset(const QList<QTouchEvent::TouchPoint> &touchPoints, int maxCount)
+{
+ QPointF result;
+ const int count = qMin(touchPoints.size(), maxCount);
+ for (int p = 0; p < count; ++p)
+ result += touchPoints.at(p).pos() - touchPoints.at(p).startPos();
+ return result / qreal(count);
+}
+
+// ### fixme: Remove this
+// Use single finger pan to scroll QPlainTextEdit/QTextEdit
+// by changing the number of pan points to 1 for these classes.
+// This used to be Qt 4's behavior on Windows which was achieved using native
+// Windows gesture recognizers for these classes.
+// The other classes inheriting QScrollArea still use standard 2 finger pan.
+// In the long run, they should also use single finger pan to
+// scroll on touch screens, however, this requires a distinct Tap&Hold-followed-by-pan
+// type gesture to avoid clashes with item view selection and DnD.
+
+static inline int panTouchPoints(const QTouchEvent *event, const QObject *object,
+ int defaultTouchPoints)
+{
+ return event->device()->type() == QTouchDevice::TouchScreen && object && object->parent()
+ && (object->parent()->inherits("QPlainTextEdit") || object->parent()->inherits("QTextEdit"))
+ ? 1 : defaultTouchPoints;
+}
+
QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
- QObject *,
+ QObject *object,
QEvent *event)
{
QPanGesture *q = static_cast<QPanGesture *>(state);
@@ -76,18 +100,15 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
result = QGestureRecognizer::MayBeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
d->lastOffset = d->offset = QPointF();
+ d->pointCount = panTouchPoints(ev, object, m_pointCount);
break;
}
case QEvent::TouchEnd: {
if (q->state() != Qt::NoGesture) {
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
- if (ev->touchPoints().size() == 2) {
- QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
- QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ if (ev->touchPoints().size() == d->pointCount) {
d->lastOffset = d->offset;
- d->offset =
- QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
- p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
+ d->offset = panOffset(ev->touchPoints(), d->pointCount);
}
result = QGestureRecognizer::FinishGesture;
} else {
@@ -97,16 +118,12 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
}
case QEvent::TouchUpdate: {
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
- if (ev->touchPoints().size() >= 2) {
- QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
- QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ if (ev->touchPoints().size() >= d->pointCount) {
d->lastOffset = d->offset;
- d->offset =
- QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
- p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
+ d->offset = panOffset(ev->touchPoints(), d->pointCount);
if (d->offset.x() > 10 || d->offset.y() > 10 ||
d->offset.x() < -10 || d->offset.y() < -10) {
- q->setHotSpot(p1.startScreenPos());
+ q->setHotSpot(ev->touchPoints().first().startScreenPos());
result = QGestureRecognizer::TriggerGesture;
} else {
result = QGestureRecognizer::MayBeGesture;
@@ -283,7 +300,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
case QEvent::TouchBegin: {
d->velocityValue = 1;
d->time.start();
- d->started = true;
+ d->state = QSwipeGesturePrivate::Started;
result = QGestureRecognizer::MayBeGesture;
break;
}
@@ -297,9 +314,10 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
}
case QEvent::TouchUpdate: {
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
- if (!d->started)
+ if (d->state == QSwipeGesturePrivate::NoGesture)
result = QGestureRecognizer::CancelGesture;
else if (ev->touchPoints().size() == 3) {
+ d->state = QSwipeGesturePrivate::ThreePointsReached;
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
QTouchEvent::TouchPoint p3 = ev->touchPoints().at(2);
@@ -354,12 +372,18 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
} else if (ev->touchPoints().size() > 3) {
result = QGestureRecognizer::CancelGesture;
} else { // less than 3 touch points
- if (d->started && (ev->touchPointStates() & Qt::TouchPointPressed))
- result = QGestureRecognizer::CancelGesture;
- else if (d->started)
- result = QGestureRecognizer::Ignore;
- else
+ switch (d->state) {
+ case QSwipeGesturePrivate::NoGesture:
result = QGestureRecognizer::MayBeGesture;
+ break;
+ case QSwipeGesturePrivate::Started:
+ result = QGestureRecognizer::Ignore;
+ break;
+ case QSwipeGesturePrivate::ThreePointsReached:
+ result = (ev->touchPointStates() & Qt::TouchPointPressed)
+ ? QGestureRecognizer::CancelGesture : QGestureRecognizer::Ignore;
+ break;
+ }
}
break;
}
@@ -378,7 +402,7 @@ void QSwipeGestureRecognizer::reset(QGesture *state)
d->swipeAngle = 0;
d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint();
- d->started = false;
+ d->state = QSwipeGesturePrivate::NoGesture;
d->velocityValue = 0;
d->time.invalidate();
diff --git a/src/widgets/kernel/qstandardgestures_p.h b/src/widgets/kernel/qstandardgestures_p.h
index aeabd9cc7e..15ba31f26a 100644
--- a/src/widgets/kernel/qstandardgestures_p.h
+++ b/src/widgets/kernel/qstandardgestures_p.h
@@ -55,11 +55,14 @@ QT_BEGIN_NAMESPACE
class QPanGestureRecognizer : public QGestureRecognizer
{
public:
- QPanGestureRecognizer();
+ explicit QPanGestureRecognizer(int pointCount = 2) : m_pointCount(pointCount) {}
QGesture *create(QObject *target);
QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
void reset(QGesture *state);
+
+private:
+ const int m_pointCount;
};
class QPinchGestureRecognizer : public QGestureRecognizer
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 63497ce745..7f2e5a5e17 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1403,6 +1403,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
if (q->testAttribute(Qt::WA_ShowWithoutActivating))
win->setProperty("_q_showWithoutActivating", QVariant(true));
+ if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
+ win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true)));
win->setFlags(data.window_flags);
fixPosIncludesFrame();
if (q->testAttribute(Qt::WA_Moved)
@@ -7151,10 +7153,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
}
}
- // generate a move event for QWidgets without window handles. QWidgets with native
- // window handles already receive a move event from
- // QGuiApplicationPrivate::processGeometryChangeEvent.
- if (isMove && (!q->windowHandle() || q->testAttribute(Qt::WA_DontShowOnScreen))) {
+ if (isMove) {
QMoveEvent e(q->pos(), oldPos);
QApplication::sendEvent(q, &e);
}
@@ -10510,8 +10509,9 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
QWidget *parentWithWindow =
newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
if (parentWithWindow) {
- if (f & Qt::Window) {
- q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
+ QWidget *topLevel = parentWithWindow->window();
+ if ((f & Qt::Window) && topLevel && topLevel->windowHandle()) {
+ q->windowHandle()->setTransientParent(topLevel->windowHandle());
q->windowHandle()->setParent(0);
} else {
q->windowHandle()->setTransientParent(0);
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 2f2db32852..38f02b2ed9 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -863,7 +863,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
QRect scrollRect = rect & clipRect();
bool overlapped = false;
- bool accelerateScroll = accelEnv && isOpaque
+ bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent)
&& !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft())));
if (!accelerateScroll) {
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 7b52638e28..de8f11e5ec 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -434,14 +434,19 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
QWindow *win = w->windowHandle();
if (!win)
win = w->nativeParentWidget()->windowHandle();
- if (win && win->geometry().contains(event->globalPos())) {
- // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
- const QPoint localPos = win->mapFromGlobal(event->globalPos());
- QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
- QCoreApplicationPrivate::setEventSpontaneous(e, true);
- QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
- e->setTimestamp(event->timestamp());
- QCoreApplication::postEvent(win, e);
+ if (win) {
+ const QRect globalGeometry = win->isTopLevel()
+ ? win->geometry()
+ : QRect(win->mapToGlobal(QPoint(0, 0)), win->size());
+ if (globalGeometry.contains(event->globalPos())) {
+ // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
+ const QPoint localPos = win->mapFromGlobal(event->globalPos());
+ QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
+ QCoreApplicationPrivate::setEventSpontaneous(e, true);
+ QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
+ e->setTimestamp(event->timestamp());
+ QCoreApplication::postEvent(win, e);
+ }
}
}
}
@@ -539,14 +544,36 @@ void QWidgetWindow::handleKeyEvent(QKeyEvent *event)
QGuiApplication::sendSpontaneousEvent(receiver, event);
}
-void QWidgetWindow::updateGeometry()
+bool QWidgetWindow::updateSize()
{
+ bool changed = false;
if (m_widget->testAttribute(Qt::WA_OutsideWSRange))
- return;
+ return changed;
+ if (m_widget->data->crect.size() != geometry().size()) {
+ changed = true;
+ m_widget->data->crect.setSize(geometry().size());
+ }
- const QMargins margins = frameMargins();
+ updateMargins();
+ return changed;
+}
+
+bool QWidgetWindow::updatePos()
+{
+ bool changed = false;
+ if (m_widget->testAttribute(Qt::WA_OutsideWSRange))
+ return changed;
+ if (m_widget->data->crect.topLeft() != geometry().topLeft()) {
+ changed = true;
+ m_widget->data->crect.moveTopLeft(geometry().topLeft());
+ }
+ updateMargins();
+ return changed;
+}
- m_widget->data->crect = geometry();
+void QWidgetWindow::updateMargins()
+{
+ const QMargins margins = frameMargins();
QTLWExtra *te = m_widget->d_func()->topData();
te->posIncludesFrame= false;
te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
@@ -605,24 +632,25 @@ void QWidgetWindow::updateNormalGeometry()
void QWidgetWindow::handleMoveEvent(QMoveEvent *event)
{
- updateGeometry();
- QGuiApplication::sendSpontaneousEvent(m_widget, event);
+ if (updatePos())
+ QGuiApplication::sendSpontaneousEvent(m_widget, event);
}
void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
{
QSize oldSize = m_widget->data->crect.size();
- updateGeometry();
- QGuiApplication::sendSpontaneousEvent(m_widget, event);
+ if (updateSize()) {
+ QGuiApplication::sendSpontaneousEvent(m_widget, event);
- if (m_widget->d_func()->paintOnScreen()) {
- QRegion updateRegion(geometry());
- if (m_widget->testAttribute(Qt::WA_StaticContents))
- updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
- m_widget->d_func()->syncBackingStore(updateRegion);
- } else {
- m_widget->d_func()->syncBackingStore();
+ if (m_widget->d_func()->paintOnScreen()) {
+ QRegion updateRegion(geometry());
+ if (m_widget->testAttribute(Qt::WA_StaticContents))
+ updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
+ m_widget->d_func()->syncBackingStore(updateRegion);
+ } else {
+ m_widget->d_func()->syncBackingStore();
+ }
}
}
diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index 7f12ae8e20..0632a5c364 100644
--- a/src/widgets/kernel/qwidgetwindow_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -108,7 +108,9 @@ private slots:
private:
void repaintWindow();
- void updateGeometry();
+ bool updateSize();
+ bool updatePos();
+ void updateMargins();
void updateNormalGeometry();
enum FocusWidgets {
diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp
index 38c7497ffa..5b4b346da9 100644
--- a/src/widgets/styles/qandroidstyle.cpp
+++ b/src/widgets/styles/qandroidstyle.cpp
@@ -38,7 +38,6 @@
#include <QFile>
#include <QFont>
#include <QApplication>
-#include <QTime>
#include <qdrawutil.h>
#include <QPixmapCache>
#include <QFileInfo>
@@ -55,105 +54,33 @@
QT_BEGIN_NAMESPACE
namespace {
- const int textStyle_bold = 1;
- const int textStyle_italic = 2;
-
- const int typeface_sans = 1;
- const int typeface_serif = 2;
- const int typeface_monospace = 3;
-
const quint32 NO_COLOR = 1;
const quint32 TRANSPARENT_COLOR = 0;
}
-static int fontType(const QString &androidControl)
-{
- if (androidControl == QLatin1String("textViewStyle"))
- return QPlatformTheme::SystemFont;
- else if (androidControl == QLatin1String("buttonStyle"))
- return QPlatformTheme::PushButtonFont;
- else if (androidControl == QLatin1String("checkboxStyle"))
- return QPlatformTheme::CheckBoxFont;
- else if (androidControl == QLatin1String("radioButtonStyle"))
- return QPlatformTheme::RadioButtonFont;
- else if (androidControl == QLatin1String("simple_list_item_single_choice"))
- return QPlatformTheme::ItemViewFont;
- else if (androidControl == QLatin1String("simple_spinner_dropdown_item"))
- return QPlatformTheme::ComboMenuItemFont;
- else if (androidControl == QLatin1String("spinnerStyle"))
- return QPlatformTheme::ComboLineEditFont;
- else if (androidControl == QLatin1String("simple_list_item"))
- return QPlatformTheme::ListViewFont;
- return -1;
-}
-
-static int paletteType(const QString &androidControl)
-{
- if (androidControl == QLatin1String("textViewStyle"))
- return QPlatformTheme::SystemPalette;
- else if (androidControl == QLatin1String("buttonStyle"))
- return QPlatformTheme::ButtonPalette;
- else if (androidControl == QLatin1String("checkboxStyle"))
- return QPlatformTheme::CheckBoxPalette;
- else if (androidControl == QLatin1String("radioButtonStyle"))
- return QPlatformTheme::RadioButtonPalette;
- else if (androidControl == QLatin1String("simple_list_item_single_choice"))
- return QPlatformTheme::ItemViewPalette;
- else if (androidControl == QLatin1String("editTextStyle"))
- return QPlatformTheme::TextLineEditPalette;
- else if (androidControl == QLatin1String("spinnerStyle"))
- return QPlatformTheme::ComboBoxPalette;
- return -1;
-}
-
QAndroidStyle::QAndroidStyle()
: QFusionStyle()
{
QPixmapCache::clear();
checkBoxControl = NULL;
- QString stylePath(QLatin1String(qgetenv("MINISTRO_ANDROID_STYLE_PATH")));
- const QLatin1Char slashChar('/');
- if (!stylePath.isEmpty() && !stylePath.endsWith(slashChar))
- stylePath += slashChar;
-
- QString androidTheme = QLatin1String(qgetenv("QT_ANDROID_THEME"));
- if (!androidTheme.isEmpty() && !androidTheme.endsWith(slashChar))
- androidTheme += slashChar;
-
- if (stylePath.isEmpty()) {
- stylePath = QLatin1String("/data/data/org.kde.necessitas.ministro/files/dl/style/")
- + QLatin1String(qgetenv("QT_ANDROID_THEME_DISPLAY_DPI")) + slashChar;
- }
- Q_ASSERT(!stylePath.isEmpty());
-
- if (!androidTheme.isEmpty() && QFileInfo(stylePath + androidTheme + QLatin1String("style.json")).exists())
- stylePath += androidTheme;
-
- QFile f(stylePath + QLatin1String("style.json"));
- if (!f.open(QIODevice::ReadOnly))
- return;
-
- QJsonParseError error;
- QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error);
- if (document.isNull()) {
- qCritical() << error.errorString();
- return;
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ QPalette *standardPalette = reinterpret_cast<QPalette *>(nativeInterface->nativeResourceForIntegration("AndroidStandardPalette"));
+ if (standardPalette)
+ m_standardPalette = *standardPalette;
+
+ QHash<QByteArray, QFont> *qwidgetsFonts = reinterpret_cast<QHash<QByteArray, QFont> *>(nativeInterface->nativeResourceForIntegration("AndroidQWidgetFonts"));
+ if (qwidgetsFonts) {
+ for (auto it = qwidgetsFonts->constBegin(); it != qwidgetsFonts->constEnd(); ++it)
+ QApplication::setFont(it.value(), it.key());
+ qwidgetsFonts->clear(); // free the memory
}
- if (!document.isObject()) {
- qCritical() << "Style.json does not contain a valid style.";
+ QJsonObject *object = reinterpret_cast<QJsonObject *>(nativeInterface->nativeResourceForIntegration("AndroidStyleData"));
+ if (!object)
return;
- }
- QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
-
- QHash<int, QPalette> *palettes = reinterpret_cast<QHash<int, QPalette> *>(nativeInterface->nativeResourceForIntegration("AndroidStylePalettes"));
- QHash<int, QFont> *fonts = reinterpret_cast<QHash<int, QFont> *>(nativeInterface->nativeResourceForIntegration("AndroidStyleFonts"));
- palettes->clear();
- fonts->clear();
- QJsonObject object = document.object();
- for (QJsonObject::const_iterator objectIterator = object.constBegin();
- objectIterator != object.constEnd();
+ for (QJsonObject::const_iterator objectIterator = object->constBegin();
+ objectIterator != object->constEnd();
++objectIterator) {
QString key = objectIterator.key();
QJsonValue value = objectIterator.value();
@@ -163,85 +90,6 @@ QAndroidStyle::QAndroidStyle()
}
QJsonObject item = value.toObject();
- QJsonObject::const_iterator attributeIterator = item.find(QLatin1String("qtClass"));
- QString qtClassName;
- if (attributeIterator != item.constEnd()) {
- // The item has palette and font information for a specific Qt Class (e.g. QWidget, QPushButton, etc.)
- qtClassName = attributeIterator.value().toString();
- }
- const int ft = fontType(key);
- if (ft > -1 || !qtClassName.isEmpty()) {
- // Extract font information
- QFont font;
-
- // Font size (in pixels)
- attributeIterator = item.find(QLatin1String("TextAppearance_textSize"));
- if (attributeIterator != item.constEnd())
- font.setPixelSize(int(attributeIterator.value().toDouble()));
-
- // Font style
- attributeIterator = item.find(QLatin1String("TextAppearance_textStyle"));
- if (attributeIterator != item.constEnd()) {
- const int style = int(attributeIterator.value().toDouble());
- font.setBold(style & textStyle_bold);
- font.setItalic(style & textStyle_italic);
- }
-
- // Font typeface
- attributeIterator = item.find(QLatin1String("TextAppearance_typeface"));
- if (attributeIterator != item.constEnd()) {
- QFont::StyleHint styleHint = QFont::AnyStyle;
- switch (int(attributeIterator.value().toDouble())) {
- case typeface_sans:
- styleHint = QFont::SansSerif;
- break;
- case typeface_serif:
- styleHint = QFont::Serif;
- break;
- case typeface_monospace:
- styleHint = QFont::Monospace;
- break;
- }
- font.setStyleHint(styleHint, QFont::PreferMatch);
- }
- if (!qtClassName.isEmpty())
- QApplication::setFont(font, qtClassName.toUtf8());
- if (ft > -1)
- fonts->insert(ft, font);
- // Extract font information
- }
-
- const int pt = paletteType(key);
- if (pt > -1 || !qtClassName.isEmpty()) {
- // Extract palette information
- QPalette palette;
- attributeIterator = item.find(QLatin1String("defaultTextColorPrimary"));
- if (attributeIterator != item.constEnd())
- palette.setColor(QPalette::WindowText, QRgb(int(attributeIterator.value().toDouble())));
-
- attributeIterator = item.find(QLatin1String("defaultBackgroundColor"));
- if (attributeIterator != item.constEnd())
- palette.setColor(QPalette::Background, QRgb(int(attributeIterator.value().toDouble())));
-
- attributeIterator = item.find(QLatin1String("TextAppearance_textColor"));
- if (attributeIterator != item.constEnd())
- setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::WindowText);
-
- attributeIterator = item.find(QLatin1String("TextAppearance_textColorLink"));
- if (attributeIterator != item.constEnd())
- setPaletteColor(attributeIterator.value().toObject().toVariantMap(), palette, QPalette::Link);
-
- attributeIterator = item.find(QLatin1String("TextAppearance_textColorHighlight"));
- if (attributeIterator != item.constEnd())
- palette.setColor(QPalette::Highlight, QRgb(int(attributeIterator.value().toDouble())));
-
- if (QLatin1String("QWidget") == qtClassName)
- m_standardPalette = palette;
-
- if (pt > -1)
- palettes->insert(pt, palette);
- // Extract palette information
- }
QAndroidStyle::ItemType itemType = qtControl(key);
if (QC_UnknownType == itemType)
continue;
@@ -277,6 +125,7 @@ QAndroidStyle::QAndroidStyle()
break;
}
}
+ *object = QJsonObject(); // free memory
}
QAndroidStyle::~QAndroidStyle()
@@ -284,81 +133,6 @@ QAndroidStyle::~QAndroidStyle()
qDeleteAll(m_androidControlsHash);
}
-
-void QAndroidStyle::setPaletteColor(const QVariantMap &object,
- QPalette &palette,
- QPalette::ColorRole role)
-{
- // QPalette::Active -> ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
- palette.setColor(QPalette::Active,
- role,
- QRgb(object.value(QLatin1String("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt()));
-
- // QPalette::Inactive -> ENABLED_STATE_SET
- palette.setColor(QPalette::Inactive,
- role,
- QRgb(object.value(QLatin1String("ENABLED_STATE_SET")).toInt()));
-
- // QPalette::Disabled -> EMPTY_STATE_SET
- palette.setColor(QPalette::Disabled,
- role,
- QRgb(object.value(QLatin1String("EMPTY_STATE_SET")).toInt()));
-
- palette.setColor(QPalette::Current, role, palette.color(QPalette::Active, role));
-
- if (role == QPalette::WindowText) {
- // QPalette::BrightText -> PRESSED
- // QPalette::Active -> PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET
- palette.setColor(QPalette::Active,
- QPalette::BrightText,
- QRgb(object.value(QLatin1String("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET")).toInt()));
-
- // QPalette::Inactive -> PRESSED_ENABLED_STATE_SET
- palette.setColor(QPalette::Inactive,
- QPalette::BrightText,
- QRgb(object.value(QLatin1String("PRESSED_ENABLED_STATE_SET")).toInt()));
-
- // QPalette::Disabled -> PRESSED_STATE_SET
- palette.setColor(QPalette::Disabled,
- QPalette::BrightText,
- QRgb(object.value(QLatin1String("PRESSED_STATE_SET")).toInt()));
-
- palette.setColor(QPalette::Current, QPalette::BrightText, palette.color(QPalette::Active, QPalette::BrightText));
-
- // QPalette::HighlightedText -> SELECTED
- // QPalette::Active -> ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET
- palette.setColor(QPalette::Active,
- QPalette::HighlightedText,
- QRgb(object.value(QLatin1String("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET")).toInt()));
-
- // QPalette::Inactive -> ENABLED_SELECTED_STATE_SET
- palette.setColor(QPalette::Inactive,
- QPalette::HighlightedText,
- QRgb(object.value(QLatin1String("ENABLED_SELECTED_STATE_SET")).toInt()));
-
- // QPalette::Disabled -> SELECTED_STATE_SET
- palette.setColor(QPalette::Disabled,
- QPalette::HighlightedText,
- QRgb(object.value(QLatin1String("SELECTED_STATE_SET")).toInt()));
-
- palette.setColor(QPalette::Current,
- QPalette::HighlightedText,
- palette.color(QPalette::Active, QPalette::HighlightedText));
-
- // Same colors for Text
- palette.setColor(QPalette::Active, QPalette::Text, palette.color(QPalette::Active, role));
- palette.setColor(QPalette::Inactive, QPalette::Text, palette.color(QPalette::Inactive, role));
- palette.setColor(QPalette::Disabled, QPalette::Text, palette.color(QPalette::Disabled, role));
- palette.setColor(QPalette::Current, QPalette::Text, palette.color(QPalette::Current, role));
-
- // And for ButtonText
- palette.setColor(QPalette::Active, QPalette::ButtonText, palette.color(QPalette::Active, role));
- palette.setColor(QPalette::Inactive, QPalette::ButtonText, palette.color(QPalette::Inactive, role));
- palette.setColor(QPalette::Disabled, QPalette::ButtonText, palette.color(QPalette::Disabled, role));
- palette.setColor(QPalette::Current, QPalette::ButtonText, palette.color(QPalette::Current, role));
- }
-}
-
QAndroidStyle::ItemType QAndroidStyle::qtControl(const QString &android)
{
if (android == QLatin1String("buttonStyle"))
@@ -470,6 +244,10 @@ QAndroidStyle::ItemType QAndroidStyle::qtControl(QStyle::PrimitiveElement primit
case QStyle::PE_FrameLineEdit:
return QC_EditText;
+ case QStyle::PE_IndicatorViewItemCheck:
+ case QStyle::PE_IndicatorCheckBox:
+ return QC_Checkbox;
+
case QStyle::PE_FrameWindow:
case QStyle::PE_Widget:
case QStyle::PE_Frame:
@@ -583,37 +361,8 @@ void QAndroidStyle::drawControl(QStyle::ControlElement element,
}
break;
default:
- break;
- }
- } else if (element == CE_ItemViewItem) {
- const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
- if (vopt && vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
- p->save();
- p->setClipRect(opt->rect);
-
- QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, w);
-
- // draw the background
- proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, w);
-
- // draw the check mark
- QStyleOptionViewItem option(*vopt);
- option.rect = checkRect;
- option.state = option.state & ~QStyle::State_HasFocus;
-
- switch (vopt->checkState) {
- case Qt::Unchecked:
- option.state |= QStyle::State_Off;
- break;
- default:
- option.state |= QStyle::State_On;
- break;
- }
- QPixmap pixmap = checkBoxControl->imgCheckBox(&option);
- p->drawPixmap(checkRect, pixmap);
- p->restore();
- } else {
QFusionStyle::drawControl(element, opt, p, w);
+ break;
}
} else {
QFusionStyle::drawControl(element, opt, p, w);
@@ -758,7 +507,7 @@ QRect QAndroidStyle::subControlRect(ComplexControl cc,
case CC_GroupBox: {
if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
- QSize checkBoxSize = checkBoxControl->sizeCheckBox(opt);
+ QSize checkBoxSize = checkBoxControl->size(opt);
int indicatorWidth = checkBoxSize.width();
int indicatorHeight = checkBoxSize.height();
QRect checkBoxRect;
@@ -815,9 +564,9 @@ int QAndroidStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_ScrollBarExtent:
return 0;
case PM_IndicatorWidth:
- return checkBoxControl->sizeCheckBox(option).width();
+ return checkBoxControl->size(option).width();
case PM_IndicatorHeight:
- return checkBoxControl->sizeCheckBox(option).height();
+ return checkBoxControl->size(option).height();
default:
return QFusionStyle::pixelMetric(metric, option, widget);
}
@@ -834,7 +583,7 @@ QSize QAndroidStyle::sizeFromContents(ContentsType ct,
if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
bool nullIcon = hdr->icon.isNull();
int margin = pixelMetric(QStyle::PM_HeaderMargin, hdr, w);
- int iconSize = nullIcon ? 0 : checkBoxControl->sizeCheckBox(opt).width();
+ int iconSize = nullIcon ? 0 : checkBoxControl->size(opt).width();
QSize txt;
/*
* These next 4 lines are a bad hack to fix a bug in case a QStyleSheet is applied at QApplication level.
@@ -868,7 +617,7 @@ QSize QAndroidStyle::sizeFromContents(ContentsType ct,
if (ct == CT_GroupBox) {
if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
QSize textSize = opt->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
- QSize checkBoxSize = checkBoxControl->sizeCheckBox(opt);
+ QSize checkBoxSize = checkBoxControl->size(opt);
int indicatorWidth = checkBoxSize.width();
int indicatorHeight = checkBoxSize.height();
QRect checkBoxRect;
@@ -964,13 +713,6 @@ QSize QAndroidStyle::AndroidDrawable::size() const
return QSize();
}
-QPixmap QAndroidStyle::AndroidDrawable::img() const
-{
- if (type() == Image || type() == NinePatch)
- return static_cast<const QAndroidStyle::AndroidImageDrawable *>(this)->img();
-
- return QPixmap();
-}
QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidDrawable::fromMap(const QVariantMap &drawable,
ItemType itemType)
@@ -1036,19 +778,7 @@ void QAndroidStyle::AndroidImageDrawable::draw(QPainter *painter, const QStyleOp
QPixmapCache::insert(m_hashKey, pm);
}
- painter->drawPixmap(opt->rect.x(), (opt->rect.height() - pm.height()) / 2, pm);
-}
-QPixmap QAndroidStyle::AndroidImageDrawable::img() const
-{
- if (m_hashKey.isEmpty())
- m_hashKey = QFileInfo(m_filePath).fileName();
-
- QPixmap pm;
- if (!QPixmapCache::find(m_hashKey, &pm)) {
- pm.load(m_filePath);
- QPixmapCache::insert(m_hashKey, pm);
- }
- return pm;
+ painter->drawPixmap(opt->rect.x(), opt->rect.y() + (opt->rect.height() - pm.height()) / 2, pm);
}
QSize QAndroidStyle::AndroidImageDrawable::size() const
@@ -1446,14 +1176,6 @@ QSize QAndroidStyle::AndroidStateDrawable::sizeImage(const QStyleOption *opt) co
s = drawable->size();
return s;
}
-QPixmap QAndroidStyle::AndroidStateDrawable::img(const QStyleOption *opt) const
-{
- QPixmap pm;
- const AndroidDrawable *drawable = bestAndroidStateMatch(opt);
- if (drawable)
- pm = drawable->img();
- return pm;
-}
const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::bestAndroidStateMatch(const QStyleOption *opt) const
{
@@ -1733,7 +1455,6 @@ QRect QAndroidStyle::AndroidControl::subElementRect(QStyle::SubElement /* subEle
return visualRect(option->direction, option->rect, r);
}
return option->rect;
-
}
QRect QAndroidStyle::AndroidControl::subControlRect(const QStyleOptionComplex *option,
@@ -1778,6 +1499,16 @@ QMargins QAndroidStyle::AndroidControl::padding()
return QMargins();
}
+QSize QAndroidStyle::AndroidControl::size(const QStyleOption *option)
+{
+ if (const AndroidDrawable *drawable = backgroundDrawable()) {
+ if (drawable->type() == State)
+ drawable = static_cast<const AndroidStateDrawable *>(backgroundDrawable())->bestAndroidStateMatch(option);
+ return drawable->size();
+ }
+ return QSize();
+}
+
const QAndroidStyle::AndroidDrawable *QAndroidStyle::AndroidControl::backgroundDrawable() const
{
return m_background;
@@ -1788,11 +1519,12 @@ QAndroidStyle::AndroidCompoundButtonControl::AndroidCompoundButtonControl(const
: AndroidControl(control, itemType)
{
QVariantMap::const_iterator it = control.find(QLatin1String("CompoundButton_button"));
- if (it != control.end())
+ if (it != control.end()) {
m_button = AndroidDrawable::fromMap(it.value().toMap(), itemType);
- else
+ const_cast<AndroidDrawable *>(m_button)->setPaddingLeftToSizeWidth();
+ } else {
m_button = 0;
- const_cast<AndroidDrawable *>(m_button)->setPaddingLeftToSizeWidth();
+ }
}
QAndroidStyle::AndroidCompoundButtonControl::~AndroidCompoundButtonControl()
@@ -1808,16 +1540,24 @@ void QAndroidStyle::AndroidCompoundButtonControl::drawControl(const QStyleOption
if (m_button)
m_button->draw(p, opt);
}
-QSize QAndroidStyle::AndroidCompoundButtonControl::sizeCheckBox(const QStyleOption *opt) const
+
+QMargins QAndroidStyle::AndroidCompoundButtonControl::padding()
{
- const AndroidDrawable *drawable = m_button;
- return static_cast<const QAndroidStyle::AndroidStateDrawable *>(drawable)->sizeImage(opt);
+ if (m_button)
+ return m_button->padding();
+ return AndroidControl::padding();
}
-QPixmap QAndroidStyle::AndroidCompoundButtonControl::imgCheckBox(const QStyleOption *opt) const
+
+QSize QAndroidStyle::AndroidCompoundButtonControl::size(const QStyleOption *option)
{
- const AndroidDrawable *drawable = m_button;
- return static_cast<const QAndroidStyle::AndroidStateDrawable *>(drawable)->img(opt);
+ if (m_button) {
+ if (m_button->type() == State)
+ return static_cast<const AndroidStateDrawable *>(m_button)->bestAndroidStateMatch(option)->size();
+ return m_button->size();
+ }
+ return AndroidControl::size(option);
}
+
const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidCompoundButtonControl::backgroundDrawable() const
{
return m_background ? m_background : m_button;
@@ -1908,7 +1648,6 @@ QRect QAndroidStyle::AndroidProgressBarControl::subElementRect(QStyle::SubElemen
p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
padding = m_progressDrawable->padding();
p |= QRect(padding.left(), padding.top(), padding.right() - padding.left(), padding.bottom() - padding.top());
-
QRect r = option->rect.adjusted(p.left(), p.top(), -p.right(), -p.bottom());
if (horizontal) {
@@ -1991,15 +1730,15 @@ void QAndroidStyle::AndroidSeekBarControl::drawControl(const QStyleOption *optio
if (drawable->type() == State)
drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
QStyleOption copy(*option);
- copy.rect.setY((copy.rect.height() - m_minSize.height()) / 2);
- copy.rect.setHeight(m_minSize.height());
+ copy.rect.setHeight(m_progressDrawable->size().height());
copy.rect.setWidth(copy.rect.width() - drawable->size().width());
- copy.rect.translate(drawable->size().width() / 2, 0);
+ const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
+ copy.rect.translate(drawable->size().width() / 2, yTranslate);
m_progressDrawable->draw(p, &copy);
if (styleOption->orientation == Qt::Vertical)
qCritical() << "Vertical slider are not supported";
- int pos = copy.rect.width()*factor - drawable->size().width() / 2;
- copy.rect.translate(pos, 0);
+ int pos = copy.rect.width() * factor - drawable->size().width() / 2;
+ copy.rect.translate(pos, -yTranslate);
copy.rect.setSize(drawable->size());
m_seekBarThumb->draw(p, &copy);
}
diff --git a/src/widgets/styles/qandroidstyle_p.h b/src/widgets/styles/qandroidstyle_p.h
index 65fa4cd096..d8e7768380 100644
--- a/src/widgets/styles/qandroidstyle_p.h
+++ b/src/widgets/styles/qandroidstyle_p.h
@@ -124,7 +124,6 @@ public:
static AndroidDrawable *fromMap(const QVariantMap &drawable, ItemType itemType);
static QMargins extractMargins(const QVariantMap &value);
virtual void setPaddingLeftToSizeWidth();
- QPixmap img() const;
protected:
ItemType m_itemType;
QMargins m_padding;
@@ -149,7 +148,6 @@ public:
virtual void draw(QPainter *painter,const QStyleOption *opt) const;
virtual QSize size() const;
- QPixmap img() const;
protected:
QString m_filePath;
mutable QString m_hashKey;
@@ -223,7 +221,6 @@ public:
static int extractState(const QVariantMap &value);
virtual void setPaddingLeftToSizeWidth();
QSize sizeImage(const QStyleOption *opt) const;
- QPixmap img(const QStyleOption *opt) const;
private:
typedef QPair<int, const AndroidDrawable *> StateType;
QList<StateType> m_states;
@@ -263,6 +260,7 @@ public:
const QSize &contentsSize,
const QWidget *w) const;
virtual QMargins padding();
+ virtual QSize size(const QStyleOption *option);
protected:
virtual const AndroidDrawable * backgroundDrawable() const;
const AndroidDrawable *m_background;
@@ -276,8 +274,8 @@ public:
AndroidCompoundButtonControl(const QVariantMap &control, ItemType itemType);
virtual ~AndroidCompoundButtonControl();
virtual void drawControl(const QStyleOption *opt, QPainter *p, const QWidget *w);
- QSize sizeCheckBox(const QStyleOption *opt) const;
- QPixmap imgCheckBox(const QStyleOption *opt) const;
+ virtual QMargins padding();
+ virtual QSize size(const QStyleOption *option);
protected:
virtual const AndroidDrawable * backgroundDrawable() const;
const AndroidDrawable *m_button;
@@ -376,9 +374,6 @@ private:
static ItemType qtControl(QStyle::SubElement subElement);
static ItemType qtControl(const QString &android);
- static void setPaletteColor(const QVariantMap &object,
- QPalette &palette,
- QPalette::ColorRole role);
private:
typedef QHash<int, AndroidControl *> AndroidControlsHash;
AndroidControlsHash m_androidControlsHash;
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 815b10c921..7e9a631c5e 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -1114,7 +1114,7 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget
(opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
(opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off );
// High-dpi icons do not need adjustmet; make sure tabIconSize is not larger than iconSize
- tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.width()));
+ tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height()));
*iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
tabIconSize.width(), tabIconSize .height());
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index ef3795c9a1..817f16b297 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -553,7 +553,9 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor);
} else if (header->sortIndicator & QStyleOptionHeader::SortDown) {
arrow = colorizedImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_arrow.png"), arrowColor, 180);
- } if (!arrow.isNull()) {
+ }
+
+ if (!arrow.isNull()) {
r.setSize(QSize(arrow.width()/2, arrow.height()/2));
r.moveCenter(header->rect.center());
painter->drawPixmap(r.translated(offset), arrow);
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index 06ee74bdfe..61d1cd796e 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -701,10 +701,12 @@ GtkWidget* QGtkStylePrivate::getTextColorWidget() const
void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget)
{
if (Q_GTK_IS_WIDGET(widget)) {
- static GtkWidget* protoLayout = 0;
+ GtkWidget *protoLayout = gtkWidgetMap()->value("GtkContainer");
if (!protoLayout) {
protoLayout = QGtkStylePrivate::gtk_fixed_new();
QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value("GtkWindow")), protoLayout);
+ QHashableLatin1Literal widgetPath = QHashableLatin1Literal::fromData(strdup("GtkContainer"));
+ gtkWidgetMap()->insert(widgetPath, protoLayout);
}
Q_ASSERT(protoLayout);
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index fb0bafa66d..328378cb8e 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -296,14 +296,12 @@ void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt, bool isUnified)
p->fillRect(rect, QColor(Qt::transparent));
p->restore();
} else if (active) {
- int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
- p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
+ p->fillRect(rect, QColor(167, 167, 167));
} else {
- int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 9 : 0;
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
- gradient.setColorAt(0, QColor(207 + d, 207 + d, 207 + d));
- gradient.setColorAt(0.5, QColor(206 + d, 206 + d, 206 + d));
- gradient.setColorAt(1, QColor(201 + d, 201 + d, 201 + d));
+ gradient.setColorAt(0, QColor(216, 216, 216));
+ gradient.setColorAt(0.5, QColor(215, 215, 215));
+ gradient.setColorAt(1, QColor(210, 210, 210));
p->fillRect(rect, gradient);
}
@@ -881,13 +879,6 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg
gbi.size = sz == QAquaSizeSmall ? kHIThemeGrowBoxSizeSmall : kHIThemeGrowBoxSizeNormal;
if (HIThemeGetGrowBoxBounds(&p, &gbi, &r) == noErr) {
int width = 0;
- // Snow Leopard and older get a size grip, as well as QMdiSubWindows.
- if (QSysInfo::MacintoshVersion <= QSysInfo::MV_10_6
-#ifndef QT_NO_MDIAREA
- || (widg && widg->parentWidget() && qobject_cast<QMdiSubWindow *>(widg->parentWidget()))
-#endif
- )
- width = r.size.width;
ret = QSize(width, r.size.height);
}
}
@@ -1830,7 +1821,7 @@ static QCocoaWidget cocoaWidgetFromHIThemeButtonKind(ThemeButtonKind kind)
return w;
}
-NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) const
+NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const
{
NSView *bv = cocoaControls[widget];
if (!bv) {
@@ -1903,37 +1894,39 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) cons
const_cast<QMacStylePrivate *>(this)->cocoaControls.insert(widget, bv);
}
- if (offset) {
- if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeLarge))
- offset->setY(2);
- else if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeSmall))
- *offset = QPoint(-1, 2);
- else if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeMini))
- offset->setY(2);
- else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeSmall)
- || widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeLarge))
- offset->setY(1);
- else if (widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeSmall))
- offset->setX(-1);
- else if (widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeMini))
- *offset = QPoint(7, 5);
- else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeMini))
- *offset = QPoint(2, -1);
- else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeLarge))
- *offset = QPoint(3, -1);
- else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeSmall))
- *offset = QPoint(2, 1);
- else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeMini))
- *offset = QPoint(5, 0);
- }
-
return bv;
}
-void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPainter *p, QCocoaDrawRectBlock drawRectBlock) const
+void QMacStylePrivate::drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &qtRect, QPainter *p, bool isQWidget, QCocoaDrawRectBlock drawRectBlock) const
{
+ QPoint offset;
+ if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeLarge))
+ offset.setY(2);
+ else if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeSmall))
+ offset = QPoint(-1, 2);
+ else if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeMini))
+ offset.setY(2);
+ else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeSmall)
+ || widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeLarge))
+ offset.setY(1);
+ else if (widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeSmall))
+ offset.setX(-1);
+ else if (widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeMini))
+ offset = QPoint(7, 5);
+ else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeMini))
+ offset = QPoint(2, -1);
+ else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeLarge))
+ offset = isQWidget ? QPoint(3, -1) : QPoint(-1, -3);
+ else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeSmall))
+ offset = QPoint(2, 1);
+ else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeMini))
+ offset = QPoint(5, 0);
+ else if (widget == QCocoaWidget(QCocoaComboBox, QAquaSizeLarge))
+ offset = QPoint(3, 0);
+
QMacCGContext ctx(p);
CGContextSaveGState(ctx);
+ CGContextTranslateCTM(ctx, offset.x(), offset.y());
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext
@@ -2046,8 +2039,8 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
}
pm = QPixmap::fromImage(image);
} else if ((usingYosemiteOrLater && combo && !editableCombo) || button) {
- QPoint offset;
- NSButton *bc = (NSButton *)cocoaControl(cocoaWidgetFromHIThemeButtonKind(bdi->kind), &offset);
+ QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi->kind);
+ NSButton *bc = (NSButton *)cocoaControl(cw);
[bc highlight:pressed];
bc.enabled = bdi->state != kThemeStateUnavailable && bdi->state != kThemeStateUnavailableInactive;
bc.allowsMixedState = YES;
@@ -2057,9 +2050,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
QRect rect = opt->rect;
if (bdi->kind == kThemePopupButtonMini)
rect.adjust(0, 0, -5, 0);
- p->translate(offset);
- drawNSViewInRect(bc, rect, p);
- p->translate(-offset);
+ drawNSViewInRect(cw, bc, rect, p);
return;
} else if (usingYosemiteOrLater && editableCombo) {
QImage image = activePixmap.toImage();
@@ -2131,34 +2122,26 @@ QMacStyle::QMacStyle()
: QCommonStyle(*new QMacStylePrivate)
{
Q_D(QMacStyle);
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- d->receiver = [[NotificationReceiver alloc] initWithPrivate:d];
- NotificationReceiver *receiver = static_cast<NotificationReceiver *>(d->receiver);
+ d->receiver = [[NotificationReceiver alloc] initWithPrivate:d];
+ NotificationReceiver *receiver = static_cast<NotificationReceiver *>(d->receiver);
- [[NSNotificationCenter defaultCenter] addObserver:receiver
- selector:@selector(scrollBarStyleDidChange:)
- name:NSPreferredScrollerStyleDidChangeNotification
- object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:receiver
+ selector:@selector(scrollBarStyleDidChange:)
+ name:NSPreferredScrollerStyleDidChangeNotification
+ object:nil];
- d->nsscroller = [[NSScroller alloc] init];
- }
-#endif
+ d->nsscroller = [[NSScroller alloc] init];
d->indicatorBranchButtonCell = nil;
}
QMacStyle::~QMacStyle()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
Q_D(QMacStyle);
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- [reinterpret_cast<NSScroller*>(d->nsscroller) release];
+ [reinterpret_cast<NSScroller*>(d->nsscroller) release];
- NotificationReceiver *receiver = static_cast<NotificationReceiver *>(d->receiver);
- [[NSNotificationCenter defaultCenter] removeObserver:receiver];
- [receiver release];
- }
-#endif
+ NotificationReceiver *receiver = static_cast<NotificationReceiver *>(d->receiver);
+ [[NSNotificationCenter defaultCenter] removeObserver:receiver];
+ [receiver release];
delete qt_mac_backgroundPattern;
qt_mac_backgroundPattern = 0;
@@ -2256,7 +2239,7 @@ void QMacStyle::polish(QWidget* w)
}
if (qobject_cast<QMenu*>(w) || qobject_cast<QComboBoxPrivateContainer *>(w)) {
- w->setWindowOpacity(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 ? 0.985 : 0.94);
+ w->setWindowOpacity(0.985);
if (!w->testAttribute(Qt::WA_SetPalette)) {
QPixmap px(64, 64);
px.fill(Qt::white);
@@ -2541,9 +2524,7 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
}
break;
case PM_ScrollBarExtent: {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 &&
- [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay) {
+ if ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay) {
switch (d->aquaSizeConstrain(opt, widget)) {
case QAquaSizeUnknown:
case QAquaSizeLarge:
@@ -2556,7 +2537,6 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
}
break;
}
-#endif
switch (d->aquaSizeConstrain(opt, widget)) {
case QAquaSizeUnknown:
case QAquaSizeLarge:
@@ -2747,13 +2727,8 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
ret = 1;
break;
case PM_ScrollView_ScrollBarOverlap:
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- ret = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 &&
- [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay) ?
+ ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay ?
pixelMetric(PM_ScrollBarExtent, opt, widget) : 0;
-#else
- ret = 0;
-#endif
break;
default:
ret = QCommonStyle::pixelMetric(metric, opt, widget);
@@ -3083,11 +3058,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
|| (opt && QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ScrollBar))
#endif
) {
- ret = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (ret)
- ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay;
-#endif
+ ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay;
}
break;
default:
@@ -3795,9 +3766,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
alignment |= Qt::TextHideMnemonic;
if (down)
cr.translate(shiftX, shiftY);
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5
- && (tbstyle == Qt::ToolButtonTextOnly
- || (tbstyle != Qt::ToolButtonTextOnly && !down))) {
+ if (tbstyle == Qt::ToolButtonTextOnly
+ || (tbstyle != Qt::ToolButtonTextOnly && !down)) {
QPen pen = p->pen();
QColor light = down ? Qt::black : Qt::white;
light.setAlphaF(0.375f);
@@ -3812,12 +3782,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
proxy()->drawItemText(p, cr, alignment, pal,
tb->state & State_Enabled, tb->text, role);
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 &&
- (tb->state & State_Sunken)) {
- // Draw a "drop shadow" in earlier versions.
- proxy()->drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment,
- tb->palette, tb->state & State_Enabled, tb->text);
- }
}
} else {
QCommonStyle::drawControl(ce, &myTb, p, w);
@@ -3938,17 +3902,15 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
if (hasMenu && yosemiteOrLater && bdi.kind != kThemeBevelButton) {
- QCocoaWidget w = cocoaWidgetFromHIThemeButtonKind(bdi.kind);
- QPoint offset;
- NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(QCocoaWidget(QCocoaPullDownButton, w.second), &offset);
+ QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind);
+ cw.first = QCocoaPullDownButton;
+ NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(cw);
[pdb highlight:(bdi.state == kThemeStatePressed)];
pdb.enabled = bdi.state != kThemeStateUnavailable && bdi.state != kThemeStateUnavailableInactive;
QRect rect = opt->rect;
- rect.adjust(0, 0, w.second == QAquaSizeSmall ? -4 : w.second == QAquaSizeMini ? -9 : -6, 0);
- p->translate(offset);
- d->drawNSViewInRect(pdb, rect, p);
- p->translate(-offset);
- } else if (hasMenu && bdi.state == kThemeStatePressed && QSysInfo::macVersion() > QSysInfo::MV_10_6)
+ rect.adjust(0, 0, cw.second == QAquaSizeSmall ? -4 : cw.second == QAquaSizeMini ? -9 : -6, 0);
+ d->drawNSViewInRect(cw, pdb, rect, p, w != 0);
+ } else if (hasMenu && bdi.state == kThemeStatePressed)
d->drawColorlessButton(newRect, &bdi, p, opt);
else
HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
@@ -3987,16 +3949,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (hasMenu && (!yosemiteOrLater || bdi.kind == kThemeBevelButton)) {
int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
QRect ir = btn->rect;
- int arrowXOffset = 0;
- if (QSysInfo::macVersion() > QSysInfo::MV_10_6)
- arrowXOffset = bdi.kind == kThemePushButton ? 6 :
+ int arrowXOffset = bdi.kind == kThemePushButton ? 6 :
bdi.kind == kThemePushButtonSmall ? 7 : 8;
- int arrowYOffset;
- if (QSysInfo::macVersion() > QSysInfo::MV_10_6)
- arrowYOffset = bdi.kind == kThemePushButton ? 3 :
+ int arrowYOffset = bdi.kind == kThemePushButton ? 3 :
bdi.kind == kThemePushButtonSmall ? 1 : 2;
- else
- arrowYOffset = bdi.kind == kThemePushButton ? 4 : 2;
if (!w) {
// adjustment for Qt Quick Controls
arrowYOffset -= ir.top();
@@ -4012,17 +3968,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
pdi.version = qt_mac_hitheme_version;
pdi.state = tds == kThemeStateInactive ? kThemeStateActive : tds;
pdi.orientation = kThemeArrowDown;
- if (QSysInfo::macVersion() > QSysInfo::MV_10_6) {
- if (bdi.kind == kThemePushButtonMini)
- pdi.size = kThemeArrow5pt;
- else if (bdi.kind == kThemePushButton || bdi.kind == kThemePushButtonSmall)
- pdi.size = kThemeArrow7pt;
- } else {
- if (arrowRect.size.width < 8.)
- pdi.size = kThemeArrow5pt;
- else
- pdi.size = kThemeArrow9pt;
- }
+ if (bdi.kind == kThemePushButtonMini)
+ pdi.size = kThemeArrow5pt;
+ else if (bdi.kind == kThemePushButton || bdi.kind == kThemePushButtonSmall)
+ pdi.size = kThemeArrow7pt;
HIThemeDrawPopupArrow(&arrowRect, &pdi, cg, kHIThemeOrientationNormal);
}
}
@@ -4101,10 +4050,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
QRect textRect = itemTextRect(
btn.fontMetrics, freeContentRect, Qt::AlignCenter, btn.state & State_Enabled, btn.text);
if (hasMenu) {
- if (QSysInfo::macVersion() > QSysInfo::MV_10_6)
- textRect.moveTo(w ? 15 : 11, textRect.top()); // Supports Qt Quick Controls
- else
- textRect.adjust(-1, 0, -1, 0);
+ textRect.moveTo(w ? 15 : 11, textRect.top()); // Supports Qt Quick Controls
}
// Draw the icon:
if (hasIcon) {
@@ -4145,9 +4091,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
QStyleOptionComboBox comboCopy = *cb;
comboCopy.direction = Qt::LeftToRight;
- if ((opt->state & QStyle::State_Small) && QSysInfo::macVersion() > QSysInfo::MV_10_6)
- comboCopy.rect.translate(0, w ? (QSysInfo::macVersion() > QSysInfo::MV_10_8 ? 0 : -1) : -2); // Supports Qt Quick Controls
- else if (QSysInfo::macVersion() > QSysInfo::MV_10_8)
+ if (opt->state & QStyle::State_Small)
+ comboCopy.rect.translate(0, w ? (QSysInfo::macVersion() > QSysInfo::MV_10_8 ? 0 : -1) :
+ (QSysInfo::macVersion() > QSysInfo::MV_10_9 ? 0 : -2)); // Supports Qt Quick Controls
+ else if (QSysInfo::macVersion() == QSysInfo::MV_10_9)
comboCopy.rect.translate(0, 1);
QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
}
@@ -4284,10 +4231,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
ThemeTabDirection ttd = getTabDirection(myTab.shape);
bool verticalTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
bool selected = (myTab.state & QStyle::State_Selected);
- bool usingLionOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_6;
bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
- if (usingLionOrLater && selected && !myTab.documentMode
+ if (selected && !myTab.documentMode
&& (!usingYosemiteOrLater || myTab.state & State_Active))
myTab.palette.setColor(QPalette::WindowText, Qt::white);
@@ -4296,7 +4242,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
// outside world, unless they read the source, in which case, it's
// their own fault).
bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem");
- bool isSelectedAndNeedsShadow = selected && usingLionOrLater && !usingYosemiteOrLater;
+ bool isSelectedAndNeedsShadow = selected && !usingYosemiteOrLater;
if (isSelectedAndNeedsShadow || verticalTabs || nonDefaultFont || !tab->icon.isNull()
|| !myTab.leftButtonSize.isEmpty() || !myTab.rightButtonSize.isEmpty()) {
int heightOffset = 0;
@@ -4768,14 +4714,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
case CE_ProgressBarGroove:
break;
case CE_SizeGrip: {
- // We do not draw size grips on versions > 10.6 unless it's a QMdiSubWindow
- if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_6
-#ifndef QT_NO_MDIAREA
- && !(w && w->parentWidget() && qobject_cast<QMdiSubWindow *>(w->parentWidget()))
-#endif
- )
- break;
-
if (w && w->testAttribute(Qt::WA_MacOpaqueSizeGrip)) {
HIThemeGrowBoxDrawInfo gdi;
gdi.version = qt_mac_hitheme_version;
@@ -5444,7 +5382,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
const bool isHorizontal = slider->orientation == Qt::Horizontal;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (cc == CC_ScrollBar && proxy()->styleHint(SH_ScrollBar_Transient, opt, widget)) {
bool wasActive = false;
CGFloat opacity = 0.0;
@@ -5607,9 +5544,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
[NSGraphicsContext restoreGraphicsState];
CGContextRestoreGState(cg);
- } else
-#endif
- {
+ } else {
d->stopAnimation(opt->styleObject);
if (usingYosemiteOrLater && cc == CC_Slider) {
@@ -5641,12 +5576,13 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
// Yosemite demands its blue progress track when no tickmarks are present
if (!(slider->subControls & SC_SliderTickmarks)) {
QCocoaWidgetKind sliderKind = slider->orientation == Qt::Horizontal ? QCocoaHorizontalSlider : QCocoaVerticalSlider;
- NSSlider *sl = (NSSlider *)d->cocoaControl(QCocoaWidget(sliderKind, QAquaSizeLarge), 0);
+ QCocoaWidget cw = QCocoaWidget(sliderKind, QAquaSizeLarge);
+ NSSlider *sl = (NSSlider *)d->cocoaControl(cw);
sl.minValue = slider->minimum;
sl.maxValue = slider->maximum;
sl.intValue = slider->sliderValue;
sl.enabled = slider->state & QStyle::State_Enabled;
- d->drawNSViewInRect(sl, opt->rect, p, ^(NSRect rect, CGContextRef ctx) {
+ d->drawNSViewInRect(cw, sl, opt->rect, p, widget != 0, ^(NSRect rect, CGContextRef ctx) {
if (slider->upsideDown) {
if (isHorizontal) {
CGContextTranslateCTM(ctx, rect.size.width, 0);
@@ -5819,12 +5755,21 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
break;
case CC_ComboBox:
if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
+ const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
HIThemeButtonDrawInfo bdi;
- d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
+ d->initComboboxBdi(combo, &bdi, widget, tds);
+ HIRect rect = qt_hirectForQRect(combo->rect);
+ if (combo->editable && usingYosemiteOrLater)
+ rect.origin.y += tds == kThemeStateInactive ? 1 : 2;
if (tds != kThemeStateInactive)
- QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
- else
- d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
+ QMacStylePrivate::drawCombobox(rect, bdi, p);
+ else if (!widget && combo->editable && usingYosemiteOrLater) {
+ QCocoaWidget cw = cocoaWidgetFromHIThemeButtonKind(bdi.kind);
+ NSView *cb = d->cocoaControl(cw);
+ QRect r = combo->rect.adjusted(3, 0, 0, 0);
+ d->drawNSViewInRect(cw, cb, r, p, widget != 0);
+ } else
+ d->drawColorlessButton(rect, &bdi, p, opt);
}
break;
case CC_TitleBar:
@@ -5880,11 +5825,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
uint sc = SC_TitleBarMinButton;
ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox;
bool active = titlebar->state & State_Active;
- if (QSysInfo::macVersion() < QSysInfo::MV_10_6) {
- int border = 2;
- titleBarRect.origin.x += border;
- titleBarRect.origin.y -= border;
- }
while (sc <= SC_TitleBarCloseButton) {
if (sc & titlebar->subControls) {
@@ -6023,23 +5963,12 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4);
p->setRenderHint(QPainter::Antialiasing);
p->fillPath(path, brush);
- } else if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ } else {
static QPixmap pm(QLatin1String(":/qt-project.org/mac/style/images/leopard-unified-toolbar-on.png"));
p->save();
p->setRenderHint(QPainter::SmoothPixmapTransform);
QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);
p->restore();
- } else {
- QPen oldPen = p->pen();
- p->setPen(QColor(0, 0, 0, 0x3a));
- p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
- p->drawLine(tb->rect.left() + 1, tb->rect.top(),
- tb->rect.right() - 1, tb->rect.top());
- p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
- tb->rect.right() - 1, tb->rect.bottom());
- p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
- p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
- p->setPen(oldPen);
}
}
proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget);
@@ -6192,10 +6121,7 @@ QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc,
HIRect macSBRect = qt_hirectForQRect(sb->rect);
ControlPartCode part;
bool reverseHorizontal = (sb->direction == Qt::RightToLeft
- && sb->orientation == Qt::Horizontal
- && (!sb->upsideDown ||
- (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4
- && sb->upsideDown)));
+ && sb->orientation == Qt::Horizontal);
if (HIThemeHitTestScrollBarArrows(&macSBRect, &sbi, sb->orientation == Qt::Horizontal,
&pos, 0, &part)) {
if (part == kControlUpButtonPart)
@@ -6381,6 +6307,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
switch (sc) {
case SC_ComboBoxEditField:{
ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_9)
+ ret.setHeight(ret.height() - 1);
break; }
case SC_ComboBoxArrow:{
ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
@@ -6822,10 +6750,13 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz.rwidth() += 10;
sz.rheight() += 10;
return sz;
- case CT_ComboBox:
+ case CT_ComboBox: {
sz.rwidth() += 50;
- sz.rheight() += 2;
+ const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt);
+ if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_10 || (cb && !cb->editable))
+ sz.rheight() += 2;
break;
+ }
case CT_Menu: {
QStyleHintReturnMask menuMask;
QStyleOption myOption = *opt;
diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h
index 080f944ef8..89a95713b7 100644
--- a/src/widgets/styles/qmacstyle_mac_p_p.h
+++ b/src/widgets/styles/qmacstyle_mac_p_p.h
@@ -204,9 +204,9 @@ public:
void setAutoDefaultButton(QObject *button) const;
- NSView *cocoaControl(QCocoaWidget widget, QPoint *offset) const;
+ NSView *cocoaControl(QCocoaWidget widget) const;
- void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p, QCocoaDrawRectBlock drawRectBlock = nil) const;
+ void drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &rect, QPainter *p, bool isQWidget = true, QCocoaDrawRectBlock drawRectBlock = nil) const;
void resolveCurrentNSView(QWindow *window);
public:
@@ -222,10 +222,8 @@ public:
mutable QPointer<QFocusFrame> focusWidget;
CFAbsoluteTime defaultButtonStart;
bool mouseDown;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
void* receiver;
void *nsscroller;
-#endif
void *indicatorBranchButtonCell;
NSView *backingStoreNSView;
QHash<QCocoaWidget, NSView *> cocoaControls;
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 7c4d239894..109a0ea451 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1772,8 +1772,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_ComboBox_Popup Allows popups as a combobox drop-down
menu.
- \omitvalue SH_ComboBox_UseNativePopup Whether we should use a native popup.
- Only supported for non-editable combo boxes on Mac OS X so far.
+ \omitvalue SH_ComboBox_UseNativePopup
\value SH_Workspace_FillSpaceOnMaximize The workspace should
maximize the client area.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 12ada3f6e4..fa15a0d4c4 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -698,6 +698,8 @@ public:
SH_ToolTip_FallAsleepDelay,
SH_Widget_Animate,
SH_Splitter_OpaqueResize,
+ // Whether we should use a native popup.
+ // Only supported for non-editable combo boxes on Mac OS X so far.
SH_ComboBox_UseNativePopup,
SH_LineEdit_PasswordMaskDelay,
SH_TabBar_ChangeCurrentDelay,
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 3619c3ff29..9deeb725f9 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -1832,6 +1832,20 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
}
return;
#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ if (cb->state & State_HasFocus) {
+ p->setPen(cb->palette.highlightedText().color());
+ p->setBackground(cb->palette.highlight());
+ } else {
+ p->setPen(cb->palette.text().color());
+ p->setBackground(cb->palette.background());
+ }
+ }
+ QCommonStyle::drawControl(ce, opt, p, widget);
+ break;
+#endif // QT_NO_COMBOBOX
default:
QCommonStyle::drawControl(ce, opt, p, widget);
}
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index 007952192a..463b120e04 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -1473,7 +1473,11 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
break;
}
#endif // QT_NO_ITEMVIEWS
-
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ QCommonStyle::drawControl(element, option, painter, widget);
+ break;
+#endif // QT_NO_COMBOBOX
default:
QWindowsXPStyle::drawControl(element, option, painter, widget);
break;
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index c18bbb3431..c1f7b599b3 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -963,7 +963,8 @@ void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
QImage img;
if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
- buffer(w, h); // Ensure a buffer of at least (w, h) in size
+ if (!buffer(w, h)) // Ensure a buffer of at least (w, h) in size
+ return;
HDC dc = bufferHDC();
// Clear the buffer
@@ -2539,7 +2540,7 @@ QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, const
const int hSpace = theme->rect.width() - size.width();
const int vSpace = theme->rect.height() - size.height();
- const bool sufficientSpace = horizontal && hSpace > (contentsMargin.left() + contentsMargin.right())
+ const bool sufficientSpace = (horizontal && hSpace > (contentsMargin.left() + contentsMargin.right()))
|| vSpace > contentsMargin.top() + contentsMargin.bottom();
return sufficientSpace ? QRect(theme->rect.topLeft() + QPoint(hSpace, vSpace) / 2, size) : QRect();
}
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 815afe85f2..3db7781acc 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1520,13 +1520,16 @@ void QLineEdit::mouseMoveEvent(QMouseEvent * e)
#else
const bool select = (d->imHints & Qt::ImhNoPredictiveText);
#endif
+#ifndef QT_NO_IM
if (d->control->composeMode() && select) {
int startPos = d->xToPos(d->mousePressPos.x());
int currentPos = d->xToPos(e->pos().x());
if (startPos != currentPos)
d->control->setSelection(startPos, currentPos - startPos);
- } else {
+ } else
+#endif
+ {
d->control->moveCursor(d->xToPos(e->pos().x()), select);
}
}
@@ -1577,6 +1580,7 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
int position = d->xToPos(e->pos().x());
// exit composition mode
+#ifndef QT_NO_IM
if (d->control->composeMode()) {
int preeditPos = d->control->cursor();
int posInPreedit = position - d->control->cursor();
@@ -1601,6 +1605,7 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
position += (sizeChange - preeditLength);
}
}
+#endif
if (position >= 0)
d->control->selectWordAtPos(position);
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 0731c89094..f1126322d8 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -47,8 +47,8 @@
#ifndef QT_NO_IM
#include "qinputmethod.h"
#include "qlist.h"
-#include <qpropertyanimation.h>
#endif
+#include <qpropertyanimation.h>
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index f9376a78d5..ddecea81bf 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1500,6 +1500,13 @@ bool QMainWindow::event(QEvent *event)
/*!
\property QMainWindow::unifiedTitleAndToolBarOnMac
\brief whether the window uses the unified title and toolbar look on Mac OS X
+
+ Note that the Qt 5 implementation has several limitations compared to Qt 4:
+ \list
+ \li Use in windows with OpenGL content is not supported. This includes QGLWidget and QOpenGLWidget.
+ \li Using dockable or movable toolbars may result in painting errors and is not recommended
+ \endlist
+
\since 5.2
*/
void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 43f168ecd8..8f8642a72a 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -68,7 +68,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_DOCKWIDGET
+#ifdef QT_NO_DOCKWIDGET
extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
#endif
@@ -615,11 +615,8 @@ static QList<T> findChildrenHelper(const QObject *o)
}
//pre4.3 tests the format that was used before 4.3
-bool QMainWindowLayoutState::checkFormat(QDataStream &stream, bool pre43)
+bool QMainWindowLayoutState::checkFormat(QDataStream &stream)
{
-#ifdef QT_NO_TOOLBAR
- Q_UNUSED(pre43);
-#endif
while (!stream.atEnd()) {
uchar marker;
stream >> marker;
@@ -630,8 +627,7 @@ bool QMainWindowLayoutState::checkFormat(QDataStream &stream, bool pre43)
case QToolBarAreaLayout::ToolBarStateMarkerEx:
{
QList<QToolBar *> toolBars = findChildrenHelper<QToolBar*>(mainWindow);
- if (!toolBarAreaLayout.restoreState(stream, toolBars, marker,
- pre43 /*testing 4.3 format*/, true /*testing*/)) {
+ if (!toolBarAreaLayout.restoreState(stream, toolBars, marker, true /*testing*/)) {
return false;
}
}
@@ -672,14 +668,8 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
}
QDataStream ds(copy);
- const bool oldFormat = !checkFormat(ds, false);
- if (oldFormat) {
- //we should try with the old format
- QDataStream ds2(copy);
- if (!checkFormat(ds2, true)) {
- return false; //format unknown
- }
- }
+ if (!checkFormat(ds))
+ return false;
QDataStream stream(copy);
@@ -719,7 +709,7 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream,
case QToolBarAreaLayout::ToolBarStateMarkerEx:
{
QList<QToolBar *> toolBars = findChildrenHelper<QToolBar*>(mainWindow);
- if (!toolBarAreaLayout.restoreState(stream, toolBars, marker, oldFormat))
+ if (!toolBarAreaLayout.restoreState(stream, toolBars, marker))
return false;
for (int i = 0; i < toolBars.size(); ++i) {
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index abec34af14..d9e18b03f4 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -133,7 +133,7 @@ public:
QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0);
void saveState(QDataStream &stream) const;
- bool checkFormat(QDataStream &stream, bool pre43);
+ bool checkFormat(QDataStream &stream);
bool restoreState(QDataStream &stream, const QMainWindowLayoutState &oldState);
};
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 1e291f469e..3553baf68a 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -1511,7 +1511,7 @@ void QMdiAreaPrivate::highlightNextSubWindow(int increaseFactor)
#ifndef QT_NO_RUBBERBAND
if (!rubberBand) {
- rubberBand = new QRubberBand(QRubberBand::Rectangle, viewport);
+ rubberBand = new QRubberBand(QRubberBand::Rectangle, q);
// For accessibility to identify this special widget.
rubberBand->setObjectName(QLatin1String("qt_rubberband"));
rubberBand->setWindowFlags(rubberBand->windowFlags() | Qt::WindowStaysOnTopHint);
@@ -1528,6 +1528,20 @@ void QMdiAreaPrivate::highlightNextSubWindow(int increaseFactor)
Q_ASSERT(indexToHighlighted >= 0);
}
+void QMdiAreaPrivate::showRubberBandFor(QMdiSubWindow *subWindow)
+{
+ if (!subWindow || !rubberBand)
+ return;
+
+ if (viewMode == QMdiArea::TabbedView)
+ rubberBand->setGeometry(tabBar->tabRect(childWindows.indexOf(subWindow)));
+ else
+ rubberBand->setGeometry(subWindow->geometry());
+
+ rubberBand->raise();
+ rubberBand->show();
+}
+
/*!
\internal
\since 4.4
diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h
index 1092fd9a30..ba531adaad 100644
--- a/src/widgets/widgets/qmdiarea_p.h
+++ b/src/widgets/widgets/qmdiarea_p.h
@@ -248,14 +248,7 @@ public:
}
#ifndef QT_NO_RUBBERBAND
- inline void showRubberBandFor(QMdiSubWindow *subWindow)
- {
- if (!subWindow || !rubberBand)
- return;
- rubberBand->setGeometry(subWindow->geometry());
- rubberBand->raise();
- rubberBand->show();
- }
+ void showRubberBandFor(QMdiSubWindow *subWindow);
inline void hideRubberBand()
{
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index a4c22de15b..2c27344a4a 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -3189,8 +3189,10 @@ void QMenu::actionEvent(QActionEvent *e)
delete menuItem;
} else if (e->type() == QEvent::ActionChanged) {
QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action()));
- copyActionToPlatformItem(e->action(), menuItem);
- d->platformMenu->syncMenuItem(menuItem);
+ if (menuItem) {
+ copyActionToPlatformItem(e->action(), menuItem);
+ d->platformMenu->syncMenuItem(menuItem);
+ }
}
d->platformMenu->syncSeparatorsCollapsible(d->collapsibleSeparators);
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index b6a21f183a..72a556db7c 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -2042,11 +2042,13 @@ void QPlainTextEdit::mouseMoveEvent(QMouseEvent *e)
d->sendControlEvent(e);
if (!(e->buttons() & Qt::LeftButton))
return;
- QRect visible = d->viewport->rect();
- if (visible.contains(pos))
- d->autoScrollTimer.stop();
- else if (!d->autoScrollTimer.isActive())
- d->autoScrollTimer.start(100, this);
+ if (e->source() == Qt::MouseEventNotSynthesized) {
+ const QRect visible = d->viewport->rect();
+ if (visible.contains(pos))
+ d->autoScrollTimer.stop();
+ else if (!d->autoScrollTimer.isActive())
+ d->autoScrollTimer.start(100, this);
+ }
}
/*! \reimp
@@ -2055,7 +2057,7 @@ void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e)
{
Q_D(QPlainTextEdit);
d->sendControlEvent(e);
- if (d->autoScrollTimer.isActive()) {
+ if (e->source() == Qt::MouseEventNotSynthesized && d->autoScrollTimer.isActive()) {
d->autoScrollTimer.stop();
d->ensureCursorVisible();
}
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 2d95009eb3..7ef864139f 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1574,11 +1574,13 @@ void QTextEdit::mouseMoveEvent(QMouseEvent *e)
d->sendControlEvent(e);
if (!(e->buttons() & Qt::LeftButton))
return;
- QRect visible = d->viewport->rect();
- if (visible.contains(pos))
- d->autoScrollTimer.stop();
- else if (!d->autoScrollTimer.isActive())
- d->autoScrollTimer.start(100, this);
+ if (e->source() == Qt::MouseEventNotSynthesized) {
+ const QRect visible = d->viewport->rect();
+ if (visible.contains(pos))
+ d->autoScrollTimer.stop();
+ else if (!d->autoScrollTimer.isActive())
+ d->autoScrollTimer.start(100, this);
+ }
}
/*! \reimp
@@ -1587,7 +1589,7 @@ void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
{
Q_D(QTextEdit);
d->sendControlEvent(e);
- if (d->autoScrollTimer.isActive()) {
+ if (e->source() == Qt::MouseEventNotSynthesized && d->autoScrollTimer.isActive()) {
d->autoScrollTimer.stop();
ensureCursorVisible();
}
diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index 5494d49232..1dd39174ac 100644
--- a/src/widgets/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
@@ -1286,21 +1286,15 @@ void QToolBarAreaLayout::saveState(QDataStream &stream) const
}
}
-static inline int getInt(QDataStream &stream, Qt::Orientation o, bool pre43)
+static inline int getInt(QDataStream &stream)
{
- if (pre43) {
- QPoint p;
- stream >> p;
- return pick(o, p);
- } else {
- int x;
- stream >> x;
- return x;
- }
+ int x;
+ stream >> x;
+ return x;
}
-bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*> &_toolBars, uchar tmarker, bool pre43, bool testing)
+bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*> &_toolBars, uchar tmarker, bool testing)
{
QList<QToolBar*> toolBars = _toolBars;
int lines;
@@ -1325,8 +1319,8 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
stream >> objectName;
uchar shown;
stream >> shown;
- item.pos = getInt(stream, dock.o, pre43);
- item.size = getInt(stream, dock.o, pre43);
+ item.pos = getInt(stream);
+ item.size = getInt(stream);
/*
4.3.0 added floating toolbars, but failed to add the ability to restore them.
@@ -1339,9 +1333,9 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar*
QRect rect;
bool floating = false;
uint geom0, geom1;
- geom0 = getInt(stream, dock.o, pre43);
+ geom0 = getInt(stream);
if (tmarker == ToolBarStateMarkerEx) {
- geom1 = getInt(stream, dock.o, pre43);
+ geom1 = getInt(stream);
rect = unpackRect(geom0, geom1, &floating);
}
diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h
index 63a0924bcb..ad377876b4 100644
--- a/src/widgets/widgets/qtoolbararealayout_p.h
+++ b/src/widgets/widgets/qtoolbararealayout_p.h
@@ -230,7 +230,7 @@ public:
QLayoutItem *unplug(const QList<int> &path, QToolBarAreaLayout *other);
void saveState(QDataStream &stream) const;
- bool restoreState(QDataStream &stream, const QList<QToolBar*> &toolBars, uchar tmarker, bool pre43, bool testing = false);
+ bool restoreState(QDataStream &stream, const QList<QToolBar*> &toolBars, uchar tmarker, bool testing = false);
bool isEmpty() const;
};
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index a82dd99591..e6385ba390 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -179,6 +179,7 @@ void QWidgetLineControl::paste(QClipboard::Mode clipboardMode)
*/
void QWidgetLineControl::commitPreedit()
{
+#ifndef QT_NO_IM
if (!composeMode())
return;
@@ -190,6 +191,7 @@ void QWidgetLineControl::commitPreedit()
setPreeditArea(-1, QString());
m_textLayout.clearAdditionalFormats();
updateDisplayText(/*force*/ true);
+#endif
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index 328faf7926..f21d88177c 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -228,8 +228,10 @@ public:
}
void setText(const QString &txt)
{
+#ifndef QT_NO_IM
if (composeMode())
qApp->inputMethod()->reset();
+#endif
internalSetText(txt, -1, false);
}
void commitPreedit();
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 954cae345f..93835156da 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1582,8 +1582,10 @@ void QWidgetTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton butto
cursor.clearSelection();
}
}
+ // Do not start selection on a mouse event synthesized from a touch event.
if (!(button & Qt::LeftButton) ||
- !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
+ !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))
+ || QApplicationPrivate::mouseEventSource(e) != Qt::MouseEventNotSynthesized) {
e->ignore();
return;
}
@@ -1754,6 +1756,11 @@ void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton but
{
Q_Q(QWidgetTextControl);
+ if (QApplicationPrivate::mouseEventSource(e) != Qt::MouseEventNotSynthesized) {
+ setCursorPosition(pos); // Emulate Tap to set cursor for events synthesized from touch.
+ return;
+ }
+
const QTextCursor oldSelection = cursor;
if (sendMouseEventToInputContext(
e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) {
diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
index 4e3d5c64bc..df2f97ce0e 100644
--- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
+++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
@@ -1996,6 +1996,10 @@ void tst_QTextCodec::codecForHtml_data()
"auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: "
"none;\">&#x37b</span>\000";
QTest::newRow("greek text UTF-8") << html << 106 << 106;
+
+ html = "<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=unicode\">"
+ "<head/><body><p>bla</p></body></html>"; // QTBUG-41998, ICU will return UTF-16.
+ QTest::newRow("legacy unicode UTF-8") << html << 106 << 106;
}
void tst_QTextCodec::codecForHtml()
diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
index 35bd518b3a..0a55da5b7e 100644
--- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
+++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
@@ -886,25 +886,25 @@ void tst_qmessagehandler::formatLogMessage_data()
#define BA QByteArrayLiteral
QTest::newRow("basic") << "%{type} %{file} %{line} %{function} %{message}"
- << "debug main.cpp 1 func msg\n"
+ << "debug main.cpp 1 func msg"
<< QtDebugMsg << BA("main.cpp") << 1 << BA("func") << BA("") << "msg";
// test the if conditions
QString format = "[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}";
QTest::newRow("if-debug")
- << format << "[D] msg\n"
+ << format << "[D] msg"
<< QtDebugMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
QTest::newRow("if_warning")
- << format << "[W] msg\n"
+ << format << "[W] msg"
<< QtWarningMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
QTest::newRow("if_critical")
- << format << "[C] msg\n"
+ << format << "[C] msg"
<< QtCriticalMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
QTest::newRow("if_fatal")
- << format << "[F] msg\n"
+ << format << "[F] msg"
<< QtFatalMsg << BA("") << 0 << BA("func") << QByteArray() << "msg";
QTest::newRow("if_cat")
- << format << "[F] cat: msg\n"
+ << format << "[F] cat: msg"
<< QtFatalMsg << BA("") << 0 << BA("func") << BA("cat") << "msg";
}
diff --git a/tests/auto/corelib/io/qsettings/bom.ini b/tests/auto/corelib/io/qsettings/bom.ini
new file mode 100644
index 0000000000..8d46ee8d91
--- /dev/null
+++ b/tests/auto/corelib/io/qsettings/bom.ini
@@ -0,0 +1,4 @@
+[section1]
+foo1=bar1
+[section2]
+foo2=bar2
diff --git a/tests/auto/corelib/io/qsettings/qsettings.qrc b/tests/auto/corelib/io/qsettings/qsettings.qrc
index 587c22ebe3..c0be7e013f 100644
--- a/tests/auto/corelib/io/qsettings/qsettings.qrc
+++ b/tests/auto/corelib/io/qsettings/qsettings.qrc
@@ -1,9 +1,10 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>resourcefile.ini</file>
- <file>resourcefile2.ini</file>
- <file>resourcefile3.ini</file>
- <file>resourcefile4.ini</file>
- <file>resourcefile5.ini</file>
-</qresource>
+<RCC>
+ <qresource prefix="/">
+ <file>resourcefile.ini</file>
+ <file>resourcefile2.ini</file>
+ <file>resourcefile3.ini</file>
+ <file>resourcefile4.ini</file>
+ <file>resourcefile5.ini</file>
+ <file>bom.ini</file>
+ </qresource>
</RCC>
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index 3e68e4859f..c89923f159 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -161,6 +161,7 @@ private slots:
void testByteArray_data();
void testByteArray();
void iniCodec();
+ void bom();
private:
const bool m_canWriteNativeSystemSettings;
@@ -730,6 +731,15 @@ void tst_QSettings::iniCodec()
}
+void tst_QSettings::bom()
+{
+ QSettings s(":/bom.ini", QSettings::IniFormat);
+ QStringList allkeys = s.allKeys();
+ QCOMPARE(allkeys.size(), 2);
+ QVERIFY(allkeys.contains("section1/foo1"));
+ QVERIFY(allkeys.contains("section2/foo2"));
+}
+
void tst_QSettings::testErrorHandling_data()
{
QTest::addColumn<int>("filePerms"); // -1 means file should not exist
diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
index e07dda250f..3abbb71960 100644
--- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
+++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
@@ -154,6 +154,11 @@ void tst_QStorageInfo::tempFile()
QVERIFY(file.open());
QStorageInfo storage1(file.fileName());
+#ifdef Q_OS_LINUX
+ if (storage1.fileSystemType() == "btrfs")
+ QSKIP("This test doesn't work on btrfs, probably due to a btrfs bug");
+#endif
+
qint64 free = storage1.bytesFree();
file.write(QByteArray(1024*1024, '1'));
@@ -170,6 +175,11 @@ void tst_QStorageInfo::caching()
QVERIFY(file.open());
QStorageInfo storage1(file.fileName());
+#ifdef Q_OS_LINUX
+ if (storage1.fileSystemType() == "btrfs")
+ QSKIP("This test doesn't work on btrfs, probably due to a btrfs bug");
+#endif
+
qint64 free = storage1.bytesFree();
QStorageInfo storage2(storage1);
QVERIFY(free == storage2.bytesFree());
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index 5b5161e24a..6d801f75c1 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -1179,6 +1179,12 @@ void tst_QUrl::toLocalFile_data()
QTest::newRow("data0") << QString::fromLatin1("file:/a.txt") << QString::fromLatin1("/a.txt");
QTest::newRow("data4") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
+ QTest::newRow("data4a") << QString::fromLatin1("webdavs://somewebdavhost/somedir/somefile")
+#ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only.
+ << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile");
+#else
+ << QString();
+#endif
#ifdef Q_OS_WIN
QTest::newRow("data5") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("c:/a.txt");
#else
@@ -1227,6 +1233,9 @@ void tst_QUrl::fromLocalFile_data()
QTest::newRow("data3") << QString::fromLatin1("c:/a.txt") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
QTest::newRow("data4") << QString::fromLatin1("//somehost/somedir/somefile") << QString::fromLatin1("file://somehost/somedir/somefile")
<< QString::fromLatin1("/somedir/somefile");
+ QTest::newRow("data4a") << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile")
+ << QString::fromLatin1("webdavs://somewebdavhost/somedir/somefile")
+ << QString::fromLatin1("/somedir/somefile");
QTest::newRow("data5") << QString::fromLatin1("//somehost") << QString::fromLatin1("file://somehost")
<< QString::fromLatin1("");
QTest::newRow("data6") << QString::fromLatin1("//somehost/") << QString::fromLatin1("file://somehost/")
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index ed84c111c6..d05ed6c20f 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -95,6 +95,7 @@ private slots:
void changeFilter();
void changeSourceData_data();
void changeSourceData();
+ void changeSourceDataKeepsStableSorting_qtbug1548();
void sortFilterRole();
void selectionFilteredOut();
void match_data();
@@ -143,6 +144,7 @@ private slots:
void noMapAfterSourceDelete();
void forwardDropApi();
+ void canDropMimeData();
protected:
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
@@ -2009,6 +2011,79 @@ void tst_QSortFilterProxyModel::changeSourceData()
}
}
+// Checks that the model is a table, and that each and every row is like this:
+// i-th row: ( rows.at(i), i )
+static void checkSortedTableModel(const QAbstractItemModel *model, const QStringList &rows)
+{
+ QCOMPARE(model->rowCount(), rows.length());
+ QCOMPARE(model->columnCount(), 2);
+
+ for (int row = 0; row < model->rowCount(); ++row) {
+ const QString column0 = model->index(row, 0).data().toString();
+ const int column1 = model->index(row, 1).data().toString().toInt();
+
+ QCOMPARE(column0, rows.at(row));
+ QCOMPARE(column1, row);
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548()
+{
+ // Check that emitting dataChanged from the source model
+ // for a change of a role which is not the sorting role
+ // doesn't alter the sorting. In this case, we sort on the DisplayRole,
+ // and play with other roles.
+
+ static const QStringList rows
+ = QStringList() << "a" << "b" << "b" << "b" << "c" << "c" << "x";
+
+ // Build a table of pairs (string, #row) in each row
+ QStandardItemModel model(0, 2);
+
+ for (int rowNumber = 0; rowNumber < rows.length(); ++rowNumber) {
+ QStandardItem *column0 = new QStandardItem(rows.at(rowNumber));
+ column0->setCheckable(true);
+ column0->setCheckState(Qt::Unchecked);
+
+ QStandardItem *column1 = new QStandardItem(QString::number(rowNumber));
+
+ const QList<QStandardItem *> row
+ = QList<QStandardItem *>() << column0 << column1;
+
+ model.appendRow(row);
+ }
+
+ checkSortedTableModel(&model, rows);
+
+ // Build the proxy model
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+
+ // The proxy is now sorted by the first column, check that the sorting
+ // * is correct (the input is already sorted, so it must not have changed)
+ // * was stable (by looking at the second column)
+ checkSortedTableModel(&model, rows);
+
+ // Change the check status of an item. That must not break the stable sorting
+ // changes the middle "b"
+ model.item(2)->setCheckState(Qt::Checked);
+ checkSortedTableModel(&model, rows);
+
+ // changes the starting "a"
+ model.item(0)->setCheckState(Qt::Checked);
+ checkSortedTableModel(&model, rows);
+
+ // change the background color of the first "c"
+ model.item(4)->setBackground(Qt::red);
+ checkSortedTableModel(&model, rows);
+
+ // change the background color of the second "c"
+ model.item(5)->setBackground(Qt::red);
+ checkSortedTableModel(&model, rows);
+}
+
void tst_QSortFilterProxyModel::sortFilterRole()
{
QStandardItemModel model;
@@ -3835,6 +3910,36 @@ void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
}
+// A source model with ABABAB rows, where only A rows accept drops.
+// It will then be sorted by a QSFPM.
+class DropOnOddRows : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ DropOnOddRows(QObject *parent = 0) : QAbstractListModel(parent) {}
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
+ {
+ if (role == Qt::DisplayRole)
+ return (index.row() % 2 == 0) ? "A" : "B";
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const
+ {
+ Q_UNUSED(parent);
+ return 10;
+ }
+
+ bool canDropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int column, const QModelIndex &parent) const Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(row);
+ Q_UNUSED(column);
+ return parent.row() % 2 == 0;
+ }
+};
+
class SourceAssertion : public QSortFilterProxyModel
{
Q_OBJECT
@@ -3899,5 +4004,30 @@ void tst_QSortFilterProxyModel::forwardDropApi()
QVERIFY(model.dropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
}
+static QString rowTexts(QAbstractItemModel *model) {
+ QString str;
+ for (int row = 0 ; row < model->rowCount(); ++row)
+ str += model->index(row, 0).data().toString();
+ return str;
+}
+
+void tst_QSortFilterProxyModel::canDropMimeData()
+{
+ // Given a source model which only supports dropping on even rows
+ DropOnOddRows sourceModel;
+ QCOMPARE(rowTexts(&sourceModel), QString("ABABABABAB"));
+
+ // and a proxy model that sorts the rows
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&sourceModel);
+ proxy.sort(0, Qt::AscendingOrder);
+ QCOMPARE(rowTexts(&proxy), QString("AAAAABBBBB"));
+
+ // the proxy should correctly map canDropMimeData to the source model,
+ // i.e. accept drops on the first 5 rows and refuse drops on the next 5.
+ for (int row = 0; row < proxy.rowCount(); ++row)
+ QCOMPARE(proxy.canDropMimeData(0, Qt::CopyAction, -1, -1, proxy.index(row, 0)), row < 5);
+}
+
QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
index 5cfbce0d7a..befd45018a 100644
--- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
+++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
@@ -40,6 +40,7 @@
#include <private/qeventloop_p.h>
#if defined(Q_OS_UNIX)
#include <private/qeventdispatcher_unix_p.h>
+ #include <QtCore/private/qcore_unix_p.h>
#if defined(HAVE_GLIB)
#include <private/qeventdispatcher_glib_p.h>
#endif
@@ -172,7 +173,9 @@ private slots:
void execAfterExit();
void wakeUp();
void quit();
+#if defined(Q_OS_UNIX)
void processEventsExcludeSocket();
+#endif
void processEventsExcludeTimers();
void deliverInDefinedOrder();
@@ -383,6 +386,7 @@ void tst_QEventLoop::customEvent(QEvent *e)
}
}
+#if defined(Q_OS_UNIX)
class SocketEventsTester: public QObject
{
Q_OBJECT
@@ -391,8 +395,10 @@ public:
{
socket = 0;
server = 0;
- dataArrived = false;
+ dataSent = false;
+ dataReadable = false;
testResult = false;
+ dataArrived = false;
}
~SocketEventsTester()
{
@@ -415,8 +421,10 @@ public:
QTcpSocket *socket;
QTcpServer *server;
- bool dataArrived;
+ bool dataSent;
+ bool dataReadable;
bool testResult;
+ bool dataArrived;
public slots:
void sendAck()
{
@@ -428,12 +436,26 @@ public slots:
qint64 size = sizeof(data);
QTcpSocket *serverSocket = server->nextPendingConnection();
+ QCoreApplication::processEvents();
serverSocket->write(data, size);
- serverSocket->flush();
- QTest::qSleep(200); //allow the TCP/IP stack time to loopback the data, so our socket is ready to read
- QCoreApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
- testResult = dataArrived;
- QCoreApplication::processEvents(); //check the deferred event is processed
+ dataSent = serverSocket->waitForBytesWritten(-1);
+
+ if (dataSent) {
+ fd_set fdread;
+ int fd = socket->socketDescriptor();
+ FD_ZERO(&fdread);
+ FD_SET(fd, &fdread);
+ dataReadable = (1 == qt_safe_select(fd + 1, &fdread, 0, 0, 0));
+ }
+
+ if (!dataReadable) {
+ testResult = dataArrived;
+ } else {
+ QCoreApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
+ testResult = dataArrived;
+ // to check if the deferred event is processed
+ QCoreApplication::processEvents();
+ }
serverSocket->close();
QThread::currentThread()->exit(0);
}
@@ -449,12 +471,16 @@ public:
SocketEventsTester *tester = new SocketEventsTester();
if (tester->init())
exec();
+ dataSent = tester->dataSent;
+ dataReadable = tester->dataReadable;
testResult = tester->testResult;
dataArrived = tester->dataArrived;
delete tester;
}
- bool testResult;
- bool dataArrived;
+ bool dataSent;
+ bool dataReadable;
+ bool testResult;
+ bool dataArrived;
};
void tst_QEventLoop::processEventsExcludeSocket()
@@ -462,9 +488,17 @@ void tst_QEventLoop::processEventsExcludeSocket()
SocketTestThread thread;
thread.start();
QVERIFY(thread.wait());
+ QVERIFY(thread.dataSent);
+ QVERIFY(thread.dataReadable);
+ #if defined(HAVE_GLIB)
+ QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
+ if (qobject_cast<QEventDispatcherGlib *>(eventDispatcher))
+ QEXPECT_FAIL("", "ExcludeSocketNotifiers is currently broken in the Glib dispatchers", Continue);
+ #endif
QVERIFY(!thread.testResult);
QVERIFY(thread.dataArrived);
}
+#endif
class TimerReceiver : public QObject
{
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
index 78c75b44e8..5833123dfe 100644
--- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
+++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
@@ -642,18 +642,25 @@ struct CountedStruct
QThread *thread;
};
-static QEventLoop _e;
+static QScopedPointer<QEventLoop> _e;
static QThread *_t = Q_NULLPTR;
class StaticEventLoop
{
public:
- static void quitEventLoop() { _e.quit(); if (_t) QCOMPARE(QThread::currentThread(), _t); }
+ static void quitEventLoop()
+ {
+ QVERIFY(!_e.isNull());
+ _e->quit();
+ if (_t)
+ QCOMPARE(QThread::currentThread(), _t);
+ }
};
void tst_QTimer::singleShotToFunctors()
{
int count = 0;
+ _e.reset(new QEventLoop);
QEventLoop e;
QTimer::singleShot(0, CountedStruct(&count));
@@ -661,7 +668,7 @@ void tst_QTimer::singleShotToFunctors()
QCOMPARE(count, 1);
QTimer::singleShot(0, &StaticEventLoop::quitEventLoop);
- QCOMPARE(_e.exec(), 0);
+ QCOMPARE(_e->exec(), 0);
QThread t1;
QObject c1;
@@ -687,7 +694,7 @@ void tst_QTimer::singleShotToFunctors()
QCOMPARE(e.exec(), 0);
QTimer::singleShot(0, &c2, &StaticEventLoop::quitEventLoop);
- QCOMPARE(_e.exec(), 0);
+ QCOMPARE(_e->exec(), 0);
_t->quit();
_t->wait();
@@ -721,8 +728,10 @@ void tst_QTimer::singleShotToFunctors()
thread.quit();
thread.wait();
#endif
-}
+ _e.reset();
+ _t = Q_NULLPTR;
+}
class DontBlockEvents : public QObject
{
diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro
index f8d054f70c..39178ba9e6 100644
--- a/tests/auto/corelib/kernel/qvariant/qvariant.pro
+++ b/tests/auto/corelib/kernel/qvariant/qvariant.pro
@@ -6,3 +6,4 @@ INCLUDEPATH += $$PWD/../../../other/qvariant_common
SOURCES = tst_qvariant.cpp
RESOURCES += qvariant.qrc
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
+contains(QT_CONFIG, c++11): CONFIG += c++11
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index eae6311854..301db37233 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -3840,11 +3840,10 @@ struct ContainerAPI<Container, QByteArray>
}
};
-// We have no built-in defines to check the stdlib features.
-// #define TEST_FORWARD_LIST
-
-#ifdef TEST_FORWARD_LIST
-#include <forward_list>
+#ifdef __has_include
+# if __has_include(<forward_list>)
+# define TEST_FORWARD_LIST
+# include <forward_list>
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(std::forward_list)
@@ -3898,7 +3897,8 @@ struct ContainerAPI<std::forward_list<QString> >
return variant == value;
}
};
-#endif
+# endif // __has_include(<forward_list>)
+#endif // __has_include
template<typename Container>
struct KeyGetter
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 57473021aa..e001440045 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -4447,6 +4447,28 @@ void tst_QString::section_data()
<< QString("o") << 1 << 2
<< int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
<< QString("o1o2o") << false;
+ QTest::newRow( "range1" ) << QString("o1o2o")
+ << QString("o") << -5 << -5
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << QString() << false;
+ QTest::newRow( "range2" ) << QString("oo1o2o")
+ << QString("o") << -5 << 1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
+ |QString::SectionSkipEmpty)
+ << QString("oo1o2o") << false;
+ QTest::newRow( "range3" ) << QString("o1o2o")
+ << QString("o") << 2 << 1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << QString() << false;
+ QTest::newRow( "range4" ) << QString("o1o2o")
+ << QString("o") << 4 << 4
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
+ << QString() << false;
+ QTest::newRow( "range5" ) << QString("o1oo2o")
+ << QString("o") << -2 << -1
+ << int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep
+ |QString::SectionSkipEmpty)
+ << QString("o1oo2o") << false;
QTest::newRow( "rx1" ) << QString("o1o2o")
<< QString("[a-z]") << 0 << 0
<< int(QString::SectionIncludeLeadingSep|QString::SectionIncludeTrailingSep)
diff --git a/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro b/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro
index 08ee0dd3d9..1e74d42bbd 100644
--- a/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro
+++ b/tests/auto/corelib/tools/qversionnumber/qversionnumber.pro
@@ -1,4 +1,4 @@
CONFIG += testcase parallel_test
TARGET = tst_qversionnumber
-QT = core testlib
+QT = core-private testlib
SOURCES = tst_qversionnumber.cpp
diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
index 18bc86620a..f97b8a4df8 100644
--- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
+++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp
@@ -33,7 +33,7 @@
****************************************************************************/
#include <QtTest/QtTest>
-#include <qversionnumber.h>
+#include <private/qversionnumber_p.h>
class tst_QVersionNumber : public QObject
{
diff --git a/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp b/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp
index 5263d431d0..b4c16c6fa3 100644
--- a/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp
+++ b/tests/auto/dbus/qdbusabstractadaptor/qmyserver/qmyserver.cpp
@@ -75,6 +75,11 @@ public slots:
return m_conn.isConnected();
}
+ Q_NOREPLY void requestSync(const QString &seq)
+ {
+ emit syncReceived(seq);
+ }
+
void emitSignal(const QString& interface, const QString& name, const QDBusVariant& parameter)
{
if (interface.endsWith('2'))
@@ -126,10 +131,14 @@ public slots:
valueSpy.clear();
}
+signals:
+ Q_SCRIPTABLE void syncReceived(const QString &sequence);
+
private slots:
- void handleConnection(const QDBusConnection& con)
+ void handleConnection(QDBusConnection con)
{
m_conn = con;
+ con.registerObject(objectPath, this, QDBusConnection::ExportScriptableSignals);
}
private:
diff --git a/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
index 6d25bf2213..9fe6bc790e 100644
--- a/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
+++ b/tests/auto/dbus/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp
@@ -338,6 +338,24 @@ void registerMyObjectPeer(const QString & path, QDBusConnection::RegisterOptions
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
}
+void syncPeer()
+{
+ static int counter = 0;
+ QString reqId = QString::number(++counter);
+
+ // wait for the sync signal with the right ID
+ QEventLoop loop;
+ QDBusConnection con("peer");
+ con.connect(serviceName, objectPath, interfaceName, "syncReceived",
+ QStringList() << reqId, QString(), &loop, SLOT(quit()));
+
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "requestSync");
+ req << reqId;
+ QDBusConnection::sessionBus().send(req);
+
+ loop.exec();
+}
+
void emitSignalPeer(const QString &interface, const QString &name, const QVariant &parameter)
{
if (parameter.isValid())
@@ -1159,6 +1177,8 @@ void tst_QDBusAbstractAdaptor::signalEmissionsPeer()
// connect all signals and emit only one
{
+ syncPeer();
+
QDBusSignalSpy spy;
con.connect(QString(), "/", "local.Interface2", "signal",
&spy, SLOT(slot(QDBusMessage)));
@@ -1186,6 +1206,8 @@ void tst_QDBusAbstractAdaptor::signalEmissionsPeer()
// connect one signal and emit them all
{
+ syncPeer();
+
QDBusSignalSpy spy;
con.connect(QString(), "/", interface, name, &spy, SLOT(slot(QDBusMessage)));
emitSignalPeer("local.Interface2", "signal", QVariant());
@@ -1214,6 +1236,7 @@ void tst_QDBusAbstractAdaptor::sameSignalDifferentPathsPeer()
registerMyObjectPeer("/p1");
registerMyObjectPeer("/p2");
+ syncPeer();
QDBusSignalSpy spy;
con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
emitSignalPeer("local.Interface2", QString(), QVariant());
@@ -1241,6 +1264,7 @@ void tst_QDBusAbstractAdaptor::sameObjectDifferentPathsPeer()
registerMyObjectPeer("/p1");
registerMyObjectPeer("/p2", 0); // don't export anything
+ syncPeer();
QDBusSignalSpy spy;
con.connect(QString(), "/p1", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
con.connect(QString(), "/p2", "local.Interface2", "signal", &spy, SLOT(slot(QDBusMessage)));
@@ -1263,6 +1287,7 @@ void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer()
registerMyObjectPeer("/p1", QDBusConnection::ExportScriptableSignals);
registerMyObjectPeer("/p2", 0); // don't export anything
+ syncPeer();
QDBusSignalSpy spy;
con.connect(QString(), "/p1", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
con.connect(QString(), "/p2", "local.MyObject", "scriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
@@ -1286,6 +1311,7 @@ void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer()
registerMyObjectPeer("/p2", QDBusConnection::ExportScriptableSignals
| QDBusConnection::ExportNonScriptableSignals);
+ syncPeer();
QDBusSignalSpy spy;
con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
@@ -1338,6 +1364,7 @@ void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer()
// connect all signals and emit only one
{
+ syncPeer();
QDBusSignalSpy spy;
con.connect(QString(), "/", "local.Interface4", "signal", "",
&spy, SLOT(slot(QDBusMessage)));
@@ -1358,6 +1385,7 @@ void tst_QDBusAbstractAdaptor::overloadedSignalEmissionPeer()
QFETCH(QString, signature);
// connect one signal and emit them all
{
+ syncPeer();
QDBusSignalSpy spy;
con.connect(QString(), "/", interface, name, signature, &spy, SLOT(slot(QDBusMessage)));
emitSignalPeer("local.Interface4", "signal", QVariant());
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg
new file mode 100644
index 0000000000..aaa4ac4e10
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg
new file mode 100644
index 0000000000..a61d2723d7
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg
new file mode 100644
index 0000000000..43e56dcef7
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg
new file mode 100644
index 0000000000..d5d06f7409
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg
new file mode 100644
index 0000000000..1886f3775e
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg
new file mode 100644
index 0000000000..5cec757354
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg
new file mode 100644
index 0000000000..b3dcc466a9
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg
new file mode 100644
index 0000000000..8bc390e2b9
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 4cb70612ea..676f8084a1 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -173,6 +173,8 @@ private slots:
void invertPixelsRGB_data();
void invertPixelsRGB();
+ void exifOrientation();
+
void cleanupFunctions();
private:
@@ -2639,6 +2641,22 @@ void tst_QImage::invertPixelsRGB()
QCOMPARE(qBlue(pixel) >> 4, (255 - 96) >> 4);
}
+void tst_QImage::exifOrientation()
+{
+ for (unsigned int i = 1; i <= 8; ++i) {
+ QImage img;
+ QRgb px;
+
+ QVERIFY(img.load(m_prefix + QString::fromLatin1("jpeg_exif_orientation_value_%1.jpg").arg(i)));
+
+ px = img.pixel(0, 0);
+ QVERIFY(qRed(px) > 250 && qGreen(px) < 5 && qBlue(px) < 5);
+
+ px = img.pixel(img.width() - 1, 0);
+ QVERIFY(qRed(px) < 5 && qGreen(px) < 5 && qBlue(px) > 250);
+ }
+}
+
static void cleanupFunction(void* info)
{
bool *called = static_cast<bool*>(info);
diff --git a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp
index e08af2491d..a63183e5fc 100644
--- a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp
+++ b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp
@@ -59,30 +59,39 @@ void tst_QDoubleValidator::validateThouSep_data()
{
QTest::addColumn<QString>("localeName");
QTest::addColumn<QString>("value");
+ QTest::addColumn<bool>("rejectGroupSeparator");
QTest::addColumn<QValidator::State>("result");
- QTest::newRow("1,000C") << "C" << QString("1,000") << ACC;
- QTest::newRow("1.000C") << "C" << QString("1.000") << ACC;
+ QTest::newRow("1,000C") << "C" << QString("1,000") << false << ACC;
+ QTest::newRow("1,000.1C") << "C" << QString("1,000.1") << false << ACC;
+ QTest::newRow("1,000.1C_reject") << "C" << QString("1,000.1") << true << INV;
+ QTest::newRow("1.000C") << "C" << QString("1.000") << false << ACC;
- QTest::newRow("1,000de") << "de" << QString("1,000") << ACC;
- QTest::newRow("1.000de") << "de" << QString("1.000") << ACC;
+ QTest::newRow("1,000de") << "de" << QString("1,000") << false << ACC;
+ QTest::newRow("1.000de") << "de" << QString("1.000") << false << ACC;
- QTest::newRow(".C") << "C" << QString(".") << ITM;
- QTest::newRow(".de") << "de" << QString(".") << INV;
- QTest::newRow(",C") << "C" << QString(",") << INV;
- QTest::newRow(",de") << "de" << QString(",") << ITM;
+ QTest::newRow(".C") << "C" << QString(".") << false << ITM;
+ QTest::newRow(".de") << "de" << QString(".") << false << INV;
+ QTest::newRow("1.000,1de") << "de" << QString("1.000,1") << false << ACC;
+ QTest::newRow("1.000,1de_reject") << "de" << QString("1.000,1") << true << INV;
+ QTest::newRow(",C") << "C" << QString(",") << false << INV;
+ QTest::newRow(",de") << "de" << QString(",") << false << ITM;
}
void tst_QDoubleValidator::validateThouSep()
{
QFETCH(QString, localeName);
QFETCH(QString, value);
+ QFETCH(bool, rejectGroupSeparator);
QFETCH(QValidator::State, result);
int dummy = 0;
QDoubleValidator iv(-10000, 10000, 3, 0);
iv.setNotation(QDoubleValidator::ScientificNotation);
- iv.setLocale(QLocale(localeName));
+ QLocale locale(localeName);
+ if (rejectGroupSeparator)
+ locale.setNumberOptions(QLocale::RejectGroupSeparator);
+ iv.setLocale(locale);
QCOMPARE(iv.validate(value, dummy), result);
}
diff --git a/tests/auto/gui/util/qregularexpressionvalidator/tst_qregularexpressionvalidator.cpp b/tests/auto/gui/util/qregularexpressionvalidator/tst_qregularexpressionvalidator.cpp
index 31853f7015..eff07ad07f 100644
--- a/tests/auto/gui/util/qregularexpressionvalidator/tst_qregularexpressionvalidator.cpp
+++ b/tests/auto/gui/util/qregularexpressionvalidator/tst_qregularexpressionvalidator.cpp
@@ -74,6 +74,9 @@ void tst_QRegularExpressionValidator::validate_data()
QTest::newRow("data14") << QRegularExpression("\\w\\d\\d") << QString("E5") << QValidator::Intermediate;
QTest::newRow("data15") << QRegularExpression("\\w\\d\\d") << QString("+9") << QValidator::Invalid;
+ QTest::newRow("emptystr1") << QRegularExpression("[T][e][s][t]") << QString("") << QValidator::Intermediate;
+ QTest::newRow("emptystr2") << QRegularExpression("[T][e][s][t]") << QString() << QValidator::Intermediate;
+
QTest::newRow("empty01") << QRegularExpression() << QString() << QValidator::Acceptable;
QTest::newRow("empty02") << QRegularExpression() << QString("test") << QValidator::Acceptable;
}
diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST
index fbd72492d8..7792e05e0f 100644
--- a/tests/auto/network/access/qnetworkreply/BLACKLIST
+++ b/tests/auto/network/access/qnetworkreply/BLACKLIST
@@ -7,3 +7,6 @@ osx
[SslHandshakeFailedError]
osx
[httpAbort]
+*
+[backgroundRequestInterruption:ftp, bg, nobg]
+*
diff --git a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST
new file mode 100644
index 0000000000..bf4afa8c45
--- /dev/null
+++ b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST
@@ -0,0 +1,4 @@
+[udpTest]
+*
+[passwordAuth]
+*
diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro
index 0cf910df73..4e30a9cded 100644
--- a/tests/auto/network/ssl/ssl.pro
+++ b/tests/auto/network/ssl/ssl.pro
@@ -5,19 +5,21 @@ SUBDIRS=\
qsslerror \
qsslkey \
-contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked):
+contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
contains(QT_CONFIG, private_tests) {
SUBDIRS += \
qsslsocket \
qsslsocket_onDemandCertificates_member \
qsslsocket_onDemandCertificates_static \
}
+}
winrt: SUBDIRS -= \
qsslsocket_onDemandCertificates_member \
qsslsocket_onDemandCertificates_static \
-contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked):
+contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
contains(QT_CONFIG, private_tests) {
- SUBDIRS += qasn1element
+ SUBDIRS += qasn1element
+ }
}
diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp
index 0ba464a82c..56198ceb65 100644
--- a/tests/auto/opengl/qgl/tst_qgl.cpp
+++ b/tests/auto/opengl/qgl/tst_qgl.cpp
@@ -42,6 +42,8 @@
#include <qglcolormap.h>
#include <qpaintengine.h>
#include <qopenglfunctions.h>
+#include <qopenglframebufferobject.h>
+#include <qopenglpaintdevice.h>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
@@ -78,6 +80,7 @@ private slots:
void glWidgetRendering();
void glFBOSimpleRendering();
void glFBORendering();
+ void currentFboSync();
void multipleFBOInterleavedRendering();
void glFBOUseInGLWidget();
void glPBufferRendering();
@@ -1138,6 +1141,93 @@ void tst_QGL::glFBORendering()
qt_opengl_check_test_pattern(fb);
}
+class QOpenGLFramebufferObjectPaintDevice : public QOpenGLPaintDevice
+{
+public:
+ QOpenGLFramebufferObjectPaintDevice(int width, int height)
+ : QOpenGLPaintDevice(width, height)
+ , m_fbo(width, height, QOpenGLFramebufferObject::CombinedDepthStencil)
+ {
+ }
+
+ void ensureActiveTarget()
+ {
+ m_fbo.bind();
+ }
+
+ QImage toImage() const
+ {
+ return m_fbo.toImage();
+ }
+
+private:
+ QOpenGLFramebufferObject m_fbo;
+};
+
+void tst_QGL::currentFboSync()
+{
+ if (!QGLFramebufferObject::hasOpenGLFramebufferObjects())
+ QSKIP("QGLFramebufferObject not supported on this platform");
+
+#if defined(Q_OS_QNX)
+ QSKIP("Reading the QGLFramebufferObject is unsupported on this platform");
+#endif
+
+ QGLWidget glw;
+ glw.makeCurrent();
+
+ {
+ QGLFramebufferObject fbo1(256, 256, QGLFramebufferObject::CombinedDepthStencil);
+
+ QOpenGLFramebufferObjectPaintDevice fbo2(256, 256);
+
+ QImage sourceImage(256, 256, QImage::Format_ARGB32_Premultiplied);
+ QPainter sourcePainter(&sourceImage);
+ qt_opengl_draw_test_pattern(&sourcePainter, 256, 256);
+
+ QPainter fbo1Painter(&fbo1);
+
+ QPainter fbo2Painter(&fbo2);
+ fbo2Painter.drawImage(0, 0, sourceImage);
+ fbo2Painter.end();
+
+ QImage fbo2Image = fbo2.toImage();
+
+ fbo1Painter.drawImage(0, 0, sourceImage);
+ fbo1Painter.end();
+
+ QGLFramebufferObject::bindDefault();
+
+ QCOMPARE(fbo1.toImage(), fbo2Image);
+ }
+
+ {
+ QGLFramebufferObject fbo1(512, 512, QGLFramebufferObject::CombinedDepthStencil);
+
+ QOpenGLFramebufferObjectPaintDevice fbo2(256, 256);
+
+ QImage sourceImage(256, 256, QImage::Format_ARGB32_Premultiplied);
+ QPainter sourcePainter(&sourceImage);
+ qt_opengl_draw_test_pattern(&sourcePainter, 256, 256);
+
+ QPainter fbo2Painter(&fbo2);
+ fbo2Painter.drawImage(0, 0, sourceImage);
+ QImage fbo2Image1 = fbo2.toImage();
+ fbo2Painter.fillRect(0, 0, 256, 256, Qt::white);
+
+ QPainter fbo1Painter(&fbo1);
+ fbo1Painter.drawImage(0, 0, sourceImage);
+ fbo1Painter.end();
+
+ // check that the OpenGL paint engine now knows it needs to sync
+ fbo2Painter.drawImage(0, 0, sourceImage);
+ QImage fbo2Image2 = fbo2.toImage();
+
+ fbo2Painter.end();
+
+ QCOMPARE(fbo2Image1, fbo2Image2);
+ }
+}
// Tests multiple QPainters active on different FBOs at the same time, with
// interleaving painting. Performance-wise, this is sub-optimal, but it still
diff --git a/tests/auto/other/qaccessibility/BLACKLIST b/tests/auto/other/qaccessibility/BLACKLIST
deleted file mode 100644
index 11598aece6..0000000000
--- a/tests/auto/other/qaccessibility/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[abstractScrollAreaTest]
-osx
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 1c8121f142..af0a0b446e 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -2648,57 +2648,67 @@ void tst_QAccessibility::abstractScrollAreaTest()
// Horizontal scrollBar.
abstractScrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- QCOMPARE(interface->childCount(), 2);
QWidget *horizontalScrollBar = abstractScrollArea.horizontalScrollBar();
+
+ // On OS X >= 10.9 the scrollbar will be hidden unless explicitly enabled in the preferences
+ bool scrollBarsVisible = !horizontalScrollBar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, horizontalScrollBar);
+ int childCount = scrollBarsVisible ? 2 : 1;
+ QCOMPARE(interface->childCount(), childCount);
QWidget *horizontalScrollBarContainer = horizontalScrollBar->parentWidget();
- QVERIFY(verifyChild(horizontalScrollBarContainer, interface, 1, globalGeometry));
+ if (scrollBarsVisible)
+ QVERIFY(verifyChild(horizontalScrollBarContainer, interface, 1, globalGeometry));
// Horizontal scrollBar widgets.
QLabel *secondLeftLabel = new QLabel(QLatin1String("L2"));
abstractScrollArea.addScrollBarWidget(secondLeftLabel, Qt::AlignLeft);
- QCOMPARE(interface->childCount(), 2);
+ QCOMPARE(interface->childCount(), childCount);
QLabel *firstLeftLabel = new QLabel(QLatin1String("L1"));
abstractScrollArea.addScrollBarWidget(firstLeftLabel, Qt::AlignLeft);
- QCOMPARE(interface->childCount(), 2);
+ QCOMPARE(interface->childCount(), childCount);
QLabel *secondRightLabel = new QLabel(QLatin1String("R2"));
abstractScrollArea.addScrollBarWidget(secondRightLabel, Qt::AlignRight);
- QCOMPARE(interface->childCount(), 2);
+ QCOMPARE(interface->childCount(), childCount);
QLabel *firstRightLabel = new QLabel(QLatin1String("R1"));
abstractScrollArea.addScrollBarWidget(firstRightLabel, Qt::AlignRight);
- QCOMPARE(interface->childCount(), 2);
+ QCOMPARE(interface->childCount(), childCount);
// Vertical scrollBar.
abstractScrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- QCOMPARE(interface->childCount(), 3);
+ if (scrollBarsVisible)
+ ++childCount;
+ QCOMPARE(interface->childCount(), childCount);
QWidget *verticalScrollBar = abstractScrollArea.verticalScrollBar();
QWidget *verticalScrollBarContainer = verticalScrollBar->parentWidget();
- QVERIFY(verifyChild(verticalScrollBarContainer, interface, 2, globalGeometry));
+ if (scrollBarsVisible)
+ QVERIFY(verifyChild(verticalScrollBarContainer, interface, 2, globalGeometry));
// Vertical scrollBar widgets.
QLabel *secondTopLabel = new QLabel(QLatin1String("T2"));
abstractScrollArea.addScrollBarWidget(secondTopLabel, Qt::AlignTop);
- QCOMPARE(interface->childCount(), 3);
+ QCOMPARE(interface->childCount(), childCount);
QLabel *firstTopLabel = new QLabel(QLatin1String("T1"));
abstractScrollArea.addScrollBarWidget(firstTopLabel, Qt::AlignTop);
- QCOMPARE(interface->childCount(), 3);
+ QCOMPARE(interface->childCount(), childCount);
QLabel *secondBottomLabel = new QLabel(QLatin1String("B2"));
abstractScrollArea.addScrollBarWidget(secondBottomLabel, Qt::AlignBottom);
- QCOMPARE(interface->childCount(), 3);
+ QCOMPARE(interface->childCount(), childCount);
QLabel *firstBottomLabel = new QLabel(QLatin1String("B1"));
abstractScrollArea.addScrollBarWidget(firstBottomLabel, Qt::AlignBottom);
- QCOMPARE(interface->childCount(), 3);
+ QCOMPARE(interface->childCount(), childCount);
// CornerWidget.
+ ++childCount;
abstractScrollArea.setCornerWidget(new QLabel(QLatin1String("C")));
- QCOMPARE(interface->childCount(), 4);
+ QCOMPARE(interface->childCount(), childCount);
QWidget *cornerWidget = abstractScrollArea.cornerWidget();
- QVERIFY(verifyChild(cornerWidget, interface, 3, globalGeometry));
+ if (scrollBarsVisible)
+ QVERIFY(verifyChild(cornerWidget, interface, 3, globalGeometry));
QCOMPARE(verifyHierarchy(interface), 0);
diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
index 1be570e4b8..e3a72f4ab4 100644
--- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
+++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
@@ -1103,9 +1103,7 @@ void tst_QPrinter::fontEmbedding()
{
// fontEmbeddingEnabled() / setFontEmbeddingEnabled() / PPK_FontEmbedding
// PdfFormat: Supported, default true
- // NativeFormat, Cups: Supported, default true
- // NativeFormat, Win: Unsupported, always false
- // NativeFormat, Mac: Unsupported, always false
+ // NativeFormat: Supported, default true
QPrinter pdf;
pdf.setOutputFormat(QPrinter::PdfFormat);
@@ -1116,25 +1114,17 @@ void tst_QPrinter::fontEmbedding()
QPrinter native;
if (native.outputFormat() == QPrinter::NativeFormat) {
// Test default
-#if defined Q_OS_MAC || defined Q_OS_WIN
- QCOMPARE(native.fontEmbeddingEnabled(), false);
-#else
QCOMPARE(native.fontEmbeddingEnabled(), true);
-#endif // Q_OS_MAC || Q_OS_WIN
// Test set/get
- bool expected = true;
- native.setFontEmbeddingEnabled(expected);
-#if defined Q_OS_MAC || defined Q_OS_WIN
- expected = false;
-#endif // Q_OS_MAC || Q_OS_WIN
- QCOMPARE(native.fontEmbeddingEnabled(), expected);
+ native.setFontEmbeddingEnabled(true);
+ QCOMPARE(native.fontEmbeddingEnabled(), true);
// Test value preservation
native.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(native.fontEmbeddingEnabled(), expected);
+ QCOMPARE(native.fontEmbeddingEnabled(), true);
native.setOutputFormat(QPrinter::NativeFormat);
- QCOMPARE(native.fontEmbeddingEnabled(), expected);
+ QCOMPARE(native.fontEmbeddingEnabled(), true);
} else {
QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
}
diff --git a/tests/auto/tools/moc/parse-defines.h b/tests/auto/tools/moc/parse-defines.h
index c9b5d13b1f..9a00955846 100644
--- a/tests/auto/tools/moc/parse-defines.h
+++ b/tests/auto/tools/moc/parse-defines.h
@@ -77,6 +77,8 @@
#define DEFINE_CMDLINE_SIGNAL void cmdlineSignal(const QMap<int, int> &i)
#endif
+#define HASH_SIGN #
+
PD_BEGIN_NAMESPACE
class DEFINE_CMDLINE_EMPTY PD_CLASSNAME DEFINE_CMDLINE_EMPTY
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 965a16e7c2..fe6ad6637a 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -1565,7 +1565,7 @@ public slots:
void doAnotherThing(bool a = (1 < 3), bool b = (1 > 4)) { Q_UNUSED(a); Q_UNUSED(b); }
-#if defined(Q_MOC_RUN) || (defined(Q_COMPILER_AUTO_TYPE) && !(defined(Q_CC_CLANG) && (__clang_major__ * 100) + __clang_minor__) < 304)
+#if defined(Q_MOC_RUN) || (defined(Q_COMPILER_AUTO_TYPE) && !(defined(Q_CC_CLANG) && Q_CC_CLANG < 304))
// There is no Q_COMPILER_>> but if compiler support auto, it should also support >>
void performSomething(QVector<QList<QString>> e = QVector<QList<QString>>(8 < 1),
QHash<int, QVector<QString>> h = QHash<int, QVector<QString>>())
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
index 5239614fc7..fb432a7d21 100644
--- a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
+++ b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
@@ -20,4 +20,3 @@ wince* {
DEFINES += SRCDIR=\\\"$$PWD/\\\"
}
-macx:CONFIG += insignificant_test # QTBUG-39183
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
index 2ffb81a751..241e6d0e7e 100644
--- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -448,6 +448,8 @@ void tst_QFileDialog2::task180459_lastDirectory_data()
void tst_QFileDialog2::task180459_lastDirectory()
{
+ if (qApp->platformName().toLower() == QStringLiteral("cocoa"))
+ QSKIP("Insignificant on OSX"); //QTBUG-39183
//first visit the temp directory and close the dialog
QNonNativeFileDialog *dlg = new QNonNativeFileDialog(0, "", tempDir.path());
QFileSystemModel *model = dlg->findChild<QFileSystemModel*>("qt_filesystem_model");
diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp b/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp
index 833494f25e..bdf610e426 100644
--- a/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp
+++ b/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp
@@ -71,6 +71,7 @@ tst_QGestureRecognizer::tst_QGestureRecognizer()
: m_fingerDistance(qRound(QGuiApplication::primaryScreen()->physicalDotsPerInch() / 2.0))
, m_touchDevice(new QTouchDevice)
{
+ qputenv("QT_PAN_TOUCHPOINTS", "2"); // Prevent device detection of pan touch point count.
}
void tst_QGestureRecognizer::initTestCase()
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro b/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro
index 201085aecd..d1f9bede0b 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/qgraphicsview.pro
@@ -9,5 +9,4 @@ SOURCES += tst_qgraphicsview.cpp tst_qgraphicsview_2.cpp
HEADERS += tst_qgraphicsview.h
DEFINES += QT_NO_CAST_TO_ASCII
-mac:CONFIG+=insignificant_test # QTBUG-26580
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
index 8171277f36..04852721db 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
@@ -143,6 +143,10 @@ class tst_QGraphicsView : public QObject
{
Q_OBJECT
+public:
+ tst_QGraphicsView()
+ : platformName(qApp->platformName().toLower())
+ { }
private slots:
void initTestCase();
void cleanup();
@@ -272,6 +276,7 @@ private:
#if defined Q_OS_BLACKBERRY
QScopedPointer<QWidget> rootWindow;
#endif
+ QString platformName;
};
void tst_QGraphicsView::initTestCase()
@@ -2827,6 +2832,8 @@ void tst_QGraphicsView::scrollBarRanges()
if (style == QLatin1String("GTK+") && useStyledPanel)
QSKIP("GTK + style test skipped, see QTBUG-29002");
+ if (useStyledPanel && style == QStringLiteral("Macintosh") && platformName == QStringLiteral("cocoa"))
+ QSKIP("Insignificant on OSX");
QGraphicsScene scene;
QGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
@@ -4733,6 +4740,8 @@ public:
void tst_QGraphicsView::hoverLeave()
{
+ if (platformName == QStringLiteral("cocoa"))
+ QSKIP("Insignificant on OSX");
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
QGraphicsScene scene;
QGraphicsView view(&scene);
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
index 766065acda..f000907e0e 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
+++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
@@ -782,10 +782,8 @@ void tst_QItemDelegate::dateTimeEditor()
widget.setFocus();
widget.editItem(item2);
- QTestEventLoop::instance().enterLoop(1);
-
+ QTRY_VERIFY(widget.viewport()->findChild<QDateEdit *>());
QDateEdit *dateEditor = widget.viewport()->findChild<QDateEdit *>();
- QVERIFY(dateEditor);
QCOMPARE(dateEditor->date(), date);
dateEditor->setDate(date.addDays(60));
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index 565eac2cba..389ff6572d 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
@@ -434,7 +434,7 @@ public:
{
QTableView::setModel(model);
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ this, SLOT(slotCurrentChanged(QModelIndex,QModelIndex)));
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(itemSelectionChanged(QItemSelection,QItemSelection)));
}
@@ -495,7 +495,7 @@ public:
bool checkSignalOrder;
public slots:
- void currentChanged(QModelIndex , QModelIndex ) {
+ void slotCurrentChanged(QModelIndex, QModelIndex) {
hasCurrentChanged++;
if (checkSignalOrder)
QVERIFY(hasCurrentChanged > hasSelectionChanged);
diff --git a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp
index 7904848faf..4b7e2a7198 100644
--- a/tests/auto/widgets/kernel/qaction/tst_qaction.cpp
+++ b/tests/auto/widgets/kernel/qaction/tst_qaction.cpp
@@ -61,6 +61,7 @@ private slots:
void setText();
void setIconText_data() { setText_data(); }
void setIconText();
+ void setUnknownFont();
void actionEvent();
void setStandardKeys();
void alternateShortcuts();
@@ -184,6 +185,15 @@ void tst_QAction::setIconText()
QCOMPARE(action.text(), textFromIconText);
}
+void tst_QAction::setUnknownFont() // QTBUG-42728
+{
+ QAction action(0);
+ QFont font("DoesNotExist", 11);
+ action.setFont(font);
+
+ QMenu menu;
+ menu.addAction(&action); // should not crash
+}
void tst_QAction::updateState(QActionEvent *e)
{
diff --git a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro
index d61681d5cb..d61681d5cb 100755..100644
--- a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro
+++ b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
index c6c7464194..36791293ab 100755..100644
--- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
+++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
@@ -95,6 +95,8 @@ private slots:
void tst_updateWinId_QTBUG40681();
void tst_recreateWindow_QTBUG40817();
+ void tst_resize_count();
+ void tst_move_count();
};
void tst_QWidget_window::initTestCase()
@@ -660,6 +662,105 @@ void tst_QWidget_window::tst_recreateWindow_QTBUG40817()
tab.setCurrentIndex(1);
}
+class ResizeWidget : public QWidget
+{
+Q_OBJECT
+public:
+ ResizeWidget(QWidget *parent = 0)
+ : QWidget(parent)
+ , resizeCount(0)
+ { }
+
+ int resizeCount;
+
+protected:
+ void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE
+ {
+ resizeCount++;
+ }
+};
+
+void tst_QWidget_window::tst_resize_count()
+{
+ {
+ ResizeWidget resize;
+ resize.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&resize));
+ QCOMPARE(resize.resizeCount, 1);
+ resize.resizeCount = 0;
+ QSize size = resize.size();
+ size.rwidth() += 10;
+ resize.resize(size);
+ QGuiApplication::sync();
+ QTRY_COMPARE(resize.resizeCount, 1);
+
+ resize.resizeCount = 0;
+
+ ResizeWidget child(&resize);
+ child.resize(200,200);
+ child.winId();
+ child.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&child));
+ QGuiApplication::sync();
+ QTRY_COMPARE(child.resizeCount, 1);
+ child.resizeCount = 0;
+ size = child.size();
+ size.rwidth() += 10;
+ child.resize(size);
+ QGuiApplication::sync();
+ QCOMPARE(resize.resizeCount, 0);
+ QCOMPARE(child.resizeCount, 1);
+ }
+ {
+ ResizeWidget parent;
+ ResizeWidget child(&parent);
+ child.resize(200,200);
+ child.winId();
+ parent.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&parent));
+ parent.resizeCount = 0;
+ QGuiApplication::sync();
+ QTRY_COMPARE(child.resizeCount, 1);
+ child.resizeCount = 0;
+ QSize size = child.size();
+ size.rwidth() += 10;
+ child.resize(size);
+ QGuiApplication::sync();
+ QCOMPARE(parent.resizeCount, 0);
+ QCOMPARE(child.resizeCount, 1);
+ }
+
+}
+
+class MoveWidget : public QWidget
+{
+Q_OBJECT
+public:
+ MoveWidget(QWidget *parent = 0)
+ : QWidget(parent)
+ , moveCount(0)
+ { }
+
+ void moveEvent(QMoveEvent *) Q_DECL_OVERRIDE
+ {
+ moveCount++;
+ }
+
+ int moveCount;
+};
+
+void tst_QWidget_window::tst_move_count()
+{
+ MoveWidget move;
+ move.move(500,500);
+ move.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&move));
+ QTRY_VERIFY(move.moveCount >= 1);
+ move.moveCount = 0;
+
+ move.move(220,250);
+ QTRY_VERIFY(move.moveCount >= 1);
+}
QTEST_MAIN(tst_QWidget_window)
#include "tst_qwidget_window.moc"
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index 27c803b43d..751a16c59d 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
@@ -104,6 +104,7 @@ public:
tst_QMainWindow();
private slots:
+ void cleanup();
void getSetCheck();
void constructor();
void iconSize();
@@ -147,6 +148,12 @@ private slots:
void QTBUG21378_animationFinished();
};
+
+void tst_QMainWindow::cleanup()
+{
+ QVERIFY(QApplication::topLevelWidgets().isEmpty());
+}
+
// Testing get/set functions
void tst_QMainWindow::getSetCheck()
{
@@ -854,6 +861,7 @@ void tst_QMainWindow::takeCentralWidget() {
QVERIFY(!w2.isNull());
QCOMPARE(w2.data(), hopefullyW2);
+ delete w2;
}
void tst_QMainWindow::corner()
diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
index f457955657..ff9bc7c4a2 100644
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
@@ -104,7 +104,7 @@ static bool tabBetweenSubWindowsIn(QMdiArea *mdiArea, int tabCount = -1, bool re
if (tabCount > 1)
QTest::qWait(500);
if (walkThrough) {
- QRubberBand *rubberBand = mdiArea->viewport()->findChild<QRubberBand *>();
+ QRubberBand *rubberBand = mdiArea->findChild<QRubberBand *>();
if (!rubberBand) {
qWarning("No rubber band");
return false;
diff --git a/tests/manual/diaglib/README.txt b/tests/manual/diaglib/README.txt
new file mode 100644
index 0000000000..13387f5a2a
--- /dev/null
+++ b/tests/manual/diaglib/README.txt
@@ -0,0 +1,34 @@
+This is a collection of functions and classes helpful for diagnosing bugs
+in Qt 4 and Qt 5. It can be included in the application's .pro file by
+adding:
+
+include([path to Qt sources]/tests/manual/diaglib/diaglib.pri)
+
+For Qt 4, the environment variable QTDIR may be used:
+include($$(QTDIR)/tests/manual/diaglib/diaglib.pri)
+
+The .pri file adds the define QT_DIAG_LIB, so, diagnostic
+code can be enlosed within #ifdef to work without it as well.
+
+All functions and classes are in the QtDiag namespace.
+
+class EventFilter (eventfilter.h):
+ An event filter that logs Qt events to qDebug() depending on
+ configured categories (for example mouse, keyboard, etc).
+
+function glInfo() (glinfo.h):
+ Returns a string describing the Open GL configuration (obtained
+ by querying GL_VENDOR and GL_RENDERER). Available only
+ when the QT qmake variable contains opengl.
+
+functions dumpNativeWindows(), dumpNativeQtTopLevels():
+ These functions du,p out the hierarchy of native Windows. Currently
+ implemented for Windows only.
+
+function dumpAllWidgets() (qwidgetdump.h):
+ Dumps the hierarchy of QWidgets including information about flags,
+ visibility, geometry, etc.
+
+function dumpAllWindows() (qwindowdump.h):
+ Dumps the hierarchy of QWindows including information about flags,
+ visibility, geometry, etc.
diff --git a/tests/manual/diaglib/diaglib.pri b/tests/manual/diaglib/diaglib.pri
new file mode 100644
index 0000000000..138660f85e
--- /dev/null
+++ b/tests/manual/diaglib/diaglib.pri
@@ -0,0 +1,43 @@
+INCLUDEPATH += $$PWD
+SOURCES += \
+ $$PWD/eventfilter.cpp \
+ $$PWD/qwindowdump.cpp \
+
+HEADERS += \
+ $$PWD/eventfilter.h \
+ $$PWD/qwindowdump.h \
+ $$PWD/nativewindowdump.h
+
+win32 {
+ SOURCES += $$PWD/nativewindowdump_win.cpp
+ LIBS *= -luser32
+} else {
+ SOURCES += $$PWD/nativewindowdump.cpp
+}
+
+greaterThan(QT_MAJOR_VERSION, 4) {
+ QT += gui-private core-private
+ contains(QT, widgets) {
+ HEADERS += \
+ $$PWD/$$PWD/qwidgetdump.h
+
+ SOURCES += \
+ $$PWD/qwidgetdump.cpp
+ }
+} else {
+ HEADERS += \
+ $$PWD/$$PWD/qwidgetdump.h
+
+ SOURCES += \
+ $$PWD/qwidgetdump.cpp
+}
+
+contains(QT, opengl) {
+HEADERS += \
+ $$PWD/glinfo.h
+
+SOURCES += \
+ $$PWD/glinfo.cpp
+}
+
+DEFINES += QT_DIAG_LIB
diff --git a/tests/manual/diaglib/eventfilter.cpp b/tests/manual/diaglib/eventfilter.cpp
new file mode 100644
index 0000000000..f0573975f6
--- /dev/null
+++ b/tests/manual/diaglib/eventfilter.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "eventfilter.h"
+#include <QtGui/QMouseEvent>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+namespace QtDiag {
+
+EventFilter::EventFilter(EventCategories eventCategories, QObject *p)
+ : QObject(p)
+{
+ init(eventCategories);
+}
+
+EventFilter::EventFilter(QObject *p)
+ : QObject(p)
+{
+ init(EventCategories(0xFFFFFFF));
+}
+
+void EventFilter::init(EventCategories eventCategories)
+{
+ if (eventCategories & MouseEvents) {
+ m_eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease
+ << QEvent::MouseButtonDblClick << QEvent::NonClientAreaMouseButtonPress
+ << QEvent::NonClientAreaMouseButtonRelease
+ << QEvent::NonClientAreaMouseButtonDblClick
+ << QEvent::Enter << QEvent::Leave;
+ }
+ if (eventCategories & MouseMoveEvents)
+ m_eventTypes << QEvent::MouseMove << QEvent::NonClientAreaMouseMove;
+ if (eventCategories & TouchEvents) {
+ m_eventTypes << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
+#if QT_VERSION >= 0x050000
+ m_eventTypes << QEvent::TouchCancel;
+#endif
+ }
+ if (eventCategories & TabletEvents) {
+ m_eventTypes << QEvent::TabletEnterProximity << QEvent::TabletLeaveProximity
+ << QEvent::TabletMove << QEvent::TabletPress << QEvent::TabletRelease;
+ }
+ if (eventCategories & DragAndDropEvents) {
+ m_eventTypes << QEvent::DragEnter << QEvent::DragMove << QEvent::DragLeave
+ << QEvent::Drop << QEvent::DragResponse;
+ }
+ if (eventCategories & KeyEvents) {
+ m_eventTypes << QEvent::KeyPress << QEvent::KeyRelease << QEvent::ShortcutOverride
+ << QEvent::Shortcut;
+ }
+ if (eventCategories & GeometryEvents)
+ m_eventTypes << QEvent::Move << QEvent::Resize;
+ if (eventCategories & PaintEvents) {
+ m_eventTypes << QEvent::UpdateRequest << QEvent::Paint
+ << QEvent::Show << QEvent::Hide;
+#if QT_VERSION >= 0x050000
+ m_eventTypes << QEvent::Expose;
+#endif
+ }
+ if (eventCategories & TimerEvents)
+ m_eventTypes << QEvent::Timer << QEvent::ZeroTimerEvent;
+ if (eventCategories & ObjectEvents) {
+ m_eventTypes << QEvent::ChildAdded << QEvent::ChildPolished
+ << QEvent::ChildRemoved << QEvent::Create << QEvent::Destroy;
+ }
+}
+
+bool EventFilter::eventFilter(QObject *o, QEvent *e)
+{
+ static int n = 0;
+ if (m_eventTypes.contains(e->type())) {
+ QDebug debug = qDebug().nospace();
+ const QString on = o->objectName();
+ debug << '#' << n++ << ' ' << o->metaObject()->className();
+ if (!on.isEmpty())
+ debug << '/' << on;
+ debug << ' ' << e;
+ }
+ return false;
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/eventfilter.h b/tests/manual/diaglib/eventfilter.h
new file mode 100644
index 0000000000..d87ac68b07
--- /dev/null
+++ b/tests/manual/diaglib/eventfilter.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _EVENTFILTER_
+#define _EVENTFILTER_
+
+#include <QtCore/QObject>
+#include <QtCore/QEvent>
+#include <QtCore/QList>
+
+namespace QtDiag {
+
+// Event filter that can for example be installed on QApplication
+// to log relevant events.
+
+class EventFilter : public QObject {
+public:
+ enum EventCategory {
+ MouseEvents = 0x00001,
+ MouseMoveEvents = 0x00002,
+ TouchEvents = 0x00004,
+ TabletEvents = 0x00008,
+ DragAndDropEvents = 0x00010,
+ KeyEvents = 0x00020,
+ GeometryEvents = 0x00040,
+ PaintEvents = 0x00080,
+ TimerEvents = 0x00100,
+ ObjectEvents = 0x00200
+ };
+ Q_DECLARE_FLAGS(EventCategories, EventCategory)
+
+ explicit EventFilter(EventCategories eventCategories, QObject *p = 0);
+ explicit EventFilter(QObject *p = 0);
+
+ bool eventFilter(QObject *, QEvent *);
+
+private:
+ void init(EventCategories eventCategories);
+
+ QList<QEvent::Type> m_eventTypes;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(EventFilter::EventCategories)
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/glinfo.cpp b/tests/manual/diaglib/glinfo.cpp
new file mode 100644
index 0000000000..cd30e46b45
--- /dev/null
+++ b/tests/manual/diaglib/glinfo.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "glinfo.h"
+
+#include <QtOpenGL/QGLFunctions>
+#include <QtOpenGL/QGLWidget>
+#if QT_VERSION > 0x050000
+# if QT_VERSION >= 0x050400
+# include <QtWidgets/QOpenGLWidget>
+# include <QtGui/QOpenGLWindow>
+# else // 5.4
+# include <QtGui/QWindow>
+# endif // 5.0..5.4
+# include <QtGui/QOpenGLContext>
+# include <QtGui/QOpenGLFunctions>
+# include <QtGui/QWindow>
+#endif
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QTimer>
+
+namespace QtDiag {
+
+#if QT_VERSION > 0x050000
+
+static QString getGlString(const QOpenGLContext *ctx, GLenum name)
+{
+ if (const GLubyte *p = ctx->functions()->glGetString(name))
+ return QString::fromLatin1(reinterpret_cast<const char *>(p));
+ return QString();
+}
+
+static QString glInfo(const QOpenGLContext *ctx)
+{
+ return getGlString(ctx, GL_VENDOR)
+ + QLatin1Char('\n')
+ + getGlString(ctx, GL_RENDERER);
+}
+
+static QString glInfo(const QGLContext *ctx)
+{
+ return glInfo(ctx->contextHandle());
+}
+
+QString glInfo(const QObject *o)
+{
+# if QT_VERSION >= 0x050400
+ if (o->isWindowType()) {
+ if (const QOpenGLWindow *oglw = qobject_cast<const QOpenGLWindow *>(o))
+ return glInfo(oglw->context());
+ return QString();
+ }
+# endif // 5.4
+ if (o->isWidgetType()) {
+ if (const QGLWidget *g = qobject_cast<const QGLWidget *>(o))
+ return glInfo(g->context());
+# if QT_VERSION >= 0x050400
+ if (const QOpenGLWidget *g = qobject_cast<const QOpenGLWidget *>(o))
+ return glInfo(g->context());
+# endif // 5.4
+ }
+ return QString();
+}
+
+#else // Qt4:
+
+static QString getGlString(GLenum name)
+{
+ if (const GLubyte *p = glGetString(name))
+ return QString::fromLatin1(reinterpret_cast<const char *>(p));
+ return QString();
+}
+
+QString glInfo(const QWidget *)
+{
+ return getGlString(GL_VENDOR) + QLatin1Char('\n') + getGlString(GL_RENDERER);
+}
+
+#endif
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/glinfo.h b/tests/manual/diaglib/glinfo.h
new file mode 100644
index 0000000000..1f515267f2
--- /dev/null
+++ b/tests/manual/diaglib/glinfo.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _GLINFO_
+#define _GLINFO_
+
+#include <QtCore/QtGlobal>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QString)
+
+namespace QtDiag {
+
+QString glInfo(const QObject *o);
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/nativewindowdump.cpp b/tests/manual/diaglib/nativewindowdump.cpp
new file mode 100644
index 0000000000..a6c741a085
--- /dev/null
+++ b/tests/manual/diaglib/nativewindowdump.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nativewindowdump.h"
+
+namespace QtDiag {
+
+void dumpNativeWindows(WId)
+{
+}
+
+void dumpNativeQtTopLevels()
+{
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/nativewindowdump.h b/tests/manual/diaglib/nativewindowdump.h
new file mode 100644
index 0000000000..405998feea
--- /dev/null
+++ b/tests/manual/diaglib/nativewindowdump.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _NATIVEWINDOWDUMP_
+#define _NATIVEWINDOWDUMP_
+
+#include <QtGui/qwindowdefs.h>
+
+namespace QtDiag {
+
+void dumpNativeWindows(WId root = 0);
+void dumpNativeQtTopLevels();
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/nativewindowdump_win.cpp b/tests/manual/diaglib/nativewindowdump_win.cpp
new file mode 100644
index 0000000000..814b580f4b
--- /dev/null
+++ b/tests/manual/diaglib/nativewindowdump_win.cpp
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nativewindowdump.h"
+#include "qwindowdump.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QDebug>
+#include <QtCore/QVector>
+
+#include <QtCore/qt_windows.h>
+
+namespace QtDiag {
+
+struct DumpContext {
+ DumpContext() : indentation(0) {}
+
+ int indentation;
+ QSharedPointer<QTextStream> stream;
+};
+
+#define debugWinStyle(str, style, styleConstant) \
+if (style & styleConstant) \
+ str << ' ' << #styleConstant;
+
+static void formatNativeWindow(HWND hwnd, QTextStream &str)
+{
+ str << hex << showbase << quintptr(hwnd) << noshowbase << dec;
+ RECT rect;
+ if (GetWindowRect(hwnd, &rect)) {
+ str << ' ' << (rect.right - rect.left) << 'x' << (rect.bottom - rect.top)
+ << '+' << rect.left << '+' << rect.top;
+ }
+ if (IsWindowVisible(hwnd))
+ str << " [visible]";
+
+ str << hex << showbase;
+ if (const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE)) {
+ str << " style=" << style;
+ debugWinStyle(str, style, WS_OVERLAPPED)
+ debugWinStyle(str, style, WS_POPUP)
+ debugWinStyle(str, style, WS_MINIMIZE)
+ debugWinStyle(str, style, WS_CHILD)
+ debugWinStyle(str, style, WS_VISIBLE)
+ debugWinStyle(str, style, WS_DISABLED)
+ debugWinStyle(str, style, WS_CLIPSIBLINGS)
+ debugWinStyle(str, style, WS_CLIPCHILDREN)
+ debugWinStyle(str, style, WS_MAXIMIZE)
+ debugWinStyle(str, style, WS_CAPTION)
+ debugWinStyle(str, style, WS_BORDER)
+ debugWinStyle(str, style, WS_DLGFRAME)
+ debugWinStyle(str, style, WS_VSCROLL)
+ debugWinStyle(str, style, WS_HSCROLL)
+ debugWinStyle(str, style, WS_SYSMENU)
+ debugWinStyle(str, style, WS_THICKFRAME)
+ debugWinStyle(str, style, WS_GROUP)
+ debugWinStyle(str, style, WS_TABSTOP)
+ debugWinStyle(str, style, WS_MINIMIZEBOX)
+ debugWinStyle(str, style, WS_MAXIMIZEBOX)
+ }
+ if (const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE)) {
+ str << " exStyle=" << exStyle;
+ debugWinStyle(str, exStyle, WS_EX_DLGMODALFRAME)
+ debugWinStyle(str, exStyle, WS_EX_NOPARENTNOTIFY)
+ debugWinStyle(str, exStyle, WS_EX_TOPMOST)
+ debugWinStyle(str, exStyle, WS_EX_ACCEPTFILES)
+ debugWinStyle(str, exStyle, WS_EX_TRANSPARENT)
+ debugWinStyle(str, exStyle, WS_EX_MDICHILD)
+ debugWinStyle(str, exStyle, WS_EX_TOOLWINDOW)
+ debugWinStyle(str, exStyle, WS_EX_WINDOWEDGE)
+ debugWinStyle(str, exStyle, WS_EX_CLIENTEDGE)
+ debugWinStyle(str, exStyle, WS_EX_CONTEXTHELP)
+ debugWinStyle(str, exStyle, WS_EX_RIGHT)
+ debugWinStyle(str, exStyle, WS_EX_LEFT)
+ debugWinStyle(str, exStyle, WS_EX_RTLREADING)
+ debugWinStyle(str, exStyle, WS_EX_LTRREADING)
+ debugWinStyle(str, exStyle, WS_EX_LEFTSCROLLBAR)
+ debugWinStyle(str, exStyle, WS_EX_RIGHTSCROLLBAR)
+ debugWinStyle(str, exStyle, WS_EX_CONTROLPARENT)
+ debugWinStyle(str, exStyle, WS_EX_STATICEDGE)
+ debugWinStyle(str, exStyle, WS_EX_APPWINDOW)
+ debugWinStyle(str, exStyle, WS_EX_LAYERED)
+ debugWinStyle(str, exStyle, WS_EX_NOINHERITLAYOUT)
+ debugWinStyle(str, exStyle, WS_EX_NOREDIRECTIONBITMAP)
+ debugWinStyle(str, exStyle, WS_EX_LAYOUTRTL)
+ debugWinStyle(str, exStyle, WS_EX_COMPOSITED)
+ debugWinStyle(str, exStyle, WS_EX_NOACTIVATE)
+ }
+ str << noshowbase << dec;
+
+ wchar_t buf[512];
+ if (GetWindowText(hwnd, buf, sizeof(buf)/sizeof(buf[0])))
+ str << " title=\"" << QString::fromWCharArray(buf) << '"';
+ if (GetClassName(hwnd, buf, sizeof(buf)/sizeof(buf[0])))
+ str << " class=\"" << QString::fromWCharArray(buf) << '"';
+ str << '\n';
+}
+
+static void dumpNativeWindowRecursion(HWND hwnd, DumpContext *dc);
+
+BOOL CALLBACK dumpWindowEnumChildProc(HWND hwnd, LPARAM lParam)
+{
+ dumpNativeWindowRecursion(hwnd, reinterpret_cast<DumpContext *>(lParam));
+ return TRUE;
+}
+
+static void dumpNativeWindowRecursion(HWND hwnd, DumpContext *dc)
+{
+ indentStream(*dc->stream, dc->indentation);
+ formatNativeWindow(hwnd, *dc->stream);
+ DumpContext nextLevel = *dc;
+ nextLevel.indentation += 2;
+ EnumChildWindows(hwnd, dumpWindowEnumChildProc, reinterpret_cast<LPARAM>(&nextLevel));
+}
+
+/* recurse by Z order, same result */
+static void dumpNativeWindowRecursionByZ(HWND hwnd, DumpContext *dc)
+{
+ indentStream(*dc->stream, dc->indentation);
+ formatNativeWindow(hwnd, *dc->stream);
+ if (const HWND topChild = GetTopWindow(hwnd)) {
+ DumpContext nextLevel = *dc;
+ nextLevel.indentation += 2;
+ for (HWND child = topChild; child ; child = GetNextWindow(child, GW_HWNDNEXT))
+ dumpNativeWindowRecursionByZ(child, &nextLevel);
+ }
+}
+
+typedef QVector<WId> WIdVector;
+
+static void dumpNativeWindows(const WIdVector& wins)
+{
+ DumpContext dc;
+ QString s;
+ dc.stream = QSharedPointer<QTextStream>(new QTextStream(&s));
+ foreach (WId win, wins)
+ dumpNativeWindowRecursion(reinterpret_cast<HWND>(win), &dc);
+#if QT_VERSION > 0x050000
+ qDebug().noquote() << s;
+#else
+ qDebug("%s", qPrintable(s));
+#endif
+}
+
+void dumpNativeWindows(WId rootIn)
+{
+ const WId root = rootIn ? rootIn : reinterpret_cast<WId>(GetDesktopWindow());
+ dumpNativeWindows(WIdVector(1, root));
+}
+
+BOOL CALLBACK findQtTopLevelEnumChildProc(HWND hwnd, LPARAM lParam)
+{
+ WIdVector *v = reinterpret_cast<WIdVector *>(lParam);
+ wchar_t buf[512];
+ if (GetClassName(hwnd, buf, sizeof(buf)/sizeof(buf[0]))) {
+ if (wcsstr(buf, L"Qt"))
+ v->append(reinterpret_cast<WId>(hwnd));
+ }
+ return TRUE;
+}
+
+static WIdVector findQtTopLevels()
+{
+ WIdVector result;
+ EnumChildWindows(GetDesktopWindow(),
+ findQtTopLevelEnumChildProc,
+ reinterpret_cast<LPARAM>(&result));
+ return result;
+}
+
+void dumpNativeQtTopLevels()
+{
+ dumpNativeWindows(findQtTopLevels());
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/qwidgetdump.cpp b/tests/manual/diaglib/qwidgetdump.cpp
new file mode 100644
index 0000000000..d4f985c7c8
--- /dev/null
+++ b/tests/manual/diaglib/qwidgetdump.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwidgetdump.h"
+
+#include <QWidget>
+#if QT_VERSION > 0x050000
+# include <QtGui/QScreen>
+# include <QtGui/QWindow>
+#endif
+#include <QApplication>
+#include <QtCore/QMetaObject>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+namespace QtDiag {
+
+static void dumpWidgetRecursion(QTextStream &str, const QWidget *w,
+ FormatWindowOptions options, int depth = 0)
+{
+ indentStream(str, 2 * depth);
+ formatObject(str, w);
+ str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] ");
+ if (const WId nativeWinId = w->internalWinId())
+ str << "[native: " << hex << showbase << nativeWinId << dec << noshowbase << "] ";
+ if (w->isWindow())
+ str << "[top] ";
+ str << (w->testAttribute(Qt::WA_Mapped) ? "[mapped] " : "[not mapped] ");
+ if (w->testAttribute(Qt::WA_DontCreateNativeAncestors))
+ str << "[NoNativeAncestors] ";
+ formatRect(str, w->geometry());
+ if (!(options & DontPrintWindowFlags)) {
+ str << ' ';
+ formatWindowFlags(str, w->windowFlags());
+ }
+ str << '\n';
+#if QT_VERSION > 0x050000
+ if (const QWindow *win = w->windowHandle()) {
+ indentStream(str, 2 * (1 + depth));
+ formatWindow(str, win, options);
+ str << '\n';
+ }
+#endif // Qt 5
+ foreach (const QObject *co, w->children()) {
+ if (co->isWidgetType())
+ dumpWidgetRecursion(str, static_cast<const QWidget *>(co), options, depth + 1);
+ }
+}
+
+void dumpAllWidgets(FormatWindowOptions options)
+{
+ QString d;
+ QTextStream str(&d);
+ str << "### QWidgets:\n";
+ foreach (QWidget *tw, QApplication::topLevelWidgets())
+ dumpWidgetRecursion(str, tw, options);
+#if QT_VERSION > 0x050000
+ qDebug().noquote() << d;
+#else
+ qDebug("%s", qPrintable(d));
+#endif
+}
+
+} // namespace QtDiag
diff --git a/tests/manual/diaglib/qwidgetdump.h b/tests/manual/diaglib/qwidgetdump.h
new file mode 100644
index 0000000000..f9615b5d2f
--- /dev/null
+++ b/tests/manual/diaglib/qwidgetdump.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _WIDGETDUMP_
+#define _WIDGETDUMP_
+
+#include "qwindowdump.h"
+
+namespace QtDiag {
+
+void dumpAllWidgets(FormatWindowOptions options = 0);
+
+} // namespace QtDiag
+
+#endif
diff --git a/tests/manual/diaglib/qwindowdump.cpp b/tests/manual/diaglib/qwindowdump.cpp
new file mode 100644
index 0000000000..2ecc52ca77
--- /dev/null
+++ b/tests/manual/diaglib/qwindowdump.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowdump.h"
+
+#if QT_VERSION > 0x050000
+# include <QtGui/QGuiApplication>
+# include <QtGui/QScreen>
+# include <QtGui/QWindow>
+# include <qpa/qplatformwindow.h>
+#endif
+#include <QtCore/QMetaObject>
+#include <QtCore/QRect>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+namespace QtDiag {
+
+void indentStream(QTextStream &s, int indent)
+{
+ for (int i = 0; i < indent; ++i)
+ s << ' ';
+}
+
+void formatObject(QTextStream &str, const QObject *o)
+{
+ str << o->metaObject()->className();
+ const QString on = o->objectName();
+ if (!on.isEmpty())
+ str << "/\"" << on << '"';
+}
+
+void formatRect(QTextStream &str, const QRect &geom)
+{
+ str << geom.width() << 'x' << geom.height()
+ << forcesign << geom.x() << geom.y() << noforcesign;
+}
+
+#define debugType(s, type, typeConstant) \
+if ((type & typeConstant) == typeConstant) \
+ s << ' ' << #typeConstant;
+
+#define debugFlag(s, flags, flagConstant) \
+if (flags & flagConstant) \
+ s << ' ' << #flagConstant;
+
+void formatWindowFlags(QTextStream &str, const Qt::WindowFlags flags)
+{
+ str << showbase << hex << unsigned(flags) << dec << noshowbase;
+ const Qt::WindowFlags windowType = flags & Qt::WindowType_Mask;
+ debugFlag(str, flags, Qt::Window)
+ debugType(str, windowType, Qt::Dialog)
+ debugType(str, windowType, Qt::Sheet)
+ debugType(str, windowType, Qt::Drawer)
+ debugType(str, windowType, Qt::Popup)
+ debugType(str, windowType, Qt::Tool)
+ debugType(str, windowType, Qt::ToolTip)
+ debugType(str, windowType, Qt::SplashScreen)
+ debugType(str, windowType, Qt::Desktop)
+ debugType(str, windowType, Qt::SubWindow)
+#if QT_VERSION > 0x050000
+ debugType(str, windowType, Qt::ForeignWindow)
+ debugType(str, windowType, Qt::CoverWindow)
+#endif
+ debugFlag(str, flags, Qt::MSWindowsFixedSizeDialogHint)
+ debugFlag(str, flags, Qt::MSWindowsOwnDC)
+ debugFlag(str, flags, Qt::X11BypassWindowManagerHint)
+ debugFlag(str, flags, Qt::FramelessWindowHint)
+ debugFlag(str, flags, Qt::WindowTitleHint)
+ debugFlag(str, flags, Qt::WindowSystemMenuHint)
+ debugFlag(str, flags, Qt::WindowMinimizeButtonHint)
+ debugFlag(str, flags, Qt::WindowMaximizeButtonHint)
+ debugFlag(str, flags, Qt::WindowContextHelpButtonHint)
+ debugFlag(str, flags, Qt::WindowShadeButtonHint)
+ debugFlag(str, flags, Qt::WindowStaysOnTopHint)
+ debugFlag(str, flags, Qt::CustomizeWindowHint)
+#if QT_VERSION > 0x050000
+ debugFlag(str, flags, Qt::WindowTransparentForInput)
+ debugFlag(str, flags, Qt::WindowOverridesSystemGestures)
+ debugFlag(str, flags, Qt::WindowDoesNotAcceptFocus)
+ debugFlag(str, flags, Qt::NoDropShadowWindowHint)
+ debugFlag(str, flags, Qt::WindowFullscreenButtonHint)
+#endif
+ debugFlag(str, flags, Qt::WindowStaysOnBottomHint)
+ debugFlag(str, flags, Qt::MacWindowToolBarButtonHint)
+ debugFlag(str, flags, Qt::BypassGraphicsProxyWidget)
+ debugFlag(str, flags, Qt::WindowOkButtonHint)
+ debugFlag(str, flags, Qt::WindowCancelButtonHint)
+}
+
+#if QT_VERSION > 0x050000
+
+void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options)
+{
+ const QPlatformWindow *pw = w->handle();
+ formatObject(str, w);
+ str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] ");
+ if (const WId nativeWinId = pw ? pw->winId() : WId(0))
+ str << "[native: " << hex << showbase << nativeWinId << dec << noshowbase << "] ";
+ if (w->isTopLevel())
+ str << "[top] ";
+ if (w->isExposed())
+ str << "[exposed] ";
+ formatRect(str, w->geometry());
+ if (!(options & DontPrintWindowFlags)) {
+ str << ' ';
+ formatWindowFlags(str, w->flags());
+ }
+ str << '\n';
+}
+
+static void dumpWindowRecursion(QTextStream &str, const QWindow *w,
+ FormatWindowOptions options = 0, int depth = 0)
+{
+ indentStream(str, 2 * depth);
+ formatWindow(str, w);
+ foreach (const QObject *co, w->children()) {
+ if (co->isWindowType())
+ dumpWindowRecursion(str, static_cast<const QWindow *>(co), options, depth + 1);
+ }
+}
+
+void dumpAllWindows(FormatWindowOptions options)
+{
+ QString d;
+ QTextStream str(&d);
+ str << "### QWindows:\n";
+ foreach (QWindow *w, QGuiApplication::topLevelWindows())
+ dumpWindowRecursion(str, w, options);
+ qDebug().noquote() << d;
+}
+
+#else // Qt 5
+class QWindow {};
+
+void formatWindow(QTextStream &, const QWindow *, FormatWindowOptions)
+{
+}
+
+void dumpAllWindows(FormatWindowOptions options)
+{
+}
+
+#endif // Qt 4
+
+} // namespace QtDiag
diff --git a/src/plugins/bearer/networkmanager/qnmdbushelper.h b/tests/manual/diaglib/qwindowdump.h
index e224af87f1..ab7c0243e9 100644
--- a/src/plugins/bearer/networkmanager/qnmdbushelper.h
+++ b/tests/manual/diaglib/qwindowdump.h
@@ -3,7 +3,7 @@
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -31,43 +31,33 @@
**
****************************************************************************/
-#ifndef QNMDBUSHELPERPRIVATE_H
-#define QNMDBUSHELPERPRIVATE_H
+#ifndef _WINDOWDUMP_
+#define _WINDOWDUMP_
-#include <QDBusObjectPath>
-#include <QDBusContext>
-#include <QMap>
+#include <QtCore/qnamespace.h>
-#ifndef QT_NO_DBUS
+QT_FORWARD_DECLARE_CLASS(QRect)
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QWindow)
+QT_FORWARD_DECLARE_CLASS(QTextStream)
-QT_BEGIN_NAMESPACE
+namespace QtDiag {
-class QNmDBusHelper: public QObject, protected QDBusContext
- {
- Q_OBJECT
- public:
- QNmDBusHelper(QObject *parent = 0);
- ~QNmDBusHelper();
+enum FormatWindowOption {
+ DontPrintWindowFlags = 0x001
+};
- public slots:
- void deviceStateChanged(quint32);
- void slotAccessPointAdded(QDBusObjectPath);
- void slotAccessPointRemoved(QDBusObjectPath);
- void slotPropertiesChanged(QMap<QString,QVariant>);
- void slotSettingsRemoved();
- void activeConnectionPropertiesChanged(QMap<QString,QVariant>);
+Q_DECLARE_FLAGS(FormatWindowOptions, FormatWindowOption)
+Q_DECLARE_OPERATORS_FOR_FLAGS(FormatWindowOptions)
-Q_SIGNALS:
- void pathForStateChanged(const QString &, quint32);
- void pathForAccessPointAdded(const QString &);
- void pathForAccessPointRemoved(const QString &);
- void pathForPropertiesChanged(const QString &, QMap<QString,QVariant>);
- void pathForSettingsRemoved(const QString &);
- void pathForConnectionsChanged(const QStringList &pathsList);
-};
+void indentStream(QTextStream &s, int indent);
+void formatObject(QTextStream &str, const QObject *o);
+void formatRect(QTextStream &str, const QRect &geom);
+void formatWindowFlags(QTextStream &str, const Qt::WindowFlags flags);
-QT_END_NAMESPACE
+void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions options = 0);
+void dumpAllWindows(FormatWindowOptions options = 0);
-#endif // QT_NO_DBUS
+} // namespace QtDiag
-#endif// QNMDBUSHELPERPRIVATE_H
+#endif
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index e593756a7d..fe3e624bfe 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -29,6 +29,7 @@ qtabletevent \
qtexteditlist \
qtbug-8933 \
qtouchevent \
+touch \
qwidget_zorder \
repaint \
socketengine \
diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp
new file mode 100644
index 0000000000..6b06db614c
--- /dev/null
+++ b/tests/manual/touch/main.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QLabel>
+#include <QMenu>
+#include <QMenuBar>
+#include <QAction>
+#include <QMainWindow>
+#include <QSplitter>
+#include <QVector>
+#include <QCommandLineOption>
+#include <QCommandLineParser>
+#include <QPlainTextEdit>
+#include <QPaintEvent>
+#include <QScreen>
+#include <QDebug>
+#include <QTextStream>
+
+QDebug operator<<(QDebug debug, const QTouchDevice *d)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QTouchDevice(" << d->name() << ',';
+ switch (d->type()) {
+ case QTouchDevice::TouchScreen:
+ debug << "TouchScreen";
+ break;
+ case QTouchDevice::TouchPad:
+ debug << "TouchPad";
+ break;
+ }
+ debug << ", capabilities=" << d->capabilities()
+ << ", maximumTouchPoints=" << d->maximumTouchPoints() << ')';
+ return debug;
+}
+
+typedef QVector<QEvent::Type> EventTypeVector;
+
+class EventFilter : public QObject {
+ Q_OBJECT
+public:
+ explicit EventFilter(const EventTypeVector &types, QObject *p) : QObject(p), m_types(types) {}
+
+ bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE;
+
+signals:
+ void eventReceived(const QString &);
+
+private:
+ const EventTypeVector m_types;
+};
+
+bool EventFilter::eventFilter(QObject *o, QEvent *e)
+{
+ static int n = 0;
+ if (m_types.contains(e->type())) {
+ QString message;
+ QDebug(&message) << '#' << n++ << ' ' << o->objectName() << ' ' << e;
+ emit eventReceived(message);
+ }
+ return false;
+}
+
+class TouchTestWidget : public QWidget {
+public:
+ explicit TouchTestWidget(QWidget *parent = 0) : QWidget(parent)
+ {
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+
+ bool event(QEvent *event) Q_DECL_OVERRIDE
+ {
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ event->accept();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::event(event);
+ }
+};
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+public:
+ MainWindow();
+ QWidget *touchWidget() const { return m_touchWidget; }
+
+public slots:
+ void appendToLog(const QString &text) { m_logTextEdit->appendPlainText(text); }
+ void dumpTouchDevices();
+
+private:
+ QWidget *m_touchWidget;
+ QPlainTextEdit *m_logTextEdit;
+};
+
+MainWindow::MainWindow()
+ : m_touchWidget(new TouchTestWidget)
+ , m_logTextEdit(new QPlainTextEdit)
+{
+ setWindowTitle(QStringLiteral("Touch Event Tester ") + QT_VERSION_STR);
+
+ setObjectName("MainWin");
+ QMenu *fileMenu = menuBar()->addMenu("File");
+ QAction *da = fileMenu->addAction(QStringLiteral("Dump devices"));
+ da->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
+ connect(da, SIGNAL(triggered()), this, SLOT(dumpTouchDevices()));
+ QAction *qa = fileMenu->addAction(QStringLiteral("Quit"));
+ qa->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
+ connect(qa, SIGNAL(triggered()), this, SLOT(close()));
+
+ QSplitter *mainSplitter = new QSplitter(Qt::Vertical);
+
+ m_touchWidget->setObjectName(QStringLiteral("TouchWidget"));
+ const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size();
+ m_touchWidget->setMinimumSize(screenSize / 2);
+ mainSplitter->addWidget(m_touchWidget);
+
+ m_logTextEdit->setObjectName(QStringLiteral("LogTextEdit"));
+ m_logTextEdit->setMinimumHeight(screenSize.height() / 4);
+ mainSplitter->addWidget(m_logTextEdit);
+ setCentralWidget(mainSplitter);
+
+ dumpTouchDevices();
+}
+
+void MainWindow::dumpTouchDevices()
+{
+ QString message;
+ QDebug debug(&message);
+ const QList<const QTouchDevice *> devices = QTouchDevice::devices();
+ debug << devices.size() << "Device(s):\n";
+ for (int i = 0; i < devices.size(); ++i)
+ debug << "Device #" << i << devices.at(i) << '\n';
+ appendToLog(message);
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QStringLiteral("Touch/Mouse tester"));
+ parser.addHelpOption();
+ const QCommandLineOption mouseMoveOption(QStringLiteral("mousemove"),
+ QStringLiteral("Log mouse move events"));
+ parser.addOption(mouseMoveOption);
+ const QCommandLineOption globalFilterOption(QStringLiteral("global"),
+ QStringLiteral("Global event filter"));
+ parser.addOption(globalFilterOption);
+ parser.process(QApplication::arguments());
+
+ MainWindow w;
+ w.show();
+ const QSize pos = QGuiApplication::primaryScreen()->availableGeometry().size() - w.size();
+ w.move(pos.width() / 2, pos.height() / 2);
+
+ EventTypeVector eventTypes;
+ eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease
+ << QEvent::MouseButtonDblClick
+ << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd;
+ if (parser.isSet(mouseMoveOption))
+ eventTypes << QEvent::MouseMove;
+ QObject *filterTarget = parser.isSet(globalFilterOption)
+ ? static_cast<QObject *>(&a)
+ : static_cast<QObject *>(w.touchWidget());
+ EventFilter *filter = new EventFilter(eventTypes, filterTarget);
+ filterTarget->installEventFilter(filter);
+ QObject::connect(filter, SIGNAL(eventReceived(QString)), &w, SLOT(appendToLog(QString)));
+
+ return a.exec();
+}
+
+#include "main.moc"
diff --git a/tests/manual/touch/touch.pro b/tests/manual/touch/touch.pro
new file mode 100644
index 0000000000..fcb3c47f43
--- /dev/null
+++ b/tests/manual/touch/touch.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+QT = core gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+CONFIG -= app_bundle
+SOURCES += main.cpp